eZ Publish  [4.0]
eztemplatelocaleoperator.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZTemplateLocaleOperator class
00004 //
00005 // Created on: <01-Mar-2002 13:49:40 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 eZTemplateLocaleOperator eztemplatelocaleoperator.php
00033   \ingroup eZTemplateOperators
00034   \brief Locale aware conversions and output using operator "l10n"
00035 
00036   This class takes care of converting variables and displaying them
00037   according to their locale settings.
00038   The class has one operator called l10n (short for localization) which
00039   takes one parameter which is localization type.
00040   Supported types are time, shorttime, date, shortdate, currency and number.
00041 
00042 \code
00043 // Example template code
00044 {$curdate|l10n(date)}
00045 {$cash|l10n(currency)}
00046 \endcode
00047 */
00048 
00049 //include_once( "lib/ezlocale/classes/ezlocale.php" );
00050 //include_once( 'lib/ezlocale/classes/ezdatetime.php' );
00051 
00052 class eZTemplateLocaleOperator
00053 {
00054     /*!
00055      Initializes the object with the default locale.
00056      \note Add support for specifying the locale object.
00057     */
00058     function eZTemplateLocaleOperator()
00059     {
00060         $this->Operators = array( 'l10n', 'locale', 'datetime', 'currentdate', 'maketime', 'makedate', 'gettime' );
00061         $this->LocaleName = 'l10n';
00062         $this->LocaleFetchName = 'locale';
00063         $this->DateTimeName = 'datetime';
00064         $this->CurrentDateName = 'currentdate';
00065         $this->MakeTimeName = 'maketime';
00066         $this->MakeDateName = 'makedate';
00067         $this->GetTimeName = 'gettime';
00068     }
00069 
00070     /*!
00071      Returns array with l10n.
00072     */
00073     function operatorList()
00074     {
00075         return $this->Operators;
00076     }
00077 
00078     /*!
00079      Returns a list with hints for the template compiler.
00080     */
00081     function operatorTemplateHints()
00082     {
00083         $hints = array(
00084             $this->LocaleName      => array( 'input' => true, 'output' => true, 'parameters' => true,
00085                                              'transform-parameters' => true, 'input-as-parameter' => 'always',
00086                                              'element-transformation' => true,
00087                                              'element-transformation-func' => 'l10nTransformation' ),
00088             $this->LocaleFetchName      => array( 'input' => true, 'output' => true, 'parameters' => true,
00089                                                   'transform-parameters' => true, 'input-as-parameter' => 'always',
00090                                                   'element-transformation' => false ),
00091             $this->DateTimeName    => array( 'input' => true, 'output' => true, 'parameters' => true,
00092                                              'transform-parameters' => true, 'input-as-parameter' => 'always',
00093                                              'element-transformation' => true,
00094                                              'element-transformation-func' => 'dateTimeTransformation' ),
00095             $this->CurrentDateName => array( 'input' => false, 'output' => true, 'parameters' => false,
00096                                              'transform-parameters' => true, 'input-as-parameter' => false,
00097                                              'element-transformation' => true,
00098                                              'element-transformation-func' => 'currentDateTransformation' ),
00099             $this->MakeTimeName    => array( 'input' => true, 'output' => true, 'parameters' => true,
00100                                              'transform-parameters' => true, 'input-as-parameter' => false,
00101                                              'element-transformation' => true,
00102                                              'element-transformation-func' => 'makeDateTimeTransformation' ),
00103             $this->MakeDateName    => array( 'input' => true, 'output' => true, 'parameters' => true,
00104                                              'transform-parameters' => true, 'input-as-parameter' => false,
00105                                              'element-transformation' => true,
00106                                              'element-transformation-func' => 'makeDateTimeTransformation' ),
00107             $this->GetTimeName     => array( 'input' => true, 'output' => true, 'parameters' => 1,
00108                                              'transform-parameters' => true, 'input-as-parameter' => false,
00109                                              'element-transformation' => true,
00110                                              'element-transformation-func' => 'getTimeTransformation' )
00111         );
00112         return $hints;
00113     }
00114 
00115     /*!
00116      \return true to tell the template engine that the parameter list exists per operator type.
00117     */
00118     function namedParameterPerOperator()
00119     {
00120         return true;
00121     }
00122 
00123     /*!
00124      See eZTemplateOperator::namedParameterList
00125     */
00126     function namedParameterList()
00127     {
00128         return array( 'l10n' =>     array( 'type' =>      array( 'type' => 'string',  'required' => true,  'default' => false ),
00129                                            'locale' =>    array( 'type' => 'string',  'required' => false, 'default' => false ),
00130                                            'param' =>     array( 'type' => 'string',  'required' => false, 'default' => false ) ),
00131                       'datetime' => array( 'class' =>     array( 'type' => 'string',  'required' => true,  'default' => false ),
00132                                            'data' =>      array( 'type' => 'mixed',   'required' => false, 'default' => false ) ),
00133                       'gettime' =>  array( 'timestamp' => array( 'type' => 'integer', 'required' => false, 'default' => false ) ),
00134                       'maketime' => array( 'hour' =>      array( 'type' => 'integer', 'required' => false, 'default' => false ),
00135                                            'minute' =>    array( 'type' => 'integer', 'required' => false, 'default' => false ),
00136                                            'second' =>    array( 'type' => 'integer', 'required' => false, 'default' => false ),
00137                                            'month' =>     array( 'type' => 'integer', 'required' => false, 'default' => false ),
00138                                            'day' =>       array( 'type' => 'integer', 'required' => false, 'default' => false ),
00139                                            'year' =>      array( 'type' => 'integer', 'required' => false, 'default' => false ),
00140                                            'dst' =>       array( 'type' => 'integer', 'required' => false, 'default' => false ) ),
00141                       'makedate' => array( 'month' =>     array( 'type' => 'integer', 'required' => false, 'default' => false ),
00142                                            'day' =>       array( 'type' => 'integer', 'required' => false, 'default' => false ),
00143                                            'year' =>      array( 'type' => 'integer', 'required' => false, 'default' => false ),
00144                                            'dst' =>       array( 'type' => 'integer', 'required' => false, 'default' => false ) ) );
00145     }
00146 
00147     /*!
00148      Transforms
00149      */
00150     function l10nTransformation( $operatorName, &$node, $tpl, &$resourceData,
00151                                  $element, $lastElement, $elementList, $elementTree, &$parameters )
00152     {
00153         $values = array();
00154         $newElements = array();
00155 
00156         $newElements[] = eZTemplateNodeTool::createCodePieceElement( '// l10nTransformation begin' . "\n" );
00157         $newElements[] = eZTemplateNodeTool::createCodePieceElement( '//include_once("lib/ezlocale/classes/ezlocale.php");' . "\n" );
00158         $values[] = $parameters[0];
00159 
00160         if ( count( $parameters ) > 2 )
00161         {
00162             $values[] = $parameters[2];
00163             $newElements[] = eZTemplateNodeTool::createCodePieceElement( "\$locale = eZLocale::instance( %2% );\n", $values );
00164         }
00165         else
00166         {
00167             $values[] = false;
00168             $newElements[] = eZTemplateNodeTool::createCodePieceElement( "\$locale = eZLocale::instance();\n" );
00169         }
00170 
00171         if ( !eZTemplateNodeTool::isStaticElement( $parameters[1] ) )
00172         {
00173             $newElements[] = eZTemplateNodeTool::createCodePieceElement( '// l10nTransformation: not static' . "\n" );
00174             $values[] = $parameters[1];
00175 
00176             $code = "%tmp1% = \$locale->getFormattingFunction( %3% );\n";
00177             $code .= "if ( %tmp1% )\n";
00178             $code .= "{\n";
00179             $code .= "    if ( %3% === 'currency' )\n";
00180             if ( count( $parameters ) > 3 )
00181             {
00182                 $values[] = $parameters[3];
00183                 $code .= "        if( %4% === false )\n";
00184                 $code .= "            %output% = \$locale->%tmp1%( %1%, \$locale->attribute( 'currency_symbol' ) );\n";
00185                 $code .= "        else\n";
00186                 $code .= "            %output% = \$locale->%tmp1%( %1%, %4% );\n";
00187 
00188             }
00189             else
00190             {
00191                 $code .= "        %output% = \$locale->%tmp1%( %1%, \$locale->attribute( 'currency_symbol' ) );\n";
00192             }
00193             $code .= "    else\n";
00194             $code .= "        %output% = \$locale->%tmp1%( %1% );\n";
00195             $code .= "}\n";
00196             $code .= "else\n";
00197             $code .= "    %output% = %1%;\n";
00198 
00199             $newElements[] = eZTemplateNodeTool::createCodePieceElement( $code, $values, false, 1 );
00200 
00201 
00202             $newElements[] = eZTemplateNodeTool::createCodePieceElement( '// l10nTransformation end' . "\n" );
00203             return $newElements;
00204         }
00205         else
00206         {
00207             $values[] = false;
00208             $newElements[] = eZTemplateNodeTool::createCodePieceElement( '// l10nTransformation: static' . "\n" );
00209             if ( ( $function = eZTemplateNodeTool::elementStaticValue( $parameters[1] ) ) !== false )
00210             {
00211                 $locale = eZLocale::instance();
00212                 $method = $locale->getFormattingFunction( $function );
00213 
00214                 if ( $method )
00215                 {
00216                     switch( $function )
00217                     {
00218                         case 'currency':
00219                             {
00220                                 if ( count( $parameters ) > 3 )
00221                                 {
00222                                     $values[] = $parameters[3];
00223                                     $newElements[] = eZTemplateNodeTool::createCodePieceElement( "if( %4% === false)\n%output% = \$locale->$method( %1%, \$locale->attribute( 'currency_symbol' ) );\nelse\n%output% = \$locale->$method( %1%, %4% );\n", $values );
00224                                 }
00225                                 else
00226                                 {
00227                                     $newElements[] = eZTemplateNodeTool::createCodePieceElement( "%output% = \$locale->$method( %1%, \$locale->attribute( 'currency_symbol' ) );\n", $values );
00228                                 }
00229 
00230                             } break;
00231                         default:
00232                             {
00233                                 $newElements[] = eZTemplateNodeTool::createCodePieceElement( "\n%output% = \$locale->$method( %1% );\n", $values );
00234                             } break;
00235                     }
00236                     return $newElements;
00237                 }
00238             }
00239         }
00240     }
00241 
00242     function dateTimeTransformation( $operatorName, &$node, $tpl, &$resourceData,
00243                                      $element, $lastElement, $elementList, $elementTree, &$parameters )
00244     {
00245         $values = array();
00246         $newElements = array();
00247         $paramCount = count( $parameters );
00248         if ( $paramCount < 2 )
00249         {
00250             return false;
00251         }
00252         if ( !eZTemplateNodeTool::isStaticElement( $parameters[1] ) )
00253         {
00254             return false;
00255         }
00256         else
00257         {
00258             $class = eZTemplateNodeTool::elementStaticValue( $parameters[1] );
00259         }
00260         if ( ( $class == 'custom' ) && ( $paramCount != 3 ) )
00261         {
00262             return false;
00263         }
00264 
00265         $newElements[] = eZTemplateNodeTool::createCodePieceElement( '//include_once("lib/ezlocale/classes/ezlocale.php");' . "\n" );
00266         $newElements[] = eZTemplateNodeTool::createCodePieceElement( '$locale = eZLocale::instance();' . "\n" );
00267 
00268         if ( $class == 'custom' )
00269         {
00270             $values[] = $parameters[0];
00271             $values[] = $parameters[2];
00272             $newElements[] = eZTemplateNodeTool::createCodePieceElement( "%output% = \$locale->formatDateTimeType( %2%, %1% );\n", $values );
00273             return $newElements;
00274 
00275         }
00276         else
00277         {
00278             $dtINI = eZINI::instance( 'datetime.ini' );
00279             $formats = $dtINI->variable( 'ClassSettings', 'Formats' );
00280             if ( array_key_exists( $class, $formats ) )
00281             {
00282                 $classFormat = addcslashes( $formats[$class], "'" );
00283                 $values[] = $parameters[0];
00284                 $newElements[] = eZTemplateNodeTool::createCodePieceElement( "%output% = \$locale->formatDateTimeType( '$classFormat', %1% );\n", $values );
00285                 return $newElements;
00286             }
00287         }
00288         return false;
00289     }
00290 
00291     function currentDateTransformation( $operatorName, &$node, $tpl, &$resourceData,
00292                                         $element, $lastElement, $elementList, $elementTree, &$parameters )
00293     {
00294         $newElements = array();
00295         $newElements[] = eZTemplateNodeTool::createCodePieceElement( "%output% = time();\n" );
00296         return $newElements;
00297     }
00298 
00299     function makeDateTimeTransformation( $operatorName, &$node, $tpl, &$resourceData,
00300                                          $element, $lastElement, $elementList, $elementTree, &$parameters )
00301     {
00302         $values = array();
00303         $arguments = array();
00304         $newElements = array();
00305         $paramCount = count( $parameters );
00306 
00307         if ( $operatorName == 'makedate' )
00308         {
00309             $arguments = array ( 0, 0, 0 );
00310         }
00311         for ( $i = 0; $i < $paramCount; ++$i )
00312         {
00313             if ( $parameters[$i] === null )
00314             {
00315                 break;
00316             }
00317             $values[] = $parameters[$i];
00318             $arguments[] = '%' . ($i + 1) . '%';
00319         }
00320 
00321         $code = count( $arguments ) == 0 ? "%output% = time();\n" : "%output% = mktime( " . implode( ', ', $arguments ) . " );\n";
00322         $newElements[] = eZTemplateNodeTool::createCodePieceElement( $code, $values );
00323         return $newElements;
00324     }
00325 
00326     function getTimeTransformation( $operatorName, &$node, $tpl, &$resourceData,
00327                                     $element, $lastElement, $elementList, $elementTree, &$parameters )
00328     {
00329         $newElements = array();
00330         $values = array();
00331         $paramCount = count( $parameters );
00332 
00333         if ( $paramCount == 1 )
00334         {
00335             $values[] = $parameters[0];
00336             $code = "%tmp1% = %1%;\n";
00337         }
00338         else if ( $paramCount == 0 )
00339         {
00340             $code = "%tmp1% = time();\n";
00341         }
00342         else
00343         {
00344             return false;
00345         }
00346         $newElements[] = eZTemplateNodeTool::createCodePieceElement(
00347             $code .
00348             "%tmp2% = getdate( %tmp1% );\n".
00349             "%tmp3% = date( 'W', %tmp1% );\n".
00350             "if ( %tmp2%['wday'] == 0 )\n{\n\t++%tmp3%;\n}\n".
00351             "%output% = array( 'seconds' => %tmp2%['seconds'],
00352               'minutes' => %tmp2%['minutes'],
00353               'hours' => %tmp2%['hours'],
00354               'day' => %tmp2%['mday'],
00355               'month' => %tmp2%['mon'],
00356               'year' => %tmp2%['year'],
00357               'weeknumber' => %tmp3%,
00358               'weekday' => %tmp2%['wday'],
00359               'yearday' => %tmp2%['yday'],
00360               'epoch' => %tmp2%[0] );\n", $values, false, 3);
00361         return $newElements;
00362     }
00363 
00364     /*!
00365      Converts the variable according to the locale type.
00366      Allowed types are:
00367      - time
00368      - shorttime
00369      - date
00370      - shortdate
00371      - currency
00372      - clean_currency
00373      - number
00374     */
00375     function modify( $tpl, $operatorName, $operatorParameters, $rootNamespace, $currentNamespace, &$operatorValue, $namedParameters,
00376                      $placement )
00377     {
00378         if ( $operatorName == $this->LocaleFetchName )
00379         {
00380             if ( $operatorValue !== null )
00381             {
00382                 $localeString = $operatorValue;
00383             }
00384             else
00385             {
00386                 if ( count( $operatorParameters ) < 1 )
00387                 {
00388                     $tpl->missingParameter( $operatorName, 'localestring' );
00389                     return;
00390                 }
00391                 $localeString = $tpl->elementValue( $operatorParameters[0], $rootNamespace, $currentNamespace, $placement, true );
00392             }
00393             $locale = eZLocale::instance( $localeString );
00394             $operatorValue = $locale;
00395             return;
00396         }
00397         $locale = eZLocale::instance();
00398         if ( $operatorName == $this->GetTimeName )
00399         {
00400             $timestamp = $operatorValue;
00401             if ( $timestamp === null )
00402                 $timestamp = $namedParameters['timestamp'];
00403 
00404             if ( !$timestamp )
00405                 $timestamp = time();
00406 
00407             $info = getdate( $timestamp );
00408             $week = date( 'W', $timestamp );
00409             if ( $info['wday'] == 0 )
00410                 ++$week;
00411             $operatorValue = array( 'seconds' => $info['seconds'],
00412                                     'minutes' => $info['minutes'],
00413                                     'hours' => $info['hours'],
00414                                     'day' => $info['mday'],
00415                                     'month' => $info['mon'],
00416                                     'year' => $info['year'],
00417                                     'weeknumber' => $week,
00418                                     'weekday' => $info['wday'],
00419                                     'yearday' => $info['yday'],
00420                                     'epoch' => $info[0] );
00421         }
00422         else if ( $operatorName == $this->MakeTimeName )
00423         {
00424             $parameters = array();
00425             if ( $namedParameters['hour'] !== false )
00426                 $parameters[] = $namedParameters['hour'];
00427             if ( $namedParameters['minute'] !== false )
00428                 $parameters[] = $namedParameters['minute'];
00429             if ( $namedParameters['second'] !== false )
00430                 $parameters[] = $namedParameters['second'];
00431             if ( $namedParameters['month'] !== false )
00432                 $parameters[] = $namedParameters['month'];
00433             {
00434                 if ( $namedParameters['day'] !== false )
00435                     $parameters[] = $namedParameters['day'];
00436                 {
00437                     if ( $namedParameters['year'] !== false )
00438                         $parameters[] = $namedParameters['year'];
00439                     {
00440                         if ( $namedParameters['dst'] !== false )
00441                             $parameters[] = $namedParameters['dst'];
00442                     }
00443                 }
00444             }
00445 
00446             $operatorValue = count( $parameters ) == 0 ? time() : call_user_func_array( 'mktime', $parameters );
00447         }
00448         else if ( $operatorName == $this->MakeDateName )
00449         {
00450             $parameters = array( 0, 0, 0 );
00451             if ( $namedParameters['month'] !== false )
00452                 $parameters[] = $namedParameters['month'];
00453             {
00454                 if ( $namedParameters['day'] !== false )
00455                     $parameters[] = $namedParameters['day'];
00456                 {
00457                     if ( $namedParameters['year'] !== false )
00458                         $parameters[] = $namedParameters['year'];
00459                     {
00460                         if ( $namedParameters['dst'] !== false )
00461                             $parameters[] = $namedParameters['dst'];
00462                     }
00463                 }
00464             }
00465             $operatorValue = call_user_func_array( 'mktime', $parameters );
00466         }
00467         else if ( $operatorName == $this->CurrentDateName )
00468         {
00469             $operatorValue = time();
00470         }
00471         else if ( $operatorName == $this->DateTimeName )
00472         {
00473             $class = $namedParameters['class'];
00474             if ( $class === null )
00475                 return;
00476             if ( $class == 'custom' )
00477             {
00478                 $operatorValue = $locale->formatDateTimeType( $namedParameters['data'], $operatorValue );
00479             }
00480             else
00481             {
00482                 $dtINI = eZINI::instance( 'datetime.ini' );
00483                 $formats = $dtINI->variable( 'ClassSettings', 'Formats' );
00484                 if ( array_key_exists( $class, $formats ) )
00485                 {
00486                     $classFormat = $formats[$class];
00487                     $operatorValue = $locale->formatDateTimeType( $classFormat, $operatorValue );
00488                 }
00489                 else
00490                     $tpl->error( $operatorName, "DateTime class '$class' is not defined", $placement );
00491             }
00492         }
00493         else if ( $operatorName == $this->LocaleName )
00494         {
00495             $type = $namedParameters['type'];
00496             if ( $type === null )
00497                 return;
00498 
00499             $localeString = $namedParameters['locale'];
00500             $param = $namedParameters['param'];
00501 
00502             // change locale if need
00503             if ( $localeString )
00504                 $locale = eZLocale::instance( $localeString );
00505 
00506             $method = $locale->getFormattingFunction( $type );
00507             if ( $method )
00508             {
00509                 switch ( $type )
00510                 {
00511                     case 'currency':
00512                         {
00513                             if ( $param === false )
00514                                 $param = $locale->attribute( 'currency_symbol' );
00515 
00516                             $operatorValue = $locale->$method( $operatorValue, $param );
00517                         } break;
00518 
00519                     default:
00520                         {
00521                             $operatorValue = $locale->$method( $operatorValue );
00522                         } break;
00523                 }
00524             }
00525             else
00526             {
00527                 $tpl->error( $operatorName, "Unknown locale type: '$type'", $placement );
00528             }
00529         }
00530     }
00531 
00532     /// \privatesection
00533     /// The operator array
00534     public $Operators;
00535     /// A reference to the locale object
00536     public $Locale;
00537 
00538     public $LocaleName;
00539     public $DateTimeName;
00540     public $CurrentDateName;
00541 }
00542 
00543 ?>