/**
  * Renders the current frontend page into the basic frontend template.html file and adds some useful data to the
  * template (e.x. logged in user if there is any, site title, etc.)
  * 
  * @param PageModel $pageModel
  *
  * @return HttpResponse The rendered CMS page ready to send it to the client
  * @throws HttpException if the page does not exist or is not accessible for the current user
  */
 protected function generateCMSPage(PageModel $pageModel)
 {
     if ($this->cmsPage === null) {
         $this->eventDispatcher->dispatch('cms.page_not_found', new PageNotFoundEvent($this->httpRequest));
         throw new HttpException('Could not find cms page', 404);
     }
     if (!$pageModel->hasUserReadAccess($this->cmsPage, $this->auth)) {
         $this->eventDispatcher->dispatch('cms.page_access_denied', new PageAccessDeniedEvent($this->httpRequest));
         throw new HttpException('You don\'t have access to this page', 403);
     }
     $currentEnv = $this->core->getCurrentDomain()->environment;
     $lastChanged = new \DateTime($this->cmsPage->getLastModified());
     $cacheDuration = 18000;
     //31536000; <-- a year
     $responseHeaders = array('Content-Type' => 'text/html; charset=utf-8', 'Content-Language' => $this->cmsPage->getLanguage(), 'Cache-Control' => 'No-Cache', 'Last-Modified' => null, 'Vary' => 'Accept-Encoding');
     // Don't cache if a module controls page content
     /*if($this->cmsRoute->getModuleID() === null)
     		$responseHeaders['Last-Modified'] = gmdate('D, d M Y H:i:s \G\M\T', $lastChanged->getTimestamp());*/
     /*if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $this->cmsPage->getLastModified() <= date('Y-m-d H:i:s', strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])))
     		return new HttpResponse(304, null, $responseHeaders);*/
     $lang = $this->getLocaleHandler()->getLanguage();
     // HTML Cache here!
     $pageCacheActive = isset($this->core->getSettings()->cms->{$currentEnv}->page_cache) ? $this->core->getSettings()->cms->{$currentEnv}->page_cache : false;
     $pageCacheMode = $this->cmsPage->getCacheMode();
     $cacheDir = $this->core->getSiteCacheDir() . 'html' . DIRECTORY_SEPARATOR;
     $pageCacheFile = $cacheDir . 'page-' . $this->cmsPage->getID() . '.html';
     if ($pageCacheActive === true && $this->auth->isLoggedIn() === false && in_array($pageCacheMode, array(CmsPage::CACHE_MODE_PRIVATE, CmsPage::CACHE_MODE_PUBLIC)) && stream_resolve_include_path($pageCacheFile)) {
         $fileTime = filemtime($pageCacheFile);
         // TODO: check if a parent page has changed not only the current
         if ($this->cmsPage->getLastModified() === null || $fileTime >= $lastChanged->getTimestamp()) {
             if ($currentEnv === 'dev') {
                 echo 'Cached page found from: ' . date('d.m.Y H:i:s', $fileTime);
             }
             return new HttpResponse(200, $pageCacheFile, $responseHeaders, true);
         }
     }
     $pageElementCache = isset($this->core->getSettings()->cms->{$currentEnv}) && $this->core->getSettings()->cms->{$currentEnv}->page_cache === true;
     $elementModel = new ElementModel($this->db);
     $elements = $elementModel->getElementTree($this->cmsPage, $pageElementCache);
     if ($this->cmsPage->getLayoutID() !== null && $elements->offsetExists($this->cmsPage->getLayoutID())) {
         $this->cmsPage->setLayout($elements->offsetGet($this->cmsPage->getLayoutID()));
     }
     $elementView = new CmsView($this->templateEngine, $this->core->getSiteRoot() . 'templates' . DIRECTORY_SEPARATOR . $this->currentDomain->template . DIRECTORY_SEPARATOR . 'elements' . DIRECTORY_SEPARATOR);
     // Last modified
     $dtLastModified = new \DateTime($this->cmsPage->getLastModified());
     $dtCreated = new \DateTime($this->cmsPage->getCreated());
     $pageHtml = $this->cmsPage->render($this, $elementView);
     /*$dtLastModifiedRender = new \DateTime($this->cmsPage->getLastModified());
     
     		$responseHeaders['Last-Modified'] = gmdate('D, d M Y H:i:s \G\M\T', $dtLastModifiedRender->getTimestamp());*/
     $tplVars = array('siteTitle' => $this->cmsPage->getTitle(), 'meta_description' => $this->cmsPage->getDescription(), 'page_id' => $this->cmsPage->getID(), 'page_html' => $pageHtml, 'modifier_name' => $this->cmsPage->getModifierName(), 'creator_name' => $this->cmsPage->getCreatorName(), 'date_modified' => $dtLastModified->format($this->getLocaleHandler()->getDateTimeFormat()), 'date_created' => $dtCreated->format($this->getLocaleHandler()->getDateTimeFormat()), 'logged_in' => $this->auth->isLoggedIn(), 'cms_page' => true, 'area_head' => $this->generateAreaHead($this->cmsPage), 'area_body' => $this->generateAreaBody($this->cmsPage), 'current_uri' => urlencode($this->httpRequest->getURI()));
     if ($this->auth->isLoggedIn()) {
         $stmntElements = $this->db->prepare("SELECT ID, name, class FROM cms_element_available WHERE active = '1' ORDER BY name");
         $resElements = $this->db->select($stmntElements);
         $elementList = array();
         foreach ($resElements as $mod) {
             $mod->author = null;
             $mod->version = null;
             $mod->description = null;
             $settingsFile = $this->core->getSiteRoot() . 'settings' . DIRECTORY_SEPARATOR . 'elements' . DIRECTORY_SEPARATOR . $mod->name . '.config.json';
             if (stream_resolve_include_path($settingsFile) === false) {
                 $elementList[] = $mod;
                 continue;
             }
             try {
                 $jsonObj = JsonUtils::decodeFile($settingsFile);
                 if (isset($jsonObj->name) === true) {
                     $mod->name = isset($jsonObj->name->{$lang}) ? $jsonObj->name->{$lang} : $jsonObj->name->en;
                 }
                 if (isset($jsonObj->description) === true) {
                     $mod->description = isset($jsonObj->description->{$lang}) ? $jsonObj->description->{$lang} : $jsonObj->description->en;
                 }
             } catch (\Exception $e) {
                 $this->logger->error('Could not parse config file of element: ' . $mod->name, $e);
             }
             $elementList[] = $mod;
         }
         usort($elementList, function ($a, $b) {
             return strtolower($a->name) > strtolower($b->name);
         });
         $tplVars['elements'] = $elementList;
     }
     $html = $this->renderBasicTemplate('template.html', $tplVars);
     if ($pageCacheActive === true && $this->auth->isLoggedIn() === false && in_array($pageCacheMode, array(CmsPage::CACHE_MODE_PRIVATE, CmsPage::CACHE_MODE_PUBLIC))) {
         file_put_contents($pageCacheFile, $html);
     }
     $httpStatusCode = $this->cmsPage->getErrorCode() !== null ? $this->cmsPage->getErrorCode() : 200;
     return new HttpResponse($httpStatusCode, $html, $responseHeaders);
 }