"Fossies" - the Fresh Open Source Software Archive

Member "smarty-3.1.34/libs/sysplugins/smarty_internal_compile_section.php" (28 Feb 2019, 18397 Bytes) of package /linux/www/smarty-3.1.34.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "smarty_internal_compile_section.php" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 3.1.32_vs_3.1.33.

    1 <?php
    2 /**
    3  * Smarty Internal Plugin Compile Section
    4  * Compiles the {section} {sectionelse} {/section} tags
    5  *
    6  * @package    Smarty
    7  * @subpackage Compiler
    8  * @author     Uwe Tews
    9  */
   10 
   11 /**
   12  * Smarty Internal Plugin Compile Section Class
   13  *
   14  * @package    Smarty
   15  * @subpackage Compiler
   16  */
   17 class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_ForeachSection
   18 {
   19     /**
   20      * Attribute definition: Overwrites base class.
   21      *
   22      * @var array
   23      * @see Smarty_Internal_CompileBase
   24      */
   25     public $required_attributes = array('name', 'loop');
   26 
   27     /**
   28      * Attribute definition: Overwrites base class.
   29      *
   30      * @var array
   31      * @see Smarty_Internal_CompileBase
   32      */
   33     public $shorttag_order = array('name', 'loop');
   34 
   35     /**
   36      * Attribute definition: Overwrites base class.
   37      *
   38      * @var array
   39      * @see Smarty_Internal_CompileBase
   40      */
   41     public $optional_attributes = array('start', 'step', 'max', 'show', 'properties');
   42 
   43     /**
   44      * counter
   45      *
   46      * @var int
   47      */
   48     public $counter = 0;
   49 
   50     /**
   51      * Name of this tag
   52      *
   53      * @var string
   54      */
   55     public $tagName = 'section';
   56 
   57     /**
   58      * Valid properties of $smarty.section.name.xxx variable
   59      *
   60      * @var array
   61      */
   62     public $nameProperties = array(
   63         'first', 'last', 'index', 'iteration', 'show', 'total', 'rownum', 'index_prev',
   64         'index_next', 'loop'
   65     );
   66 
   67     /**
   68      * {section} tag has no item properties
   69      *
   70      * @var array
   71      */
   72     public $itemProperties = null;
   73 
   74     /**
   75      * {section} tag has always name attribute
   76      *
   77      * @var bool
   78      */
   79     public $isNamed = true;
   80 
   81     /**
   82      * Compiles code for the {section} tag
   83      *
   84      * @param array                                 $args     array with attributes from parser
   85      * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
   86      *
   87      * @return string compiled code
   88      * @throws \SmartyCompilerException
   89      * @throws \SmartyException
   90      */
   91     public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
   92     {
   93         $compiler->loopNesting++;
   94         // check and get attributes
   95         $_attr = $this->getAttributes($compiler, $args);
   96         $attributes = array('name' => $compiler->getId($_attr[ 'name' ]));
   97         unset($_attr[ 'name' ]);
   98         foreach ($attributes as $a => $v) {
   99             if ($v === false) {
  100                 $compiler->trigger_template_error("'{$a}' attribute/variable has illegal value", null, true);
  101             }
  102         }
  103         $local = "\$__section_{$attributes['name']}_" . $this->counter++ . '_';
  104         $sectionVar = "\$_smarty_tpl->tpl_vars['__smarty_section_{$attributes['name']}']";
  105         $this->openTag($compiler, 'section', array('section', $compiler->nocache, $local, $sectionVar));
  106         // maybe nocache because of nocache variables
  107         $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
  108         $initLocal = array();
  109         $initNamedProperty = array();
  110         $initFor = array();
  111         $incFor = array();
  112         $cmpFor = array();
  113         $propValue = array(
  114             'index'     => "{$sectionVar}->value['index']", 'show' => 'true', 'step' => 1,
  115             'iteration' => "{$local}iteration",
  116         );
  117         $propType = array('index' => 2, 'iteration' => 2, 'show' => 0, 'step' => 0,);
  118         // search for used tag attributes
  119         $this->scanForProperties($attributes, $compiler);
  120         if (!empty($this->matchResults[ 'named' ])) {
  121             $namedAttr = $this->matchResults[ 'named' ];
  122         }
  123         if (isset($_attr[ 'properties' ]) && preg_match_all("/['](.*?)[']/", $_attr[ 'properties' ], $match)) {
  124             foreach ($match[ 1 ] as $prop) {
  125                 if (in_array($prop, $this->nameProperties)) {
  126                     $namedAttr[ $prop ] = true;
  127                 } else {
  128                     $compiler->trigger_template_error("Invalid property '{$prop}'", null, true);
  129                 }
  130             }
  131         }
  132         $namedAttr[ 'index' ] = true;
  133         $output = "<?php\n";
  134         foreach ($_attr as $attr_name => $attr_value) {
  135             switch ($attr_name) {
  136                 case 'loop':
  137                     if (is_numeric($attr_value)) {
  138                         $v = (int)$attr_value;
  139                         $t = 0;
  140                     } else {
  141                         $v = "(is_array(@\$_loop=$attr_value) ? count(\$_loop) : max(0, (int) \$_loop))";
  142                         $t = 1;
  143                     }
  144                     if ($t === 1) {
  145                         $initLocal[ 'loop' ] = $v;
  146                         $v = "{$local}loop";
  147                     }
  148                     break;
  149                 case 'show':
  150                     if (is_bool($attr_value)) {
  151                         $v = $attr_value ? 'true' : 'false';
  152                         $t = 0;
  153                     } else {
  154                         $v = "(bool) $attr_value";
  155                         $t = 3;
  156                     }
  157                     break;
  158                 case 'step':
  159                     if (is_numeric($attr_value)) {
  160                         $v = (int)$attr_value;
  161                         $v = ($v === 0) ? 1 : $v;
  162                         $t = 0;
  163                         break;
  164                     }
  165                     $initLocal[ 'step' ] = "((int)@$attr_value) === 0 ? 1 : (int)@$attr_value";
  166                     $v = "{$local}step";
  167                     $t = 2;
  168                     break;
  169                 case 'max':
  170                 case 'start':
  171                     if (is_numeric($attr_value)) {
  172                         $v = (int)$attr_value;
  173                         $t = 0;
  174                         break;
  175                     }
  176                     $v = "(int)@$attr_value";
  177                     $t = 3;
  178                     break;
  179             }
  180             if ($t === 3 && $compiler->getId($attr_value)) {
  181                 $t = 1;
  182             }
  183             $propValue[ $attr_name ] = $v;
  184             $propType[ $attr_name ] = $t;
  185         }
  186         if (isset($namedAttr[ 'step' ])) {
  187             $initNamedProperty[ 'step' ] = $propValue[ 'step' ];
  188         }
  189         if (isset($namedAttr[ 'iteration' ])) {
  190             $propValue[ 'iteration' ] = "{$sectionVar}->value['iteration']";
  191         }
  192         $incFor[ 'iteration' ] = "{$propValue['iteration']}++";
  193         $initFor[ 'iteration' ] = "{$propValue['iteration']} = 1";
  194         if ($propType[ 'step' ] === 0) {
  195             if ($propValue[ 'step' ] === 1) {
  196                 $incFor[ 'index' ] = "{$sectionVar}->value['index']++";
  197             } elseif ($propValue[ 'step' ] > 1) {
  198                 $incFor[ 'index' ] = "{$sectionVar}->value['index'] += {$propValue['step']}";
  199             } else {
  200                 $incFor[ 'index' ] = "{$sectionVar}->value['index'] -= " . -$propValue[ 'step' ];
  201             }
  202         } else {
  203             $incFor[ 'index' ] = "{$sectionVar}->value['index'] += {$propValue['step']}";
  204         }
  205         if (!isset($propValue[ 'max' ])) {
  206             $propValue[ 'max' ] = $propValue[ 'loop' ];
  207             $propType[ 'max' ] = $propType[ 'loop' ];
  208         } elseif ($propType[ 'max' ] !== 0) {
  209             $propValue[ 'max' ] = "{$propValue['max']} < 0 ? {$propValue['loop']} : {$propValue['max']}";
  210             $propType[ 'max' ] = 1;
  211         } else {
  212             if ($propValue[ 'max' ] < 0) {
  213                 $propValue[ 'max' ] = $propValue[ 'loop' ];
  214                 $propType[ 'max' ] = $propType[ 'loop' ];
  215             }
  216         }
  217         if (!isset($propValue[ 'start' ])) {
  218             $start_code =
  219                 array(1 => "{$propValue['step']} > 0 ? ", 2 => '0', 3 => ' : ', 4 => $propValue[ 'loop' ], 5 => ' - 1');
  220             if ($propType[ 'loop' ] === 0) {
  221                 $start_code[ 5 ] = '';
  222                 $start_code[ 4 ] = $propValue[ 'loop' ] - 1;
  223             }
  224             if ($propType[ 'step' ] === 0) {
  225                 if ($propValue[ 'step' ] > 0) {
  226                     $start_code = array(1 => '0');
  227                     $propType[ 'start' ] = 0;
  228                 } else {
  229                     $start_code[ 1 ] = $start_code[ 2 ] = $start_code[ 3 ] = '';
  230                     $propType[ 'start' ] = $propType[ 'loop' ];
  231                 }
  232             } else {
  233                 $propType[ 'start' ] = 1;
  234             }
  235             $propValue[ 'start' ] = join('', $start_code);
  236         } else {
  237             $start_code =
  238                 array(
  239                     1  => "{$propValue['start']} < 0 ? ", 2 => 'max(', 3 => "{$propValue['step']} > 0 ? ", 4 => '0',
  240                     5  => ' : ', 6 => '-1', 7 => ', ', 8 => "{$propValue['start']} + {$propValue['loop']}", 10 => ')',
  241                     11 => ' : ', 12 => 'min(', 13 => $propValue[ 'start' ], 14 => ', ',
  242                     15 => "{$propValue['step']} > 0 ? ", 16 => $propValue[ 'loop' ], 17 => ' : ',
  243                     18 => $propType[ 'loop' ] === 0 ? $propValue[ 'loop' ] - 1 : "{$propValue['loop']} - 1",
  244                     19 => ')'
  245                 );
  246             if ($propType[ 'step' ] === 0) {
  247                 $start_code[ 3 ] = $start_code[ 5 ] = $start_code[ 15 ] = $start_code[ 17 ] = '';
  248                 if ($propValue[ 'step' ] > 0) {
  249                     $start_code[ 6 ] = $start_code[ 18 ] = '';
  250                 } else {
  251                     $start_code[ 4 ] = $start_code[ 16 ] = '';
  252                 }
  253             }
  254             if ($propType[ 'start' ] === 0) {
  255                 if ($propType[ 'loop' ] === 0) {
  256                     $start_code[ 8 ] = $propValue[ 'start' ] + $propValue[ 'loop' ];
  257                 }
  258                 $propType[ 'start' ] = $propType[ 'step' ] + $propType[ 'loop' ];
  259                 $start_code[ 1 ] = '';
  260                 if ($propValue[ 'start' ] < 0) {
  261                     for ($i = 11; $i <= 19; $i++) {
  262                         $start_code[ $i ] = '';
  263                     }
  264                     if ($propType[ 'start' ] === 0) {
  265                         $start_code = array(
  266                             max(
  267                                 $propValue[ 'step' ] > 0 ? 0 : -1,
  268                                 $propValue[ 'start' ] + $propValue[ 'loop' ]
  269                             )
  270                         );
  271                     }
  272                 } else {
  273                     for ($i = 1; $i <= 11; $i++) {
  274                         $start_code[ $i ] = '';
  275                     }
  276                     if ($propType[ 'start' ] === 0) {
  277                         $start_code =
  278                             array(
  279                                 min(
  280                                     $propValue[ 'step' ] > 0 ? $propValue[ 'loop' ] : $propValue[ 'loop' ] - 1,
  281                                     $propValue[ 'start' ]
  282                                 )
  283                             );
  284                     }
  285                 }
  286             }
  287             $propValue[ 'start' ] = join('', $start_code);
  288         }
  289         if ($propType[ 'start' ] !== 0) {
  290             $initLocal[ 'start' ] = $propValue[ 'start' ];
  291             $propValue[ 'start' ] = "{$local}start";
  292         }
  293         $initFor[ 'index' ] = "{$sectionVar}->value['index'] = {$propValue['start']}";
  294         if (!isset($_attr[ 'start' ]) && !isset($_attr[ 'step' ]) && !isset($_attr[ 'max' ])) {
  295             $propValue[ 'total' ] = $propValue[ 'loop' ];
  296             $propType[ 'total' ] = $propType[ 'loop' ];
  297         } else {
  298             $propType[ 'total' ] =
  299                 $propType[ 'start' ] + $propType[ 'loop' ] + $propType[ 'step' ] + $propType[ 'max' ];
  300             if ($propType[ 'total' ] === 0) {
  301                 $propValue[ 'total' ] =
  302                     min(
  303                         ceil(
  304                             ($propValue[ 'step' ] > 0 ? $propValue[ 'loop' ] - $propValue[ 'start' ] :
  305                                 (int)$propValue[ 'start' ] + 1) / abs($propValue[ 'step' ])
  306                         ),
  307                         $propValue[ 'max' ]
  308                     );
  309             } else {
  310                 $total_code = array(
  311                     1  => 'min(', 2 => 'ceil(', 3 => '(', 4 => "{$propValue['step']} > 0 ? ",
  312                     5  => $propValue[ 'loop' ], 6 => ' - ', 7 => $propValue[ 'start' ], 8 => ' : ',
  313                     9  => $propValue[ 'start' ], 10 => '+ 1', 11 => ')', 12 => '/ ', 13 => 'abs(',
  314                     14 => $propValue[ 'step' ], 15 => ')', 16 => ')', 17 => ", {$propValue['max']})",
  315                 );
  316                 if (!isset($propValue[ 'max' ])) {
  317                     $total_code[ 1 ] = $total_code[ 17 ] = '';
  318                 }
  319                 if ($propType[ 'loop' ] + $propType[ 'start' ] === 0) {
  320                     $total_code[ 5 ] = $propValue[ 'loop' ] - $propValue[ 'start' ];
  321                     $total_code[ 6 ] = $total_code[ 7 ] = '';
  322                 }
  323                 if ($propType[ 'start' ] === 0) {
  324                     $total_code[ 9 ] = (int)$propValue[ 'start' ] + 1;
  325                     $total_code[ 10 ] = '';
  326                 }
  327                 if ($propType[ 'step' ] === 0) {
  328                     $total_code[ 13 ] = $total_code[ 15 ] = '';
  329                     if ($propValue[ 'step' ] === 1 || $propValue[ 'step' ] === -1) {
  330                         $total_code[ 2 ] = $total_code[ 12 ] = $total_code[ 14 ] = $total_code[ 16 ] = '';
  331                     } elseif ($propValue[ 'step' ] < 0) {
  332                         $total_code[ 14 ] = -$propValue[ 'step' ];
  333                     }
  334                     $total_code[ 4 ] = '';
  335                     if ($propValue[ 'step' ] > 0) {
  336                         $total_code[ 8 ] = $total_code[ 9 ] = $total_code[ 10 ] = '';
  337                     } else {
  338                         $total_code[ 5 ] = $total_code[ 6 ] = $total_code[ 7 ] = $total_code[ 8 ] = '';
  339                     }
  340                 }
  341                 $propValue[ 'total' ] = join('', $total_code);
  342             }
  343         }
  344         if (isset($namedAttr[ 'loop' ])) {
  345             $initNamedProperty[ 'loop' ] = "'loop' => {$propValue['loop']}";
  346         }
  347         if (isset($namedAttr[ 'total' ])) {
  348             $initNamedProperty[ 'total' ] = "'total' => {$propValue['total']}";
  349             if ($propType[ 'total' ] > 0) {
  350                 $propValue[ 'total' ] = "{$sectionVar}->value['total']";
  351             }
  352         } elseif ($propType[ 'total' ] > 0) {
  353             $initLocal[ 'total' ] = $propValue[ 'total' ];
  354             $propValue[ 'total' ] = "{$local}total";
  355         }
  356         $cmpFor[ 'iteration' ] = "{$propValue['iteration']} <= {$propValue['total']}";
  357         foreach ($initLocal as $key => $code) {
  358             $output .= "{$local}{$key} = {$code};\n";
  359         }
  360         $_vars = 'array(' . join(', ', $initNamedProperty) . ')';
  361         $output .= "{$sectionVar} = new Smarty_Variable({$_vars});\n";
  362         $cond_code = "{$propValue['total']} !== 0";
  363         if ($propType[ 'total' ] === 0) {
  364             if ($propValue[ 'total' ] === 0) {
  365                 $cond_code = 'false';
  366             } else {
  367                 $cond_code = 'true';
  368             }
  369         }
  370         if ($propType[ 'show' ] > 0) {
  371             $output .= "{$local}show = {$propValue['show']} ? {$cond_code} : false;\n";
  372             $output .= "if ({$local}show) {\n";
  373         } elseif ($propValue[ 'show' ] === 'true') {
  374             $output .= "if ({$cond_code}) {\n";
  375         } else {
  376             $output .= "if (false) {\n";
  377         }
  378         $jinit = join(', ', $initFor);
  379         $jcmp = join(', ', $cmpFor);
  380         $jinc = join(', ', $incFor);
  381         $output .= "for ({$jinit}; {$jcmp}; {$jinc}){\n";
  382         if (isset($namedAttr[ 'rownum' ])) {
  383             $output .= "{$sectionVar}->value['rownum'] = {$propValue['iteration']};\n";
  384         }
  385         if (isset($namedAttr[ 'index_prev' ])) {
  386             $output .= "{$sectionVar}->value['index_prev'] = {$propValue['index']} - {$propValue['step']};\n";
  387         }
  388         if (isset($namedAttr[ 'index_next' ])) {
  389             $output .= "{$sectionVar}->value['index_next'] = {$propValue['index']} + {$propValue['step']};\n";
  390         }
  391         if (isset($namedAttr[ 'first' ])) {
  392             $output .= "{$sectionVar}->value['first'] = ({$propValue['iteration']} === 1);\n";
  393         }
  394         if (isset($namedAttr[ 'last' ])) {
  395             $output .= "{$sectionVar}->value['last'] = ({$propValue['iteration']} === {$propValue['total']});\n";
  396         }
  397         $output .= '?>';
  398         return $output;
  399     }
  400 }
  401 
  402 /**
  403  * Smarty Internal Plugin Compile Sectionelse Class
  404  *
  405  * @package    Smarty
  406  * @subpackage Compiler
  407  */
  408 class Smarty_Internal_Compile_Sectionelse extends Smarty_Internal_CompileBase
  409 {
  410     /**
  411      * Compiles code for the {sectionelse} tag
  412      *
  413      * @param array                                 $args     array with attributes from parser
  414      * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
  415      *
  416      * @return string compiled code
  417      */
  418     public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
  419     {
  420         // check and get attributes
  421         $_attr = $this->getAttributes($compiler, $args);
  422         list($openTag, $nocache, $local, $sectionVar) = $this->closeTag($compiler, array('section'));
  423         $this->openTag($compiler, 'sectionelse', array('sectionelse', $nocache, $local, $sectionVar));
  424         return "<?php }} else {\n ?>";
  425     }
  426 }
  427 
  428 /**
  429  * Smarty Internal Plugin Compile Sectionclose Class
  430  *
  431  * @package    Smarty
  432  * @subpackage Compiler
  433  */
  434 class Smarty_Internal_Compile_Sectionclose extends Smarty_Internal_CompileBase
  435 {
  436     /**
  437      * Compiles code for the {/section} tag
  438      *
  439      * @param array                                 $args     array with attributes from parser
  440      * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
  441      *
  442      * @return string compiled code
  443      */
  444     public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
  445     {
  446         $compiler->loopNesting--;
  447         // must endblock be nocache?
  448         if ($compiler->nocache) {
  449             $compiler->tag_nocache = true;
  450         }
  451         list($openTag, $compiler->nocache, $local, $sectionVar) =
  452             $this->closeTag($compiler, array('section', 'sectionelse'));
  453         $output = "<?php\n";
  454         if ($openTag === 'sectionelse') {
  455             $output .= "}\n";
  456         } else {
  457             $output .= "}\n}\n";
  458         }
  459         $output .= '?>';
  460         return $output;
  461     }
  462 }