1<?php
2
3/*
4 * This file is part of Twig.
5 *
6 * (c) Fabien Potencier
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Twig\TokenParser;
13
14use Twig\Node\EmbedNode;
15use Twig\Node\Expression\ConstantExpression;
16use Twig\Node\Expression\NameExpression;
17use Twig\Token;
18
19/**
20 * Embeds a template.
21 */
22final class EmbedTokenParser extends IncludeTokenParser
23{
24    public function parse(Token $token)
25    {
26        $stream = $this->parser->getStream();
27
28        $parent = $this->parser->getExpressionParser()->parseExpression();
29
30        list($variables, $only, $ignoreMissing) = $this->parseArguments();
31
32        $parentToken = $fakeParentToken = new Token(/* Token::STRING_TYPE */ 7, '__parent__', $token->getLine());
33        if ($parent instanceof ConstantExpression) {
34            $parentToken = new Token(/* Token::STRING_TYPE */ 7, $parent->getAttribute('value'), $token->getLine());
35        } elseif ($parent instanceof NameExpression) {
36            $parentToken = new Token(/* Token::NAME_TYPE */ 5, $parent->getAttribute('name'), $token->getLine());
37        }
38
39        // inject a fake parent to make the parent() function work
40        $stream->injectTokens([
41            new Token(/* Token::BLOCK_START_TYPE */ 1, '', $token->getLine()),
42            new Token(/* Token::NAME_TYPE */ 5, 'extends', $token->getLine()),
43            $parentToken,
44            new Token(/* Token::BLOCK_END_TYPE */ 3, '', $token->getLine()),
45        ]);
46
47        $module = $this->parser->parse($stream, [$this, 'decideBlockEnd'], true);
48
49        // override the parent with the correct one
50        if ($fakeParentToken === $parentToken) {
51            $module->setNode('parent', $parent);
52        }
53
54        $this->parser->embedTemplate($module);
55
56        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
57
58        return new EmbedNode($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
59    }
60
61    public function decideBlockEnd(Token $token)
62    {
63        return $token->test('endembed');
64    }
65
66    public function getTag()
67    {
68        return 'embed';
69    }
70}
71
72class_alias('Twig\TokenParser\EmbedTokenParser', 'Twig_TokenParser_Embed');
73