ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

PHP template problem

May 16, 2009 7:12pm

Subscribe [2]
  • #1 / May 16, 2009 7:12pm

    Mirage

    273 posts

    I have a PHP script that runs perfectly fine as a standalone script. It also runs great when ‘including’ it in an EE template, like so

    <?php include( $_SERVER['DOCUMENT_ROOT'].'/myscript.php' );?>

    I am making use heredoc notation in that script (urls obfuscated):

    $xsl = <<<EOT
    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="utf-8" indent="yes">
    <xsl:template match="/deals">
    <rss version="2.0">
        <channel>
            <title>Test</title>
            <link>http://host.tld/somefeed</link>
            <description>The description.</description>
            <language>en-us</language>
                    
            <xsl:for-each select="deal">
            <item>
              <title><xsl:value-of select="name"></title>
              <link>http://host.tld/somefeed/<xsl:value-of select="id"></link>
              <description><xsl:value-of select="background"></description>
              <xsl:value-of select="created-at"></pubDate>
            </item>
            </xsl:for-each>
        </channel>
    </rss>
    </xsl:template>
    </xsl:stylesheet>
    EOT;

    When I paste the entire script into an EE template it does not work. After some testing, I found that the culprit was the $xsl variable. It failed to parse in a subsequent function call. Apparently something in the template gets mangled before my PHP code gets a chance to execute.

    I also tried to replace the above with this in the template - but that also fails (PHP parsing set to output):

    $xsl='{embed="somefeeds/somexsl"}';
    
    // more code…

    The somexsl template was created as a ‘static’ template.

    The only work-around I found so far, is to encode the literal string (html_encode) and where I use it in the php I run it through html_entity_decode($xsl) first.

    Not exactly pretty, but I’d like to understand why the other options do not work. It appears as though the EE Template Parser does something I do not know or do not understand. I could most certainly make a plugin, but this seemed like a case where some simple php code in a template should do.

    Thanks for any feedback.
    Juergen

  • #2 / May 17, 2009 3:16pm

    Greg Aker

    6022 posts

    Mirage:

    What are you trying to accomplish with the xml?

    Also, what version/build of ExpressionEngine are you running?

    -greg

  • #3 / May 17, 2009 4:11pm

    Mirage

    273 posts

    Hi Greg -

    Using 1.6.7. The XML generated by the script is an RSS feed. I’m using the XSL to do the transform. The problem clearly is with the $xsl literal string. EE must be doing something to the template before PHP gets a shot at it.

    Thanks,
    Juergen

  • #4 / May 17, 2009 5:02pm

    Greg Aker

    6022 posts

    Mirage:

    Is there something in this XML that the Magpie plugin doesn’t accomplish?

    -greg

  • #5 / May 17, 2009 6:43pm

    Mirage

    273 posts

    Greg,

    I’ll check that out and get back to you. The idea/exercise for me was not to use a plugin but rather just a php enabled template. I’m perfectly capable of writing a plugin, but it really wasn’t necessary for what I wanted to accomplish.

    I assume it’s got something to do with the output types then (RSS or XML)?

    At any rate - my thinking goes along the lines that the Template Parser (or whatever is responsible here) should leave anything between my PHP tags alone (unless it’s EE tags. Maybe I’m just not experienced enough, but I’d have figured that’s the way it works.

    I’ll let you know on Magpie.

    Cheers,
    Juergen

  • #6 / May 17, 2009 7:09pm

    Mirage

    273 posts

    Ok, I checked that out real quick. I think you mis-understood.

    Magpie is an RSS parser. I’m not parsing RSS output. I’m transforming some remote xml response TO RSS. To accomplish that I use XSLT and the built-in php functionality. For completeness I’m posting the entire template code here. I have to post it as regular text because the forums [ code ] tags won’t show the encoding for the literal:

    <?php
    
    // StyleSheet
    $xsl = <<<EOT
    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="utf-8" indent="yes">
    <xsl:template match="/deals">
    <rss version="2.0">
        <channel>
            <title>Title</title>
            <link>http://host.tld/somefeed/</link>
            <description>The description</description>
            <language>en-us</language>
                    
            <xsl:for-each select="deal">
            <item>
              <title><xsl:value-of select="name"></title>
              <link>http://host.tld/somefeed/<xsl:value-of select="id"></link>
              <description><xsl:value-of select="background"></description>
              <xsl:value-of select="created-at"></pubDate>
            </item>
            </xsl:for-each>
        </channel>
    </rss>
    </xsl:template>
    </xsl:stylesheet>
    EOT;
    
    // API URL
    $url='host.tld/somefeed.xml';
    
    // Highrise requires a login or a token
    $token='abcdefghigklmnopqrstuvwxyz';
    
    
    // Get the XML
    $ch=curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://{$token}:X@{$url}");
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    
    $deals = curl_exec〈$ch〉;
    $info = curl_getinfo($ch);
    curl_close($ch);
    
    $xsl_doc = new DomDocument();
    $result=$xsl_doc->loadXML(html_entity_decode($xsl));
    
    $xml_doc = new DomDocument();
    $xml_doc->loadXML($deals);
    
    $proc = new XSLTProcessor();
    $proc->importStylesheet($xsl_doc);
    echo $proc->transformToXML($xml_doc);
    ?>

    Again, if I do not literally encode my $xsl variable, the template will fail. It works without the literal encoding if I just include this script or run it on it’s own (makes sense).

    Cheers,
    Juergen

  • #7 / May 17, 2009 7:46pm

    Mirage

    273 posts

    A’ight I found the problem.

    I worked through the core Template class, and in there is function named convert_xml_declaration. That’s the bugger. It messes up the literal XML declaration in my variable, hands the result to PHP and then boom she goes.

    I can cheat around it by doing this:

    <?php
    
    // StyleSheet
    $xsl =  '<?'.'xml version="1.0" encoding="utf-8"?>'. <<<EOT
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="utf-8" indent="yes">
    <xsl:template match="/deals">
    <rss version="2.0">
    ...
    ...

    In fact it seems that the PHP5 XSLT processor doesn’t even need the declaration in the XSL source. So I could skip it completely.

    From my quick scan through the template class it seems like this is the only stuff the parser messes with outside of EE tags and it does so for a reason. Perhaps it would be prudent to check if the xml declaration is part of a php source. Just thinking. It might be irrelevant for 2.x and it’s certainly a fringe case with a reasonable workaround. I’ll make a note in the user guide.

    Case closed, Watson.

  • #8 / May 18, 2009 1:16am

    John Henry Donovan

    12339 posts

    Glad you discovered a workaround. Feel free to start a new thread if you have any more questions.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases