Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

properties for @CHUNK and @SNIPPET binding #15488

Merged
merged 4 commits into from Mar 9, 2021
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 28 additions & 3 deletions core/src/Revolution/modTemplateVar.php
Expand Up @@ -52,6 +52,7 @@ class modTemplateVar extends modElement
public $bindings = [
'FILE',
'CHUNK',
'SNIPPET',
'DOCUMENT',
'RESOURCE',
'SELECT',
Expand Down Expand Up @@ -832,12 +833,13 @@ public function getBindingDataFromValue($value)
$nvalue = trim($value);
$cmd = false;
$param = '';
$properties = [];
if (substr($nvalue, 0, 1) == '@') {
list($cmd, $param) = $this->parseBinding($nvalue);
list($cmd, $param, $properties) = $this->parseBinding($nvalue);
$cmd = trim($cmd);
}

return ['cmd' => $cmd, 'param' => $param];
return ['cmd' => $cmd, 'param' => $param, 'properties' => $properties];
}

/**
Expand Down Expand Up @@ -870,6 +872,7 @@ public function processBindings($value = '', $resourceId = 0, $preProcess = true
}
$cmd = $bdata['cmd'];
$param = !empty($bdata['param']) ? $bdata['param'] : null;
$properties = !empty($bdata['properties']) ? $bdata['properties'] : [];
switch ($cmd) {
case 'FILE':
if ($preProcess) {
Expand All @@ -879,9 +882,15 @@ public function processBindings($value = '', $resourceId = 0, $preProcess = true

case 'CHUNK': /* retrieve a chunk and process it's content */
if ($preProcess) {
$output = $this->xpdo->getChunk($param);
$output = $this->xpdo->getChunk($param, $properties);
}
break;

case 'SNIPPET':
if ($preProcess) {
$output = $this->xpdo->runSnippet($param, $properties);
}
break;

case 'RESOURCE':
case 'DOCUMENT': /* retrieve a document and process it's content */
Expand Down Expand Up @@ -986,11 +995,27 @@ public function parseBinding($binding_string)
$match = [];
$binding_string = trim($binding_string);
$regexp = '/@(' . implode('|', $this->bindings) . ')\s*(.*)/is'; /* Split binding on whitespace */

if (preg_match($regexp, $binding_string, $match)) {
/* We can't return the match array directly because the first element is the whole string */

$regexp2 = '/(\S+)\s+(.+)/is'; /* Split binding on second whitespace to get properties */

$properties = [];
if (preg_match($regexp2, $match[2] , $match2)) {
Bruno17 marked this conversation as resolved.
Show resolved Hide resolved
if (isset($match2[2])) {
$props = json_decode($match2[2],true);
if (is_array($props)){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it is useful to check for json_last_error instead and log the issue somehow.

See this method from https://stackoverflow.com/questions/6041741/fastest-way-to-check-if-a-string-is-json-in-php

function json_validate($string)
{
    // decode the JSON data
    $result = json_decode($string);

    // switch and check possible JSON errors
    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            $error = ''; // JSON is valid // No error has occurred
            break;
        case JSON_ERROR_DEPTH:
            $error = 'The maximum stack depth has been exceeded.';
            break;
        case JSON_ERROR_STATE_MISMATCH:
            $error = 'Invalid or malformed JSON.';
            break;
        case JSON_ERROR_CTRL_CHAR:
            $error = 'Control character error, possibly incorrectly encoded.';
            break;
        case JSON_ERROR_SYNTAX:
            $error = 'Syntax error, malformed JSON.';
            break;
        // PHP >= 5.3.3
        case JSON_ERROR_UTF8:
            $error = 'Malformed UTF-8 characters, possibly incorrectly encoded.';
            break;
        // PHP >= 5.5.0
        case JSON_ERROR_RECURSION:
            $error = 'One or more recursive references in the value to be encoded.';
            break;
        // PHP >= 5.5.0
        case JSON_ERROR_INF_OR_NAN:
            $error = 'One or more NAN or INF values in the value to be encoded.';
            break;
        case JSON_ERROR_UNSUPPORTED_TYPE:
            $error = 'A value of a type that cannot be encoded was given.';
            break;
        default:
            $error = 'Unknown JSON error occured.';
            break;
    }

    if ($error !== '') {
        // throw the Exception or exit // or whatever :)
        exit($error);
    }

    // everything is OK
    return $result;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such a validation method can go into in a global (helper) class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, testing and logging all possible mistakes. like valid json or not existing snippets, chunks... could be an additional feature request

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until then you can check for json_last_error and log a debug message with 'invalid JSON'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check added

$properties = $props;
$match[2] = $match2[1];
}
}
}

$binding_array = [
strtoupper($match[1]),
trim($match[2]),
$properties
]; /* Make command uppercase */

return $binding_array;
Expand Down