$new_key) { $object[$new_key] = $object[$old_key]; } } unset($object); return $array; } /** * Get from array only values with given keys. * If requested key is not in given array exception is thrown. * * @static * @throws InvalidArgumentException * * @param array $array * @param array $keys * * @return array */ public static function getByKeysStrict(array $array, array $keys) { $result = []; foreach ($keys as $key) { if (!isset($array[$key])) { throw new InvalidArgumentException(sprintf('Array does not have element with key "%1$s".', $key)); } $result[$key] = $array[$key]; } return $result; } /** * Get values with the $keys from $array. * If the requested key is not in the given array it is skipped. * * @static * * @param array $array * @param array $keys * * @return array */ public static function getByKeys(array $array, array $keys) { $result = []; foreach ($keys as $key) { if (array_key_exists($key, $array)) { $result[$key] = $array[$key]; } } return $result; } /** * Select sub-array of array items with keys in given numeric range. * * @static * * @param array $array Array with numeric keys to test for given range. * @param int $start Range start value. * @param int $end Range end value. * * @return array */ public static function getByKeysRange(array $array, $start, $end) { $result = []; foreach ($array as $key => $val) { if ($key >= $start && $key <= $end) { $result[$key] = $val; } } return $result; } /** * Renames array elements keys according to given map. * * @param array $array * @param array $field_map * * @return array */ public static function renameKeys(array $array, array $field_map) { foreach ($field_map as $old_key => $new_key) { if (array_key_exists($old_key, $array)) { $array[$new_key] = $array[$old_key]; unset($array[$old_key]); } } return $array; } /** * Renames keys according to given map for given array of the objects. * * @param array $array * @param array $field_map * * @return array */ public static function renameObjectsKeys(array $array, array $field_map) { foreach ($array as &$object) { foreach ($field_map as $old_key => $new_key) { $object[$new_key] = $object[$old_key]; unset($object[$old_key]); } } unset($object); return $array; } /** * Sort array by multiple fields. * * @static * * @param array $array array to sort passed by reference * @param array $fields fields to sort, can be either string with field name or array with 'field' and 'order' keys */ public static function sort(array &$array, array $fields) { foreach ($fields as $fid => $field) { if (!is_array($field)) { $fields[$fid] = ['field' => $field, 'order' => ZBX_SORT_UP]; } } self::$fields = $fields; uasort($array, [self::class, 'compare']); } /** * Method to be used as callback for uasort function in sort method. * * @TODO: with PHP 5.3+ this should be changed to closure * @static * * @param $a * @param $b * * @return int */ protected static function compare($a, $b) { foreach (self::$fields as $field) { // if field is not set or is null, treat it as smallest string // strnatcasecmp() has unexpected behaviour with null values if (!isset($a[$field['field']]) && !isset($b[$field['field']])) { $cmp = 0; } elseif (!isset($a[$field['field']])) { $cmp = -1; } elseif (!isset($b[$field['field']])) { $cmp = 1; } else { $cmp = strnatcasecmp($a[$field['field']], $b[$field['field']]); } if ($cmp != 0) { return $cmp * ($field['order'] == ZBX_SORT_UP?1:-1); } } return 0; } /** * Sort array by keys in ascending order. * Performs case-insensitive string comparisons using a "natural order" algorithm. * * @param array $array */ public static function ksort(array &$array): void { uksort($array, 'strnatcasecmp'); } /** * Unset values that are contained in $a2 from $a1. Skip arrays and keys given in $skipKeys. * * @param array $a1 array to modify * @param array $a2 array to compare with * @param array $skipKeys fields to ignore * * @return array */ public static function unsetEqualValues(array $a1, array $a2, array $skipKeys = []) { // ignore given fields foreach ($skipKeys as $key) { unset($a2[$key]); } foreach ($a1 as $key => $value) { // check if the values under $key are equal, skip arrays if (isset($a2[$key]) && !is_array($value) && !is_array($a2[$key]) && (string) $a1[$key] === (string) $a2[$key]) { unset($a1[$key]); } } return $a1; } /** * Checks if array $arrays contains arrays with duplicate values under the $uniqueField key. If a duplicate exists, * returns the first duplicate, otherwise returns null. * * Example 1: * $data = array( * array('name' => 'CPU load'), * array('name' => 'CPU load'), * array('name' => 'Free memory') * ); * var_dump(CArrayHelper::findDuplicate($data, 'name')); // returns array with index 1 * * Example 2: * $data = array( * array('host' => 'Zabbix server', 'name' => 'CPU load'), * array('host' => 'Zabbix server', 'name' => 'Free memory'), * array('host' => 'Linux server', 'name' => 'CPU load'), * array('host' => 'Zabbix server', 'name' => 'CPU load') * ); * var_dump(CArrayHelper::findDuplicate($data, 'name', 'host')); // returns array with index 3 * * @param array $arrays an array of arrays * @param string $uniqueField key to be used as unique criteria * @param string $uniqueField2 second key to be used as unique criteria * * @return null|array the first duplicate found or null if there are no duplicates */ public static function findDuplicate(array $arrays, $uniqueField, $uniqueField2 = null) { $uniqueValues = []; foreach ($arrays as $array) { $value = $array[$uniqueField]; if ($uniqueField2 !== null) { $uniqueByValue = $array[$uniqueField2]; if (isset($uniqueValues[$uniqueByValue]) && isset($uniqueValues[$uniqueByValue][$value])) { return $array; } $uniqueValues[$uniqueByValue][$value] = $value; } else { if (isset($uniqueValues[$value])) { return $array; } $uniqueValues[$value] = $value; } } } /** * Sort an array of objects so that the objects whose $field value matches $pattern are at the top. Return the first * $limit objects. * * @param array $array Array of objects to sort. * @param string $field Name of the field to search. * @param string $pattern String to match the value against $field. * @param int $limit Number of objects to return. * * @return array */ public static function sortByPattern(array $array, $field, $pattern, $limit) { $chunk_size = $limit; $result = []; foreach ($array as $key => $value) { if (mb_strtolower($value[$field]) === mb_strtolower($pattern)) { $result = [$key => $value] + $result; } elseif ($limit > 0) { $result[$key] = $value; } else { continue; } $limit--; } if ($result) { $result = array_chunk($result, $chunk_size, true); $result = $result[0]; } return $result; } /** * Check if given array is hash or just normal indexed array. * * @param array $value * * @return bool true if value is hash array, false otherwise */ public static function isHash($value): bool { $expectedKey = 0; foreach ($value as $key => $val) { if ($key !== $expectedKey++) { return true; } } return false; } }