diff --git a/lib/Horde/Array.php b/lib/Horde/Array.php index 4f46c56..5b899b3 100644 --- a/lib/Horde/Array.php +++ b/lib/Horde/Array.php @@ -1,4 +1,5 @@ key = $key; $function = $dir ? 'reverseCompare' : 'compare'; if ($assoc) { - uasort($array, array($helper, $function)); + uasort($array, [ $helper, $function ]); } else { - usort($array, array($helper, $function)); + usort($array, [ $helper, $function ]); } } @@ -62,7 +62,7 @@ public static function arraySort(array &$array, $key = null, $dir = 0, * @param string &$base Will be set to the base element. * @param array &$keys Will be set to the list of keys. * - * @return boolean True on sucess, false on error. + * @return boolean True on success, false on error. */ public static function getArrayParts($field, &$base, &$keys) { @@ -77,62 +77,90 @@ public static function getArrayParts($field, &$base, &$keys) return true; } + /** + * Given an HTML type array field "example[key1][key2][key3]" breaks up + * the keys into [ 'example', 'key1', 'key2', 'key3' ] so that they could be + * used to reference a regular PHP array. + * + * @param string $field The field name to be examined. + * + * @return array|null Array of keys, null on error. + */ + public static function getFieldParts($field) + { + if (preg_match('|^([^\[]*)((\[[^\[\]]*\])*)$|', $field, $matches)) { + $keys = [ $matches[1] ]; + if (strlen($matches[2])) { + $keys = array_merge($keys, explode('][', substr($matches[2], 1, -1))); + } + return $keys; + } + return null; + } + /** * Using an array of keys iterate through the array following the - * keys to find the final key value. If a value is passed then set - * that value. + * keys to find the final key value. * - * @param array &$array The array to be used. - * @param array &$keys The key path to follow as an array. - * @param array $value If set the target element will have this value set - * to it. + * @param array $array The array to be used. + * @param array|string $keys The key path to follow as an array or string. + * @param string $extraKey Additional key to add at position 1, if any. * - * @return mixed The final value of the key path. + * @return mixed The final value of the key path. */ - public static function getElement(&$array, array &$keys, $value = null) + public static function getElement(array $array, $keys, $extraKey = null) { - if (count($keys)) { - $key = array_shift($keys); - return isset($array[$key]) - ? self::getElement($array[$key], $keys, $value) - : false; + $ref = &$array; + + if (!is_array($keys)) { + $keys = [ $keys ]; + } + + if (isset($extraKey)) { + array_splice($keys, 1, 0, $extraKey); } - if (!is_null($value)) { - $array = $value; + foreach ($keys as $key) { + if (!isset($ref[$key])) { + return null; + } + $ref = &$ref[$key]; } - return $array; + return $ref; } /** * Using an array of keys iterate through the $array following the * nested $keys to find the final key's value. If a $value is passed then set * that value. If missing, create array levels along that path. - * Existing values in that path will be overwritten even if $value is null. - * - * @param array &$array The array to be used. - * @param array &$keys The key path to follow as an array. - * @param array $value Target element will have this value set - * to it. + * Existing value in that path will be overwritten. * - * @return mixed The final value of the key path. + * @param array &$array The array to be used. + * @param array|string $keys The key path to follow as an array or string. + * @param mixed $value Target element will have this value set to it. + * @param string $extraKey Additional key to add at position 1, if any. */ - public static function setElement(&$array, array &$keys, $value = null) + public static function setElement(array &$array, $keys, $value, $extraKey = null) { - if (count($keys)) { - $key = array_shift($keys); - if (!isset($array[$key])) { - $array[$key] = array(); - } - return isset($array[$key]) - ? self::setElement($array[$key], $keys, $value) - : false; + $ref = &$array; + + if (!is_array($keys)) { + $keys = [ $keys ]; + } + + if (isset($extraKey)) { + array_splice($keys, 1, 0, $extraKey); } - $array = $value; + foreach ($keys as $key) { + if (!isset($ref[$key])) { + $ref[$key] = []; + } + $ref = &$ref[$key]; + } - return $array; + $ref = $value; } /** @@ -146,10 +174,9 @@ public static function setElement(&$array, array &$keys, $value = null) * * @return array The extracted rectangle. */ - public static function getRectangle(array $array, $row, $col, $height, - $width) + public static function getRectangle(array $array, $row, $col, $height, $width) { - $rec = array(); + $rec = []; for ($y = $row; $y < $row + $height; $y++) { $rec[] = array_slice($array[$y], $col, $width); } @@ -160,9 +187,9 @@ public static function getRectangle(array $array, $row, $col, $height, * Given an array, returns an associative array with each element key * derived from its value. * For example: - * array(0 => 'foo', 1 => 'bar') + * [ 0 => 'foo', 1 => 'bar' ] * would become: - * array('foo' => 'foo', 'bar' => 'bar') + * [ 'foo' => 'foo', 'bar' => 'bar' ] * * @param array $array An array of values. * @@ -172,6 +199,6 @@ public static function valuesToKeys(array $array) { return $array ? array_combine($array, $array) - : array(); + : []; } } diff --git a/src/ArrayUtils.php b/src/ArrayUtils.php index e1ff2b3..c8867dd 100644 --- a/src/ArrayUtils.php +++ b/src/ArrayUtils.php @@ -38,8 +38,7 @@ public static function arraySort( $key = null, $dir = 0, $assoc = true - ) - { + ) { /* Return if the array is empty. */ if (empty($array)) { return; @@ -86,61 +85,90 @@ public static function getArrayParts($field, &$base, &$keys) return true; } + /** + * Given an HTML type array field "example[key1][key2][key3]" breaks up + * the keys into [ 'example', 'key1', 'key2', 'key3' ] so that they could be + * used to reference a regular PHP array. + * + * @param string $field The field name to be examined. + * + * @return array|null Array of keys, null on error. + */ + public static function getFieldParts($field) + { + if (preg_match('|^([^\[]*)((\[[^\[\]]*\])*)$|', $field, $matches)) { + $keys = [ $matches[1] ]; + if (strlen($matches[2])) { + $keys = array_merge($keys, explode('][', substr($matches[2], 1, -1))); + } + return $keys; + } + return null; + } + /** * Using an array of keys iterate through the array following the - * keys to find the final key value. If a value is passed then set - * that value. + * keys to find the final key value. * - * @param array &$array The array to be used. - * @param array &$keys The key path to follow as an array. - * @param array $value If set the target element will have this value set - * to it. + * @param array $array The array to be used. + * @param array|string $keys The key path to follow as an array or string. + * @param string $extraKey Additional key to add at position 1, if any. * - * @return mixed The final value of the key path. + * @return mixed The final value of the key path. */ - public static function getElement(&$array, array &$keys, $value = null) + public static function getElement(array $array, $keys, $extraKey = null) { - if (count($keys)) { - $key = array_shift($keys); - return isset($array[$key]) - ? self::getElement($array[$key], $keys, $value) - : false; + $ref = &$array; + + if (!is_array($keys)) { + $keys = [ $keys ]; } - if (!is_null($value)) { - $array = $value; + if (isset($extraKey)) { + array_splice($keys, 1, 0, $extraKey); } - return $array; + foreach ($keys as $key) { + if (!isset($ref[$key])) { + return null; + } + $ref = &$ref[$key]; + } + + return $ref; } + /** * Using an array of keys iterate through the $array following the * nested $keys to find the final key's value. If a $value is passed then set * that value. If missing, create array levels along that path. - * Existing values in that path will be overwritten even if $value is null. + * Existing value in that path will be overwritten. * - * @param array &$array The array to be used. - * @param array &$keys The key path to follow as an array. - * @param array $value Target element will have this value set - * to it. - * - * @return mixed The final value of the key path. + * @param array &$array The array to be used. + * @param array|string $keys The key path to follow as an array or string. + * @param mixed $value Target element will have this value set to it. + * @param string $extraKey Additional key to add at position 1, if any. */ - public static function setElement(&$array, array &$keys, $value = null) + public static function setElement(array &$array, $keys, $value, $extraKey = null) { - if (count($keys)) { - $key = array_shift($keys); - if (!isset($array[$key])) { - $array[$key] = array(); - } - return isset($array[$key]) - ? self::setElement($array[$key], $keys, $value) - : false; + $ref = &$array; + + if (!is_array($keys)) { + $keys = [ $keys ]; + } + + if (isset($extraKey)) { + array_splice($keys, 1, 0, $extraKey); } - $array = $value; + foreach ($keys as $key) { + if (!isset($ref[$key])) { + $ref[$key] = []; + } + $ref = &$ref[$key]; + } - return $array; + $ref = $value; } /** @@ -160,8 +188,7 @@ public static function getRectangle( $col, $height, $width - ) - { + ) { $rec = []; for ($y = $row; $y < $row + $height; $y++) { $rec[] = array_slice($array[$y], $col, $width);