@@ -14,7 +14,6 @@ class Condition | |||
{ | |||
return $value == $comparable; | |||
} | |||
/** | |||
* Strict equals | |||
* | |||
@@ -27,7 +26,6 @@ class Condition | |||
{ | |||
return $value === $comparable; | |||
} | |||
/** | |||
* Simple not equal | |||
* | |||
@@ -40,7 +38,6 @@ class Condition | |||
{ | |||
return $value != $comparable; | |||
} | |||
/** | |||
* Strict not equal | |||
* | |||
@@ -53,7 +50,6 @@ class Condition | |||
{ | |||
return $value !== $comparable; | |||
} | |||
/** | |||
* Strict greater than | |||
* | |||
@@ -66,7 +62,6 @@ class Condition | |||
{ | |||
return $value > $comparable; | |||
} | |||
/** | |||
* Strict less than | |||
* | |||
@@ -79,7 +74,6 @@ class Condition | |||
{ | |||
return $value < $comparable; | |||
} | |||
/** | |||
* Greater or equal | |||
* | |||
@@ -92,7 +86,6 @@ class Condition | |||
{ | |||
return $value >= $comparable; | |||
} | |||
/** | |||
* Less or equal | |||
* | |||
@@ -105,7 +98,6 @@ class Condition | |||
{ | |||
return $value <= $comparable; | |||
} | |||
/** | |||
* In array | |||
* | |||
@@ -118,7 +110,6 @@ class Condition | |||
{ | |||
return (is_array($comparable) && in_array($value, $comparable)); | |||
} | |||
/** | |||
* Not in array | |||
* | |||
@@ -131,7 +122,6 @@ class Condition | |||
{ | |||
return (is_array($comparable) && !in_array($value, $comparable)); | |||
} | |||
/** | |||
* Is null equal | |||
* | |||
@@ -143,7 +133,6 @@ class Condition | |||
{ | |||
return is_null($value); | |||
} | |||
/** | |||
* Is not null equal | |||
* | |||
@@ -155,7 +144,6 @@ class Condition | |||
{ | |||
return !is_null($value); | |||
} | |||
/** | |||
* Start With | |||
* | |||
@@ -169,14 +157,11 @@ class Condition | |||
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 | |||
* | |||
@@ -190,14 +175,11 @@ class Condition | |||
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 | |||
* | |||
@@ -211,16 +193,12 @@ class Condition | |||
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 | |||
* | |||
@@ -233,7 +211,6 @@ class Condition | |||
{ | |||
return (strpos($value, $comparable) !== false); | |||
} | |||
/** | |||
* Dates equal | |||
* | |||
@@ -247,7 +224,6 @@ class Condition | |||
$date = date($format, strtotime($value)); | |||
return $date == $comparable; | |||
} | |||
/** | |||
* Months equal | |||
* | |||
@@ -261,7 +237,6 @@ class Condition | |||
$month = date('m', strtotime($value)); | |||
return $month == $comparable; | |||
} | |||
/** | |||
* Years equal | |||
* | |||
@@ -276,3 +251,4 @@ class Condition | |||
return $year == $comparable; | |||
} | |||
} | |||
?> |
@@ -7,3 +7,4 @@ class ConditionNotAllowedException extends \Exception | |||
parent::__construct($message, $code, $previous); | |||
} | |||
} | |||
?> |
@@ -7,3 +7,4 @@ class FileNotFoundException extends \Exception | |||
parent::__construct($message, $code, $previous); | |||
} | |||
} | |||
?> |
@@ -7,3 +7,4 @@ class InvalidJsonException extends \Exception | |||
parent::__construct($message, $code, $previous); | |||
} | |||
} | |||
?> |
@@ -7,3 +7,4 @@ class InvalidNodeException extends \Exception | |||
parent::__construct($message, $code, $previous); | |||
} | |||
} | |||
?> |
@@ -7,3 +7,4 @@ class NullValueException extends \Exception | |||
parent::__construct($message, $code, $previous); | |||
} | |||
} | |||
?> |
@@ -5,7 +5,6 @@ require_once(dirname(__FILE__)."/Exceptions/FileNotFoundException.php"); | |||
require_once(dirname(__FILE__)."/Exceptions/InvalidJsonException.php"); | |||
require_once(dirname(__FILE__)."/Results/ValueNotFound.php"); | |||
require_once(dirname(__FILE__)."/Condition.php"); | |||
trait JsonQueriable | |||
{ | |||
/** | |||
@@ -13,44 +12,37 @@ trait JsonQueriable | |||
* @var string|array | |||
*/ | |||
protected $_node = ''; | |||
/** | |||
* contain prepared data for process | |||
* @var mixed | |||
*/ | |||
protected $_map; | |||
/** | |||
* contains column names | |||
* @var array | |||
*/ | |||
protected $_select = []; | |||
/** | |||
* contains column names for except | |||
* @var array | |||
*/ | |||
protected $_except = []; | |||
/** | |||
* Stores base contents. | |||
* | |||
* @var array | |||
*/ | |||
protected $_baseContents = []; | |||
/** | |||
* Stores all conditions. | |||
* | |||
* @var array | |||
*/ | |||
protected $_conditions = []; | |||
/** | |||
* @var bool | |||
*/ | |||
protected $_isProcessed = false; | |||
/** | |||
* map all conditions with methods | |||
* @var array | |||
@@ -84,8 +76,6 @@ trait JsonQueriable | |||
'month' => 'monthEqual', | |||
'year' => 'yearEqual', | |||
]; | |||
/** | |||
* import data from file | |||
* | |||
@@ -106,7 +96,6 @@ trait JsonQueriable | |||
throw new FileNotFoundException(); | |||
} | |||
/** | |||
* Prepare data from desire conditions | |||
* | |||
@@ -118,7 +107,6 @@ trait JsonQueriable | |||
if ($this->_isProcessed) { | |||
return $this; | |||
} | |||
if (count($this->_conditions) > 0) { | |||
$calculatedData = $this->processConditions(); | |||
$this->_map = $this->objectToArray($calculatedData); | |||
@@ -128,12 +116,10 @@ trait JsonQueriable | |||
$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 | |||
@@ -145,7 +131,6 @@ trait JsonQueriable | |||
$this->_isProcessed = false; | |||
return $this; | |||
} | |||
/** | |||
* Parse object to array | |||
* | |||
@@ -157,18 +142,14 @@ trait JsonQueriable | |||
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 | |||
* | |||
@@ -180,12 +161,9 @@ trait JsonQueriable | |||
if (!is_array($arr)) { | |||
return false; | |||
} | |||
rsort($arr); | |||
return isset($arr[0]) && is_array($arr[0]); | |||
} | |||
/** | |||
* Check given value is valid JSON | |||
* | |||
@@ -199,22 +177,16 @@ trait JsonQueriable | |||
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 | |||
* | |||
@@ -224,14 +196,11 @@ trait JsonQueriable | |||
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 | |||
* | |||
@@ -241,15 +210,11 @@ trait JsonQueriable | |||
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 | |||
* | |||
@@ -260,11 +225,9 @@ trait JsonQueriable | |||
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); | |||
@@ -273,10 +236,8 @@ trait JsonQueriable | |||
} else { | |||
$output = json_decode(json_encode($this->takeColumn($data)), $isObject); | |||
} | |||
return $output; | |||
} | |||
/** | |||
* Read JSON data from file | |||
* | |||
@@ -293,20 +254,14 @@ trait JsonQueriable | |||
'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 | |||
* | |||
@@ -319,32 +274,24 @@ trait JsonQueriable | |||
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 | |||
* | |||
@@ -354,7 +301,6 @@ trait JsonQueriable | |||
{ | |||
return $this->getFromNested($this->_map, $this->_node); | |||
} | |||
/** | |||
* process AND and OR conditions | |||
* | |||
@@ -375,10 +321,8 @@ trait JsonQueriable | |||
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; | |||
@@ -387,10 +331,8 @@ trait JsonQueriable | |||
} | |||
return $res; | |||
}); | |||
return $result; | |||
} | |||
/** | |||
* make WHERE clause | |||
* | |||
@@ -405,13 +347,11 @@ trait JsonQueriable | |||
$value = $condition; | |||
$condition = '='; | |||
} | |||
if (count($this->_conditions) < 1) { | |||
array_push($this->_conditions, []); | |||
} | |||
return $this->makeWhere($key, $condition, $value); | |||
} | |||
/** | |||
* make WHERE clause with OR | |||
* | |||
@@ -426,12 +366,9 @@ trait JsonQueriable | |||
$value = $condition; | |||
$condition = '='; | |||
} | |||
array_push($this->_conditions, []); | |||
return $this->makeWhere($key, $condition, $value); | |||
} | |||
/** | |||
* generator for AND and OR where | |||
* | |||
@@ -448,18 +385,14 @@ trait JsonQueriable | |||
$key($this); | |||
return $this; | |||
} | |||
array_push($current, [ | |||
'key' => $key, | |||
'condition' => $condition, | |||
'value' => $value, | |||
]); | |||
$this->_conditions[$index] = $current; | |||
return $this; | |||
} | |||
/** | |||
* make WHERE IN clause | |||
* | |||
@@ -473,7 +406,6 @@ trait JsonQueriable | |||
return $this; | |||
} | |||
/** | |||
* make WHERE NOT IN clause | |||
* | |||
@@ -486,7 +418,6 @@ trait JsonQueriable | |||
$this->where($key, 'notin', $value); | |||
return $this; | |||
} | |||
/** | |||
* make WHERE NULL clause | |||
* | |||
@@ -498,8 +429,6 @@ trait JsonQueriable | |||
$this->where($key, 'null', 'null'); | |||
return $this; | |||
} | |||
/** | |||
* make WHERE Boolean clause | |||
* | |||
@@ -513,7 +442,6 @@ trait JsonQueriable | |||
} | |||
return $this; | |||
} | |||
/** | |||
* make WHERE NOT NULL clause | |||
* | |||
@@ -526,7 +454,6 @@ trait JsonQueriable | |||
return $this; | |||
} | |||
/** | |||
* make WHERE START WITH clause | |||
* | |||
@@ -540,7 +467,6 @@ trait JsonQueriable | |||
return $this; | |||
} | |||
/** | |||
* make WHERE ENDS WITH clause | |||
* | |||
@@ -554,7 +480,6 @@ trait JsonQueriable | |||
return $this; | |||
} | |||
/** | |||
* make WHERE MATCH clause | |||
* | |||
@@ -568,7 +493,6 @@ trait JsonQueriable | |||
return $this; | |||
} | |||
/** | |||
* make WHERE CONTAINS clause | |||
* | |||
@@ -582,7 +506,6 @@ trait JsonQueriable | |||
return $this; | |||
} | |||
/** | |||
* make WHERE DATE clause | |||
* | |||
@@ -596,7 +519,6 @@ trait JsonQueriable | |||
return $this; | |||
} | |||
/** | |||
* make WHERE month clause | |||
* | |||
@@ -610,7 +532,6 @@ trait JsonQueriable | |||
return $this; | |||
} | |||
/** | |||
* make WHERE Year clause | |||
* | |||
@@ -624,7 +545,6 @@ trait JsonQueriable | |||
return $this; | |||
} | |||
/** | |||
* make macro for custom where clause | |||
* | |||
@@ -638,7 +558,7 @@ trait JsonQueriable | |||
self::$_rulesMap[$name] = $fn; | |||
return true; | |||
} | |||
return false; | |||
} | |||
} | |||
?> |
@@ -6,12 +6,9 @@ require_once(dirname(__FILE__)."/Exceptions/InvalidJsonException.php"); | |||
require_once(dirname(__FILE__)."/Exceptions/InvalidNodeException.php"); | |||
require_once(dirname(__FILE__)."/Exceptions/NullValueException.php"); | |||
require_once(dirname(__FILE__)."/JsonQueriable.php"); | |||
class Jsonq | |||
{ | |||
use JsonQueriable; | |||
/** | |||
* this constructor set main json file path | |||
* otherwise create it and read file contents | |||
@@ -27,7 +24,6 @@ class Jsonq | |||
$this->import($jsonFile); | |||
} | |||
} | |||
/** | |||
* Deep copy current instance | |||
* | |||
@@ -37,7 +33,6 @@ class Jsonq | |||
{ | |||
return clone $this; | |||
} | |||
/** | |||
* Set node path, where JsonQ start to prepare | |||
* | |||
@@ -48,16 +43,12 @@ class Jsonq | |||
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 | |||
* | |||
@@ -69,7 +60,6 @@ class Jsonq | |||
{ | |||
return $this->from($node); | |||
} | |||
/** | |||
* select desired column | |||
* | |||
@@ -82,10 +72,8 @@ class Jsonq | |||
if (count($args) > 0 ){ | |||
$this->_select = $args; | |||
} | |||
return $this; | |||
} | |||
/** | |||
* select desired column for except | |||
* | |||
@@ -98,10 +86,8 @@ class Jsonq | |||
if (count($args) > 0 ){ | |||
$this->_except = $args; | |||
} | |||
return $this; | |||
} | |||
/** | |||
* getting prepared data | |||
* | |||
@@ -112,10 +98,8 @@ class Jsonq | |||
public function get($object = false) | |||
{ | |||
$this->prepare(); | |||
return $this->prepareResult($this->_map, $object); | |||
} | |||
/** | |||
* alias of get method | |||
* | |||
@@ -127,7 +111,6 @@ class Jsonq | |||
{ | |||
return $this->get($object); | |||
} | |||
/** | |||
* check data exists in system | |||
* | |||
@@ -140,7 +123,6 @@ class Jsonq | |||
return (!empty($this->_map) && !is_null($this->_map)); | |||
} | |||
/** | |||
* reset given data to the $_map | |||
* | |||
@@ -153,20 +135,16 @@ class Jsonq | |||
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 | |||
* | |||
@@ -177,7 +155,6 @@ class Jsonq | |||
public function groupBy($column) | |||
{ | |||
$this->prepare(); | |||
$data = []; | |||
foreach ($this->_map as $map) { | |||
$value = $this->getFromNested($map, $column); | |||
@@ -185,34 +162,27 @@ class Jsonq | |||
$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 | |||
* | |||
@@ -222,10 +192,8 @@ class Jsonq | |||
public function count() | |||
{ | |||
$this->prepare(); | |||
return count($this->_map); | |||
} | |||
/** | |||
* size is an alias of count | |||
* | |||
@@ -236,7 +204,6 @@ class Jsonq | |||
{ | |||
return $this->count(); | |||
} | |||
/** | |||
* sum prepared data | |||
* @param int $column | |||
@@ -246,7 +213,6 @@ class Jsonq | |||
public function sum($column = null) | |||
{ | |||
$this->prepare(); | |||
$sum = 0; | |||
if (is_null($column)) { | |||
$sum = array_sum($this->_map); | |||
@@ -256,13 +222,10 @@ class Jsonq | |||
if (is_scalar($value)) { | |||
$sum += $value; | |||
} | |||
} | |||
} | |||
return $sum; | |||
} | |||
/** | |||
* getting max value from prepared data | |||
* | |||
@@ -273,16 +236,13 @@ class Jsonq | |||
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 | |||
* | |||
@@ -293,16 +253,13 @@ class Jsonq | |||
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 | |||
* | |||
@@ -313,10 +270,8 @@ class Jsonq | |||
public function avg($column = null) | |||
{ | |||
$this->prepare(); | |||
$count = $this->count(); | |||
$total = $this->sum($column); | |||
return ($total/$count); | |||
} | |||
@@ -330,15 +285,12 @@ class Jsonq | |||
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 | |||
* | |||
@@ -349,12 +301,10 @@ class Jsonq | |||
public function last($object = false) | |||
{ | |||
$this->prepare(); | |||
$data = $this->_map; | |||
if (count($data) > 0) { | |||
return $this->prepareResult(end($data), $object); | |||
} | |||
return null; | |||
} | |||
@@ -369,24 +319,19 @@ class Jsonq | |||
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 | |||
* | |||
@@ -398,37 +343,30 @@ class Jsonq | |||
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. | |||
* | |||
@@ -440,16 +378,12 @@ class Jsonq | |||
public function sortByCallable(callable $sortFunc) | |||
{ | |||
$this->prepare(); | |||
if (!is_array($this->_map)) { | |||
return $this; | |||
} | |||
usort($this->_map, $sortFunc); | |||
return $this; | |||
} | |||
/** | |||
* Sort an array value | |||
* | |||
@@ -460,13 +394,11 @@ class Jsonq | |||
{ | |||
if ($order == 'desc') { | |||
rsort($this->_map); | |||
}else{ | |||
} else { | |||
sort($this->_map); | |||
} | |||
return $this; | |||
} | |||
/** | |||
* getting data from desire path | |||
* | |||
@@ -480,7 +412,6 @@ class Jsonq | |||
{ | |||
return $this->from($path)->prepare()->get($object); | |||
} | |||
/** | |||
* take action of each element of prepared data | |||
* | |||
@@ -495,7 +426,6 @@ class Jsonq | |||
$fn($key, $val); | |||
} | |||
} | |||
/** | |||
* transform prepared data by using callable function | |||
* | |||
@@ -506,15 +436,12 @@ class Jsonq | |||
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 | |||
* | |||
@@ -526,18 +453,14 @@ class Jsonq | |||
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 | |||
* | |||
@@ -549,7 +472,6 @@ class Jsonq | |||
public function filter(callable $fn, $key = false) | |||
{ | |||
$this->prepare(); | |||
$data = []; | |||
foreach ($this->_map as $k => $val) { | |||
if ($fn($val)) { | |||
@@ -560,10 +482,8 @@ class Jsonq | |||
} | |||
} | |||
} | |||
return $this->prepareResult($data, false); | |||
} | |||
/** | |||
* then method set position of working data | |||
* | |||
@@ -575,12 +495,9 @@ class Jsonq | |||
public function then($node) | |||
{ | |||
$this->_map = $this->prepare()->first(false); | |||
$this->from($node); | |||
return $this; | |||
} | |||
/** | |||
* import raw JSON data for process | |||
* | |||
@@ -590,14 +507,11 @@ class Jsonq | |||
public function json($data) | |||
{ | |||
$json = $this->isJson($data, true); | |||
if ($json) { | |||
return $this->collect($json); | |||
} | |||
return $this; | |||
} | |||
/** | |||
* import parsed data from raw json | |||
* | |||
@@ -608,10 +522,8 @@ class Jsonq | |||
{ | |||
$this->_map = $this->objectToArray($data); | |||
$this->_baseContents = &$this->_map; | |||
return $this; | |||
} | |||
/** | |||
* implode resulting data from desire key and delimeter | |||
* | |||
@@ -623,23 +535,19 @@ class Jsonq | |||
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 | |||
* | |||
@@ -650,14 +558,11 @@ class Jsonq | |||
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 | |||
* | |||
@@ -668,10 +573,8 @@ class Jsonq | |||
public function column($column) | |||
{ | |||
$this->prepare(); | |||
return array_column($this->_map, $column); | |||
} | |||
/** | |||
* getting raw JSON from prepared data | |||
* | |||
@@ -681,10 +584,8 @@ class Jsonq | |||
public function toJson() | |||
{ | |||
$this->prepare(); | |||
return json_encode($this->_map); | |||
} | |||
/** | |||
* getting all keys from prepared data | |||
* | |||
@@ -694,10 +595,8 @@ class Jsonq | |||
public function keys() | |||
{ | |||
$this->prepare(); | |||
return array_keys($this->_map); | |||
} | |||
/** | |||
* getting all values from prepared data | |||
* | |||
@@ -707,10 +606,8 @@ class Jsonq | |||
public function values() | |||
{ | |||
$this->prepare(); | |||
return array_values($this->_map); | |||
} | |||
/** | |||
* getting chunk values from prepared data | |||
* | |||
@@ -722,10 +619,8 @@ class Jsonq | |||
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); | |||
@@ -735,7 +630,7 @@ class Jsonq | |||
} | |||
return count($chunks) > 0 ? $chunks : null; | |||
} | |||
return $chunk_value; | |||
} | |||
} | |||
?> |
@@ -4,4 +4,5 @@ if (!defined('DEDEINC')) exit('dedebiz'); | |||
* This class represents a query result where a given | |||
* value was queried but did not exist. | |||
*/ | |||
class ValueNotFound {} | |||
class ValueNotFound {} | |||
?> |
@@ -1,4 +1,4 @@ | |||
获得作者名称 | |||
作者名称标签 | |||
>>dede>> | |||
{dede:adminname/} | |||
>>dede>> |
@@ -1,4 +1,4 @@ | |||
文档列表调用标记 | |||
文档列表标签 | |||
>>dede>> | |||
{dede:arclist typeid='' row='' col='' titlelen='' flag='h' infolen='' imgwidth='' imgheight='' listtype='' orderby='' keyword='' limit='0,1'} | |||
<a href='[field:arcurl/]'>[field:title/]</a> | |||
@@ -1,4 +1,4 @@ | |||
自定义模型的文档列表调用标记 | |||
自定义模型文档列表标签 | |||
>>dede>> | |||
{dede:arclistsg typeid='' row='' flag='h' col='' titlelen='' orderway='' keyword='' limit='0,1'} | |||
<a href='[field:arcurl/]'>[field:title/]</a> | |||
@@ -1,13 +1,11 @@ | |||
问答调用标签 | |||
问答标签 | |||
>>dede>> | |||
{dede:ask row='6' qtype='new' tid='0' titlelen='24'} | |||
<dd> | |||
<span class="tclass">[<a href='[field:typeurl/]'>[field:tidname/]</a>]</span> | |||
<span class="tlink"><a href="[field:url/]">[field:title/]</a></span> | |||
</dd> | |||
{dede:ask row='6' qtype='new' tid='0' titlelen='30'} | |||
[<a href='[field:typeurl/]'>[field:tidname/]</a>] | |||
<a href="[field:url/]">[field:title/]</a> | |||
{/dede:ask} | |||
>>dede>> | |||
row='6' 调用条数 | |||
qtype='new' 排序类型commend推荐、ok表示已解决问题、high高分问题 、new最新问题 | |||
tid='0' 栏目id,默认是全部 | |||
titlelen='24' 标题长度 | |||
titlelen='30' 标题长度 |
@@ -1,4 +1,4 @@ | |||
按排序位置的获取单个栏目的链接信息 | |||
按排序位置获取单个栏目链接信息 | |||
>>dede>> | |||
{dede:autochannel partsort='' typeid=''}{/dede:autochannel} | |||
>>dede>> | |||
@@ -1,13 +1,9 @@ | |||
连载图书最新文档调用 | |||
连载图书最新文档标签 | |||
>>dede>> | |||
{dede:bookcontentlist row='12' booktype='-1' orderby='lastpost' author='' keyword=''} | |||
<table width="100%" cellspacing="2" cellpadding="2"> | |||
<tr> | |||
<td width='40%'>[[field:cataloglink/]] [field:booklink/]</td> | |||
<td width='40%'>[field:contentlink/]</td> | |||
<td width='20%'>[field:lastpost function="GetDateMk(@me)"/]</td> | |||
</tr> | |||
</table> | |||
[field:cataloglink/] [field:booklink/] | |||
[field:contentlink/] | |||
[field:lastpost function="GetDateMk(@me)"/] | |||
{/dede:bookcontentlist} | |||
>>dede>> | |||
这个标签和booklist实际是完全相同的,只是默认底层模板不同 | |||
@@ -1,4 +1,4 @@ | |||
连载图书调用 | |||
连载图书标签 | |||
>>dede>> | |||
{dede:booklist row='12' booktype='-1' orderby='lastpost' author='' keyword=''} | |||
<a href='[field:bookurl/]'>[field:bookname/]</a> | |||
@@ -1,7 +1,7 @@ | |||
获取栏目列表标签 | |||
>>dede>> | |||
{dede:channel type='top' typeid='' notypeid='' row='8' currentstyle="<li><a href='~typelink~' class='thisclass'>~typename~</a></li>"} | |||
<li><a href='[field:typelink/]'>[field:typename/]</a> </li> | |||
<li><a href='[field:typelink/]'>[field:typename/]</a></li> | |||
{/dede:channel} | |||
>>dede>> | |||
typeid='' 调用栏目id,用英文逗号分开表示多个栏目 | |||
@@ -1,21 +1,19 @@ | |||
获取当前栏目的下级栏目的文档列表标签 | |||
当前栏目下级栏目文档列表标签 | |||
>>dede>> | |||
{dede:channelartlist typeid='' notypeid='' row='6'} | |||
<dl> | |||
<dt><a href='{dede:field name='typeurl'/}'>{dede:field name='typename'/}</a></dt> | |||
<dd> | |||
<ul> | |||
<li><a href='{dede:field name='typeurl'/}'>{dede:field name='typename'/}</a> | |||
{dede:arclist titlelen='42' row='10'} | |||
<ul class='autod'> | |||
<ul> | |||
<li><a href="[field:arcurl/]">[field:title/]</a></li> | |||
<li>([field:pubdate function="MyDate('m-d',@me)"/])</li> | |||
</ul> | |||
{/dede:arclist} | |||
</dd> | |||
</dl> | |||
</li> | |||
{/dede:channelartlist} | |||
>>dede>> | |||
typeid='' 调用栏目id,用英文逗号分开表示多个栏目 | |||
notypeid='' 不调用栏目id,用英文逗号分开表示多个栏目 | |||
row='20' 获取的栏目返回值 | |||
除了宏标记外,channelArtlist 是唯一一个可以直接嵌套其它标记的标记,不过仅限于嵌套 | |||
{dede:type}{/dede:type}和{dede:arclist}{/dede:arclist}两个标记 | |||
除了宏标签外,channelArtlist 是唯一一个可以直接嵌套其它标签的标签,不过仅限于嵌套 | |||
{dede:type}{/dede:type}和{dede:arclist}{/dede:arclist}两个标签 |
@@ -1,4 +1,4 @@ | |||
这仅是一个演示标签 | |||
演示标签 | |||
>>dede>> | |||
{dede:demotag/} | |||
>>dede>> | |||
@@ -1,10 +1,8 @@ | |||
调用最新评论 | |||
调用最新评论标签 | |||
>>dede>> | |||
{dede:feedback} | |||
<ul> | |||
<li class='fbtitle'>[field:username function="(@me=='guest' ? '游客' : @me)"/]对[field:title/]的评论:</li> | |||
<li class='fbmsg'><a href="apps/feedback.php?aid=[field:aid/]">[field:msg/]</a></li> | |||
</ul> | |||
[field:username function="(@me=='guest' ? '游客' : @me)"/]对[field:title/]的评论 | |||
<a href="apps/feedback.php?aid=[field:aid/]">[field:msg/]</a></li> | |||
{/dede:feedback} | |||
>>dede>> | |||
row='12' 调用评论条数 | |||
@@ -1,9 +1,9 @@ | |||
友情链接 | |||
友情链接标签 | |||
>>dede>> | |||
{dede:flink row='24'/} | |||
{dede:flink row='30'/} | |||
>>dede>> | |||
type='image' 或textall,图片链接,text文字链接; | |||
row='24' 链接数量 | |||
row='30' 链接数量 | |||
titlelen='24' 站点文字的长度 | |||
linktype='1' 链接位置(1首页,2内页) | |||
typeid='0' 所有类型 | |||
typeid='0' 所有类型 |
@@ -1,10 +1,8 @@ | |||
圈子调用标签 | |||
圈子标签 | |||
>>dede>> | |||
{dede:group row='6' orderby='threads' titlelen='30'} | |||
<li> | |||
<span><img style="visibility: inherit;" title="[field:groupname/]" src="[field:icon/]" /></span> | |||
<span><a href="[field:url/]" title="[field:groupname/]" target="_blank">[field:groupname/]</a></span> | |||
</li> | |||
<img style="visibility: inherit;" title="[field:groupname/]" src="[field:icon/]"> | |||
<a href="[field:url/]" title="[field:groupname/]" target="_blank">[field:groupname/]</a> | |||
{/dede:group} | |||
>>dede>> | |||
row='6' 调用条数 | |||
@@ -1,10 +1,8 @@ | |||
圈子主题调用标签 | |||
圈子主题标签 | |||
>>dede>> | |||
{dede:groupthread gid='0' orderby='dateline' orderway='desc' row='12' titlelen='30'} | |||
<li> | |||
<a href='[field:groupurl/]' target="_blank">[[field:groupname function="cn_substr(@me,10)"/]]</a> | |||
<a href="[field:url/]" title="[field:subject/]" target="_blank">[field:subject/]</a>([field:lastpost function="GetDateMk('@me')"/]) | |||
</li> | |||
{/dede:groupthread} | |||
>>dede>> | |||
gid='0' 圈子id,默认为全部 | |||
@@ -1,4 +1,4 @@ | |||
获取网站搜索的热门关键词 | |||
网站搜索热门关键词标签 | |||
>>dede>> | |||
{dede:hotwords/} | |||
>>dede>> | |||
@@ -1,4 +1,4 @@ | |||
分类信息的地区与小分类搜索 | |||
分类信息地区与小分类搜索标签 | |||
>>dede>> | |||
{dede:infoguide/} | |||
>>dede>> |
@@ -1,4 +1,4 @@ | |||
分类信息地区与类型快捷链接 | |||
分类信息地区与类型快捷链接标签 | |||
>>dede>> | |||
{dede:infolink/} | |||
>>dede>> |
@@ -1,7 +1,9 @@ | |||
JSONQ标签 | |||
>>dede>> | |||
{dede:jsonq url='https://www.dedebiz.com/api/v1/ping' path='list' cachetime=3600}[field:id/] - [field:name/]<br/>{/dede:jsonq} | |||
{dede:jsonq url='https://www.dedebiz.com/api/v1/ping' path='list' cachetime='3600'} | |||
<a href="[field:arcurl/]">[field:title/]</a> | |||
{/dede:json} | |||
>>dede>> | |||
url='' JSON接口地址 | |||
path='' 路径(可选),如果为空[field:path/]可获取指定path的值 | |||
cachetime=3600 缓存时间 | |||
cachetime='3600' 缓存时间 |
@@ -1,4 +1,4 @@ | |||
单页文档相同标识调用标签 | |||
单页文档相同标识标签 | |||
>>dede>> | |||
{dede:likepage likeid='' row=''/} | |||
>>dede>> | |||
@@ -1,4 +1,4 @@ | |||
单页文档调用标签 | |||
单页文档标签 | |||
>>dede>> | |||
{dede:likespage row=''/} | |||
>>dede>> |
@@ -1,4 +1,4 @@ | |||
调用任意表的数据标签 | |||
任意表数据标签 | |||
>>dede>> | |||
{dede:loop table='dede_archives' sort='' row='4' if=''} | |||
<a href='[field:arcurl/]'>[field:title/]</a> | |||
@@ -1,4 +1,4 @@ | |||
会员信息调用标签 | |||
会员信息标签 | |||
>>dede>> | |||
{dede:memberlist orderby='scores' row='20'} | |||
<a href="../user/index.php?uid={dede:field.userid/}">{dede:field.userid/}</a> | |||
@@ -1,4 +1,4 @@ | |||
广告调用 | |||
广告标签 | |||
>>dede>> | |||
{dede:myad name=''/} | |||
>>dede>> | |||
@@ -1,6 +1,6 @@ | |||
自定义宏标记调用标签 | |||
自定义宏标标签 | |||
>>dede>> | |||
{dede:mytag typeid='0' name=''/} | |||
>>dede>> | |||
typeid='0' 栏目id,0为全站栏目 | |||
name='' 标记名 | |||
name='' 标签名 |
@@ -1,8 +1,8 @@ | |||
子栏目调用标签 | |||
子栏目标签 | |||
>>dede>> | |||
{dede:sonchannel} | |||
<a href='[field:typeurl/]'>[field:typename/]</a> | |||
{/dede:sonchannel} | |||
>>dede>> | |||
row='100' 返回数目 | |||
col='1' 默认单列显示 | |||
col='1' 默认单列显示 |
@@ -1,4 +1,4 @@ | |||
TAG调用标签 | |||
TAG标签 | |||
>>dede>> | |||
{dede:tag row='30' sort='new'/} | |||
>>dede>> | |||
@@ -1,4 +1,4 @@ | |||
指定的单个栏目的链接标签 | |||
指定单个栏目数据标签 | |||
>>dede>> | |||
{dede:type} | |||
<a href="[field:typelink/]">[field:typename/]</a> | |||
@@ -1,5 +1,4 @@ | |||
<?php | |||
/** | |||
* JSONQ标签 | |||
* | |||
@@ -16,9 +15,7 @@ function lib_jsonq(&$ctag, &$refObj) | |||
$attlist = "url|,path|,cachetime|3600"; | |||
FillAttsDefault($ctag->CAttribute->Items, $attlist); | |||
extract($ctag->CAttribute->Items, EXTR_SKIP); | |||
$Innertext = trim($ctag->GetInnerText()); | |||
if ($url == '' || $Innertext == '') return ''; | |||
$key = md5($url); | |||
try { | |||
@@ -42,7 +39,6 @@ function lib_jsonq(&$ctag, &$refObj) | |||
SetCache("tagjsonq2", $key, $revalue, $cachetime); | |||
return $revalue; | |||
} | |||
$row = GetCache("tagjsonq", $key); | |||
if (!is_array($row) || $cachetime == 0) { | |||
$jsonq = new Jsonq($url); | |||
@@ -52,14 +48,11 @@ function lib_jsonq(&$ctag, &$refObj) | |||
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) { | |||
@@ -75,9 +68,9 @@ function lib_jsonq(&$ctag, &$refObj) | |||
} | |||
$revalue .= $ctp->GetResult(); | |||
} | |||
return $revalue; | |||
} catch (Exception $e) { | |||
return ""; | |||
} | |||
} | |||
?> |