Path

ez projects / ezssp / forum / general / ezp 4.x compatible release...


ezp 4.x compatible release status?

You need to be logged in to post messages in the forums. New users may register here.

Norbert Wagner

Member since:
09 January 2008

Posts: 5

Thursday 29 January 2009 12:12:20 pm

Hi,
what is the status of trunk, is it usable?
Are there chances of a eZ Publish 4.x release soon?

I would be very interested in this extension, perhaps I'll take a lunk at the trunk version.

Thanks,
Norbert
Up

Kristof Coomans

Member since:
12 February 2004

Posts: 68

Thursday 29 January 2009 1:09:42 pm

Hi Norbert

Work on this extension is currently in the fridge, but you can use the trunk version for eZ Publish 4. If you discover any issues in it, then let us know. Good luck ;)

independent eZ Publish developer and service provider | http://blog.coomanskristof.be | http://ezpedia.org

Up

Norbert Wagner

Member since:
09 January 2008

Posts: 5

Thursday 29 January 2009 1:22:18 pm

Ok, I'll give it a try and let you know.

Thanks,
Norbert
Up

Sebastian Schoeller

Member since:
07 March 2003

Posts: 9

Tuesday 27 October 2009 8:17:22 am

Hi Norbert, hi Kristof,

I think to have changed the code of ezssp in order to work with ez 4.2. I had changed some lines of code in subtreeskeletonpublishtype.php exclusively for the ezXML and ezDOMDocument objects, without knowing anything about eZ/php and it seems to work. Here it is:




<?php


//


// ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##


// SOFTWARE NAME: eZ publish Subtree Skeleton Publisher extension


// SOFTWARE RELEASE: 0.x


// COPYRIGHT NOTICE: Copyright (C) 2007 Kristof Coomans <http://blog.kristofcoomans.be>


// SOFTWARE LICENSE: GNU General Public License v2.0


// NOTICE: >


//  This program is free software; you can redistribute it and/or


//  modify it under the terms of version 2.0 of the GNU General


//  Public License as published by the Free Software Foundation.


//


//  This program is distributed in the hope that it will be useful,


//  but WITHOUT ANY WARRANTY; without even the implied warranty of


//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


//  GNU General Public License for more details.


//


//  You should have received a copy of version 2.0 of the GNU General


//  Public License along with this program; if not, write to the Free


//  Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,


//  MA 02110-1301, USA.


//


//


// ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##


//


 

class SubtreeSkeletonPublishType extends eZWorkflowEventType


{


   var $oldNodeIDToNewObjectIDMap = array();


   var $ownerID;


 

   function SubtreeSkeletonPublishType()


   {


       $this->eZWorkflowEventType( 'subtreeskeletonpublish', ezi18n( 'extension/ezssp', 'Subtree Skeleton Publisher' ) );


       // limit workflows which use this event to be used only on the post-publish trigger


       $this->setTriggerTypes( array( 'content' => array( 'publish' => array( 'after' ) ) ) );


 

       $this->oldNodeIDToNewObjectIDMap = array();


   }


 

   function attributeDecoder( $event, $attr )


   {


       $retValue = null;


       switch( $attr )


       {


           case 'skeleton_node_id':


           {


               $retValue = $event->attribute( 'data_int1' );


           } break;


 

           case 'skeleton_user_groups':


           {


               $retValue = $this->unserializeUserGroupsConfig( $event );


           } break;


 

           case 'role_list':


           {


               $retValue = eZRole::fetchList();


           } break;


 

           default:


           {


               eZDebug::writeNotice( 'unknown attribute: ' . $attr, 'SubtreeSkeletonPublishType' );


           }


       }


       return $retValue;


   }


 

   function typeFunctionalAttributes()


   {


       return array( 'skeleton_node_id', 'skeleton_user_groups', 'role_list' );


   }


 

   function unserializeUserGroupsConfig( $event )


   {


       $retValue = array();


       $xmlString = $event->attribute( 'data_text1' );


       if ( $xmlString =='' )


       {


           return $retValue;


       }


 

      $dom = new DOMDocument();


      $dom->loadXML( $xmlString );


      $root = $dom->documentElement;


      $groups = $root->getElementsByTagName( 'group' );


 

       foreach ( $groups as $group )


       {


           $nodeID = $group->getAttribute( 'node_id' );


           $addOwner = ( $group->getAttribute( 'add_owner' ) !== false );


           $roles = $group->getElementsByTagName( 'role' );


           $roleList = array();


           foreach ( $roles as $role )


           {


               $roleList[] = $role->getAttribute( 'role_id' );


           }


 

           $retValue[$nodeID] = array( 'roles' => $roleList, 'add_owner' => $addOwner );


       }


 

       return $retValue;


   }


 

   function serializeUserGroupsConfig( $userGroups )


   {


       $dom = new DOMDocument();


       $skeleton = $dom->createElement( 'skeleton' );


       $dom->appendChild( $skeleton );


 

       foreach ( $userGroups as $nodeID => $groupConfig )


       {


           unset( $groupNode );


           $groupNode = $dom->createElement( 'group' );


           $groupNode->setAttribute( 'node_id', $nodeID );


           $skeleton->appendChild( $groupNode );


 

           if ( $groupConfig['add_owner'] == true )


           {


               $groupNode->setAttribute( 'add_owner', 'true' );


           }


 

           if ( array_key_exists( 'roles', $groupConfig ) )


           {


               foreach ( $groupConfig['roles'] as $roleID )


               {


                   unset( $roleNode );


                   $roleNode = $dom->createElement( 'role' );


                   $roleNode->setAttribute( 'role_id', $roleID );


                   $groupNode->appendChild( $roleNode );


               }


           }


       }


 

       $xmlString = $dom->saveXML();


       return $xmlString;


   }


 

   function fetchHTTPInput( $http, $base, $event )


   {


       $userGroups = $this->attributeDecoder( $event, 'skeleton_user_groups' );


 

       // this condition can be removed when this issue if fixed: http://issues.ez.no/10685


       if ( count( $_POST ) > 0 )


       {


           $userGroups = $this->attributeDecoder( $event, 'skeleton_user_groups' );


 

           $userGroupRoles = array();


           $rolesPostVarName = 'UserGroupRoleList_' . $event->attribute( 'id' );


           if ( $http->hasPostVariable( $rolesPostVarName ) )


           {


               $userGroupRoles = $http->postVariable( $rolesPostVarName );


           }


 

           $addOwnerGroups = array();


           $addOwnerPostVarName = 'UserGroupAddOwner_' . $event->attribute( 'id' );


           if ( $http->hasPostVariable( $addOwnerPostVarName ) && is_array( $http->postVariable( $addOwnerPostVarName ) ) )


           {


               $addOwnerGroups = $http->postVariable( $addOwnerPostVarName );


           }


 

           foreach ( $userGroups as $groupID => $groupConfig )


           {


               if ( array_key_exists( $groupID, $userGroupRoles ) )


               {


                   $userGroups[$groupID]['roles'] = $userGroupRoles[$groupID];


               }


               else


               {


                   $userGroups[$groupID]['roles'] = array();


               }


 

               $userGroups[$groupID]['add_owner'] = in_array( $groupID, $addOwnerGroups );


           }


 

           $serializedUserGroupsConfig = $this->serializeUserGroupsConfig( $userGroups );


           eZDebug::writeDebug( $serializedUserGroupsConfig, 'fetchHTTPInput' );


           $event->setAttribute( 'data_text1', $serializedUserGroupsConfig );


       }


   }


 

   /*!


    \reimp


   */


   function customWorkflowEventHTTPAction( $http, $action, $workflowEvent )


   {


       $eventID = $workflowEvent->attribute( 'id' );


       $module = $GLOBALS['eZRequestedModule'];


 

       switch ( $action )


       {


           case 'SelectSkeleton':


           {


               eZContentBrowse::browse( array( 'action_name' => 'SelectSkeleton',


                                               'browse_custom_action' => array( 'name' => 'CustomActionButton[' . $eventID . '_SkeletonSelected]',


                                                                                'value' => $eventID ),


                                               'from_page' => '/workflow/edit/' . $workflowEvent->attribute( 'workflow_id' ),


                                               'ignore_nodes_select' => $this->attributeDecoder( $workflowEvent, 'skeleton_node_id' )


                                              ),


                                        $module );


           } break;


 

           case 'SkeletonSelected':


           {


               $nodeList = eZContentBrowse::result( 'SelectSkeleton' );


               if ( $nodeList )


               {


                   $workflowEvent->setAttribute( 'data_int1', $nodeList[0] );


               }


           } break;


 

           case 'AddSkeletonUserGroups':


           {


               eZContentBrowse::browse( array( 'action_name' => 'AddSkeletonUserGroups',


                                               'browse_custom_action' => array( 'name' => 'CustomActionButton[' . $eventID . '_SkeletonUserGroupsAdded]',


                                                                                'value' => $eventID ),


                                               'start_node' => $this->attributeDecoder( $workflowEvent, 'skeleton_node_id' ),


                                               'from_page' => '/workflow/edit/' . $workflowEvent->attribute( 'workflow_id' ),


                                               'ignore_nodes_select' => array_keys( $this->attributeDecoder( $workflowEvent, 'skeleton_user_groups' ) )


                                              ),


                                        $module );


           } break;


 

           case 'SkeletonUserGroupsAdded':


           {


               $nodeList = eZContentBrowse::result( 'AddSkeletonUserGroups' );


               if ( $nodeList )


               {


                   $this->addUserGroups( $workflowEvent, $nodeList );


               }


           } break;


 

           case 'RemoveSkeletonUserGroups':


           {


               $removeVarName = 'DeleteUserGroupIDList_' . $eventID;


               if ( $http->hasPostVariable( $removeVarName ) )


               {


                   $removeList = $http->postVariable( $removeVarName );


                   $this->removeUserGroups( $workflowEvent, $removeList );


               }


           } break;


 

           default:


           {


               eZDebug::writeNotice( 'unknown custom action: ' . $action, 'SubtreeSkeletonPublishType' );


           }


       }


   }


 

   /*!


    \brief Adds user groups to the list


   */


   function addUserGroups( $workflowEvent, $nodeList )


   {


       $userGroups = $this->attributeDecoder( $workflowEvent, 'skeleton_user_groups' );


 

       foreach ( $nodeList as $nodeID )


       {


           if ( !array_key_exists( $nodeID, $userGroups ) )


           {


               $userGroups[$nodeID] = array( 'roles' => array(), 'add_owner' => false );


           }


       }


 

       $serializedUserGroupsConfig = $this->serializeUserGroupsConfig( $userGroups );


       eZDebug::writeDebug( $serializedUserGroupsConfig, 'addUserGroups' );


       $workflowEvent->setAttribute( 'data_text1', $serializedUserGroupsConfig );


   }


 

   function removeUserGroups( $workflowEvent, $nodeList )


   {


       $userGroups = $this->attributeDecoder( $workflowEvent, 'skeleton_user_groups' );


 

       foreach ( $nodeList as $nodeID )


       {


           if ( array_key_exists( $nodeID, $userGroups ) )


           {


               unset( $userGroups[$nodeID] );


           }


       }


 

       $serializedUserGroupsConfig = $this->serializeUserGroupsConfig( $userGroups );


       eZDebug::writeDebug( $serializedUserGroupsConfig, 'removeUserGroups' );


       $workflowEvent->setAttribute( 'data_text1', $serializedUserGroupsConfig );


   }


 

   function execute( $process, $event )


   {


       // global variable to prevent endless recursive workflows with this event


       $recursionProtect = 'SubTreeSkelectonPublishType_recursionprotect_' . $event->attribute( 'id' );


       if ( array_key_exists( $recursionProtect, $GLOBALS ) )


       {


           return eZWorkflowType::STATUS_ACCEPTED;


       }


 

       $parameters = $process->attribute( 'parameter_list' );


       $object = eZContentObject::fetch( $parameters['object_id'] );


 

       // if the object is not published for the first time, then we don't do anything


       if ( $object->attribute( 'modified' ) != $object->attribute( 'published' ) )


       {


           return eZWorkflowType::STATUS_ACCEPTED;


       }


 

       // put the following block in comments for easy debugging


 

       // defer to cron, this is safer because we are going to create some other objects as well


       if ( eZSys::isShellExecution() == false )


       {


           return eZWorkflowType::STATUS_DEFERRED_TO_CRON_REPEAT;


       }


 

       if ( !array_key_exists( $recursionProtect, $GLOBALS ) )


       {


           $GLOBALS[$recursionProtect] = true;


       }


 

       $this->copySkeleton( $object, $event );


       $this->addOwnerLocation( $object, $event );


       $this->assignRoles( $object, $event );


 

       unset( $GLOBALS[$recursionProtect] );


       return eZWorkflowType::STATUS_ACCEPTED;


   }


 

   function addOwnerLocation( $object, $event )


   {


       $userGroups = $this->attributeDecoder( $event, 'skeleton_user_groups' );


       $userID = $object->attribute( 'owner_id' );


 

       foreach ( $userGroups as $groupNodeID => $groupConfig )


       {


           if ( $groupConfig['add_owner'] == true )


           {


               if ( !array_key_exists( $groupNodeID, $this->oldNodeIDToNewObjectIDMap ) )


               {


                   // show debug warning


                   continue;


               }


 

               $newGroupID = $this->oldNodeIDToNewObjectIDMap[$groupNodeID];


 

               $operationResult = eZOperationHandler::execute( 'membership', 'register', array( 'group_id' => $newGroupID, 'user_id' => $userID ) );


           }


       }


   }


 

   function assignRoles( $object, $event )


   {


       $madeChanges = array();


 

       $db = eZDB::instance();


       $db->begin();


 

       $userGroups = $this->attributeDecoder( $event, 'skeleton_user_groups' );


       foreach ( $userGroups as $groupNodeID => $groupConfig )


       {


           // use the node id of the copied node


           if ( !array_key_exists( $groupNodeID, $this->oldNodeIDToNewObjectIDMap ) )


           {


               // show debug warning


               continue;


           }


 

           $newGroupID = $this->oldNodeIDToNewObjectIDMap[$groupNodeID];


 

           foreach ( $groupConfig['roles'] as $roleID )


           {


               $role = eZRole::fetch( $roleID );


 

               if ( !is_object( $role ) )


               {


                   // show debug warning


                   continue;


               }


 

               $projectNode = $object->attribute( 'main_node' );


               $pathString = $projectNode->attribute( 'path_string' );


 

               $query = "INSERT INTO ezuser_role ( role_id, contentobject_id, limit_identifier, limit_value ) VALUES ( '$roleID', '$newGroupID', 'Subtree', '$pathString' )";


               $db->query( $query );


           }


       }


 

       $db->commit();


 

       if ( in_array( true, $madeChanges ) )


       {


           eZRole::expireCache();


 

           eZContentCacheManager::clearAllContentCache();


 

           eZUser::cleanupCache();


       }


   }


 

   /*


       PART: SKELETON


   */


   function copySkeleton( $object, $event )


   {


       $projectNode = $object->attribute( 'main_node' );


       $this->ownerID = $object->attribute( 'owner_id' );


 

       $skeletonNodeID = $this->attributeDecoder( $event, 'skeleton_node_id' );


       $skeletonNode = eZContentObjectTreeNode::fetch( $skeletonNodeID );


 

       $this->copyChildrenRecursive( $skeletonNode, $projectNode );


   }


 

    /*


       Maybe we need to use this first parameter, to ignore policies


       But I don't think it does any harm that each user can read the skeleton


 

       array( 'Limitation' => array() )


 

       maybe it's useful to not read every node because of permissions of the project creator


       then we can insert customer groups and other stuff too in the skeleton


   */


   function copyChildrenRecursive( $sourceParentNode, $targetParentNode )


   {


       $db = eZDB::instance();


       $db->begin();


 

       $sourceParentNodeID = $sourceParentNode->attribute( 'node_id' );


 

       $timeSortFields = array( 'published', 'modified', 'modified_subnode' );


       $sortOrder = $sourceParentNode->attribute( 'sort_order' );


       $sortField = $sourceParentNode->attribute( 'sort_field' );


       $delay = false;


 

       if ( in_array( eZContentObjectTreeNode::sortFieldName( $sortField ), $timeSortFields ) )


       {


           // bitwise NOT


           $sortOrder = ~ $sortOrder;


           $delay = true;


       }


 

       $sortArray = eZContentObjectTreeNode::sortArrayBySortFieldAndSortOrder( $sourceParentNode->attribute( 'sort_field' ), $sortOrder );


 

       $subTreeParams = array(


           'Depth' => 1,


           'DepthOperator' => 'eq',


           'Limitation' => array(),


           'SortBy' => $sortArray


           );


 

       $sourceNodeList = eZContentObjectTreeNode::subTreeByNodeID( $subTreeParams, $sourceParentNodeID );


 

       foreach ( $sourceNodeList as $sourceNode )


       {


           eZDebug::writeDebug( $sourceNode->attribute( 'name' ) );


           $newNode = $this->copyNode( $sourceNode, $targetParentNode, $sourceParentNode );


           $this->oldNodeIDToNewObjectIDMap[$sourceNode->attribute( 'node_id' )] = $newNode->attribute( 'contentobject_id' );


           $sourceObj = $sourceParentNode->object();


           $contentClass = $sourceObj->attribute( 'content_class' );


           if ( $contentClass->attribute( 'is_container' ) )


           {


               $this->copyChildrenRecursive( $sourceNode, $newNode );


           }


 

           if ( $delay )


           {


               eZDebug::writeDebug( 'found timed-sorted subtree, sleeping 2 seconds' );


               sleep( 2 );


           }


       }


 

       $db->commit();


   }


 

   function copyNode( $sourceNode, $targetParentNode, $sourceParentNode )


   {


       $sourceParentObject = $sourceParentNode->attribute( 'object' );


       $tagetParentObject = $targetParentNode->attribute( 'object' );


       $object = $sourceNode->attribute( 'object' );


 

       $sectionID = $tagetParentObject->attribute( 'section_id' );


       if ( $object->attribute( 'section_id' ) != $sourceParentObject->attribute( 'section_id' ) )


       {


           $sectionID = $object->attribute( 'section_id' );


       }


 

       //eZDebug::writeDebug( 'section id: ' . $sectionID );


 

       $newObject = $object->copy( false );


       $newObject->setAttribute( 'section_id', $sectionID );


       $newObject->setAttribute( 'owner_id', $this->ownerID );


       $newObject->store();


       $newParentNodeID = $targetParentNode->attribute( 'node_id' );


 

       $curVersion       = $newObject->attribute( 'current_version' );


       $curVersionObject = $newObject->attribute( 'current' );


       $curVersionObject->setAttribute( 'creator_id', $this->ownerID );


       $curVersionObject->store();


       $newObjAssignments = $curVersionObject->attribute( 'node_assignments' );


       unset( $curVersionObject );


 

       // remove old node assignments


       foreach( $newObjAssignments as $assignment )


       {


           $assignment->remove();


       }


 

       // and create a new one


       $nodeAssignment = eZNodeAssignment::create( array(


                                                        'contentobject_id' => $newObject->attribute( 'id' ),


                                                        'contentobject_version' => $curVersion,


                                                        'parent_node' => $newParentNodeID,


                                                        'is_main' => 1,


                                                        'sort_field' => $sourceNode->attribute( 'sort_field' ),


                                                        'sort_order' => $sourceNode->attribute( 'sort_order' )


                                                        ) );


       $nodeAssignment->store();


 

       $result = eZOperationHandler::execute( 'content', 'publish',


           array( 'object_id' => $newObject->attribute( 'id' ),


                  'version'  => $curVersion ) );


 

       // Update "priority" and "is_invisible" attribute for the newly created node.


       $newNode = $newObject->attribute( 'main_node' );


       $newNode->setAttribute( 'priority', $sourceNode->attribute( 'priority' ) );


       $newNode->store();


       eZContentObjectTreeNode::updateNodeVisibility( $newNode, $targetParentNode );


 

       return $newNode;


   }


}


 

eZWorkflowEventType::registerEventType( 'subtreeskeletonpublish', 'SubtreeSkeletonPublishType' );


 

?>


Up

You need to be logged in to post messages in the forums. New users may register here.