Snippet: PHP Snippet Adding additional locations for an object

Compatibility

The code above works with eZ publish 3.8 and 3.9.

Policy checking

You can remove policy checking by removing the conditional structures with $canManageLocations and $canCreate

Code sample

Since eZ publish 3.8, the publish operation doesn't need to be executed anymore when adding new locations for objects which are already in the node tree.

The following code was based on a part of the action view of the content module (kernel/content/action.php). The known variables are:

  • $node: instance of eZContentObjectTreeNode, which holds the object we want to create new tree leaves for
  • $selectedNodeIDArray: array with the node ID's of the additional parent nodes
$object =& $node->attribute( 'object' );
$objectID = $object->attribute( 'id' );

include_once( 'kernel/classes/datatypes/ezuser/ezuser.php' );
$user =& eZUser::currentUser();

$canManageLocations = $object->checkAccess( 'edit' ) || $user->attribute( 'has_manage_locations' );

if ( $canManageLocations )
{

   $nodeAssignmentList = eZNodeAssignment::fetchForObject( $objectID, $object->attribute( 'current_version' ), 0, false );

    $assignedNodes =& $object->assignedNodes();
    $objectID = $object->attribute( 'id' );

    $parentNodeIDArray = array();
    $setMainNode = false;
    $hasMainNode = false;

    foreach ( $assignedNodes as $assignedNode )
    {
        $assignedNodeID = $assignedNode->attribute( 'node_id' );
        if ( $assignedNode->attribute( 'is_main' ) )
        {
            $hasMainNode = true;
        }

        $append = false;
        foreach ( $nodeAssignmentList as $nodeAssignment )
        {
            if ( $nodeAssignment['parent_node'] == $assignedNode->attribute( 'parent_node_id' ) )
            {
                $append = true;
                break;
            }
        }
        if ( $append )
        {
            $parentNodeIDArray[] = $assignedNode->attribute( 'parent_node_id' );
        }
    }

    if ( !$hasMainNode )
    {
        $setMainNode = true;
    }

    include_once( 'lib/ezdb/classes/ezdb.php');
    $db =& eZDB::instance();
    $db->begin();
    $locationAdded = false;
    foreach ( $selectedNodeIDArray as $selectedNodeID )
    {
        if ( !in_array( $selectedNodeID, $parentNodeIDArray ) )
        {
            $parentNode = eZContentObjectTreeNode::fetch( $selectedNodeID );
            $parentNodeObject =& $parentNode->attribute( 'object' );

            $canCreate = ( ( $parentNode->checkAccess( 'create', $object->attribute( 'contentclass_id' ), $parentNodeObject->attribute( 'contentclass_id' ) ) == 1 ) ||
                           ( $parentNode->canAddLocation() && $node->canRead() ) );

            if ( $canCreate )
            {
                $insertedNode =& $object->addLocation( $selectedNodeID, true );

                // Now set is as published and fix main_node_id
                $insertedNode->setAttribute( 'contentobject_is_published', 1 );
                $insertedNode->setAttribute( 'main_node_id', $node->attribute( 'main_node_id' ) );
                $insertedNode->setAttribute( 'contentobject_version', $node->attribute( 'contentobject_version' ) );
                // Make sure the path_identification_string is set correctly.
                $insertedNode->updateSubTreePath();
                $insertedNode->sync();

                $locationAdded = true;
            }
        }
    }

    if ( $locationAdded )
    {
        include_once( 'lib/ezutils/classes/ezini.php' );
        $ini =& eZINI::instance();
        $userClassID = $ini->variable( "UserSettings", "UserClassID" );

        if ( $object->attribute( 'contentclass_id' ) == $userClassID )
        {
            eZUser::cleanupCache();
        }
    }
    $db->commit();

    include_once( 'kernel/classes/ezcontentcachemanager.php' );
    eZContentCacheManager::clearContentCacheIfNeeded( $objectID );
}