/** * @expectedException \Cx\Model\Base\ValidationException */ public function testValidationException() { $nodeRepo = self::$em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Node'); $n = new \Cx\Core\ContentManager\Model\Entity\Node(); $n->setParent($nodeRepo->getRoot()); $nodeRepo->getRoot()->addChildren($n); self::$em->persist($n); self::$em->flush(); $p = new \Cx\Core\ContentManager\Model\Entity\Page(); $p->setNode($n); $p->setLang(1); $p->setTitle('validation testpage'); $p->setNodeIdShadowed($n->getId()); $p->setUseCustomContentForAllChannels(''); $p->setUseCustomApplicationTemplateForAllChannels(''); $p->setUseSkinForAllChannels(''); $p->setType(\Cx\Core\ContentManager\Model\Entity\Page::TYPE_APPLICATION); $p->setActive(1); //set disallowed module name $p->setModule('1|@f2'); $p->setCmd(''); self::$em->persist($n); self::$em->persist($p); //should raise exception self::$em->flush(); }
public function testPagesByLang() { $nodeRepo = self::$em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Node'); $node = new \Cx\Core\ContentManager\Model\Entity\Node(); $node->setParent($nodeRepo->getRoot()); $nodeRepo->getRoot()->addChildren($node); self::$em->persist($node); self::$em->flush(); $p1 = new \Cx\Core\ContentManager\Model\Entity\Page(); $p2 = new \Cx\Core\ContentManager\Model\Entity\Page(); $p1->setNode($node); $p2->setNode($node); $p1->setLang(1); $p1->setTitle('testpage'); $p1->setNodeIdShadowed($node->getId()); $p1->setUseCustomContentForAllChannels(''); $p1->setUseCustomApplicationTemplateForAllChannels(''); $p1->setUseSkinForAllChannels(''); $p1->setCmd(''); $p1->setActive(1); $p2->setLang(2); $p2->setTitle('testpage2'); $p2->setNodeIdShadowed($node->getId()); $p2->setUseCustomContentForAllChannels(''); $p2->setUseCustomApplicationTemplateForAllChannels(''); $p2->setUseSkinForAllChannels(''); $p2->setCmd(''); $p2->setActive(1); self::$em->persist($node); self::$em->persist($p1); self::$em->persist($p2); self::$em->flush(); self::$em->refresh($node); // Refreshes the state of the given entity from the database, overwriting local changes. $id = $p1->getId(); $r = self::$em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Page'); $p = $r->find($id); $pages = $p->getNode()->getPagesByLang(); $this->assertArrayHasKey(2, $pages); $this->assertArrayHasKey(1, $pages); $this->assertEquals('testpage', $pages[1]->getTitle()); $this->assertEquals('testpage2', $pages[2]->getTitle()); }
protected function getResolvedFallbackPage() { $nodeRepo = self::$em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Node'); $root = $nodeRepo->getRoot(); $n1 = new \Cx\Core\ContentManager\Model\Entity\Node(); $n1->setParent($root); $root->addChildren($n1); self::$em->persist($n1); self::$em->flush(); //test if requesting this page... $p2 = new \Cx\Core\ContentManager\Model\Entity\Page(); $p2->setLang(1); $p2->setTitle('pageThatsFallingBack'); $p2->setNode($n1); $p2->setType(\Cx\Core\ContentManager\Model\Entity\Page::TYPE_FALLBACK); $p2->setNodeIdShadowed($n1->getId()); $p2->setUseCustomContentForAllChannels(''); $p2->setUseCustomApplicationTemplateForAllChannels(''); $p2->setUseSkinForAllChannels(''); $p2->setCmd(''); $p2->setActive(1); //... will yield contents of this page as result. $p1 = new \Cx\Core\ContentManager\Model\Entity\Page(); $p1->setLang(2); $p1->setTitle('pageThatHoldsTheContent'); $p1->setNode($n1); $p1->setType(\Cx\Core\ContentManager\Model\Entity\Page::TYPE_CONTENT); $p1->setContent('fallbackContent'); $p1->setNodeIdShadowed($n1->getId()); $p1->setUseCustomContentForAllChannels(''); $p1->setUseCustomApplicationTemplateForAllChannels(''); $p1->setUseSkinForAllChannels(''); $p1->setCmd(''); $p1->setActive(1); self::$em->persist($n1); self::$em->persist($p1); self::$em->persist($p2); self::$em->flush(); self::$em->refresh($n1); return false; $url = new Url('http://example.com/pageThatsFallingBack/'); $resolver = new Resolver($url, 1, self::$em, '', $this->mockFallbackLanguages, true); $resolver->resolve(); $p = $resolver->getPage(); return $p; }
function _saveAlias($slug, $target, $is_local, $id = '') { if ($slug == '') { return false; } // is internal target if ($is_local) { // get target page $temp_page = new \Cx\Core\ContentManager\Model\Entity\Page(); $temp_page->setTarget($target); $existing_aliases = $this->_getAliasesWithSameTarget($temp_page); // if alias already exists -> fail foreach ($existing_aliases as $existing_alias) { if (($id == '' || $existing_alias->getNode()->getId() != $id) && $slug == $existing_alias->getSlug()) { return false; } } } if ($id == '') { // create new node $node = new \Cx\Core\ContentManager\Model\Entity\Node(); $node->setParent($this->nodeRepository->getRoot()); $this->em->persist($node); // add a page $page = $this->_createTemporaryAlias(); $page->setNode($node); } else { $node = $this->nodeRepository->find($id); if (!$node) { return false; } $pages = $node->getPages(true); if (count($pages) != 1) { return false; } $page = $pages->first(); // we won't change anything on non aliases if ($page->getType() != \Cx\Core\ContentManager\Model\Entity\Page::TYPE_ALIAS) { return false; } } // set page attributes $page->setSlug($slug); $page->setTarget($target); $page->setTitle($page->getSlug()); // sanitize slug while (file_exists(ASCMS_PATH . '/' . $page->getSlug())) { $page->nextSlug(); } // save try { $page->validate(); } catch (\Cx\Core\ContentManager\Model\Entity\PageException $e) { return $e->getUserMessage(); } $this->em->persist($page); $this->em->flush(); $this->em->refresh($node); $this->em->refresh($page); return true; }
public function testSlugReleasing() { $nodeRepo = self::$em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Node'); $root = $nodeRepo->getRoot(); $n1 = new \Cx\Core\ContentManager\Model\Entity\Node(); $n1->setParent($root); $root->addChildren($n1); $n2 = new \Cx\Core\ContentManager\Model\Entity\Node(); $n2->setParent($root); $root->addChildren($n2); self::$em->persist($n1); self::$em->persist($n2); self::$em->flush(); $p1 = new \Cx\Core\ContentManager\Model\Entity\Page(); $p1->setLang(1); $p1->setTitle('slug release testpage'); $p1->setNode($n1); $p1->setNodeIdShadowed($n1->getId()); $p1->setUseCustomContentForAllChannels(''); $p1->setUseCustomApplicationTemplateForAllChannels(''); $p1->setUseSkinForAllChannels(''); $p1->setCmd(''); $p1->setActive(1); self::$em->persist($root); self::$em->persist($n1); self::$em->persist($n2); self::$em->persist($p1); self::$em->flush(); $idp1 = $p1->getId(); $idn2 = $n2->getId(); self::$em->refresh($n1); self::$em->refresh($n2); $this->assertEquals('slug-release-testpage', $p1->getSlug()); $p1 = self::$em->find('Cx\\Core\\ContentManager\\Model\\Entity\\Page', $idp1); $n2 = self::$em->find('Cx\\Core\\ContentManager\\Model\\Entity\\Node', $idn2); //shouldn't provocate a slug conflict, since we delete the other page below $p2 = new \Cx\Core\ContentManager\Model\Entity\Page(); $p2->setLang(1); $p2->setTitle('slug release testpage'); $p2->setNode($n2); $p2->setNodeIdShadowed($n2->getId()); $p2->setUseCustomContentForAllChannels(''); $p2->setUseCustomApplicationTemplateForAllChannels(''); $p2->setUseSkinForAllChannels(''); $p2->setCmd(''); $p2->setActive(1); self::$em->remove($p1); self::$em->flush(); self::$em->persist($p2); self::$em->flush(); $this->assertEquals('slug-release-testpage', $p2->getSlug()); }
public function serialize() { return serialize(array($this->id, $this->active, $this->backendAccessId, $this->caching, $this->cmd, $this->content, $this->contentTitle, $this->cssName, $this->cssNavName, $this->customContent, $this->display, $this->editingStatus, $this->end, $this->frontendAccessId, $this->isVirtual, $this->lang, $this->linkTarget, $this->metarobots, $this->metatitle, $this->module, $this->node->getId(), $this->nodeIdShadowed, $this->protection, $this->skin, $this->slug, $this->slugBase, $this->slugSuffix, $this->sourceMode, $this->start, $this->target, $this->title, $this->type, $this->updatedAt, $this->updatedBy, $this->metadesc, $this->metakeys)); }
public function testGetPathToPage() { $nodeRepo = self::$em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Node'); $n1 = new \Cx\Core\ContentManager\Model\Entity\Node(); $n1->setParent($nodeRepo->getRoot()); $nodeRepo->getRoot()->addChildren($n1); $n2 = new \Cx\Core\ContentManager\Model\Entity\Node(); $n2->setParent($n1); $n1->addChildren($n2); self::$em->persist($n1); self::$em->persist($n2); self::$em->flush(); $p1 = new \Cx\Core\ContentManager\Model\Entity\Page(); $p1->setLang(1); $p1->setTitle('root'); $p1->setNode($n1); $p1->setNodeIdShadowed($n1->getId()); $p1->setUseCustomContentForAllChannels(''); $p1->setUseCustomApplicationTemplateForAllChannels(''); $p1->setUseSkinForAllChannels(''); $p1->setCmd(''); $p1->setActive(1); $p2 = new \Cx\Core\ContentManager\Model\Entity\Page(); $p2->setLang(1); $p2->setTitle('child page'); $p2->setNode($n2); $p2->setNodeIdShadowed($n2->getId()); $p2->setUseCustomContentForAllChannels(''); $p2->setUseCustomApplicationTemplateForAllChannels(''); $p2->setUseSkinForAllChannels(''); $p2->setCmd(''); $p2->setActive(1); self::$em->persist($n1); self::$em->persist($n2); self::$em->persist($p1); self::$em->persist($p2); self::$em->flush(); $pageId = $p2->getId(); \Env::get('em')->refresh($n1); //make sure we re-fetch a correct state self::$em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Node')->verify(); $pageRepo = self::$em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Page'); $page = $pageRepo->findOneById($pageId); $this->assertEquals('root/child-page', $pageRepo->getPath($page)); }
public function testTranslate() { $nodeRepo = self::$em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Node'); $pageRepo = self::$em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Page'); $n1 = new \Cx\Core\ContentManager\Model\Entity\Node(); $n1->setParent($nodeRepo->getRoot()); $nodeRepo->getRoot()->addChildren($n1); $n2 = new \Cx\Core\ContentManager\Model\Entity\Node(); $n2->setParent($n1); self::$em->persist($n1); self::$em->persist($n2); self::$em->flush(); $p1 = new \Cx\Core\ContentManager\Model\Entity\Page(); $p1->setLang(1); $p1->setTitle('test translate root'); $p1->setNode($n1); $p1->setNodeIdShadowed($n1->getId()); $p1->setUseCustomContentForAllChannels(''); $p1->setUseCustomApplicationTemplateForAllChannels(''); $p1->setUseSkinForAllChannels(''); $p1->setCmd(''); $p1->setActive(1); $p2 = new \Cx\Core\ContentManager\Model\Entity\Page(); $p2->setLang(1); $p2->setTitle('child page'); $p2->setNode($n2); $p2->setNodeIdShadowed($n1->getId()); $p2->setUseCustomContentForAllChannels(''); $p2->setUseCustomApplicationTemplateForAllChannels(''); $p2->setUseSkinForAllChannels(''); $p2->setCmd(''); $p2->setActive(1); self::$em->persist($n1); self::$em->persist($n2); self::$em->persist($p1); self::$em->persist($p2); self::$em->flush(); $pageId = $p2->getId(); self::$em->refresh($n1); self::$em->refresh($n2); $pageToTranslate = $pageRepo->findOneById($pageId); // copy page following redirects $page = $pageToTranslate->copyToLang(2, true, true, true, true, true, false, true); $page->setActive(1); $pageToTranslate->setupPath(2); $page->setNodeIdShadowed($pageToTranslate->getId()); self::$em->persist($page); self::$em->flush(); $pageId = $page->getId(); // Translated page id self::$em->refresh($n1); self::$em->refresh($n2); $page = $pageRepo->findOneById($pageId); // Translated page $this->assertEquals('/test-translate-root/child-page', $page->getPath()); $this->assertEquals(2, $page->getLang()); //see if the parent node is really, really there. $parentPages = $page->getNode()->getParent()->getPagesByLang(); $this->assertArrayHasKey(2, $parentPages); $this->assertEquals('test translate root', $parentPages[2]->getTitle()); }
/** * Returns the preview page built from the session page array. * @return Cx\Core\ContentManager\Model\Entity\Page $page */ private function getPreviewPage() { $data = $this->sessionPage; $page = $this->pageRepo->findOneById($data['pageId']); if (!$page) { $page = new \Cx\Core\ContentManager\Model\Entity\Page(); $node = new \Cx\Core\ContentManager\Model\Entity\Node(); $node->setParent($this->nodeRepo->getRoot()); $node->setLvl(1); $this->nodeRepo->getRoot()->addChildren($node); $node->addPage($page); $page->setNode($node); $this->pageRepo->addVirtualPage($page); } unset($data['pageId']); $page->setLang(\FWLanguage::getLanguageIdByCode($data['lang'])); unset($data['lang']); $page->updateFromArray($data); $page->setUpdatedAtToNow(); $page->setActive(true); $page->setVirtual(true); $page->validate(); return $page; }
function installModules() { global $objDatabase; $em = \Env::get('em'); $nodeRepo = $em->getRepository('\\Cx\\Core\\ContentManager\\Model\\Entity\\Node'); //$i = 1; if (empty($_POST['installModule']) || !is_array($_POST['installModule'])) { return false; } //$currentTime = time(); $paridarray = array(); foreach (array_keys($_POST['installModule']) as $moduleId) { $id = intval($moduleId); $objResult = $objDatabase->Execute("\n SELECT name\n FROM " . DBPREFIX . "modules\n WHERE id={$id}\n "); if ($objResult) { if (!$objResult->EOF) { $module_name = $objResult->fields['name']; } } else { $this->errorHandling(); return false; } // get content from repo $query = "SELECT *\n FROM " . DBPREFIX . "module_repository\n WHERE moduleid={$id}\n ORDER BY parid ASC"; $objResult = $objDatabase->Execute($query); if ($objResult) { while (!$objResult->EOF) { // define parent node $root = false; if (isset($paridarray[$objResult->fields['parid']])) { $parcat = $paridarray[$objResult->fields['parid']]; } else { $root = true; $parcat = $nodeRepo->getRoot(); } $this->arrayInstalledModules[$module_name] = true; $sourceMode = !empty($objResult->fields['expertmode']) && $objResult->fields['expertmode'] == 'y' ? true : false; // create node $newnode = new \Cx\Core\ContentManager\Model\Entity\Node(); $newnode->setParent($parcat); // replace root node by parent! $em->persist($newnode); $em->flush(); $nodeRepo->moveDown($newnode, true); // move to the end of this level $paridarray[$objResult->fields['id']] = $newnode; // add content to default lang // add content to all langs without fallback // link content to all langs with fallback foreach (\FWLanguage::getActiveFrontendLanguages() as $lang) { if ($lang['is_default'] === 'true' || $lang['fallback'] == null) { $page = $this->createPage($newnode, $lang['id'], $objResult->fields['title'], \Cx\Core\ContentManager\Model\Entity\Page::TYPE_APPLICATION, $module_name, $objResult->fields['cmd'], !$root && $objResult->fields['displaystatus'], $sourceMode, $objResult->fields['content']); } else { $page = $this->createPage($newnode, $lang['id'], $objResult->fields['title'], \Cx\Core\ContentManager\Model\Entity\Page::TYPE_FALLBACK, $module_name, $objResult->fields['cmd'], !$root && $objResult->fields['displaystatus'], $sourceMode, ''); } $em->persist($page); } $em->flush(); $objResult->MoveNext(); } } else { $this->errorHandling(); return false; } } // end foreach return true; }
/** * Restores a page from histroy. */ protected function restoreHistory() { \Permission::checkAccess(77, 'static'); // Create node $node = new \Cx\Core\ContentManager\Model\Entity\Node(); $node->setParent($this->nodeRepo->getRoot()); $this->em->persist($node); $this->em->flush(); $arrData = $this->revertPage($this->pageId); $currentPage = $arrData['page']; $logs = $arrData['logs']; $nodeIdShadowed = $currentPage->getNodeIdShadowed(); $this->restorePage($node, $currentPage, $logs); $logsRemove = $this->logRepo->getLogsByAction('remove'); foreach ($logsRemove as $logRemove) { $arrData = $this->revertPage($logRemove->getObjectId()); $page = $arrData['page']; $logs = $arrData['logs']; if ($page->getNodeIdShadowed() == $nodeIdShadowed) { $this->restorePage($node, $page, $logs); } } $this->redirectPage($currentPage->getId()); }
/** * Handles request from the client * @todo Clean up usage of $param and $_GET * @global Array $_CORELANG Core language data * @param Array $params Client parameters * @return type */ public function set($params) { global $_CORELANG; // Global access check if (!\Permission::checkAccess(6, 'static', true) || !\Permission::checkAccess(35, 'static', true)) { throw new \Exception($_CORELANG['TXT_CORE_CM_USAGE_DENIED']); } $newPage = false; $reload = false; $pg = \Env::get('pageguard'); $dataPost = !empty($params['post']) ? $params['post'] : array(); $pageArray = !empty($dataPost['page']) ? $dataPost['page'] : array(); // Only set in the editing mode. $pageId = !empty($pageArray['id']) ? intval($pageArray['id']) : (!empty($dataPost['pageId']) ? intval($dataPost['pageId']) : 0); $nodeId = !empty($pageArray['node']) ? intval($pageArray['node']) : (!empty($dataPost['nodeId']) ? intval($dataPost['nodeId']) : 0); $lang = !empty($pageArray['lang']) ? contrexx_input2raw($pageArray['lang']) : (!empty($dataPost['lang']) ? contrexx_input2raw($dataPost['lang']) : \FWLanguage::getLanguageCodeById(\FWLanguage::getDefaultLangId())); $action = !empty($dataPost['action']) ? contrexx_input2raw($dataPost['action']) : ''; $cacheManager = new \Cx\Core_Modules\Cache\Controller\CacheManager(); $cacheManager->deleteSingleFile($pageId); if (!empty($pageArray)) { if (!empty($pageArray['target']) && !empty($pageArray['target_protocol'])) { $pageArray['target'] = $pageArray['target_protocol'] . $pageArray['target']; } elseif (empty($pageArray['target']) && !empty($pageArray['target_protocol'])) { $pageArray['target'] = ''; } $validatedPageArray = $this->validatePageArray($pageArray); } // UPDATE if (!empty($pageId)) { // If we got a page id, the page already exists and can be updated. $page = $this->pageRepo->find($pageId, 0, null, false); $node = $page->getNode(); // TRANSLATE } else { if (!empty($nodeId) && !empty($lang)) { // We are translating the page. $node = $this->nodeRepo->find($nodeId); $page = $node->translatePage(true, \FWLanguage::getLanguageIdByCode($lang)); $page->setNodeIdShadowed($node->getId()); $page->setEditingStatus(''); $newPage = true; $reload = true; // CREATE } else { if (empty($pageId) && !empty($lang)) { if (!\Permission::checkAccess(5, 'static', true)) { throw new \Exception($_CORELANG['TXT_CORE_CM_CREATION_DENIED']); } // Create a new node/page combination. $node = new \Cx\Core\ContentManager\Model\Entity\Node(); // CREATE WITHIN if (isset($dataPost['parent_node'])) { $parentNode = $this->nodeRepo->find($dataPost['parent_node']); if (!$parentNode) { $parentNode = $this->nodeRepo->getRoot(); } $node->setParent($parentNode); $parentNode->addChildren($node); // add parent node to ID, so the node containing the new page is opened if (!isset($_COOKIE['jstree_open'])) { $_COOKIE['jstree_open'] = ''; } $openNodes = explode(',', $_COOKIE['jstree_open']); if ($openNodes == array(0 => '')) { $openNodes = array(); } if (!in_array('#node_' . $parentNode->getId(), $openNodes)) { $openNodes[] = '#node_' . $parentNode->getId(); } setcookie('jstree_open', implode(',', $openNodes)); $this->em->persist($node); $this->em->flush(); // CREATE } else { $node->setParent($this->nodeRepo->getRoot()); $this->nodeRepo->getRoot()->addChildren($node); $this->em->persist($node); $this->em->flush(); } $page = new \Cx\Core\ContentManager\Model\Entity\Page(); $page->setNode($node); $node->addPage($page); $page->setNodeIdShadowed($node->getId()); $page->setLang(\FWLanguage::getLanguageIdByCode($lang)); $page->setUpdatedBy(\FWUser::getFWUserObject()->objUser->getUsername()); $newPage = true; $reload = true; } else { throw new \Exception('Page cannot be created. There are too little information.'); } } } // Page access check if ($page->isBackendProtected() && !\Permission::checkAccess($page->getBackendAccessId(), 'dynamic', true)) { throw new \Cx\Core\ContentManager\Model\Entity\PageException('Not allowed to read page'); } if (!empty($pageArray)) { $page->updateFromArray($validatedPageArray); if ($newPage) { // Make sure page has an ID $this->em->persist($page); $this->em->flush(); } } if (!empty($action)) { switch ($action) { case 'activate': case 'publish': $page->setActive(true); break; case 'deactivate': $page->setActive(false); break; case 'show': $page->setDisplay(true); break; case 'hide': $page->setDisplay(false); break; case 'protect': $page->setFrontendProtection(true); break; case 'unprotect': $page->setFrontendProtection(false); break; case 'lock': $page->setBackendProtection(true); break; case 'unlock': $page->setBackendProtection(false); break; } if ($action != 'publish' && !$page->isDraft()) { $action = 'publish'; } } $page->setUpdatedAtToNow(); $page->validate(); // Permissions are only updated in the editing mode. if (!empty($pageArray)) { if ($action == 'publish') { if (\Permission::checkAccess(36, 'static', true)) { if ($page->isFrontendProtected()) { // remove all \Permission::removeAccess($page->getFrontendAccessId(), 'dynamic'); if (isset($dataPost['frontendGroups'])) { // set new $pg->setAssignedGroupIds($page, $dataPost['frontendGroups'], true); } } if ($page->isBackendProtected()) { // remove all $groupIds = $pg->getAssignedGroupIds($page, false); \Permission::removeAccess($page->getBackendAccessId(), 'dynamic'); if (isset($dataPost['backendGroups'])) { // set new $pg->setAssignedGroupIds($page, $dataPost['backendGroups'], false); } if ($page->isBackendProtected() && !\Permission::checkAccess($page->getBackendAccessId(), 'dynamic', true)) { if (!count($groupIds)) { $page->setBackendProtection(false); } else { $pg->setAssignedGroupIds($page, $groupIds, false); } } } } } } // Block associations are only updated in the editing mode. if (!empty($pageArray) && empty($dataPost['ignoreBlocks'])) { if (!isset($dataPost['pageBlocks'])) { $dataPost['pageBlocks'] = array(); } $page->setRelatedBlocks($dataPost['pageBlocks']); } $draftUpdateLog = null; $liveUpdateLog = null; $updatingDraft = false; if ($action == 'publish' && \Permission::checkAccess(78, 'static', true)) { // User w/permission clicked save&publish. we should either publish the page or submit the draft for approval. if ($page->getEditingStatus() == 'hasDraftWaiting') { $reload = true; } if ($page->getEditingStatus() != '') { $logEntries = $this->logRepo->getLogEntries($page, false); $this->em->remove($logEntries[0]); } $page->setEditingStatus(''); $this->messages[] = $_CORELANG['TXT_CORE_SAVED']; } else { // User clicked save [as draft], so let's do that. $updatingDraft = $page->getEditingStatus() != '' ? true : false; if ($action == 'publish') { // User w/o publish permission clicked save&publish. submit it as a draft. $page->setEditingStatus('hasDraftWaiting'); $this->messages[] = $_CORELANG['TXT_CORE_DRAFT_SUBMITTED']; } else { if ($page->getEditingStatus() == 'hasDraftWaiting' && \Permission::checkAccess(78, 'static', true)) { $reload = true; } $page->setEditingStatus('hasDraft'); $this->messages[] = $_CORELANG['TXT_CORE_SAVED_AS_DRAFT']; } // Gedmo-loggable generates a LogEntry (i.e. revision) on persist, so we'll have to // store the draft first, then revert the current version to what it previously was. // In the end, we'll have the current [published] version properly stored as a page // and the draft version stored as a gedmo LogEntry. $this->em->persist($page); // Gedmo hooks in on persist/flush, so we unfortunately need to flush our em in // order to get a clean set of logEntries. $this->em->flush(); $logEntries = $this->logRepo->getLogEntries($page, false); // Revert to the published version. $cachedEditingStatus = $page->getEditingStatus(); $this->logRepo->revert($page, $logEntries[1]->getVersion()); $page->setEditingStatus($cachedEditingStatus); switch ($action) { case 'activate': case 'publish': $page->setActive(true); break; case 'deactivate': $page->setActive(false); break; case 'show': $page->setDisplay(true); break; case 'hide': $page->setDisplay(false); break; case 'protect': $page->setFrontendProtection(true); break; case 'unprotect': $page->setFrontendProtection(false); break; case 'lock': $page->setBackendProtection(true); break; case 'unlock': $page->setBackendProtection(false); break; } $this->em->persist($page); // Gedmo auto-logs slightly too much data. clean up unnecessary revisions: if ($updatingDraft) { $this->em->flush(); $logEntries = $this->logRepo->getLogEntries($page); $currentLog = $logEntries[1]; $currentLogData = $currentLog->getData(); $currentLogData['editingStatus'] = $page->getEditingStatus(); $currentLog->setData($currentLogData); $this->em->persist($currentLog); $liveUpdateLog = $logEntries[2]; $this->em->remove($logEntries[2]); } } $this->em->persist($page); if (isset($dataPost['inheritFrontendAccess']) && $dataPost['inheritFrontendAccess'] == 'on' || isset($dataPost['inheritBackendAccess']) && $dataPost['inheritBackendAccess'] == 'on' || isset($dataPost['inheritSkin']) && $dataPost['inheritSkin'] == 'on' || isset($dataPost['inheritCustomContent']) && $dataPost['inheritCustomContent'] == 'on' || isset($dataPost['inheritCssName']) && $dataPost['inheritCssName'] == 'on' || isset($dataPost['inheritCssNavName']) && $dataPost['inheritCssNavName'] == 'on' || isset($dataPost['inheritCaching']) && $dataPost['inheritCaching'] == 'on') { $pageStack = $page->getChildren(); while (count($pageStack)) { $currentPage = array_pop($pageStack); foreach ($currentPage->getChildren() as $child) { array_push($pageStack, $child); } if (isset($dataPost['inheritFrontendAccess']) && $dataPost['inheritFrontendAccess'] == 'on') { $reload = true; $page->copyProtection($currentPage, true); } if (isset($dataPost['inheritBackendAccess']) && $dataPost['inheritBackendAccess'] == 'on') { $reload = true; $page->copyProtection($currentPage, false); } if (isset($dataPost['inheritSkin']) && $dataPost['inheritSkin'] == 'on') { $currentPage->setSkin($page->getSkin()); } if (isset($dataPost['inheritCustomContent']) && $dataPost['inheritCustomContent'] == 'on') { $currentPage->setCustomContent($page->getCustomContent()); } if (isset($dataPost['inheritCssName']) && $dataPost['inheritCssName'] == 'on') { $currentPage->setCssName($page->getCssName()); } if (isset($dataPost['inheritCssNavName']) && $dataPost['inheritCssNavName'] == 'on') { $currentPage->setCssNavName($page->getCssNavName()); } if (isset($dataPost['inheritCaching']) && $dataPost['inheritCaching'] == 'on') { $currentPage->setCaching($page->getCaching()); } $this->em->persist($currentPage); } } $this->em->flush(); // bug fix #2279 // could not save alias after running $this->em->clear() // Aliases are only updated in the editing mode. if (!empty($pageArray)) { // Only users with publish rights can create aliases. if (\Permission::checkAccess(115, 'static', true) && \Permission::checkAccess(78, 'static', true)) { // Aliases are updated after persist. $data = array(); $data['alias'] = $pageArray['alias']; $aliases = $page->getAliases(); $page->updateFromArray($data); if ($aliases != $page->getAliases()) { $reload = true; } } else { // Users without permission shouldn't see the aliasses anyway //$this->messages[] = $_CORELANG['TXT_CORE_ALIAS_CREATION_DENIED']; } } // this fixes log version number skipping $this->em->clear(); $logs = $this->logRepo->getLogEntries($page); $this->em->persist($logs[0]); if ($updatingDraft) { $data = $logs[1]->getData(); if (!empty($action) && $draftUpdateLog) { $data = $draftUpdateLog->getData(); } $data['editingStatus'] = 'hasDraft'; if ($action == 'publish' && !\Permission::checkAccess(78, 'static', true)) { $data['editingStatus'] = 'hasDraftWaiting'; } switch ($action) { case 'activate': $data['active'] = true; break; case 'deactivate': $data['active'] = false; break; case 'show': $data['display'] = true; break; case 'hide': $data['display'] = false; break; case 'protect': $data['protection'] = $data['protection'] | FRONTEND_PROTECTION; break; case 'unprotect': $data['protection'] = $data['protection'] & ~FRONTEND_PROTECTION; break; case 'lock': $data['protection'] = $data['protection'] | BACKEND_PROTECTION; break; case 'unlock': $data['protection'] = $data['protection'] & ~BACKEND_PROTECTION; break; } $logs[1]->setData($data); if (!empty($action) && $action != 'publish') { $data = $logs[0]->getData(); if ($liveUpdateLog) { $data = $liveUpdateLog->getData(); } switch ($action) { case 'activate': $data['active'] = true; break; case 'deactivate': $data['active'] = false; break; case 'show': $data['display'] = true; break; case 'hide': $data['display'] = false; break; case 'protect': $data['protection'] = $data['protection'] | FRONTEND_PROTECTION; break; case 'unprotect': $data['protection'] = $data['protection'] & ~FRONTEND_PROTECTION; break; case 'lock': $data['protection'] = $data['protection'] | BACKEND_PROTECTION; break; case 'unlock': $data['protection'] = $data['protection'] & ~BACKEND_PROTECTION; break; } $logs[0]->setData($data); } $this->em->persist($logs[0]); $this->em->persist($logs[1]); $this->em->flush(); } // get version // if it is a draft, don't take the last one $version = $page->getVersion()->getVersion(); if ($page->isDraft()) { $version--; } return array('reload' => $reload, 'id' => $page->getId(), 'version' => $version, 'node' => $page->getNode()->getId(), 'lang' => \FWLanguage::getLanguageCodeById($page->getLang())); }
/** * Loads pages from module repository * @param int $moduleId the module id * @return boolean True on success, false if no pages found in repo */ protected function loadPagesFromModuleRepository($moduleId) { $cx = \Env::get('cx'); $em = $cx->getDb()->getEntityManager(); $id = $moduleId; $nodeRepo = $em->getRepository('\\Cx\\Core\\ContentManager\\Model\\Entity\\Node'); $pageRepo = $em->getRepository('\\Cx\\Core\\ContentManager\\Model\\Entity\\Page'); $module_name = $this->componentName; // get content from repo $query = ' SELECT `id`, `moduleid`, `content`, `title`, `cmd`, `expertmode`, `parid`, `displaystatus`, `username`, `displayorder` FROM `' . DBPREFIX . 'module_repository` WHERE `moduleid` = ' . $id . ' ORDER BY `parid` ASC '; $objResult = $cx->getDb()->getAdoDb()->query($query); if ($objResult->EOF) { // no pages return false; } $paridarray = array(); while (!$objResult->EOF) { // define parent node $root = false; if (isset($paridarray[$objResult->fields['parid']])) { $parcat = $paridarray[$objResult->fields['parid']]; } else { $root = true; $parcat = $nodeRepo->getRoot(); } // create node $newnode = new \Cx\Core\ContentManager\Model\Entity\Node(); $newnode->setParent($parcat); // replace root node by parent! $em->persist($newnode); $em->flush(); $nodeRepo->moveDown($newnode, true); // move to the end of this level $paridarray[$objResult->fields['id']] = $newnode; // add content to default lang // add content to all langs without fallback // link content to all langs with fallback foreach (\FWLanguage::getActiveFrontendLanguages() as $lang) { if ($lang['is_default'] === 'true' || $lang['fallback'] == null) { $page = $pageRepo->createPage($newnode, $lang['id'], $objResult->fields['title'], \Cx\Core\ContentManager\Model\Entity\Page::TYPE_APPLICATION, $module_name, $objResult->fields['cmd'], !$root && $objResult->fields['displaystatus'], $objResult->fields['content']); } else { $page = $pageRepo->createPage($newnode, $lang['id'], $objResult->fields['title'], \Cx\Core\ContentManager\Model\Entity\Page::TYPE_FALLBACK, $module_name, $objResult->fields['cmd'], !$root && $objResult->fields['displaystatus'], ''); } $em->persist($page); } $em->flush(); $objResult->MoveNext(); } return true; }
/** * Converts a tree level to JSON * @param Cx\Core\ContentManager\Model\Entity\Node $root Root node of the current level * @param Array $logs List of all logs (used to get the username) * @return String JSON data */ private function tree_to_jstree_array($root, $flat = false, &$actions = null) { $fallback_langs = $this->fallbacks; $sorted_tree = array(); foreach ($root->getChildren() as $node) { $sorted_tree[$node->getLft()] = $node; } ksort($sorted_tree); // get open nodes $open_nodes = array(); if (isset($_COOKIE['jstree_open'])) { $tmp_open_nodes = explode(',', $_COOKIE['jstree_open']); foreach ($tmp_open_nodes as $node) { $node_id = substr($node, 6); $open_nodes[$node_id] = true; } } $output = array(); $tree = array(); $nodeLevels = array(); foreach ($sorted_tree as $node) { $data = array(); $metadata = array(); $children = array(); // if this node is expanded (toggled) $toggled = isset($open_nodes[$node->getId()]) && $open_nodes[$node->getId()]; if (!$flat || $toggled) { $children = $this->tree_to_jstree_array($node, $flat); } $last_resort = 0; $numberOfPages = 0; /** * I (<*****@*****.**> cannot recall the reason why to * get alias pages too but I think there was one (probably not a nice one) * @todo Write unit tests for CM then try $node->getPages() * if the above is done do the following too * @todo Replace $numberOfPages by $pages = $node->getPages(), then just count them */ foreach ($node->getPages(false, true) as $page) { // don't display aliases in cm's tree if ($page->getType() == \Cx\Core\ContentManager\Model\Entity\Page::TYPE_ALIAS) { continue 2; } $numberOfPages++; $user = $page->getUpdatedBy(); $data[\FWLanguage::getLanguageCodeById($page->getLang())] = array('language' => \FWLanguage::getLanguageCodeById($page->getLang()), 'title' => $page->getTitle(), 'attr' => array('id' => $page->getId(), 'data-href' => json_encode(array('slug' => $page->getSlug(), 'path' => $page->getPath(), 'module' => $page->getModule() . ' ' . $page->getCmd(), 'lastupdate' => $page->getUpdatedAt()->format('d.m.Y H:i'), 'level' => $page->getNode()->getLvl(), 'user' => $user)), 'frontend_access_id' => $page->getFrontendAccessId(), 'backend_access_id' => $page->getBackendAccessId(), 'protected' => $page->isFrontendProtected(), 'locked' => $page->isBackendProtected())); $editingStatus = $page->getEditingStatus(); if ($page->isActive()) { if ($editingStatus == 'hasDraft') { $publishingStatus = 'published draft'; } else { if ($editingStatus == 'hasDraftWaiting') { $publishingStatus = 'published draft waiting'; } else { $publishingStatus = 'published'; } } } else { if ($editingStatus == 'hasDraft') { $publishingStatus = 'unpublished draft'; } else { if ($editingStatus == 'hasDraftWaiting') { $publishingStatus = 'unpublished draft waiting'; } else { $publishingStatus = 'unpublished'; } } } if ($page->isBackendProtected() && !\Permission::checkAccess($page->getBackendAccessId(), 'dynamic', true)) { $publishingStatus .= ' locked'; } $metadata[$page->getId()] = array('visibility' => $page->getStatus(), 'publishing' => $publishingStatus); $last_resort = \FWLanguage::getLanguageCodeById($page->getLang()); } if ($numberOfPages == 0) { continue; } foreach ($fallback_langs as $lang => $fallback) { // fallback can be false, array_key_exists does not like booleans if (!$fallback) { $fallback = null; } if (!array_key_exists($lang, $data) && array_key_exists($fallback, $data)) { $data[$lang]['language'] = $lang; $data[$lang]['title'] = $data[$fallback]['title']; if ($data[$fallback]['attr']['id'] == 'broken') { $data[$lang]['attr']['id'] = 'broken'; } else { $data[$lang]['attr']['id'] = '0'; } } else { if (!array_key_exists($lang, $data)) { $data[$lang]['language'] = $lang; if (array_key_exists($last_resort, $data)) { $data[$lang]['title'] = $data[$last_resort]['title']; $data[$lang]['attr']['id'] = '0'; } else { $data[$lang]['title'] = 'No Title'; $data[$lang]['attr']['id'] = 'broken'; } } } $metadata[0] = array('visibility' => 'active', 'publishing' => 'unpublished'); $metadata['broken'] = array('visibility' => 'broken', 'publishing' => 'unpublished'); } $state = array(); if (count($node->getChildren()) > 0) { if ($toggled) { $state = array('state' => 'open'); } else { $state = array('state' => 'closed'); } } $nodeLevels[$node->getId()] = $node->getLvl(); if (isset($children['nodeLevels'])) { $nodeLevels = $nodeLevels + $children['nodeLevels']; } $tree[] = array_merge(array('attr' => array('id' => 'node_' . $node->getId(), 'rel_id' => $node->getId()), 'data' => array_values($data), 'children' => isset($children['tree']) ? $children['tree'] : array(), 'metadata' => $metadata), $state); } $output['tree'] = $tree; $output['nodeLevels'] = $nodeLevels; $output['hasHome'] = array(); foreach (\FWLanguage::getActiveFrontendLanguages() as $lang) { $page = $this->pageRepo->findOneBy(array('module' => 'Home', 'cmd' => '', 'lang' => $lang['id'])); $output['hasHome'][$lang['lang']] = $page ? $page->getId() : false; } return $output; }
function _handleContentPage($formId = 0) { if (!$formId) { return; } $objDatabase = \Env::get('db'); $objFWUser = \FWUser::getFWUserObject(); $pageRepo = $this->em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Page'); $pages = array(); foreach ($pageRepo->findBy(array('module' => 'Contact', 'cmd' => $formId)) as $page) { if ($page) { $pages[$page->getLang()] = $page; } } $frontendLangIds = array_keys(\FWLanguage::getActiveFrontendLanguages()); $selectedLangIds = array_keys($this->arrForms[$formId]['lang']); // filter out only those languages that are active in the frontent. // we do want to create/update only the content pages of those languages. $selectedLangIds = array_intersect($selectedLangIds, $frontendLangIds); // Maybe there will already be a fallback page if we activate a new language. // So we use the fallback page to prevent the creation of a new page. foreach ($selectedLangIds as $selectedLangId) { if (!isset($pages[$selectedLangId])) { $fallbackPage = $pageRepo->findOneByModuleCmdLang('Contact', $formId, $selectedLangId); if (!empty($fallbackPage)) { $pages[$selectedLangId] = $fallbackPage; } } } $presentLangIds = array_keys($pages); // define which languages of the content pages have to be updated // $updateLangIds = array_intersect($selectedLangIds, $presentLangIds); // define which languages of the content pages have to be created // $newLangIds = array_diff($selectedLangIds, $updateLangIds); // define which languages of the content pages have to be removed $deleteLangIds = array_diff($presentLangIds, $selectedLangIds); $langIdsOfAssociatedPagesOfPageNode = array(); foreach ($presentLangIds as $langId) { $langIdsOfAssociatedPagesOfPageNode[$pages[$langId]->getId()] = array_keys($pages[$langId]->getNode()->getPagesByLang()); } foreach ($selectedLangIds as $langId) { $page = null; $node = null; if (isset($pages[$langId])) { // Content page already exists, so we will update this very page $page = $pages[$langId]; \DBG::msg("Page in lang {$langId} exists -> Update()"); } else { // Content page of the frontend language $langId doesn't exist yet. // Therefore we will either have to create a new node or we will have to // find a node to which we can attach our new page. // We will prefer the latter. \DBG::msg("Page doesn't exist in lang {$langId} -> Create()"); // Check if there exists already a content page to who's node we could attach our new page if (count($pages)) { if ($langId != \FWLanguage::getDefaultLangId() && isset($pages[\FWLanguage::getDefaultLangId()]) && !in_array($langId, $langIdsOfAssociatedPagesOfPageNode[$pages[\FWLanguage::getDefaultLangId()]->getId()])) { // if that is the case, we will attach our new page to this node $node = $pages[\FWLanguage::getDefaultLangId()]->getNode(); \DBG::msg("Page does exists in the default language"); \DBG::msg("Attach page to node {$node->getId()} of the page of the lang " . \FWLanguage::getDefaultLangId()); } else { foreach ($pages as $langIdOfPage => $page) { // Skip the page of the default frontend language - we just checked this page's node before if ($langIdOfPage == \FWLanguage::getDefaultLangId()) { continue; } // Check if there exists a node of the pages in the other languages that don't // have an associated page in the language we're going to create a new page if (!in_array($langId, $langIdsOfAssociatedPagesOfPageNode[$pages[$langIdOfPage]->getId()])) { $node = $pages[$langIdOfPage]->getNode(); \DBG::msg("Attach page to node {$node->getId()} of the page of the lang {$langIdOfPage}"); break; } } } } if ($node === null) { \DBG::msg("No node found -> Create()"); $root = $this->em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Node')->getRoot(); // Create a new node $node = new \Cx\Core\ContentManager\Model\Entity\Node(); $node->setParent($root); $this->em->persist($node); } // Create a new Page $page = new \Cx\Core\ContentManager\Model\Entity\Page(); $page->setNode($node); // Set the following attributes only on new pages $page->setTitle($this->arrForms[$formId]['lang'][$langId]['name']); $page->setDisplay(false); $page->setActive(true); $page->setLang($langId); } $page->setType(\Cx\Core\ContentManager\Model\Entity\Page::TYPE_APPLICATION); $page->setModule('Contact'); $page->setCmd($formId); $content = $page->getContent(); //if the content is missing the placeholder {APPLICATION_DATA}, append the placeholder to the page's content. if (!preg_match_all('/\\{APPLICATION_DATA\\}/xi', $content, $matches)) { $content .= '{APPLICATION_DATA}'; } $page->setContent($content); $page->setSourceMode(true); $this->em->persist($page); // Remember newly created pages. We will need this for the creating of other new pages above in this method. if (!isset($pages[$langId])) { $pages[$langId] = $page; $langIdsOfAssociatedPagesOfPageNode[$pages[$langId]->getId()] = array($langId); } } //$this->em->flush(); // Delete those content pages of those languages that had been deactivated foreach ($deleteLangIds as $langId) { $page = $pages[$langId]; $node = $page->getNode(); \DBG::msg("Delete page: {$langId}"); //DBG::dump(count($node->getPages())); $this->em->remove($page); //$this->em->persist($page); //$this->em->flush(); //DBG::dump(count($node->getPages())); // TODO: Delete empty nodes } $this->em->flush(); }