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.
}
 /**
  * Removes nodes
  *
  * This function does not check about permissions, this is the responsibility of the caller!
  *
  * @param array $removeNodeIdList Array of Node ID to remove
  *
  * @return array An array with operation status, always true
  */
 public static function removeNodes(array $removeNodeIdList)
 {
     $mainNodeChanged = array();
     $nodeAssignmentIdList = array();
     $objectIdList = array();
     $db = eZDB::instance();
     $db->begin();
     foreach ($removeNodeIdList as $nodeId) {
         $node = eZContentObjectTreeNode::fetch($nodeId);
         $objectId = $node->attribute('contentobject_id');
         foreach (eZNodeAssignment::fetchForObject($objectId, eZContentObject::fetch($objectId)->attribute('current_version'), 0, false) as $nodeAssignmentKey => $nodeAssignment) {
             if ($nodeAssignment['parent_node'] == $node->attribute('parent_node_id')) {
                 $nodeAssignmentIdList[$nodeAssignment['id']] = 1;
             }
         }
         if ($nodeId == $node->attribute('main_node_id')) {
             $mainNodeChanged[$objectId] = 1;
         }
         $node->removeThis();
         if (!isset($objectIdList[$objectId])) {
             $objectIdList[$objectId] = eZContentObject::fetch($objectId);
         }
     }
     eZNodeAssignment::purgeByID(array_keys($nodeAssignmentIdList));
     foreach (array_keys($mainNodeChanged) as $objectId) {
         $allNodes = $objectIdList[$objectId]->assignedNodes();
         // Registering node that will be promoted as 'main'
         $mainNodeChanged[$objectId] = $allNodes[0];
         eZContentObjectTreeNode::updateMainNodeID($allNodes[0]->attribute('node_id'), $objectId, false, $allNodes[0]->attribute('parent_node_id'));
     }
     // Give other search engines that the default one a chance to reindex
     // when removing locations.
     if (!eZSearch::getEngine() instanceof eZSearchEngine) {
         foreach (array_keys($objectIdList) as $objectId) {
             eZContentOperationCollection::registerSearchObject($objectId);
         }
     }
     $db->commit();
     //call appropriate method from search engine
     eZSearch::removeNodes($removeNodeIdList);
     $userClassIdList = eZUser::contentClassIDs();
     foreach ($objectIdList as $objectId => $object) {
         eZContentCacheManager::clearObjectViewCacheIfNeeded($objectId);
         // clear user policy cache if this was a user object
         if (in_array($object->attribute('contentclass_id'), $userClassIdList)) {
             eZUser::purgeUserCacheByUserId($object->attribute('id'));
         }
     }
     // we don't clear template block cache here since it's cleared in eZContentObjectTreeNode::removeNode()
     return array('status' => true);
 }
    eZDebug::writeError("No assignments passed to content/removeassignment");
    return $module->redirectToView('view', array('full', 2));
}
// process current action
if ($module->isCurrentAction('ConfirmRemoval')) {
    $http->removeSessionVariable('AssignmentRemoveData');
    $assignments = eZNodeAssignment::fetchListByID($removeList);
    $mainNodeChanged = false;
    $db = eZDB::instance();
    $db->begin();
    foreach ($assignments as $assignment) {
        $assignmentID = $assignment->attribute('id');
        if ($assignment->attribute('is_main')) {
            $mainNodeChanged = true;
        }
        eZNodeAssignment::purgeByID($assignmentID);
    }
    if ($mainNodeChanged) {
        eZNodeAssignment::setNewMainAssignment($objectID, $editVersion);
    }
    $db->commit();
    return $module->redirectToView('edit', array($objectID, $editVersion, $editLanguage, $fromLanguage));
} else {
    if ($module->isCurrentAction('CancelRemoval')) {
        $http->removeSessionVariable('AssignmentRemoveData');
        return $module->redirectToView('edit', array($objectID, $editVersion, $editLanguage, $fromLanguage));
    }
}
// default action: show the confirmation dialog
$assignmentsToRemove = eZNodeAssignment::fetchListByID($removeList);
$removeList = array();
Example #4
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.
}
 /**
  * Add an object to an array of nodes.
  *
  * The array of nodes, is given by the post field ymcActiveNodeAssignmentsPool[]
  *
  * This hook is run at "post_fetch" time.
  * 
  * @param mixed  $module                  Is eZModule.
  * @param mixed  $class                   Is eZContentClass.
  * @param mixed  $object                  Is eZContentObject.
  * @param mixed  $version                 Is eZContentObjectVersion.
  * @param mixed  $contentObjectAttributes Is eZContentObjectAttribute.
  * @param string $editVersion             Number as String.
  * @param string $editLanguage            E.g. eng-GB.
  * @param mixed  $fromLanguage            Or false.
  * @param mixed  &$validation             Array.
  *
  * @return void
  */
 public function addNodeAssignments($module, $class, $object, $version, $contentObjectAttributes, $editVersion, $editLanguage, $fromLanguage, &$validation)
 {
     $http = eZHTTPTool::instance();
     // UseNodeAssignments is only set in two templates, where it is 0:
     // design/admin/templates/content/edit.tpl
     // design/admin/override/templates/content/template_look_edit.tpl
     //
     // This means, that we exit here, if we come from these templates.
     if ($http->hasPostVariable('UseNodeAssigments')) {
         //@todo: Should we really return here? Wouldn't it be better to trigger the
         //add and removal actions also from the admin interface?
         //            return;
     }
     $ObjectID = $object->attribute('id');
     // Assign to nodes
     if ($http->hasPostVariable('ymcActiveNodeAssignmentsPool') && is_array($http->postVariable('ymcActiveNodeAssignmentsPool'))) {
         $selectedNodeIDArray = $http->postVariable('ymcActiveNodeAssignmentsPool');
         $assignedIDArray = array();
         $setMainNode = false;
         $hasMainNode = false;
         // * Get all nodes, to which the object is already assigned to and
         //   put them in $assignedIDArray[]
         //
         // * Also removed assignments, but did not understant this.
         //
         // nodeAssignments returns array of eZNodeAssignment
         foreach ($version->nodeAssignments() as $assignedNode) {
             $assignedNodeID = $assignedNode->attribute('parent_node');
             if ($assignedNode->attribute('is_main')) {
                 $hasMainNode = true;
             }
             if ($assignedNode->attribute('op_code') === eZNodeAssignment::OP_CODE_REMOVE && in_array($assignedNodeID, $selectedNodeIDArray)) {
                 if ($assignedNode->attribute('is_main')) {
                     $hasMainNode = false;
                 }
                 eZNodeAssignment::purgeByID($assignedNode->attribute('id'));
             } else {
                 $assignedIDArray[] = $assignedNodeID;
             }
         }
         if (!$hasMainNode) {
             $setMainNode = true;
         }
         foreach ($selectedNodeIDArray as $nodeID) {
             if ((int) $nodeID > 0 and !in_array((int) $nodeID, $assignedIDArray)) {
                 $nodeID = (int) $nodeID;
                 $isPermitted = true;
                 // Check access
                 $newNode = eZContentObjectTreeNode::fetch($nodeID);
                 if (is_object($newNode)) {
                     $newNodeObject = $newNode->attribute('object');
                     $canCreate = $newNodeObject->checkAccess('create', $class->attribute('id'), $newNodeObject->attribute('contentclass_id')) == 1;
                     if (!$canCreate) {
                         $isPermitted = false;
                     } else {
                         $canCreateClassList = $newNodeObject->attribute('can_create_class_list');
                         $objectClassID = $object->attribute('contentclass_id');
                         $canCreateClassIDList = array();
                         foreach (array_keys($canCreateClassList) as $key) {
                             $canCreateClassIDList[] = $canCreateClassList[$key]['id'];
                         }
                         if (!in_array($objectClassID, $canCreateClassIDList)) {
                             $isPermitted = false;
                         }
                     }
                     if (!$isPermitted) {
                         eZDebug::writeError($newNode->attribute('path_identification_string'), "[ymcEdit] You are not allowed to place this object under:");
                         $validation['placement'][] = array('text' => ezi18n('kernel/content', 'You are not allowed to place this object under: %1', null, array($newNode->attribute('url_alias'))));
                         $validation['processed'] = true;
                         // Error message.
                     } else {
                         $isMain = 0;
                         $db = eZDB::instance();
                         $db->begin();
                         $version->assignToNode($nodeID, $isMain);
                         $db->commit();
                     }
                 } else {
                     eZDebug::writeError($nodeID, "[ymcEdit] Tried to place an object on a non existing node with id:");
                     $validation['placement'][] = array('text' => ezi18n('kernel/content', 'You can not place this object on a non existing location'));
                     $validation['processed'] = true;
                     // Error message.
                 }
             }
         }
         if ($setMainNode) {
             eZNodeAssignment::setNewMainAssignment($object->attribute('id'), $version->attribute('version'));
         }
     }
 }