Skip to content

Commit 2c6c7b0

Browse files
committed
- Added Magento 2.4.0 compatibility
- Removed helper functions from `app/functions.php` since the file is no longer available in Magento 2.4 - Removed deprecated function `layoutBlock` from twig environment - Updated to twig to 3.0.*
1 parent ab83282 commit 2c6c7b0

File tree

5 files changed

+78
-138
lines changed

5 files changed

+78
-138
lines changed

Framework/View/TemplateEngine/Twig.php

Lines changed: 55 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace SchumacherFM\Twig\Framework\View\TemplateEngine;
44

5+
use LogicException;
6+
use Magento\Framework\Exception\FileSystemException;
57
use Magento\Framework\ObjectManagerInterface;
68
use Magento\Framework\Event\ManagerInterface;
79
use Magento\Framework\View\Element\AbstractBlock;
@@ -11,38 +13,53 @@
1113
use Magento\Framework\App\Filesystem\DirectoryList;
1214
use Magento\Framework\App\Config\ScopeConfigInterface;
1315
use Twig\Environment;
16+
use Twig\Error\LoaderError;
17+
use Twig\Error\RuntimeError;
18+
use Twig\Error\SyntaxError;
19+
use Twig\Extension\DebugExtension;
20+
use Twig\TemplateWrapper;
21+
use Twig\TwigFilter;
22+
use Twig\TwigFunction;
1423

1524
class Twig extends Php
1625
{
1726
const TWIG_CACHE_DIR = 'twig';
1827

1928
/**
20-
* @var \Magento\Framework\App\Config\ScopeConfigInterface
29+
* @var ScopeConfigInterface
2130
*/
22-
protected $_scopeConfig;
31+
protected $scopeConfig;
32+
2333
/**
24-
* @var \Twig_Environment
34+
* @var Environment
2535
*/
26-
private $twig = null;
36+
protected $twig = null;
37+
2738
/**
2839
* @var DirectoryList
2940
*/
30-
protected $_directoryList;
41+
protected $directoryList;
42+
3143
/**
3244
* Event manager
3345
*
34-
* @var \Magento\Framework\Event\ManagerInterface
46+
* @var ManagerInterface
3547
*/
3648
protected $eventManager;
3749

50+
/**
51+
* @var BlockInterface
52+
*/
53+
protected $currentBlock;
54+
3855
/**
3956
* @param ObjectManagerInterface $helperFactory
4057
* @param DirectoryList $directoryList
4158
* @param ScopeConfigInterface $scopeConfig
4259
* @param ManagerInterface $eventManager
4360
* @param Environment $twig
4461
*
45-
* @throws \Magento\Framework\Exception\FileSystemException
62+
* @throws FileSystemException
4663
*/
4764
public function __construct(
4865
ObjectManagerInterface $helperFactory,
@@ -53,8 +70,8 @@ public function __construct(
5370
)
5471
{
5572
parent::__construct($helperFactory);
56-
$this->_directoryList = $directoryList;
57-
$this->_scopeConfig = $scopeConfig;
73+
$this->directoryList = $directoryList;
74+
$this->scopeConfig = $scopeConfig;
5875
$this->eventManager = $eventManager;
5976
$this->twig = $twig;
6077
$this->initTwig();
@@ -63,68 +80,50 @@ public function __construct(
6380
/**
6481
* Initialises Twig with all Magento 2 necessary functions
6582
*
66-
* @throws \Magento\Framework\Exception\FileSystemException
83+
* @throws FileSystemException
6784
*/
6885
private function initTwig()
6986
{
7087
$this->twig->setCache($this->getCachePath());
71-
if ($this->_scopeConfig->isSetFlag('dev/twig/debug')) {
88+
if ($this->scopeConfig->isSetFlag('dev/twig/debug')) {
7289
$this->twig->enableDebug();
7390
} else {
7491
$this->twig->disableDebug();
7592
}
76-
if ($this->_scopeConfig->isSetFlag('dev/twig/auto_reload')) {
93+
if ($this->scopeConfig->isSetFlag('dev/twig/auto_reload')) {
7794
$this->twig->enableAutoReload();
7895
} else {
7996
$this->twig->disableAutoReload();
8097
}
81-
if ($this->_scopeConfig->isSetFlag('dev/twig/strict_variables')) {
98+
if ($this->scopeConfig->isSetFlag('dev/twig/strict_variables')) {
8299
$this->twig->enableStrictVariables();
83100
} else {
84101
$this->twig->disableStrictVariables();
85102
}
86-
$this->twig->setCharset($this->_scopeConfig->getValue('dev/twig/charset'));
87-
$this->twig->addFunction(new \Twig\TwigFunction('helper', [$this, 'helper']));
88-
$this->twig->addFunction(new \Twig\TwigFunction('layoutBlock', [$this, 'layoutBlock']));
89-
$this->twig->addFunction(new \Twig\TwigFunction('get*', [$this, 'catchGet']));
90-
$this->twig->addFunction(new \Twig\TwigFunction('isset', [$this, '__isset']));
91-
$this->twig->addFunction(new \Twig\TwigFunction('child_html', [$this, 'getChildHtml'], [
103+
$this->twig->setCharset($this->scopeConfig->getValue('dev/twig/charset'));
104+
$this->twig->addFunction(new TwigFunction('helper', [$this, 'helper']));
105+
$this->twig->addFunction(new TwigFunction('get*', [$this, 'catchGet']));
106+
$this->twig->addFunction(new TwigFunction('isset', [$this, '__isset']));
107+
$this->twig->addFunction(new TwigFunction('child_html', [$this, 'getChildHtml'], [
92108
'needs_context' => true,
93109
'is_safe' => ['html']
94110
]));
95111

96-
$this->twig->addFilter(new \Twig\TwigFilter('trans', '__'));
97-
$this->twig->addExtension(new \Twig\Extension\DebugExtension());
98-
foreach ($this->getDefinedFunctionsInHelpersFile() as $functionName) {
99-
$this->twig->addFunction(new \Twig\TwigFunction($functionName, $functionName));
100-
}
112+
$this->twig->addFilter(new TwigFilter('trans', '__'));
113+
$this->twig->addExtension(new DebugExtension());
101114
$this->eventManager->dispatch('twig_init', ['twig' => $this->twig]);
102115
}
103116

104-
/**
105-
* @return \Twig\Loader\LoaderInterface
106-
* @throws \Magento\Framework\Exception\FileSystemException
107-
*/
108-
private function getLoader()
109-
{
110-
$loader = new \stdClass();
111-
$this->eventManager->dispatch('twig_loader', ['loader' => $loader]);
112-
if (false === ($loader instanceof \Twig\Loader\LoaderInterface)) {
113-
$loader = new \Twig\Loader\FilesystemLoader($this->_directoryList->getPath(DirectoryList::ROOT));
114-
}
115-
return $loader;
116-
}
117-
118117
/**
119118
* @return string
120-
* @throws \Magento\Framework\Exception\FileSystemException
119+
* @throws FileSystemException
121120
*/
122121
private function getCachePath()
123122
{
124-
if (false === $this->_scopeConfig->isSetFlag('dev/twig/cache')) {
123+
if (false === $this->scopeConfig->isSetFlag('dev/twig/cache')) {
125124
return false;
126125
}
127-
return $this->_directoryList->getPath(DirectoryList::VAR_DIR) . DIRECTORY_SEPARATOR . self::TWIG_CACHE_DIR;
126+
return $this->directoryList->getPath(DirectoryList::VAR_DIR) . DIRECTORY_SEPARATOR . self::TWIG_CACHE_DIR;
128127
}
129128

130129
/**
@@ -136,19 +135,6 @@ public function catchGet(...$args)
136135
return $this->__call('get' . $name, $args);
137136
}
138137

139-
/**
140-
* @param $method
141-
* @param $args
142-
*
143-
* @deprecated since 1.7
144-
* @return mixed
145-
*/
146-
public function layoutBlock($method, $args)
147-
{
148-
@trigger_error(sprintf('Using the "layoutBlock" function in twig is deprecated since version 1.7, use the "block" variable instead.'), E_USER_DEPRECATED);
149-
return $this->__call($method, $args);
150-
}
151-
152138
/**
153139
* Render template
154140
* Render the named template in the context of a particular block and with
@@ -158,33 +144,33 @@ public function layoutBlock($method, $args)
158144
* @param string $fileName
159145
* @param array $dictionary
160146
* @return string rendered template
161-
* @throws \Magento\Framework\Exception\FileSystemException
162-
* @throws \Twig\Error\LoaderError
163-
* @throws \Twig\Error\RuntimeError
164-
* @throws \Twig\Error\SyntaxError
147+
* @throws FileSystemException
148+
* @throws LoaderError
149+
* @throws RuntimeError
150+
* @throws SyntaxError
165151
*/
166152
public function render(BlockInterface $block, $fileName, array $dictionary = [])
167153
{
168-
$tmpBlock = $this->_currentBlock;
169-
$this->_currentBlock = $block;
154+
$tmpBlock = $this->currentBlock;
155+
$this->currentBlock = $block;
170156
$this->twig->addGlobal('block', $block);
171157
$result = $this->getTemplate($fileName)->render($dictionary);
172-
$this->_currentBlock = $tmpBlock;
158+
$this->currentBlock = $tmpBlock;
173159
return $result;
174160
}
175161

176162
/**
177163
* @param $fileName
178164
*
179-
* @return \Twig\TemplateWrapper
180-
* @throws \Magento\Framework\Exception\FileSystemException
181-
* @throws \Twig\Error\LoaderError
182-
* @throws \Twig\Error\RuntimeError
183-
* @throws \Twig\Error\SyntaxError
165+
* @return TemplateWrapper
166+
* @throws FileSystemException
167+
* @throws LoaderError
168+
* @throws RuntimeError
169+
* @throws SyntaxError
184170
*/
185171
private function getTemplate($fileName)
186172
{
187-
$tf = str_replace($this->_directoryList->getPath(DirectoryList::ROOT) . DIRECTORY_SEPARATOR, '', $fileName);
173+
$tf = str_replace($this->directoryList->getPath(DirectoryList::ROOT) . DIRECTORY_SEPARATOR, '', $fileName);
188174
return $this->twig->load($tf);
189175
}
190176

@@ -193,13 +179,13 @@ private function getTemplate($fileName)
193179
*
194180
* @param string $className
195181
* @return AbstractHelper
196-
* @throws \LogicException
182+
* @throws LogicException
197183
*/
198184
public function helper($className)
199185
{
200186
$helper = $this->_helperFactory->get($className);
201187
if (false === $helper instanceof AbstractHelper) {
202-
throw new \LogicException($className . ' doesn\'t extends Magento\Framework\App\Helper\AbstractHelper');
188+
throw new LogicException($className . ' doesn\'t extends Magento\Framework\App\Helper\AbstractHelper');
203189
}
204190
return $helper;
205191
}
@@ -216,54 +202,4 @@ public function getChildHtml(array $context, $alias = '', $useCache = true)
216202
return $block->getChildHtml($alias, $useCache);
217203
}
218204

219-
/**
220-
* @return array
221-
* @throws \Magento\Framework\Exception\FileSystemException
222-
*/
223-
private function getDefinedFunctionsInHelpersFile()
224-
{
225-
$filepath = $this->_directoryList->getPath(DirectoryList::APP) . '/functions.php';
226-
$source = file_get_contents($filepath);
227-
$tokens = token_get_all($source);
228-
$functions = array();
229-
$nextStringIsFunc = false;
230-
$inClass = false;
231-
$bracesCount = 0;
232-
foreach ($tokens as $token) {
233-
switch ($token[0]) {
234-
case T_CLASS:
235-
$inClass = true;
236-
break;
237-
case T_FUNCTION:
238-
if (!$inClass) {
239-
$nextStringIsFunc = true;
240-
}
241-
break;
242-
case T_STRING:
243-
if ($nextStringIsFunc) {
244-
$nextStringIsFunc = false;
245-
$functions[] = $token[1];
246-
}
247-
break;
248-
// Anonymous functions
249-
case '(':
250-
case ';':
251-
$nextStringIsFunc = false;
252-
break;
253-
// Exclude Classes
254-
case '{':
255-
if ($inClass) $bracesCount++;
256-
break;
257-
case '}':
258-
if ($inClass) {
259-
$bracesCount--;
260-
if ($bracesCount === 0) {
261-
$inClass = false;
262-
}
263-
}
264-
break;
265-
}
266-
}
267-
return $functions;
268-
}
269205
}

Plugin/TemplatePlugin.php

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,36 @@
22

33
namespace SchumacherFM\Twig\Plugin;
44

5+
use Magento\Framework\View\Element\Template;
6+
use Magento\Framework\View\Element\Template\File\Validator;
7+
58
/**
69
* Class TemplatePlugin
710
*/
811
class TemplatePlugin
912
{
1013
/**
11-
* @var \Magento\Framework\View\Element\Template\File\Validator
14+
* @var Validator
1215
*/
1316
protected $validator;
1417

1518
/**
1619
* TemplatePlugin constructor.
1720
*
18-
* @param \Magento\Framework\View\Element\Template\File\Validator $validator
21+
* @param Validator $validator
1922
*/
20-
public function __construct(
21-
\Magento\Framework\View\Element\Template\File\Validator $validator
22-
)
23+
public function __construct(Validator $validator)
2324
{
2425
$this->validator = $validator;
2526
}
2627

2728
/**
28-
* @param \Magento\Framework\View\Element\Template $subject
29+
* @param Template $subject
2930
* @param callable $proceed
3031
* @param string $fileName
3132
* @return string
3233
*/
33-
public function aroundFetchView(
34-
\Magento\Framework\View\Element\Template $subject,
35-
callable $proceed,
36-
string $fileName
37-
): string
34+
public function aroundFetchView(Template $subject, callable $proceed, string $fileName): string
3835
{
3936
$twigFile = $subject->getTemplateFile(str_replace('.phtml', '.html.twig', $subject->getTemplate()));
4037

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,12 @@ For versioning have a look at [Semantic Versioning 2.0.0](http://semver.org/)
163163
History
164164
-------
165165

166-
#### 0.1.0
166+
#### 2.0.0
167167

168-
- Initial release
168+
- Added Magento 2.4.0 compatibility
169+
- Removed helper functions from `app/functions.php` since the file is no longer available in Magento 2.4
170+
- Removed deprecated function `layoutBlock` from twig environment
171+
- Updated to twig to 3.0.*
169172

170173
License
171174
-------

Twig/Loader/FilesystemLoader.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
<?php
1+
<?php declare(strict_types=1);
22

33
namespace SchumacherFM\Twig\Twig\Loader;
44

55
use Magento\Framework\App\Filesystem\DirectoryList;
6-
use Magento\Framework\View\Design\ThemeInterface;
76
use Magento\Framework\View\DesignInterface;
87
use Magento\Framework\View\Element\Template\File\Resolver;
98
use Magento\Framework\View\File\Collector\Base;
@@ -105,7 +104,6 @@ protected function initTemplateNamespaces()
105104
}
106105

107106
// Add Theme Namespaces
108-
/** @var ThemeInterface[] $inheritedThemes */
109107
$inheritedThemes = $theme->getInheritedThemes();
110108
foreach ($inheritedThemes as $inheritanceLevel => $currentTheme) {
111109
$themeFiles = $this->themeFilesCollector->getFiles($currentTheme, 'templates');

0 commit comments

Comments
 (0)