eZ Publish  [trunk]
ezmoduleoperationinfo.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZModuleOperationInfo class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package lib
00009  */
00010 
00011 /*!
00012   \class eZModuleOperationInfo ezmoduleoperationinfo.php
00013   \brief The class eZModuleOperationInfo does
00014 
00015 */
00016 
00017 class eZModuleOperationInfo
00018 {
00019     const ERROR_NO_CLASS = 5;
00020     const ERROR_NO_CLASS_METHOD = 6;
00021     const ERROR_CLASS_INSTANTIATE_FAILED = 7;
00022     const ERROR_MISSING_PARAMETER = 8;
00023 
00024     const STATUS_CONTINUE = 1;
00025     const STATUS_CANCELLED = 2;
00026     const STATUS_HALTED = 3;
00027     const STATUS_REPEAT = 4;
00028     const STATUS_QUEUED = 5;
00029 
00030     /**
00031      * Constructor
00032      * @param string $moduleName
00033      * @param bool $useTriggers
00034      */
00035     function eZModuleOperationInfo( $moduleName, $useTriggers = true )
00036     {
00037         $this->ModuleName = $moduleName;
00038         $this->IsValid = false;
00039         $this->OperationList = array();
00040         $this->Memento = null;
00041         $this->UseTriggers = $useTriggers;
00042     }
00043 
00044     /**
00045      * ???
00046      *
00047      * @return bool
00048      */
00049     function isValid()
00050     {
00051         return $this->IsValid;
00052     }
00053 
00054     /**
00055      * Loads the operations definition for the current module
00056      * @return bool true if the operations were loaded, false if an error occured
00057      */
00058     function loadDefinition()
00059     {
00060         $pathList = eZModule::globalPathList();
00061         foreach ( $pathList as $path )
00062         {
00063             $definitionFile = $path . '/' . $this->ModuleName . '/operation_definition.php';
00064             if ( file_exists( $definitionFile ) )
00065                 break;
00066             $definitionFile = null;
00067         }
00068         if ( $definitionFile === null )
00069         {
00070             eZDebug::writeError( 'Missing operation definition file for module: ' . $this->ModuleName, __METHOD__ );
00071             return false;
00072         }
00073         unset( $OperationList );
00074         include( $definitionFile );
00075         if ( !isset( $OperationList ) )
00076         {
00077             eZDebug::writeError( 'Missing operation definition list for module: ' . $this->ModuleName, __METHOD__ );
00078             return false;
00079         }
00080         $this->OperationList = $OperationList;
00081         $this->IsValid = true;
00082         return true;
00083     }
00084 
00085     function makeOperationKeyArray( $operationDefinition, $operationParameters )
00086     {
00087         $keyDefinition = null;
00088         if ( array_key_exists( 'keys', $operationDefinition ) and
00089              is_array( $operationDefinition['keys'] ) )
00090         {
00091             $keyDefinition = $operationDefinition['keys'];
00092         }
00093         return $this->makeKeyArray( $keyDefinition, $operationDefinition['parameters'], $operationParameters );
00094     }
00095 
00096     function makeKeyArray( $keyDefinition, $parameterDefinition, $operationParameters )
00097     {
00098         $keyArray = array();
00099         if ( $keyDefinition !== null )
00100         {
00101             foreach ( $keyDefinition as $key )
00102             {
00103                 $keyArray[$key] = $operationParameters[$key];
00104             }
00105         }
00106         else
00107         {
00108             foreach ( $parameterDefinition as $operationParameter )
00109             {
00110                 $keyArray[$operationParameter['name']] = $operationParameters[$operationParameter['name']];
00111             }
00112         }
00113         return $keyArray;
00114     }
00115 
00116     /**
00117      * Executes the operation
00118      *
00119      * @param string $operationName
00120      * @param array $operationParameters
00121      * @param array $mementoData
00122      * @return mixed the operation execution result, or null if an error occured
00123      */
00124     function execute( $operationName, $operationParameters, $mementoData = null )
00125     {
00126         $moduleName = $this->ModuleName;
00127         if ( !isset( $this->OperationList[$operationName] ) )
00128         {
00129             eZDebug::writeError( "No such operation '$operationName' in module '$moduleName'", __METHOD__ );
00130             return null;
00131         }
00132         $operationDefinition = $this->OperationList[$operationName];
00133         if ( !isset( $operationDefinition['default_call_method'] ) )
00134         {
00135             eZDebug::writeError( "No call method defined for operation '$operationName' in module '$moduleName'", __METHOD__ );
00136             return null;
00137         }
00138         if ( !isset( $operationDefinition['body'] ) )
00139         {
00140             eZDebug::writeError( "No body for operation '$operationName' in module '$moduleName'", __METHOD__ );
00141             return null;
00142         }
00143         if ( !isset( $operationDefinition['parameters'] ) )
00144         {
00145             eZDebug::writeError( "No parameters defined for operation '$operationName' in module '$moduleName'", __METHOD__ );
00146             return null;
00147         }
00148         $callMethod = $operationDefinition['default_call_method'];
00149         $resultArray = null;
00150         $this->Memento = null;
00151         if ( isset( $callMethod['include_file'] ) and
00152              isset( $callMethod['class'] ) )
00153         {
00154             $bodyCallCount = array( 'loop_run' => array() );
00155             $operationKeys = null;
00156             if ( isset( $operationDefinition['keys'] ) )
00157                 $operationKeys = $operationDefinition['keys'];
00158             $operationParameterDefinitions = $operationDefinition['parameters'];
00159 
00160             $db = eZDB::instance();
00161             $db->begin();
00162 
00163             $this->storeOperationMemento( $operationKeys, $operationParameterDefinitions, $operationParameters, $bodyCallCount, $operationName );
00164 
00165             $runOperation = true;
00166             if ( $mementoData === null )
00167             {
00168                 $keyArray = $this->makeOperationKeyArray( $operationDefinition, $operationParameters );
00169                 $mainMemento = null;
00170                 if ( $this->UseTriggers )
00171                     $mainMemento = eZOperationMemento::fetchMain( $keyArray );
00172 
00173                 if ( $mainMemento !== null )
00174                 {
00175                     $this->Memento = $mainMemento;
00176                     $mementoOperationData = $this->Memento->data();
00177                     if ( isset( $mementoOperationData['loop_run'] ) )
00178                         $bodyCallCount['loop_run'] = $mementoOperationData['loop_run'];
00179                 }
00180 
00181 
00182                 $mementoList = null;
00183                 if ( $this->UseTriggers )
00184                     $mementoList = eZOperationMemento::fetchList( $keyArray );
00185 
00186                 if ( count( $mementoList ) > 0 )
00187                 {
00188                     $lastResultArray = array();
00189                     $mementoRestoreSuccess = true;
00190                     // restoring running operation
00191                     foreach ( $mementoList as $memento )
00192                     {
00193                         $mementoData = $memento->data();
00194                         $memento->remove();
00195 
00196                         $resultArray = $this->executeBody( $callMethod['include_file'], $callMethod['class'], $operationDefinition['body'],
00197                                                            $operationKeys, $operationParameterDefinitions, $operationParameters,
00198                                                            $mementoData, $bodyCallCount, $operationDefinition['name'] );
00199                         if ( is_array( $resultArray ) )
00200                         {
00201                             $lastResultArray = array_merge( $lastResultArray, $resultArray );
00202                             if ( !$resultArray['status'] )
00203                                 $mementoRestoreSuccess = false;
00204                         }
00205                     }
00206                     $resultArray = $lastResultArray;
00207                     //                 $resultArray['status'] = $mementoRestoreSuccess;
00208                     $runOperation = false;
00209                 }
00210             }
00211             if ( $runOperation )
00212             {
00213                 // start  new operation
00214                 $resultArray = $this->executeBody( $callMethod['include_file'], $callMethod['class'], $operationDefinition['body'],
00215                                                     $operationKeys, $operationParameterDefinitions, $operationParameters,
00216                                                     $mementoData, $bodyCallCount, $operationDefinition['name'] );
00217             }
00218 
00219             if ( is_array( $resultArray ) and
00220                  isset( $resultArray['status'] ) and
00221                  ( $resultArray['status'] == eZModuleOperationInfo::STATUS_HALTED
00222                    or $resultArray['status'] == eZModuleOperationInfo::STATUS_REPEAT ) )
00223             {
00224                 if ( $this->Memento !== null )
00225                 {
00226                     // $bodyCallCount stores an indexed array of each operation method that was executed
00227                     // it must be store in the memento on HALT/REPEAT so that the operation can be resumed
00228                     // where it was stopped (same behaviour as triggers)
00229                     $this->storeOperationMemento( $operationKeys, $operationParameterDefinitions, $operationParameters, $bodyCallCount, $operationName );
00230                     $data = $this->Memento->data();
00231                     $data['loop_run'] = $bodyCallCount['loop_run'];
00232                     $this->Memento->setData( $data );
00233                     $this->Memento->store();
00234                 }
00235             }
00236             else if ( $this->Memento !== null and
00237                       $this->Memento->attribute( 'id' ) !== null )
00238             {
00239 //                 eZDebug::writeDebug( $this->Memento, 'ezmodule operation result not halted' );
00240                 $this->Memento->remove();
00241             }
00242 //            if ( $resultArray['status'] == eZModuleOperationInfo::STATUS_CANCELLED )
00243 //            {
00244 //                return null;
00245 //            }
00246             /*
00247             else if ( isset( $mementoData['memento_key'] ) )
00248             {
00249                 $memento = eZOperationMemento::fetch( $mementoData['mementoKey'] );
00250                 if ( $memento->attribute( 'main_key') !=  $mementoData['mementoKey'] )
00251                 {
00252                     $mainMemento = eZOperationMemento::fetch( $memento->attribute( 'main_key') );
00253                 }
00254                 $memento->remove();
00255             }
00256             */
00257             $this->Memento = null;
00258 
00259             $db->commit();
00260         }
00261         else
00262         {
00263             eZDebug::writeError( "No valid call methods found for operation '$operationName' in module '$moduleName'", __METHOD__ );
00264             return null;
00265         }
00266         if ( !is_array( $resultArray ) )
00267         {
00268             eZDebug::writeError( "Operation '$operationName' in module '$moduleName' did not return a result array", __METHOD__ );
00269             return null;
00270         }
00271         if ( isset( $resultArray['internal_error'] ) )
00272         {
00273             switch ( $resultArray['internal_error'] )
00274             {
00275                 case eZModuleOperationInfo::ERROR_NO_CLASS:
00276                 {
00277                     $className = $resultArray['internal_error_class_name'];
00278                     eZDebug::writeError( "No class '$className' available for operation '$operationName' in module '$moduleName'", __METHOD__ );
00279                     return null;
00280                 } break;
00281                 case eZModuleOperationInfo::ERROR_NO_CLASS_METHOD:
00282                 {
00283                     $className = $resultArray['internal_error_class_name'];
00284                     $classMethodName = $resultArray['internal_error_class_method_name'];
00285                     eZDebug::writeError( "No method '$classMethodName' in class '$className' available for operation '$operationName' in module '$moduleName'", __METHOD__ );
00286                     return null;
00287                 } break;
00288                 case eZModuleOperationInfo::ERROR_CLASS_INSTANTIATE_FAILED:
00289                 {
00290                     $className = $resultArray['internal_error_class_name'];
00291                     eZDebug::writeError( "Failed instantiating class '$className' which is needed for operation '$operationName' in module '$moduleName'", __METHOD__ );
00292                     return null;
00293                 } break;
00294                 case eZModuleOperationInfo::ERROR_MISSING_PARAMETER:
00295                 {
00296                     $parameterName = $resultArray['internal_error_parameter_name'];
00297                     eZDebug::writeError( "Missing parameter '$parameterName' for operation '$operationName' in module '$moduleName'", __METHOD__ );
00298                     return null;
00299                 } break;
00300                 default:
00301                 {
00302                     $internalError = $resultArray['internal_error'];
00303                     eZDebug::writeError( "Unknown internal error '$internalError' for operation '$operationName' in module '$moduleName'", __METHOD__ );
00304                     return null;
00305                 } break;
00306             }
00307             return null;
00308         }
00309         else if ( isset( $resultArray['error'] ) )
00310         {
00311         }
00312         else if ( isset( $resultArray['status'] ) )
00313         {
00314             return $resultArray;
00315         }
00316         else
00317         {
00318             eZDebug::writeError( "Operation '$operationName' in module '$moduleName' did not return a result value", __METHOD__ );
00319         }
00320         return null;
00321     }
00322 
00323     /**
00324      * Executes the operation body
00325      *
00326      * @param string $includeFile Path to the file where the operation class is defined
00327      * @param string $className Name of the class holding the operation methods (@see $includeFile)
00328      * @param array $bodyStructure
00329      * @param array $operationKeys
00330      * @param array $operationParameterDefinitions
00331      * @param array $operationParameters
00332      * @param array $mementoData
00333      * @param int $bodyCallCount
00334      * @param string $operationName
00335      * @param array $currentLoopData
00336      * @return array
00337      */
00338     function executeBody( $includeFile, $className, $bodyStructure,
00339                           $operationKeys, $operationParameterDefinitions, $operationParameters,
00340                           &$mementoData, &$bodyCallCount, $operationName, $currentLoopData = null )
00341     {
00342         $bodyReturnValue = array( 'status' => eZModuleOperationInfo::STATUS_CONTINUE );
00343         foreach ( $bodyStructure as $body )
00344         {
00345             if ( !isset( $body['type'] ) )
00346             {
00347                 eZDebug::writeError( 'No type for body element, skipping', __METHOD__ );
00348                 continue;
00349             }
00350             if ( !isset( $body['name'] ) )
00351             {
00352                 eZDebug::writeError( 'No name for body element, skipping', __METHOD__ );
00353                 continue;
00354             }
00355             $bodyName = $body['name'];
00356             if ( !isset( $bodyCallCount['loop_run'][$bodyName] ) )
00357                 $bodyCallCount['loop_run'][$bodyName] = 0;
00358             $type = $body['type'];
00359             switch ( $type )
00360             {
00361                 case 'loop':
00362                 {
00363                     $children = $body['children'];
00364                     $tmpOperationParameterDefinitions = $operationParameterDefinitions;
00365                     if ( isset( $body['child_parameters'] ) )
00366                         $tmpOperationParameterDefinitions = $body['child_parameters'];
00367                     $loopName = $body['name'];
00368 
00369                     if ( $mementoData !== null )
00370                     {
00371                         $returnValue = $this->executeBody( $includeFile, $className, $children,
00372                                                            $operationKeys, $tmpOperationParameterDefinitions, $operationParameters,
00373                                                            $mementoData, $bodyCallCount, $operationName, null );
00374                         if ( !$returnValue['status'] )
00375                             return $returnValue;
00376                     }
00377                     else
00378                     {
00379                         ++$bodyCallCount['loop_run'][$bodyName];
00380 
00381                         $method = $body['method'];
00382                         $resultArray = $this->executeClassMethod( $includeFile, $className, $method,
00383                                                                   $operationParameterDefinitions, $operationParameters );
00384                         $parameters = array();
00385                         if ( isset( $resultArray['parameters'] ) )
00386                         {
00387                             $parameters = $resultArray['parameters'];
00388                         }
00389                         $count = 0;
00390                         $countDone = 0;
00391                         $countHalted = 0;
00392                         $countCanceled = 0;
00393                         $countRepeated = 0;
00394                         foreach ( $parameters as $parameterStructure )
00395                         {
00396                             $tmpOperationParameters = $operationParameters;
00397                             foreach ( $parameterStructure as $parameterName => $parameterValue )
00398                             {
00399                                 $tmpOperationParameters[$parameterName] = $parameterValue;
00400                             }
00401 
00402                             ++$count;
00403                             $returnValue = $this->executeBody( $includeFile, $className, $children,
00404                                                                $operationKeys, $tmpOperationParameterDefinitions, $tmpOperationParameters,
00405                                                                $mementoData, $bodyCallCount, $operationName, array( 'name' => $loopName,
00406                                                                                                                     'count' => count( $parameters ),
00407                                                                                                                     'index' => $count  ) );
00408                             switch( $returnValue['status'] )
00409                             {
00410                                 case eZModuleOperationInfo::STATUS_CANCELLED:
00411                                 {
00412                                     $bodyReturnValue = $returnValue;
00413                                     ++$countCanceled;
00414                                 }break;
00415                                 case eZModuleOperationInfo::STATUS_CONTINUE:
00416                                 {
00417                                     $bodyReturnValue = $returnValue;
00418 
00419                                     ++$countDone;
00420                                 }break;
00421                                 case eZModuleOperationInfo::STATUS_HALTED:
00422                                 {
00423                                     $bodyReturnValue = $returnValue;
00424                                     ++$countHalted;
00425                                 }break;
00426                                 case eZModuleOperationInfo::STATUS_REPEAT:
00427                                 {
00428                                     $bodyReturnValue = $returnValue;
00429                                     ++$countRepeated;
00430                                 }break;
00431                             }
00432                         }
00433                         if ( $body['continue_operation'] == 'all' )
00434                         {
00435                             if ( $count == $countDone )
00436                             {
00437                                 // continue operation
00438                             }
00439                             if ( $countCanceled > 0 )
00440                             {
00441                                 return $bodyReturnValue;
00442                                 //cancel operation
00443                             }
00444                             if ( $countHalted > 0 )
00445                             {
00446                                 return $bodyReturnValue;                                //show tempalate
00447                             }
00448 
00449                         }
00450                     }
00451                 } break;
00452                 case 'trigger':
00453                 {
00454                     if ( !$this->UseTriggers )
00455                     {
00456                         $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_CONTINUE;
00457                         continue;
00458 
00459                     }
00460 
00461                     $triggerName = $body['name'];
00462                     $triggerRestored = false;
00463                     $executeTrigger = true;
00464                     if ( $mementoData !== null )
00465                     {
00466                         if ( $mementoData['name'] == $triggerName )
00467                         {
00468                             $executeTrigger =  $this->restoreBodyMementoData( $bodyName, $mementoData,
00469                                                                               $operationParameters, $bodyCallCount, $currentLoopData );
00470                             $triggerRestored = true;
00471                         }
00472                         else
00473                         {
00474                             $executeTrigger = false;
00475                         }
00476                     }
00477                     if ( $executeTrigger )
00478                     {
00479                         $status = $this->executeTrigger( $bodyReturnValue, $body,
00480                                                           $operationParameterDefinitions, $operationParameters,
00481                                                           $bodyCallCount, $currentLoopData,
00482                                                           $triggerRestored, $operationName, $operationKeys );
00483 
00484                         switch( $status )
00485                         {
00486                             case eZModuleOperationInfo::STATUS_CONTINUE:
00487                             {
00488                                 $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_CONTINUE;
00489                             }break;
00490                             case eZModuleOperationInfo::STATUS_CANCELLED:
00491                             {
00492                                 $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_CANCELLED;
00493                                 return $bodyReturnValue;
00494                             }break;
00495                             case eZModuleOperationInfo::STATUS_HALTED:
00496                             {
00497 
00498                                 $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_HALTED;
00499                                 return $bodyReturnValue;
00500                             }
00501                             case eZModuleOperationInfo::STATUS_REPEAT:
00502                             {
00503 
00504                                 $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_REPEAT;
00505                                 return $bodyReturnValue;
00506                             }
00507                         }
00508                     }else
00509                     {
00510                         $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_CONTINUE;
00511                     }
00512                 } break;
00513                 case 'method':
00514                 {
00515                     if ( $mementoData === null )
00516                     {
00517                         $method = $body['method'];
00518                         $frequency = $body['frequency'];
00519                         $executeMethod = true;
00520                         if ( $frequency == 'once' and
00521                              $bodyCallCount['loop_run'][$bodyName] != 0 )
00522                             $executeMethod = false;
00523                         $tmpOperationParameterDefinitions = $operationParameterDefinitions;
00524                         if ( isset( $body['parameters'] ) )
00525                             $tmpOperationParameterDefinitions = $body['parameters'];
00526                         if ( $executeMethod )
00527                         {
00528                             $result = $this->executeClassMethod( $includeFile, $className, $method,
00529                                                                  $tmpOperationParameterDefinitions, $operationParameters );
00530                             if ( $result && array_key_exists( 'status', $result ) )
00531                             {
00532                                 switch( $result['status'] )
00533                                 {
00534                                     case eZModuleOperationInfo::STATUS_CONTINUE:
00535                                     default:
00536                                     {
00537                                         // moved from outside the case:
00538                                         // we don't want to count the method as executed if it doesn't return a CONTINUE status,
00539                                         // or it won't be executed next run
00540                                         ++$bodyCallCount['loop_run'][$bodyName];
00541                                         $result['status'] = eZModuleOperationInfo::STATUS_CONTINUE;
00542                                         $bodyReturnValue = $result;
00543                                     } break;
00544 
00545                                     case eZModuleOperationInfo::STATUS_CANCELLED:
00546                                     case eZModuleOperationInfo::STATUS_HALTED:
00547                                     {
00548                                         return $result;
00549                                     } break;
00550                                 }
00551                             }
00552                         }
00553                     }
00554                 } break;
00555                 default:
00556                 {
00557                     eZDebug::writeError( "Unknown operation type $type", __METHOD__ );
00558                 }
00559             }
00560         }
00561 
00562         return $bodyReturnValue;
00563     }
00564 
00565     /**
00566      * Executes an operation trigger
00567      *
00568      * @param array $bodyReturnValue The current return value
00569      * @param array $body Body data for the trigger being executed
00570      * @param array $operationParameterDefinitions Operation parameters definition
00571      * @param array $operationParameters Operation parameters values
00572      * @param int $bodyCallCount Number of times the body was called
00573      * @param array $currentLoopData Memento data for the operation
00574      * @param bool $triggerRestored Boolean that indicates if operation data (memento) was restored
00575      * @param string $operationName The operation name
00576      * @param array $operationKeys Additional parameters. Only used by looping so far.
00577      * @return
00578      */
00579     function executeTrigger( &$bodyReturnValue, $body,
00580                              $operationParameterDefinitions, $operationParameters,
00581                              &$bodyCallCount, $currentLoopData,
00582                              $triggerRestored, $operationName, &$operationKeys )
00583     {
00584         $triggerName = $body['name'];
00585         $triggerKeys = $body['keys'];
00586 
00587         $status = eZTrigger::runTrigger( $triggerName, $this->ModuleName, $operationName, $operationParameters, $triggerKeys );
00588 
00589 
00590         if ( $status['Status'] == eZTrigger::WORKFLOW_DONE ||
00591              $status['Status'] == eZTrigger::NO_CONNECTED_WORKFLOWS )
00592         {
00593             ++$bodyCallCount['loop_run'][$triggerName];
00594             return eZModuleOperationInfo::STATUS_CONTINUE;
00595         }
00596         else if ( $status['Status'] == eZTrigger::STATUS_CRON_JOB ||
00597                   $status['Status'] == eZTrigger::FETCH_TEMPLATE ||
00598                   $status['Status'] == eZTrigger::FETCH_TEMPLATE_REPEAT ||
00599                   $status['Status'] == eZTrigger::REDIRECT )
00600         {
00601             $bodyMemento = $this->storeBodyMemento( $triggerName, $triggerKeys,
00602                                                     $operationKeys, $operationParameterDefinitions, $operationParameters,
00603                                                     $bodyCallCount, $currentLoopData, $operationName );
00604             $workflowProcess = $status['WorkflowProcess'];
00605             if ( $workflowProcess !== null )
00606             {
00607                 $workflowProcess->setAttribute( 'memento_key', $bodyMemento->attribute( 'memento_key' ) );
00608                 $workflowProcess->store();
00609             }
00610 
00611             $bodyReturnValue['result'] = $status['Result'];
00612             if ( $status['Status'] == eZTrigger::REDIRECT )
00613             {
00614                 $bodyReturnValue['redirect_url'] = $status['Result'];
00615             }
00616             if ( $status['Status'] == eZTrigger::FETCH_TEMPLATE_REPEAT )
00617             {
00618                 // Hack for project issue #14371 (fetch template repeat)
00619                 // The object version's status is set to REPEAT so that it can
00620                 // be submitted again
00621                 if ( $operationName == 'publish' && $this->ModuleName == 'content' )
00622                 {
00623                     eZContentOperationCollection::setVersionStatus( $operationParameters['object_id'],
00624                         $operationParameters['version'], eZContentObjectVersion::STATUS_REPEAT );
00625                 }
00626                 return eZModuleOperationInfo::STATUS_REPEAT;
00627             }
00628             else
00629             {
00630                 return eZModuleOperationInfo::STATUS_HALTED;
00631             }
00632         }
00633         else if ( $status['Status'] == eZTrigger::WORKFLOW_CANCELLED or
00634                   $status['Status'] == eZTrigger::WORKFLOW_RESET )
00635         {
00636              return eZModuleOperationInfo::STATUS_CANCELLED;
00637              $bodyReturnValue['result'] = $status['Result'];
00638         }
00639     }
00640 
00641     function storeOperationMemento( $operationKeys, $operationParameterDefinitions, $operationParameters,
00642                                     &$bodyCallCount, $operationName )
00643     {
00644         $mementoData = array();
00645         $mementoData['module_name'] = $this->ModuleName;
00646         $mementoData['operation_name'] = $operationName;
00647         if ( $this->Memento === null )
00648         {
00649             $keyArray = $this->makeKeyArray( $operationKeys, $operationParameterDefinitions, $operationParameters );
00650             $mementoData['loop_run'] = $bodyCallCount['loop_run'];
00651             $memento = eZOperationMemento::create( $keyArray, $mementoData, true );
00652             $this->Memento = $memento;
00653         }
00654         else
00655         {
00656             $mementoData = $this->Memento->data();
00657             $mementoData['loop_run'] = $bodyCallCount['loop_run'];
00658             $this->Memento->setData( $mementoData );
00659         }
00660     }
00661 
00662     function removeBodyMemento( $bodyName, $bodyKeys,
00663                                 $operationKeys, $operationParameterDefinitions, $operationParameters,
00664                                 &$bodyCallCount, $currentLoopData, $operationName )
00665     {
00666         $keyArray = $this->makeKeyArray( $operationKeys, $operationParameterDefinitions, $operationParameters );
00667     }
00668 
00669     /**
00670      * Packs the current body data (memento) for save & re-use
00671      *
00672      * @param string $bodyName
00673      * @param array $bodyKeys
00674      * @param array $operationKeys
00675      * @param array $operationParameterDefinitions
00676      * @param array $operationParameters
00677      * @param int $bodyCallCount
00678      * @param array $currentLoopData
00679      * @param string $operationName
00680      * @return The memento
00681      */
00682     function storeBodyMemento( $bodyName, $bodyKeys,
00683                                $operationKeys, $operationParameterDefinitions, $operationParameters,
00684                                &$bodyCallCount, $currentLoopData, $operationName )
00685     {
00686         $this->storeOperationMemento( $operationKeys, $operationParameterDefinitions, $operationParameters, $bodyCallCount, $operationName );
00687 
00688         $keyArray = $this->makeKeyArray( $operationKeys, $operationParameterDefinitions, $operationParameters );
00689         $http = eZHTTPTool::instance();
00690         $keyArray['session_key'] = $http->getSessionKey();
00691         $mementoData = array();
00692         $mementoData['name'] = $bodyName;
00693         $mementoData['parameters'] = $operationParameters;
00694         $mementoData['loop_data'] = $currentLoopData;
00695         $mementoData['module_name'] = $this->ModuleName;
00696         $mementoData['operation_name'] = $operationName;
00697         $memento = eZOperationMemento::create( $keyArray, $mementoData, false, $this->Memento->attribute( 'memento_key' ) );
00698         $memento->store();
00699         return $memento;
00700     }
00701 
00702     function restoreBodyMementoData( $bodyName, &$mementoData,
00703                                      &$operationParameters, &$bodyCallCount, &$currentLoopData )
00704     {
00705         $operationParameters = array();
00706         if ( isset( $mementoData['parameters'] ) )
00707             $operationParameters = $mementoData['parameters'];
00708         if ( isset( $mementoData[ 'main_memento' ] ) )
00709         {
00710             $this->Memento = $mementoData[ 'main_memento' ];
00711             $mainMementoData = $this->Memento->data();
00712             if ( isset( $mainMementoData['loop_run'] ) )
00713             {
00714                 $bodyCallCount['loop_run'] = $mainMementoData['loop_run'];
00715             }
00716 
00717         }
00718 
00719 //         if ( $this->Memento !== null )
00720 //         {
00721 //             $mementoOperationData = $this->Memento->data();
00722 //             if ( isset( $mementoOperationData['loop_run'] ) )
00723 //                 $bodyCallCount['loop_run'] = $mementoOperationData['loop_run'];
00724 //         }
00725         if ( isset( $mementoData['loop_data'] ) )
00726             $currentLoopData = $mementoData['loop_data'];
00727 
00728         if ( isset( $mementoData['skip_trigger'] ) && $mementoData['skip_trigger'] == true )
00729         {
00730             $mementoData = null;
00731             return false;
00732         }
00733         else
00734         {
00735             $mementoData = null;
00736             return true;
00737         }
00738 
00739         return true;
00740     }
00741 
00742     /**
00743      * Executes a class method in an operation body
00744      *
00745      * @param string $includeFile The file where the class & method are defined
00746      * @param string $className The class where the method is implemented
00747      * @param string $methodName The method to call
00748      * @param mixed $operationParameterDefinitions The method parameters definition
00749      * @param mixed $operationParameters The method parameters values
00750      * @return array
00751      */
00752     function executeClassMethod( $includeFile, $className, $methodName,
00753                                  $operationParameterDefinitions, $operationParameters )
00754     {
00755         include_once( $includeFile );
00756         if ( !class_exists( $className ) )
00757         {
00758             return array( 'internal_error' => eZModuleOperationInfo::ERROR_NO_CLASS,
00759                           'internal_error_class_name' => $className );
00760         }
00761         $classObject = $this->objectForClass( $className );
00762         if ( $classObject === null )
00763         {
00764             return array( 'internal_error' => eZModuleOperationInfo::ERROR_CLASS_INSTANTIATE_FAILED,
00765                           'internal_error_class_name' => $className );
00766         }
00767         if ( !method_exists( $classObject, $methodName ) )
00768         {
00769             return array( 'internal_error' => eZModuleOperationInfo::ERROR_NO_CLASS_METHOD,
00770                           'internal_error_class_name' => $className,
00771                           'internal_error_class_method_name' => $methodName );
00772         }
00773         $parameterArray = array();
00774 
00775         foreach ( $operationParameterDefinitions as $operationParameterDefinition )
00776         {
00777             $parameterName = $operationParameterDefinition['name'];
00778             if ( isset( $operationParameterDefinition['constant'] ) )
00779             {
00780                 $constantValue = $operationParameterDefinition['constant'];
00781                 $parameterArray[] = $constantValue;
00782             }
00783             else if ( isset( $operationParameters[$parameterName] ) )
00784             {
00785                 // Do type checking
00786                 $parameterArray[] = $operationParameters[$parameterName];
00787             }
00788             else
00789             {
00790                 if ( $operationParameterDefinition['required'] )
00791                 {
00792 
00793                     return array( 'internal_error' => eZModuleOperationInfo::ERROR_MISSING_PARAMETER,
00794                                   'internal_error_parameter_name' => $parameterName );
00795                 }
00796                 else if ( isset( $operationParameterDefinition['default'] ) )
00797                 {
00798                     $parameterArray[] = $operationParameterDefinition['default'];
00799                 }
00800                 else
00801                 {
00802                     $parameterArray[] = null;
00803                 }
00804             }
00805         }
00806 
00807         return call_user_func_array( array( $classObject, $methodName ), $parameterArray );
00808     }
00809 
00810     /**
00811      * Helper method that keeps and returns the instances of operation objects
00812      * @param string $className The class the method should return an object for
00813      * @return $className
00814      * @private
00815      * @todo Use a static variable instead of globals
00816      */
00817     function objectForClass( $className )
00818     {
00819         if ( !isset( $GLOBALS['eZModuleOperationClassObjectList'] ) )
00820         {
00821             $GLOBALS['eZModuleOperationClassObjectList'] = array();
00822         }
00823         if ( isset( $GLOBALS['eZModuleOperationClassObjectList'][$className] ) )
00824         {
00825             return $GLOBALS['eZModuleOperationClassObjectList'][$className];
00826         }
00827 
00828         return $GLOBALS['eZModuleOperationClassObjectList'][$className] = new $className();
00829     }
00830 
00831     /**
00832      * @deprecated use call_user_func_array() instead
00833      */
00834     function callClassMethod( $methodName, $classObject, $parameterArray )
00835     {
00836         return call_user_func_array( array( $classObject, $methodName ), $parameterArray );
00837     }
00838 
00839 
00840     /// \privatesection
00841     public $ModuleName;
00842     public $FunctionList;
00843     public $IsValid;
00844     public $UseTriggers = false;
00845 
00846     /**
00847      * @var eZOperationMemento
00848      */
00849     public $Memento;
00850 }
00851 
00852 ?>