Files
kupshop/bundles/KupShop/KupShopBundle/Command/CompileTemplatesCommand.php
2025-08-02 16:30:27 +02:00

126 lines
4.7 KiB
PHP

<?php
namespace KupShop\KupShopBundle\Command;
use KupShop\I18nBundle\Entity\Language;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Functional\Mapping;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
#[AsCommand('kupshop:compile_templates', 'Compile all top-level templates in all languages (if LANGUAGES env present)')]
class CompileTemplatesCommand extends Command
{
public const INLINE_ONLY_MARKER = '@compiler:inline-only';
public function run(InputInterface $input, OutputInterface $output): int
{
// Ignore i18bundle - do not load from database - not present during build
$languageContext = Contexts::get(LanguageContext::class);
// Try to take languages from env
if (getenv('LANGUAGES')) {
$languages = Mapping::mapKeys(explode(',', getenv('LANGUAGES')), function ($index, $lang) {
$language = new Language();
$language->setId($lang);
return [$lang, $language];
});
} else {
$languages = (new LanguageContext())->getSupported();
}
$reflection = new \ReflectionClass($languageContext);
$property = $reflection->getProperty('supported');
$property->setAccessible(true);
$property->setValue($languageContext, $languages);
error_reporting(E_ALL & ~(E_NOTICE | E_DEPRECATED | E_USER_DEPRECATED | E_WARNING));
foreach ($languageContext->getSupported() as $id => $lang) {
$languageContext->activate($id);
$this->compileTemplates($id, $output);
}
return 0;
}
protected function compileTemplates($id, OutputInterface $output)
{
$output->writeln("Compiling {$id} templates ...");
$extension = 'tpl';
$templatesToCompile = [];
$inlineOnlyTemplates = [];
// loop over array of template directories
$smarty = createSmarty();
foreach ($smarty->getTemplateDir() as $templateDir) {
if (!is_dir($templateDir)) {
continue;
}
$dirIterator = new \RecursiveDirectoryIterator($templateDir);
$filesIterator = new \RecursiveIteratorIterator($dirIterator);
foreach ($filesIterator as $file) {
$template = $file->getFilename();
if (substr(basename($file->getPathname()), 0, 1) == '.') {
continue;
}
if (!substr_compare($template, $extension, -strlen($extension)) == 0) {
continue;
}
if (!is_file($file->getPathname())) {
$output->writeln('!skip nonexistent!'.$file->getPathname());
continue;
}
// Get relative template path inside template folder
if ($file->getPath() == substr($templateDir, 0, -1)) {
$templateName = $template;
} else {
$templateName = substr($file->getPath(), strlen($templateDir)).DIRECTORY_SEPARATOR.$template;
}
// Skip files marked as 'inline only' - no need to compile them separately
if (strpos(file_get_contents($file->getPathname()), self::INLINE_ONLY_MARKER) !== false) {
$output->writeln('!skip inline only!'.$templateName);
$inlineOnlyTemplates[] = $templateName;
continue;
}
$templatesToCompile[] = $templateName;
}
}
$templatesToCompile = array_diff(array_unique($templatesToCompile), array_unique($inlineOnlyTemplates));
// $templatesToCompile=['index.tpl', 'home.tpl'];
foreach ($templatesToCompile as $template) {
$output->write(" {$template}: ");
$timestart = getScriptTime();
$smarty = createSmarty();
// ReRegister switch plugin
$smarty->loadPlugin('smarty_compiler_switch');
$smarty->registerFilter('post', 'smarty_postfilter_switch');
$cache_id = null;
if ($smarty instanceof \SmartyML) {
$cache_id = Contexts::get(LanguageContext::class)->getActiveId();
}
$_tpl = $smarty->createTemplate($template, $cache_id, $cache_id, null, false);
if ($_tpl->mustCompile()) {
$_tpl->compileTemplateSource();
}
$duration = round((getScriptTime() - $timestart) * 1000);
$output->writeln("{$duration}ms");
}
}
}