예제 #1
0
 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);
 }
예제 #4
0
 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;
 }
예제 #5
0
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 );

?>
예제 #8
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 );

?>
예제 #11
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();
예제 #13
0
 /**
  * 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());
     }
 }