-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add filter on the module folder to avoid caching all files by Twig
- Loading branch information
1 parent
e53dce6
commit 88428fd
Showing
8 changed files
with
383 additions
and
0 deletions.
There are no files selected for viewing
114 changes: 114 additions & 0 deletions
114
src/PrestaShopBundle/Cache/ModuleTemplateCacheWarmer.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
<?php | ||
/** | ||
* 2007-2019 PrestaShop and contributors. | ||
* | ||
* NOTICE OF LICENSE | ||
* | ||
* This source file is subject to the Open Software License (OSL 3.0) | ||
* that is bundled with this package in the file LICENSE.txt. | ||
* It is also available through the world-wide-web at this URL: | ||
* https://opensource.org/licenses/OSL-3.0 | ||
* If you did not receive a copy of the license and are unable to | ||
* obtain it through the world-wide-web, please send an email | ||
* to license@prestashop.com so we can send you a copy immediately. | ||
* | ||
* DISCLAIMER | ||
* | ||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer | ||
* versions in the future. If you wish to customize PrestaShop for your | ||
* needs please refer to http://www.prestashop.com for more information. | ||
* | ||
* @author PrestaShop SA <contact@prestashop.com> | ||
* @copyright 2007-2019 PrestaShop SA and contributors | ||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) | ||
* International Registered Trademark & Property of PrestaShop SA | ||
*/ | ||
|
||
namespace PrestaShopBundle\Cache; | ||
|
||
use Psr\Container\ContainerInterface; | ||
use Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinderInterface; | ||
use Symfony\Component\Finder\Finder; | ||
use Symfony\Component\Templating\TemplateReference; | ||
use Twig\Error\Error; | ||
use Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheCacheWarmer; | ||
|
||
/** | ||
* Generates the Twig cache for all paths, with a specific filter for given namespace | ||
*/ | ||
class ModuleTemplateCacheWarmer extends TemplateCacheCacheWarmer | ||
{ | ||
private $paths; | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function __construct(ContainerInterface $container, TemplateFinderInterface $finder = null, $paths = array()) | ||
{ | ||
$this->paths = []; | ||
$keyToRemove = array_search('Modules', $paths); | ||
// If the key was found, move it in a new array | ||
if (false !== $keyToRemove) { | ||
$exceptionPath = $paths[$keyToRemove]; | ||
unset($paths[$keyToRemove]); | ||
$this->paths = [$keyToRemove => $exceptionPath]; | ||
} | ||
parent::__construct($container, $finder, $paths); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function warmUp($cacheDir) | ||
{ | ||
// Default behavior for all folder except Modules | ||
parent::warmUp($cacheDir); | ||
|
||
$twig = $this->container->get('twig'); | ||
$templates = []; | ||
|
||
foreach ($this->paths as $path => $namespace) { | ||
$templates = array_merge($templates, $this->findTemplatesInFolder($namespace, $path)); | ||
} | ||
|
||
foreach ($templates as $template) { | ||
if ('twig' !== $template->get('engine')) { | ||
continue; | ||
} | ||
|
||
try { | ||
$twig->loadTemplate($template); | ||
} catch (Error $e) { | ||
// problem during compilation, give up | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Find templates from *.twig files in the given directory. | ||
* | ||
* @param string $namespace The namespace for these templates | ||
* @param string $dir The folder where to look for templates | ||
* | ||
* @return array An array of templates of type TemplateReferenceInterface | ||
*/ | ||
private function findTemplatesInFolder($namespace, $dir) | ||
{ | ||
if (!is_dir($dir)) { | ||
return array(); | ||
} | ||
|
||
$templates = array(); | ||
$finder = new Finder(); | ||
|
||
foreach ($finder->files()->followLinks()->name('*.twig')->in($dir) as $file) { | ||
$name = $file->getRelativePathname(); | ||
$templates[] = new TemplateReference( | ||
$namespace ? sprintf('@%s/%s', $namespace, $name) : $name, | ||
'twig' | ||
); | ||
} | ||
|
||
return $templates; | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
src/PrestaShopBundle/DependencyInjection/Compiler/OverrideTwigServiceCompilerPass.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php | ||
/** | ||
* 2007-2018 PrestaShop. | ||
* | ||
* NOTICE OF LICENSE | ||
* | ||
* This source file is subject to the Open Software License (OSL 3.0) | ||
* that is bundled with this package in the file LICENSE.txt. | ||
* It is also available through the world-wide-web at this URL: | ||
* https://opensource.org/licenses/OSL-3.0 | ||
* If you did not receive a copy of the license and are unable to | ||
* obtain it through the world-wide-web, please send an email | ||
* to license@prestashop.com so we can send you a copy immediately. | ||
* | ||
* DISCLAIMER | ||
* | ||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer | ||
* versions in the future. If you wish to customize PrestaShop for your | ||
* needs please refer to http://www.prestashop.com for more information. | ||
* | ||
* @author PrestaShop SA <contact@prestashop.com> | ||
* @copyright 2007-2018 PrestaShop SA | ||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) | ||
* International Registered Trademark & Property of PrestaShop SA | ||
*/ | ||
|
||
namespace PrestaShopBundle\DependencyInjection\Compiler; | ||
|
||
use PrestaShopBundle\Cache\ModuleTemplateCacheWarmer; | ||
use PrestaShopBundle\Twig\Locator\ModuleTemplateIterator; | ||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
|
||
/** | ||
* Twig templates are allowed in the whole modules folder. | ||
* However, the generated cache parse all the files found each folder in `twig.paths`, | ||
* including php, css, js, md files and so on. | ||
* | ||
* This compiler pass updates the called class to filter the allowed extensions. | ||
*/ | ||
class OverrideTwigServiceCompilerPass implements CompilerPassInterface | ||
{ | ||
public function process(ContainerBuilder $container) | ||
{ | ||
$definition = $container->getDefinition('twig.cache_warmer'); | ||
$definition->setClass(ModuleTemplateCacheWarmer::class); | ||
|
||
$definition = $container->getDefinition('twig.template_iterator'); | ||
$definition->setClass(ModuleTemplateIterator::class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
src/PrestaShopBundle/Twig/Locator/ModuleTemplateIterator.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<?php | ||
|
||
/** | ||
* 2007-2018 PrestaShop. | ||
* | ||
* NOTICE OF LICENSE | ||
* | ||
* This source file is subject to the Open Software License (OSL 3.0) | ||
* that is bundled with this package in the file LICENSE.txt. | ||
* It is also available through the world-wide-web at this URL: | ||
* https://opensource.org/licenses/OSL-3.0 | ||
* If you did not receive a copy of the license and are unable to | ||
* obtain it through the world-wide-web, please send an email | ||
* to license@prestashop.com so we can send you a copy immediately. | ||
* | ||
* DISCLAIMER | ||
* | ||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer | ||
* versions in the future. If you wish to customize PrestaShop for your | ||
* needs please refer to http://www.prestashop.com for more information. | ||
* | ||
* @author PrestaShop SA <contact@prestashop.com> | ||
* @copyright 2007-2018 PrestaShop SA | ||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) | ||
* International Registered Trademark & Property of PrestaShop SA | ||
*/ | ||
|
||
namespace PrestaShopBundle\Twig\Locator; | ||
|
||
use Symfony\Bundle\TwigBundle\TemplateIterator; | ||
use Symfony\Component\Finder\Finder; | ||
use Symfony\Component\HttpKernel\KernelInterface; | ||
|
||
/** | ||
* Extended class: Iterator for all templates in bundles and in the application Resources directory. | ||
* This one applies a specific filter on the module folder, in order to take only *.twig | ||
*/ | ||
class ModuleTemplateIterator extends TemplateIterator | ||
{ | ||
private $kernel; | ||
private $rootDir; | ||
private $templates; | ||
private $paths; | ||
private $defaultPath; | ||
|
||
/** | ||
* @param KernelInterface $kernel A KernelInterface instance | ||
* @param string $rootDir The directory where global templates can be stored | ||
* @param array $paths Additional Twig paths to warm | ||
* @param string $defaultPath The directory where global templates can be stored | ||
*/ | ||
public function __construct(KernelInterface $kernel, $rootDir, array $paths = array(), $defaultPath = null) | ||
{ | ||
$this->paths = []; | ||
$this->kernel = $kernel; | ||
$this->rootDir = $rootDir; | ||
$this->defaultPath = $defaultPath; | ||
|
||
$keyToRemove = array_search('Modules', $paths); | ||
// If the key was found, move it in a new array | ||
if (false !== $keyToRemove) { | ||
$exceptionPath = $paths[$keyToRemove]; | ||
unset($paths[$keyToRemove]); | ||
$this->paths = [$keyToRemove => $exceptionPath]; | ||
} | ||
parent::__construct($kernel, $rootDir, $paths, $defaultPath); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getIterator() | ||
{ | ||
if (null !== $this->templates) { | ||
return $this->templates; | ||
} | ||
|
||
// Not done yet, we need the array back | ||
$this->templates = iterator_to_array(parent::getIterator()); | ||
|
||
foreach ($this->paths as $dir => $namespace) { | ||
$this->templates = array_merge($this->templates, $this->findTemplatesInDirectory($dir, $namespace)); | ||
} | ||
|
||
return $this->templates = new \ArrayIterator(array_unique($this->templates)); | ||
} | ||
|
||
/** | ||
* Find templates in the given directory. | ||
* | ||
* @param string $dir The directory where to look for templates | ||
* @param string|null $namespace The template namespace | ||
* | ||
* @return array | ||
*/ | ||
private function findTemplatesInDirectory($dir, $namespace = null, array $excludeDirs = array()) | ||
{ | ||
if (!is_dir($dir)) { | ||
return array(); | ||
} | ||
|
||
$templates = array(); | ||
foreach (Finder::create()->files()->name('*.twig')->followLinks()->in($dir)->exclude($excludeDirs) as $file) { | ||
$templates[] = (null !== $namespace ? '@' . $namespace . '/' : '') . str_replace('\\', '/', $file->getRelativePathname()); | ||
} | ||
|
||
return $templates; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?php | ||
/** | ||
* 2007-2019 PrestaShop. | ||
* | ||
* NOTICE OF LICENSE | ||
* | ||
* This source file is subject to the Open Software License (OSL 3.0) | ||
* that is bundled with this package in the file LICENSE.txt. | ||
* It is also available through the world-wide-web at this URL: | ||
* https://opensource.org/licenses/OSL-3.0 | ||
* If you did not receive a copy of the license and are unable to | ||
* obtain it through the world-wide-web, please send an email | ||
* to license@prestashop.com so we can send you a copy immediately. | ||
* | ||
* DISCLAIMER | ||
* | ||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer | ||
* versions in the future. If you wish to customize PrestaShop for your | ||
* needs please refer to http://www.prestashop.com for more information. | ||
* | ||
* @author PrestaShop SA <contact@prestashop.com> | ||
* @copyright 2007-2019 PrestaShop SA | ||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) | ||
* International Registered Trademark & Property of PrestaShop SA | ||
*/ | ||
|
||
namespace Tests\Unit\Core\Cache; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use PrestaShopBundle\Cache\ModuleTemplateCacheWarmer; | ||
use Symfony\Component\DependencyInjection\ContainerInterface; | ||
use Twig\Environment; | ||
|
||
// REVIEW ME: Is this class well located? | ||
class ModuleTemplateCacheWarmerTest extends TestCase | ||
{ | ||
public function testOnlyGenerateTwig() | ||
{ | ||
$twigMock = $this | ||
->getMockBuilder(Environment::class) | ||
->disableOriginalConstructor() | ||
->setMethods(array('loadTemplate')) | ||
->getMock(); | ||
|
||
$container = $this->getMockBuilder(ContainerInterface::class)->disableOriginalConstructor()->getMock(); | ||
$container->expects($this->any())->method('get')->with('twig')->will($this->returnValue($twigMock)); | ||
|
||
$cacheWarmer = new ModuleTemplateCacheWarmer($container, null, [__DIR__ . '/../../Twig/Fixtures/modules' => 'Modules']); | ||
|
||
// Actual test: Should only have one file to load | ||
$twigMock | ||
->expects($this->once()) | ||
->method('loadTemplate'); | ||
|
||
$cacheWarmer->warmUp(sys_get_temp_dir()); | ||
} | ||
} |
Empty file.
Empty file.
Oops, something went wrong.