<?php
namespace App\Controller;
use App\Service\ServiceController;
use JsonException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class PageDefaultController extends Controller
{
private $invalidSetters = [
'setCreatedAt',
'setUpdatedAt',
'setTranslatableLocale'
];
private \App\Service\ServiceController $serviceController;
public function __construct(ServiceController $serviceController)
{
$this->serviceController = $serviceController;
}
/**
* @Route("/members/dash", name="members_dash")
*/
public function membersDashAction()
{
return $this->render('@theme/members/members-dash.html.twig');
}
/**
* @Route("/special-user/dash", name="special_user_dash")
*/
public function specialUserDashAction()
{
return $this->render('@theme/security/special-dash.html.twig');
}
public function generateAndModifyMetaDataTags($page, $componentEnity)
{
//print_r(get_class_methods($componentEnity));
$possibleMetaTitles = ['getHeadline', 'getHeading', 'getTitle', 'getName', 'getMetaTitle'];
$possibleMetaDescription = ['getContent', 'getDescription', 'getExcerpt', 'getMetaDescription'];
// fallbacks
if ('' == $page->getMetatitle()) {
$page->setMetatitle($page->getTitle());
}
if ('' == $page->getMetadescription()) {
$page->setMetadescription($page->getContent());
}
$metaDataArray = [];
foreach ($possibleMetaTitles as $metaTitle) {
if (method_exists($componentEnity, $metaTitle)) {
$data = call_user_func([$componentEnity, $metaTitle]);
if ('' != $data) {
$metaDataArray['title'] = call_user_func([$componentEnity, $metaTitle]);
}
}
}
foreach ($possibleMetaDescription as $metaDescription) {
if (method_exists($componentEnity, $metaDescription)) {
$data = call_user_func([$componentEnity, $metaDescription]);
if ('' != $data) {
$metaDataArray['description'] = $data;
}
}
}
if (array_key_exists('title', $metaDataArray)) {
$page->setMetatitle($metaDataArray['title'].' | '.$page->getMetatitle());
}
if (array_key_exists('description', $metaDataArray)) {
$page->setMetadescription(strip_tags($metaDataArray['description']));
}
return $page;
}
public function routeToControllerName($routename)
{
$routes = $this->get('router')->getRouteCollection();
return $routes->get($routename)->getDefaults();
}
public function findPageSlugParameters($slug)
{
$matches = [];
$regex = '/{(\w*)}/';
preg_match_all($regex, $slug, $matches);
return $matches[1];
}
public function pageChecks($page)
{
if (0 == $page->isActive()) {
return false;
}
return new \DateTime() >= $page->getViewableFrom();
}
/**
* @Route("/switch-locale/{_locale}", name="switch_locale")
*
* @param mixed $_locale
*/
public function switchLocale(Request $request, $_locale)
{
return $this->redirect('/');
// return $this->redirect($request->headers->get('referer'));
}
/**
* // @Route("/{_locale}", name="home", defaults={"slug": "home"}))
* // @Route("/{_locale}/{slug}", name="change_locale", requirements={"slug": ".+"}).
*/
// public function changeLocale(Request $request, $_locale, $slug){
// $pageData = $this->routeMatcher($request, $slug);
// return $pageData;
// }
/**
* @Route("/page.php", name="page_php_home")
*/
public function getMethodRouterAction(Request $request)
{
$params = $request->query->all();
$debug = $request->query->has('_debug');
$session = $request->getSession();
$em = $this->getDoctrine()->getManager();
$cmsComponentArray = $this->serviceController->fetchCmsComponents();
// Using doctrine cache to store dynamic page slugs
// Used in twig function generatePath (converts id to slug) and assists links with translations
$slugCache = $em->getRepository('App:Page')->findAllByLocale($request->getLocale());
$cacheDriver = $this->container->get('doctrine_cache.providers.arraycache');
$cacheDriver->save('slugCache', $slugCache);
if ($request->query->has('_locale')) {
$this->debug($debug, '<p>CHANGING LOCALE</p>');
if ($request->getLocale() != $request->query->get('_locale')) {
$session->set('_locale', $request->query->get('_locale'));
$request->setLocale($session->get('_locale', $request->query->get('_locale')));
return $this->redirect($this->generateUrl($request->get('_route'), $request->query->all()));
}
}
$structureEntities = [];
$pageID = $request->query->get('page');
if (!is_numeric($pageID)) {
throw $this->createNotFoundException('PCGC - No PageID passed');
}
$pageEntity = $em->getRepository('App:Page')->find($pageID);
if (null === $pageEntity) {
throw $this->createNotFoundException('PCGC - No Page found for id#'.$pageID);
}
$pageSlugArray = explode('/', $pageEntity->getSlug());
$fullSegmentOrder = [];
if (count($pageSlugArray) > 1) {
$pageSlugArrayCount = count($pageSlugArray);
for ($i = 0; $i < ($pageSlugArrayCount + 1); ++$i) {
if (array_key_exists($i, $pageSlugArray) && substr_count($pageSlugArray[$i], '{') > 0) {
$fullSegmentOrder[] = $pageSlugArray[$i];
unset($pageSlugArray[$i]);
}
}
}
$this->debug($debug, '<p>'.$pageEntity->getSlug().'</p>');
if (substr_count($pageEntity->getSlug(), '{') > 0) {
foreach ($params as $key => $id) {
$key = strtolower($key);
if (('_locale' != $key) || ('page' != $key) || ('_debug' != $key)) {
$comkey = $this->searchArrayKeyVal('slugEntity', $key, $cmsComponentArray);
$this->debug($debug, "<p>Searching for '".$key."' against slugEntity in cmsComponentArray</p>");
if (is_numeric($comkey)) {
$order = array_search($cmsComponentArray[$comkey]['slug'], $fullSegmentOrder);
$this->debug($debug, '<p>'.$order.' - '.$cmsComponentArray[$comkey]['slugEntity'].'</p>');
$bundle = str_replace('\\', '', $cmsComponentArray[$comkey]['bundle']).':'.$cmsComponentArray[$comkey]['slugEntity'];
$structureEntities[$order] = $em->getRepository($bundle)->find($id);
}
}
}
}
$slugfixer = implode('/', $pageSlugArray);
$slug = $slugfixer;
ksort($structureEntities);
foreach ($structureEntities as $urlelement) {
$slug .= '/'.$urlelement->getSlug();
}
if ($debug) {
$this->debug($debug, '<p>Path re-built to <strong>'.$slug.'</strong></p>');
$pageData = $this->routeMatcherV2($request, ltrim($slug, '/'));
if (is_array($pageData)) {
$pageAllowed = $this->pageChecks($pageData['page']);
if (false == $pageAllowed) {
throw $this->createNotFoundException('PCGC: Page view checks for PageID# "'.$pageData['page']->getId().'" has failed (disabled, before viewdate ect...) - so showing 404');
}
// HTML Blocks
$htmlblocks = [];
$assignedHtmlblocks = $pageData['page']->getHtmlblocks();
if ((is_countable($assignedHtmlblocks) ? count($assignedHtmlblocks) : 0) > 0) {
$allHtmlBlocks = $em->getRepository('App:HtmlBlocks')->findBy(['deleted' => false]);
foreach ($assignedHtmlblocks as $assignedblock) {
foreach ($allHtmlBlocks as $allHtmlBlock) {
if ($assignedblock['blockId'] == $allHtmlBlock->getId()) {
$htmlblocks[] = [
'blockId' => $allHtmlBlock->getId(),
'position' => $assignedblock['position'],
'data' => $allHtmlBlock->getHtml(),
];
}
}
}
}
$pageMeta = $pageData['page'];
// replace metatitle if empty
if ('' == $pageData['page']->getMetatitle()) {
$pageMeta->setMetatitle($pageData['page']->getTitle());
}
// replace metatitles if exist on components
foreach ($pageData['pageComponents'] as $pageComp) {
$pageMeta = $this->generateAndModifyMetaDataTags($pageData['page'], $pageComp['entity']);
}
return $this->render('@theme/templates/'.$pageData['page']->getTemplate()->getTemplateFile(), [
'page' => $pageMeta,
'slug' => $pageData['slug'],
'pageComponents' => $pageData['pageComponents'],
'pageHtmlBlocks' => $htmlblocks,
'longUrl' => strtolower(implode('/', $params)),
]);
} // this will be a redirect
return $pageData;
}
return $this->redirect(str_replace('//', '/', $slug));
}
/**
* @Route("/page-preview", name="page_preview_home")
*/
public function getPreviewMethodRouterAction(Request $request)
{
$params = $request->query->all();
$session = $request->getSession();
$em = $this->getDoctrine()->getManager();
$cmsComponentArray = $this->serviceController->fetchCmsComponents();
// Using doctrine cache to store dynamic page slugs
// Used in twig function generatePath (converts id to slug) and assists links with translations
$slugCache = $em->getRepository('App:Page')->findAllByLocale($request->getLocale());
$cacheDriver = $this->container->get('doctrine_cache.providers.arraycache');
$cacheDriver->save('slugCache', $slugCache);
if ($request->query->has('_locale') && $request->getLocale() != $request->query->get('_locale')) {
$session->set('_locale', $request->query->get('_locale'));
$request->setLocale($session->get('_locale', $request->query->get('_locale')));
return $this->redirect($this->generateUrl($request->get('_route'), $request->query->all()));
}
$structureEntities = [];
$pageID = $request->query->get('id');
if (!is_numeric($pageID)) {
throw $this->createNotFoundException('PCGC - No PageID passed');
}
$pageEntity = $em->getRepository('App:Page')->find($pageID);
if (null === $pageEntity) {
throw $this->createNotFoundException('PCGC - No Page found for id#'.$pageID);
}
if ($request->query->has('preview')) {
$previewId = $request->query->get('preview');
$previewEntity = $em->getRepository('App:PagePreview')->find($previewId);
if (null === $previewEntity) {
throw $this->createNotFoundException('PCGC - No PagePreview found for id#'.$previewId);
}
if ($previewEntity->getPage()->getId() != $pageEntity->getId()) {
throw $this->createNotFoundException('PCGC - PagePreview->pageID#'.$previewEntity->getPage()->getId().' does not match PageID#'.$pageID);
}
// get nessacary getters (dup content)
$validSetters = $this->getSetters($previewEntity, $pageEntity);
foreach ($validSetters as $validSetter) {
if (in_array($validSetter, $this->invalidSetters)) {
continue;
}
$validGetter = str_replace('set', 'get', $validSetter);
$pageEntity->{$validSetter}($previewEntity->{$validGetter}());
}
}
$pageSlugArray = explode('/', $pageEntity->getSlug());
$fullSegmentOrder = [];
if (count($pageSlugArray) > 1) {
$pageSlugArrayCount = count($pageSlugArray);
for ($i = 0; $i < ($pageSlugArrayCount + 1); ++$i) {
if (array_key_exists($i, $pageSlugArray) && substr_count($pageSlugArray[$i], '{') > 0) {
$fullSegmentOrder[] = $pageSlugArray[$i];
unset($pageSlugArray[$i]);
}
}
}
if (substr_count($pageEntity->getSlug(), '{') > 0) {
foreach ($params as $key => $id) {
$key = strtolower($key);
if (('_locale' != $key) || ('page' != $key) || ('_debug' != $key)) {
$comkey = $this->searchArrayKeyVal('slugEntity', $key, $cmsComponentArray);
if (is_numeric($comkey)) {
$order = array_search($cmsComponentArray[$comkey]['slug'], $fullSegmentOrder);
$bundle = str_replace('\\', '', $cmsComponentArray[$comkey]['bundle']).':'.$cmsComponentArray[$comkey]['slugEntity'];
$structureEntities[$order] = $em->getRepository($bundle)->find($id);
}
}
}
}
$slugfixer = implode('/', $pageSlugArray);
$slug = $slugfixer;
ksort($structureEntities);
foreach ($structureEntities as $urlelement) {
$slug .= '/'.$urlelement->getSlug();
}
$pageData = $this->routeMatcherV2($request, ltrim($slug, '/'));
$pageData['page'] = $pageEntity;
if (is_array($pageData)) {
$pageAllowed = $this->pageChecks($pageData['page']);
if (false == $pageAllowed) {
throw $this->createNotFoundException('PCGC: Page view checks for PageID# "'.$pageData['page']->getId().'" has failed (disabled, before viewdate ect...) - so showing 404');
}
// HTML Blocks
$htmlblocks = [];
$assignedHtmlblocks = $pageData['page']->getHtmlblocks();
if ((is_countable($assignedHtmlblocks) ? count($assignedHtmlblocks) : 0) > 0) {
$allHtmlBlocks = $em->getRepository('App:HtmlBlocks')->findBy(['deleted' => false]);
foreach ($assignedHtmlblocks as $assignedblock) {
foreach ($allHtmlBlocks as $allHtmlBlock) {
if ($assignedblock['blockId'] == $allHtmlBlock->getId()) {
$htmlblocks[] = [
'blockId' => $allHtmlBlock->getId(),
'position' => $assignedblock['position'],
'data' => $allHtmlBlock->getHtml(),
];
}
}
}
}
$pageMeta = $pageData['page'];
// replace metatitle if empty
if ('' == $pageData['page']->getMetatitle()) {
$pageMeta->setMetatitle($pageData['page']->getTitle());
}
// replace metatitles if exist on components
foreach ($pageData['pageComponents'] as $pageComp) {
$pageMeta = $this->generateAndModifyMetaDataTags($pageData['page'], $pageComp['entity']);
}
return $this->render('@theme/templates/'.$pageData['page']->getTemplate()->getTemplateFile(), [
'page' => $pageMeta,
'slug' => $pageData['slug'],
'pageComponents' => $pageData['pageComponents'],
'pageHtmlBlocks' => $htmlblocks,
'longUrl' => strtolower(implode('/', $params)),
'preview' => true,
]);
} // this will be a redirect
return $pageData;
return new Response('EOF');
}
public function routeMatcherV2($request, $slug)
{
$multilingual = $this->container->getParameter('multilingual');
$locale = $request->getLocale();
$cmsComponentArray = $this->serviceController->fetchCmsComponents();
$pcgcComponents = [];
$em = $this->getDoctrine()->getManager();
$debug = (bool) $request->query->has('_debug');
$this->debug($debug, '<p>ROUTER DEBUG<br/>This will show you feedback during the route match process</p>');
$this->debug($debug, '<br/>Current Locale ['.$request->getLocale().']');
$this->debug($debug, '<br/>Looking for: <strong>'.$slug.'</strong>');
//////////////////////////
// SIMPLE MATCHES
//////////////////////////
// simple direct match
// this will match the home page in any locale and any default 'en' page
$page = $em->getRepository('App:Page')->findOneBy(['slug' => $slug, 'deleted' => false, 'active' => true]);
if (null !== $page) {
$pageComponents = $this->getComponentData($debug, $cmsComponentArray, $page->getComponents(), $request, $page->getId());
$this->debug($debug, "<br/><span style='color:green' >(STEP1) Found - ".$page->getTitle().' (ID#'.$page->getId().')<br/>Will render page out of debug mode</span>');
return [
'page' => $page,
'slug' => $slug,
'pageComponents' => $pageComponents,
];
}
// simple direct match for SELECTED TRANSLATION
// this route will match translations - locales matched after query
$pageAll = $em->getRepository('App:Page')->findAll();
foreach ($pageAll as $page) {
if ($page->getSlug() == $slug) {
if (false == $request->query->has('preview') && ($page->isDeleted() || !$page->isActive())) {
throw $this->createNotFoundException('PCGC: Page Route for "'.$slug.'" has been deactived or deleted');
}
$pageComponents = $this->getComponentData($debug, $cmsComponentArray, $page->getComponents(), $request, $page->getId());
$this->debug($debug, "<br/><span style='color:green' >(STEP2- transaltion) Found - ".$page->getTitle().' (ID#'.$page->getId().')<br/>Will render page out of debug mode</span>');
return [
'page' => $page,
'slug' => $slug,
'pageComponents' => $pageComponents,
];
}
}
$this->debug($debug, '<p>No direct matches found - looking for complex matches (has a url component was used?)<br/>Checking All Pages:</p>');
// if no direct matches found ( usually means a url component was used )
//////////////////////////
// COMPLEX MATCHES
//////////////////////////
$urlSegments = explode('/', $slug);
/////////////////////////////////////////
// this is for debug reasons only ( logic repeated after this loop )
if ($debug) {
$this->debug($debug, '<pre>');
$this->debug($debug, '<p><strong>COMPLEX ROUTE MATCHING</strong></p>');
foreach ($pageAll as $page) {
$pageSlugParametersArray = $this->findPageSlugParameters($page->getSlug());
$possiblePageSegments = explode('/', $page->getSlug());
$slugMatches = array_intersect($urlSegments, $possiblePageSegments);
$count = 0;
$this->debug($debug, 'Looking for: <strong>'.$slug.'</strong><br/>');
$this->debug($debug, 'Looking at : <strong>'.$page->getSlug().'</strong> - ID#'.$page->getId().'<br/>');
if (count($possiblePageSegments) === count($urlSegments)) {
$this->debug($debug, "<span style='color:green; font-weight:bold' >Passed phase 1</span>");
++$count;
}
$this->debug($debug, ' - '.count($possiblePageSegments).'/'.count($urlSegments).' URL Segment Count');
if ((is_countable($pageSlugParametersArray) ? count($pageSlugParametersArray) : 0) > 0) {
++$count;
$this->debug($debug, "<br/><span style='color:green; font-weight:bold' >Passed phase 2</span> - ".(is_countable($pageSlugParametersArray) ? count($pageSlugParametersArray) : 0).' URL Parameter Components');
} else {
$this->debug($debug, '<br/>No URL components on this page');
}
if (count($slugMatches) > 0) {
++$count;
$this->debug($debug, "<br/><span style='color:green; font-weight:bold' >Passed phase 3</span> - ".count($slugMatches).' URL slug matches');
} else {
$this->debug($debug, '<br/>No URL slug matches on this page');
}
if ((is_countable($pageSlugParametersArray) ? count($pageSlugParametersArray) : 0) + count($slugMatches) == count($urlSegments)) {
++$count;
$this->debug($debug, "<br/><span style='color:green; font-weight:bold' >Passed phase 4</span> - slugParameters + slugMatches = urlSegments");
} else {
$this->debug($debug, '<br/>slugParameters + slugMatches dont add up to '.count($urlSegments));
}
if (4 == $count) {
$this->debug($debug, "<br/><span style='color:green; font-weight:bold' >SUCCESS!! - full match</span>");
$confirmedDebugPage = $page;
$this->debug($debug, "<br/><span style='color:green' >(STEP3- complex) Found - ".$confirmedDebugPage->getTitle().' (ID#'.$confirmedDebugPage->getId().')<br/>Will render page out of debug mode</span>');
} else {
$this->debug($debug, '<br/>Not this page');
}
$this->debug($debug, '<p>-----------------------------------</p>');
}// end of pages loop
if (!$confirmedDebugPage) {
$this->debug($debug, '<br/>Doh! - Route Not Matched ');
}
$this->debug($debug, '</pre>');
}// end of debug
///////////////////////////////////////
foreach ($pageAll as $page) {
$pageSlugParametersArray = $this->findPageSlugParameters($page->getSlug());
$possiblePageSegments = explode('/', $page->getSlug());
$slugMatches = array_intersect($urlSegments, $possiblePageSegments);
$count = 0;
if (count($possiblePageSegments) === count($urlSegments)) {
++$count;
}
if ((is_countable($pageSlugParametersArray) ? count($pageSlugParametersArray) : 0) > 0) {
++$count;
}
if (count($slugMatches) > 0) {
++$count;
}
if ((is_countable($pageSlugParametersArray) ? count($pageSlugParametersArray) : 0) + count($slugMatches) == count($urlSegments)) {
++$count;
}
// Passed all 4 checks
if (4 == $count) {
$confirmedPage = $page;
}
}// end of pages loop
if (isset($confirmedPage)) {
$this->debug($debug, '<p>Calling renderPageWithURLComponents</p>');
return $this->renderPageWithURLComponents($request, $confirmedPage, $slug, $cmsComponentArray);
}
$this->debug($debug, '<p><strong>STILL NO MATCH</strong> - START CHECKING TRANSLATIONS - with seperate indervidual url segments</p>');
// exit;
////////////////////////////
// Lacale auto switcher
////////////////////////////
// if page still not found check translations then change locale to match
// Note: for the switcher to work you have to refresh the page
if ($multilingual) {
$repository = $em->getRepository(\Gedmo\Translatable\Entity\Translation::class);
foreach ($pageAll as $page) {
$translations = $repository->findTranslations($page);
foreach ($translations as $locale => $fields) {
foreach ($urlSegments as $segment) {
$transSlug = explode('/', $fields['slug']);
foreach ($transSlug as $transSlugSegment) {
$this->debug($debug, '<br/>['.$locale.']'.$segment.':'.$transSlugSegment);
if ($segment === $transSlugSegment) {
$this->debug($debug, ' <strong> - Match ***</strong>');
$diffrentLanguagesWithSameSlug[$locale] = 0;
$setLocale = $locale;
//wasnt sure which was the correct method - keeps changing!
$request->getSession()->set('_locale', $setLocale);
$request->setLocale($setLocale);
if ($debug) {
$this->debug($debug, '<p><strong>*** REFRESHING PAGE IN ['.$setLocale.'] - autoswitching ***</strong></p>');
} elseif ($request->query->has('_locale')) {
$this->debug($debug, '<br/>Already Redirected - preventing loop');
} else {
return $this->redirect('/'.$slug.'?_locale='.$setLocale);
}
}
}
}
}
}
// check if en from different locale
foreach ($pageAll as $page) {
$page->setTranslatableLocale('en');
$em->refresh($page);
foreach ($urlSegments as $segment) {
$locale = 'en';
$transSlug = explode('/', $page->getSlug());
foreach ($transSlug as $transSlugSegment) {
$this->debug($debug, '<br/>['.$locale.']'.$segment.':'.$transSlugSegment);
if ($segment === $transSlugSegment) {
$this->debug($debug, ' <strong> - Match ***</strong>');
$diffrentLanguagesWithSameSlug[$locale] = 0;
$setLocale = $locale;
// wasnt sure which was the correct method - keeps changing!
$request->getSession()->set('_locale', $setLocale);
$request->setLocale($setLocale);
if ($debug) {
$this->debug($debug, '<p><strong>*** REFRESHING PAGE IN ['.$setLocale.'] - autoswitching ***</strong></p>');
} elseif ($request->query->has('_locale')) {
$this->debug($debug, '<br/>Already Redirected - preventing loop');
} else {
return $this->redirect('/'.$slug.'?_locale='.$setLocale);
}
}
}
}
}
} // end if($multilingual)
// return new Response('<p>End - showing 404 page</p>');
throw $this->createNotFoundException('PCGC - Route not matched: showing 404 page');
}
public function renderPageWithURLComponents($request, $confirmedPage, $slug, $cmsComponentArray)
{
$em = $this->getDoctrine()->getManager();
$debug = (bool) $request->query->has('_debug');
$this->debug($debug, '<br/>looking for components:<br/>');
$pageSlugParametersArray = $this->findPageSlugParameters($confirmedPage->getSlug());
if ($debug) {
$this->debug($debug, 'Current URL components to match<br/>');
print_r($pageSlugParametersArray);
$this->debug($debug, '<p>If more than one URL component then the last one will be checked by default ('.(is_countable($pageSlugParametersArray) ? count($pageSlugParametersArray) : 0).' Found)</p>');
}
// extra check
$slugPieces = explode('/', $slug);
$confirmedPagePieces = explode('/', $confirmedPage->getSlug());
foreach ($cmsComponentArray as $cmsComponent) {
if ('' != $cmsComponent['slug']) {
$slugCheck = str_replace(' ', '', $cmsComponent['slug']);
$this->debug($debug, '<br/>Lookin at: '.$slugCheck);
if ($slugCheck == '{'.end($pageSlugParametersArray).'}') {
if ($debug) {
$this->debug($debug, ' - Matched<br/>');
print_r($cmsComponent);
}
$slugKey = array_search('{'.end($pageSlugParametersArray).'}', $confirmedPagePieces);
if (!is_numeric($slugKey)) {
$this->debug($debug, '<p>Oh No! -Key not found for "{'.end($pageSlugParametersArray).'}" in '.$confirmedPage->getSlug().'</p>');
} else {
$this->debug($debug, "<p>Using the slug '".$slugPieces[$slugKey]."' on ".stripslashes($cmsComponent['bundle']).':'.$cmsComponent['slugEntity'].' </p>');
}
$component_find_slug = $slugPieces[$slugKey];
$pageComponents = $this->getComponentData($debug, $cmsComponentArray, $confirmedPage->getComponents(), $request, $confirmedPage->getId(), $component_find_slug, $slugPieces, $pageSlugParametersArray);
return [
'page' => $confirmedPage,
'slug' => $slug,
'pageComponents' => $pageComponents,
];
}
}
}
}
public function getComponentData($debug, $cmsComponentArray, $pageComponents, $request, $confirmedPageId, $component_find_slug = null, $slugPieces = [], $pageSlugParametersArray = [])
{
if ($debug) {
$this->debug($debug, '<pre>');
$this->debug($debug, '<strong>AVAILABLE COMPONENTS:</strong><br/>');
$this->debug($debug, "<table cellpadding='10' width='100%'>");
$this->debug($debug, "<tr style='border-bottom:1px solid #666; font-size:12px'><th>Name</th><th>Slug</th><th>SlugEntity</th><th>Route</th><th>Type</th><th>Bundle</th><tr>");
foreach ($cmsComponentArray as $com) {
$this->debug($debug, "<tr style='border-top:1px dashed #666; font-size:12px'>");
$this->debug($debug, "<td style='white-space:nowrap; padding-top:5px; padding-bottom:5px'>".$com['name'].'</td>');
$this->debug($debug, "<td style='white-space:nowrap'>".$com['slug'].'</td>');
$this->debug($debug, "<td style='white-space:nowrap'>".$com['slugEntity'].'</td>');
$this->debug($debug, "<td style='white-space:nowrap'>".$com['route'].'</td>');
$this->debug($debug, "<td style='white-space:nowrap'>".$com['componentType'].'</td>');
$this->debug($debug, "<td style='white-space:nowrap'>".$com['bundle'].'</td>');
$this->debug($debug, '<tr>');
}
$this->debug($debug, '</table>');
$this->debug($debug, '</pre>');
$this->debug($debug, '<pre>');
$this->debug($debug, '<strong>ACTIVE PAGE COMPONENTS:</strong><br/>');
$this->debug($debug, "<table cellpadding='10' width='100%'>");
$this->debug($debug, "<tr style='border-bottom:1px solid #666; font-size:12px'><th>Position</th><th>Route</th><tr>");
foreach ($pageComponents as $com) {
$this->debug($debug, "<tr style='border-top:1px dashed #666; font-size:12px'>");
$this->debug($debug, "<td style='white-space:nowrap; padding-top:5px; padding-bottom:5px'>".$com['position'].'</td>');
$this->debug($debug, "<td style='white-space:nowrap'>".$com['route'].'</td>');
}
$this->debug($debug, '</table>');
$this->debug($debug, '</pre>');
}
$pageComponentsReturn = [];
// Find out which URL segments are dynamic by removing
// preceeding segments (parent and page)
$totalSlug = is_countable($slugPieces) ? count($slugPieces) : 0;
$totalPara = is_countable($pageSlugParametersArray) ? count($pageSlugParametersArray) : 0;
$diff = $totalSlug - $totalPara;
for ($i = 0; $i < $diff; ++$i) {
unset($slugPieces[$i]);
}
$slugPieces = array_values($slugPieces);
$this->debug($debug, '<pre>');
$this->debug($debug, '<p><strong>COMPONENT LINKING</strong></p>');
// Workout extra segments - these will have no route
// and componentType = 'segment'
$extraUrlSegments = $pageSlugParametersArray;
if ((is_countable($pageSlugParametersArray) ? count($pageSlugParametersArray) : 0) > 1) {
unset($extraUrlSegments[(is_countable($extraUrlSegments) ? count($extraUrlSegments) : 0) - 1], $slugPieces[count($slugPieces) - 1]);
$extraUrlSegments = array_values($extraUrlSegments);
$slugPieces = array_values($slugPieces);
$this->debug($debug, '<p>SEGMENT ONLY ('.count($extraUrlSegments).' found)</p>');
// $this->debug($debug, "<br/>The next 2 array keys and values should match up");
// $this->debug($debug, "<br/>".print_r($extraUrlSegments, true));
// $this->debug($debug, "<br/>".print_r($slugPieces, true));
foreach ($extraUrlSegments as $index => $segment) {
$comkey = $this->searchArrayKeyVal('slug', '{'.$segment.'}', $cmsComponentArray);
if (is_numeric($comkey)) {
$entity = $this->getEntityData(['component' => $cmsComponentArray[$comkey], 'slug' => $slugPieces[$index]], $request, $debug);
$entityId = $entity->getId();
if ($entityId) {
$pageComponentsReturn[] = [
'position' => null,
'urlKey' => $cmsComponentArray[$comkey]['slugEntity'],
'urlValue' => $entityId,
'data' => null,
'entity' => $entity,
];
}
} else {
$this->debug($debug, "<p>Dynamic Slug '".$slugPieces[$index]."' for URL Annotation '".$segment."' NOT FOUND - but can continue, you should check your routes/link</p>");
}
}
}
// Check all page components
$comCount = 0;
foreach ($pageComponents as $pageComponent) {
if (null != $pageComponent['route']) {
++$comCount;
$this->debug($debug, '<p>------------------------------</p>');
$this->debug($debug, '<p>COMPONENT '.$comCount.'</p>');
// found pagecomponent
$comkey = $this->searchArrayKeyVal('route', $pageComponent['route'], $cmsComponentArray);
if (!is_numeric($comkey)) {
$this->debug($debug, '<p>The component <strong>'.$pageComponent['route'].'</strong> not found - has it been deleted?</p>');
$pageComponentsReturn[] = [
'position' => $pageComponent['position'],
'urlKey' => null,
'urlValue' => null,
'data' => '',
'entity' => null,
];
} else {
$this->debug($debug, '<p>Comkey (#'.$comkey.') found for = '.$pageComponent['route']);
$action = $this->routeToControllerName($cmsComponentArray[$comkey]['route']);
$this->debug($debug, '<br/>Controller = '.$cmsComponentArray[$comkey]['route'].'</p>');
// Non-URL reliant (slugless) component
if (null == $cmsComponentArray[$comkey]['slug']) {
$this->debug($debug, '<p>SLUGLESS:<br/>RENDERING CONTROLLER into = <strong>'.$action['_controller'].'</strong></p>');
// fetch component data
$response = $this->forward($action['_controller'], ['request' => $request, 'pageId' => $confirmedPageId]);
$pageComponentsReturn[] = [
'position' => $pageComponent['position'],
'urlKey' => null,
'urlValue' => null,
'data' => $response->getContent(),
'entity' => null,
];
} else {
// URL Component found
$removal = ['{', '}']; //used for str_replace
$controllerSlug = str_replace($removal, '', $cmsComponentArray[$comkey]['slug']);
// Get entityID for getMethodRouterAction - used to assist with locale/translation switching
$entity = $this->getEntityData(['component' => $cmsComponentArray[$comkey], 'slug' => $component_find_slug], $request, $debug);
$entityId = $entity->getId();
// fetch component data
$this->debug($debug, '<p>SLUG REQUIRED:<br/>RENDERING CONTROLLER = <strong>'.$action['_controller'].'</strong></p>');
$response = $this->forward($action['_controller'], ['request' => $request, 'pageId' => $confirmedPageId, $controllerSlug => $component_find_slug]);
$pageComponentsReturn[] = [
'position' => $pageComponent['position'],
'urlKey' => $cmsComponentArray[$comkey]['slugEntity'],
'urlValue' => $entityId,
'data' => $response->getContent(),
'entity' => $entity,
];
}
} // end if(!is_numeric($comkey)
}
}
$this->debug($debug, '</pre>');
return $pageComponentsReturn;
}
public function getEntityData($data, $request, $debug)
{
$em = $this->getDoctrine()->getManager();
$locale = $request->getLocale();
$queryEntity = str_replace('\\', '', $data['component']['bundle'].':'.$data['component']['slugEntity']);
$queryEntity = str_replace('/', '', $queryEntity);
$this->debug($debug, '<p>ENTITY QUERY - '.$queryEntity);
if ('en' != $locale) {
$entity = $em->getRepository($queryEntity)->findSlugWithLocale($data['slug'], $locale);
$this->debug($debug, '->findSlugWithLocale(<strong>'.$data['slug'].'</strong>, <strong>'.$locale.'</strong>)');
} else {
$entity = $em->getRepository($queryEntity)->findOneBySlug($data['slug']);
$this->debug($debug, '->findOneBySlug(<strong>'.$data['slug'].'</strong>)');
}
if ($entity) {
$this->debug($debug, '<br/>RESULT: EntityId =<strong>'.$entity->getId().'</strong></p>');
return $entity;
}
return false;
}
public function searchArrayKeyVal($sKey, $id, $array)
{
foreach ($array as $key => $val) {
if ($val[$sKey] == $id) {
return $key;
}
}
foreach ($array as $key => $val) {
if (strtolower($val[$sKey]) === strtolower($id)) {
return $key;
}
}
return false;
}
public function isJson($string)
{
try {
json_decode($string, false, 512, JSON_THROW_ON_ERROR);
return true;
} catch (JsonException $jsonException) {
return false;
}
}
// function to compare entities and returns common setters
public function getSetters($entity, $entity2)
{
$classMethods = get_class_methods($entity);
$classMethods2 = get_class_methods($entity2);
$settersArray = [];
foreach ($classMethods as $classMethod) {
if ('set' == substr($classMethod, 0, 3)) {
foreach ($classMethods2 as $classMethod2) {
if ('set' == substr($classMethod2, 0, 3) && $classMethod == $classMethod2) {
$settersArray[] = $classMethod2;
}
}
}
}
return $settersArray;
}
// THIS ROUTE MUST BE THE VERY LAST ROUTE LOADED
/**
* @Route("/", name="home", defaults={"slug": "home"}))
* @Route("/{slug}", name="router", requirements={"slug": ".+"})
*
* @param mixed $slug
*/
public function routerAction(Request $request, $slug)
{
$session = $request->getSession();
$em = $this->getDoctrine()->getManager();
$slugCache = $em->getRepository('App:Page')->findAllByLocale($request->getLocale());
$cacheDriver = $this->container->get('doctrine_cache.providers.arraycache');
$cacheDriver->save('slugCache', $slugCache);
$debug = $request->query->has('_debug');
$this->debug($debug, 'Current Locale -'.$request->getLocale().' | request Locale -'.$request->query->get('_locale'));
if ($request->query->has('_locale')) {
$this->debug($debug, '<p>CHANGING LOCALE</p>');
if ($request->getLocale() != $request->query->get('_locale')) {
$session->set('_locale', $request->query->get('_locale'));
$request->setLocale($session->get('_locale', $request->query->get('_locale')));
return $this->redirect('/'.$slug);
}
}
$pageData = $this->routeMatcherV2($request, $slug);
// REDIRECT CHECKER
$this->debug($debug, 'Checking for redirects...');
foreach ($pageData['pageComponents'] as $pageComponent) {
$redirectCheck = $pageComponent['data'];
if ($this->isJson($redirectCheck)) {
$decoded = json_decode($redirectCheck, false, 512, JSON_THROW_ON_ERROR);
if (property_exists($decoded, 'componentRedirect') && null !== $decoded->componentRedirect) {
$this->debug($debug, 'Redirect found ... will goto '.$decoded->componentRedirect);
if (!$debug) {
return $this->redirect($decoded->componentRedirect);
}
}
}
}
if (is_array($pageData)) {
$longUrl = 'page.php?Page='.$pageData['page']->getId();
if (array_key_exists('pageComponents', $pageData) && null != $pageData['pageComponents']) {
foreach ($pageData['pageComponents'] as $component) {
if (array_key_exists('urlKey', $component) && null != $component['urlKey']) {
$longUrl .= '&'.$component['urlKey'].'='.$component['urlValue'];
}
}
}
$pageAllowed = $this->pageChecks($pageData['page']);
if (false == $pageAllowed) {
throw $this->createNotFoundException('PCGC: Page Checks for pageId "'.$pageData['page']->getId().'" has failed (disabled, before viewdate ect...) - showing 404');
}
// HTML Blocks
$htmlblocks = [];
$assignedHtmlblocks = $pageData['page']->getHtmlblocks();
if ((is_countable($assignedHtmlblocks) ? count($assignedHtmlblocks) : 0) > 0) {
$allHtmlBlocks = $em->getRepository('App:HtmlBlocks')->findBy(['deleted' => false]);
foreach ($assignedHtmlblocks as $assignedblock) {
foreach ($allHtmlBlocks as $allHtmlBlock) {
if ($assignedblock['blockId'] == $allHtmlBlock->getId()) {
$htmlblocks[] = [
'blockId' => $allHtmlBlock->getId(),
'position' => $assignedblock['position'],
'data' => $allHtmlBlock->getHtml(),
];
}
}
}
}
$pageMeta = $pageData['page'];
// replace metatitle if empty
if ('' == $pageData['page']->getMetatitle()) {
$pageMeta->setMetatitle($pageData['page']->getTitle());
}
// replace metatitles if exist on components
foreach ($pageData['pageComponents'] as $pageComp) {
$pageMeta = $this->generateAndModifyMetaDataTags($pageData['page'], $pageComp['entity']);
}
return $this->render('@theme/templates/'.$pageData['page']->getTemplate()->getTemplateFile(), [
'page' => $pageMeta,
'slug' => $pageData['slug'],
'pageComponents' => $pageData['pageComponents'],
'pageHtmlBlocks' => $htmlblocks,
'longUrl' => strtolower($longUrl),
]);
} // this will be a redirect
return $pageData;
}
private function debug(bool $debug, $message): void
{
if ($debug) {
echo $message;
}
}
}