Right way to create an eZ object using PHP

Author Message

Hakim Bouras

Friday 12 March 2010 3:41:37 am

Hi,

I have a few questions about the right way to create an ez object, using PHP.

I was not able to find a place where there are clear guidelines on the subject. So from different places I checked (forum, eZpedia, API code) I figured out the following steps :

1/ getting an instance of the class of the object

2/ creating an object from the class (adding records in tables ezcontentobject and ezcontentobject_attribute )
$object = $class->instantiate( $userID, $sectionID, $version, $languageCode, eZContentObjectVersion::STATUS_INTERNAL_DRAFT );

3/ setting internal object attributes using
$object->setAttribute( <attribute_name>, <attribute_value> );
(...);
$object->store();

4/ setting other attributes using }
$dataMap = $object->attribute( 'data_map' );
$attribute = $dataMap[ <attribute_name> ];
$attribute->setAttribute( <attribute_type>, <attribute_value> );
$attribute->sync();

5/ creating a node assignement (adding record a record in table eznode_assignment)
$nodeAssignment = $object->createNodeAssignment( $parentNodeID,
$isMain, $remoteID,
$class->attribute( 'sort_field' ),
$class->attribute( 'sort_order' ) );

What is the purpose of this step - is it mandatory ? What the assignment is used for in ez Publish ?It is not clear to understand this assignment of a node that does not yet exist (there are no ezcontentobject_tree object created at this step)

6/ publishing the object, which is doing a lot of things and along them:

  • create a node (main node)
  • update the publishing date of the object
  • update the op_code of the nodeAsssignment
  • call custom edit handler and workflow scripts
  • ...

$operationResult = eZOperationHandler::execute( 'content',
'publish',
array( 'object_id' => $object->ID,
'version' => $object->CurrentVersion )
);

We need to fetch again the object, for the $object to hold of the changes made during the publish process. Is there a way to directly pass the $object to a publish process so that we do not need to refetch the current object ?

Is this process correct ? Are there any "more efficient way" to do it ?

And a last question about object updating.

Is there a way to update a published object without having to republish it ? When I only "store" my changes, they are not directely available, unless I republish the object - which is a problem when updating an object in a workflow or a custom edit handler (because it makes a loop)

Thanks for all your feedback, and once I get the answers I will post the global method I wrote to handle object creation and hide the complexity.

Hakim Bouras
PRISMALOG - Creation de site Internet

Matthieu Sévère

Friday 12 March 2010 6:42:56 am

Hello Hakim,

I'm using this :

$params = array();                
$params['parent_node_id'] = $ini->variable('purchase_settings','stockists_folder_node_id');   
$params['class_identifier'] = 'stockist'; 
$params['creator_id'] = 14; // admin
$params['attributes'] = $attributesData;
$contentObject = eZContentFunctions::createAndPublishObject( $params );

In attributesDate you store an associative array with all the attributes of your object

You can also look here : http://pubsvn.ez.no/websvn2/listing.php?repname=nextgen&path=/trunk/tests/toolkit/extras/kernelwrapper/#path_trunk_tests_toolkit_extras_kernelwrapper_

You'll find a kernel wrapper. I think eZ Systems use it for their unit tests.

Cheers

--
eZ certified developer: http://ez.no/certification/verify/346216

Hakim Bouras

Monday 15 March 2010 3:31:12 am

Hi Matthieu,

Thanks for your answer.

I did not know about the eZContentFunctions::createAndPublishObject method and about the kernel wrapper classes (ezpClass, ezpObject and ezpNode) available in the "Test" folder.

Both are interresting sources to understand the process, and gives some more information to handle attributes, versions and language versions.

I am still wondering :

  • what the NodeAssignment is used for ?
  • is there a way to update object attributes without republishing the object?

Hakim

Matthieu Sévère

Monday 15 March 2010 4:07:49 am

A node is used to build your content tree.

A object is an instance of your content type.

A node assignment is used to link your object to a node and then give him a position in your content tree.

I don't really understand what you mean by republish the object but basically when you edit an object is create a draft you can store it for later editing or publish it so that it becomes your published version.

--
eZ certified developer: http://ez.no/certification/verify/346216

Hakim Bouras

Monday 15 March 2010 5:50:39 am

>>A node assignment is used to link your object to a node and then give him a position in your content tree.

From what I have seen in the structure of a NodeAssignment, there is no information about the content tree (which is built in the TreeNode objects - ezcontentobject_tree table).

It looks like there is a relation 1 to 1 or 1 to 0 between the two tables and there is an "op_code" field and a "from_node_id" (which is set either to 0 or -1) in the table eznode_assignment that are not available in ezcontentobject_tree.

There might be a reason why of this structure but I do not get it.

>> I don't really understand what you mean by republish the object
>> but basically when you edit an object is create a draft you can store it
>> for later editing or publish it so that it becomes your published version.

I was talking about updating an object through a php script, not through the user interface. I do not think that draft versions are created automatically when you update the attribute of an object, I suspect that you would have to create explicitely a draft version of the object.

Hakim

Igor Vrdoljak

Thursday 18 March 2010 10:44:35 pm

Hi Hakim

You can change your content objects without republishing them. I use it rather often, due to heavy processing included in publishing new version of an object, which makes it impractical if you are doing a batch of work including changing a few thousand objects.

The procedure is very simple, you fetch current version of your object, change the attributes and store the changes. The last thing you need to do is to clear the caches, so that your view cache would be correctly created.

$contentObject = $node->attribute('object');

// get the current version,you can also set the modified timestamp
$version = $contentObject->version($contentObject->attribute('current_version'));
$version->setAttribute( 'modified', eZDateTime::currentTimeStamp() );

// change the attributes
...
...

// store the changes and clear view cache of the object
$contentObject->store();
$contentObject->expireAllViewCache();

// also, you may have need to change the object name:
$class = $contentObject->contentClass();
$contentObject->setName( $class->contentObjectName( $contentObject ) );
$contentObject->store();

http://www.netgen.hr/eng
http://twitter.com/ivrdoljak

Hakim Bouras

Friday 26 March 2010 4:14:01 am

Thanks Igor for your explanations. It works fine, and the part about updating the name was very usefull as well.

Cheers,

Hakim

Alex Kozeka

Thursday 04 November 2010 5:35:06 am

Hi,

Could someone also help to find correct way of setting default sort order for newly created or already existing node?

I thought that the code:

$nodeAssignment = $object->createNodeAssignment( $parentNodeID,$isMain, $remoteID,$class->attribute( 'sort_field' ),$class->attribute( 'sort_order' ) );

should do the job, however it didn't.

Internal research showed that 'ezcontentobject_tree' table stores child nodes sort type and sort order, and not 'eznode_assignment' (but it also has related fields) but didn't find place in code where it is used.

--
Argentea S.p.A., http://www.argentea.it/

Powered by eZ Publish™ CMS Open Source Web Content Management. Copyright © 1999-2014 eZ Systems AS (except where otherwise noted). All rights reserved.