|
eZ Publish
[trunk]
|
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 ?>