diff --git a/composer.lock b/composer.lock index 0bba6e6151..7fdfa1a703 100644 --- a/composer.lock +++ b/composer.lock @@ -653,7 +653,7 @@ "dist": { "type": "path", "url": "core", - "reference": "1d60dcc9ae7937cd50c1fb7f4ea3bf7bdc5a2e3c" + "reference": "97ccc1d789eaa3fdac99486faecb8788985beb13" }, "require": { "asm89/stack-cors": "^1.1", @@ -695,7 +695,7 @@ "symfony/translation": "^4.4", "symfony/validator": "^4.4", "symfony/yaml": "^4.4", - "twig/twig": "^1.38.2", + "twig/twig": "^2.10.0", "typo3/phar-stream-wrapper": "^3.1.2", "zendframework/zend-diactoros": ">=1.7 <1.8", "zendframework/zend-feed": "^2.12" @@ -3471,21 +3471,22 @@ }, { "name": "twig/twig", - "version": "v1.42.3", + "version": "v2.12.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "201baee843e0ffe8b0b956f336dd42b2a92fae4e" + "reference": "ddd4134af9bfc6dba4eff7c8447444ecc45b9ee5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/201baee843e0ffe8b0b956f336dd42b2a92fae4e", - "reference": "201baee843e0ffe8b0b956f336dd42b2a92fae4e", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/ddd4134af9bfc6dba4eff7c8447444ecc45b9ee5", + "reference": "ddd4134af9bfc6dba4eff7c8447444ecc45b9ee5", "shasum": "" }, "require": { - "php": ">=5.5.0", - "symfony/polyfill-ctype": "^1.8" + "php": "^7.0", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { "psr/container": "^1.0", @@ -3495,7 +3496,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.42-dev" + "dev-master": "2.12-dev" } }, "autoload": { @@ -3533,7 +3534,7 @@ "keywords": [ "templating" ], - "time": "2019-08-24T12:51:03+00:00" + "time": "2019-10-17T07:34:53+00:00" }, { "name": "typo3/phar-stream-wrapper", diff --git a/core/composer.json b/core/composer.json index 8f72b206dd..8a382d21c6 100644 --- a/core/composer.json +++ b/core/composer.json @@ -32,7 +32,7 @@ "symfony/polyfill-iconv": "^1.0", "symfony/yaml": "^4.4", "typo3/phar-stream-wrapper": "^3.1.2", - "twig/twig": "^1.38.2", + "twig/twig": "^2.10.0", "doctrine/common": "^2.7", "doctrine/annotations": "^1.4", "guzzlehttp/guzzle": "^6.3", diff --git a/core/core.services.yml b/core/core.services.yml index fee9101701..e4948103f1 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -1637,11 +1637,11 @@ services: # @todo Figure out what to do about debugging functions. # @see https://www.drupal.org/node/1804998 twig.extension.debug: - class: Twig_Extension_Debug + class: Twig\Extension\DebugExtension tags: - { name: twig.extension } twig.loader: - class: Twig_Loader_Chain + class: Twig\Loader\ChainLoader public: false tags: - { name: service_collector, tag: twig.loader, call: addLoader, required: TRUE } diff --git a/core/lib/Drupal/Core/Render/Markup.php b/core/lib/Drupal/Core/Render/Markup.php index 0947f8fc67..8278389df9 100644 --- a/core/lib/Drupal/Core/Render/Markup.php +++ b/core/lib/Drupal/Core/Render/Markup.php @@ -17,7 +17,7 @@ * rendering. * * @see \Drupal\Core\Template\TwigExtension::escapeFilter - * @see \Twig_Markup + * @see \Twig\Markup */ final class Markup implements MarkupInterface, \Countable { use MarkupTrait; diff --git a/core/lib/Drupal/Core/Template/Loader/FilesystemLoader.php b/core/lib/Drupal/Core/Template/Loader/FilesystemLoader.php index b84e790b62..4edb6e2d8d 100644 --- a/core/lib/Drupal/Core/Template/Loader/FilesystemLoader.php +++ b/core/lib/Drupal/Core/Template/Loader/FilesystemLoader.php @@ -4,6 +4,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Extension\ThemeHandlerInterface; +use Twig\Loader\FilesystemLoader as TwigFilesystemLoader; /** * Loads templates from the filesystem. @@ -12,7 +13,7 @@ * filesystem loader so that templates can be referenced by namespace, like * @block/block.html.twig or @mytheme/page.html.twig. */ -class FilesystemLoader extends \Twig_Loader_Filesystem { +class FilesystemLoader extends TwigFilesystemLoader { /** * Constructs a new FilesystemLoader object. diff --git a/core/lib/Drupal/Core/Template/Loader/StringLoader.php b/core/lib/Drupal/Core/Template/Loader/StringLoader.php index 909a09a8f8..3991a72680 100644 --- a/core/lib/Drupal/Core/Template/Loader/StringLoader.php +++ b/core/lib/Drupal/Core/Template/Loader/StringLoader.php @@ -2,7 +2,7 @@ namespace Drupal\Core\Template\Loader; -use Twig\Loader\ExistsLoaderInterface; +use Twig\Loader\LoaderInterface; use Twig\Loader\SourceContextLoaderInterface; use Twig\Source; @@ -18,13 +18,13 @@ * This class override ensures that the string loader behaves as expected in * the loader chain. If Twig's string loader is used as is, any string (even a * reference to a file-based Twig template) is treated as a valid template and - * is rendered instead of a \Twig_Error_Loader exception being thrown. + * is rendered instead of a \Twig\Error\LoaderError exception being thrown. * * @see \Drupal\Core\Template\TwigEnvironment::renderInline() * @see \Drupal\Core\Render\Element\InlineTemplate * @see twig_render_template() */ -class StringLoader implements \Twig_LoaderInterface, ExistsLoaderInterface, SourceContextLoaderInterface { +class StringLoader implements LoaderInterface, SourceContextLoaderInterface { /** * {@inheritdoc} diff --git a/core/lib/Drupal/Core/Template/Loader/ThemeRegistryLoader.php b/core/lib/Drupal/Core/Template/Loader/ThemeRegistryLoader.php index 862092b606..b59b83d8ff 100644 --- a/core/lib/Drupal/Core/Template/Loader/ThemeRegistryLoader.php +++ b/core/lib/Drupal/Core/Template/Loader/ThemeRegistryLoader.php @@ -3,13 +3,15 @@ namespace Drupal\Core\Template\Loader; use Drupal\Core\Theme\Registry; +use Twig\Error\LoaderError; +use Twig\Loader\FilesystemLoader; /** * Loads templates based on information from the Drupal theme registry. * * Allows for template inheritance based on the currently active template. */ -class ThemeRegistryLoader extends \Twig_Loader_Filesystem { +class ThemeRegistryLoader extends FilesystemLoader { /** * The theme registry used to determine which template to use. @@ -39,7 +41,7 @@ public function __construct(Registry $theme_registry) { * @return string|false * The path to the template, or false if the template is not found. * - * @throws \Twig_Error_Loader + * @throws \Twig\Error\LoaderError * Thrown if a template matching $name cannot be found. */ protected function findTemplate($name, $throw = TRUE) { @@ -61,7 +63,7 @@ protected function findTemplate($name, $throw = TRUE) { } if ($throw) { - throw new \Twig_Error_Loader(sprintf('Unable to find template "%s" in the Drupal theme registry.', $name)); + throw new LoaderError(sprintf('Unable to find template "%s" in the Drupal theme registry.', $name)); } return FALSE; diff --git a/core/lib/Drupal/Core/Template/TwigEnvironment.php b/core/lib/Drupal/Core/Template/TwigEnvironment.php index 426234459b..b59f8a73f7 100644 --- a/core/lib/Drupal/Core/Template/TwigEnvironment.php +++ b/core/lib/Drupal/Core/Template/TwigEnvironment.php @@ -6,16 +6,17 @@ use Drupal\Core\PhpStorage\PhpStorageFactory; use Drupal\Core\Render\Markup; use Drupal\Core\State\StateInterface; +use Twig\Environment; +use Twig\Extension\SandboxExtension; +use Twig\Loader\LoaderInterface; /** * A class that defines a Twig environment for Drupal. * * Instances of this class are used to store the configuration and extensions, * and are used to load templates from the file system or other locations. - * - * @see core\vendor\twig\twig\lib\Twig\Environment.php */ -class TwigEnvironment extends \Twig_Environment { +class TwigEnvironment extends Environment { /** * Key name of the Twig cache prefix metadata key-value pair in State. @@ -55,12 +56,12 @@ class TwigEnvironment extends \Twig_Environment { * The Twig extension hash. * @param \Drupal\Core\State\StateInterface $state * The state service. - * @param \Twig_LoaderInterface $loader + * @param \Twig\Loader\LoaderInterface $loader * The Twig loader or loader chain. * @param array $options * The options for the Twig environment. */ - public function __construct($root, CacheBackendInterface $cache, $twig_extension_hash, StateInterface $state, \Twig_LoaderInterface $loader = NULL, array $options = []) { + public function __construct($root, CacheBackendInterface $cache, $twig_extension_hash, StateInterface $state, LoaderInterface $loader = NULL, array $options = []) { $this->state = $state; // Ensure that twig.engine is loaded, given that it is needed to render a @@ -97,7 +98,7 @@ public function __construct($root, CacheBackendInterface $cache, $twig_extension $this->setLoader($loader); parent::__construct($this->getLoader(), $options); $policy = new TwigSandboxPolicy(); - $sandbox = new \Twig_Extension_Sandbox($policy, TRUE); + $sandbox = new SandboxExtension($policy, TRUE); $this->addExtension($sandbox); } diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php index db6e080b5f..2188cffa44 100644 --- a/core/lib/Drupal/Core/Template/TwigExtension.php +++ b/core/lib/Drupal/Core/Template/TwigExtension.php @@ -14,6 +14,14 @@ use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\Theme\ThemeManagerInterface; use Drupal\Core\Url; +use Twig\Environment; +use Twig\Extension\AbstractExtension; +use Twig\Markup as TwigMarkup; +use Twig\Node\Expression\ArrayExpression; +use Twig\Node\Expression\ConstantExpression; +use Twig\Node\Node; +use Twig\TwigFilter; +use Twig\TwigFunction; /** * A class providing Drupal Twig extensions. @@ -23,7 +31,7 @@ * * @see \Drupal\Core\CoreServiceProvider */ -class TwigExtension extends \Twig_Extension { +class TwigExtension extends AbstractExtension { /** * The URL generator. @@ -137,19 +145,19 @@ public function setDateFormatter(DateFormatterInterface $date_formatter) { public function getFunctions() { return [ // This function will receive a renderable array, if an array is detected. - new \Twig_SimpleFunction('render_var', [$this, 'renderVar']), + new TwigFunction('render_var', [$this, 'renderVar']), // The url and path function are defined in close parallel to those found // in \Symfony\Bridge\Twig\Extension\RoutingExtension - new \Twig_SimpleFunction('url', [$this, 'getUrl'], ['is_safe_callback' => [$this, 'isUrlGenerationSafe']]), - new \Twig_SimpleFunction('path', [$this, 'getPath'], ['is_safe_callback' => [$this, 'isUrlGenerationSafe']]), - new \Twig_SimpleFunction('link', [$this, 'getLink']), - new \Twig_SimpleFunction('file_url', function ($uri) { + new TwigFunction('url', [$this, 'getUrl'], ['is_safe_callback' => [$this, 'isUrlGenerationSafe']]), + new TwigFunction('path', [$this, 'getPath'], ['is_safe_callback' => [$this, 'isUrlGenerationSafe']]), + new TwigFunction('link', [$this, 'getLink']), + new TwigFunction('file_url', function ($uri) { return file_url_transform_relative(file_create_url($uri)); }), - new \Twig_SimpleFunction('attach_library', [$this, 'attachLibrary']), - new \Twig_SimpleFunction('active_theme_path', [$this, 'getActiveThemePath']), - new \Twig_SimpleFunction('active_theme', [$this, 'getActiveTheme']), - new \Twig_SimpleFunction('create_attribute', [$this, 'createAttribute']), + new TwigFunction('attach_library', [$this, 'attachLibrary']), + new TwigFunction('active_theme_path', [$this, 'getActiveThemePath']), + new TwigFunction('active_theme', [$this, 'getActiveTheme']), + new TwigFunction('create_attribute', [$this, 'createAttribute']), ]; } @@ -159,32 +167,32 @@ public function getFunctions() { public function getFilters() { return [ // Translation filters. - new \Twig_SimpleFilter('t', 't', ['is_safe' => ['html']]), - new \Twig_SimpleFilter('trans', 't', ['is_safe' => ['html']]), + new TwigFilter('t', 't', ['is_safe' => ['html']]), + new TwigFilter('trans', 't', ['is_safe' => ['html']]), // The "raw" filter is not detectable when parsing "trans" tags. To detect // which prefix must be used for translation (@, !, %), we must clone the // "raw" filter and give it identifiable names. These filters should only // be used in "trans" tags. // @see TwigNodeTrans::compileString() - new \Twig_SimpleFilter('placeholder', [$this, 'escapePlaceholder'], ['is_safe' => ['html'], 'needs_environment' => TRUE]), + new TwigFilter('placeholder', [$this, 'escapePlaceholder'], ['is_safe' => ['html'], 'needs_environment' => TRUE]), // Replace twig's escape filter with our own. - new \Twig_SimpleFilter('drupal_escape', [$this, 'escapeFilter'], ['needs_environment' => TRUE, 'is_safe_callback' => 'twig_escape_filter_is_safe']), + new TwigFilter('drupal_escape', [$this, 'escapeFilter'], ['needs_environment' => TRUE, 'is_safe_callback' => 'twig_escape_filter_is_safe']), // Implements safe joining. // @todo Make that the default for |join? Upstream issue: // https://github.com/fabpot/Twig/issues/1420 - new \Twig_SimpleFilter('safe_join', [$this, 'safeJoin'], ['needs_environment' => TRUE, 'is_safe' => ['html']]), + new TwigFilter('safe_join', [$this, 'safeJoin'], ['needs_environment' => TRUE, 'is_safe' => ['html']]), // Array filters. - new \Twig_SimpleFilter('without', [$this, 'withoutFilter']), + new TwigFilter('without', [$this, 'withoutFilter']), // CSS class and ID filters. - new \Twig_SimpleFilter('clean_class', '\Drupal\Component\Utility\Html::getClass'), - new \Twig_SimpleFilter('clean_id', '\Drupal\Component\Utility\Html::getId'), + new TwigFilter('clean_class', '\Drupal\Component\Utility\Html::getClass'), + new TwigFilter('clean_id', '\Drupal\Component\Utility\Html::getId'), // This filter will render a renderable array to use the string results. - new \Twig_SimpleFilter('render', [$this, 'renderVar']), - new \Twig_SimpleFilter('format_date', [$this->dateFormatter, 'format']), + new TwigFilter('render', [$this, 'renderVar']), + new TwigFilter('format_date', [$this->dateFormatter, 'format']), ]; } @@ -299,7 +307,7 @@ public function getLink($text, $url, $attributes = []) { } // The text has been processed by twig already, convert it to a safe object // for the render system. - if ($text instanceof \Twig_Markup) { + if ($text instanceof TwigMarkup) { $text = Markup::create($text); } $build = [ @@ -351,18 +359,18 @@ public function getActiveThemePath() { * If param1 and param2 reference placeholders in the route, it would not * need to be escaped, but we don't know that in advance. * - * @param \Twig_Node $args_node + * @param \Twig\Node\Node $args_node * The arguments of the path/url functions. * * @return array * An array with the contexts the URL is safe */ - public function isUrlGenerationSafe(\Twig_Node $args_node) { + public function isUrlGenerationSafe(Node $args_node) { // Support named arguments. $parameter_node = $args_node->hasNode('parameters') ? $args_node->getNode('parameters') : ($args_node->hasNode(1) ? $args_node->getNode(1) : NULL); - if (!isset($parameter_node) || $parameter_node instanceof \Twig_Node_Expression_Array && count($parameter_node) <= 2 && - (!$parameter_node->hasNode(1) || $parameter_node->getNode(1) instanceof \Twig_Node_Expression_Constant)) { + if (!isset($parameter_node) || $parameter_node instanceof ArrayExpression && count($parameter_node) <= 2 && + (!$parameter_node->hasNode(1) || $parameter_node->getNode(1) instanceof ConstantExpression)) { return ['html']; } @@ -392,15 +400,15 @@ public function attachLibrary($library) { /** * Provides a placeholder wrapper around ::escapeFilter. * - * @param \Twig_Environment $env - * A Twig_Environment instance. + * @param \Twig\Environment $env + * A Twig Environment instance. * @param mixed $string * The value to be escaped. * * @return string|null * The escaped, rendered output, or NULL if there is no valid output. */ - public function escapePlaceholder(\Twig_Environment $env, $string) { + public function escapePlaceholder(Environment $env, $string) { $return = $this->escapeFilter($env, $string); return $return ? '' . $return . '' : NULL; @@ -414,8 +422,8 @@ public function escapePlaceholder(\Twig_Environment $env, $string) { * Note: This function should be kept in sync with * theme_render_and_autoescape(). * - * @param \Twig_Environment $env - * A Twig_Environment instance. + * @param \Twig\Environment $env + * A Twig Environment instance. * @param mixed $arg * The value to be escaped. * @param string $strategy @@ -436,7 +444,7 @@ public function escapePlaceholder(\Twig_Environment $env, $string) { * @todo Refactor this to keep it in sync with theme_render_and_autoescape() * in https://www.drupal.org/node/2575065 */ - public function escapeFilter(\Twig_Environment $env, $arg, $strategy = 'html', $charset = NULL, $autoescape = FALSE) { + public function escapeFilter(Environment $env, $arg, $strategy = 'html', $charset = NULL, $autoescape = FALSE) { // Check for a numeric zero int or float. if ($arg === 0 || $arg === 0.0) { return 0; @@ -449,8 +457,8 @@ public function escapeFilter(\Twig_Environment $env, $arg, $strategy = 'html', $ $this->bubbleArgMetadata($arg); - // Keep Twig_Markup objects intact to support autoescaping. - if ($autoescape && ($arg instanceof \Twig_Markup || $arg instanceof MarkupInterface)) { + // Keep \Twig\Markup objects intact to support autoescaping. + if ($autoescape && ($arg instanceof TwigMarkup || $arg instanceof MarkupInterface)) { return $arg; } @@ -538,7 +546,7 @@ protected function bubbleArgMetadata($arg) { * If an object is passed which does not implement __toString(), * RenderableInterface or toString() then an exception is thrown; * Other objects are casted to string. However in the case that the - * object is an instance of a Twig_Markup object it is returned directly + * object is an instance of a \Twig\Markup object it is returned directly * to support auto escaping. * * If an array is passed it is rendered via render() and scalar values are @@ -552,7 +560,7 @@ protected function bubbleArgMetadata($arg) { * RenderableInterface or toString(). * * @return mixed - * The rendered output or an Twig_Markup object. + * The rendered output or an \Twig\Markup object. * * @see render * @see TwigNodeVisitor @@ -604,8 +612,8 @@ public function renderVar($arg) { /** * Joins several strings together safely. * - * @param \Twig_Environment $env - * A Twig_Environment instance. + * @param \Twig\Environment $env + * A Twig Environment instance. * @param mixed[]|\Traversable|null $value * The pieces to join. * @param string $glue @@ -616,7 +624,7 @@ public function renderVar($arg) { * @return string * The strings joined together. */ - public function safeJoin(\Twig_Environment $env, $value, $glue = '') { + public function safeJoin(Environment $env, $value, $glue = '') { if ($value instanceof \Traversable) { $value = iterator_to_array($value, FALSE); } diff --git a/core/lib/Drupal/Core/Template/TwigNodeTrans.php b/core/lib/Drupal/Core/Template/TwigNodeTrans.php index b6d6d077d4..e581fa9c2b 100644 --- a/core/lib/Drupal/Core/Template/TwigNodeTrans.php +++ b/core/lib/Drupal/Core/Template/TwigNodeTrans.php @@ -2,7 +2,18 @@ namespace Drupal\Core\Template; +use Twig\Compiler; +use Twig\Error\SyntaxError; use Twig\Node\CheckToStringNode; +use Twig\Node\Expression\AbstractExpression; +use Twig\Node\Expression\ConstantExpression; +use Twig\Node\Expression\FilterExpression; +use Twig\Node\Expression\FunctionExpression; +use Twig\Node\Expression\GetAttrExpression; +use Twig\Node\Expression\NameExpression; +use Twig\Node\Expression\TempNameExpression; +use Twig\Node\Node; +use Twig\Node\PrintNode; /** * A class that defines the Twig 'trans' tag for Drupal. @@ -14,12 +25,12 @@ * @see https://twig-extensions.readthedocs.io/en/latest/i18n.html * @see https://github.com/fabpot/Twig-extensions */ -class TwigNodeTrans extends \Twig_Node { +class TwigNodeTrans extends Node { /** * {@inheritdoc} */ - public function __construct(\Twig_Node $body, \Twig_Node $plural = NULL, \Twig_Node_Expression $count = NULL, \Twig_Node_Expression $options = NULL, $lineno, $tag = NULL) { + public function __construct(Node $body, Node $plural = NULL, AbstractExpression $count = NULL, AbstractExpression $options = NULL, $lineno, $tag = NULL) { $nodes['body'] = $body; if ($count !== NULL) { $nodes['count'] = $count; @@ -36,7 +47,7 @@ public function __construct(\Twig_Node $body, \Twig_Node $plural = NULL, \Twig_N /** * {@inheritdoc} */ - public function compile(\Twig_Compiler $compiler) { + public function compile(Compiler $compiler) { $compiler->addDebugInfo($this); list($singular, $tokens) = $this->compileString($this->getNode('body')); @@ -88,7 +99,7 @@ public function compile(\Twig_Compiler $compiler) { /** * Extracts the text and tokens for the "trans" tag. * - * @param \Twig_Node $body + * @param \Twig\Node\Node $body * The node to compile. * * @return array @@ -96,10 +107,11 @@ public function compile(\Twig_Compiler $compiler) { * - string $text * The extracted text. * - array $tokens - * The extracted tokens as new \Twig_Node_Expression_Name instances. + * The extracted tokens as new \Twig\Node\Expression\TempNameExpression + * instances. */ - protected function compileString(\Twig_Node $body) { - if ($body instanceof \Twig_Node_Expression_Name || $body instanceof \Twig_Node_Expression_Constant || $body instanceof \Twig_Node_Expression_TempName) { + protected function compileString(Node $body) { + if ($body instanceof NameExpression || $body instanceof ConstantExpression || $body instanceof TempNameExpression) { return [$body, []]; } @@ -108,13 +120,9 @@ protected function compileString(\Twig_Node $body) { $text = ''; foreach ($body as $node) { - if (get_class($node) === 'Twig_Node' && $node->getNode(0) instanceof \Twig_Node_SetTemp) { - $node = $node->getNode(1); - } - - if ($node instanceof \Twig_Node_Print) { + if ($node instanceof PrintNode) { $n = $node->getNode('expr'); - while ($n instanceof \Twig_Node_Expression_Filter) { + while ($n instanceof FilterExpression) { $n = $n->getNode('node'); } @@ -124,7 +132,7 @@ protected function compileString(\Twig_Node $body) { $args = $n; // Support TwigExtension->renderVar() function in chain. - if ($args instanceof \Twig_Node_Expression_Function) { + if ($args instanceof FunctionExpression) { $args = $n->getNode('arguments')->getNode(0); } @@ -134,7 +142,7 @@ protected function compileString(\Twig_Node $body) { // safe for templates. // @see TwigExtension::getFilters() $argPrefix = '@'; - while ($args instanceof \Twig_Node_Expression_Filter) { + while ($args instanceof FilterExpression) { switch ($args->getNode('filter')->getAttribute('value')) { case 'placeholder': $argPrefix = '%'; @@ -145,7 +153,7 @@ protected function compileString(\Twig_Node $body) { if ($args instanceof CheckToStringNode) { $args = $args->getNode('expr'); } - if ($args instanceof \Twig_Node_Expression_GetAttr) { + if ($args instanceof GetAttrExpression) { $argName = []; // Reuse the incoming expression. $expr = $args; @@ -153,7 +161,7 @@ protected function compileString(\Twig_Node $body) { $argName[] = $args->getNode('attribute')->getAttribute('value'); while ($args->hasNode('node')) { $args = $args->getNode('node'); - if ($args instanceof \Twig_Node_Expression_Name) { + if ($args instanceof NameExpression) { $argName[] = $args->getAttribute('name'); } else { @@ -168,7 +176,7 @@ protected function compileString(\Twig_Node $body) { if (!is_null($args)) { $argName = $args->getAttribute('name'); } - $expr = new \Twig_Node_Expression_Name($argName, $n->getTemplateLine()); + $expr = new NameExpression($argName, $n->getTemplateLine()); } $placeholder = sprintf('%s%s', $argPrefix, $argName); $text .= $placeholder; @@ -181,14 +189,14 @@ protected function compileString(\Twig_Node $body) { } } elseif (!$body->hasAttribute('data')) { - throw new \Twig_Error_Syntax('{% trans %} tag cannot be empty'); + throw new SyntaxError('{% trans %} tag cannot be empty'); } else { $text = $body->getAttribute('data'); } return [ - new \Twig_Node([new \Twig_Node_Expression_Constant(trim($text), $body->getTemplateLine())]), + new Node([new ConstantExpression(trim($text), $body->getTemplateLine())]), $tokens, ]; } diff --git a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php index 5286242281..0429b6a31d 100644 --- a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php +++ b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php @@ -2,8 +2,15 @@ namespace Drupal\Core\Template; +use Twig\Environment; +use Twig\Node\Expression\FilterExpression; +use Twig\Node\Expression\FunctionExpression; +use Twig\Node\Node; +use Twig\Node\PrintNode; +use Twig\NodeVisitor\AbstractNodeVisitor; + /** - * Provides a Twig_NodeVisitor to change the generated parse-tree. + * Provides a TwigNodeVisitor to change the generated parse-tree. * * This is used to ensure that everything printed is wrapped via the * TwigExtension->renderVar() function in order to just write {{ content }} @@ -11,22 +18,22 @@ * * @see twig_render */ -class TwigNodeVisitor extends \Twig_BaseNodeVisitor { +class TwigNodeVisitor extends AbstractNodeVisitor { /** * {@inheritdoc} */ - protected function doEnterNode(\Twig_Node $node, \Twig_Environment $env) { + protected function doEnterNode(Node $node, Environment $env) { return $node; } /** * {@inheritdoc} */ - protected function doLeaveNode(\Twig_Node $node, \Twig_Environment $env) { + protected function doLeaveNode(Node $node, Environment $env) { // We use this to inject a call to render_var -> TwigExtension->renderVar() // before anything is printed. - if ($node instanceof \Twig_Node_Print) { + if ($node instanceof PrintNode) { if (!empty($this->skipRenderVarFunction)) { // No need to add the callback, we have escape active already. unset($this->skipRenderVarFunction); @@ -35,12 +42,12 @@ protected function doLeaveNode(\Twig_Node $node, \Twig_Environment $env) { $class = get_class($node); $line = $node->getTemplateLine(); return new $class( - new \Twig_Node_Expression_Function('render_var', new \Twig_Node([$node->getNode('expr')]), $line), + new FunctionExpression('render_var', new Node([$node->getNode('expr')]), $line), $line ); } // Change the 'escape' filter to our own 'drupal_escape' filter. - elseif ($node instanceof \Twig_Node_Expression_Filter) { + elseif ($node instanceof FilterExpression) { $name = $node->getNode('filter')->getAttribute('value'); if ('escape' == $name || 'e' == $name) { // Use our own escape filter that is MarkupInterface aware. diff --git a/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php b/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php index 995ce97803..fcffa1cd13 100644 --- a/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php +++ b/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php @@ -5,6 +5,7 @@ use Drupal\Component\Utility\Crypt; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\PhpStorage\PhpStorageFactory; +use Twig\Cache\CacheInterface; /** * Provides an alternate cache storage for Twig using PhpStorage. @@ -16,7 +17,7 @@ * * @see \Drupal\Core\DependencyInjection\Compiler\TwigExtensionPass */ -class TwigPhpStorageCache implements \Twig_CacheInterface { +class TwigPhpStorageCache implements CacheInterface { /** * The maximum length for each part of the cache key suffix. diff --git a/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php index 4adc9d60d3..ab8dc33feb 100644 --- a/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php +++ b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php @@ -3,6 +3,8 @@ namespace Drupal\Core\Template; use Drupal\Core\Site\Settings; +use Twig\Sandbox\SecurityError; +use Twig\Sandbox\SecurityPolicyInterface; /** * Default sandbox policy for Twig templates. @@ -13,7 +15,7 @@ * objects can do by whitelisting certain classes, method names, and method * names with an allowed prefix. All object properties may be accessed. */ -class TwigSandboxPolicy implements \Twig_Sandbox_SecurityPolicyInterface { +class TwigSandboxPolicy implements SecurityPolicyInterface { /** * An array of whitelisted methods in the form of methodName => TRUE. @@ -102,7 +104,7 @@ public function checkMethodAllowed($obj, $method) { } } - throw new \Twig_Sandbox_SecurityError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, get_class($obj))); + throw new SecurityError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, get_class($obj))); } } diff --git a/core/lib/Drupal/Core/Template/TwigTransTokenParser.php b/core/lib/Drupal/Core/Template/TwigTransTokenParser.php index 07580e90d7..93e4fdcfe3 100644 --- a/core/lib/Drupal/Core/Template/TwigTransTokenParser.php +++ b/core/lib/Drupal/Core/Template/TwigTransTokenParser.php @@ -2,6 +2,16 @@ namespace Drupal\Core\Template; +use Twig\Error\SyntaxError; +use Twig\Node\Expression\FilterExpression; +use Twig\Node\Expression\GetAttrExpression; +use Twig\Node\Expression\NameExpression; +use Twig\Node\Node; +use Twig\Node\PrintNode; +use Twig\Node\TextNode; +use Twig\Token; +use Twig\TokenParser\AbstractTokenParser; + /** * A class that defines the Twig 'trans' token parser for Drupal. * @@ -9,16 +19,15 @@ * code into an Abstract Syntax Tree (AST). The AST will later be compiled * into PHP code usable for runtime execution of the template. * - * @see \Twig_TokenParser * @see https://twig-extensions.readthedocs.io/en/latest/i18n.html * @see https://github.com/fabpot/Twig-extensions */ -class TwigTransTokenParser extends \Twig_TokenParser { +class TwigTransTokenParser extends AbstractTokenParser { /** * {@inheritdoc} */ - public function parse(\Twig_Token $token) { + public function parse(Token $token) { $lineno = $token->getLine(); $stream = $this->parser->getStream(); $body = NULL; @@ -26,24 +35,24 @@ public function parse(\Twig_Token $token) { $count = NULL; $plural = NULL; - if (!$stream->test(\Twig_Token::BLOCK_END_TYPE) && $stream->test(\Twig_Token::STRING_TYPE)) { + if (!$stream->test(Token::BLOCK_END_TYPE) && $stream->test(Token::STRING_TYPE)) { $body = $this->parser->getExpressionParser()->parseExpression(); } - if (!$stream->test(\Twig_Token::BLOCK_END_TYPE) && $stream->test(\Twig_Token::NAME_TYPE, 'with')) { + if (!$stream->test(Token::BLOCK_END_TYPE) && $stream->test(Token::NAME_TYPE, 'with')) { $stream->next(); $options = $this->parser->getExpressionParser()->parseExpression(); } if (!$body) { - $stream->expect(\Twig_Token::BLOCK_END_TYPE); + $stream->expect(Token::BLOCK_END_TYPE); $body = $this->parser->subparse([$this, 'decideForFork']); if ('plural' === $stream->next()->getValue()) { $count = $this->parser->getExpressionParser()->parseExpression(); - $stream->expect(\Twig_Token::BLOCK_END_TYPE); + $stream->expect(Token::BLOCK_END_TYPE); $plural = $this->parser->subparse([$this, 'decideForEnd'], TRUE); } } - $stream->expect(\Twig_Token::BLOCK_END_TYPE); + $stream->expect(Token::BLOCK_END_TYPE); $this->checkTransString($body, $lineno); @@ -76,27 +85,27 @@ public function getTag() { /** * Ensure that any nodes that are parsed are only of allowed types. * - * @param \Twig_Node $body + * @param \Twig\Node\Node $body * The expression to check. * @param int $lineno * The source line. * - * @throws \Twig_Error_Syntax + * @throws \Twig\Error\SyntaxError */ - protected function checkTransString(\Twig_Node $body, $lineno) { + protected function checkTransString(Node $body, $lineno) { foreach ($body as $node) { if ( - $node instanceof \Twig_Node_Text + $node instanceof TextNode || - ($node instanceof \Twig_Node_Print && $node->getNode('expr') instanceof \Twig_Node_Expression_Name) + ($node instanceof PrintNode && $node->getNode('expr') instanceof NameExpression) || - ($node instanceof \Twig_Node_Print && $node->getNode('expr') instanceof \Twig_Node_Expression_GetAttr) + ($node instanceof PrintNode && $node->getNode('expr') instanceof GetAttrExpression) || - ($node instanceof \Twig_Node_Print && $node->getNode('expr') instanceof \Twig_Node_Expression_Filter) + ($node instanceof PrintNode && $node->getNode('expr') instanceof FilterExpression) ) { continue; } - throw new \Twig_Error_Syntax(sprintf('The text to be translated with "trans" can only contain references to simple variables'), $lineno); + throw new SyntaxError(sprintf('The text to be translated with "trans" can only contain references to simple variables'), $lineno); } } diff --git a/core/modules/block_content/templates/block-content-add-list.html.twig b/core/modules/block_content/templates/block-content-add-list.html.twig index 08104617c6..f04d5e58ba 100644 --- a/core/modules/block_content/templates/block-content-add-list.html.twig +++ b/core/modules/block_content/templates/block-content-add-list.html.twig @@ -14,11 +14,11 @@ * @ingroup themeable */ #} -{% spaceless %} +{% apply spaceless %}