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
<?php
namespace App\Twig ;
use Twig\TwigFilter ;
use Twig\TwigFunction ;
use App\Entity\Locales ;
use App\Entity\Setting ;
use Gregwar\Image\Image ;
use App\Entity\HtmlBlocks ;
use App\Service\SimpleCache ;
use Twig\Extension\AbstractExtension ;
use Doctrine\Persistence\ManagerRegistry ;
class TwigExtension extends AbstractExtension
{
private ?\Symfony\Component\DependencyInjection\ContainerInterface $container = null ;
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 )
{
$this -> container = $this -> kernel -> getContainer ();
}
public function getName ()
{
return 'twig_extension' ;
}
#[\Override ]
public function getFilters ()
{
return [
new TwigFilter ( 'cacheBust' , fn ( $asset ) => $this -> cacheBust ( $asset )),
];
}
#[\Override ]
public function getFunctions ()
{
return [
new TwigFunction ( 'renderPcgcComponents' , fn ( $positionId , $pageComponents ) => $this -> renderPcgcComponents ( $positionId , $pageComponents )),
new TwigFunction ( 'removeBracesFromSlug' , fn ( $string ) => $this -> removeBracesFromSlug ( $string )),
new TwigFunction ( 'generatePath' , fn ( $request , $pageID , $parametersArray = []) => $this -> generatePath ( $request , $pageID , $parametersArray )),
new TwigFunction ( 'imageCache' , fn ( $pathtofile , $filter , $width = 0 , $height = 0 , $background = 'transparent' ) => $this -> imageCache ( $pathtofile , $filter , $width , $height , $background )),
new TwigFunction ( 'fetchLocales' , fn () => $this -> fetchLocales ()),
new TwigFunction ( 'breadcrumbs' , function ( $pageEntity = null , $currentUrl = null ) {
$this -> breadcrumbs ( $pageEntity , $currentUrl );
}),
new TwigFunction ( 'renderPcgcHtmlBlock' , fn ( $positionId , $pageHtmlblocks ) => $this -> renderPcgcHtmlBlock ( $positionId , $pageHtmlblocks )),
new TwigFunction ( 'allowInlineEditor' , fn ( $entity , $field ) => $this -> allowInlineEditor ( $entity , $field )),
new TwigFunction ( 'showAdminControlLinks' , fn ( $entity , $route ) => $this -> showAdminControlLinks ( $entity , $route )),
new TwigFunction ( 'moneyFormat' , fn ( $number ) => $this -> moneyFormat ( $number )),
new TwigFunction ( 'domCheckIgnore' , fn ( $value ) => $this -> domCheckIgnore ( $value )),
new TwigFunction ( 'pcgcComponentEntities' , fn ( $pageComponents , $entityName = null , $field = null ) => $this -> pcgcComponentEntities ( $pageComponents , $entityName , $field )),
new TwigFunction ( 'pcgcComponentEntity' , fn ( $pageComponents , $field = null ) => $this -> pcgcComponentEntity ( $pageComponents , $field )),
new TwigFunction ( 'replaceIfComponentDataExists' , fn ( $pageComponents , $field = null , $fallback = null ) => $this -> replaceIfComponentDataExists ( $pageComponents , $field , $fallback )),
new TwigFunction ( 'forceRenderPcgcHtmlBlock' , fn ( $identifier ) => $this -> forceRenderPcgcHtmlBlock ( $identifier )),
new TwigFunction ( 'forceRenderPcgcHtmlBlockByIdentifier' , fn ( $identifier ) => $this -> forceRenderPcgcHtmlBlockByIdentifier ( $identifier )),
new TwigFunction ( 'renderSetting' , fn ( $id , $field ) => $this -> renderSetting ( $id , $field ), [ 'is_safe' => [ 'html' ]]),
];
}
public function renderSetting ( $id , $field )
{
/** @var array $setting */
$setting = $this -> doctrine -> getRepository ( Setting ::class)-> findActiveSetting ( $id );
if (! $setting ) {
return '' ;
}
if (! array_key_exists ( $field , $setting )) {
return '' ;
}
return nl2br ( $setting [ $field ]);
}
// fetch field from selected entity from a page component - use if you have multiple components on the same page
public function pcgcComponentEntities ( $pageComponents , $entityName = null , $field = null )
{
$component = [];
$checkfield = substr ((string) $field , 0 , 3 );
if ('get' != $checkfield ) {
$field = 'get' . ucwords ((string) $field );
}
if (isset($component [ 'urlKey' ])) {
foreach ($pageComponents as $component ) {
if (strtolower ((string) $component [ 'urlKey' ]) === strtolower ((string) $entityName ) && method_exists ( $component [ 'entity' ], $field )) {
return call_user_func ([ $component [ 'entity' ], $field ]);
}
}
}
}
// fetch field from url component - only if using a url based component
public function pcgcComponentEntity ( $pageComponents , $field = null )
{
$checkfield = substr ((string) $field , 0 , 3 );
if ('get' != $checkfield ) {
$field = 'get' . ucwords ((string) $field );
}
// ADDED AS VAR WAS MISSING _ CW
$entityName = '' ;
foreach ($pageComponents as $component ) {
if (isset($component [ 'urlKey' ]) && strtolower ((string) $component [ 'urlKey' ]) === strtolower ( $entityName ) && method_exists ( $component [ 'entity' ], $field )) {
return call_user_func ([ $component [ 'entity' ], $field ]);
}
}
}
// Simlar to the above 'pcgcComponentEntity' function except you can use a fallback string
// This was intented to be used as an alternative to an if statement
public function replaceIfComponentDataExists ( $pageComponents , $field = null , $fallback = null )
{
$data = null ;
$checkfield = substr ((string) $field , 0 , 3 );
if ('get' != $checkfield ) {
$field = 'get' . ucwords ((string) $field );
}
foreach ($pageComponents as $component ) {
if ((isset($component [ 'urlKey' ]) && null != $component [ 'urlKey' ]) && null != $component [ 'data' ] && method_exists ( $component [ 'entity' ], $field )) {
$data = call_user_func ([ $component [ 'entity' ], $field ]);
}
}
if (null == $data ) {
return $fallback ;
}
return $data ;
}
public function moneyFormat ( $number )
{
return number_format ( $number , 2 , ',' , '.' );
}
// fix for the domcrawler (which gathers component positions on the add/edit page controller )
// used to ignore app.request or app.user twig functions - wasn't an issue on my testing machine but did effect TREV
public function domCheckIgnore ( $value )
{
if (is_array ( $value )) {
return null ;
}
return $value ;
}
// fetch image or generate new depending on parameter provided - this function may get overriden by the App/Twig/AdminTwigExtension
public function imageCache ( $pathtofile , $filter , $width = 0 , $height = 0 , $background = 'transparent' )
{
echo $this -> imageCacheService -> imageCache ( $pathtofile , $filter , $width , $height , $background );
}
// generate page url which translates to the current locale
// get all slugs stored in the array cache to generate the path
// example : <a href="{{generatePath( app.request, 7, {'blog_category': post.category.slug, 'blog_post_slug': post.slug} )}}">
public function generatePath ( $request , $pageID , $parametersArray = [])
{
$locale = $request -> getLocale ();
$session = $request -> getSession ();
$localePages = $session -> get ( 'localePages' );
$not_found = [];
$slugCache = $this -> cache -> get ( 'slugCache' );
if (null == $slugCache ) { // prevents error in page admin ( dom crawer issue with app.request )
return false ;
}
foreach (unserialize ( $slugCache ) as $page ) {
if ($page [ 'id' ] == $pageID ) {
$finalUrl = $page [ 'slug' ];
$confirmedPagePieces = explode ( '/' , (string) $page [ 'slug' ]);
foreach ($parametersArray as $key => $parameter ) {
$slugCheck = str_replace ( ' ' , '' , (string) $key );
$slugKey = array_search ( '{' . $slugCheck . '}' , $confirmedPagePieces );
if (!is_numeric ( $slugKey )) {
$not_found [ $key ] = $parameter ;
} else {
$finalUrl = str_replace ( '{' . $slugCheck . '}' , $parameter , (string) $finalUrl );
}
}
$getparams = '' ;
if (count ( $not_found ) > 0 ) {
$getparams = '?' ;
foreach ($not_found as $extraParam => $extraParamValue ) {
$getparams .= $extraParam . '=' . $extraParamValue . '&' ;
}
$getparams = rtrim ( $getparams , '&' );
}
return '/' . str_replace ( '//' , '/' , $finalUrl . $getparams );
}
}
$getparams = '' ;
if (count ( $not_found ) > 0 ) {
$getparams = '?path=notfound&' ;
foreach ($not_found as $extraParam => $extraParamValue ) {
$getparams .= $extraParam . '=' . $extraParamValue . '&' ;
}
$getparams = rtrim ( $getparams , '&' );
}
return '#' . $getparams ;
}
// used to tidy page {slugs}
public function removeBracesFromSlug ( $string )
{
return preg_replace ( '#{[\s\S]+?}#' , '' , (string) $string );
}
// Inserts the relevant component into the page template
// Also assists the new/edit page component selector (domcrawler picks up on the domcheck attribute)
public function renderPcgcComponents ( $positionId , $pageComponents )
{
if ($pageComponents ) {
if ('domcheck' == $pageComponents [ 0 ][ 'position' ]) {
echo "<div data-pcgc='domcheck'>" . $positionId . '</div>' ;
}
foreach ($pageComponents as $component ) {
if ($component [ 'position' ] == $positionId && array_key_exists ( 'data' , $component )) {
return $component [ 'data' ];
}
}
}
}
// Inserts the relevant htmlblock into the page template
// Also assists the new/edit page component selector (domcrawler picks up on the domcheck attribute)
public function renderPcgcHtmlBlock ( $positionId , $pageHtmlblocks )
{
if ($pageHtmlblocks ) {
if ('domcheck' == $pageHtmlblocks [ 0 ][ 'position' ]) {
echo "<div data-pcgc='domcheckhtml'>" . $positionId . '</div>' ;
}
foreach ($pageHtmlblocks as $block ) {
if ($block [ 'position' ] == $positionId && array_key_exists ( 'data' , $block )) {
if ($this -> authorizationChecker -> isGranted ( 'ROLE_PAGE_EDITOR' )) {
return $this -> getInlineEditorHTML ( HtmlBlocks ::class, 'html' , $block [ 'data' ], $block [ 'blockId' ], 'HtmlBlock' );
}
return $block [ 'data' ];
}
}
}
}
// Inserts the relevant htmlblock into the page template
// This function is not used tied to the CMS - renders same block on every page
public function forceRenderPcgcHtmlBlock ( $identifier )
{
if ($identifier ) {
$block = $this -> doctrine -> getRepository ( HtmlBlocks ::class)-> findOneBy ([ 'title' => $identifier , 'deleted' => false , 'active' => true ]);
if (null !== $block ) {
if ($this -> authorizationChecker -> isGranted ( 'ROLE_PAGE_EDITOR' )) {
return $this -> getInlineEditorHTML ( HtmlBlocks ::class, 'html' , $block -> getHtml (), $block -> getId (), 'HtmlBlock' );
}
return $block -> getHtml ();
}
}
}
// Inserts the relevant htmlblock into the page template
// This function is not used tied to the CMS - renders same block on every page
public function forceRenderPcgcHtmlBlockByIdentifier ( $identifier )
{
if ($identifier ) {
$block = $this -> doctrine -> getRepository ( HtmlBlocks ::class)-> findOneBy ([ 'id' => $identifier , 'deleted' => false , 'active' => true ]);
if (null !== $block ) {
if ($this -> authorizationChecker -> isGranted ( 'ROLE_PAGE_EDITOR' )) {
return $this -> getInlineEditorHTML ( HtmlBlocks ::class, 'html' , $block -> getHtml (), $block -> getId (), 'HtmlBlock' );
}
return $block -> getHtml ();
}
}
}
public function allowInlineEditor ( $entity , $field )
{
$namespaceMeta = $this -> serviceController -> getBundleNameFromEntity ( $entity , $field );
$getterMethod = 'get' . ucwords ((string) $field );
$editText = $entity ->{ $getterMethod }();
if ('' == $editText ) {
return null ;
}
$request = $this -> requestStack -> getCurrentRequest ();
// $request = $this->container->get('request');
if ( $request -> query -> has ( 'preview' )) {
return $editText ;
}
if ($this -> authorizationChecker -> isGranted ( 'ROLE_PAGE_EDITOR' )) {
return $this -> getInlineEditorHTML ( $namespaceMeta [ 'full' ], $field , $editText , $entity -> getId (), $namespaceMeta [ 'short' ], $namespaceMeta [ 'fieldmeta' ]);
}
return $editText ;
}
public function showAdminControlLinks ( $entity , $route )
{
$namespaceMeta = $this -> serviceController -> getBundleNameFromEntity ( $entity );
$url = $this -> router -> generate ( $route , [ 'id' => $entity -> getId ()]);
if ($this -> authorizationChecker -> isGranted ( 'ROLE_ADMIN' )) {
$buttons = "<div class='adminControlButtons'>" ;
$buttons .= " <div class='inlineEditorToolboxContainer'>Admin Control (" . $namespaceMeta [ 'short' ]. ')</div>' ;
$buttons .= " <div class='inlineEditorToolboxLink'><a href='" . $url . "' data-toggle='tooltip' title='View/Edit' ><span class='glyphicon glyphicon-pencil'></span> View/Edit</a></div>" ;
$buttons .= '</div>' ;
return $buttons ;
}
}
public function getInlineEditorHTML ( $namespace , $field , $content , $id , $entityname = null , $fieldmeta = null )
{
// show inline editor
$request = $this -> requestStack -> getCurrentRequest ();
$isPreview = $this -> requestStack -> getMainRequest ()-> query -> getBoolean ( 'preview' );
if ($isPreview ) {
return $content ;
}
$locale = $request -> getLocale ();
$showFullEditor = 1 ;
if (null != $fieldmeta && 'string' == $fieldmeta [ 'type' ]) {
$showFullEditor = 0 ;
}
// Redactor required uniqueIDs - classes conflicted if multiple editors were used
$uniqueID = substr ( md5 ( random_int ( 1 , 9999 )), 0 , 7 );
$editor = "<div class='inlineEditorContainer'>" ;
$editor .= " <div id='inlineEditor-message-" . $uniqueID . "' class='inlineEditorToolboxContainer'>Editable (" . $entityname . ':' . $field . ')</div>' ;
$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> Save</a></div>" ;
// $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>";
$editor .= " <div class='inlineEditor' data-fulleditor='" . $showFullEditor . "' id='" . $uniqueID . "' data-entitynamespace='" . $namespace . "' data-entityfield='" . $field . "' data-id='" . $id . "' data-locale='" . $locale . "' >" ;
if (0 == $showFullEditor ) {
$editor .= '<p>' ;
}
$editor .= $content ;
if (0 == $showFullEditor ) {
$editor .= '</p>' ;
}
$editor .= ' </div>' ;
// if($showFullEditor ==1){
// $editor .= " <textarea class='inlineEditor' data-fulleditor='".$showFullEditor."' id='".$uniqueID."' data-entitynamespace='".$namespace."' data-entityfield='".$field."' data-id='".$id."' data-locale='".$locale."' >";
// $editor .= $content;
// $editor .= " </textarea>";
// }else{
// $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."' />";
// }
$editor .= '</div>' ;
return $editor ;
}
// simple function to fetch all locales
// done this way to ensure locale switch buttons work on non cms pages
public function fetchLocales ()
{
return $this -> doctrine -> getRepository ( Locales ::class)-> findBy ([ 'active' => true ]);
}
public function breadcrumbs ( $pageEntity = null , $currentUrl = null )
{
// // this function generates a full url category path
// $currentUrl = $this->container->get('request')->getUri();
if ( null != $pageEntity && null != $currentUrl ) {
$exploded = explode ( '/' , (string) $currentUrl );
unset($exploded [ 0 ]);
$exploded = array_values ( $exploded );
$structure = [];
$explodedCount = count ( $exploded );
for ($i = 0 ; $i < $explodedCount ; ++ $i ) {
if (array_key_exists ( $i - 1 , $structure )) {
$structure [ $i ] = $structure [ $i - 1 ][ 'url' ]. '/' . $exploded [ $i ];
} else {
$structure [ $i ] = '/' . $exploded [ $i ];
}
$url = array_key_exists ( $i - 1 , $structure ) ? $structure [ $i - 1 ][ 'url' ]. '/' . $exploded [ $i ] : '/' . $exploded [ $i ];
$structure [ $i ] = [ 'url' => $url , 'title' => $exploded [ $i ]];
}
// print_r($structure);
$seperater = ' / ' ;
$html = '<div class="breadcrumb">' ;
$html .= '<span><a href="/"><i class="fa-regular fa-house-blank"></i><span class="sr-only">Home</span></a></span>' . $seperater ;
$count = 0 ;
foreach ($structure as $item ) {
++$count ;
if (count ( $structure ) == $count ) {
$seperater = '' ;
}
$html .= '<span><a href="' . $item [ 'url' ]. '">' . str_replace ( '-' , ' ' , ucfirst ( $item [ 'title' ])). '</a></span>' . $seperater ;
}
$html .= '</div>' ;
echo $html ;
}
}
// simple function to pluralise text string (adds 's' if array count >1 )
public function pluralize ( $text , $array , $plural_version = null )
{
return (is_countable ( $array ) ? count ( $array ) : 0 ) > 1 ? ( $plural_version ?: $text . 's' ) : $text ;
}
// simple word limiter function
public function wordLimiter ( $str , $limit = 30 )
{
$words = explode ( ' ' , strip_tags ((string) $str ));
if ($words > $limit ) {
return implode ( ' ' , array_splice ( $words , 0 , $limit )). '...' ;
}
return $str ;
}
/**
* Cache bust specified asset.
*/
public function cacheBust ( mixed $asset )
{
$asset = '/' . ltrim ((string) $asset , '/' );
$assetPath = sprintf ( '%s/../public/%s' , $this -> projectRoot , $asset );
// If we are assuming a CSS or JS file exists when it doesn't,
// we probably need to know about it.
if (! file_exists ( $assetPath )) {
throw new \RuntimeException ( sprintf ( 'Asset: %s is missing!' , $asset ));
}
$modified = filemtime ( $assetPath );
return $asset . sprintf ( '?version=%d' , $modified );
}
}