Message-ID: <509285277.4332.1485866202861.JavaMail.confluence@ip-10-127-227-164> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_4331_1034647438.1485866202861" ------=_Part_4331_1034647438.1485866202861 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
The ContentService implemented in eZ Publish 5.1 has no knowledge of the= Legacy workflow engine. This means that all features in the 4.x series tha= t used workflows need a workaround. One of the most common use-cases is pre= -publishing approval, for instance of user generated content.
Fortunately, there is a quite simple way to trigger workflows from eZ Pu= blish 5 code: by using a Legacy Kernel Callback. The overall process is des= cribed in the Lega= cy code and features documentation chapter.
Thanks to this, it is possible to create a draft using native eZ Publish= 5 code, and get this draft pre-approved using the legacy workflow & co= llaboration systems, including email notifications.
Let's take an approval workflow as an example. It needs to be configured= the old way, using the backoffice. Create a workflow, add an Approve event to = it, and connect it to the content/publish/before trigger.
This is done the usual way, as extensively covered in the Public API Cookbook. The main d=
ifferent is that we will NOT call ContentService::publishVersion=
()
.
$contentType =3D $contentTypeService->loadContentTypeByIdentifie= r( $contentTypeIdentifier ); $contentCreateStruct =3D $contentService->newContentCreateStruct( $conte= ntType, 'eng-GB' ); $contentCreateStruct->setField( 'title', $title ); $contentCreateStruct->setField( 'intro', $intro ); $contentCreateStruct->setField( 'body', $body ); $locationCreateStruct =3D $locationService->newLocationCreateStruct( $pa= rentLocationId ); // create a draft using the content and location create struct and publish = it $draft =3D $contentService->createContent( $contentCreateStruct, array( = $locationCreateStruct ) );=20
You need to use the object to run a Legacy Kernel Callback (e.g. code fr= agment). This legacy code will execute the publish operation with the given= content id and version number. It will then check the operation result, an= d return true or false, depending if the operation went all the way through= , or if it was interrupted (approval workflow event, for instance). This ha= ndling could and should of course be enhanced, with error han= dling to begin with, but it doesn't change the core principle.
This example will work in any controller that extends eZ\Publ=
ish\EzPublishCoreBundle\Controller
:
/** * @param $contentId * @param $versionId * @return bool true if the operation was completed, false if it was interr= upted */ protected function runLegacyPublish( $contentId, $versionId, $runAsUserId = =3D null ) { $legacyKernel =3D $this->getLegacyKernel(); return $legacyKernel->runCallback( function () use ( $contentId, $versionId, $runAsUserId ) { $db =3D \eZDB::instance(); $transactionCounter =3D $db->transactionCounter(); if ( $runAsUserId ) { \eZUser::setCurrentlyLoggedInUser( \eZUser::fetch( $runAsUs= erId ), $runAsUserId ); } $operationResult =3D \eZOperationHandler::execute( 'content', 'publish', array( 'object_id' =3D> $contentId= , 'version' =3D> $versionId ) ); if ( ( array_key_exists( 'status', $operationResult ) &&= ; $operationResult['status'] !=3D \eZModuleOperationInfo::STATUS_CONTINUE )= ) { // Required by https://jira.ez.no/browse/EZP-20558 for ( $i =3D 0, $counter =3D ( $db->transactionCounter()= - $transactionCounter ); $i < $counter; ++$i ) { $db->commit(); } return false; } return true; } ); }=20
eZ Script context
If you are running the callback in a command line script, you need to ad= d these calls before executing any legacy code:
$script =3D \eZScript::instance( array( 'use-modules' =3D> true = ) ); $script->initialize();=20
Any Legacy code can be executed this way. While it is a backwar= d compatibility feature, it is considered good practice to work around= missing features. It is however not recommended to rely heavily on Legacy = features for performances reasons.
Pay attention to the user
Public API code is always executed as a user, by default anonymous. Sinc= e workflows are often user dependent (Approval is), it is important that th= is code is executed as an editor, or as a user who will trigger the workflo= w.
$repository->setCurrentUser( $repository->getUserService()-&g= t;loadUser( $userId ) );=20
Of course, this isn't required when using Public API code in controllers= , since those will use the currently-logged in user.
Legacy code also requires a user
By default, code in LegacyKernel::runCallback()
calls is ex=
ecuted as anonymous. You'll have to log the executing user manually on =
legacy as well.
\eZUser::setCurrentlyLoggedInUser( \eZUser::fetch( $runAsUserId ), = $runAsUserId );=20
Content created using the Public API does appear as expected in the dash= board, and the draft can be checked from here. Collaboration options from t= he backoffice are available, and the object's lifecycle can be managed the = way it used to with eZ Publish 4.x.
The code below is a working Command script example that demonstrates the= workaround. Just drop it in a bundle and update the namespace: https://gist.github.com/bdunogier/e05ed564770fa6= a51e51