pug-php/pug-symfony

View on GitHub
src/Pug/Twig/Environment.php

Summary

Maintainability
B
6 hrs
Test Coverage
<?php
 
declare(strict_types=1);
 
namespace Pug\Twig;
 
use Psr\Container\ContainerInterface;
use Pug\PugSymfonyEngine;
use Pug\Symfony\Traits\PrivatePropertyAccessor;
use RuntimeException;
use Twig\Environment as TwigEnvironment;
use Twig\Error\RuntimeError;
use Twig\Extension\EscaperExtension;
use Twig\Extension\OptimizerExtension;
use Twig\Loader\LoaderInterface;
use Twig\Parser;
use Twig\Source;
use Twig\Template;
use Twig\TwigFunction;
 
class Environment extends TwigEnvironment
{
use PrivatePropertyAccessor;
 
`syntax error, unexpected 'PugSymfonyEngine' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST)`
protected PugSymfonyEngine $pugSymfonyEngine;
 
protected ContainerInterface $container;
 
/**
* @var string[]
*/
protected array $classNames = [];
 
public array $extensions = [];
 
public TwigEnvironment $rootEnv;
 
public TwigEnvironment $env;
 
public function __construct(LoaderInterface $loader, $options = [])
{
parent::__construct($loader, $options);
 
$this->extensions = $this->getExtensions();
}
 
public function getEngine()
{
return $this->pugSymfonyEngine;
}
 
public function getRenderer()
{
return $this->pugSymfonyEngine->getRenderer();
}
 
public function getRuntime(string $class)
{
try {
return parent::getRuntime($class);
} catch (RuntimeError $error) {
if (!($this->rootEnv ?? null)) {
throw $error;
}
 
try {
return $this->rootEnv->getRuntime($class);
} catch (RuntimeError) {
throw $error;
}
}
}
 
Method `fromTwigEnvironment` has 27 lines of code (exceeds 25 allowed). Consider refactoring.
public static function fromTwigEnvironment(
TwigEnvironment $baseTwig,
PugSymfonyEngine $pugSymfonyEngine,
ContainerInterface $container,
): static {
$twig = new static($baseTwig->getLoader(), [
'debug' => $baseTwig->isDebug(),
'charset' => $baseTwig->getCharset(),
'strict_variables' => $baseTwig->isStrictVariables(),
Line exceeds 120 characters; contains 125 characters
'autoescape' => static::getPrivateExtensionProperty($baseTwig, EscaperExtension::class, 'defaultStrategy'),
'cache' => $baseTwig->getCache(true),
'auto_reload' => $baseTwig->isAutoReload(),
Line exceeds 120 characters; contains 122 characters
'optimizations' => static::getPrivateExtensionProperty($baseTwig, OptimizerExtension::class, 'optimizers'),
]);
$twig->rootEnv = $baseTwig;
 
$twig->setPugSymfonyEngine($pugSymfonyEngine);
$twig->setContainer($container);
 
$extensions = $baseTwig->getExtensions();
 
foreach (array_keys($twig->getExtensions()) as $key) {
unset($extensions[$key]);
}
 
foreach ($baseTwig->getGlobals() as $key => $value) {
$twig->addGlobal($key, $value);
}
 
foreach ($baseTwig->getFilters() as $filter) {
$twig->addFilter($filter);
}
 
foreach ($baseTwig->getFunctions() as $function) {
$twig->addFunction($function);
}
 
$twig->setExtensions($extensions);
 
return $twig;
}
 
public function setPugSymfonyEngine(PugSymfonyEngine $pugSymfonyEngine): void
{
$this->pugSymfonyEngine = $pugSymfonyEngine;
}
 
public function setContainer(ContainerInterface $container): void
{
$this->container = $container;
}
 
/**
* @SuppressWarnings(PHPMD.DuplicatedArrayKey)
*/
Function `compileSource` has a Cognitive Complexity of 23 (exceeds 5 allowed). Consider refactoring.
Method `compileSource` has 46 lines of code (exceeds 25 allowed). Consider refactoring.
The method compileSource() has a Cyclomatic Complexity of 10. The configured cyclomatic complexity threshold is 10.
public function compileSource(Source $source): string
{
$path = $source->getPath();
 
if ($this->pugSymfonyEngine->supports($path)) {
$pug = $this->getRenderer();
$code = $source->getCode();
$php = $pug->compile($code, $path);
$codeFirstLine = $this->isDebug() ? 39 : 28;
$templateLine = 1;
$debugInfo = [$codeFirstLine => $templateLine];
$lines = explode("\n", $php);
 
if ($this->isDebug()) {
$formatter = $pug->getCompiler()->getFormatter();
 
foreach ($lines as $index => $line) {
if (preg_match('/^\/\/ PUG_DEBUG:(\d+)$/m', $line, $match)) {
$node = $formatter->getNodeFromDebugId((int) $match[1]);
$location = $node->getSourceLocation();
 
if ($location) {
$newLine = $location->getLine();
 
Avoid deeply nested control flow statements.
if ($newLine > $templateLine) {
$templateLine = $newLine;
$debugInfo[$codeFirstLine + $index] = $newLine;
}
}
}
}
}
 
$fileName = $this->isDebug() ? 'PugDebugTemplateTemplate' : 'PugTemplateTemplate';
$templateFile = __DIR__."/../../../cache-templates/$fileName.php";
$name = $source->getName();
$className = $this->classNames[$name] ?? '__Template_'.sha1($path);
$pathExport = var_export($path, true);
$replacements = [
$fileName => $className,
"'{{filename}}'" => var_export($name, true),
'{{filename}}' => $name,
"'{{path}}'" => $pathExport,
'// {{code}}' => "?>$php<?php",
'[/* {{debugInfo}} */]' => var_export(array_reverse($debugInfo, true), true),
];
 
if ($this->isDebug()) {
$sourceExport = var_export($code, true);
$replacements["'{{source}}'"] = $sourceExport;
$replacements['__internal_1'] = '__internal_'.sha1('1'.$path);
$replacements['__internal_2'] = '__internal_'.sha1('2'.$path);
}
 
return strtr(file_get_contents($templateFile), $replacements);
}
 
return parent::compileSource($source);
}
 
public function loadTemplate(string $cls, string $name, int $index = null): Template
{
$this->classNames[$name] = $cls.($index === null ? '' : '___'.$index);
 
return parent::loadTemplate($cls, $name, $index);
}
 
public function render($name, array $context = []): string
{
if (is_string($name) && $this->pugSymfonyEngine->supports($name)) {
[$name, $context] = $this->pugSymfonyEngine->getRenderArguments($name, $context);
}
 
return parent::render($name, $context);
}
 
public function getTemplateClass(string $name, int $index = null): string
{
if (substr($name, 0, 16) === '__twig_function_') {
return 'TwigFunctionTemplate_'.sha1($name);
}
 
return parent::getTemplateClass($name, $index);
}
 
public function compileCode(TwigFunction $function, string $code)
{
$name = $function->getName();
$parser = new Parser($this);
$path = '__twig_function_'.$name.'_'.sha1($code).'.html.twig';
$stream = $this->tokenize(new Source($code, $path, $path));
$output = $this->compile($parser->parse($stream));
 
if (!preg_match('/^\s*echo\s(.*);\s*$/m', $output, $match)) {
throw new RuntimeException('Unable to compile '.$name.' function.');
}
 
return '('.trim($match[1]).')'."\n";
}
 
protected static function getPrivateExtensionProperty(TwigEnvironment $twig, string $extension, string $property)
{
return static::getPrivateProperty($twig->getExtension($extension), $property);
}
}