Deprecated: Symfony\Component\Translation\t(): Implicitly marking parameter $domain as nullable is deprecated, the explicit nullable type must be used instead in /var/www/html/t/taurushr/vendor/symfony/translation/Resources/functions.php on line 18

Deprecated: Symfony\Component\Dotenv\Dotenv::loadEnv(): Implicitly marking parameter $envKey as nullable is deprecated, the explicit nullable type must be used instead in /var/www/html/t/taurushr/vendor/symfony/dotenv/Dotenv.php on line 110

Deprecated: Symfony\Component\Runtime\GenericRuntime::getResolver(): Implicitly marking parameter $reflector as nullable is deprecated, the explicit nullable type must be used instead in /var/www/html/t/taurushr/vendor/symfony/runtime/GenericRuntime.php on line 89

Deprecated: Symfony\Component\Runtime\RuntimeInterface::getResolver(): Implicitly marking parameter $reflector as nullable is deprecated, the explicit nullable type must be used instead in /var/www/html/t/taurushr/vendor/symfony/runtime/RuntimeInterface.php on line 26

Deprecated: Symfony\Component\Console\Input\ArgvInput::__construct(): Implicitly marking parameter $argv as nullable is deprecated, the explicit nullable type must be used instead in /var/www/html/t/taurushr/vendor/symfony/console/Input/ArgvInput.php on line 46

Deprecated: Symfony\Component\Console\Input\ArgvInput::__construct(): Implicitly marking parameter $definition as nullable is deprecated, the explicit nullable type must be used instead in /var/www/html/t/taurushr/vendor/symfony/console/Input/ArgvInput.php on line 46

Deprecated: Symfony\Component\Console\Input\Input::__construct(): Implicitly marking parameter $definition as nullable is deprecated, the explicit nullable type must be used instead in /var/www/html/t/taurushr/vendor/symfony/console/Input/Input.php on line 36

Deprecated: Constant E_STRICT is deprecated in /var/www/html/t/taurushr/vendor/symfony/error-handler/ErrorHandler.php on line 58

Deprecated: Constant E_STRICT is deprecated in /var/www/html/t/taurushr/vendor/symfony/error-handler/ErrorHandler.php on line 76
Symfony Profiler

src/Twig/TwigExtension.php line 164

Open in your IDE?
  1. <?php
  2. namespace App\Twig;
  3. use Twig\TwigFilter;
  4. use Twig\TwigFunction;
  5. use App\Entity\Locales;
  6. use App\Entity\Setting;
  7. use Gregwar\Image\Image;
  8. use App\Entity\HtmlBlocks;
  9. use App\Service\SimpleCache;
  10. use Twig\Extension\AbstractExtension;
  11. use Doctrine\Persistence\ManagerRegistry;
  12. class TwigExtension extends AbstractExtension
  13. {
  14.     private ?\Symfony\Component\DependencyInjection\ContainerInterface $container null;
  15.     public function __construct(private readonly \App\Service\ImageCacheService $imageCacheService, private readonly \Symfony\Component\HttpKernel\KernelInterface $kernel, private readonly \Symfony\Component\Routing\RouterInterface $router, private readonly ManagerRegistry $doctrine, private readonly \Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface $authorizationChecker, private readonly \Symfony\Component\HttpFoundation\RequestStack $requestStack, private readonly \App\Service\ServiceController $serviceController, private readonly SimpleCache $cache, private $projectRoot)
  16.     {
  17.         $this->container $this->kernel->getContainer();
  18.     }
  19.     public function getName()
  20.     {
  21.         return 'twig_extension';
  22.     }
  23.     #[\Override]
  24.     public function getFilters()
  25.     {
  26.         return [
  27.             new TwigFilter('cacheBust', fn ($asset) => $this->cacheBust($asset)),
  28.         ];
  29.     }
  30.     #[\Override]
  31.     public function getFunctions()
  32.     {
  33.         return [
  34.             new TwigFunction('renderPcgcComponents', fn ($positionId$pageComponents) => $this->renderPcgcComponents($positionId$pageComponents)),
  35.             new TwigFunction('removeBracesFromSlug', fn ($string) => $this->removeBracesFromSlug($string)),
  36.             new TwigFunction('generatePath', fn ($request$pageID$parametersArray = []) => $this->generatePath($request$pageID$parametersArray)),
  37.             new TwigFunction('imageCache', fn ($pathtofile$filter$width 0$height 0$background 'transparent') => $this->imageCache($pathtofile$filter$width$height$background)),
  38.             new TwigFunction('fetchLocales', fn () => $this->fetchLocales()),
  39.             new TwigFunction('breadcrumbs', function ($pageEntity null$currentUrl null) {
  40.                 $this->breadcrumbs($pageEntity$currentUrl);
  41.             }),
  42.             new TwigFunction('renderPcgcHtmlBlock', fn ($positionId$pageHtmlblocks) => $this->renderPcgcHtmlBlock($positionId$pageHtmlblocks)),
  43.             new TwigFunction('allowInlineEditor', fn ($entity$field) => $this->allowInlineEditor($entity$field)),
  44.             new TwigFunction('showAdminControlLinks', fn ($entity$route) => $this->showAdminControlLinks($entity$route)),
  45.             new TwigFunction('moneyFormat', fn ($number) => $this->moneyFormat($number)),
  46.             new TwigFunction('domCheckIgnore', fn ($value) => $this->domCheckIgnore($value)),
  47.             new TwigFunction('pcgcComponentEntities', fn ($pageComponents$entityName null$field null) => $this->pcgcComponentEntities($pageComponents$entityName$field)),
  48.             new TwigFunction('pcgcComponentEntity', fn ($pageComponents$field null) => $this->pcgcComponentEntity($pageComponents$field)),
  49.             new TwigFunction('replaceIfComponentDataExists', fn ($pageComponents$field null$fallback null) => $this->replaceIfComponentDataExists($pageComponents$field$fallback)),
  50.             new TwigFunction('forceRenderPcgcHtmlBlock', fn ($identifier) => $this->forceRenderPcgcHtmlBlock($identifier)),
  51.             new TwigFunction('forceRenderPcgcHtmlBlockByIdentifier', fn ($identifier) => $this->forceRenderPcgcHtmlBlockByIdentifier($identifier)),
  52.             new TwigFunction('renderSetting', fn ($id$field) => $this->renderSetting($id$field), ['is_safe' => ['html']]),
  53.         ];
  54.     }
  55.     public function renderSetting($id$field)
  56.     {
  57.         /** @var array $setting */
  58.         $setting $this->doctrine->getRepository(Setting::class)->findActiveSetting($id);
  59.         if (! $setting) {
  60.             return '';
  61.         }
  62.         if (! array_key_exists($field$setting)) {
  63.             return '';
  64.         }
  65.         return nl2br($setting[$field]);
  66.     }
  67.     // fetch field from selected entity from a page component - use if you have multiple components on the same page
  68.     public function pcgcComponentEntities($pageComponents$entityName null$field null)
  69.     {
  70.         $component = [];
  71.         $checkfield substr((string) $field03);
  72.         if ('get' != $checkfield) {
  73.             $field 'get'.ucwords((string) $field);
  74.         }
  75.         if (isset($component['urlKey'])) {
  76.             foreach ($pageComponents as $component) {
  77.                 if (strtolower((string) $component['urlKey']) === strtolower((string) $entityName) && method_exists($component['entity'], $field)) {
  78.                     return call_user_func([$component['entity'], $field]);
  79.                 }
  80.             }
  81.         }
  82.     }
  83.     // fetch field from url component - only if using a url based component
  84.     public function pcgcComponentEntity($pageComponents$field null)
  85.     {
  86.         $checkfield substr((string) $field03);
  87.         if ('get' != $checkfield) {
  88.             $field 'get'.ucwords((string) $field);
  89.         }
  90.         // ADDED AS VAR WAS MISSING _ CW
  91.         $entityName '';
  92.         foreach ($pageComponents as $component) {
  93.             if (isset($component['urlKey']) && strtolower((string) $component['urlKey']) === strtolower($entityName) && method_exists($component['entity'], $field)) {
  94.                 return call_user_func([$component['entity'], $field]);
  95.             }
  96.         }
  97.     }
  98.     // Simlar to the above 'pcgcComponentEntity' function except you can use a fallback string
  99.     // This was intented to be used as an alternative to an if statement
  100.     public function replaceIfComponentDataExists($pageComponents$field null$fallback null)
  101.     {
  102.         $data null;
  103.         $checkfield substr((string) $field03);
  104.         if ('get' != $checkfield) {
  105.             $field 'get'.ucwords((string) $field);
  106.         }
  107.         foreach ($pageComponents as $component) {
  108.             if ((isset($component['urlKey']) && null != $component['urlKey']) && null != $component['data'] && method_exists($component['entity'], $field)) {
  109.                 $data call_user_func([$component['entity'], $field]);
  110.             }
  111.         }
  112.         if (null == $data) {
  113.             return $fallback;
  114.         }
  115.         return $data;
  116.     }
  117.     public function moneyFormat($number)
  118.     {
  119.         return number_format($number2',''.');
  120.     }
  121.     // fix for the domcrawler (which gathers component positions on the add/edit page controller )
  122.     // used to ignore app.request or app.user twig functions - wasn't an issue on my testing machine but did effect TREV
  123.     public function domCheckIgnore($value)
  124.     {
  125.         if (is_array($value)) {
  126.             return null;
  127.         }
  128.         return $value;
  129.     }
  130.     // fetch image or generate new depending on parameter provided - this function may get overriden by the App/Twig/AdminTwigExtension
  131.     public function imageCache($pathtofile$filter$width 0$height 0$background 'transparent')
  132.     {
  133.         echo $this->imageCacheService->imageCache($pathtofile$filter$width$height$background);
  134.     }
  135.     // generate page url which translates to the current locale
  136.     // get all slugs stored in the array cache to generate the path
  137.     // example : <a href="{{generatePath( app.request, 7, {'blog_category': post.category.slug, 'blog_post_slug': post.slug}  )}}">
  138.     public function generatePath($request$pageID$parametersArray = [])
  139.     {
  140.         $locale $request->getLocale();
  141.         $session $request->getSession();
  142.         $localePages $session->get('localePages');
  143.         $not_found = [];
  144.         $slugCache $this->cache->get('slugCache');
  145.         if (null == $slugCache) { // prevents error in page admin ( dom crawer issue with app.request )
  146.             return false;
  147.         }
  148.         foreach (unserialize($slugCache) as $page) {
  149.             if ($page['id'] == $pageID) {
  150.                 $finalUrl $page['slug'];
  151.                 $confirmedPagePieces explode('/', (string) $page['slug']);
  152.                 foreach ($parametersArray as $key => $parameter) {
  153.                     $slugCheck str_replace(' ''', (string) $key);
  154.                     $slugKey array_search('{'.$slugCheck.'}'$confirmedPagePieces);
  155.                     if (!is_numeric($slugKey)) {
  156.                         $not_found[$key] = $parameter;
  157.                     } else {
  158.                         $finalUrl str_replace('{'.$slugCheck.'}'$parameter, (string) $finalUrl);
  159.                     }
  160.                 }
  161.                 $getparams '';
  162.                 if (count($not_found) > 0) {
  163.                     $getparams '?';
  164.                     foreach ($not_found as $extraParam => $extraParamValue) {
  165.                         $getparams .= $extraParam.'='.$extraParamValue.'&';
  166.                     }
  167.                     $getparams rtrim($getparams'&');
  168.                 }
  169.                 return '/'.str_replace('//''/'$finalUrl.$getparams);
  170.             }
  171.         }
  172.         $getparams '';
  173.         if (count($not_found) > 0) {
  174.             $getparams '?path=notfound&';
  175.             foreach ($not_found as $extraParam => $extraParamValue) {
  176.                 $getparams .= $extraParam.'='.$extraParamValue.'&';
  177.             }
  178.             $getparams rtrim($getparams'&');
  179.         }
  180.         return '#'.$getparams;
  181.     }
  182.     // used to tidy page {slugs}
  183.     public function removeBracesFromSlug($string)
  184.     {
  185.         return preg_replace('#{[\s\S]+?}#''', (string) $string);
  186.     }
  187.     // Inserts the relevant component into the page template
  188.     // Also assists the new/edit page component selector (domcrawler picks up on the domcheck attribute)
  189.     public function renderPcgcComponents($positionId$pageComponents)
  190.     {
  191.         if ($pageComponents) {
  192.             if ('domcheck' == $pageComponents[0]['position']) {
  193.                 echo "<div data-pcgc='domcheck'>".$positionId.'</div>';
  194.             }
  195.             foreach ($pageComponents as $component) {
  196.                 if ($component['position'] == $positionId && array_key_exists('data'$component)) {
  197.                     return $component['data'];
  198.                 }
  199.             }
  200.         }
  201.     }
  202.     // Inserts the relevant htmlblock into the page template
  203.     // Also assists the new/edit page component selector (domcrawler picks up on the domcheck attribute)
  204.     public function renderPcgcHtmlBlock($positionId$pageHtmlblocks)
  205.     {
  206.         if ($pageHtmlblocks) {
  207.             if ('domcheck' == $pageHtmlblocks[0]['position']) {
  208.                 echo "<div data-pcgc='domcheckhtml'>".$positionId.'</div>';
  209.             }
  210.             foreach ($pageHtmlblocks as $block) {
  211.                 if ($block['position'] == $positionId && array_key_exists('data'$block)) {
  212.                     if ($this->authorizationChecker->isGranted('ROLE_PAGE_EDITOR')) {
  213.                         return $this->getInlineEditorHTML(HtmlBlocks::class, 'html'$block['data'], $block['blockId'], 'HtmlBlock');
  214.                     }
  215.                     return $block['data'];
  216.                 }
  217.             }
  218.         }
  219.     }
  220.     // Inserts the relevant htmlblock into the page template
  221.     // This function is not used tied to the CMS - renders same block on every page
  222.     public function forceRenderPcgcHtmlBlock($identifier)
  223.     {
  224.         if ($identifier) {
  225.             $block $this->doctrine->getRepository(HtmlBlocks::class)->findOneBy(['title' => $identifier'deleted' => false'active' => true]);
  226.             if (null !== $block) {
  227.                 if ($this->authorizationChecker->isGranted('ROLE_PAGE_EDITOR')) {
  228.                     return $this->getInlineEditorHTML(HtmlBlocks::class, 'html'$block->getHtml(), $block->getId(), 'HtmlBlock');
  229.                 }
  230.                 return $block->getHtml();
  231.             }
  232.         }
  233.     }
  234.         // Inserts the relevant htmlblock into the page template
  235.     // This function is not used tied to the CMS - renders same block on every page
  236.     public function forceRenderPcgcHtmlBlockByIdentifier($identifier)
  237.     {
  238.         if ($identifier) {
  239.             $block $this->doctrine->getRepository(HtmlBlocks::class)->findOneBy(['id' => $identifier'deleted' => false'active' => true]);
  240.             if (null !== $block) {
  241.                 if ($this->authorizationChecker->isGranted('ROLE_PAGE_EDITOR')) {
  242.                     return $this->getInlineEditorHTML(HtmlBlocks::class, 'html'$block->getHtml(), $block->getId(), 'HtmlBlock');
  243.                 }
  244.                 return $block->getHtml();
  245.             }
  246.         }
  247.     }
  248.     public function allowInlineEditor($entity$field)
  249.     {
  250.         $namespaceMeta $this->serviceController->getBundleNameFromEntity($entity$field);
  251.         $getterMethod 'get'.ucwords((string) $field);
  252.         $editText $entity->{$getterMethod}();
  253.         if ('' == $editText) {
  254.             return null;
  255.         }
  256.         $request $this->requestStack->getCurrentRequest();
  257.         // $request = $this->container->get('request');
  258.         if ($request->query->has('preview')) {
  259.             return $editText;
  260.         }
  261.         if ($this->authorizationChecker->isGranted('ROLE_PAGE_EDITOR')) {
  262.             return $this->getInlineEditorHTML($namespaceMeta['full'], $field$editText$entity->getId(), $namespaceMeta['short'], $namespaceMeta['fieldmeta']);
  263.         }
  264.         return $editText;
  265.     }
  266.     public function showAdminControlLinks($entity$route)
  267.     {
  268.         $namespaceMeta $this->serviceController->getBundleNameFromEntity($entity);
  269.         $url $this->router->generate($route, ['id' => $entity->getId()]);
  270.         if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
  271.             $buttons "<div class='adminControlButtons'>";
  272.             $buttons .= "    <div class='inlineEditorToolboxContainer'>Admin Control (".$namespaceMeta['short'].')</div>';
  273.             $buttons .= "    <div class='inlineEditorToolboxLink'><a href='".$url."' data-toggle='tooltip' title='View/Edit' ><span class='glyphicon glyphicon-pencil'></span>&nbsp;View/Edit</a></div>";
  274.             $buttons .= '</div>';
  275.             return $buttons;
  276.         }
  277.     }
  278.     public function getInlineEditorHTML($namespace$field$content$id$entityname null$fieldmeta null)
  279.     {
  280.         // show inline editor
  281.         $request $this->requestStack->getCurrentRequest();
  282.         $isPreview $this->requestStack->getMainRequest()->query->getBoolean('preview');
  283.         if ($isPreview) {
  284.             return $content;
  285.         }
  286.         $locale $request->getLocale();
  287.         $showFullEditor 1;
  288.         if (null != $fieldmeta && 'string' == $fieldmeta['type']) {
  289.             $showFullEditor 0;
  290.         }
  291.         // Redactor required uniqueIDs - classes conflicted if multiple editors were used
  292.         $uniqueID substr(md5(random_int(19999)), 07);
  293.         $editor "<div class='inlineEditorContainer'>";
  294.         $editor .= "    <div id='inlineEditor-message-".$uniqueID."' class='inlineEditorToolboxContainer'>Editable (".$entityname.':'.$field.')</div>';
  295.         $editor .= "    <div class='inlineEditorToolboxSave'><a data-toggle='tooltip' title='Save Text' id='btn-save-".$uniqueID."' style='display:none'><span class='glyphicon glyphicon-floppy-disk'></span>&nbsp;Save</a></div>";
  296.         // $editor .= "    <div class='inlineEditorToolboxClose'><a data-toggle='tooltip' title='Close Editor' id='btn-cancel-".$uniqueID."' style='display:none'><span class='glyphicon glyphicon-remove-sign'></span></a></div>";
  297.         $editor .= "    <div class='inlineEditor' data-fulleditor='".$showFullEditor."' id='".$uniqueID."' data-entitynamespace='".$namespace."'  data-entityfield='".$field."' data-id='".$id."' data-locale='".$locale."' >";
  298.         if (== $showFullEditor) {
  299.             $editor .= '<p>';
  300.         }
  301.         $editor .= $content;
  302.         if (== $showFullEditor) {
  303.             $editor .= '</p>';
  304.         }
  305.         $editor .= '    </div>';
  306.         // if($showFullEditor ==1){
  307.         //     $editor .= "    <textarea class='inlineEditor' data-fulleditor='".$showFullEditor."' id='".$uniqueID."' data-entitynamespace='".$namespace."'  data-entityfield='".$field."' data-id='".$id."' data-locale='".$locale."' >";
  308.         //     $editor .= $content;
  309.         //     $editor .= "    </textarea>";
  310.         // }else{
  311.         //     $editor .= "    <input type='text' class='inlineEditor' data-fulleditor='".$showFullEditor."' value='".$content."' id='".$uniqueID."' data-entitynamespace='".$namespace."'  data-entityfield='".$field."' data-id='".$id."' data-locale='".$locale."' />";
  312.         // }
  313.         $editor .= '</div>';
  314.         return $editor;
  315.     }
  316.     // simple function to fetch all locales
  317.     // done this way to ensure locale switch buttons work on non cms pages
  318.     public function fetchLocales()
  319.     {
  320.         return $this->doctrine->getRepository(Locales::class)->findBy(['active' => true]);
  321.     }
  322.     public function breadcrumbs($pageEntity null$currentUrl null)
  323.     {
  324.         // // this function generates a full url category path
  325.         // $currentUrl = $this->container->get('request')->getUri();
  326.         if (null != $pageEntity && null != $currentUrl) {
  327.             $exploded explode('/', (string) $currentUrl);
  328.             unset($exploded[0]);
  329.             $exploded array_values($exploded);
  330.             $structure = [];
  331.             $explodedCount count($exploded);
  332.             for ($i 0$i $explodedCount; ++$i) {
  333.                 if (array_key_exists($i 1$structure)) {
  334.                     $structure[$i] = $structure[$i 1]['url'].'/'.$exploded[$i];
  335.                 } else {
  336.                     $structure[$i] = '/'.$exploded[$i];
  337.                 }
  338.                 $url array_key_exists($i 1$structure) ? $structure[$i 1]['url'].'/'.$exploded[$i] : '/'.$exploded[$i];
  339.                 $structure[$i] = ['url' => $url'title' => $exploded[$i]];
  340.             }
  341.             // print_r($structure);
  342.             $seperater ' / ';
  343.             $html '<div class="breadcrumb">';
  344.             $html .= '<span><a href="/"><i class="fa-regular fa-house-blank"></i><span class="sr-only">Home</span></a></span>' .$seperater;
  345.             $count 0;
  346.             foreach ($structure as $item) {
  347.                 ++$count;
  348.                 if (count($structure) == $count) {
  349.                     $seperater '';
  350.                 }
  351.                 $html .= '<span><a href="'.$item['url'].'">'.str_replace('-'' 'ucfirst($item['title'])).'</a></span>' .$seperater;
  352.             }
  353.             $html .= '</div>';
  354.             echo $html;
  355.         }
  356.     }
  357.     // simple function to pluralise text string (adds 's' if array count >1 )
  358.     public function pluralize($text$array$plural_version null)
  359.     {
  360.         return (is_countable($array) ? count($array) : 0) > ? ($plural_version ?: $text.'s') : $text;
  361.     }
  362.     // simple word limiter function
  363.     public function wordLimiter($str$limit 30)
  364.     {
  365.         $words explode(' 'strip_tags((string) $str));
  366.         if ($words $limit) {
  367.             return implode(' 'array_splice($words0$limit)).'...';
  368.         }
  369.         return $str;
  370.     }
  371.     /**
  372.      * Cache bust specified asset.
  373.      */
  374.     public function cacheBust(mixed $asset)
  375.     {
  376.         $asset '/'.ltrim((string) $asset'/');
  377.         $assetPath sprintf('%s/../public/%s'$this->projectRoot$asset);
  378.         // If we are assuming a CSS or JS file exists when it doesn't,
  379.         // we probably need to know about it.
  380.         if (!file_exists($assetPath)) {
  381.             throw new \RuntimeException(sprintf('Asset: %s is missing!'$asset));
  382.         }
  383.         $modified filemtime($assetPath);
  384.         return $asset.sprintf('?version=%d'$modified);
  385.     }
  386. }