18 require_once SQ_INCLUDE_PATH.
'/asset.inc';
19 require_once SQ_CORE_PACKAGE_PATH.
'/data_source/data_source/data_source.inc';
20 require_once SQ_LIB_PATH.
'/html_form/html_form.inc';
44 parent::__construct($assetid);
57 $lock_types = parent::lockTypes();
58 $lock_types[
'json_data_source'] = ($lock_types[
'attributes'] | $lock_types[
'links']);
80 $allowed_link[
'asset'][
'card'] =
'M';
81 $allowed_link[
'asset'][
'exclusive'] = FALSE;
83 $links[SQ_LINK_TYPE_1] = $allowed_link;
84 $links[SQ_LINK_TYPE_2] = $allowed_link;
85 $links[SQ_LINK_TYPE_3] = $allowed_link;
86 $links[SQ_LINK_NOTICE] = $allowed_link;
106 if (empty($json_data)) {
111 $results = $this->_parse($json_data);
116 foreach ($results as &$asset) {
117 foreach ($asset as &$attr) {
118 if (is_array($attr)) {
119 $attr = self::_encodeJson($attr);
139 $source = $this->_getSource();
142 if (substr($source, 0, 2) ===
'a=') {
143 $source_asset = substr($source, 2);
144 $data = $this->_getAssetContents($source_asset);
148 $data = file_get_contents($source);
164 $GLOBALS[
'SQ_SYSTEM']->pm->startTimer($this);
166 $source = $this->_getSource();
168 if (!empty($source)) {
171 if (!isset($this->_tmp[$source])) {
174 $result = parent::getResultSet($source);
176 if ($result !== FALSE) {
177 $this->_tmp[$source] = $result;
179 $this->_tmp[$source] = $this->
getItems();
180 parent::setResultSet($this->_tmp[$source], $source);
184 $GLOBALS[
'SQ_SYSTEM']->pm->stopTimer($this);
185 return (!empty($source)) ? $this->_tmp[$source] : Array();
200 $cherry_pick_nodes = $this->
attr(
'nodes');
201 replace_global_keywords($cherry_pick_nodes);
203 return preg_split(
"/[\s,]+/", $cherry_pick_nodes);
218 if (empty($original_json_data))
return;
221 $results = $this->_parse($original_json_data);
222 if (empty($results))
return;
225 $output_json = self::_encodeJson($results);
226 if (empty($output_json))
return;
230 header(
'Content-type: application/json');
232 echo self::_formatJsonText($output_json);
242 private static function _convertJsPathToArray($js_string)
244 return explode(
'.', preg_replace(
"/\[(\d)\]/",
".$1", $js_string));
257 private function _decodeJson($json_data)
260 if (function_exists(
'json_decode')) {
261 $result = json_decode($json_data,
true);
263 require_once
'Services/JSON.php';
264 $json =
new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
265 $result = $json->decode($json_data);
268 if ($result === NULL) {
269 trigger_error($this->_getJsonParseError() .
': ' .$this->name.
' (Id: #'.$this->id.
')', E_USER_WARNING);
285 private function _encodeJson($arr)
288 if (function_exists(
'json_encode')) {
289 $result = json_encode($arr);
291 require_once
'Services/JSON.php';
292 $json =
new Services_JSON();
293 $result = $json->encodeUnsafe($arr);
295 if ($json->isError($result)) {
296 trigger_error($result->message, E_USER_WARNING);
313 private static function _formatJsonText($json)
320 for ($i = 0; $i <= strlen($json); $i++) {
321 $char = substr($json, $i, 1);
322 if ($char ==
'"') $quoting = !$quoting;
325 if($char ==
'}' || $char ==
']') {
328 for ($j = 0; $j < $pos; $j++) $result .= $indent;
335 if ($char ==
',' || $char ==
'{' || $char ==
'[') {
337 if ($char ==
'{' || $char ==
'[') $pos ++;
338 for ($j = 0; $j < $pos; $j++) $result .= $indent;
355 private static function _isAssociativeArray($a)
357 foreach (array_keys($a) as $key) {
358 if (is_string($key)) {
375 private static function _getArrayValueByJsPath($subject, $js_path_string)
377 $js_path = self::_convertJsPathToArray($js_path_string);
378 return self::_getArrayValueByKeyPath($subject, $js_path);
388 private static function _getArrayValueByKeyPath($subject, $key_path)
390 if (is_array($subject)) {
393 if (count($key_path) > 1) {
394 $next_level = array_shift($key_path);
395 if (array_key_exists($next_level, $subject)) {
396 return self::_getArrayValueByKeyPath($subject[$next_level], $key_path);
398 }
else if ((count($key_path) === 1) && array_key_exists($key_path[0], $subject)) {
400 return $subject[$key_path[0]];
418 private function _getAssetContents($assetid, $type_code=
'')
420 $asset_contents =
'';
421 $asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($assetid, $type_code);
423 if ($asset == NULL) {
424 trigger_error(
'Unable to load asset (Id: #'.$assetid.
')', E_USER_WARNING);
430 if (!$asset->readAccess()) {
431 trigger_error(
'No read permission for asset (Id: #'.$assetid.
')', E_USER_WARNING);
435 if ($asset instanceOf
File){
436 $existing = $asset->getExistingFile();
437 if (empty($existing) || !is_file($existing[
'path']))
return $asset_contents;
438 $asset_contents = file_get_contents($existing[
'path']);
442 $asset_contents = ob_get_contents();
446 return $asset_contents;
457 private function _getJsonParseError()
462 if (function_exists(
'json_last_error')) {
464 $error = json_last_error();
468 case JSON_ERROR_NONE:
469 return "No error has occurred";
471 case JSON_ERROR_DEPTH:
472 return "The maximum stack depth has been exceeded";
474 case JSON_ERROR_CTRL_CHAR:
475 return "Control character error, possibly incorrectly encoded";
477 case JSON_ERROR_STATE_MISMATCH:
478 return "Invalid or malformed JSON";
480 case JSON_ERROR_SYNTAX:
481 return "Syntax error";
486 return "JSON parse error";
498 private function _getSource()
502 $parameter_map_source_asset = $parameter_map->getParameterValue(
'source_asset');
503 if (!empty($parameter_map_source_asset)) {
507 if (assert_valid_assetid($parameter_map_source_asset,
'',
true,
false)) {
508 return 'a=' . $parameter_map_source_asset;
513 $link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_NOTICE,
'', TRUE,
'json_data_source');
515 return 'a=' . $link[
'minorid'];
519 $uri = $this->
attr(
'path');
521 replace_global_keywords($uri);
538 private function _parse($json_data)
541 $results = self::_decodeJson($json_data);
542 if (empty($results) || !is_array($results)){
547 $root_object = $this->
attr(
'root_object');
548 replace_global_keywords($root_object);
549 if (!empty($root_object)) {
550 $results = self::_getArrayValueByJsPath($results, $root_object);
551 if ($results == FALSE || !is_array($results))
return Array();
555 if (self::_isAssociativeArray($results) || !is_array($results[0])) {
556 $results = Array($results);
561 if (!empty($cherry_pick_nodes)) {
563 foreach ($results as &$asset) {
565 foreach ($cherry_pick_nodes as $attr) {
567 $value = self::_getArrayValueByJsPath($asset, $attr);
569 if ($value !== FALSE) {
571 if (strpos($attr,
'[')) {
572 $attr = preg_replace(
"/\[(\d)\]/",
"_$1", $attr);
574 $asset[$attr] = $value;