diff --git a/src/apps/digg_ajax.php b/src/apps/digg_ajax.php index 9290c95b..0f6512a4 100755 --- a/src/apps/digg_ajax.php +++ b/src/apps/digg_ajax.php @@ -40,7 +40,7 @@ if (!is_array($row) || $cfg_digg_update == 0) { } DelCache($prefix, $key); } - SetCache($prefix, $key, $row, 0); + SetCache($prefix, $key, $row); } else { if ($action == 'good') { $row['goodpost'] = $row['goodpost'] + 1; @@ -59,7 +59,7 @@ if (!is_array($row) || $cfg_digg_update == 0) { DelCache($prefix, $key); } } - SetCache($prefix, $key, $row, 0); + SetCache($prefix, $key, $row); } $digg = ''; if (!is_array($row)) exit(); diff --git a/src/system/libraries/jsonq/Condition.php b/src/system/libraries/jsonq/Condition.php new file mode 100644 index 00000000..e7dc405b --- /dev/null +++ b/src/system/libraries/jsonq/Condition.php @@ -0,0 +1,278 @@ + $comparable; + } + + /** + * Strict less than + * + * @param mixed $value + * @param mixed $comparable + * + * @return bool + */ + public static function lessThan($value, $comparable) + { + return $value < $comparable; + } + + /** + * Greater or equal + * + * @param mixed $value + * @param mixed $comparable + * + * @return bool + */ + public static function greaterThanOrEqual($value, $comparable) + { + return $value >= $comparable; + } + + /** + * Less or equal + * + * @param mixed $value + * @param mixed $comparable + * + * @return bool + */ + public static function lessThanOrEqual($value, $comparable) + { + return $value <= $comparable; + } + + /** + * In array + * + * @param mixed $value + * @param array $comparable + * + * @return bool + */ + public static function in($value, $comparable) + { + return (is_array($comparable) && in_array($value, $comparable)); + } + + /** + * Not in array + * + * @param mixed $value + * @param array $comparable + * + * @return bool + */ + public static function notIn($value, $comparable) + { + return (is_array($comparable) && !in_array($value, $comparable)); + } + + /** + * Is null equal + * + * @param mixed $value + * + * @return bool + */ + public static function isNull($value, $comparable) + { + return is_null($value); + } + + /** + * Is not null equal + * + * @param mixed $value + * + * @return bool + */ + public static function isNotNull($value, $comparable) + { + return !is_null($value); + } + + /** + * Start With + * + * @param mixed $value + * @param string $comparable + * + * @return bool + */ + public static function startWith($value, $comparable) + { + if (is_array($comparable) || is_array($value) || is_object($comparable) || is_object($value)) { + return false; + } + + if (preg_match("/^$comparable/", $value)) { + return true; + } + + return false; + } + + /** + * End with + * + * @param mixed $value + * @param string $comparable + * + * @return bool + */ + public static function endWith($value, $comparable) + { + if (is_array($comparable) || is_array($value) || is_object($comparable) || is_object($value)) { + return false; + } + + if (preg_match("/$comparable$/", $value)) { + return true; + } + + return false; + } + + /** + * Match with pattern + * + * @param mixed $value + * @param string $comparable + * + * @return bool + */ + public static function match($value, $comparable) + { + if (is_array($comparable) || is_array($value) || is_object($comparable) || is_object($value)) { + return false; + } + + $comparable = trim($comparable); + + if (preg_match("/^$comparable$/", $value)) { + return true; + } + + return false; + } + + /** + * Contains substring in string + * + * @param string $value + * @param string $comparable + * + * @return bool + */ + public static function contains($value, $comparable) + { + return (strpos($value, $comparable) !== false); + } + + /** + * Dates equal + * + * @param string $value + * @param string $comparable + * + * @return bool + */ + public static function dateEqual($value, $comparable, $format = 'Y-m-d') + { + $date = date($format, strtotime($value)); + return $date == $comparable; + } + + /** + * Months equal + * + * @param string $value + * @param string $comparable + * + * @return bool + */ + public static function monthEqual($value, $comparable) + { + $month = date('m', strtotime($value)); + return $month == $comparable; + } + + /** + * Years equal + * + * @param string $value + * @param string $comparable + * + * @return bool + */ + public static function yearEqual($value, $comparable) + { + $year = date('Y', strtotime($value)); + return $year == $comparable; + } +} diff --git a/src/system/libraries/jsonq/Exceptions/ConditionNotAllowedException.php b/src/system/libraries/jsonq/Exceptions/ConditionNotAllowedException.php new file mode 100644 index 00000000..db408076 --- /dev/null +++ b/src/system/libraries/jsonq/Exceptions/ConditionNotAllowedException.php @@ -0,0 +1,9 @@ + 'equal', + 'eq' => 'equal', + '==' => 'strictEqual', + 'seq' => 'strictEqual', + '!=' => 'notEqual', + 'neq' => 'notEqual', + '!==' => 'strictNotEqual', + 'sneq' => 'strictNotEqual', + '>' => 'greaterThan', + 'gt' => 'greaterThan', + '<' => 'lessThan', + 'lt' => 'lessThan', + '>=' => 'greaterThanOrEqual', + 'gte' => 'greaterThanOrEqual', + '<=' => 'lessThanOrEqual', + 'lte' => 'lessThanOrEqual', + 'in' => 'in', + 'notin' => 'notIn', + 'null' => 'isNull', + 'notnull' => 'isNotNull', + 'startswith' => 'startWith', + 'endswith' => 'endWith', + 'match' => 'match', + 'contains' => 'contains', + 'dates' => 'dateEqual', + 'month' => 'monthEqual', + 'year' => 'yearEqual', + ]; + + + /** + * import data from file + * + * @param string|null $file + * @return bool + * @throws FileNotFoundException + * @throws InvalidJsonException + */ + public function import($file = null) + { + if (!is_null($file)) { + if (is_string($file)) { + $this->_map = $this->getDataFromFile($file); + $this->_baseContents = $this->_map; + return true; + } + } + + throw new FileNotFoundException(); + } + + /** + * Prepare data from desire conditions + * + * @return $this + * @throws ConditionNotAllowedException + */ + protected function prepare() + { + if ($this->_isProcessed) { + return $this; + } + + if (count($this->_conditions) > 0) { + $calculatedData = $this->processConditions(); + $this->_map = $this->objectToArray($calculatedData); + + $this->_conditions = []; + $this->_node = ''; + $this->_isProcessed = true; + return $this; + } + + $this->_isProcessed = true; + $this->_map = $this->objectToArray($this->getData()); + return $this; + } + + /** + * Our system will cache processed data and prevend multiple time processing. If + * you want to reprocess this method can help you + * + * @return $this + */ + public function reProcess() + { + $this->_isProcessed = false; + return $this; + } + + /** + * Parse object to array + * + * @param object $obj + * @return array|mixed + */ + protected function objectToArray($obj) + { + if (!is_array($obj) && !is_object($obj)) { + return $obj; + } + + if (is_array($obj)) { + return $obj; + } + + if (is_object($obj)) { + $obj = get_object_vars($obj); + } + + return array_map([$this, 'objectToArray'], $obj); + } + + /** + * Check given value is multidimensional array + * + * @param array $arr + * @return bool + */ + protected function isMultiArray($arr) + { + if (!is_array($arr)) { + return false; + } + + rsort($arr); + + return isset($arr[0]) && is_array($arr[0]); + } + + /** + * Check given value is valid JSON + * + * @param string $value + * @param bool $isReturnMap + * + * @return bool|array + */ + public function isJson($value, $isReturnMap = false) + { + if (is_array($value) || is_object($value)) { + return false; + } + + $data = json_decode($value, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + return false; + } + + return $isReturnMap ? $data : true; + } + + + public function takeColumn($array) + { + return $this->selectColumn($this->exceptColumn($array)); + } + + /** + * selecting specific column + * + * @param $array + * @return array + */ + protected function selectColumn($array) + { + $keys = $this->_select; + + if (count($keys) == 0) { + return $array; + } + + return array_intersect_key($array, array_flip((array) $keys)); + } + + /** + * selecting specific column + * + * @param $array + * @return array + */ + protected function exceptColumn($array) + { + $keys = $this->_except; + + if (count($keys) == 0) { + return $array; + } + + return array_diff_key($array, array_flip((array) $keys)); + } + + + /** + * Prepare data for result + * + * @param mixed $data + * @param bool $isObject + * @return array|mixed + */ + protected function prepareResult($data, $isObject) + { + $output = []; + + if (is_null($data) || is_scalar($data)) { + return $data; + } + + if ($this->isMultiArray($data)) { + foreach ($data as $key => $val) { + $val = $this->takeColumn($val); + $output[$key] = $isObject ? (object) $val : $val; + } + } else { + $output = json_decode(json_encode($this->takeColumn($data)), $isObject); + } + + return $output; + } + + /** + * Read JSON data from file + * + * @param string $file + * @param string $type + * @return bool|string|array + * @throws FileNotFoundException + * @throws InvalidJsonException + */ + protected function getDataFromFile($file, $type = 'application/json') + { + $opts = [ + 'http' => [ + 'header' => 'Content-Type: '.$type.'; charset=utf-8', + ], + ]; + + $context = stream_context_create($opts); + $data = file_get_contents($file, 0, $context); + $json = $this->isJson($data, true); + + if (!$json) { + throw new InvalidJsonException(); + } + + return $json; + } + + + + /** + * Get data from nested array + * + * @param $map array + * @param $node string + * @return bool|array|mixed + */ + protected function getFromNested($map, $node) + { + if (empty($node) || $node == '.') { + return $map; + } + + if ($node) { + $terminate = false; + $path = explode('.', $node); + + foreach ($path as $val) { + if (!is_array($map)) return $map; + + if (!array_key_exists($val, $map)) { + $terminate = true; + break; + } + + $map = &$map[$val]; + } + + if ($terminate) { + return new ValueNotFound(); + } + + return $map; + } + + return new ValueNotFound(); + } + + /** + * get data from node path + * + * @return mixed + */ + protected function getData() + { + return $this->getFromNested($this->_map, $this->_node); + } + + /** + * process AND and OR conditions + * + * @return array|string|object + * @throws ConditionNotAllowedException + */ + protected function processConditions() + { + $data = $this->getData(); + $conditions = $this->_conditions; + $result = array_filter($data, function ($val) use ($conditions) { + $res = false; + foreach ($conditions as $cond) { + $tmp = true; + foreach ($cond as $rule) { + $function = self::$_rulesMap[$rule['condition']]; + if (!is_callable($function)) { + if (!method_exists(Condition::class, $function)) { + throw new ConditionNotAllowedException("Exception: $function condition not allowed"); + } + + $function = [Condition::class, $function]; + } + + $value = $this->getFromNested($val, $rule['key']); + $return = $value instanceof ValueNotFound ? false : call_user_func_array($function, [$value, $rule['value']]); + $tmp &= $return; + } + $res |= $tmp; + } + return $res; + }); + + return $result; + } + + /** + * make WHERE clause + * + * @param string $key + * @param string $condition + * @param mixed $value + * @return $this + */ + public function where($key, $condition = null, $value = null) + { + if (!is_null($condition) && is_null($value)) { + $value = $condition; + $condition = '='; + } + + if (count($this->_conditions) < 1) { + array_push($this->_conditions, []); + } + return $this->makeWhere($key, $condition, $value); + } + + /** + * make WHERE clause with OR + * + * @param string $key + * @param string $condition + * @param mixed $value + * @return $this + */ + public function orWhere($key = null, $condition = null, $value = null) + { + if (!is_null($condition) && is_null($value)) { + $value = $condition; + $condition = '='; + } + + array_push($this->_conditions, []); + + return $this->makeWhere($key, $condition, $value); + } + + /** + * generator for AND and OR where + * + * @param string $key + * @param string $condition + * @param mixed $value + * @return $this + */ + protected function makeWhere($key, $condition = null, $value = null) + { + $current = end($this->_conditions); + $index = key($this->_conditions); + if (is_callable($key)) { + $key($this); + return $this; + } + + array_push($current, [ + 'key' => $key, + 'condition' => $condition, + 'value' => $value, + ]); + + $this->_conditions[$index] = $current; + + return $this; + } + + /** + * make WHERE IN clause + * + * @param string $key + * @param array $value + * @return $this + */ + public function whereIn($key = null, $value = []) + { + $this->where($key, 'in', $value); + + return $this; + } + + /** + * make WHERE NOT IN clause + * + * @param string $key + * @param mixed $value + * @return $this + */ + public function whereNotIn($key = null, $value = []) + { + $this->where($key, 'notin', $value); + return $this; + } + + /** + * make WHERE NULL clause + * + * @param string $key + * @return $this + */ + public function whereNull($key = null) + { + $this->where($key, 'null', 'null'); + return $this; + } + + + /** + * make WHERE Boolean clause + * + * @param string $key + * @return $this + */ + public function whereBool($key, $value) + { + if (is_bool($value)) { + $this->where($key, '==', $value); + } + return $this; + } + + /** + * make WHERE NOT NULL clause + * + * @param string $key + * @return $this + */ + public function whereNotNull($key = null) + { + $this->where($key, 'notnull', 'null'); + + return $this; + } + + /** + * make WHERE START WITH clause + * + * @param string $key + * @param string $value + * @return $this + */ + public function whereStartsWith($key, $value) + { + $this->where($key, 'startswith', $value); + + return $this; + } + + /** + * make WHERE ENDS WITH clause + * + * @param string $key + * @param string $value + * @return $this + */ + public function whereEndsWith($key, $value) + { + $this->where($key, 'endswith', $value); + + return $this; + } + + /** + * make WHERE MATCH clause + * + * @param string $key + * @param string $value + * @return $this + */ + public function whereMatch($key, $value) + { + $this->where($key, 'match', $value); + + return $this; + } + + /** + * make WHERE CONTAINS clause + * + * @param string $key + * @param string $value + * @return $this + */ + public function whereContains($key, $value) + { + $this->where($key, 'contains', $value); + + return $this; + } + + /** + * make WHERE DATE clause + * + * @param string $key + * @param string $value + * @return $this + */ + public function whereDate($key, $value) + { + $this->where($key, 'dates', $value); + + return $this; + } + + /** + * make WHERE month clause + * + * @param string $key + * @param string $value + * @return $this + */ + public function whereMonth($key, $value) + { + $this->where($key, 'month', $value); + + return $this; + } + + /** + * make WHERE Year clause + * + * @param string $key + * @param string $value + * @return $this + */ + public function whereYear($key, $value) + { + $this->where($key, 'year', $value); + + return $this; + } + + /** + * make macro for custom where clause + * + * @param string $name + * @param callable $fn + * @return bool + */ + public static function macro($name, callable $fn) + { + if (!in_array($name, self::$_rulesMap)) { + self::$_rulesMap[$name] = $fn; + return true; + } + + return false; + } +} diff --git a/src/system/libraries/jsonq/Jsonq.php b/src/system/libraries/jsonq/Jsonq.php new file mode 100644 index 00000000..25443624 --- /dev/null +++ b/src/system/libraries/jsonq/Jsonq.php @@ -0,0 +1,741 @@ +_data + * + * @param null $jsonFile + * @throws Exceptions\FileNotFoundException + * @throws InvalidJsonException + */ + public function __construct($jsonFile = null) + { + if (!is_null($jsonFile)) { + $this->import($jsonFile); + } + } + + /** + * Deep copy current instance + * + * @return Jsonq + */ + public function copy() + { + return clone $this; + } + + /** + * Set node path, where JsonQ start to prepare + * + * @param null $node + * @return $this + * @throws NullValueException + */ + public function from($node = null) + { + $this->_isProcessed = false; + + if (is_null($node) || $node == '') { + throw new NullValueException("Null node exception"); + } + + $this->_node = $node; + + return $this; + } + + /** + * Alias of from() method + * + * @param null $node + * @return $this + * @throws NullValueException + */ + public function at($node = null) + { + return $this->from($node); + } + + /** + * select desired column + * + * @param ... scalar + * @return $this + */ + public function select() + { + $args = func_get_args(); + if (count($args) > 0 ){ + $this->_select = $args; + } + + return $this; + } + + /** + * select desired column for except + * + * @param ... scalar + * @return $this + */ + public function except() + { + $args = func_get_args(); + if (count($args) > 0 ){ + $this->_except = $args; + } + + return $this; + } + + /** + * getting prepared data + * + * @param bool $object + * @return array|object + * @throws ConditionNotAllowedException + */ + public function get($object = false) + { + $this->prepare(); + + return $this->prepareResult($this->_map, $object); + } + + /** + * alias of get method + * + * @param bool $object + * @return array|object + * @throws ConditionNotAllowedException + */ + public function fetch($object = true) + { + return $this->get($object); + } + + /** + * check data exists in system + * + * @return bool + * @throws ConditionNotAllowedException + */ + public function exists() + { + $this->prepare(); + + return (!empty($this->_map) && !is_null($this->_map)); + } + + /** + * reset given data to the $_map + * + * @param mixed $data + * @param bool $instance + * @return jsonq + */ + public function reset($data = null, $instance = false) + { + if (!is_null($data)) { + $this->_baseContents = $data; + } + + if ($instance) { + $self = new self(); + $self->collect($this->_baseContents); + + return $self; + } + + $this->_map = $this->_baseContents; + $this->reProcess(); + + return $this; + } + + /** + * getting group data from specific column + * + * @param string $column + * @return $this + * @throws ConditionNotAllowedException + */ + public function groupBy($column) + { + $this->prepare(); + + $data = []; + foreach ($this->_map as $map) { + $value = $this->getFromNested($map, $column); + if ($value) { + $data[$value][] = $map; + } + } + + $this->_map = $data; + return $this; + } + + public function countGroupBy($column) + { + + $this->prepare(); + + $data = []; + foreach ($this->_map as $map) { + $value = $this->getFromNested($map, $column); + if (!$value) { + continue; + } + + if (isset($data[$value])) { + $data[$value] ++; + } else { + $data[$value] = 1; + } + } + + $this->_map = $data; + return $this; + } + + /** + * count prepared data + * + * @return int + * @throws ConditionNotAllowedException + */ + public function count() + { + $this->prepare(); + + return count($this->_map); + } + + /** + * size is an alias of count + * + * @return int + * @throws ConditionNotAllowedException + */ + public function size() + { + return $this->count(); + } + + /** + * sum prepared data + * @param int $column + * @return int + * @throws ConditionNotAllowedException + */ + public function sum($column = null) + { + $this->prepare(); + + $sum = 0; + if (is_null($column)) { + $sum = array_sum($this->_map); + } else { + foreach ($this->_map as $key => $val) { + $value = $this->getFromNested($val, $column); + if (is_scalar($value)) { + $sum += $value; + } + + } + } + + return $sum; + } + + /** + * getting max value from prepared data + * + * @param int $column + * @return int + * @throws ConditionNotAllowedException + */ + public function max($column = null) + { + $this->prepare(); + + if (is_null($column)) { + $max = max($this->_map); + } else { + $max = max(array_column($this->_map, $column)); + } + + return $max; + } + + /** + * getting min value from prepared data + * + * @param int $column + * @return string + * @throws ConditionNotAllowedException + */ + public function min($column = null) + { + $this->prepare(); + + if (is_null($column)) { + $min = min($this->_map); + } else { + $min = min(array_column($this->_map, $column)); + } + + return $min; + } + + /** + * getting average value from prepared data + * + * @param int $column + * @return string + * @throws ConditionNotAllowedException + */ + public function avg($column = null) + { + $this->prepare(); + + $count = $this->count(); + $total = $this->sum($column); + + return ($total/$count); + } + + /** + * getting first element of prepared data + * + * @param bool $object + * @return object|array|null + * @throws ConditionNotAllowedException + */ + public function first($object = false) + { + $this->prepare(); + + $data = $this->_map; + if (count($data) > 0) { + return $this->prepareResult(reset($data), $object); + } + + return null; + } + + /** + * getting last element of prepared data + * + * @param bool $object + * @return object|array|null + * @throws ConditionNotAllowedException + */ + public function last($object = false) + { + $this->prepare(); + + $data = $this->_map; + if (count($data) > 0) { + return $this->prepareResult(end($data), $object); + } + + return null; + } + + /** + * getting nth number of element of prepared data + * + * @param int $index + * @param bool $object + * @return object|array|null + * @throws ConditionNotAllowedException + */ + public function nth($index, $object = false) + { + $this->prepare(); + + $data = $this->_map; + $total_elm = count($data); + $idx = abs($index); + + if (!is_integer($index) || $total_elm < $idx || $index == 0 || !is_array($this->_map)) { + return null; + } + + if ($index > 0) { + $result = $data[$index - 1]; + } else { + $result = $data[$this->count() + $index]; + } + + return $this->prepareResult($result, $object); + } + + /** + * sorting from prepared data + * + * @param string $column + * @param string $order + * @return object|array|null + * @throws ConditionNotAllowedException + */ + public function sortBy($column, $order = 'asc') + { + $this->prepare(); + + if (!is_array($this->_map)) { + return $this; + } + + usort($this->_map, function ($a, $b) use ($column, $order) { + $val1 = $this->getFromNested($a, $column); + $val2 = $this->getFromNested($b, $column); + if (is_string($val1)) { + $val1 = strtolower($val1); + } + + if (is_string($val2)) { + $val2 = strtolower($val2); + } + + if ($val1 == $val2) { + return 0; + } + $order = strtolower(trim($order)); + + if ($order == 'desc') { + return ($val1 > $val2) ? -1 : 1; + } else { + return ($val1 < $val2) ? -1 : 1; + } + }); + + return $this; + } + + /** + * Sort prepared data using a custom sort function. + * + * @param callable $sortFunc + * + * @return object|array|null + * @throws ConditionNotAllowedException + */ + public function sortByCallable(callable $sortFunc) + { + $this->prepare(); + + if (!is_array($this->_map)) { + return $this; + } + + usort($this->_map, $sortFunc); + + return $this; + } + + /** + * Sort an array value + * + * @param string $order + * @return Jsonq + */ + public function sort($order = 'asc') + { + if ($order == 'desc') { + rsort($this->_map); + }else{ + sort($this->_map); + } + + return $this; + } + + /** + * getting data from desire path + * + * @param string $path + * @param bool $object + * @return mixed + * @throws NullValueException + * @throws ConditionNotAllowedException + */ + public function find($path, $object = false) + { + return $this->from($path)->prepare()->get($object); + } + + /** + * take action of each element of prepared data + * + * @param callable $fn + * @throws ConditionNotAllowedException + */ + public function each(callable $fn) + { + $this->prepare(); + + foreach ($this->_map as $key => $val) { + $fn($key, $val); + } + } + + /** + * transform prepared data by using callable function + * + * @param callable $fn + * @return object|array + * @throws ConditionNotAllowedException + */ + public function transform(callable $fn) + { + $this->prepare(); + + $new_data = []; + foreach ($this->_map as $key => $val) { + $new_data[$key] = $fn($val); + } + + return $this->prepareResult($new_data, false); + } + + /** + * pipe send output in next pipe + * + * @param callable $fn + * @param string|null $class + * @return object|array + * @throws ConditionNotAllowedException + */ + public function pipe(callable $fn, $class = null) + { + $this->prepare(); + + if (is_string($fn) && !is_null($class)) { + $instance = new $class; + + $this->_map = call_user_func_array([$instance, $fn], [$this]); + return $this; + } + + $this->_map = $fn($this); + return $this; + } + + /** + * filtered each element of prepared data + * + * @param callable $fn + * @param bool $key + * @return mixed|array + * @throws ConditionNotAllowedException + */ + public function filter(callable $fn, $key = false) + { + $this->prepare(); + + $data = []; + foreach ($this->_map as $k => $val) { + if ($fn($val)) { + if ($key) { + $data[$k] = $val; + } else { + $data[] = $val; + } + } + } + + return $this->prepareResult($data, false); + } + + /** + * then method set position of working data + * + * @param string $node + * @return jsonq + * @throws NullValueException + * @throws ConditionNotAllowedException + */ + public function then($node) + { + $this->_map = $this->prepare()->first(false); + + $this->from($node); + + return $this; + } + + /** + * import raw JSON data for process + * + * @param string $data + * @return jsonq + */ + public function json($data) + { + $json = $this->isJson($data, true); + + if ($json) { + return $this->collect($json); + } + + return $this; + } + + /** + * import parsed data from raw json + * + * @param array|object $data + * @return jsonq + */ + public function collect($data) + { + $this->_map = $this->objectToArray($data); + $this->_baseContents = &$this->_map; + + return $this; + } + + /** + * implode resulting data from desire key and delimeter + * + * @param string|array $key + * @param string $delimiter + * @return string|array + * @throws ConditionNotAllowedException + */ + public function implode($key, $delimiter = ',') + { + $this->prepare(); + + $implode = []; + if (is_string($key)) { + return $this->makeImplode($key, $delimiter); + } + + if (is_array($key)) { + foreach ($key as $k) { + $imp = $this->makeImplode($k, $delimiter); + $implode[$k] = $imp; + } + + return $implode; + } + return ''; + } + + /** + * process implode from resulting data + * + * @param string $key + * @param string $delimiter + * @return string|null + */ + protected function makeImplode($key, $delimiter) + { + $data = array_column($this->_map, $key); + + if (is_array($data)) { + return implode($delimiter, $data); + } + + return null; + } + + /** + * getting specific key's value from prepared data + * + * @param string $column + * @return object|array + * @throws ConditionNotAllowedException + */ + public function column($column) + { + $this->prepare(); + + return array_column($this->_map, $column); + } + + /** + * getting raw JSON from prepared data + * + * @return string + * @throws ConditionNotAllowedException + */ + public function toJson() + { + $this->prepare(); + + return json_encode($this->_map); + } + + /** + * getting all keys from prepared data + * + * @return object|array + * @throws ConditionNotAllowedException + */ + public function keys() + { + $this->prepare(); + + return array_keys($this->_map); + } + + /** + * getting all values from prepared data + * + * @return object|array + * @throws ConditionNotAllowedException + */ + public function values() + { + $this->prepare(); + + return array_values($this->_map); + } + + /** + * getting chunk values from prepared data + * + * @param int $amount + * @param $fn + * @return object|array|bool + * @throws ConditionNotAllowedException + */ + public function chunk($amount, callable $fn = null) + { + $this->prepare(); + + $chunk_value = array_chunk($this->_map, $amount); + $chunks = []; + + if (!is_null($fn) && is_callable($fn)) { + foreach ($chunk_value as $chunk) { + $return = $fn($chunk); + if (!is_null($return)) { + $chunks[] = $return; + } + } + return count($chunks) > 0 ? $chunks : null; + } + + return $chunk_value; + } +} diff --git a/src/system/libraries/jsonq/Results/ValueNotFound.php b/src/system/libraries/jsonq/Results/ValueNotFound.php new file mode 100644 index 00000000..d32bfb4e --- /dev/null +++ b/src/system/libraries/jsonq/Results/ValueNotFound.php @@ -0,0 +1,7 @@ +>dede>> +{dede:jsonq url='https://www.dedebiz.com/api/v1/ping' path='list' cachetime=3600}[field:id/] - [field:name/]
{/dede:jsonq} +>>dede>> +url='' JSON接口地址 +path='' 路径(可选),如果为空[field:path/]可获取指定path的值 +cachetime=3600 缓存时间 \ No newline at end of file diff --git a/src/system/taglib/help/sql.txt b/src/system/taglib/help/sql.txt index fce438af..454a02ec 100755 --- a/src/system/taglib/help/sql.txt +++ b/src/system/taglib/help/sql.txt @@ -1,5 +1,5 @@ SQL标签 >>dede>> -{dede:sql sql=''}[field:title/]{/dede} +{dede:sql sql=''}[field:title/]{/dede:sql} >>dede>> sql='' 完整的SQL语句 \ No newline at end of file diff --git a/src/system/taglib/jsonq.lib.php b/src/system/taglib/jsonq.lib.php new file mode 100644 index 00000000..d9f171f4 --- /dev/null +++ b/src/system/taglib/jsonq.lib.php @@ -0,0 +1,83 @@ +CAttribute->Items, $attlist); + extract($ctag->CAttribute->Items, EXTR_SKIP); + + $Innertext = trim($ctag->GetInnerText()); + + if ($url == '' || $Innertext == '') return ''; + $key = md5($url); + try { + if ($path=='') { + $jsonq = new Jsonq($url); + $revalue = GetCache("tagjsonq2", $key); + if (!empty($revalue)) { + return $revalue; + } + $revalue = ""; + $ctp = new DedeTagParse(); + $ctp->SetNameSpace('field', '[', ']'); + $ctp->LoadSource($Innertext); + foreach ($ctp->CTags as $tagid => $ctag) { + $tagname = $ctag->GetName(); + $vv = $jsonq->from($tagname)->get(); + $ctp->Assign($tagid, $vv); + $jsonq->reset(); + } + $revalue .= $ctp->GetResult(); + SetCache("tagjsonq2", $key, $revalue, $cachetime); + return $revalue; + } + + $row = GetCache("tagjsonq", $key); + if (!is_array($row) || $cachetime == 0) { + $jsonq = new Jsonq($url); + $row = $jsonq->from($path)->get(); + SetCache("tagjsonq", $key, $row, $cachetime); + } + if (!is_array($row)) { + return ""; + } + + $ctp = new DedeTagParse(); + $ctp->SetNameSpace('field', '[', ']'); + $ctp->LoadSource($Innertext); + + $GLOBALS['autoindex'] = 0; + $revalue = ""; + + foreach ($row as $key => $value) { + $GLOBALS['autoindex']++; + foreach ($ctp->CTags as $tagid => $ctag) { + if ($ctag->GetName() == 'array') { + $ctp->Assign($tagid, $value); + } else { + if (!empty($value[$ctag->GetName()])) { + $ctp->Assign($tagid, $value[$ctag->GetName()]); + } else { + $ctp->Assign($tagid, ""); + } + } + } + $revalue .= $ctp->GetResult(); + } + + return $revalue; + } catch (Exception $e) { + return ""; + } +}