function install($package, $installType, $parameters, $name, $os, $filename, $subdirectory, $content, &$installParameters, &$installData) { $serializedNameListNode = $content->getElementsByTagName('serialized-name-list')->item(0); $serializedNameList = $serializedNameListNode ? $serializedNameListNode->textContent : false; $classNameList = new eZContentClassNameList($serializedNameList); if ($classNameList->isEmpty()) { $classNameList->initFromString($content->getElementsByTagName('name')->item(0)->textContent); // for backward compatibility( <= 3.8 ) } $classNameList->validate(); $serializedDescriptionListNode = $content->getElementsByTagName('serialized-description-list')->item(0); $serializedDescriptionList = $serializedDescriptionListNode ? $serializedDescriptionListNode->textContent : false; $classDescriptionList = new eZSerializedObjectNameList($serializedDescriptionList); $classIdentifier = $content->getElementsByTagName('identifier')->item(0)->textContent; $classRemoteID = $content->getElementsByTagName('remote-id')->item(0)->textContent; $classObjectNamePattern = $content->getElementsByTagName('object-name-pattern')->item(0)->textContent; $classURLAliasPattern = is_object($content->getElementsByTagName('url-alias-pattern')->item(0)) ? $content->getElementsByTagName('url-alias-pattern')->item(0)->textContent : null; $classIsContainer = $content->getAttribute('is-container'); if ($classIsContainer !== false) { $classIsContainer = $classIsContainer == 'true' ? 1 : 0; } $classRemoteNode = $content->getElementsByTagName('remote')->item(0); $classID = $classRemoteNode->getElementsByTagName('id')->item(0)->textContent; $classGroupsNode = $classRemoteNode->getElementsByTagName('groups')->item(0); $classCreated = $classRemoteNode->getElementsByTagName('created')->item(0)->textContent; $classModified = $classRemoteNode->getElementsByTagName('modified')->item(0)->textContent; $classCreatorNode = $classRemoteNode->getElementsByTagName('creator')->item(0); $classModifierNode = $classRemoteNode->getElementsByTagName('modifier')->item(0); $classAttributesNode = $content->getElementsByTagName('attributes')->item(0); $dateTime = time(); $classCreated = $dateTime; $classModified = $dateTime; $userID = false; if (isset($installParameters['user_id'])) { $userID = $installParameters['user_id']; } $class = eZContentClass::fetchByRemoteID($classRemoteID); if ($class) { $className = $class->name(); $description = ezpI18n::tr('kernel/package', "Class '%classname' already exists.", false, array('%classname' => $className)); $choosenAction = $this->errorChoosenAction(self::ERROR_EXISTS, $installParameters, $description, $this->HandlerType); switch ($choosenAction) { case eZPackage::NON_INTERACTIVE: case self::ACTION_REPLACE: if (eZContentClassOperations::remove($class->attribute('id')) == false) { eZDebug::writeWarning("Unable to remove class '{$className}'."); return true; } eZDebug::writeNotice("Class '{$className}' will be replaced.", 'eZContentClassPackageHandler'); break; case self::ACTION_SKIP: return true; case self::ACTION_NEW: $class->setAttribute('remote_id', eZRemoteIdUtility::generate('class')); $class->store(); $classNameList->appendGroupName(" (imported)"); break; default: $installParameters['error'] = array('error_code' => self::ERROR_EXISTS, 'element_id' => $classRemoteID, 'description' => $description, 'actions' => array()); if ($class->isRemovable()) { $errorMsg = ezpI18n::tr('kernel/package', "Replace existing class"); $objectsCount = eZContentObject::fetchSameClassListCount($class->attribute('id')); if ($objectsCount) { $errorMsg .= ' ' . ezpI18n::tr('kernel/package', "(Warning! {$objectsCount} content object(s) and their sub-items will be removed)"); } $installParameters['error']['actions'][self::ACTION_REPLACE] = $errorMsg; } $installParameters['error']['actions'][self::ACTION_SKIP] = ezpI18n::tr('kernel/package', 'Skip installing this class'); $installParameters['error']['actions'][self::ACTION_NEW] = ezpI18n::tr('kernel/package', 'Keep existing and create a new one'); return false; } } unset($class); // Try to create a unique class identifier $currentClassIdentifier = $classIdentifier; $unique = false; while (!$unique) { $classList = eZContentClass::fetchByIdentifier($currentClassIdentifier); if ($classList) { // "increment" class identifier if (preg_match('/^(.*)_(\\d+)$/', $currentClassIdentifier, $matches)) { $currentClassIdentifier = $matches[1] . '_' . ($matches[2] + 1); } else { $currentClassIdentifier = $currentClassIdentifier . '_1'; } } else { $unique = true; } unset($classList); } $classIdentifier = $currentClassIdentifier; $values = array('version' => 0, 'serialized_name_list' => $classNameList->serializeNames(), 'serialized_description_list' => $classDescriptionList->serializeNames(), 'create_lang_if_not_exist' => true, 'identifier' => $classIdentifier, 'remote_id' => $classRemoteID, 'contentobject_name' => $classObjectNamePattern, 'url_alias_name' => $classURLAliasPattern, 'is_container' => $classIsContainer, 'created' => $classCreated, 'modified' => $classModified); if ($content->hasAttribute('sort-field')) { $values['sort_field'] = eZContentObjectTreeNode::sortFieldID($content->getAttribute('sort-field')); } else { eZDebug::writeNotice('The sort field was not specified in the content class package. ' . 'This property is exported and imported since eZ Publish 4.0.2', __METHOD__); } if ($content->hasAttribute('sort-order')) { $values['sort_order'] = $content->getAttribute('sort-order'); } else { eZDebug::writeNotice('The sort order was not specified in the content class package. ' . 'This property is exported and imported since eZ Publish 4.0.2', __METHOD__); } if ($content->hasAttribute('always-available')) { $values['always_available'] = $content->getAttribute('always-available') === 'true' ? 1 : 0; } else { eZDebug::writeNotice('The default object availability was not specified in the content class package. ' . 'This property is exported and imported since eZ Publish 4.0.2', __METHOD__); } // create class $class = eZContentClass::create($userID, $values); $class->store(); $classID = $class->attribute('id'); if (!isset($installData['classid_list'])) { $installData['classid_list'] = array(); } if (!isset($installData['classid_map'])) { $installData['classid_map'] = array(); } $installData['classid_list'][] = $class->attribute('id'); $installData['classid_map'][$classID] = $class->attribute('id'); // create class attributes $classAttributeList = $classAttributesNode->getElementsByTagName('attribute'); foreach ($classAttributeList as $classAttributeNode) { $isNotSupported = strtolower($classAttributeNode->getAttribute('unsupported')) == 'true'; if ($isNotSupported) { continue; } $attributeDatatype = $classAttributeNode->getAttribute('datatype'); $attributeIsRequired = strtolower($classAttributeNode->getAttribute('required')) == 'true'; $attributeIsSearchable = strtolower($classAttributeNode->getAttribute('searchable')) == 'true'; $attributeIsInformationCollector = strtolower($classAttributeNode->getAttribute('information-collector')) == 'true'; $attributeIsTranslatable = strtolower($classAttributeNode->getAttribute('translatable')) == 'true'; $attributeSerializedNameListNode = $classAttributeNode->getElementsByTagName('serialized-name-list')->item(0); $attributeSerializedNameListContent = $attributeSerializedNameListNode ? $attributeSerializedNameListNode->textContent : false; $attributeSerializedNameList = new eZSerializedObjectNameList($attributeSerializedNameListContent); if ($attributeSerializedNameList->isEmpty()) { $attributeSerializedNameList->initFromString($classAttributeNode->getElementsByTagName('name')->item(0)->textContent); } // for backward compatibility( <= 3.8 ) $attributeSerializedNameList->validate(); $attributeSerializedDescriptionListNode = $classAttributeNode->getElementsByTagName('serialized-description-list')->item(0); $attributeSerializedDescriptionListContent = $attributeSerializedDescriptionListNode ? $attributeSerializedDescriptionListNode->textContent : false; $attributeSerializedDescriptionList = new eZSerializedObjectNameList($attributeSerializedDescriptionListContent); $attributeCategoryNode = $classAttributeNode->getElementsByTagName('category')->item(0); $attributeCategory = $attributeCategoryNode ? $attributeCategoryNode->textContent : ''; $attributeSerializedDataTextNode = $classAttributeNode->getElementsByTagName('serialized-description-text')->item(0); $attributeSerializedDataTextContent = $attributeSerializedDataTextNode ? $attributeSerializedDataTextNode->textContent : false; $attributeSerializedDataText = new eZSerializedObjectNameList($attributeSerializedDataTextContent); $attributeIdentifier = $classAttributeNode->getElementsByTagName('identifier')->item(0)->textContent; $attributePlacement = $classAttributeNode->getElementsByTagName('placement')->item(0)->textContent; $attributeDatatypeParameterNode = $classAttributeNode->getElementsByTagName('datatype-parameters')->item(0); $classAttribute = $class->fetchAttributeByIdentifier($attributeIdentifier); if (!$classAttribute) { $classAttribute = eZContentClassAttribute::create($class->attribute('id'), $attributeDatatype, array('version' => 0, 'identifier' => $attributeIdentifier, 'serialized_name_list' => $attributeSerializedNameList->serializeNames(), 'serialized_description_list' => $attributeSerializedDescriptionList->serializeNames(), 'category' => $attributeCategory, 'serialized_data_text' => $attributeSerializedDataText->serializeNames(), 'is_required' => $attributeIsRequired, 'is_searchable' => $attributeIsSearchable, 'is_information_collector' => $attributeIsInformationCollector, 'can_translate' => $attributeIsTranslatable, 'placement' => $attributePlacement)); $dataType = $classAttribute->dataType(); $classAttribute->store(); $dataType->unserializeContentClassAttribute($classAttribute, $classAttributeNode, $attributeDatatypeParameterNode); $classAttribute->sync(); } } // add class to a class group $classGroupsList = $classGroupsNode->getElementsByTagName('group'); foreach ($classGroupsList as $classGroupNode) { $classGroupName = $classGroupNode->getAttribute('name'); $classGroup = eZContentClassGroup::fetchByName($classGroupName); if (!$classGroup) { $classGroup = eZContentClassGroup::create(); $classGroup->setAttribute('name', $classGroupName); $classGroup->store(); } $classGroup->appendClass($class); } return true; }
function copyPublishContentObject($sourceObject, $sourceSubtreeNodeIDList, &$syncNodeIDListSrc, &$syncNodeIDListNew, &$syncObjectIDListSrc, &$syncObjectIDListNew, $objectIDBlackList, &$nodeIDBlackList, &$notifications, $allVersions = false, $keepCreator = false, $keepTime = false) { $sourceObjectID = $sourceObject->attribute('id'); $key = array_search($sourceObjectID, $syncObjectIDListSrc); if ($key !== false) { eZDebug::writeDebug("Object (ID = {$sourceObjectID}) has been already copied.", "Subtree copy: copyPublishContentObject()"); return 1; // object already copied } $srcNodeList = $sourceObject->attribute('assigned_nodes'); // if we already failed to copy that contentobject, then just skip it: if (in_array($sourceObjectID, $objectIDBlackList)) { return 0; } // if we already failed to copy that node, then just skip it: //if ( in_array( $sourceNodeID, $nodeIDBlackList ) ) // return 0; // if cannot read contentobject then remember it and all its nodes (nodes // which are inside subtree being copied) in black list, and skip current node: if (!$sourceObject->attribute('can_read')) { $objectIDBlackList[] = $sourceObjectID; $notifications['Warnings'][] = ezpI18n::tr('kernel/content/copysubtree', "Object (ID = %1) was not copied: you do not have permission to read the object.", null, array($sourceObjectID)); $srcNodeList = $sourceObject->attribute('assigned_nodes'); foreach ($srcNodeList as $srcNode) { $srcNodeID = $srcNode->attribute('node_id'); $sourceParentNodeID = $srcNode->attribute('parent_node_id'); $key = array_search($sourceParentNodeID, $sourceSubtreeNodeIDList); if ($key !== false) { $nodeIDBlackList[] = $srcNodeID; $notifications['Warnings'][] = ezpI18n::tr('kernel/content/copysubtree', "Node (ID = %1) was not copied: you do not have permission to read object (ID = %2).", null, array($srcNodeID, $sourceObjectID)); } } return 0; } // check if all possible parent nodes for given contentobject are already published: $isReadyToPublish = false; foreach ($srcNodeList as $srcNode) { $srcNodeID = $srcNode->attribute('node_id'); if (in_array($srcNodeID, $nodeIDBlackList)) { continue; } $srcParentNodeID = $srcNode->attribute('parent_node_id'); // if parent node for this node is outside // of subtree being copied, then skip this node: $key = array_search($srcParentNodeID, $sourceSubtreeNodeIDList); if ($key === false) { continue; } // if parent node for this node wasn't copied yet and is in black list // then add that node in black list and just skip it: $key = array_search($srcParentNodeID, $nodeIDBlackList); if ($key !== false) { $nodeIDBlackList[] = $srcNodeID; $notifications['Warnings'][] = ezpI18n::tr('kernel/content/copysubtree', "Node (ID = %1) was not copied: parent node (ID = %2) was not copied.", null, array($srcNodeID, $srcParentNodeID)); continue; } $key = array_search($srcParentNodeID, $syncNodeIDListSrc); if ($key === false) { // if parent node is not copied yet and not in black list, // then just skip sourceObject from copying for next time eZDebug::writeDebug("Parent node (ID = {$srcParentNodeID}) for contentobject (ID = {$sourceObjectID}) is not published yet.", "Subtree copy: copyPublishContentObject()"); return 2; } else { $newParentNodeID = $syncNodeIDListNew[$key]; $newParentNode = eZContentObjectTreeNode::fetch($newParentNodeID); if ($newParentNode === null) { eZDebug::writeError("Cannot fetch one of parent nodes. Error are somewhere above", "Subtree copy error: copyPublishContentObject()"); return 3; } if ($newParentNode->checkAccess('create', $sourceObject->attribute('contentclass_id')) != 1) { $nodeIDBlackList[] = $srcNodeID; $notifications['Warnings'][] = ezpI18n::tr('kernel/content/copysubtree', "Node (ID = %1) was not copied: you do not have permission to create.", null, array($srcNodeID)); continue; } else { $isReadyToPublish = true; } } } // if all nodes of sourceObject were skiped as black list entry or // as outside of subtree being copied, then sourceObject cannot be // copied and published in any new location. So insert sourceObject // in a black list and skip it. if ($isReadyToPublish == false) { $objectIDBlackList[] = $sourceObjectID; $notifications['Warnings'][] = ezpI18n::tr('kernel/content/copysubtree', "Object (ID = %1) was not copied: no one nodes of object was not copied.", null, array($sourceObjectID)); return 0; } // make copy of source object $newObject = $sourceObject->copy($allVersions); // insert source and new object's ids in $syncObjectIDList // We should reset section that will be updated in updateSectionID(). // If sectionID is 0 than the object has been newly created $newObject->setAttribute('section_id', 0); $newObject->store(); $syncObjectIDListSrc[] = $sourceObjectID; $curVersion = $newObject->attribute('current_version'); $curVersionObject = $newObject->attribute('current'); $newObjAssignments = $curVersionObject->attribute('node_assignments'); // copy nodeassigments: $assignmentsForRemoving = array(); $foundMainAssignment = false; foreach ($newObjAssignments as $assignment) { $parentNodeID = $assignment->attribute('parent_node'); // if assigment is outside of subtree being copied then do not copy this assigment $key1 = array_search($parentNodeID, $sourceSubtreeNodeIDList); $key2 = array_search($parentNodeID, $nodeIDBlackList); if ($key1 === false or $key2 !== false) { $assignmentsForRemoving[] = $assignment->attribute('id'); continue; } $key = array_search($parentNodeID, $syncNodeIDListSrc); if ($key === false) { eZDebug::writeError("Cannot publish contentobject (ID={$sourceObjectID}). Parent is not published yet.", "Subtree Copy error: copyPublishContentObject()"); return 4; } if ($assignment->attribute('is_main')) { $foundMainAssignment = true; } $newParentNodeID = $syncNodeIDListNew[$key]; $assignment->setAttribute('parent_node', $newParentNodeID); $assignment->store(); } // remove assigments which are outside of subtree being copied: eZNodeAssignment::purgeByID($assignmentsForRemoving); // if main nodeassigment was not copied then set as main first nodeassigment if ($foundMainAssignment == false) { $newObjAssignments = $curVersionObject->attribute('node_assignments'); // We need to check if it has any assignments before changing the data. if (isset($newObjAssignments[0])) { $newObjAssignments[0]->setAttribute('is_main', 1); $newObjAssignments[0]->store(); } } // publish the newly created object $result = eZOperationHandler::execute('content', 'publish', array('object_id' => $newObject->attribute('id'), 'version' => $curVersion)); // Refetch the object data since it might change in the database. $newObjectID = $newObject->attribute('id'); $newObject = eZContentObject::fetch($newObjectID); $newNodeList = $newObject->attribute('assigned_nodes'); if (count($newNodeList) == 0) { $newObject->purge(); eZDebug::writeError("Cannot publish contentobject.", "Subtree Copy Error!"); $sourceObjectName = $srcNode->getName(); $notifications['Warnings'][] = ezpI18n::tr('kernel/content/copysubtree', "Cannot publish object (Name: %1, ID: %2).", null, array($sourceObjectName, $sourceObjectID)); return -1; } // Only if the object has been published successfully, the object id can be added into $syncObjectIDListNew $syncObjectIDListNew[] = $newObject->attribute('id'); $objAssignments = $curVersionObject->attribute('node_assignments'); foreach ($newNodeList as $newNode) { $newParentNode = $newNode->fetchParent(); $newParentNodeID = $newParentNode->attribute('node_id'); $keyA = array_search($newParentNodeID, $syncNodeIDListNew); if ($keyA === false) { eZDebug::writeError("Algoritm ERROR! Cannot find new parent node ID in new ID's list", "Subtree Copy Error!"); return -2; } $srcParentNodeID = $syncNodeIDListSrc[$keyA]; // Update attributes of node $bSrcParentFound = false; foreach ($srcNodeList as $srcNode) { if ($srcNode->attribute('parent_node_id') == $srcParentNodeID) { $newNode->setAttribute('priority', $srcNode->attribute('priority')); $newNode->setAttribute('is_hidden', $srcNode->attribute('is_hidden')); // Update node visibility if ($newParentNode->attribute('is_invisible') or $newParentNode->attribute('is_hidden')) { $newNode->setAttribute('is_invisible', 1); } else { $newNode->setAttribute('is_invisible', $srcNode->attribute('is_invisible')); } $syncNodeIDListSrc[] = $srcNode->attribute('node_id'); $syncNodeIDListNew[] = $newNode->attribute('node_id'); $bSrcParentFound = true; break; } } if ($bSrcParentFound == false) { eZDebug::writeError("Cannot find source parent node in list of nodes already copied.", "Subtree Copy Error!"); } // Create unique remote_id $newRemoteID = eZRemoteIdUtility::generate('node'); $oldRemoteID = $newNode->attribute('remote_id'); $newNode->setAttribute('remote_id', $newRemoteID); // Change parent_remote_id for object assignments foreach ($objAssignments as $assignment) { if ($assignment->attribute('parent_remote_id') == $oldRemoteID) { $assignment->setAttribute('parent_remote_id', $newRemoteID); $assignment->store(); } } $newNode->store(); } // if $keepCreator == true then keep owner of contentobject being // copied and creator of its published version Unchaged $isModified = false; if ($keepTime) { $srcPublished = $sourceObject->attribute('published'); $newObject->setAttribute('published', $srcPublished); $srcModified = $sourceObject->attribute('modified'); $newObject->setAttribute('modified', $srcModified); $isModified = true; } if ($keepCreator) { $srcOwnerID = $sourceObject->attribute('owner_id'); $newObject->setAttribute('owner_id', $srcOwnerID); $isModified = true; } if ($isModified) { $newObject->store(); } if ($allVersions) { // copy time of creation and midification and creator id for // all versions of content object being copied. $srcVersionsList = $sourceObject->versions(); foreach ($srcVersionsList as $srcVersionObject) { $newVersionObject = $newObject->version($srcVersionObject->attribute('version')); if (!is_object($newVersionObject)) { continue; } $isModified = false; if ($keepTime) { $srcVersionCreated = $srcVersionObject->attribute('created'); $newVersionObject->setAttribute('created', $srcVersionCreated); $srcVersionModified = $srcVersionObject->attribute('modified'); $newVersionObject->setAttribute('modified', $srcVersionModified); $isModified = true; } if ($keepCreator) { $srcVersionCreatorID = $srcVersionObject->attribute('creator_id'); $newVersionObject->setAttribute('creator_id', $srcVersionCreatorID); $isModified = true; } if ($isModified) { $newVersionObject->store(); } } } else { $srcVersionObject = $sourceObject->attribute('current'); $newVersionObject = $newObject->attribute('current'); $isModified = false; if ($keepTime) { $srcVersionCreated = $srcVersionObject->attribute('created'); $newVersionObject->setAttribute('created', $srcVersionCreated); $srcVersionModified = $srcVersionObject->attribute('modified'); $newVersionObject->setAttribute('modified', $srcVersionModified); $isModified = true; } if ($keepCreator) { $srcVersionCreatorID = $srcVersionObject->attribute('creator_id'); $newVersionObject->setAttribute('creator_id', $srcVersionCreatorID); $isModified = true; } if ($isModified) { $newVersionObject->store(); } } return 0; // source object was copied successfully. }
/** * Test for issue #18474: RSS Export: problem when a title contains the "&" * * @link http://issues.ez.no/18479 */ public function testFeedWithSpecialCharacters() { $folderId = $this->createEZPFolder(__FUNCTION__ . ' like &'); $articles = array(); for ($i = 0; $i < 2; $i++) { $articles[] = $this->createEZPArticle($folderId, "Test object #{$i} for " . __FUNCTION__ . ' like &', "Summary for Test object #{$i} for " . __FUNCTION__, eZRemoteIdUtility::generate()); } $types = array('2.0', '1.0', 'ATOM'); foreach ($types as $type) { $rssExport = $this->createEZPRSSExport($type, $folderId, 'Feed ' . $type . ' with special characters like &', 'This feed contains special characters like &'); $xml = $rssExport->attribute('rss-xml-content'); $dom = new DomDocument('1.0'); $valid = $dom->loadXML($xml, LIBXML_NOERROR | LIBXML_NOWARNING); $this->assertTrue($valid, 'Feed ' . $type . ' is not valid'); } $this->removeObjects($articles); }
function remoteID() { $remoteID = eZPersistentObject::attribute('remote_id', true); if (!$remoteID && $this->Version == eZContentClass::VERSION_STATUS_DEFINED) { $this->setAttribute('remote_id', eZRemoteIdUtility::generate('class')); $this->sync(array('remote_id')); $remoteID = eZPersistentObject::attribute('remote_id', true); } return $remoteID; }
function copyPublishContentObject($sourceObject, $sourceSubtreeNodeIDList, &$syncNodeIDListSrc, &$syncNodeIDListNew, &$syncObjectIDListSrc, &$syncObjectIDListNew, $allVersions = false, $keepCreator = false, $keepTime = false) { global $cli; $sourceObjectID = $sourceObject->attribute('id'); $key = array_search($sourceObjectID, $syncObjectIDListSrc); if ($key !== false) { return 1; // object already copied } $srcNodeList = $sourceObject->attribute('assigned_nodes'); // check if all parent nodes for given contentobject are already published: foreach ($srcNodeList as $srcNode) { $sourceParentNodeID = $srcNode->attribute('parent_node_id'); // if parent node for this node is outside // of subtree being copied, then skip this node. $key = array_search($sourceParentNodeID, $sourceSubtreeNodeIDList); if ($key === false) { continue; } $key = array_search($sourceParentNodeID, $syncNodeIDListSrc); if ($key === false) { return 2; // one of parent nodes is not published yet - have to try to publish later. } else { $newParentNodeID = $syncNodeIDListNew[$key]; if (($newParentNode = eZContentObjectTreeNode::fetch($newParentNodeID)) === null) { return 3; // cannot fetch one of parent nodes - must be error somewhere above. } } } // make copy of source object $newObject = $sourceObject->copy($allVersions); // insert source and new object's ids in $syncObjectIDList // We should reset section that will be updated in updateSectionID(). // If sectionID is 0 than the object has been newly created $newObject->setAttribute('section_id', 0); $newObject->store(); $syncObjectIDListSrc[] = $sourceObjectID; $syncObjectIDListNew[] = $newObject->attribute('id'); $curVersion = $newObject->attribute('current_version'); $curVersionObject = $newObject->attribute('current'); $newObjAssignments = $curVersionObject->attribute('node_assignments'); // copy nodeassigments: $assignmentsForRemoving = array(); $foundMainAssignment = false; foreach ($newObjAssignments as $assignment) { $parentNodeID = $assignment->attribute('parent_node'); // if assigment is outside of subtree being copied then do not copy this assigment $key = array_search($parentNodeID, $sourceSubtreeNodeIDList); if ($key === false) { $assignmentsForRemoving[] = $assignment->attribute('id'); continue; } $key = array_search($parentNodeID, $syncNodeIDListSrc); if ($key === false) { $cli->error("Subtree Copy Error!\nOne of parent nodes for contentobject (ID = {$sourceObjectID}) is not published yet."); return 4; } if ($assignment->attribute('is_main')) { $foundMainAssignment = true; } $newParentNodeID = $syncNodeIDListNew[$key]; $assignment->setAttribute('parent_node', $newParentNodeID); $assignment->store(); } // remove assigments which are outside of subtree being copied: eZNodeAssignment::purgeByID($assignmentsForRemoving); // JB valid // if main nodeassigment was not copied then set as main first nodeassigment if ($foundMainAssignment == false) { $newObjAssignments = $curVersionObject->attribute('node_assignments'); // JB start // We need to check if it has any assignments before changing the data. if (isset($newObjAssignments[0])) { $newObjAssignments[0]->setAttribute('is_main', 1); $newObjAssignments[0]->store(); } // JB end } // publish the newly created object $result = eZOperationHandler::execute('content', 'publish', array('object_id' => $newObject->attribute('id'), 'version' => $curVersion)); // JB start // Refetch the object data since it might change in the database. $newObjectID = $newObject->attribute('id'); $newObject = eZContentObject::fetch($newObjectID); // JB end $newNodeList = $newObject->attribute('assigned_nodes'); if (count($newNodeList) == 0) { $newObject->purge(); $cli->error("Subtree Copy Error!\nCannot publish contentobject."); return 5; } $objAssignments = $curVersionObject->attribute('node_assignments'); foreach ($newNodeList as $newNode) { $newParentNodeID = $newNode->attribute('parent_node_id'); $keyA = array_search($newParentNodeID, $syncNodeIDListNew); if ($keyA === false) { die("Copy Subtree Error: Algoritm ERROR! Cannot find new parent node ID in new ID's list"); } $srcParentNodeID = $syncNodeIDListSrc[$keyA]; // Update attributes of node $bSrcParentFound = false; foreach ($srcNodeList as $srcNode) { if ($srcNode->attribute('parent_node_id') == $srcParentNodeID) { $newNode->setAttribute('priority', $srcNode->attribute('priority')); $newNode->setAttribute('is_hidden', $srcNode->attribute('is_hidden')); $newNode->setAttribute('is_invisible', $srcNode->attribute('is_invisible')); $syncNodeIDListSrc[] = $srcNode->attribute('node_id'); $syncNodeIDListNew[] = $newNode->attribute('node_id'); $bSrcParentFound = true; break; } } if ($bSrcParentFound == false) { die("Copy Subtree Error: Algoritm ERROR! Cannot find source parent node ID in source parent node ID's list of contentobject being copied."); } // Create unique remote_id $newRemoteID = eZRemoteIdUtility::generate('node'); $oldRemoteID = $newNode->attribute('remote_id'); $newNode->setAttribute('remote_id', $newRemoteID); // Change parent_remote_id for object assignments foreach ($objAssignments as $assignment) { if ($assignment->attribute('parent_remote_id') == $oldRemoteID) { $assignment->setAttribute('parent_remote_id', $newRemoteID); $assignment->store(); } } $newNode->store(); } // Update "is_invisible" attribute for the newly created node. $newNode = $newObject->attribute('main_node'); eZContentObjectTreeNode::updateNodeVisibility($newNode, $newParentNode); // ??? do we need this here? // if $keepCreator == true then keep owner of contentobject being // copied and creator of its published version Unchaged $isModified = false; if ($keepTime) { $srcPublished = $sourceObject->attribute('published'); $newObject->setAttribute('published', $srcPublished); $srcModified = $sourceObject->attribute('modified'); $newObject->setAttribute('modified', $srcModified); $isModified = true; } if ($keepCreator) { $srcOwnerID = $sourceObject->attribute('owner_id'); $newObject->setAttribute('owner_id', $srcOwnerID); $isModified = true; } if ($isModified) { $newObject->store(); } if ($allVersions) { // copy time of creation and modification and creator id for // all versions of content object being copied. $srcVersionsList = $sourceObject->versions(); foreach ($srcVersionsList as $srcVersionObject) { $newVersionObject = $newObject->version($srcVersionObject->attribute('version')); if (!is_object($newVersionObject)) { continue; } $isModified = false; if ($keepTime) { $srcVersionCreated = $srcVersionObject->attribute('created'); $newVersionObject->setAttribute('created', $srcVersionCreated); $srcVersionModified = $srcVersionObject->attribute('modified'); $newVersionObject->setAttribute('modified', $srcVersionModified); $isModified = true; } if ($keepCreator) { $srcVersionCreatorID = $srcVersionObject->attribute('creator_id'); $newVersionObject->setAttribute('creator_id', $srcVersionCreatorID); $isModified = true; } if ($isModified) { $newVersionObject->store(); } } } else { $srcVersionObject = $sourceObject->attribute('current'); $newVersionObject = $newObject->attribute('current'); $isModified = false; if ($keepTime) { $srcVersionCreated = $srcVersionObject->attribute('created'); $newVersionObject->setAttribute('created', $srcVersionCreated); $srcVersionModified = $srcVersionObject->attribute('modified'); $newVersionObject->setAttribute('modified', $srcVersionModified); $isModified = true; } if ($keepCreator) { $srcVersionCreatorID = $srcVersionObject->attribute('creator_id'); $newVersionObject->setAttribute('creator_id', $srcVersionCreatorID); $isModified = true; } if ($isModified) { $newVersionObject->store(); } } return 0; // source object was copied successfully. }
static function unserialize($contentNodeDOMNode, $contentObject, $version, $isMain, &$nodeList, &$options, $handlerType = 'ezcontentobject') { $parentNodeID = -1; $remoteID = $contentNodeDOMNode->getAttribute('remote-id'); $parentNodeRemoteID = $contentNodeDOMNode->getAttribute('parent-node-remote-id'); $node = eZContentObjectTreeNode::fetchByRemoteID($remoteID); if (is_object($node)) { $description = "Node with remote ID {$remoteID} already exists."; $choosenAction = eZPackageHandler::errorChoosenAction(eZContentObject::PACKAGE_ERROR_EXISTS, $options, $description, $handlerType, false); switch ($choosenAction) { // In case user have choosen "Keep existing object and create new" case eZContentObject::PACKAGE_NEW: $newRemoteID = eZRemoteIdUtility::generate('node'); $node->setAttribute('remote_id', $newRemoteID); $node->store(); $nodeInfo = array('contentobject_id' => $node->attribute('contentobject_id'), 'contentobject_version' => $node->attribute('contentobject_version'), 'parent_remote_id' => $remoteID); $nodeAssignment = eZPersistentObject::fetchObject(eZNodeAssignment::definition(), null, $nodeInfo); if (is_object($nodeAssignment)) { $nodeAssignment->setAttribute('parent_remote_id', $newRemoteID); $nodeAssignment->store(); } break; // When running non-interactively with ezpm.php // When running non-interactively with ezpm.php case eZPackage::NON_INTERACTIVE: case eZContentObject::PACKAGE_UPDATE: // Update existing node settigns. if (!$parentNodeRemoteID) { // when top node of subtree export, only update node sort field and sort order $node->setAttribute('sort_field', eZContentObjectTreeNode::sortFieldID($contentNodeDOMNode->getAttribute('sort-field'))); $node->setAttribute('sort_order', $contentNodeDOMNode->getAttribute('sort-order')); $node->store(); return true; } break; default: // This error may occur only if data integrity is broken $options['error'] = array('error_code' => eZContentObject::PACKAGE_ERROR_NODE_EXISTS, 'element_id' => $remoteID, 'description' => $description); return false; break; } } if ($parentNodeRemoteID) { $parentNode = eZContentObjectTreeNode::fetchByRemoteID($parentNodeRemoteID); if ($parentNode !== null) { $parentNodeID = $parentNode->attribute('node_id'); } } else { if (isset($options['top_nodes_map'][$contentNodeDOMNode->getAttribute('node-id')]['new_node_id'])) { $parentNodeID = $options['top_nodes_map'][$contentNodeDOMNode->getAttribute('node-id')]['new_node_id']; } else { if (isset($options['top_nodes_map']['*'])) { $parentNodeID = $options['top_nodes_map']['*']; } else { eZDebug::writeError('New parent node not set ' . $contentNodeDOMNode->getAttribute('name'), __METHOD__); } } } $isMain = $isMain && $contentNodeDOMNode->getAttribute('is-main-node'); $nodeInfo = array('contentobject_id' => $contentObject->attribute('id'), 'contentobject_version' => $version, 'is_main' => $isMain, 'parent_node' => $parentNodeID, 'parent_remote_id' => $remoteID, 'sort_field' => eZContentObjectTreeNode::sortFieldID($contentNodeDOMNode->getAttribute('sort-field')), 'sort_order' => $contentNodeDOMNode->getAttribute('sort-order')); if ($parentNodeID == -1 && $parentNodeRemoteID) { if (!isset($options['suspended-nodes'])) { $options['suspended-nodes'] = array(); } $options['suspended-nodes'][$parentNodeRemoteID] = array('nodeinfo' => $nodeInfo, 'priority' => $contentNodeDOMNode->getAttribute('priority')); return true; } $existNodeAssignment = eZPersistentObject::fetchObject(eZNodeAssignment::definition(), null, $nodeInfo); $nodeInfo['priority'] = $contentNodeDOMNode->getAttribute('priority'); if (!is_object($existNodeAssignment)) { $nodeAssignment = eZNodeAssignment::create($nodeInfo); $nodeList[] = $nodeInfo; $nodeAssignment->store(); } return true; }
default: { $skip = 0; } } $cli->output( 'Fixing...' ); foreach ( $rows as $i => $row ) { if ( $i == $skip ) { continue; } $escapedNewRemoteID = $db->escapeString( eZRemoteIdUtility::generate( 'class' ) ); $db->query( "UPDATE ezcontentclass SET remote_id='$escapedNewRemoteID' WHERE id=$row[id]" ); } $totalCount += $nonUniqueRemoteIDData['cnt'] - 1; $cli->output( '' ); $cli->output( '' ); } $cli->output( "Number of content classes that received a new remote ID : $totalCount" ); $script->shutdown( 0 ); ?>
$treeNode->store(); } $totalCount += $nonUniqueRemoteIDData['cnt'] - 1; $cli->output(''); $cli->output(''); } if ($db->databaseName() == 'oracle') { $nonUniqueRemoteIDDataList = $db->arrayQuery("SELECT node_id FROM ezcontentobject_tree WHERE remote_id IS NULL"); } else { $nonUniqueRemoteIDDataList = $db->arrayQuery("SELECT node_id FROM ezcontentobject_tree WHERE remote_id = ''"); } $nonUniqueRemoteIDDataListCount = count($nonUniqueRemoteIDDataList); $cli->output(''); $cli->output("Found {$nonUniqueRemoteIDDataListCount} tree nodes with empty remote IDs."); $cli->output(''); if ($nonUniqueRemoteIDDataListCount) { $cli->output('Fixing', false); foreach ($nonUniqueRemoteIDDataList as $nonUniqueRemoteIDData) { // fetch nodes with eZPersistentObject to avoid object cache $treeNodes = eZPersistentObject::fetchObjectList(eZContentObjectTreeNode::definition(), null, array('node_id' => $nonUniqueRemoteIDData['node_id']), array('modified_subnode' => 'asc')); foreach ($treeNodes as $i => $treeNode) { $treeNode->setAttribute('remote_id', eZRemoteIdUtility::generate('node')); $treeNode->store(); } ++$totalCount; $cli->output('.', false); } } $cli->output(''); $cli->output("Number of tree nodes that received a new remote ID : {$totalCount}"); $script->shutdown(0);
/** * Returns a DOM structure of the content object and it's attributes. * * Transaction unsafe. If you call several transaction unsafe methods you must enclose * the calls within a db transaction; thus within db->begin and db->commit. * * @param mixed $package * @param int|bool $specificVersion Content object version, true for current version, false for all, else array containing specific versions. * @param array|bool $options Package options or false * @param int[]|bool $contentNodeIDArray Array of allowed nodes or false * @param int[]|bool $topNodeIDArray Array of top nodes in current package export or false * @return bool|DOMElement */ function serialize( $package, $specificVersion = false, $options = false, $contentNodeIDArray = false, $topNodeIDArray = false ) { if ( $options && $options['node_assignment'] == 'main' ) { if ( !isset( $contentNodeIDArray[$this->attribute( 'main_node_id' )] ) ) { return false; } } $dom = new DomDocument(); $objectNode = $dom->createElementNS( 'http://ez.no/ezobject', 'ezremote:object' ); $objectNode->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:id', $this->ID ); $objectNode->setAttribute( 'name', $this->Name ); $objectNode->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:section_id', $this->SectionID ); $objectNode->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:owner_id', $this->OwnerID ); $objectNode->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:class_id', $this->ClassID ); $objectNode->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:published', eZDateUtils::rfc1123Date( $this->attribute( 'published' ) ) ); $objectNode->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:modified', eZDateUtils::rfc1123Date( $this->attribute( 'modified' ) ) ); if ( !$this->attribute( 'remote_id' ) ) { $this->setAttribute( 'remote_id', eZRemoteIdUtility::generate( 'object' ) ); $this->store(); } $objectNode->setAttribute( 'remote_id', $this->attribute( 'remote_id' ) ); $contentClass = $this->attribute( 'content_class' ); $objectNode->setAttribute( 'class_remote_id', $contentClass->attribute( 'remote_id' ) ); $objectNode->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:class_identifier', $contentClass->attribute( 'identifier' ) ); $alwaysAvailableText = '0'; if ( (int)$this->attribute( 'language_mask' ) & 1 ) { $alwaysAvailableText = '1'; } $objectNode->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:always_available', $alwaysAvailableText ); $versions = array(); $oneLanguagePerVersion = false; if ( $specificVersion === false ) { $versions = $this->versions(); // Since we are exporting all versions it should only contain // one language per version //$oneLanguagePerVersion = true; // uncomment to get one language per version } else if ( $specificVersion === true ) { $versions[] = $this->currentVersion(); } else { $versions[] = $this->version( $specificVersion ); // Since we are exporting a specific version it should only contain // one language per version? $oneLanguagePerVersion = true; } $this->fetchClassAttributes(); $exportedLanguages = array(); $versionsNode = $dom->createElementNS( 'http://ez.no/object/', 'ezobject:version-list' ); $versionsNode->setAttribute( 'active_version', $this->CurrentVersion ); foreach ( $versions as $version ) { if ( !$version ) { continue; } $options['only_initial_language'] = $oneLanguagePerVersion; $versionNode = $version->serialize( $package, $options, $contentNodeIDArray, $topNodeIDArray ); if ( $versionNode ) { $importedVersionNode = $dom->importNode( $versionNode, true ); $versionsNode->appendChild( $importedVersionNode ); foreach ( $versionNode->getElementsByTagName( 'object-translation' ) as $versionNodeChild ) { $exportedLanguage = $versionNodeChild->getAttribute( 'language' ); $exportedLanguages[] = $exportedLanguage; $exportedLanguages = array_unique( $exportedLanguages ); } } unset( $versionNode ); unset( $versionNode ); } $initialLanguageCode = $this->attribute( 'initial_language_code' ); if ( in_array( $initialLanguageCode, $exportedLanguages ) ) { $objectNode->setAttribute( 'initial_language', $initialLanguageCode ); } $objectNode->appendChild( $versionsNode ); return $objectNode; }
$cli->output( '' ); if ( $nonUniqueRemoteIDDataListCount ) { $cli->output( 'Fixing', false ); foreach ( $nonUniqueRemoteIDDataList as $nonUniqueRemoteIDData ) { // fetch objects with eZPersistentObject to avoid object cache $contentObjects = eZPersistentObject::fetchObjectList( eZContentObject::definition(), null, array( 'id' => $nonUniqueRemoteIDData['id'] ), array( 'status' => 'desc', 'published' => 'asc' ) ); foreach ( $contentObjects as $i => $contentObject ) { $contentObject->setAttribute( 'remote_id', eZRemoteIdUtility::generate( 'object' ) ); $contentObject->store(); } ++$totalCount; $cli->output( '.', false ); } } $cli->output( '' ); $cli->output( "Number of content objects that received a new remote ID : $totalCount" ); $script->shutdown( 0 ); ?>
static function create($parameters = array()) { if (!isset($parameters['contentobject_id'])) { eZDebug::writeError($parameters, "Cannot create node assignment without contentobject_id"); $retValue = null; return $retValue; } if (!isset($parameters['contentobject_version'])) { $parameters['contentobject_version'] = 1; } if (!isset($parameters['remote_id'])) { $parameters['remote_id'] = 0; } if (!isset($parameters['parent_node'])) { $parameters['parent_node'] = 2; } if (!isset($parameters['is_main'])) { $parameters['is_main'] = 0; } if (!isset($parameters['is_hidden'])) { $parameters['is_hidden'] = 0; } if (!isset($parameters['priority'])) { $parameters['priority'] = 0; } if (!isset($parameters['sort_field'])) { $parameters['sort_field'] = eZContentObjectTreeNode::SORT_FIELD_PUBLISHED; } if (!isset($parameters['sort_order'])) { $parameters['sort_order'] = eZContentObjectTreeNode::SORT_ORDER_DESC; } if (!isset($parameters['from_node_id'])) { $parameters['from_node_id'] = 0; } if (!isset($parameters['parent_remote_id']) || empty($parameters['parent_remote_id'])) { $parameters['parent_remote_id'] = eZRemoteIdUtility::generate('node'); } if (!isset($parameters['op_code'])) { // The default value for new node-assigments is to create nodes from them. $parameters['op_code'] = eZNodeAssignment::OP_CODE_CREATE; } return new eZNodeAssignment($parameters); }
$db = eZDB::instance(); while ($nodeAssignments = eZPersistentObject::fetchObjectList(eZNodeAssignment::definition(), null, $condition, null, $limit)) { $db->begin(); /** @var $nodeAssignments \ezNodeAssignment[] */ foreach ($nodeAssignments as $nodeAssignment) { $currentParentRemoteId = $nodeAssignment->attribute("parent_remote_id"); if (!empty($currentParentRemoteId)) { $cli->output("Skipped: node assignment #{$nodeAssignment->ID}"); continue; } $currentRemoteId = $nodeAssignment->attribute("remote_id"); if (!empty($currentRemoteId)) { $nodeAssignment->setAttribute("remote_id", 0); $nodeAssignment->setAttribute("parent_remote_id", $currentRemoteId); $cli->output("Updated node assignment #{$nodeAssignment->ID}: copied 'parent_remote_id' from 'remote_id'"); } else { $nodeAssignment->setAttribute("parent_remote_id", eZRemoteIdUtility::generate("eznode_assignment")); $cli->output("Updated node assignment #{$nodeAssignment->ID}: calculated new 'parent_remote_id'"); } $nodeAssignment->store(); $count += 1; } $db->commit(); $limit["offset"] += $optIterationLimit; sleep($optIterationSleep); } $cli->output(); $cli->output("Updated total of {$count} node assignments"); $cli->output(); $cli->output("Done"); $script->shutdown();
/** * Backward compatible remoteID generator * @return string */ static function generateRemoteID() { //eZRemoteIdUtility introduced in eZPublish version 4.5 if (method_exists('eZRemoteIdUtility', 'generate')) { return eZRemoteIdUtility::generate('tag'); } else { return md5((string) mt_rand() . (string) time()); } }