You've already forked joomla_test
first commit
This commit is contained in:
616
libraries/joomla/utilities/arrayhelper.php
Normal file
616
libraries/joomla/utilities/arrayhelper.php
Normal file
@ -0,0 +1,616 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Platform
|
||||
* @subpackage Utilities
|
||||
*
|
||||
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved
|
||||
* @license GNU General Public License version 2 or later; see LICENSE
|
||||
*/
|
||||
|
||||
defined('JPATH_PLATFORM') or die;
|
||||
|
||||
/**
|
||||
* JArrayHelper is an array utility class for doing all sorts of odds and ends with arrays.
|
||||
*
|
||||
* @package Joomla.Platform
|
||||
* @subpackage Utilities
|
||||
* @since 11.1
|
||||
*/
|
||||
abstract class JArrayHelper
|
||||
{
|
||||
/**
|
||||
* Option to perform case-sensitive sorts.
|
||||
*
|
||||
* @var mixed Boolean or array of booleans.
|
||||
* @since 11.3
|
||||
*/
|
||||
protected static $sortCase;
|
||||
|
||||
/**
|
||||
* Option to set the sort direction.
|
||||
*
|
||||
* @var mixed Integer or array of integers.
|
||||
* @since 11.3
|
||||
*/
|
||||
protected static $sortDirection;
|
||||
|
||||
/**
|
||||
* Option to set the object key to sort on.
|
||||
*
|
||||
* @var string
|
||||
* @since 11.3
|
||||
*/
|
||||
protected static $sortKey;
|
||||
|
||||
/**
|
||||
* Option to perform a language aware sort.
|
||||
*
|
||||
* @var mixed Boolean or array of booleans.
|
||||
* @since 11.3
|
||||
*/
|
||||
protected static $sortLocale;
|
||||
|
||||
/**
|
||||
* Function to convert array to integer values
|
||||
*
|
||||
* @param array &$array The source array to convert
|
||||
* @param mixed $default A default value (int|array) to assign if $array is not an array
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public static function toInteger(&$array, $default = null)
|
||||
{
|
||||
if (is_array($array))
|
||||
{
|
||||
foreach ($array as $i => $v)
|
||||
{
|
||||
$array[$i] = (int) $v;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($default === null)
|
||||
{
|
||||
$array = array();
|
||||
}
|
||||
elseif (is_array($default))
|
||||
{
|
||||
self::toInteger($default, null);
|
||||
$array = $default;
|
||||
}
|
||||
else
|
||||
{
|
||||
$array = array((int) $default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to map an array to a stdClass object.
|
||||
*
|
||||
* @param array &$array The array to map.
|
||||
* @param string $class Name of the class to create
|
||||
*
|
||||
* @return object The object mapped from the given array
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public static function toObject(&$array, $class = 'stdClass')
|
||||
{
|
||||
$obj = null;
|
||||
|
||||
if (is_array($array))
|
||||
{
|
||||
$obj = new $class;
|
||||
|
||||
foreach ($array as $k => $v)
|
||||
{
|
||||
if (is_array($v))
|
||||
{
|
||||
$obj->$k = self::toObject($v, $class);
|
||||
}
|
||||
else
|
||||
{
|
||||
$obj->$k = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to map an array to a string.
|
||||
*
|
||||
* @param array $array The array to map.
|
||||
* @param string $inner_glue The glue (optional, defaults to '=') between the key and the value.
|
||||
* @param string $outer_glue The glue (optional, defaults to ' ') between array elements.
|
||||
* @param boolean $keepOuterKey True if final key should be kept.
|
||||
*
|
||||
* @return string The string mapped from the given array
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public static function toString($array = null, $inner_glue = '=', $outer_glue = ' ', $keepOuterKey = false)
|
||||
{
|
||||
$output = array();
|
||||
|
||||
if (is_array($array))
|
||||
{
|
||||
foreach ($array as $key => $item)
|
||||
{
|
||||
if (is_array($item))
|
||||
{
|
||||
if ($keepOuterKey)
|
||||
{
|
||||
$output[] = $key;
|
||||
}
|
||||
// This is value is an array, go and do it again!
|
||||
$output[] = self::toString($item, $inner_glue, $outer_glue, $keepOuterKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
$output[] = $key . $inner_glue . '"' . $item . '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implode($outer_glue, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to map an object to an array
|
||||
*
|
||||
* @param object $p_obj The source object
|
||||
* @param boolean $recurse True to recurse through multi-level objects
|
||||
* @param string $regex An optional regular expression to match on field names
|
||||
*
|
||||
* @return array The array mapped from the given object
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public static function fromObject($p_obj, $recurse = true, $regex = null)
|
||||
{
|
||||
if (is_object($p_obj))
|
||||
{
|
||||
return self::_fromObject($p_obj, $recurse, $regex);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to map an object or array to an array
|
||||
*
|
||||
* @param mixed $item The source object or array
|
||||
* @param boolean $recurse True to recurse through multi-level objects
|
||||
* @param string $regex An optional regular expression to match on field names
|
||||
*
|
||||
* @return array The array mapped from the given object
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
protected static function _fromObject($item, $recurse, $regex)
|
||||
{
|
||||
if (is_object($item))
|
||||
{
|
||||
$result = array();
|
||||
|
||||
foreach (get_object_vars($item) as $k => $v)
|
||||
{
|
||||
if (!$regex || preg_match($regex, $k))
|
||||
{
|
||||
if ($recurse)
|
||||
{
|
||||
$result[$k] = self::_fromObject($v, $recurse, $regex);
|
||||
}
|
||||
else
|
||||
{
|
||||
$result[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (is_array($item))
|
||||
{
|
||||
$result = array();
|
||||
|
||||
foreach ($item as $k => $v)
|
||||
{
|
||||
$result[$k] = self::_fromObject($v, $recurse, $regex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = $item;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a column from an array of arrays or objects
|
||||
*
|
||||
* @param array &$array The source array
|
||||
* @param string $index The index of the column or name of object property
|
||||
*
|
||||
* @return array Column of values from the source array
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public static function getColumn(&$array, $index)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
if (is_array($array))
|
||||
{
|
||||
foreach ($array as &$item)
|
||||
{
|
||||
if (is_array($item) && isset($item[$index]))
|
||||
{
|
||||
$result[] = $item[$index];
|
||||
}
|
||||
elseif (is_object($item) && isset($item->$index))
|
||||
{
|
||||
$result[] = $item->$index;
|
||||
}
|
||||
// Else ignore the entry
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to return a value from a named array or a specified default
|
||||
*
|
||||
* @param array &$array A named array
|
||||
* @param string $name The key to search for
|
||||
* @param mixed $default The default value to give if no key found
|
||||
* @param string $type Return type for the variable (INT, FLOAT, STRING, WORD, BOOLEAN, ARRAY)
|
||||
*
|
||||
* @return mixed The value from the source array
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public static function getValue(&$array, $name, $default = null, $type = '')
|
||||
{
|
||||
$result = null;
|
||||
|
||||
if (isset($array[$name]))
|
||||
{
|
||||
$result = $array[$name];
|
||||
}
|
||||
|
||||
// Handle the default case
|
||||
if (is_null($result))
|
||||
{
|
||||
$result = $default;
|
||||
}
|
||||
|
||||
// Handle the type constraint
|
||||
switch (strtoupper($type))
|
||||
{
|
||||
case 'INT':
|
||||
case 'INTEGER':
|
||||
// Only use the first integer value
|
||||
@preg_match('/-?[0-9]+/', $result, $matches);
|
||||
$result = @(int) $matches[0];
|
||||
break;
|
||||
|
||||
case 'FLOAT':
|
||||
case 'DOUBLE':
|
||||
// Only use the first floating point value
|
||||
@preg_match('/-?[0-9]+(\.[0-9]+)?/', $result, $matches);
|
||||
$result = @(float) $matches[0];
|
||||
break;
|
||||
|
||||
case 'BOOL':
|
||||
case 'BOOLEAN':
|
||||
$result = (bool) $result;
|
||||
break;
|
||||
|
||||
case 'ARRAY':
|
||||
if (!is_array($result))
|
||||
{
|
||||
$result = array($result);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'STRING':
|
||||
$result = (string) $result;
|
||||
break;
|
||||
|
||||
case 'WORD':
|
||||
$result = (string) preg_replace('#\W#', '', $result);
|
||||
break;
|
||||
|
||||
case 'NONE':
|
||||
default:
|
||||
// No casting necessary
|
||||
break;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an associative array of arrays and inverts the array keys to values using the array values as keys.
|
||||
*
|
||||
* Example:
|
||||
* $input = array(
|
||||
* 'New' => array('1000', '1500', '1750'),
|
||||
* 'Used' => array('3000', '4000', '5000', '6000')
|
||||
* );
|
||||
* $output = JArrayHelper::invert($input);
|
||||
*
|
||||
* Output would be equal to:
|
||||
* $output = array(
|
||||
* '1000' => 'New',
|
||||
* '1500' => 'New',
|
||||
* '1750' => 'New',
|
||||
* '3000' => 'Used',
|
||||
* '4000' => 'Used',
|
||||
* '5000' => 'Used',
|
||||
* '6000' => 'Used'
|
||||
* );
|
||||
*
|
||||
* @param array $array The source array.
|
||||
*
|
||||
* @return array The inverted array.
|
||||
*
|
||||
* @since 12.3
|
||||
*/
|
||||
public static function invert($array)
|
||||
{
|
||||
$return = array();
|
||||
|
||||
foreach ($array as $base => $values)
|
||||
{
|
||||
if (!is_array($values))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($values as $key)
|
||||
{
|
||||
// If the key isn't scalar then ignore it.
|
||||
if (is_scalar($key))
|
||||
{
|
||||
$return[$key] = $base;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to determine if an array is an associative array.
|
||||
*
|
||||
* @param array $array An array to test.
|
||||
*
|
||||
* @return boolean True if the array is an associative array.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public static function isAssociative($array)
|
||||
{
|
||||
if (is_array($array))
|
||||
{
|
||||
foreach (array_keys($array) as $k => $v)
|
||||
{
|
||||
if ($k !== $v)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pivots an array to create a reverse lookup of an array of scalars, arrays or objects.
|
||||
*
|
||||
* @param array $source The source array.
|
||||
* @param string $key Where the elements of the source array are objects or arrays, the key to pivot on.
|
||||
*
|
||||
* @return array An array of arrays pivoted either on the value of the keys, or an individual key of an object or array.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public static function pivot($source, $key = null)
|
||||
{
|
||||
$result = array();
|
||||
$counter = array();
|
||||
|
||||
foreach ($source as $index => $value)
|
||||
{
|
||||
// Determine the name of the pivot key, and its value.
|
||||
if (is_array($value))
|
||||
{
|
||||
// If the key does not exist, ignore it.
|
||||
if (!isset($value[$key]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$resultKey = $value[$key];
|
||||
$resultValue = &$source[$index];
|
||||
}
|
||||
elseif (is_object($value))
|
||||
{
|
||||
// If the key does not exist, ignore it.
|
||||
if (!isset($value->$key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$resultKey = $value->$key;
|
||||
$resultValue = &$source[$index];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just a scalar value.
|
||||
$resultKey = $value;
|
||||
$resultValue = $index;
|
||||
}
|
||||
|
||||
// The counter tracks how many times a key has been used.
|
||||
if (empty($counter[$resultKey]))
|
||||
{
|
||||
// The first time around we just assign the value to the key.
|
||||
$result[$resultKey] = $resultValue;
|
||||
$counter[$resultKey] = 1;
|
||||
}
|
||||
elseif ($counter[$resultKey] == 1)
|
||||
{
|
||||
// If there is a second time, we convert the value into an array.
|
||||
$result[$resultKey] = array(
|
||||
$result[$resultKey],
|
||||
$resultValue,
|
||||
);
|
||||
$counter[$resultKey]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// After the second time, no need to track any more. Just append to the existing array.
|
||||
$result[$resultKey][] = $resultValue;
|
||||
}
|
||||
}
|
||||
|
||||
unset($counter);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to sort an array of objects on a given field
|
||||
*
|
||||
* @param array &$a An array of objects
|
||||
* @param mixed $k The key (string) or a array of key to sort on
|
||||
* @param mixed $direction Direction (integer) or an array of direction to sort in [1 = Ascending] [-1 = Descending]
|
||||
* @param mixed $caseSensitive Boolean or array of booleans to let sort occur case sensitive or insensitive
|
||||
* @param mixed $locale Boolean or array of booleans to let sort occur using the locale language or not
|
||||
*
|
||||
* @return array The sorted array of objects
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public static function sortObjects(&$a, $k, $direction = 1, $caseSensitive = true, $locale = false)
|
||||
{
|
||||
if (!is_array($locale) || !is_array($locale[0]))
|
||||
{
|
||||
$locale = array($locale);
|
||||
}
|
||||
|
||||
self::$sortCase = (array) $caseSensitive;
|
||||
self::$sortDirection = (array) $direction;
|
||||
self::$sortKey = (array) $k;
|
||||
self::$sortLocale = $locale;
|
||||
|
||||
usort($a, array(__CLASS__, '_sortObjects'));
|
||||
|
||||
self::$sortCase = null;
|
||||
self::$sortDirection = null;
|
||||
self::$sortKey = null;
|
||||
self::$sortLocale = null;
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for sorting an array of objects on a key
|
||||
*
|
||||
* @param array &$a An array of objects
|
||||
* @param array &$b An array of objects
|
||||
*
|
||||
* @return integer Comparison status
|
||||
*
|
||||
* @see JArrayHelper::sortObjects()
|
||||
* @since 11.1
|
||||
*/
|
||||
protected static function _sortObjects(&$a, &$b)
|
||||
{
|
||||
$key = self::$sortKey;
|
||||
|
||||
for ($i = 0, $count = count($key); $i < $count; $i++)
|
||||
{
|
||||
if (isset(self::$sortDirection[$i]))
|
||||
{
|
||||
$direction = self::$sortDirection[$i];
|
||||
}
|
||||
|
||||
if (isset(self::$sortCase[$i]))
|
||||
{
|
||||
$caseSensitive = self::$sortCase[$i];
|
||||
}
|
||||
|
||||
if (isset(self::$sortLocale[$i]))
|
||||
{
|
||||
$locale = self::$sortLocale[$i];
|
||||
}
|
||||
|
||||
$va = $a->$key[$i];
|
||||
$vb = $b->$key[$i];
|
||||
|
||||
if ((is_bool($va) || is_numeric($va)) && (is_bool($vb) || is_numeric($vb)))
|
||||
{
|
||||
$cmp = $va - $vb;
|
||||
}
|
||||
elseif ($caseSensitive)
|
||||
{
|
||||
$cmp = JString::strcmp($va, $vb, $locale);
|
||||
}
|
||||
else
|
||||
{
|
||||
$cmp = JString::strcasecmp($va, $vb, $locale);
|
||||
}
|
||||
|
||||
if ($cmp > 0)
|
||||
{
|
||||
|
||||
return $direction;
|
||||
}
|
||||
|
||||
if ($cmp < 0)
|
||||
{
|
||||
return -$direction;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multidimensional array safe unique test
|
||||
*
|
||||
* @param array $myArray The array to make unique.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @see http://php.net/manual/en/function.array-unique.php
|
||||
* @since 11.2
|
||||
*/
|
||||
public static function arrayUnique($myArray)
|
||||
{
|
||||
if (!is_array($myArray))
|
||||
{
|
||||
return $myArray;
|
||||
}
|
||||
|
||||
foreach ($myArray as &$myvalue)
|
||||
{
|
||||
$myvalue = serialize($myvalue);
|
||||
}
|
||||
|
||||
$myArray = array_unique($myArray);
|
||||
|
||||
foreach ($myArray as &$myvalue)
|
||||
{
|
||||
$myvalue = unserialize($myvalue);
|
||||
}
|
||||
|
||||
return $myArray;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user