예제 #1
0
파일: WIf.php 프로젝트: webiny/htpl
 /**
  * Parses the conditions and returns a compiled PHP string to execute the conditions.
  *
  * @param string $conditions A string of conditions.
  *
  * @return string
  */
 protected function parseConditions($conditions, $htpl)
 {
     // extract the strings
     preg_match_all('/([\'])([A-z]?[A-z\\.0-9]+)\\1/', $conditions, $matches, PREG_OFFSET_CAPTURE);
     $vars = [];
     if (count($matches[0]) > 0) {
         $countOffset = 0;
         foreach ($matches[0] as $m) {
             $varName = 'htpl_' . uniqid();
             $conditions = substr_replace($conditions, $varName, $m[1] + $countOffset, strlen($m[0]));
             $countOffset += strlen($varName) - strlen($m[0]);
             $vars[$varName] = $m[0];
         }
     }
     $testFunctions = ['isset' => 'isset', 'isnull' => 'isnull', 'empty' => 'empty'];
     // protected var names
     $protectedVarNames = ['false', 'true', 'null'];
     // extract the variables
     preg_match_all('/([A-z][\\w\\.|]+|[A-z]+)/', $conditions, $matches, PREG_OFFSET_CAPTURE);
     if (count($matches[0]) > 0) {
         $countOffset = 0;
         foreach ($matches[0] as $m) {
             if (!in_array($m[0], $testFunctions) && !in_array($m[0], $protectedVarNames)) {
                 if (isset($vars[$m[0]])) {
                     $var = $vars[$m[0]];
                 } else {
                     $var = VarLexer::parse('{' . $m[0] . '}', $htpl, false);
                 }
                 $conditions = substr_replace($conditions, $var, $m[1] + $countOffset, strlen($m[0]));
                 $countOffset += strlen($var) - strlen($m[0]);
             }
         }
     }
     return $conditions;
 }
예제 #2
0
파일: Compiler.php 프로젝트: webiny/htpl
 /**
  * Method that does the actual compiling.
  *
  * @param string $templateName Template name that should be compiled.
  *
  * @return Layout Compiled template in form of a string.
  * @throws HtplException
  */
 private function compileLayout($templateName)
 {
     // before we can do the template compile, we need to solve the template inheritance
     $layout = LayoutTree::getLayout($this->htpl->getTemplateProvider(), $templateName);
     $template = $layout->getSource();
     // validate that the raw template doesn't contain any PHP code
     if (strpos($template, '<?') !== false) {
         throw new HtplException(sprintf('Template "%s" contains PHP tags which are not allowed.', $templateName));
     }
     // strip out w-literal content before parsing any tags or variables
     $literals = TagLexer::parse($template)->select('w-literal');
     $literalReplacements = [];
     foreach ($literals as $l) {
         $id = '<!-- htpl: w-literal => ' . uniqid() . ' -->';
         $literalReplacements[$id] = $l['content'];
         $template = str_replace($l['outerHtml'], $id, $template);
     }
     // parse the variables
     $template = VarLexer::parse($template, $this->htpl);
     // get a list of possible functions (tags) that we support
     $functions = $this->htpl->getFunctions();
     $lexedTemplate = TagLexer::parse($template);
     foreach ($functions as $tag => $callback) {
         $tags = $lexedTemplate->select($tag);
         foreach ($tags as $t) {
             $lexedTemplate = TagLexer::parse($template);
             $currentMatch = $lexedTemplate->select($tag);
             if (count($currentMatch) < 1) {
                 continue;
             } else {
                 $currentMatch = $currentMatch[0];
             }
             $content = $currentMatch['content'];
             $attributes = isset($currentMatch['attributes']) ? $currentMatch['attributes'] : [];
             try {
                 // extract the opening and closing tag
                 $outerContent = str_replace($currentMatch['content'], '', $currentMatch['outerHtml']);
                 $closingTag = '</' . $tag . '>';
                 $openingTag = str_replace($closingTag, '', $outerContent);
                 $instance = new $callback();
                 $result = $instance->parseTag($content, $attributes, $this->htpl);
                 if (!$result) {
                     continue;
                 }
                 // check if we have context defined
                 $contextStart = '';
                 $contextEnd = '';
                 if (isset($result['contexts'])) {
                     foreach ($result['contexts'] as $c) {
                         $contextStart .= '<!-- htpl-context-start:' . $c . ' -->' . "\n";
                         $contextEnd = '<!-- htpl-context-end:' . $c . ' -->' . "\n" . $contextEnd;
                     }
                 }
                 // do the replacement
                 if (isset($result['content'])) {
                     $replacement = $contextStart . $result['openingTag'] . $result['content'] . $result['closingTag'] . $contextEnd;
                     // we replace with offset 1 cause, we always do the replacement on the current template instance
                     //$template = str_replace($currentMatch['outerHtml'], $replacement, $template);
                     $template = preg_replace('/(\\s+|)' . preg_quote($currentMatch['outerHtml'], '/') . '(\\s+|)/', $replacement, $template);
                 } else {
                     $replacement = $contextStart . $result['openingTag'] . $currentMatch['content'] . $result['closingTag'] . $contextEnd;
                     $template = preg_replace('/(\\s+|)' . preg_quote($currentMatch['outerHtml'], '/') . '(\\s+|)/', $replacement, $template);
                     /*
                     //$template = str_replace($openingTag, $result['openingTag'], $template);
                     $template = preg_replace('/(\s+|)' . preg_quote($openingTag, '/') . '(\s+|)/',
                         $result['openingTag'], $template);
                     if (isset($result['closingTag'])) {
                         //$template = str_replace($closingTag, $result['closingTag'], $template);
                         $template = preg_replace('/(\s+|)' . preg_quote($closingTag, '/') . '(\s+|)/',
                             $result['closingTag'], $template);
                     }
                     */
                 }
             } catch (HtplException $e) {
                 throw new HtplException('Htpl in unable to parse your template near: ' . $openingTag . "\n\n " . $e->getMessage());
             }
         }
     }
     // adjust contexts
     $template = $this->adjustContexts($template);
     // optimize template execution
     /*$template = preg_replace('/\?>(\s+|)\<\?php/', "\n", $template);*/
     // put back the literals
     foreach ($literalReplacements as $lrId => $lrVal) {
         $template = str_replace($lrId, $lrVal, $template);
     }
     // save the new source
     $layout->setSource($template);
     return $layout;
 }
예제 #3
0
 /**
  * @param $str
  * @param $expectedResult
  *
  * @throws \Webiny\Htpl\HtplException
  * @dataProvider parseProvider
  */
 public function testParse($str, $expectedResult)
 {
     $htpl = new Htpl(new ArrayProvider([]));
     $result = VarLexer::parse($str, $htpl);
     $this->assertSame($expectedResult, $result);
 }