uawdijnntqw1x1x1
IP : 216.73.216.8
Hostname : toronto-dev2
Kernel : Linux toronto-dev2 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023 x86_64
Disable Function : None :)
OS : Linux
PATH:
/
srv
/
users
/
craft4
/
apps
/
craft4-newsite-space
/
vendor
/
verbb
/
base
/
..
/
base
/
src
/
.
/
services
/
Templates.php
/
/
<?php namespace verbb\base\services; use verbb\base\twig\SecurityPolicy; use Craft; use craft\base\Component; use craft\helpers\Json; use craft\web\twig\Environment; use craft\web\twig\Extension; use craft\web\twig\GlobalsExtension; use Twig\Error\LoaderError; use Twig\Error\SyntaxError; use Twig\Extension\SandboxExtension; use Twig\Extension\StringLoaderExtension; use Twig\Loader\FilesystemLoader; use Twig\Parser; use yii\base\Arrayable; use yii\base\Model; use yii\log\Logger; use Exception; use ReflectionClass; use Throwable; use nystudio107\closure\helpers\Reflection as ReflectionHelper; use nystudio107\closure\twig\ClosureExpressionParser; class Templates extends Component { // Properties // ========================================================================= public string $pluginClass; public array $allowedTags = []; public array $allowedFilters = []; public array $allowedFunctions = []; public array $allowedMethods = []; public array $allowedProperties = []; private Environment $_twigEnv; private array $_objectTemplates = []; // Public Methods // ========================================================================= public function init(): void { $view = Craft::$app->getView(); $tags = $this->allowedTags ?: $this->_getTags(); $filters = $this->allowedFilters ?: $this->_getFilters(); $functions = $this->allowedFunctions ?: $this->_getFunctions(); $methods = $this->allowedMethods ?: $this->_getMethods(); $properties = $this->allowedProperties ?: $this->_getProperties(); $policy = new SecurityPolicy($tags, $filters, $methods, $properties, $functions); $loader = new FilesystemLoader(); $sandbox = new SandboxExtension($policy, true); $this->_twigEnv = new Environment($loader); $this->_twigEnv->addExtension($sandbox); // Load in Craft's own Twig extensions $this->_twigEnv->addExtension(new StringLoaderExtension()); $this->_twigEnv->addExtension(new Extension($view, $this->_twigEnv)); $this->_twigEnv->addExtension(new GlobalsExtension()); // Access any plugin-defined extensions (via a private property) $reflection = new ReflectionClass($view); $pluginExtensions = []; // Handle Craft 4.13.0+ if ($reflection->hasProperty('_siteTwigExtensions')) { $property = $reflection->getProperty('_siteTwigExtensions'); $property->setAccessible(true); $pluginExtensions = $property->getValue($view); } else if ($reflection->hasProperty('_twigExtensions')) { $property = $reflection->getProperty('_twigExtensions'); $property->setAccessible(true); $pluginExtensions = $property->getValue($view); } foreach ($pluginExtensions as $pluginExtension) { $this->_twigEnv->addExtension($pluginExtension); } // Some plugins like Closure (https://github.com/nystudio107/craft-closure) don't register things in the traditional way if (class_exists(ClosureExpressionParser::class)) { try { $parserReflection = ReflectionHelper::getReflectionProperty($this->_twigEnv, 'parser'); $parserReflection->setAccessible(true); $parser = $parserReflection->getValue($this->_twigEnv); if ($parser === null) { $parser = new Parser($this->_twigEnv); $parserReflection->setValue($this->_twigEnv, $parser); } $expressionParserReflection = ReflectionHelper::getReflectionProperty($parser, 'expressionParser'); $expressionParserReflection->setAccessible(true); $expressionParser = new ClosureExpressionParser($parser, $this->_twigEnv); $expressionParserReflection->setValue($parser, $expressionParser); } catch (Throwable $e) { $this->pluginClass::error(Craft::t('app', 'Error parsing template: “{message}” {file}:{line}', [ 'message' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), ])); } } } public function getTwig(): Environment { return $this->_twigEnv; } public function renderObjectTemplate(string $template, mixed $object, array $variables = []): string { $originalTemplate = $template; // If there are no dynamic tags, just return the template if (!str_contains($template, '{')) { return trim($template); } $twig = $this->getTwig(); try { // Is this the first time we've parsed this template? $cacheKey = md5($template); if (!isset($this->_objectTemplates[$cacheKey])) { // Replace shortcut "{var}"s with "{{object.var}}"s, without affecting normal Twig tags $template = Craft::$app->getView()->normalizeObjectTemplate($template); $this->_objectTemplates[$cacheKey] = $twig->createTemplate($template); } // Get the variables to pass to the template if ($object instanceof Model) { foreach ($object->attributes() as $name) { if (!isset($variables[$name]) && str_contains($template, $name)) { $variables[$name] = $object->$name; } } } if ($object instanceof Arrayable) { // See if we should be including any of the extra fields $extra = []; foreach ($object->extraFields() as $field => $definition) { if (is_int($field)) { $field = $definition; } if (preg_match('/\b' . preg_quote($field, '/') . '\b/', $template)) { $extra[] = $field; } } $variables += $object->toArray([], $extra, false); } $variables['object'] = $object; $variables['_variables'] = $variables; // Render it! /** @var TwigTemplate $templateObj */ $templateObj = $this->_objectTemplates[$cacheKey]; return trim($templateObj->render($variables)); } catch (Throwable $e) { $this->pluginClass::error(Craft::t('app', 'Error parsing template: “{template}”: “{message}” {file}:{line}', [ 'template' => $originalTemplate, 'message' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), ])); } return ''; } public function renderString(string $template, array $variables = []): string { // If there are no dynamic tags, just return the template if (!str_contains($template, '{')) { return $template; } $twig = $this->getTwig(); try { return $twig->createTemplate($template)->render($variables); } catch (Throwable $e) { $this->pluginClass::error(Craft::t('app', 'Error parsing template: “{template}”: “{message}” {file}:{line}', [ 'template' => $template, 'message' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), ])); } return ''; } // Public Methods // ========================================================================= private function _getTags(): array { return [ // 'apply', // 'autoescape', // 'block', // 'deprecated', // 'do', // 'embed', // 'extends', // 'flush', 'for', // 'from', 'if', // 'import', // 'include', // 'macro', // 'sandbox', 'set', // 'use', // 'verbatim', // 'with', // Craft-specific // cache // css // dd // dump // exit // header // hook // html // js // namespace // nav // paginate // redirect // requireAdmin // requireEdition // requireGuest // requireLogin // requirePermission // script // switch // tag ]; } private function _getFilters(): array { return [ // 'abs', // 'batch', 'capitalize', // 'column', // 'convert_encoding', // 'country_name', // 'country_timezones', // 'currency_name', // 'currency_symbol', // 'data_uri', 'date', // 'date_modify', // 'default', 'escape', // 'filter', 'first', // 'format', // 'format_currency', // 'format_date', // 'format_datetime', // 'format_number', // 'format_time', // 'inky', // 'inline_css', 'join', // 'json_encode', 'keys', // 'language_name', 'last', 'length', // 'locale_name', 'lower', // 'map', 'markdown', // 'merge', 'nl2br', 'number_format', 'raw', // 'reduce', 'replace', // 'reverse', // 'round', // 'slice', 'sort', // 'spaceless', 'split', 'striptags', // 'timezone_name', 'title', 'trim', 'upper', // 'url_encode', // Craft-specific // address // append // ascii // atom // attr // base64_decode // base64_encode // boolean 'camel', // column 'contains', 'currency', 'date', 'datetime', // diff // duration // encenc // explodeClass // explodeStyle // filesize // filter // float // group // hash // httpdate 'id', 'index', 'indexOf', // integer // intersect // json_encode // json_decode 'kebab', 'lcfirst', 'length', // literal 'markdown', 'md', 'merge', 'money', // multisort // namespace or ns // namespaceAttributes // namespaceInputId // namespaceInputName // number // parseAttr // parseRefs 'pascal', 'percentage', // prepend 'purify', // push // removeClass // rss 'snake', // string 'time', 'timestamp', 'translate', 't', // truncate 'ucfirst', // unique // unshift 'ucwords', // values // where // widont // without // withoutKey ]; } private function _getFunctions(): array { return [ // 'attribute', // 'block', // 'constant', // 'cycle', 'date', // 'dump', // 'html_classes', 'include', 'max', 'min', // 'parent', 'random', 'range', // 'source', // 'template_from_string', // Craft-specific // actionInput 'actionUrl', // alias 'attr', // beginBody // block // canCreateDrafts // canDelete // canDeleteForSite // canDuplicate // canSave // canView // ceil // className // clone 'collect', // combine // configure // constant 'cpUrl', // create // csrfInput 'dataUrl', // dump // endBody // expression // failMessageInput // floor // getenv // gql // head // hiddenInput // input // ol // parseBooleanEnv // parseEnv // plugin 'raw', // redirectInput // renderObjectTemplate // 'seq' // 'shuffle' 'siteUrl', // source // successMessageInput 'svg', 'tag', // ul 'url', ]; } private function _getMethods(): array { return []; } private function _getProperties(): array { return []; } }
/srv/users/craft4/apps/craft4-newsite-space/vendor/verbb/base/../base/src/./services/Templates.php