
I was looking for solution how to place comments form below weblog entry in eZ publish so I decide to create custom action. I will try to explain how to define custom Action in eZ publish which create new comment object.
In example extension (ezcomment) with new action which create new comment directory structure looks like:
extension/ezcomments | | - actions | | - content_actionhandler.php | - settings | | - content.ini.append.php
You will have to override content.ini in your extension and add
extension/mynewextension/settings/content.ini.append.php
[ActionSettings]
ExtensionDirectories[]=mynewextension
For ezcomments extension this will be extension/ezcomments/settings/content.ini.append.php with code:
<?php /* [ActionSettings] ExtensionDirectories[]=ezcomments */ ?>
Body of new custom action must be placed in:
extension/mynewextension/actions/content_actionhandler.php
This is general structure of new Action:
<?php function mynewextension_ContentActionHandler( &$module, &$http, &$objectID ) { if( $http->hasPostVariable("CustomAction") ) { //your custom action goes here } } ?>
Function name have to start with extension name, other ways it will not work
In ezcomments example code will look more complex, since it will create new comment object.
code from extension/ezcomments/actions/content_actionhandler.php
<?php include_once( 'lib/ezutils/classes/ezoperationhandler.php' ); function eZComments_ContentActionHandler( &$module, &$http, &$objectID ) { if( $http->hasPostVariable( 'AddComment' ) ) { // fetch object and read node ID $object =& eZContentObject::fetch( $objectID ); $nodeID = $object->attribute( 'main_node_id' ); // read user variable $subject = $http->postVariable( 'Subject' ); $author = $http->postVariable( 'Author' ); $message = $http->postVariable( 'Message' ); // prepare new object data $parentNodeID = $nodeID; $userID = 10; $class = eZContentClass::fetchByIdentifier( 'comment' ); $parentContentObjectTreeNode = eZContentObjectTreeNode::fetch( $parentNodeID ); $parentContentObject = $parentContentObjectTreeNode->attribute( 'object' ); $sectionID = $parentContentObject->attribute( 'section_id' ); $contentObject =& $class->instantiate( $userID, $sectionID ); $contentObjectID = $contentObject->attribute( 'id' ); $nodeAssignment =& eZNodeAssignment::create( array( 'contentobject_id' => $contentObject->attribute( 'id' ), 'contentobject_version' => $contentObject->attribute( 'current_version' ), 'parent_node' => $parentContentObjectTreeNode->attribute( 'node_id' ), 'is_main' => 1 ) ); $nodeAssignment->store(); $contentObjectAttributes =& $contentObject->contentObjectAttributes(); $loopLenght = count( $contentObjectAttributes ); // fill up content object attributes with user data for( $i = 0; $i < $loopLenght; $i++ ) { switch( $contentObjectAttributes[$i]->attribute( 'contentclass_attribute_identifier' ) ) { case 'subject': $contentObjectAttributes[$i]->setAttribute( 'data_text', $subject ); $contentObjectAttributes[$i]->store(); break; case 'author': $contentObjectAttributes[$i]->setAttribute( 'data_text', $author ); $contentObjectAttributes[$i]->store(); break; case 'message': $contentObjectAttributes[$i]->setAttribute( 'data_text', $message ); $contentObjectAttributes[$i]->store(); break; } } $contentObject->setAttribute( 'status', EZ_VERSION_STATUS_DRAFT ); $contentObject->store(); // publish new comment $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $contentObjectID, 'version' => 1 ) ); // redirect to weblog full view $module->redirectTo( '/content/view/full/' . $nodeID ); } } ?>
The simplest form for new custom action will look like:
<form method="post" action={"content/action"|ezurl}>
<input type="submit" name="CustomAction" value="Custom action" />
<input name="ContentObjectID" type="hidden" value="102" />
</form>
ContentObjectID have to be included in POST.
In ezcomments extension example from will include Subject, Author and Message input fields. Code blow can be placed in weblog_full.tpl. User will see form which can use for posting new comment:
<form method="post" action={"content/action"|ezurl}>
Subject: <input type="text" name="Subject" value="" /><br />
Author: <input type="text" name="Author" value="" /><br />
Message: <textarea name="Message"></textarea><br />
<input type="submit" name="AddComment" value="Submit" />
<input name="ContentObjectID" type="hidden" value="{$node.object.id}" />
</form>
That's all. We have new action that create new comment under weblog object. Code from content_actionhandler.php (ezcomments) need of course some additional checking for incoming data, validation, etc. but shows how custom action works in the eZ publish.


Hi Lukasz
and thank you for this useful post.
Is this code still OK for the 4.0 version of eZ publish?
If not, what should I change?
As mentioned in this post (http://ez.no/developer/forum/developer/postvariable_names_in_ezhttptool_with_ez_4_0) I can't have postVariables retrieved in a webservice extensions that seems to work for static values.
Thanks in advance for your tips.
Mickael

Hi Ćukasz
A little enhancement to your example code: if you return true from the action handler function, the content/action view will exit from the loop over all action handlers. It's just a little bit faster in case you have other action handler extension.

I've checked my code half a dozen times, and can't find anything wrong. But, for whatever reason, my action extionsion is not recognized. The only debug info I get returned is
"Error: kernel/content/action.php, Unknown content object action"
What am I doing wrong?

where can i found weblog_full.tpl or where can i create it ?

Hi,
Using this mechanism how can I retrieve a file which is part of object attribute? Then I want to e-mail that file as an attachment. Is it possible? If so plz, guide me
Looking for early response.

Yes, thank you very much!
It's very clear to me now.
Keep up the good work!

ContentObjectID is the parent object id under which new object will be created. So in case where parent object is Weblog entry we will use it ID and comment will be created under weblog entry. Hope it is understand now?

Hi,
I suggest you to use the wonderfull powercontent extension from Kristof, you don't have to code anything and get the same result (unless I misunderstood something).
X+

Hi,
Thanks for publishing a solution on how to create custom form actions!
I have only one question: "How will the ContentObjectID be assigned through HTTP-POST if you haven't even created an object yet?"
Thanks in advance.
Richard Tuin

Hi Bruce,
Thanks for comment. Code was tested with 3.6/3.7 should work with older versions as well. Possibility to have custom actions was added since rev. 1226 so in earlier eZ publish version. Very useful functionality ;)

Hi
Capture form field values and inject to template
Wednesday 20 August 2008 8:01:37 am
David ‹neriodavid_at_gmail.com›
Hi,
Good article.
I want to create an action that capture the fields value in the form, then assign these value to the template variable/parameters of a template which the action redirects to.
So, I can show some content based on the user input in the form.
How to do that?