Forums / Developer / problems with creating and removing nodeassignments

problems with creating and removing nodeassignments

Author Message

Claudia Kosny

Friday 01 December 2006 4:29:36 am

Hi there

I have a content|publish|before workflow which creates or removes nodeassignments for the currently published object depending on some data in a table.

This works fine if I edit and publish an object from the admin siteaccess.

Now I have a form un my user siteaccess, which posts some node ids to a script in an extension. This script puts the verified posted data in a table and published the object which calls my workflow again. Creating new node assignments works fine, the problem is when I want to remove an nodeassignment from the object and then later on assign the object to the same parentnode again:
Directly after calling remove() on the nodeassignment, the opcode is set to 7, which looks ok to me.

When I check the node assignments after publishing using & eZNodeAssignment::fetchForObject( $objectId, $versionNr) then the removed nodeassignemnt is still listed there, but with opcode 6. When I check using object->assignedNodes(), the removed nodeassignment is not listed.
When I check the object->attribute('parent_nodes'), the removed parentnode is also not listed.

The problem is that when I some time later try to create a nodeassignment to a parentnode where the object had had a nodeassignment sometimes before. The new node assignment is created fine with opcode 3, but in the function publishNode of the ezcontentoperationcollection.php the nodeassignment is fetched by objectid, versionnr and parentnodeid. This causes problems because sometimes it will find the nodeassignment I removed before which has opcode 6, so it does not do anything. Sometimes it also fetches the newly created node assignment, I think this depends on the position in the table, I am not sure.

When I use nodeassignment->purge() instead of ->remove(), the nodeassignment is deleted but the information about the parentnodes is not updated. Thus the additional locations are still listed in the admin view and the parentnodes list the object as subitem, so this does not solve the problem.

I have cleared the cache before and after publishing the object so I don't think it is a caching problem. I also gave all users the administrator role (for testing only), in case it has something to do with permissions, but this did not change anything.

Here the part of the workflow that creates or removes the nodeassignments, which is partially stolen from the ezlocations contribution. $channelNodeIdArr is the array with node ids for the additional locations.

include_once('kernel/classes/eznodeassignment.php');
$db =& eZDB::instance();
$db->begin();
//fetch all parent nodes of the expert
$parentNodesArr = $object->attribute('parent_nodes');
eZDebug::writeDebug('parent nodes before: "' . print_r($parentNodesArr, true) . '"', 'ezlocationstype::execute' );    

$usedParentIdArr = array();
if(is_array($channelNodeIdArr))
{               
  foreach($channelNodeIdArr as $channelNodeId)
  {
    //check if the expert is already assigned to this channel
    if(in_array($channelNodeId, $parentNodesArr))
    {
      $usedParentIdArr[] = $channelNodeId;
      eZDebug::writeError('Expert already assigned to channel with id "' . $channelNodeId . '", nothing to do', 'ezlocationstype::execute' );    
      continue;
    }
    $nodeAssignment[$channelNodeId] =& eZNodeAssignment::create(
         array('contentobject_id' => $objectId,
               'contentobject_version' => $versionNr,
               'parent_node' => $channelNodeId,
               'is_main' => 0));
    $nodeAssignment[$channelNodeId]->store();
    
    eZDebug::writeDebug('Gave expert new node assignment under channel id "' . $channelNodeId . '"', 'ezlocationstype::execute' );    
  }
}
//remove any obsolete node assignments except node assignment in user group experts(node id 65)
$allNodeAssignmentsArr =& eZNodeAssignment::fetchForObject( $objectId, $versionNr);
$obsoleteParentNodeArr = array_diff($parentNodesArr, $usedParentIdArr);
eZDebug::writeDebug('before removing' . print_r($allNodeAssignmentsArr, true), 'ezlocationstype::execute' );    

if(is_array($allNodeAssignmentsArr) && count($allNodeAssignmentsArr)>0)
{
  $tmpKeyArr = array_keys($allNodeAssignmentsArr);
  foreach($tmpKeyArr as $key)
  {
    $nodeAssignment =& $allNodeAssignmentsArr[$key];
    if(in_array($nodeAssignment->attribute('parent_node'), $obsoleteParentNodeArr))
    {
      if($nodeAssignment->attribute('parent_node') != '65')
      {
        $nodeAssignment->remove();
      
        eZDebug::writeDebug('Removed assignment of this expert to channel with node id "' . $nodeAssignment->attribute('parent_node') . '"', 'ezlocationstype::execute' );    
      }
    }          
  }
}
$foo =& eZNodeAssignment::fetchForObject( $objectId, $versionNr);      
eZDebug::writeDebug('after removing ' . print_r($foo, true), 'ezlocationstype::execute' );    

$db->commit();   

I spent the last twelve hours first trying to find out what is going wrong and then how to fix it, so I would be very grateful (and rather desperate) for any hint...

Thanks

Claudia

Claudia Kosny

Friday 01 December 2006 8:57:09 am

I solved the problem by reusing the nodeassignments with an opcode of 6, I just set the opcode to 2 if the parentnode is the same. I just hope it does not bite me in the behind later on...