| 
									
										
										
										
											2015-07-31 01:03:29 +02:00
										 |  |  | <?php | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Smarty Internal Plugin Compile ForeachSection | 
					
						
							|  |  |  |  * Shared methods for {foreach} {section} tags | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package    Smarty | 
					
						
							|  |  |  |  * @subpackage Compiler | 
					
						
							|  |  |  |  * @author     Uwe Tews | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Smarty Internal Plugin Compile ForeachSection Class | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package    Smarty | 
					
						
							|  |  |  |  * @subpackage Compiler | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_CompileBase | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Preg search pattern | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @var string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private $propertyPreg = ''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Offsets in preg match result | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @var array | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private $resultOffsets = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Start offset | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @var int | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private $startOffset = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Name of this tag | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @var string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public $tagName = ''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Valid properties of $smarty.xxx variable | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @var array | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static $nameProperties = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * {section} tag has no item properties | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @var array | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public $itemProperties = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * {section} tag has always name attribute | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @var bool | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public $isNamed = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @var array | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public $matchResults = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Scan sources for used tag attributes | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param  array                                $attributes | 
					
						
							|  |  |  |      * @param \Smarty_Internal_TemplateCompilerBase $compiler | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function scanForProperties($attributes, Smarty_Internal_TemplateCompilerBase $compiler) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->propertyPreg = '~('; | 
					
						
							|  |  |  |         $this->startOffset = 0; | 
					
						
							|  |  |  |         $this->resultOffsets = array(); | 
					
						
							|  |  |  |         $this->matchResults = array('named' => array(), 'item' => array()); | 
					
						
							|  |  |  |         if ($this->isNamed) { | 
					
						
							|  |  |  |             $this->buildPropertyPreg(true, $attributes); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (isset($this->itemProperties)) { | 
					
						
							|  |  |  |             if ($this->isNamed) { | 
					
						
							|  |  |  |                 $this->propertyPreg .= '|'; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             $this->buildPropertyPreg(false, $attributes); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $this->propertyPreg .= ')\W~i'; | 
					
						
							|  |  |  |         // Template source
 | 
					
						
							|  |  |  |         $this->matchTemplateSource($compiler); | 
					
						
							|  |  |  |         // Parent template source
 | 
					
						
							|  |  |  |         $this->matchParentTemplateSource($compiler); | 
					
						
							|  |  |  |         // {block} source
 | 
					
						
							|  |  |  |         $this->matchBlockSource($compiler); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Build property preg string | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param bool  $named | 
					
						
							|  |  |  |      * @param array $attributes | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function buildPropertyPreg($named, $attributes) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($named) { | 
					
						
							|  |  |  |             $this->resultOffsets['named'] = $this->startOffset + 3; | 
					
						
							|  |  |  |             $this->propertyPreg .= "([\$]smarty[.]{$this->tagName}[.]{$attributes['name']}[.]("; | 
					
						
							|  |  |  |             $className = get_class($this); | 
					
						
							|  |  |  |             $properties = $className::$nameProperties; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $this->resultOffsets['item'] = $this->startOffset + 3; | 
					
						
							|  |  |  |             $this->propertyPreg .= "([\$]{$attributes['item']}[@]("; | 
					
						
							|  |  |  |             $properties = $this->itemProperties; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $this->startOffset += count($properties) + 2; | 
					
						
							|  |  |  |         $propName = reset($properties); | 
					
						
							|  |  |  |         while ($propName) { | 
					
						
							|  |  |  |             $this->propertyPreg .= "({$propName})"; | 
					
						
							|  |  |  |             $propName = next($properties); | 
					
						
							|  |  |  |             if ($propName) { | 
					
						
							|  |  |  |                 $this->propertyPreg .= '|'; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $this->propertyPreg .= '))'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Find matches in source string | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $source | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function matchProperty($source) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         preg_match_all($this->propertyPreg, $source, $match, PREG_SET_ORDER); | 
					
						
							|  |  |  |         foreach ($this->resultOffsets as $key => $offset) { | 
					
						
							|  |  |  |             foreach ($match as $m) { | 
					
						
							|  |  |  |                 if (isset($m[$offset]) && !empty($m[$offset])) { | 
					
						
							|  |  |  |                     $this->matchResults[$key][strtolower($m[$offset])] = true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Find matches in template source | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param \Smarty_Internal_TemplateCompilerBase $compiler | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function matchTemplateSource(Smarty_Internal_TemplateCompilerBase $compiler) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->matchProperty($compiler->lex->data); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Find matches in all parent template source | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param \Smarty_Internal_TemplateCompilerBase $compiler | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function matchParentTemplateSource(Smarty_Internal_TemplateCompilerBase $compiler) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // search parent compiler template source
 | 
					
						
							|  |  |  |         $nextCompiler = $compiler; | 
					
						
							|  |  |  |         while ($nextCompiler !== $nextCompiler->parent_compiler) { | 
					
						
							|  |  |  |             $nextCompiler = $nextCompiler->parent_compiler; | 
					
						
							|  |  |  |             if ($compiler !== $nextCompiler) { | 
					
						
							|  |  |  |                 // get template source
 | 
					
						
							|  |  |  |                 $_content = $nextCompiler->template->source->getContent(); | 
					
						
							|  |  |  |                 if ($_content != '') { | 
					
						
							|  |  |  |                     // run pre filter if required
 | 
					
						
							|  |  |  |                     if ((isset($nextCompiler->smarty->autoload_filters['pre']) || | 
					
						
							|  |  |  |                             isset($nextCompiler->smarty->registered_filters['pre'])) && !$nextCompiler->suppressFilter | 
					
						
							|  |  |  |                     ) { | 
					
						
							|  |  |  |                         $_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $nextCompiler->template); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     $this->matchProperty($_content); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Find matches in {block} tag source | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param \Smarty_Internal_TemplateCompilerBase $compiler | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function matchBlockSource(Smarty_Internal_TemplateCompilerBase $compiler) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         foreach ($compiler->template->block_data as $b) { | 
					
						
							|  |  |  |             if (isset($b['source'])) { | 
					
						
							|  |  |  |                 $this->matchProperty($b['source']); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (class_exists('Smarty_Internal_Compile_Block', false)) { | 
					
						
							|  |  |  |             foreach (Smarty_Internal_Compile_Block::$block_data as $b) { | 
					
						
							|  |  |  |                 if (isset($b['source'])) { | 
					
						
							|  |  |  |                     $this->matchProperty($b['source']); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->matchProperty($compiler->lex->data); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Compiles code for the {$smarty.foreach.xxx} or {$smarty.section.xxx}tag | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param  array                                $args      array with attributes from parser | 
					
						
							|  |  |  |      * @param \Smarty_Internal_TemplateCompilerBase $compiler  compiler object | 
					
						
							|  |  |  |      * @param  array                                $parameter array with compilation parameter | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return string compiled code | 
					
						
							|  |  |  |      * @throws \SmartyCompilerException | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // make all lower case
 | 
					
						
							|  |  |  |         $parameter = array_map('strtolower', $parameter); | 
					
						
							|  |  |  |         $tag = trim($parameter[0], '"\''); | 
					
						
							|  |  |  |         if (!isset($parameter[1]) || false === $name = $compiler->getId($parameter[1])) { | 
					
						
							|  |  |  |             $compiler->trigger_template_error("missing or illegal \$smarty.{$tag} name attribute", $compiler->lex->taglineno); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $className = 'Smarty_Internal_Compile_' . ucfirst($tag); | 
					
						
							|  |  |  |         if ((!isset($parameter[2]) || false === $property = $compiler->getId($parameter[2])) || | 
					
						
							|  |  |  |             !in_array($property, $className::$nameProperties) | 
					
						
							|  |  |  |         ) { | 
					
						
							|  |  |  |             $compiler->trigger_template_error("missing or illegal \$smarty.{$tag} property attribute", $compiler->lex->taglineno); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-08-02 19:43:21 +02:00
										 |  |  |         $tagVar = "'__smarty_{$tag}_{$name}'"; | 
					
						
							| 
									
										
										
										
											2015-07-31 01:03:29 +02:00
										 |  |  |         return "(isset(\$_smarty_tpl->tpl_vars[{$tagVar}]->value['{$property}']) ? \$_smarty_tpl->tpl_vars[{$tagVar}]->value['{$property}'] : null)"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |