We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 23276
    • 85 Posts
    Hello, all.
    We cannot use special characters in snippet call, but i want to use them, too.
    So, I tried to solve whole problem by parsing with Regex.
    It seems to behave well, though some tests are not enough for relation to other functions.

    Example of snippet call:
    [[Snippet? param1  =  `?= ‵ [] &‵ &` &param2= &param3=[]?= &param4 &param?5=`[[Lea más...]]`]]

    The result of parsing (var_dump $parameter):
    array
      'param1' => string '?= ` [] &` &' (length=11)
      'param2' => string '' (length=0)
      'param3' => string '[]?=' (length=4)
      'param5' => string '[[Lea más...]]' (length=15)


    The behavior of this hacked code

    • First parameter’s ’&’ is completed automatically (ex. param1)
    • Parameters doesn’t have value are ignored (ex. param4)
    • Every ’?’ in parameter’s name are cut (ex. param5)
    • When a value is quoted with ’`’, we can use special characters excluding ’`’ (ex. param1, 6)
    • When a value is not quoted with ’`’, we can use special characters excluding ’`’, ’&’, ’]]’ and space (ex. param2, 3)
    • Only when a value is quoted with ’`’, ’‵’ or ’&#x2035’ in the value is replaced with ’`’ (ex. param1)
    • Multi-byte characters also are parsed well on my local server (XAMPP+PHP 4.4.7 & PHP 5.2.4), but my tests are not enough (ex. param5)

    The difference between this code and original code

    • Space characters of left and right of parameters are trimmed. (ex. param1)
      (In the case of original code, I guess first parameter of Example is parsed as ’param1 ’ with space characters.)
    • ’&’ is parsed after parsing ’‵’ and ’&#x2035’.
      The code in snippet call like ’&paramx=`value`’ is parsed as a parameter ’&paramx’ and a value. (ex. param1)
      (In the case of original code, ’&’ are replaced with ’&’ at first. Then parameters are parsed.
      Therefore, I guess the code is parsed as a parameter ’&paramx’ and a value.)

    MODx 0.9.5-0.9.6.1
    method ’evalSnippets’ in /manager/includes/document.parser.class.inc.php
    (Line numbers are the one of version 0.9.6.1)

    line 784 (before):
        function evalSnippets($documentSource) {
            preg_match_all('~\[\[(.*?)\]\]~', $documentSource, $matches);

    line 784 (after):
        function evalSnippets($documentSource) {
            preg_match_all('~\[\[((?:.*?(?:`(?:[^`]|[^]]\])*?`)?)*?)\]\]~', $documentSource, $matches);



    line 836 (before):
                    // current params
                    $currentSnippetParams= $snippetParams[$i];
                    if (!empty ($currentSnippetParams)) {
                        $tempSnippetParams= str_replace("?", "", $currentSnippetParams);
                        $splitter= "&";
                        if (strpos($tempSnippetParams, "&") > 0)
                            $tempSnippetParams= str_replace("&", "&", $tempSnippetParams);
                        //$tempSnippetParams = html_entity_decode($tempSnippetParams, ENT_NOQUOTES, $this->config['etomite_charset']); //FS#334 and FS#456
                        $tempSnippetParams= split($splitter, $tempSnippetParams);
                        $snippetParamCount= count($tempSnippetParams);
                        for ($x= 0; $x < $snippetParamCount; $x++) {
                            if (strpos($tempSnippetParams[$x], '=', 0)) {
                                if ($parameterTemp= explode("=", $tempSnippetParams[$x])) {
                                    $fp= strpos($parameterTemp[1], '`');
                                    $lp= strrpos($parameterTemp[1], '`');
                                    if (!($fp === false && $lp === false))
                                        $parameterTemp[1]= substr($parameterTemp[1], $fp +1, $lp -1);
                                    $parameter[$parameterTemp[0]]= $parameterTemp[1];
                                }
                            }
                        }
                    }


    line 836 (after):
                    // current params
                    $currentSnippetParams= $snippetParams[$i];
                    if (!empty ($currentSnippetParams)) {
                        $tempSnippetParams= preg_replace("~^\s*\?\s*~", "", $currentSnippetParams);
                        $splitter= "&";
                        if (strpos($tempSnippetParams, $splitter) != 0)
                            $tempSnippetParams= $splitter . $tempSnippetParams;
                        //$tempSnippetParams = html_entity_decode($tempSnippetParams, ENT_NOQUOTES, $this->config['etomite_charset']); //FS#334 and FS#456
                        $snippetParamCount= preg_match_all("~" . $splitter
                                          . "([^" . $splitter . "=]*(?:=\s*`[^`]*`"
                                          . "|=[^" . $splitter . "\s]*"
                                          . "|[^" . $splitter . "]*))~", $tempSnippetParams, $matches);
                        $tempSnippetParams= @ $matches[1];
                        for ($x= 0; $x < $snippetParamCount; $x++) {
                            if (preg_match('~([^=\s]*)\s*=\s*`?([^`]*)`?~', $tempSnippetParams[$x], $parameterTemp)) {
                                $parameterTemp[2]= preg_replace("~&#0*8245;|&#x0*2035;~", "`", $parameterTemp[2]);
                                if (strpos($parameterTemp[2], "&") > 0)
                                    $parameterTemp[2]= str_replace("&", "&", $parameterTemp[2]);
                                $parameterTemp[1]= str_replace("?", "", $parameterTemp[1]);
                                $parameter[$parameterTemp[1]]= $parameterTemp[2];
                            }
                        }
                    }
      • 3749
      • 24,544 Posts
      Quote from: OpenGeek at Dec 11, 2007, 10:14 AM

      This has always been a known limitation of snippet parameter values; you cannot use ? & or =.

      The problem has been addressed for 0.9.7 release.

      A workaround is to replace those characters with AMP EQ and Q (or AMPERSAND, EQUALS, and QUESTIONMARK if you want to make sure to avoid collisions) in the snippet call and then convert them back at the top of your snippet. Just be sure to replace EQ before replacing Q if you use the short versions. wink

      Bob
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 1611
        • 591 Posts
        Sorry for upping thread. But I need to place special chars in snippet params.
        I noticed the solution above was in modx code, but sine some time the line was commented (I use modx 0.9.6.3):
        //    $tempSnippetParams = html_entity_decode($tempSnippetParams, ENT_NOQUOTES, $this->config[’etomite_charset’]); //FS#334 and FS#456
        I uncomment it, got my functionality, and didn’t get any errors (yet).

        What does it means //FS#334 and FS#456?
        And what problems should I expect after uncommenting this line?

        Thank you! A.