/**
  * Clears cache of pages where an object with the given identifier is shown
  * 
  * @param string $objectIdentifier
  */
 public function clearPageCacheForObjectIdentifier($objectIdentifier)
 {
     // TODO: Move this to different implementations of the Tracking Manager...
     switch ($this->extensionConfiguration->getCacheInvalidationLevel()) {
         case 'consistent':
             $sharedLock = null;
             $sharedLockAcquired = $this->acquireLock($sharedLock, $objectIdentifier, FALSE);
             if ($sharedLockAcquired) {
                 if ($this->trackingCache->has($objectIdentifier)) {
                     $exclusiveLock = null;
                     $exclusiveLockAcquired = $this->acquireLock($exclusiveLock, $objectIdentifier . '-e', TRUE);
                     if ($exclusiveLockAcquired) {
                         $pageHashs = $this->trackingCache->get($objectIdentifier);
                         $this->pageCacheFacade->flushCacheByHashIdentifiers($pageHashs);
                         $this->trackingCache->set($objectIdentifier, array());
                         $this->releaseLock($exclusiveLock);
                     } else {
                         $pageHashs = $this->trackingCache->get($objectIdentifier);
                         $this->pageCacheFacade->flushCacheByHashIdentifiers($pageHashs);
                     }
                 }
                 $this->releaseLock($sharedLock);
             } else {
                 // Failed locking
                 // should probably throw an exception here
             }
             break;
         default:
         case 'noinvalidation':
             break;
     }
     return;
 }
 /**
  * Dispatches a request to a controller and initializes the security framework.
  *
  * @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The request to dispatch
  * @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response The response, to be modified by the controller
  * @param \EssentialDots\ExtbaseHijax\Event\Listener $listener Listener
  * @return void
  */
 public function dispatch(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response, \EssentialDots\ExtbaseHijax\Event\Listener $listener = NULL)
 {
     /* @var $request \TYPO3\CMS\Extbase\Mvc\Request */
     $this->currentRequest = $request;
     array_push($this->requestsStack, $this->currentRequest);
     if (defined('TYPO3_cliMode') && TYPO3_cliMode === TRUE) {
         parent::dispatch($request, $response);
     } else {
         array_push($this->listenersStack, $this->currentListener);
         if ($listener) {
             $this->currentListener = $listener;
         } else {
             $this->currentListener = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('EssentialDots\\ExtbaseHijax\\Event\\Listener', $request);
         }
         if (!$this->serviceContent->getExecuteExtbasePlugins()) {
             $this->listenerFactory->persist($this->currentListener);
             $this->serviceContent->setCurrentListener($this->currentListener);
         } else {
             $this->hijaxEventDispatcher->startContentElement();
             try {
                 parent::dispatch($request, $response);
             } catch (\TYPO3\CMS\Extbase\Mvc\Controller\Exception\RequiredArgumentMissingException $requiredArgumentMissingException) {
                 try {
                     // this happens with simple reload on pages where some argument is required
                     $configuration = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
                     $defaultControllerName = current(array_keys($configuration['controllerConfiguration']));
                     $allowedControllerActions = array();
                     foreach ($configuration['controllerConfiguration'] as $controllerName => $controllerActions) {
                         $allowedControllerActions[$controllerName] = $controllerActions['actions'];
                     }
                     $defaultActionName = is_array($allowedControllerActions[$request->getControllerName()]) ? current($allowedControllerActions[$request->getControllerName()]) : '';
                     // try to run the current controller with the default action
                     $request->setDispatched(false);
                     $request->setControllerActionName($defaultActionName);
                     parent::dispatch($request, $response);
                 } catch (\TYPO3\CMS\Extbase\Mvc\Controller\Exception\RequiredArgumentMissingException $requiredArgumentMissingException) {
                     if ($defaultControllerName != $request->getControllerName()) {
                         $request->setControllerName($defaultControllerName);
                         $defaultActionName = is_array($allowedControllerActions[$defaultControllerName]) ? current($allowedControllerActions[$defaultControllerName]) : '';
                         // try to run the default plugin controller with the default action
                         $request->setDispatched(false);
                         $request->setControllerActionName($defaultActionName);
                         parent::dispatch($request, $response);
                     }
                 }
             }
             if ($this->hijaxEventDispatcher->getIsHijaxElement()) {
                 $this->listenerFactory->persist($this->currentListener);
             }
             if (($this->ajaxDispatcher->getIsActive() || $this->hijaxEventDispatcher->getIsHijaxElement()) && !$this->ajaxDispatcher->getPreventMarkupUpdateOnAjaxLoad()) {
                 $currentListeners = $this->hijaxEventDispatcher->getListeners('', TRUE);
                 $signature = $this->getCurrentListener()->getId() . '(' . $this->convertArrayToCSV(array_keys($currentListeners)) . '); ';
                 $content = $response->getContent();
                 $content = '<!-- ###EVENT_LISTENER_' . self::$id . '### START ' . $signature . ' -->' . $content . '<!-- ###EVENT_LISTENER_' . self::$id . '### END -->';
                 if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('eID') && \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('eID') != 'extbase_hijax_dispatcher') {
                     $this->hijaxEventDispatcher->replaceXMLCommentsWithDivs($content, 'html');
                 }
                 $response->setContent($content);
                 $this->extensionConfiguration->setNextElementId(++self::$id);
             }
             $this->hijaxEventDispatcher->endContentElement();
         }
         $this->currentListener = array_pop($this->listenersStack);
     }
     $this->currentRequest = array_pop($this->requestsStack);
 }
 /**
  * @param array $params
  * @param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $pObj
  * @param string $hookType
  */
 protected function contentPostProc($params, $pObj, $hookType)
 {
     if ($this->extensionConfiguration->shouldIncludeEofe() && !$this->extensionConfiguration->hasIncludedEofe()) {
         $this->extensionConfiguration->setIncludedEofe(true);
         $eofe = $pObj->cObj->cObjGetSingle($pObj->tmpl->setup['config.']['extbase_hijax.']['eofe'], $pObj->tmpl->setup['config.']['extbase_hijax.']['eofe.']);
         $pObj->content = str_ireplace('</body>', $eofe . '</body>', $pObj->content);
     }
     if ($this->extensionConfiguration->shouldIncludeSofe() && !$this->extensionConfiguration->hasIncludedSofe()) {
         $this->extensionConfiguration->setIncludedSofe(true);
         $sofe = $pObj->cObj->cObjGetSingle($pObj->tmpl->setup['config.']['extbase_hijax.']['sofe'], $pObj->tmpl->setup['config.']['extbase_hijax.']['sofe.']);
         $pObj->content = preg_replace('/<body([^>]*)>/msU', '<body$1>' . $sofe, $pObj->content);
     }
     $bodyClass = $pObj->tmpl->setup['config.']['extbase_hijax.']['bodyClass'];
     if ($bodyClass && !$this->extensionConfiguration->hasAddedBodyClass()) {
         $matches = array();
         preg_match('/<body([^>]*)class="([^>]*)">/msU', $pObj->content, $matches);
         $count = 0;
         if (count($matches)) {
             $classes = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(" ", $matches[2], true);
             if (!in_array($bodyClass, $classes)) {
                 $pObj->content = preg_replace('/<body([^>]*)class="([^>]*)">/msU', '<body$1class="$2 ' . $bodyClass . '">', $pObj->content, -1, $count);
             }
         } else {
             $pObj->content = preg_replace('/<body([^>]*)>/msU', '<body$1 class="' . $bodyClass . '">', $pObj->content, -1, $count);
         }
         if ($count) {
             $this->extensionConfiguration->setAddedBodyClass(true);
         }
     }
     if ($hookType == 'output') {
         while ($this->hijaxEventDispatcher->hasPendingNextPhaseEvents()) {
             // trick to force double rendering of some content elements
             $GLOBALS['TSFE']->recordRegister = array();
             // trick to force loading of full TS template
             if (!$pObj->tmpl->loaded) {
                 $pObj->forceTemplateParsing = TRUE;
                 $pObj->getConfigArray();
             }
             $this->hijaxEventDispatcher->promoteNextPhaseEvents();
             $this->hijaxEventDispatcher->parseAndRunEventListeners($pObj->content);
             if (!$pObj->config['INTincScript']) {
                 $pObj->config['INTincScript'] = array();
             }
             $pObj->INTincScript();
             if (self::$loopCount++ > 99) {
                 // preventing dead loops
                 break;
             }
         }
     }
     if ($hookType == 'output' || $pObj->isStaticCacheble()) {
         $this->hijaxEventDispatcher->replaceXMLCommentsWithDivs($pObj->content);
     }
     if ($hookType == 'output') {
         if (count($this->nonCacheableFooterCode)) {
             ksort($this->nonCacheableFooterCode);
             $pObj->content = $this->str_lreplace('</body>', '<!-- x123456 -->' . implode('', $this->nonCacheableFooterCode) . '</body>', $pObj->content);
         }
         if (count($this->nonCacheableHeaderCode)) {
             ksort($this->nonCacheableHeaderCode);
             $pObj->content = $this->str_lreplace('</head>', '<!-- x123456 -->' . implode('', $this->nonCacheableHeaderCode) . '</head>', $pObj->content);
         }
     }
 }