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 *
22 * @final
23 */
24class EmbedTokenParser extends IncludeTokenParser
25{
26    public function parse(Token $token)
27    {
28        $stream = $this->parser->getStream();
29
30        $parent = $this->parser->getExpressionParser()->parseExpression();
31
32        list($variables, $only, $ignoreMissing) = $this->parseArguments();
33
34        $parentToken = $fakeParentToken = new Token(Token::STRING_TYPE, '__parent__', $token->getLine());
35        if ($parent instanceof ConstantExpression) {
36            $parentToken = new Token(Token::STRING_TYPE, $parent->getAttribute('value'), $token->getLine());
37        } elseif ($parent instanceof NameExpression) {
38            $parentToken = new Token(Token::NAME_TYPE, $parent->getAttribute('name'), $token->getLine());
39        }
40
41        // inject a fake parent to make the parent() function work
42        $stream->injectTokens([
43            new Token(Token::BLOCK_START_TYPE, '', $token->getLine()),
44            new Token(Token::NAME_TYPE, 'extends', $token->getLine()),
45            $parentToken,
46            new Token(Token::BLOCK_END_TYPE, '', $token->getLine()),
47        ]);
48
49        $module = $this->parser->parse($stream, [$this, 'decideBlockEnd'], true);
50
51        // override the parent with the correct one
52        if ($fakeParentToken === $parentToken) {
53            $module->setNode('parent', $parent);
54        }
55
56        $this->parser->embedTemplate($module);
57
58        $stream->expect(Token::BLOCK_END_TYPE);
59
60        return new EmbedNode($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
61    }
62
63    public function decideBlockEnd(Token $token)
64    {
65        return $token->test('endembed');
66    }
67
68    public function getTag()
69    {
70        return 'embed';
71    }
72}
73
74class_alias('Twig\TokenParser\EmbedTokenParser', 'Twig_TokenParser_Embed');
75