function updateSubTreePath($updateParent = true, $nodeMove = false) { $changeCount = 0; $nodeID = $this->attribute('node_id'); $parentNodeID = $this->attribute('parent_node_id'); // Avoid recursion due to database inconsistencies if ($nodeID === $parentNodeID) { eZDebug::writeError("Parent node ID equals node ID for node: {$nodeID}. The node cannot be a parent of itself!", __METHOD__); return false; } // Only set name if current node is not the content root $ini = eZINI::instance('content.ini'); $contentRootID = $ini->variable('NodeSettings', 'RootNode'); $obj = $this->object(); $alwaysMask = $obj->attribute('language_mask') & 1; $languages = $obj->allLanguages(); $nameList = array(); $initialLanguageID = $obj->attribute('initial_language_id'); $pathIdentificationName = false; foreach ($languages as $language) { $nodeName = ''; if ($nodeID != $contentRootID) { $objClass = $obj->attribute('content_class'); $nodeName = $objClass->urlAliasName($obj, false, $language->attribute('locale')); $nodeName = eZURLAliasFilter::processFilters($nodeName, $language, $this); $nodeName = eZURLAliasML::convertToAlias($nodeName, 'node_' . $nodeID); $nodeName = $this->adjustPathElement($nodeName, $nodeMove); // Compatibility mode: // Store name for the 'path_identification_string' column. if ($initialLanguageID == $language->attribute('id')) { $pathIdentificationName = eZURLAliasML::convertToAliasCompat($nodeName, 'node_' . $nodeID); } } $nameList[] = array('text' => $nodeName, 'language' => $language); } $parentActionName = "eznode"; $parentActionValue = $parentNodeID; $parentElementID = false; $existingElements = eZURLAliasML::fetchByAction("eznode", $nodeID); $existingElementID = null; if (count($existingElements) > 0) { $existingElementID = $existingElements[0]->attribute('id'); $parentElementID = $existingElements[0]->attribute('parent'); } // If we have parent element it means the node is already published // and we have to see if it has been moved if ($parentNodeID != 1 and $updateParent) { $parents = eZURLAliasML::fetchByAction("eznode", $parentNodeID); if (count($parents) == 0) { $parentNode = $this->fetchParent(); if (!$parentNode) { return false; } $result = $parentNode->updateSubTreePath(); if (!$result) { return false; } $parents = eZURLAliasML::fetchByAction($parentActionName, $parentActionValue); if (count($parents) == 0) { return false; } $oldParentElementID = $parentElementID; foreach ($parents as $paren) { $parentElementID = 0; if ($paren->attribute('text') != '') { $parentElementID = (int) $paren->attribute('link'); break; } } } else { $oldParentElementID = $parentElementID; $parentElementID = 0; foreach ($parents as $paren) { if ($paren->attribute('text') != '') { $parentElementID = (int) $paren->attribute('link'); break; } } } } else { } $this->updatePathIdentificationString($pathIdentificationName); $languageID = $obj->attribute('initial_language_id'); $cleanup = false; foreach ($nameList as $nameEntry) { $text = $nameEntry['text']; $language = $nameEntry['language']; $result = eZURLAliasML::storePath($text, 'eznode:' . $nodeID, $language, false, $alwaysMask, $parentElementID, $cleanup); if ($result['status'] === true) { $changeCount++; } } return $changeCount; }
$existingElements = $filter->fetchAll(); // TODO: add error handling when $existingElements is empty if (count($existingElements) > 0) { $parentID = (int) $existingElements[0]->attribute('parent'); $linkID = (int) $existingElements[0]->attribute('id'); } if ($parentIsRoot) { $parentID = 0; // Start from the top } $mask = $language->attribute('id'); $obj = $node->object(); $alwaysMask = $obj->attribute('language_mask') & 1; $mask |= $alwaysMask; $origAliasText = $aliasText; $result = eZURLAliasML::storePath($aliasText, 'eznode:' . $node->attribute('node_id'), $language, $linkID, $alwaysMask, $parentID, true, false, false, $aliasRedirects); if ($result['status'] === eZURLAliasML::LINK_ALREADY_TAKEN) { $lastElements = eZURLAliasML::fetchByPath($result['path']); if (count($lastElements) > 0) { $lastElement = $lastElements[0]; $infoCode = "feedback-alias-exists"; $infoData['new_alias'] = $aliasText; $infoData['url'] = $lastElement->attribute('path'); $infoData['action_url'] = $lastElement->actionURL(); $aliasText = $origAliasText; } } else { if ($result['status'] === true) { $aliasText = $result['path']; if (strcmp($aliasText, $origAliasText) != 0) { $infoCode = "feedback-alias-cleanup";
// Referenced url does not exist logError("The referenced path '{$toPath}' can not be found among the new URL alias entries, url entry ID is " . $row['id']); list($column, $counter) = displayProgress('E', $urlImportStartTime, $counter, $urlCount, $column); continue; } // Fetch the ID of the element to redirect to. $linkID = $elements[0]->attribute('id'); $action = $elements[0]->attribute('action'); if ($action == 'nop:') { // Cannot redirect to nops logError("The referenced path '{$toPath}' with ID " . $elements[0]->attribute('id') . " is a 'nop:' entry and cannot be used"); list($column, $counter) = displayProgress('E', $urlImportStartTime, $counter, $urlCount, $column); continue; } $alwaysAvailable = $elements[0]->attribute('lang_mask') & 1; $res = eZURLAliasML::storePath($fromPath, $action, false, $linkID, $alwaysAvailable); if (!$res || $res['status'] == 3) { logError("The wildcard url " . var_export($fromPath, true) . " cannot be created since the path already exists"); list($column, $counter) = displayProgress('s', $urlImportStartTime, $counter, $urlCount, $column); continue; } if (!$res || $res['status'] !== true) { logStoreError($res, "eZURLAliasML::storePath", array($fromPath, $action, false, $linkID, $alwaysAvailable)); list($column, $counter) = displayProgress('E', $urlImportStartTime, $counter, $urlCount, $column); continue; } logStore($res, "eZURLAliasML::storePath", array($fromPath, $action, false, $linkID, $alwaysAvailable)); $result = '.'; verifyData($result, $source, $row['id']); list($column, $counter) = displayProgress($result, $urlImportStartTime, $counter, $urlCount, $column); }
if (!$action) { $elements = eZURLAliasML::fetchByPath($aliasDestinationText); if (count($elements) > 0) { $action = $elements[0]->attribute('action'); $linkID = $elements[0]->attribute('link'); } } if (!$action) { $infoCode = "error-action-invalid"; $infoData['aliasText'] = $aliasDestinationText; } else { $origAliasText = $aliasText; if ($linkID == 0) { $linkID = true; } $result = eZURLAliasML::storePath($aliasText, $action, $language, $linkID, $isAlwaysAvailable, $parentID, true, false, false, $aliasRedirects); if ($result['status'] === eZURLAliasML::LINK_ALREADY_TAKEN) { $lastElements = eZURLAliasML::fetchByPath($result['path']); if (count($lastElements) > 0) { $lastElement = $lastElements[0]; $infoCode = "feedback-alias-exists"; $infoData['new_alias'] = $aliasText; $infoData['url'] = $lastElement->attribute('path'); $infoData['action_url'] = $lastElement->actionURL(); $aliasText = $origAliasText; } } else { if ($result['status'] === true) { $aliasText = $result['path']; if (strcmp($aliasText, $origAliasText) != 0) { $infoCode = "feedback-alias-cleanup";
/** * @see http://issues.ez.no/19062 * @group issue19062 * @covers eZURLAliasML::translate */ public function testTranslateWildcardNopUri() { $folder = new ezpObject('folder', 2); $folder->name = 'foo'; $folder->publish(); // By creating following URL alias, "test/single-page" will be registered as a NOP URI segment $uriFirstSegment = 'test19062'; $uriWildcard = "{$uriFirstSegment}/single-page"; $res = eZURLAliasML::storePath("{$uriWildcard}/article.html", "eznode:{$folder->mainNode->node_id}", $this->englishLanguage, 0, true); $wildcard = eZURLWildcardTest::createWildcard($uriWildcard, 'foo', eZURLWildcard::TYPE_FORWARD); // Translating the wildcard URL should return false in order to be then translated by eZURLWildcard in index.php self::assertFalse(eZURLAliasML::translate($uriWildcard)); // Here no wildcard and test19062 should be a nop segment (points to nothing. // Default behaviour is to return true and redirect to root ("/") self::assertTrue(eZURLAliasML::translate($uriFirstSegment)); $folder->remove(); $wildcard->remove(); }
/** * Test that store path does not reparent children of entries with same action * if they are custom aliases */ public function testStorePathReparentAliasEntries() { // Create a real folder $r = mt_rand(); $theRealFolder = new ezpObject("folder", 2); $theRealFolder->name = __FUNCTION__ . $r; $theRealFolder->publish(); // Create a real article in real folder $myNode = new ezpObject("article", $theRealFolder->mainNode->node_id); $myNode->title = "MyNode"; $myNode->publish(); // We fetch the url path element of our real folder entry, // in order to create an alias to it $realFolderUrl = eZURLAliasML::fetchByAction("eznode", $theRealFolder->mainNode->node_id); $realFolderUrlId = $realFolderUrl[0]->attribute('id'); $myNodeUrl = eZURLAliasML::fetchByAction("eznode", $myNode->mainNode->node_id); $myNodeUrlId = $myNodeUrl[0]->attribute('id'); // We create a custom url alias for the real folder under $realFolderAliasPath // Note the first path element will be a virtual nop: $realFolderAliasPath = "VirtualPath/AliasToTheRealFolder{$r}"; $action = "eznode:" . $theRealFolder->mainNode->node_id; $realFolderAlias = eZURLAliasML::storePath($realFolderAliasPath, $action, false, $realFolderUrlId); $realFolderAliasId = $realFolderAlias['element']->attribute('id'); /* We create a custom url alias for MyNode, which is located underneath the alias for real folder, in the url path \ |-- TheRealFolder (node a) | `-- MyNode (node b) `-- VirtualPath (nop:) `-- AliasToTheRealFolder (node a) `-- AliasToMyNode (node b) */ // $myNodeAliasPath = "{$realFolderAliasPath}/AliasToMyNode{$r}"; $myNodeAliasPath = "AliasToMyNode{$r}"; $myNodeAction = "eznode:" . $myNode->mainNode->node_id; $myNodeAlias = eZURLAliasML::storePath($myNodeAliasPath, $myNodeAction, false, $myNodeUrlId, false, $realFolderAliasId); $myNodeAliasOriginalParent = $myNodeAlias['element']->attribute('parent'); // We republish the real folder, not strictly necessary to change the // but it is more illustrative. $theRealFolder->name = __FUNCTION__ . $r . "Renamed"; $theRealFolder->publish(); // Assert that our alias to MyNode was indeed placed underneath $realFolderAliasPath self::assertEquals($realFolderAliasId, $myNodeAliasOriginalParent); $db = eZDB::instance(); $q = self::buildSql(array($myNode->mainNode->node_id), false, array('is_alias' => 1, 'is_original' => 1)); $myNodeAliasPostChange = $db->arrayQuery($q); $myNodeAliasPostChangeParent = $myNodeAliasPostChange[0]['parent']; // Make sure the the alias to MyNode have not been moved in the url path // after publishing the parent of the real node. self::assertEquals($myNodeAliasOriginalParent, $myNodeAliasPostChangeParent, "Parent have custom url alias have been changed inadvertently."); }
/** * Code taken from content/urlalias module */ static function addUrlALias($node, $aliasText, $languageId, $aliasRedirects = false, $parentIsRoot = false) { $infoCode = 'no-errors'; $language = eZContentLanguage::fetch($languageId); if (!$language) { $infoCode = "error-invalid-language"; $infoData['language'] = $languageCode; } else { $parentID = 0; $linkID = 0; $filter = new eZURLAliasQuery(); $filter->actions = array('eznode:' . $node->attribute('node_id')); $filter->type = 'name'; $filter->limit = false; $existingElements = $filter->fetchAll(); // TODO: add error handling when $existingElements is empty if (count($existingElements) > 0) { $parentID = (int) $existingElements[0]->attribute('parent'); $linkID = (int) $existingElements[0]->attribute('id'); } if ($parentIsRoot) { $parentID = 0; // Start from the top } $mask = $language->attribute('id'); $obj = $node->object(); $alwaysMask = $obj->attribute('language_mask') & 1; $mask |= $alwaysMask; $origAliasText = $aliasText; $result = eZURLAliasML::storePath($aliasText, 'eznode:' . $node->attribute('node_id'), $language, $linkID, $alwaysMask, $parentID, true, false, false, $aliasRedirects); if ($result['status'] === eZURLAliasML::LINK_ALREADY_TAKEN) { $lastElements = eZURLAliasML::fetchByPath($result['path']); if (count($lastElements) > 0) { $lastElement = $lastElements[0]; $infoCode = "feedback-alias-exists"; $infoData['new_alias'] = $aliasText; $infoData['url'] = $lastElement->attribute('path'); $infoData['action_url'] = $lastElement->actionURL(); //$aliasText = $origAliasText; } } else { if ($result['status'] === true) { $aliasText = $result['path']; if (strcmp($aliasText, $origAliasText) != 0) { $infoCode = "feedback-alias-cleanup"; $infoData['orig_alias'] = $origAliasText; $infoData['new_alias'] = $aliasText; } else { $infoData['new_alias'] = $aliasText; } if ($infoCode == 'no-errors') { $infoCode = "feedback-alias-created"; } //$aliasText = false; } } } return array('infoCode' => $infoCode, 'infoData' => $infoData); }