public function testTargetProperties() { $p = new \Cx\Core\ContentManager\Model\Entity\Page(); $p->setTarget('[[NODE_12]]querystring'); $this->assertEquals(1, $p->isTargetInternal()); $this->assertEquals(12, $p->getTargetNodeId()); $this->assertEquals(0, $p->getTargetLangId()); $this->assertEquals('querystring', $p->getTargetQueryString()); $p->setTarget('[[NODE_12_1]]querystring'); $this->assertEquals(1, $p->isTargetInternal()); $this->assertEquals(12, $p->getTargetNodeId()); $this->assertEquals(1, $p->getTargetLangId()); $this->assertEquals('querystring', $p->getTargetQueryString()); $p->setTarget('http://www.example.com'); $this->assertEquals(0, $p->isTargetInternal()); $this->assertEquals(0, $p->getTargetNodeId()); $this->assertEquals(0, $p->getTargetLangId()); $this->assertEquals(null, $p->getTargetQueryString()); }
/** * Does the resolving work, extends $this->url with targetPath and params. */ public function resolvePage($internal = false) { // Abort here in case we're handling a legacy request. // The legacy request will be handled by $this->legacyResolve(). // Important: We must check for $internal == FALSE here, to abort the resolving process // only when we're resolving the initial (original) request. // Internal resolving requests might be called by $this->legacyResolve() // and shall therefore be processed. if (!$internal && isset($_REQUEST['section'])) { throw new ResolverException('Legacy request'); } $path = $this->url->getSuggestedTargetPath(); if (!$this->page || $internal) { if ($this->pagePreview) { if (!empty($this->sessionPage) && !empty($this->sessionPage['pageId'])) { $this->getPreviewPage(); } } //(I) see what the model has for us $result = $this->pageRepo->getPagesAtPath($this->url->getLangDir() . '/' . $path, null, $this->lang, false, \Cx\Core\ContentManager\Model\Repository\PageRepository::SEARCH_MODE_PAGES_ONLY); if (isset($result['page']) && $result['page'] && $this->pagePreview) { if (empty($this->sessionPage)) { if (\Permission::checkAccess(6, 'static', true)) { $result['page']->setActive(true); $result['page']->setDisplay(true); if ($result['page']->getEditingStatus() == 'hasDraft' || $result['page']->getEditingStatus() == 'hasDraftWaiting') { $logEntries = $this->logRepo->getLogEntries($result['page']); $this->logRepo->revert($result['page'], $logEntries[1]->getVersion()); } } } } //(II) sort out errors if (!$result) { throw new ResolverException('Unable to locate page (tried path ' . $path . ').'); } if (!$result['page']) { throw new ResolverException('Unable to locate page for this language. (tried path ' . $path . ').'); } if (!$result['page']->isActive()) { throw new ResolverException('Page found, but it is not active.'); } // if user has no rights to see this page, we redirect to login $this->checkPageFrontendProtection($result['page']); // If an older revision was requested, revert to that in-place: if (!empty($this->historyId) && \Permission::checkAccess(6, 'static', true)) { $this->logRepo->revert($result['page'], $this->historyId); } //(III) extend our url object with matched path / params $this->url->setTargetPath($result['matchedPath'] . $result['unmatchedPath']); $this->url->setParams($this->url->getSuggestedParams()); $this->page = $result['page']; } /* the page we found could be a redirection. in this case, the URL object is overwritten with the target details and resolving starts over again. */ $target = $this->page->getTarget(); $isRedirection = $this->page->getType() == \Cx\Core\ContentManager\Model\Entity\Page::TYPE_REDIRECT; $isAlias = $this->page->getType() == \Cx\Core\ContentManager\Model\Entity\Page::TYPE_ALIAS; //handles alias redirections internal / disables external redirection $this->forceInternalRedirection = $this->forceInternalRedirection || $isAlias; if ($target && ($isRedirection || $isAlias)) { // Check if page is a internal redirection and if so handle it if ($this->page->isTargetInternal()) { //TODO: add check for endless/circular redirection (a -> b -> a -> b ... and more complex) $nId = $this->page->getTargetNodeId(); $lId = $this->page->getTargetLangId(); $module = $this->page->getTargetModule(); $cmd = $this->page->getTargetCmd(); $qs = $this->page->getTargetQueryString(); $langId = $lId ? $lId : $this->lang; // try to find the redirection target page if ($nId) { $targetPage = $this->pageRepo->findOneBy(array('node' => $nId, 'lang' => $langId)); // revert to default language if we could not retrieve the specified langauge by the redirection. // so lets try to load the redirection of the current language if (!$targetPage) { if ($langId != 0) { //make sure we weren't already retrieving the default language $targetPage = $this->pageRepo->findOneBy(array('node' => $nId, 'lang' => $this->lang)); $langId = $this->lang; } } } else { $targetPage = $this->pageRepo->findOneByModuleCmdLang($module, $cmd, $langId); // in case we were unable to find the requested page, this could mean that we are // trying to retrieve a module page that uses a string with an ID (STRING_ID) as CMD. // therefore, lets try to find the module by using the string in $cmd and INT in $langId as CMD. // in case $langId is really the requested CMD then we will have to set the // resolved language back to our original language $this->lang. if (!$targetPage) { $targetPage = $this->pageRepo->findOneBymoduleCmdLang($module, $cmd . '_' . $langId, $this->lang); if ($targetPage) { $langId = $this->lang; } } // try to retrieve a module page that uses only an ID as CMD. // lets try to find the module by using the INT in $langId as CMD. // in case $langId is really the requested CMD then we will have to set the // resolved language back to our original language $this->lang. if (!$targetPage) { $targetPage = $this->pageRepo->findOneByModuleCmdLang($module, $langId, $this->lang); $langId = $this->lang; } // revert to default language if we could not retrieve the specified langauge by the redirection. // so lets try to load the redirection of the current language if (!$targetPage) { if ($langId != 0) { //make sure we weren't already retrieving the default language $targetPage = $this->pageRepo->findOneByModuleCmdLang($module, $cmd, $this->lang); $langId = $this->lang; } } } //check whether we have a page now. if (!$targetPage) { $this->page = null; return; } // the redirection page is located within a different language. // therefore, we must set $this->lang to the target's language of the redirection. // this is required because we will next try to resolve the redirection target if ($langId != $this->lang) { $this->lang = $langId; $this->url->setLangDir(\FWLanguage::getLanguageCodeById($langId)); $this->pathOffset = ASCMS_INSTANCE_OFFSET; } $targetPath = substr($targetPage->getPath(), 1); $this->url->setTargetPath($targetPath . $qs); $this->url->setPath($targetPath . $qs); $this->isRedirection = true; $this->resolvePage(true); } else { //external target - redirect via HTTP 302 if (\FWValidator::isUri($target)) { header('Location: ' . $target); exit; } else { if ($target[0] == '/') { $target = substr($target, 1); } $langDir = ''; if (!file_exists(ASCMS_INSTANCE_PATH . ASCMS_INSTANCE_OFFSET . '/' . $target)) { $langCode = \FWLanguage::getLanguageCodeById($this->lang); if (!empty($langCode)) { $langDir = '/' . $langCode; } } header('Location: ' . ASCMS_INSTANCE_OFFSET . $langDir . '/' . $target); exit; } } } //if we followed one or more redirections, the user shall be redirected by 302. if ($this->isRedirection && !$this->forceInternalRedirection) { $params = $this->url->getSuggestedParams(); header('Location: ' . $this->page->getURL($this->pathOffset, $params)); exit; } // in case the requested page is of type fallback, we will now handle/load this page $this->handleFallbackContent($this->page, !$internal); // set legacy <section> and <cmd> in case the requested page is an application if ($this->page->getType() == \Cx\Core\ContentManager\Model\Entity\Page::TYPE_APPLICATION || $this->page->getType() == \Cx\Core\ContentManager\Model\Entity\Page::TYPE_FALLBACK) { $this->command = $this->page->getCmd(); $this->section = $this->page->getModule(); } }