eZ Publish  [4.0]
eztemplateincludefunction.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZTemplateIncludeFunction class
00004 //
00005 // Created on: <05-Mar-2002 13:55:25 amos>
00006 //
00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00008 // SOFTWARE NAME: eZ Publish
00009 // SOFTWARE RELEASE: 4.0.x
00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00011 // SOFTWARE LICENSE: GNU General Public License v2.0
00012 // NOTICE: >
00013 //   This program is free software; you can redistribute it and/or
00014 //   modify it under the terms of version 2.0  of the GNU General
00015 //   Public License as published by the Free Software Foundation.
00016 //
00017 //   This program is distributed in the hope that it will be useful,
00018 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //   GNU General Public License for more details.
00021 //
00022 //   You should have received a copy of version 2.0 of the GNU General
00023 //   Public License along with this program; if not, write to the Free
00024 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00025 //   MA 02110-1301, USA.
00026 //
00027 //
00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00029 //
00030 
00031 /*!
00032   \class eZTemplateIncludeFunction eztemplateincludefunction.php
00033   \ingroup eZTemplateFunctions
00034   \brief Includes external template code using function "include"
00035 
00036   Allows the template designer to include another template file
00037   dynamically. This allows for reuse of commonly used template code.
00038   The new template file will loaded into the current namespace or a
00039   namspace specified by the template designer, any extra parameters
00040   to this function is set as template variables for the template file
00041   using the newly aquired namespace.
00042 
00043 \code
00044 // Example template code
00045 {include uri=file:myfile.tpl}
00046 
00047 {include name=new_namespace uri=/etc/test.tpl}
00048 
00049 \endcode
00050 */
00051 
00052 class eZTemplateIncludeFunction
00053 {
00054     /*!
00055      Initializes the function with the function name $inc_name.
00056     */
00057     function eZTemplateIncludeFunction( $inc_name = "include" )
00058     {
00059         $this->IncludeName = $inc_name;
00060     }
00061 
00062     /*!
00063      Returns an array of the function names, required for eZTemplate::registerFunctions.
00064     */
00065     function functionList()
00066     {
00067         return array( $this->IncludeName );
00068     }
00069 
00070     function functionTemplateHints()
00071     {
00072         return array( $this->IncludeName => array( 'parameters' => true,
00073                                                    'static' => false,
00074                                                    'transform-children' => true,
00075                                                    'tree-transformation' => true,
00076                                                    'transform-parameters' => true ) );
00077     }
00078 
00079     function templateNodeTransformation( $functionName, &$node,
00080                                          $tpl, $parameters, $privateData )
00081     {
00082         if ( $functionName != $this->IncludeName )
00083             return false;
00084         $parameters = eZTemplateNodeTool::extractFunctionNodeParameters( $node );
00085         if ( !isset( $parameters['uri'] ) )
00086             return false;
00087 
00088         $uriData = $parameters['uri'];
00089         if ( !eZTemplateNodeTool::isStaticElement( $uriData ) )
00090             return false;
00091 
00092         $namespaceValue = false;
00093         $namespaceName = '$currentNamespace';
00094         if ( isset( $parameters['name'] ) )
00095         {
00096             $nameData = $parameters['name'];
00097             if ( !eZTemplateNodeTool::isStaticElement( $nameData ) )
00098                 return false;
00099             $namespaceValue = eZTemplateNodeTool::elementStaticValue( $nameData );
00100             $namespaceName = '$namespace';
00101         }
00102 
00103         $uriString = eZTemplateNodeTool::elementStaticValue( $uriData );
00104 
00105         $resourceName = "";
00106         $templateName = "";
00107         $resource = $tpl->resourceFor( $uriString, $resourceName, $templateName );
00108         $resourceData = $tpl->resourceData( $resource, $uriString, $resourceName, $templateName );
00109         $resourceData['use-comments'] = eZTemplateCompiler::isCommentsEnabled();
00110 
00111         $includeNodes = $resource->templateNodeTransformation( $functionName, $node, $tpl, $resourceData, $parameters, $namespaceValue );
00112         if ( $includeNodes === false )
00113             return false;
00114 
00115         $newNodes = array();
00116 
00117         $variableList = array();
00118         $uniqID = md5( uniqid('inc') );
00119         $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$oldRestoreIncludeArray" . "_$uniqID = isset( \$restoreIncludeArray ) ? \$restoreIncludeArray : array();\n".
00120                                                                "\$restoreIncludeArray = array();\n");
00121         foreach ( array_keys( $parameters ) as $parameterName )
00122         {
00123             if ( $parameterName == 'uri' or
00124                  $parameterName == 'name' )
00125                 continue;
00126             $parameterData =& $parameters[$parameterName];
00127             $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( isset( $namespaceName ) and isset( \$vars[$namespaceName]['$parameterName'] ) )\n".
00128                                                                    "    \$restoreIncludeArray[] = array( $namespaceName, '$parameterName', \$vars[$namespaceName]['$parameterName'] );\n".
00129                                                                    "elseif ( !isset( \$vars[( isset( $namespaceName ) ? $namespaceName : '' )]['$parameterName'] ) ) \n".
00130                                                                    "    \$restoreIncludeArray[] = array( ( isset( $namespaceName ) ? $namespaceName : '' ), '$parameterName', 'unset' );\n" );
00131 
00132             $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameterData, false, array(),
00133                                                                   array( $namespaceValue, eZTemplate::NAMESPACE_SCOPE_RELATIVE, $parameterName ) );
00134             $variableList[] = $parameterName;
00135         }
00136 
00137         $newNodes = array_merge( $newNodes, $includeNodes );
00138         // Restore previous variables, before including
00139         $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "foreach ( \$restoreIncludeArray as \$element )\n".
00140                                                                "{\n".
00141                                                                "    if ( \$element[2] === 'unset' )\n".
00142                                                                "    {\n".
00143                                                                "        unset( \$vars[\$element[0]][\$element[1]] );\n".
00144                                                                "        continue;\n".
00145                                                                "    }\n".
00146                                                                "    \$vars[\$element[0]][\$element[1]] = \$element[2];\n".
00147                                                                "}\n".
00148                                                                "\$restoreIncludeArray = \$oldRestoreIncludeArray" . "_$uniqID;\n" );
00149 
00150         return $newNodes;
00151     }
00152 
00153     /*!
00154      Loads the file specified in the parameter "uri" with namespace "name".
00155     */
00156     function process( $tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace )
00157     {
00158         $params = $functionParameters;
00159         if ( !isset( $params["uri"] ) )
00160         {
00161             $tpl->missingParameter( $this->IncludeName, "uri" );
00162             return false;
00163         }
00164         $uri = $tpl->elementValue( $params["uri"], $rootNamespace, $currentNamespace, $functionPlacement );
00165         $name = "";
00166         if ( isset( $params["name"] ) )
00167             $name = $tpl->elementValue( $params["name"], $rootNamespace, $currentNamespace, $functionPlacement );
00168         if ( $currentNamespace != "" )
00169         {
00170             if ( $name != "" )
00171                 $name = "$currentNamespace:$name";
00172             else
00173                 $name = $currentNamespace;
00174         }
00175         reset( $params );
00176         $whatParamsShouldBeUnset = array();
00177         $whatParamsShouldBeReplaced = array();
00178         while ( ( $key = key( $params ) ) !== null )
00179         {
00180             $item =& $params[$key];
00181             switch ( $key )
00182             {
00183                 case "name":
00184                 case "uri":
00185                     break;
00186 
00187                 default:
00188                 {
00189                     if ( !$tpl->hasVariable( $key, $name ) )
00190                     {
00191                         $whatParamsShouldBeUnset[] = $key; // Tpl vars should be removed after including
00192                     }
00193                     else
00194                     {
00195                         $whatParamsShouldBeReplaced[$key] = $tpl->variable( $key, $name ); // Tpl vars should be replaced after including
00196                     }
00197 
00198                     $item_value = $tpl->elementValue( $item, $rootNamespace, $currentNamespace, $functionPlacement );
00199                     $tpl->setVariable( $key, $item_value, $name );
00200                 } break;
00201             }
00202             next( $params );
00203         }
00204         eZTemplateIncludeFunction::handleInclude( $textElements, $uri, $tpl, $rootNamespace, $name );
00205         // unset var
00206         foreach ( $whatParamsShouldBeUnset as $key )
00207         {
00208             $tpl->unsetVariable( $key, $name );
00209         }
00210         // replace var
00211         foreach ( $whatParamsShouldBeReplaced as $key => $item_value )
00212         {
00213             $tpl->setVariable( $key, $item_value, $name );
00214         }
00215     }
00216 
00217     /*!
00218      \static
00219      Takes care of loading the template file and set it in the \a $text parameter.
00220     */
00221     static function handleInclude( &$textElements, &$uri, $tpl, $rootNamespace, $name )
00222     {
00223         $tpl->processURI( $uri, true, $extraParameters, $textElements, $name, $name );
00224     }
00225 
00226     /*!
00227      Returns false, telling the template parser that this is a single tag.
00228     */
00229     function hasChildren()
00230     {
00231         return false;
00232     }
00233 
00234     /// \privatesection
00235     /// The name of the include function
00236     public $IncludeName;
00237 }
00238 
00239 ?>