Source for file arrayhelper.php

Documentation is available at arrayhelper.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Platform
  4.  * @subpackage  Utilities
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved
  7.  * @license     GNU General Public License version 2 or later; see LICENSE
  8.  */
  9.  
  10. defined('JPATH_PLATFORM'or die;
  11.  
  12. /**
  13.  * JArrayHelper is an array utility class for doing all sorts of odds and ends with arrays.
  14.  *
  15.  * @package     Joomla.Platform
  16.  * @subpackage  Utilities
  17.  * @since       11.1
  18.  */
  19. abstract class JArrayHelper
  20. {
  21.     /**
  22.      * Option to perform case-sensitive sorts.
  23.      *
  24.      * @var    mixed  Boolean or array of booleans.
  25.      * @since  11.3
  26.      */
  27.     protected static $sortCase;
  28.  
  29.     /**
  30.      * Option to set the sort direction.
  31.      *
  32.      * @var    mixed  Integer or array of integers.
  33.      * @since  11.3
  34.      */
  35.     protected static $sortDirection;
  36.  
  37.     /**
  38.      * Option to set the object key to sort on.
  39.      *
  40.      * @var    string 
  41.      * @since  11.3
  42.      */
  43.     protected static $sortKey;
  44.  
  45.     /**
  46.      * Option to perform a language aware sort.
  47.      *
  48.      * @var    mixed  Boolean or array of booleans.
  49.      * @since  11.3
  50.      */
  51.     protected static $sortLocale;
  52.  
  53.     /**
  54.      * Function to convert array to integer values
  55.      *
  56.      * @param   array  &$array   The source array to convert
  57.      * @param   mixed  $default  A default value (int|array) to assign if $array is not an array
  58.      *
  59.      * @return  void 
  60.      *
  61.      * @since   11.1
  62.      */
  63.     public static function toInteger(&$array$default null)
  64.     {
  65.         if (is_array($array))
  66.         {
  67.             foreach ($array as $i => $v)
  68.             {
  69.                 $array[$i= (int) $v;
  70.             }
  71.         }
  72.         else
  73.         {
  74.             if ($default === null)
  75.             {
  76.                 $array array();
  77.             }
  78.             elseif (is_array($default))
  79.             {
  80.                 self::toInteger($defaultnull);
  81.                 $array $default;
  82.             }
  83.             else
  84.             {
  85.                 $array array((int) $default);
  86.             }
  87.         }
  88.     }
  89.  
  90.     /**
  91.      * Utility function to map an array to a stdClass object.
  92.      *
  93.      * @param   array   &$array  The array to map.
  94.      * @param   string  $class   Name of the class to create
  95.      *
  96.      * @return  object   The object mapped from the given array
  97.      *
  98.      * @since   11.1
  99.      */
  100.     public static function toObject(&$array$class 'stdClass')
  101.     {
  102.         $obj null;
  103.  
  104.         if (is_array($array))
  105.         {
  106.             $obj new $class;
  107.  
  108.             foreach ($array as $k => $v)
  109.             {
  110.                 if (is_array($v))
  111.                 {
  112.                     $obj->$k self::toObject($v$class);
  113.                 }
  114.                 else
  115.                 {
  116.                     $obj->$k $v;
  117.                 }
  118.             }
  119.         }
  120.         return $obj;
  121.     }
  122.  
  123.     /**
  124.      * Utility function to map an array to a string.
  125.      *
  126.      * @param   array    $array         The array to map.
  127.      * @param   string   $inner_glue    The glue (optional, defaults to '=') between the key and the value.
  128.      * @param   string   $outer_glue    The glue (optional, defaults to ' ') between array elements.
  129.      * @param   boolean  $keepOuterKey  True if final key should be kept.
  130.      *
  131.      * @return  string   The string mapped from the given array
  132.      *
  133.      * @since   11.1
  134.      */
  135.     public static function toString($array null$inner_glue '='$outer_glue ' '$keepOuterKey false)
  136.     {
  137.         $output array();
  138.  
  139.         if (is_array($array))
  140.         {
  141.             foreach ($array as $key => $item)
  142.             {
  143.                 if (is_array($item))
  144.                 {
  145.                     if ($keepOuterKey)
  146.                     {
  147.                         $output[$key;
  148.                     }
  149.                     // This is value is an array, go and do it again!
  150.                     $output[self::toString($item$inner_glue$outer_glue$keepOuterKey);
  151.                 }
  152.                 else
  153.                 {
  154.                     $output[$key $inner_glue '"' $item '"';
  155.                 }
  156.             }
  157.         }
  158.  
  159.         return implode($outer_glue$output);
  160.     }
  161.  
  162.     /**
  163.      * Utility function to map an object to an array
  164.      *
  165.      * @param   object   $p_obj    The source object
  166.      * @param   boolean  $recurse  True to recurse through multi-level objects
  167.      * @param   string   $regex    An optional regular expression to match on field names
  168.      *
  169.      * @return  array    The array mapped from the given object
  170.      *
  171.      * @since   11.1
  172.      */
  173.     public static function fromObject($p_obj$recurse true$regex null)
  174.     {
  175.         if (is_object($p_obj))
  176.         {
  177.             return self::_fromObject($p_obj$recurse$regex);
  178.         }
  179.         else
  180.         {
  181.             return null;
  182.         }
  183.     }
  184.  
  185.     /**
  186.      * Utility function to map an object or array to an array
  187.      *
  188.      * @param   mixed    $item     The source object or array
  189.      * @param   boolean  $recurse  True to recurse through multi-level objects
  190.      * @param   string   $regex    An optional regular expression to match on field names
  191.      *
  192.      * @return  array  The array mapped from the given object
  193.      *
  194.      * @since   11.1
  195.      */
  196.     protected static function _fromObject($item$recurse$regex)
  197.     {
  198.         if (is_object($item))
  199.         {
  200.             $result array();
  201.  
  202.             foreach (get_object_vars($itemas $k => $v)
  203.             {
  204.                 if (!$regex || preg_match($regex$k))
  205.                 {
  206.                     if ($recurse)
  207.                     {
  208.                         $result[$kself::_fromObject($v$recurse$regex);
  209.                     }
  210.                     else
  211.                     {
  212.                         $result[$k$v;
  213.                     }
  214.                 }
  215.             }
  216.         }
  217.         elseif (is_array($item))
  218.         {
  219.             $result array();
  220.  
  221.             foreach ($item as $k => $v)
  222.             {
  223.                 $result[$kself::_fromObject($v$recurse$regex);
  224.             }
  225.         }
  226.         else
  227.         {
  228.             $result $item;
  229.         }
  230.         return $result;
  231.     }
  232.  
  233.     /**
  234.      * Extracts a column from an array of arrays or objects
  235.      *
  236.      * @param   array   &$array  The source array
  237.      * @param   string  $index   The index of the column or name of object property
  238.      *
  239.      * @return  array  Column of values from the source array
  240.      *
  241.      * @since   11.1
  242.      */
  243.     public static function getColumn(&$array$index)
  244.     {
  245.         $result array();
  246.  
  247.         if (is_array($array))
  248.         {
  249.             foreach ($array as &$item)
  250.             {
  251.                 if (is_array($item&& isset($item[$index]))
  252.                 {
  253.                     $result[$item[$index];
  254.                 }
  255.                 elseif (is_object($item&& isset($item->$index))
  256.                 {
  257.                     $result[$item->$index;
  258.                 }
  259.                 // Else ignore the entry
  260.             }
  261.         }
  262.         return $result;
  263.     }
  264.  
  265.     /**
  266.      * Utility function to return a value from a named array or a specified default
  267.      *
  268.      * @param   array   &$array   A named array
  269.      * @param   string  $name     The key to search for
  270.      * @param   mixed   $default  The default value to give if no key found
  271.      * @param   string  $type     Return type for the variable (INT, FLOAT, STRING, WORD, BOOLEAN, ARRAY)
  272.      *
  273.      * @return  mixed  The value from the source array
  274.      *
  275.      * @since   11.1
  276.      */
  277.     public static function getValue(&$array$name$default null$type '')
  278.     {
  279.         $result null;
  280.  
  281.         if (isset($array[$name]))
  282.         {
  283.             $result $array[$name];
  284.         }
  285.  
  286.         // Handle the default case
  287.         if (is_null($result))
  288.         {
  289.             $result $default;
  290.         }
  291.  
  292.         // Handle the type constraint
  293.         switch (strtoupper($type))
  294.         {
  295.             case 'INT':
  296.             case 'INTEGER':
  297.                 // Only use the first integer value
  298.                 @preg_match('/-?[0-9]+/'$result$matches);
  299.                 $result @(int) $matches[0];
  300.                 break;
  301.  
  302.             case 'FLOAT':
  303.             case 'DOUBLE':
  304.                 // Only use the first floating point value
  305.                 @preg_match('/-?[0-9]+(\.[0-9]+)?/'$result$matches);
  306.                 $result @(float) $matches[0];
  307.                 break;
  308.  
  309.             case 'BOOL':
  310.             case 'BOOLEAN':
  311.                 $result = (bool) $result;
  312.                 break;
  313.  
  314.             case 'ARRAY':
  315.                 if (!is_array($result))
  316.                 {
  317.                     $result array($result);
  318.                 }
  319.                 break;
  320.  
  321.             case 'STRING':
  322.                 $result = (string) $result;
  323.                 break;
  324.  
  325.             case 'WORD':
  326.                 $result = (string) preg_replace('#\W#'''$result);
  327.                 break;
  328.  
  329.             case 'NONE':
  330.             default:
  331.                 // No casting necessary
  332.                 break;
  333.         }
  334.         return $result;
  335.     }
  336.  
  337.     /**
  338.      * Takes an associative array of arrays and inverts the array keys to values using the array values as keys.
  339.      *
  340.      * Example:
  341.      * $input = array(
  342.      *     'New' => array('1000', '1500', '1750'),
  343.      *     'Used' => array('3000', '4000', '5000', '6000')
  344.      * );
  345.      * $output = JArrayHelper::invert($input);
  346.      *
  347.      * Output would be equal to:
  348.      * $output = array(
  349.      *     '1000' => 'New',
  350.      *     '1500' => 'New',
  351.      *     '1750' => 'New',
  352.      *     '3000' => 'Used',
  353.      *     '4000' => 'Used',
  354.      *     '5000' => 'Used',
  355.      *     '6000' => 'Used'
  356.      * );
  357.      *
  358.      * @param   array  $array  The source array.
  359.      *
  360.      * @return  array  The inverted array.
  361.      *
  362.      * @since   12.3
  363.      */
  364.     public static function invert($array)
  365.     {
  366.         $return array();
  367.  
  368.         foreach ($array as $base => $values)
  369.         {
  370.             if (!is_array($values))
  371.             {
  372.                 continue;
  373.             }
  374.  
  375.             foreach ($values as $key)
  376.             {
  377.                 // If the key isn't scalar then ignore it.
  378.                 if (is_scalar($key))
  379.                 {
  380.                     $return[$key$base;
  381.                 }
  382.             }
  383.         }
  384.         return $return;
  385.     }
  386.  
  387.     /**
  388.      * Method to determine if an array is an associative array.
  389.      *
  390.      * @param   array  $array  An array to test.
  391.      *
  392.      * @return  boolean  True if the array is an associative array.
  393.      *
  394.      * @since   11.1
  395.      */
  396.     public static function isAssociative($array)
  397.     {
  398.         if (is_array($array))
  399.         {
  400.             foreach (array_keys($arrayas $k => $v)
  401.             {
  402.                 if ($k !== $v)
  403.                 {
  404.                     return true;
  405.                 }
  406.             }
  407.         }
  408.  
  409.         return false;
  410.     }
  411.  
  412.     /**
  413.      * Pivots an array to create a reverse lookup of an array of scalars, arrays or objects.
  414.      *
  415.      * @param   array   $source  The source array.
  416.      * @param   string  $key     Where the elements of the source array are objects or arrays, the key to pivot on.
  417.      *
  418.      * @return  array  An array of arrays pivoted either on the value of the keys, or an individual key of an object or array.
  419.      *
  420.      * @since   11.3
  421.      */
  422.     public static function pivot($source$key null)
  423.     {
  424.         $result array();
  425.         $counter array();
  426.  
  427.         foreach ($source as $index => $value)
  428.         {
  429.             // Determine the name of the pivot key, and its value.
  430.             if (is_array($value))
  431.             {
  432.                 // If the key does not exist, ignore it.
  433.                 if (!isset($value[$key]))
  434.                 {
  435.                     continue;
  436.                 }
  437.  
  438.                 $resultKey $value[$key];
  439.                 $resultValue &$source[$index];
  440.             }
  441.             elseif (is_object($value))
  442.             {
  443.                 // If the key does not exist, ignore it.
  444.                 if (!isset($value->$key))
  445.                 {
  446.                     continue;
  447.                 }
  448.  
  449.                 $resultKey $value->$key;
  450.                 $resultValue &$source[$index];
  451.             }
  452.             else
  453.             {
  454.                 // Just a scalar value.
  455.                 $resultKey $value;
  456.                 $resultValue $index;
  457.             }
  458.  
  459.             // The counter tracks how many times a key has been used.
  460.             if (empty($counter[$resultKey]))
  461.             {
  462.                 // The first time around we just assign the value to the key.
  463.                 $result[$resultKey$resultValue;
  464.                 $counter[$resultKey1;
  465.             }
  466.             elseif ($counter[$resultKey== 1)
  467.             {
  468.                 // If there is a second time, we convert the value into an array.
  469.                 $result[$resultKeyarray(
  470.                     $result[$resultKey],
  471.                     $resultValue,
  472.                 );
  473.                 $counter[$resultKey]++;
  474.             }
  475.             else
  476.             {
  477.                 // After the second time, no need to track any more. Just append to the existing array.
  478.                 $result[$resultKey][$resultValue;
  479.             }
  480.         }
  481.  
  482.         unset($counter);
  483.  
  484.         return $result;
  485.     }
  486.  
  487.     /**
  488.      * Utility function to sort an array of objects on a given field
  489.      *
  490.      * @param   array  &$a             An array of objects
  491.      * @param   mixed  $k              The key (string) or a array of key to sort on
  492.      * @param   mixed  $direction      Direction (integer) or an array of direction to sort in [1 = Ascending] [-1 = Descending]
  493.      * @param   mixed  $caseSensitive  Boolean or array of booleans to let sort occur case sensitive or insensitive
  494.      * @param   mixed  $locale         Boolean or array of booleans to let sort occur using the locale language or not
  495.      *
  496.      * @return  array  The sorted array of objects
  497.      *
  498.      * @since   11.1
  499.      */
  500.     public static function sortObjects(&$a$k$direction 1$caseSensitive true$locale false)
  501.     {
  502.         if (!is_array($locale|| !is_array($locale[0]))
  503.         {
  504.             $locale array($locale);
  505.         }
  506.  
  507.         self::$sortCase = (array) $caseSensitive;
  508.         self::$sortDirection = (array) $direction;
  509.         self::$sortKey = (array) $k;
  510.         self::$sortLocale $locale;
  511.  
  512.         usort($aarray(__CLASS__'_sortObjects'));
  513.  
  514.         self::$sortCase null;
  515.         self::$sortDirection null;
  516.         self::$sortKey null;
  517.         self::$sortLocale null;
  518.  
  519.         return $a;
  520.     }
  521.  
  522.     /**
  523.      * Callback function for sorting an array of objects on a key
  524.      *
  525.      * @param   array  &$a  An array of objects
  526.      * @param   array  &$b  An array of objects
  527.      *
  528.      * @return  integer  Comparison status
  529.      *
  530.      * @see     JArrayHelper::sortObjects()
  531.      * @since   11.1
  532.      */
  533.     protected static function _sortObjects(&$a&$b)
  534.     {
  535.         $key self::$sortKey;
  536.  
  537.         for ($i 0$count count($key)$i $count$i++)
  538.         {
  539.             if (isset(self::$sortDirection[$i]))
  540.             {
  541.                 $direction self::$sortDirection[$i];
  542.             }
  543.  
  544.             if (isset(self::$sortCase[$i]))
  545.             {
  546.                 $caseSensitive self::$sortCase[$i];
  547.             }
  548.  
  549.             if (isset(self::$sortLocale[$i]))
  550.             {
  551.                 $locale self::$sortLocale[$i];
  552.             }
  553.  
  554.             $va $a->$key[$i];
  555.             $vb $b->$key[$i];
  556.  
  557.             if ((is_bool($va|| is_numeric($va)) && (is_bool($vb|| is_numeric($vb)))
  558.             {
  559.                 $cmp $va $vb;
  560.             }
  561.             elseif ($caseSensitive)
  562.             {
  563.                 $cmp JString::strcmp($va$vb$locale);
  564.             }
  565.             else
  566.             {
  567.                 $cmp JString::strcasecmp($va$vb$locale);
  568.             }
  569.  
  570.             if ($cmp 0)
  571.             {
  572.  
  573.                 return $direction;
  574.             }
  575.  
  576.             if ($cmp 0)
  577.             {
  578.                 return -$direction;
  579.             }
  580.         }
  581.  
  582.         return 0;
  583.     }
  584.  
  585.     /**
  586.      * Multidimensional array safe unique test
  587.      *
  588.      * @param   array  $myArray  The array to make unique.
  589.      *
  590.      * @return  array 
  591.      *
  592.      * @see     http://php.net/manual/en/function.array-unique.php
  593.      * @since   11.2
  594.      */
  595.     public static function arrayUnique($myArray)
  596.     {
  597.         if (!is_array($myArray))
  598.         {
  599.             return $myArray;
  600.         }
  601.  
  602.         foreach ($myArray as &$myvalue)
  603.         {
  604.             $myvalue serialize($myvalue);
  605.         }
  606.  
  607.         $myArray array_unique($myArray);
  608.  
  609.         foreach ($myArray as &$myvalue)
  610.         {
  611.             $myvalue unserialize($myvalue);
  612.         }
  613.  
  614.         return $myArray;
  615.     }
  616. }

Documentation generated on Tue, 19 Nov 2013 14:53:51 +0100 by phpDocumentor 1.4.3