Initial Commit
This commit is contained in:
7
dependencies/rpnzl/arrch/license.txt
vendored
Normal file
7
dependencies/rpnzl/arrch/license.txt
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
Copyright (c) 2012 Michael Giuliana
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
319
dependencies/rpnzl/arrch/src/Arrch/Arrch.php
vendored
Normal file
319
dependencies/rpnzl/arrch/src/Arrch/Arrch.php
vendored
Normal file
@ -0,0 +1,319 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\Arrch;
|
||||
|
||||
/**
|
||||
* Arrch
|
||||
*
|
||||
* @copyright 2012 - 2013
|
||||
* @author Michael Giuliana
|
||||
* @link http://rpnzl.com
|
||||
* @version 1.1.0
|
||||
* @since 2013/5
|
||||
* @license MIT License - http://opensource.org/licenses/MIT
|
||||
*
|
||||
* A small library of array search and sort methods. Perhaps most
|
||||
* useful paired with a simple, flat-file storage system, Arrch
|
||||
* allows psuedo-queries of large arrays.
|
||||
*
|
||||
*/
|
||||
class Arrch
|
||||
{
|
||||
/**
|
||||
* @var arr $defaults The find() method default values.
|
||||
*/
|
||||
public static $defaults = array('where' => array(), 'limit' => 0, 'offset' => 0, 'sort_key' => null, 'sort_order' => 'ASC');
|
||||
/**
|
||||
* @var str $key_split The string to split keys when checking a deep multidimensional array value.
|
||||
*/
|
||||
public static $key_split = '.';
|
||||
/**
|
||||
* @var arr $operators A list of valid operators for comparisons.
|
||||
*/
|
||||
public static $operators = array('==', '===', '!=', '!==', '>', '<', '>=', '<=', '~', '!~');
|
||||
/**
|
||||
* This method combines the functionality of the where() and sort() methods,
|
||||
* with additional limit and offset parameters. Returns an array of matching
|
||||
* array items. Will only sort if a sort key is set.
|
||||
*
|
||||
* @param arr $data The array of objects or associative arrays to search.
|
||||
* @param arr $options The query options, see Arrch::$defaults.
|
||||
* @param misc $key An item's key or index value.
|
||||
* @return arr The result array.
|
||||
*/
|
||||
public static function find(array $data, array $options = array(), $key = 'all')
|
||||
{
|
||||
$options = static::merge(static::$defaults, $options);
|
||||
$data = static::where($data, $options['where']);
|
||||
$data = $options['sort_key'] ? static::sort($data, $options['sort_key'], $options['sort_order']) : $data;
|
||||
$data = \array_slice($data, $options['offset'], $options['limit'] == 0 ? null : $options['limit'], \true);
|
||||
switch ($key) {
|
||||
case 'all':
|
||||
return $data;
|
||||
break;
|
||||
case 'first':
|
||||
return \array_shift($data);
|
||||
break;
|
||||
case 'last':
|
||||
return \array_pop($data);
|
||||
break;
|
||||
default:
|
||||
return isset($data[$key]) ? $data[$key] : null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sorts an array of objects by the specified key.
|
||||
*
|
||||
* @param arr $data The array of objects or associative arrays to sort.
|
||||
* @param str $key The object key or key path to use in sort evaluation.
|
||||
* @param str $order ASC or DESC.
|
||||
* @return arr The result array.
|
||||
*/
|
||||
public static function sort(array $data, $key, $order = null)
|
||||
{
|
||||
\uasort($data, function ($a, $b) use($key) {
|
||||
$a_val = Arrch::extractValues($a, $key);
|
||||
$b_val = Arrch::extractValues($b, $key);
|
||||
// Strings
|
||||
if (\is_string($a_val) && \is_string($b_val)) {
|
||||
return \strcasecmp($a_val, $b_val);
|
||||
} else {
|
||||
if ($a_val == $b_val) {
|
||||
return 0;
|
||||
} else {
|
||||
return $a_val > $b_val ? 1 : -1;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (\strtoupper($order ?: Arrch::$defaults['sort_order']) == 'DESC') {
|
||||
$data = \array_reverse($data, \true);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
/**
|
||||
* Evaluates an object based on an array of conditions
|
||||
* passed into the function, formatted like so...
|
||||
*
|
||||
* array('city', 'arlington');
|
||||
* array('city', '!=', 'arlington');
|
||||
*
|
||||
* @param arr $data The array of objects or associative arrays to search.
|
||||
* @param arr $conditions The conditions to evaluate against.
|
||||
* @return arr The result array.
|
||||
*/
|
||||
public static function where(array $data, array $conditions = array())
|
||||
{
|
||||
foreach ($conditions as $condition) {
|
||||
if (!\is_array($condition)) {
|
||||
\trigger_error('Condition ' . \var_export($condition, \true) . ' must be an array!', \E_USER_ERROR);
|
||||
} else {
|
||||
\array_map(function ($item, $key) use(&$data, $condition) {
|
||||
$return = 0;
|
||||
$operator = \array_key_exists(2, $condition) ? $condition[1] : '===';
|
||||
$search_value = \array_key_exists(2, $condition) ? $condition[2] : $condition[1];
|
||||
if (\is_array($condition[0])) {
|
||||
// array of keys
|
||||
if (\is_array($search_value)) {
|
||||
// array of values
|
||||
foreach ($condition[0] as $prop) {
|
||||
$value = Arrch::extractValues($item, $prop);
|
||||
foreach ($search_value as $query_val) {
|
||||
$return += Arrch::compare(array($value, $operator, $query_val)) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// single value
|
||||
foreach ($condition[0] as $prop) {
|
||||
$value = Arrch::extractValues($item, $prop);
|
||||
$return += Arrch::compare(array($value, $operator, $search_value)) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
} elseif (\is_array($search_value)) {
|
||||
// single key, array of query values
|
||||
$value = Arrch::extractValues($item, $condition[0]);
|
||||
$c = 0;
|
||||
foreach ($search_value as $query_val) {
|
||||
$c += Arrch::compare(array($value, $operator, $query_val)) ? 1 : 0;
|
||||
}
|
||||
// Negate options that don't pass all negative assertions
|
||||
if (\in_array($operator, array('!==', '!=', '!~')) && $c < \count($search_value)) {
|
||||
$c = 0;
|
||||
}
|
||||
$return += $c;
|
||||
} else {
|
||||
// single key, single value
|
||||
$value = Arrch::extractValues($item, $condition[0]);
|
||||
$return = Arrch::compare(array($value, $operator, $search_value));
|
||||
}
|
||||
// Unset
|
||||
if (!$return) {
|
||||
unset($data[$key]);
|
||||
}
|
||||
}, $data, \array_keys($data));
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
/**
|
||||
* Finds the requested value in a multidimensional array or an object and
|
||||
* returns it.
|
||||
*
|
||||
* @param mixed $item The item containing the value.
|
||||
* @param str $key The key or key path to the desired value.
|
||||
* @return mixed The found value or null.
|
||||
*/
|
||||
public static function extractValues($item, $key)
|
||||
{
|
||||
// Array of results
|
||||
$results = array();
|
||||
// Cast as array if object
|
||||
$item = \is_object($item) ? (array) $item : $item;
|
||||
// Array of keys
|
||||
$keys = \strstr($key, static::$key_split) ? \explode(static::$key_split, $key) : array($key);
|
||||
$keys = \array_filter($keys);
|
||||
// Key count
|
||||
$key_count = \count($keys);
|
||||
// key count > 0
|
||||
if ($key_count > 0) {
|
||||
$curr_key = \array_shift($keys);
|
||||
$arrayValues = \array_values($item);
|
||||
$child = \is_array($item) ? \array_shift($arrayValues) : null;
|
||||
// it's an array
|
||||
if (\is_array($item)) {
|
||||
// Clean non-ASCII keys
|
||||
foreach ($item as $k => $v) {
|
||||
$sanitized = \preg_replace('/[^(\\x20-\\x7F)]*/', '', $k);
|
||||
if ($sanitized !== $k) {
|
||||
$item[$sanitized] = $v;
|
||||
unset($item[$k]);
|
||||
}
|
||||
}
|
||||
// it has the keys
|
||||
if (\array_key_exists($curr_key, $item)) {
|
||||
$results = \array_merge($results, static::extractValues($item[$curr_key], \implode(static::$key_split, $keys)));
|
||||
// else it's child has the key
|
||||
} elseif (\is_array($child) || \is_object($child)) {
|
||||
if (\array_key_exists($curr_key, $child)) {
|
||||
foreach ($item as $child) {
|
||||
$results = \array_merge($results, static::extractValues($child, $key));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// no key
|
||||
} else {
|
||||
$results[] = $item;
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
/**
|
||||
* Runs comparison operations on an array of values formatted like so...
|
||||
*
|
||||
* e.g. array($value, $operator, $value)
|
||||
*
|
||||
* Returns true or false depending on the outcome of the requested
|
||||
* comparative operation (<, >, =, etc..).
|
||||
*
|
||||
* @param arr $array The comparison array.
|
||||
* @return bool Whether the operation evaluates to true or false.
|
||||
*/
|
||||
public static function compare(array $array)
|
||||
{
|
||||
$return = 0;
|
||||
foreach ($array[0] as $value) {
|
||||
if ($array[1] === '~') {
|
||||
// Check if variables loosely match right away
|
||||
if ($value != $array[2]) {
|
||||
if (\is_string($value) && \is_string($array[2])) {
|
||||
$return += \stristr($value, $array[2]) ? 1 : 0;
|
||||
} elseif (\is_null($value) && \is_null($array[2])) {
|
||||
$return += 1;
|
||||
} elseif (\is_array($value) || \is_object($value)) {
|
||||
$return += \stristr(\var_export($value, \true), $array[2]) ? 1 : 0;
|
||||
}
|
||||
} else {
|
||||
$return += 1;
|
||||
}
|
||||
} elseif ($array[1] === '!~') {
|
||||
if (\is_string($value) && \is_string($array[2])) {
|
||||
$return += !\stristr($value, $array[2]) ? 1 : 0;
|
||||
} elseif (\is_null($value) && \is_null($array[2])) {
|
||||
$return += 0;
|
||||
} elseif (\is_array($value) || \is_object($value)) {
|
||||
$return += !\stristr(\var_export($value, \true), $array[2]) ? 1 : 0;
|
||||
}
|
||||
} else {
|
||||
if (\is_array($value) || \is_object($value)) {
|
||||
\trigger_error('Cannot compare object of type ' . \strtoupper(\gettype($value)) . ' with the "' . $array[1] . '" operator.', \E_USER_WARNING);
|
||||
}
|
||||
if (!\in_array($array[1], static::$operators)) {
|
||||
\trigger_error('Operator "' . $array[1] . '" is not valid.', \E_USER_ERROR);
|
||||
} else {
|
||||
switch ($array[1]) {
|
||||
case '==':
|
||||
$return += $value == $array[2] ? 1 : 0;
|
||||
break;
|
||||
case '===':
|
||||
$return += $value === $array[2] ? 1 : 0;
|
||||
break;
|
||||
case '!=':
|
||||
$return += $value != $array[2] ? 1 : 0;
|
||||
break;
|
||||
case '!==':
|
||||
$return += $value !== $array[2] ? 1 : 0;
|
||||
break;
|
||||
case '>':
|
||||
$return += $value > $array[2] ? 1 : 0;
|
||||
break;
|
||||
case '<':
|
||||
$return += $value < $array[2] ? 1 : 0;
|
||||
break;
|
||||
case '>=':
|
||||
$return += $value >= $array[2] ? 1 : 0;
|
||||
break;
|
||||
case '<=':
|
||||
$return += $value <= $array[2] ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
/**
|
||||
* Recursive array merge for options arrays to eliminate duplicates
|
||||
* in a smart manner using a variable number of array arguments.
|
||||
*
|
||||
* @param arr Various options arrays.
|
||||
* @return arr The merged array.
|
||||
*/
|
||||
public static function merge()
|
||||
{
|
||||
$args = \func_get_args();
|
||||
$where = array();
|
||||
$options = array();
|
||||
foreach ($args as $o) {
|
||||
$options = \array_merge($options, $o);
|
||||
if (isset($o['where'])) {
|
||||
if (\count($where) === 0) {
|
||||
$where = $o['where'];
|
||||
} else {
|
||||
foreach ($o['where'] as $oc) {
|
||||
$matches = 0;
|
||||
foreach ($where as $wc) {
|
||||
if ($oc == $wc) {
|
||||
$matches += 1;
|
||||
}
|
||||
}
|
||||
if ($matches === 0) {
|
||||
$where[] = $oc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$options['where'] = $where;
|
||||
return $options;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user