[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/joomla/utilities/src/ -> ArrayHelper.php (source)

   1  <?php
   2  /**
   3   * Part of the Joomla Framework Utilities Package
   4   *
   5   * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved.
   6   * @license    GNU General Public License version 2 or later; see LICENSE
   7   */
   8  
   9  namespace Joomla\Utilities;
  10  
  11  use Joomla\String\StringHelper;
  12  
  13  /**
  14   * ArrayHelper is an array utility class for doing all sorts of odds and ends with arrays.
  15   *
  16   * @since  1.0
  17   */
  18  final class ArrayHelper
  19  {
  20      /**
  21       * Private constructor to prevent instantiation of this class
  22       *
  23       * @since   1.0
  24       */
  25  	private function __construct()
  26      {
  27      }
  28  
  29      /**
  30       * Function to convert array to integer values
  31       *
  32       * @param   array      $array    The source array to convert
  33       * @param   int|array  $default  A default value to assign if $array is not an array
  34       *
  35       * @return  array
  36       *
  37       * @since   1.0
  38       */
  39  	public static function toInteger($array, $default = null)
  40      {
  41          if (\is_array($array))
  42          {
  43              return array_map('intval', $array);
  44          }
  45  
  46          if ($default === null)
  47          {
  48              return [];
  49          }
  50  
  51          if (\is_array($default))
  52          {
  53              return static::toInteger($default, null);
  54          }
  55  
  56          return [(int) $default];
  57      }
  58  
  59      /**
  60       * Utility function to map an array to a stdClass object.
  61       *
  62       * @param   array    $array      The array to map.
  63       * @param   string   $class      Name of the class to create
  64       * @param   boolean  $recursive  Convert also any array inside the main array
  65       *
  66       * @return  object
  67       *
  68       * @since   1.0
  69       */
  70  	public static function toObject(array $array, $class = 'stdClass', $recursive = true)
  71      {
  72          $obj = new $class;
  73  
  74          foreach ($array as $k => $v)
  75          {
  76              if ($recursive && \is_array($v))
  77              {
  78                  $obj->$k = static::toObject($v, $class);
  79              }
  80              else
  81              {
  82                  $obj->$k = $v;
  83              }
  84          }
  85  
  86          return $obj;
  87      }
  88  
  89      /**
  90       * Utility function to map an array to a string.
  91       *
  92       * @param   array    $array         The array to map.
  93       * @param   string   $innerGlue     The glue (optional, defaults to '=') between the key and the value.
  94       * @param   string   $outerGlue     The glue (optional, defaults to ' ') between array elements.
  95       * @param   boolean  $keepOuterKey  True if final key should be kept.
  96       *
  97       * @return  string
  98       *
  99       * @since   1.0
 100       */
 101  	public static function toString(array $array, $innerGlue = '=', $outerGlue = ' ', $keepOuterKey = false)
 102      {
 103          $output = [];
 104  
 105          foreach ($array as $key => $item)
 106          {
 107              if (\is_array($item))
 108              {
 109                  if ($keepOuterKey)
 110                  {
 111                      $output[] = $key;
 112                  }
 113  
 114                  // This is value is an array, go and do it again!
 115                  $output[] = static::toString($item, $innerGlue, $outerGlue, $keepOuterKey);
 116              }
 117              else
 118              {
 119                  $output[] = $key . $innerGlue . '"' . $item . '"';
 120              }
 121          }
 122  
 123          return implode($outerGlue, $output);
 124      }
 125  
 126      /**
 127       * Utility function to map an object to an array
 128       *
 129       * @param   object   $source   The source object
 130       * @param   boolean  $recurse  True to recurse through multi-level objects
 131       * @param   string   $regex    An optional regular expression to match on field names
 132       *
 133       * @return  array
 134       *
 135       * @since   1.0
 136       */
 137  	public static function fromObject($source, $recurse = true, $regex = null)
 138      {
 139          if (\is_object($source) || \is_array($source))
 140          {
 141              return self::arrayFromObject($source, $recurse, $regex);
 142          }
 143  
 144          return [];
 145      }
 146  
 147      /**
 148       * Utility function to map an object or array to an array
 149       *
 150       * @param   mixed    $item     The source object or array
 151       * @param   boolean  $recurse  True to recurse through multi-level objects
 152       * @param   string   $regex    An optional regular expression to match on field names
 153       *
 154       * @return  array
 155       *
 156       * @since   1.0
 157       */
 158  	private static function arrayFromObject($item, $recurse, $regex)
 159      {
 160          if (\is_object($item))
 161          {
 162              $result = [];
 163  
 164              foreach (get_object_vars($item) as $k => $v)
 165              {
 166                  if (!$regex || preg_match($regex, $k))
 167                  {
 168                      if ($recurse)
 169                      {
 170                          $result[$k] = self::arrayFromObject($v, $recurse, $regex);
 171                      }
 172                      else
 173                      {
 174                          $result[$k] = $v;
 175                      }
 176                  }
 177              }
 178  
 179              return $result;
 180          }
 181  
 182          if (\is_array($item))
 183          {
 184              $result = [];
 185  
 186              foreach ($item as $k => $v)
 187              {
 188                  $result[$k] = self::arrayFromObject($v, $recurse, $regex);
 189              }
 190  
 191              return $result;
 192          }
 193  
 194          return $item;
 195      }
 196  
 197      /**
 198       * Adds a column to an array of arrays or objects
 199       *
 200       * @param   array   $array    The source array
 201       * @param   array   $column   The array to be used as new column
 202       * @param   string  $colName  The index of the new column or name of the new object property
 203       * @param   string  $keyCol   The index of the column or name of object property to be used for mapping with the new column
 204       *
 205       * @return  array  An array with the new column added to the source array
 206       *
 207       * @since   1.5.0
 208       * @see     https://www.php.net/manual/en/language.types.array.php
 209       */
 210  	public static function addColumn(array $array, array $column, $colName, $keyCol = null)
 211      {
 212          $result = [];
 213  
 214          foreach ($array as $i => $item)
 215          {
 216              $value = null;
 217  
 218              if (!isset($keyCol))
 219              {
 220                  $value = static::getValue($column, $i);
 221              }
 222              else
 223              {
 224                  // Convert object to array
 225                  $subject = \is_object($item) ? static::fromObject($item) : $item;
 226  
 227                  if (isset($subject[$keyCol]) && is_scalar($subject[$keyCol]))
 228                  {
 229                      $value = static::getValue($column, $subject[$keyCol]);
 230                  }
 231              }
 232  
 233              // Add the column
 234              if (\is_object($item))
 235              {
 236                  if (isset($colName))
 237                  {
 238                      $item->$colName = $value;
 239                  }
 240              }
 241              else
 242              {
 243                  if (isset($colName))
 244                  {
 245                      $item[$colName] = $value;
 246                  }
 247                  else
 248                  {
 249                      $item[] = $value;
 250                  }
 251              }
 252  
 253              $result[$i] = $item;
 254          }
 255  
 256          return $result;
 257      }
 258  
 259      /**
 260       * Remove a column from an array of arrays or objects
 261       *
 262       * @param   array   $array    The source array
 263       * @param   string  $colName  The index of the column or name of object property to be removed
 264       *
 265       * @return  array  Column of values from the source array
 266       *
 267       * @since   1.5.0
 268       * @see     https://www.php.net/manual/en/language.types.array.php
 269       */
 270  	public static function dropColumn(array $array, $colName)
 271      {
 272          $result = [];
 273  
 274          foreach ($array as $i => $item)
 275          {
 276              if (\is_object($item) && isset($item->$colName))
 277              {
 278                  unset($item->$colName);
 279              }
 280              elseif (\is_array($item) && isset($item[$colName]))
 281              {
 282                  unset($item[$colName]);
 283              }
 284  
 285              $result[$i] = $item;
 286          }
 287  
 288          return $result;
 289      }
 290  
 291      /**
 292       * Extracts a column from an array of arrays or objects
 293       *
 294       * @param   array   $array     The source array
 295       * @param   string  $valueCol  The index of the column or name of object property to be used as value
 296       *                             It may also be NULL to return complete arrays or objects (this is
 297       *                             useful together with <var>$keyCol</var> to reindex the array).
 298       * @param   string  $keyCol    The index of the column or name of object property to be used as key
 299       *
 300       * @return  array  Column of values from the source array
 301       *
 302       * @since   1.0
 303       * @see     https://www.php.net/manual/en/language.types.array.php
 304       * @see     https://www.php.net/manual/en/function.array-column.php
 305       */
 306  	public static function getColumn(array $array, $valueCol, $keyCol = null)
 307      {
 308          return array_column($array, $valueCol, $keyCol);
 309      }
 310  
 311      /**
 312       * Utility function to return a value from a named array or a specified default
 313       *
 314       * @param   array|\ArrayAccess  $array    A named array or object that implements ArrayAccess
 315       * @param   string              $name     The key to search for (this can be an array index or a dot separated key sequence as in Registry)
 316       * @param   mixed               $default  The default value to give if no key found
 317       * @param   string              $type     Return type for the variable (INT, FLOAT, STRING, WORD, BOOLEAN, ARRAY)
 318       *
 319       * @return  mixed
 320       *
 321       * @since   1.0
 322       * @throws  \InvalidArgumentException
 323       */
 324  	public static function getValue($array, $name, $default = null, $type = '')
 325      {
 326          if (!\is_array($array) && !($array instanceof \ArrayAccess))
 327          {
 328              throw new \InvalidArgumentException('The object must be an array or an object that implements ArrayAccess');
 329          }
 330  
 331          $result = null;
 332  
 333          if (isset($array[$name]))
 334          {
 335              $result = $array[$name];
 336          }
 337          elseif (strpos($name, '.'))
 338          {
 339              list($name, $subset) = explode('.', $name, 2);
 340  
 341              if (isset($array[$name]) && \is_array($array[$name]))
 342              {
 343                  return static::getValue($array[$name], $subset, $default, $type);
 344              }
 345          }
 346  
 347          // Handle the default case
 348          if ($result === null)
 349          {
 350              $result = $default;
 351          }
 352  
 353          // Handle the type constraint
 354          switch (strtoupper($type))
 355          {
 356              case 'INT':
 357              case 'INTEGER':
 358                  // Only use the first integer value
 359                  @preg_match('/-?[0-9]+/', $result, $matches);
 360                  $result = @(int) $matches[0];
 361  
 362                  break;
 363  
 364              case 'FLOAT':
 365              case 'DOUBLE':
 366                  // Only use the first floating point value
 367                  @preg_match('/-?[0-9]+(\.[0-9]+)?/', $result, $matches);
 368                  $result = @(float) $matches[0];
 369  
 370                  break;
 371  
 372              case 'BOOL':
 373              case 'BOOLEAN':
 374                  $result = (bool) $result;
 375  
 376                  break;
 377  
 378              case 'ARRAY':
 379                  if (!\is_array($result))
 380                  {
 381                      $result = [$result];
 382                  }
 383  
 384                  break;
 385  
 386              case 'STRING':
 387                  $result = (string) $result;
 388  
 389                  break;
 390  
 391              case 'WORD':
 392                  $result = (string) preg_replace('#\W#', '', $result);
 393  
 394                  break;
 395  
 396              case 'NONE':
 397              default:
 398                  // No casting necessary
 399                  break;
 400          }
 401  
 402          return $result;
 403      }
 404  
 405      /**
 406       * Takes an associative array of arrays and inverts the array keys to values using the array values as keys.
 407       *
 408       * Example:
 409       * $input = array(
 410       *     'New' => array('1000', '1500', '1750'),
 411       *     'Used' => array('3000', '4000', '5000', '6000')
 412       * );
 413       * $output = ArrayHelper::invert($input);
 414       *
 415       * Output would be equal to:
 416       * $output = array(
 417       *     '1000' => 'New',
 418       *     '1500' => 'New',
 419       *     '1750' => 'New',
 420       *     '3000' => 'Used',
 421       *     '4000' => 'Used',
 422       *     '5000' => 'Used',
 423       *     '6000' => 'Used'
 424       * );
 425       *
 426       * @param   array  $array  The source array.
 427       *
 428       * @return  array
 429       *
 430       * @since   1.0
 431       */
 432  	public static function invert(array $array)
 433      {
 434          $return = [];
 435  
 436          foreach ($array as $base => $values)
 437          {
 438              if (!\is_array($values))
 439              {
 440                  continue;
 441              }
 442  
 443              foreach ($values as $key)
 444              {
 445                  // If the key isn't scalar then ignore it.
 446                  if (is_scalar($key))
 447                  {
 448                      $return[$key] = $base;
 449                  }
 450              }
 451          }
 452  
 453          return $return;
 454      }
 455  
 456      /**
 457       * Method to determine if an array is an associative array.
 458       *
 459       * @param   array  $array  An array to test.
 460       *
 461       * @return  boolean
 462       *
 463       * @since   1.0
 464       */
 465  	public static function isAssociative($array)
 466      {
 467          if (\is_array($array))
 468          {
 469              foreach (array_keys($array) as $k => $v)
 470              {
 471                  if ($k !== $v)
 472                  {
 473                      return true;
 474                  }
 475              }
 476          }
 477  
 478          return false;
 479      }
 480  
 481      /**
 482       * Pivots an array to create a reverse lookup of an array of scalars, arrays or objects.
 483       *
 484       * @param   array   $source  The source array.
 485       * @param   string  $key     Where the elements of the source array are objects or arrays, the key to pivot on.
 486       *
 487       * @return  array  An array of arrays pivoted either on the value of the keys, or an individual key of an object or array.
 488       *
 489       * @since   1.0
 490       */
 491  	public static function pivot(array $source, $key = null)
 492      {
 493          $result  = [];
 494          $counter = [];
 495  
 496          foreach ($source as $index => $value)
 497          {
 498              // Determine the name of the pivot key, and its value.
 499              if (\is_array($value))
 500              {
 501                  // If the key does not exist, ignore it.
 502                  if (!isset($value[$key]))
 503                  {
 504                      continue;
 505                  }
 506  
 507                  $resultKey   = $value[$key];
 508                  $resultValue = $source[$index];
 509              }
 510              elseif (\is_object($value))
 511              {
 512                  // If the key does not exist, ignore it.
 513                  if (!isset($value->$key))
 514                  {
 515                      continue;
 516                  }
 517  
 518                  $resultKey   = $value->$key;
 519                  $resultValue = $source[$index];
 520              }
 521              else
 522              {
 523                  // Just a scalar value.
 524                  $resultKey   = $value;
 525                  $resultValue = $index;
 526              }
 527  
 528              // The counter tracks how many times a key has been used.
 529              if (empty($counter[$resultKey]))
 530              {
 531                  // The first time around we just assign the value to the key.
 532                  $result[$resultKey]  = $resultValue;
 533                  $counter[$resultKey] = 1;
 534              }
 535              elseif ($counter[$resultKey] == 1)
 536              {
 537                  // If there is a second time, we convert the value into an array.
 538                  $result[$resultKey] = [
 539                      $result[$resultKey],
 540                      $resultValue,
 541                  ];
 542                  $counter[$resultKey]++;
 543              }
 544              else
 545              {
 546                  // After the second time, no need to track any more. Just append to the existing array.
 547                  $result[$resultKey][] = $resultValue;
 548              }
 549          }
 550  
 551          unset($counter);
 552  
 553          return $result;
 554      }
 555  
 556      /**
 557       * Utility function to sort an array of objects on a given field
 558       *
 559       * @param   array  $a              An array of objects
 560       * @param   mixed  $k              The key (string) or an array of keys to sort on
 561       * @param   mixed  $direction      Direction (integer) or an array of direction to sort in [1 = Ascending] [-1 = Descending]
 562       * @param   mixed  $caseSensitive  Boolean or array of booleans to let sort occur case sensitive or insensitive
 563       * @param   mixed  $locale         Boolean or array of booleans to let sort occur using the locale language or not
 564       *
 565       * @return  array
 566       *
 567       * @since   1.0
 568       */
 569  	public static function sortObjects(array $a, $k, $direction = 1, $caseSensitive = true, $locale = false)
 570      {
 571          if (!\is_array($locale) || !\is_array($locale[0]))
 572          {
 573              $locale = [$locale];
 574          }
 575  
 576          $sortCase      = (array) $caseSensitive;
 577          $sortDirection = (array) $direction;
 578          $key           = (array) $k;
 579          $sortLocale    = $locale;
 580  
 581          usort(
 582              $a, function ($a, $b) use ($sortCase, $sortDirection, $key, $sortLocale)
 583              {
 584                  for ($i = 0, $count = \count($key); $i < $count; $i++)
 585                  {
 586                      if (isset($sortDirection[$i]))
 587                      {
 588                          $direction = $sortDirection[$i];
 589                      }
 590  
 591                      if (isset($sortCase[$i]))
 592                      {
 593                          $caseSensitive = $sortCase[$i];
 594                      }
 595  
 596                      if (isset($sortLocale[$i]))
 597                      {
 598                          $locale = $sortLocale[$i];
 599                      }
 600  
 601                      $va = $a->{$key[$i]};
 602                      $vb = $b->{$key[$i]};
 603  
 604                      if ((\is_bool($va) || is_numeric($va)) && (\is_bool($vb) || is_numeric($vb)))
 605                      {
 606                          $cmp = $va - $vb;
 607                      }
 608                      elseif ($caseSensitive)
 609                      {
 610                          $cmp = StringHelper::strcmp($va, $vb, $locale);
 611                      }
 612                      else
 613                      {
 614                          $cmp = StringHelper::strcasecmp($va, $vb, $locale);
 615                      }
 616  
 617                      if ($cmp > 0)
 618                      {
 619                          return $direction;
 620                      }
 621  
 622                      if ($cmp < 0)
 623                      {
 624                          return -$direction;
 625                      }
 626                  }
 627  
 628                  return 0;
 629              }
 630          );
 631  
 632          return $a;
 633      }
 634  
 635      /**
 636       * Multidimensional array safe unique test
 637       *
 638       * @param   array  $array  The array to make unique.
 639       *
 640       * @return  array
 641       *
 642       * @see     https://www.php.net/manual/en/function.array-unique.php
 643       * @since   1.0
 644       */
 645  	public static function arrayUnique(array $array)
 646      {
 647          $array = array_map('serialize', $array);
 648          $array = array_unique($array);
 649          $array = array_map('unserialize', $array);
 650  
 651          return $array;
 652      }
 653  
 654      /**
 655       * An improved array_search that allows for partial matching of strings values in associative arrays.
 656       *
 657       * @param   string   $needle         The text to search for within the array.
 658       * @param   array    $haystack       Associative array to search in to find $needle.
 659       * @param   boolean  $caseSensitive  True to search case sensitive, false otherwise.
 660       *
 661       * @return  mixed    Returns the matching array $key if found, otherwise false.
 662       *
 663       * @since   1.0
 664       */
 665  	public static function arraySearch($needle, array $haystack, $caseSensitive = true)
 666      {
 667          foreach ($haystack as $key => $value)
 668          {
 669              $searchFunc = ($caseSensitive) ? 'strpos' : 'stripos';
 670  
 671              if ($searchFunc($value, $needle) === 0)
 672              {
 673                  return $key;
 674              }
 675          }
 676  
 677          return false;
 678      }
 679  
 680      /**
 681       * Method to recursively convert data to a one dimension array.
 682       *
 683       * @param   array|object  $array      The array or object to convert.
 684       * @param   string        $separator  The key separator.
 685       * @param   string        $prefix     Last level key prefix.
 686       *
 687       * @return  array
 688       *
 689       * @since   1.3.0
 690       */
 691  	public static function flatten($array, $separator = '.', $prefix = '')
 692      {
 693          if ($array instanceof \Traversable)
 694          {
 695              $array = iterator_to_array($array);
 696          }
 697          elseif (\is_object($array))
 698          {
 699              $array = get_object_vars($array);
 700          }
 701  
 702          $result = [];
 703  
 704          foreach ($array as $k => $v)
 705          {
 706              $key = $prefix ? $prefix . $separator . $k : $k;
 707  
 708              if (\is_object($v) || \is_array($v))
 709              {
 710                  $result[] = static::flatten($v, $separator, $key);
 711              }
 712              else
 713              {
 714                  $result[] = [$key => $v];
 715              }
 716          }
 717  
 718          return array_merge(...$result);
 719      }
 720  
 721      /**
 722       * Merge array recursively.
 723       *
 724       * @param   array  ...$args  Array list to be merged.
 725       *
 726       * @return  array  Merged array.
 727       *
 728       * @since   2.0.0
 729       * @throws  \InvalidArgumentException
 730       */
 731  	public static function mergeRecursive(...$args): array
 732      {
 733          $result = [];
 734  
 735          foreach ($args as $i => $array)
 736          {
 737              if (!\is_array($array))
 738              {
 739                  throw new \InvalidArgumentException(sprintf('Argument #%d is not an array.', $i + 2));
 740              }
 741  
 742              foreach ($array as $key => &$value)
 743              {
 744                  if (\is_array($value) && isset($result[$key]) && \is_array($result[$key]))
 745                  {
 746                      $result[$key] = static::mergeRecursive($result [$key], $value);
 747                  }
 748                  else
 749                  {
 750                      $result[$key] = $value;
 751                  }
 752              }
 753          }
 754  
 755          return $result;
 756      }
 757  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer