PageRenderTime 57ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/ezutils/classes/ezmoduleoperationinfo.php

https://github.com/StephanBoganskyXrow/ezpublish
PHP | 878 lines | 661 code | 57 blank | 160 comment | 110 complexity | a85e0c56c1c90372b90909f557295a24 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. //
  3. // Definition of eZModuleOperationInfo class
  4. //
  5. // Created on: <06-Oct-2002 16:27:36 amos>
  6. //
  7. // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
  8. // SOFTWARE NAME: eZ Publish
  9. // SOFTWARE RELEASE: 4.1.x
  10. // COPYRIGHT NOTICE: Copyright (C) 1999-2011 eZ Systems AS
  11. // SOFTWARE LICENSE: GNU General Public License v2.0
  12. // NOTICE: >
  13. // This program is free software; you can redistribute it and/or
  14. // modify it under the terms of version 2.0 of the GNU General
  15. // Public License as published by the Free Software Foundation.
  16. //
  17. // This program is distributed in the hope that it will be useful,
  18. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. // GNU General Public License for more details.
  21. //
  22. // You should have received a copy of version 2.0 of the GNU General
  23. // Public License along with this program; if not, write to the Free
  24. // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  25. // MA 02110-1301, USA.
  26. //
  27. //
  28. // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
  29. //
  30. /*! \file
  31. */
  32. /*!
  33. \class eZModuleOperationInfo ezmoduleoperationinfo.php
  34. \brief The class eZModuleOperationInfo does
  35. */
  36. class eZModuleOperationInfo
  37. {
  38. const ERROR_NO_CLASS = 5;
  39. const ERROR_NO_CLASS_METHOD = 6;
  40. const ERROR_CLASS_INSTANTIATE_FAILED = 7;
  41. const ERROR_MISSING_PARAMETER = 8;
  42. const STATUS_CONTINUE = 1;
  43. const STATUS_CANCELLED = 2;
  44. const STATUS_HALTED = 3;
  45. const STATUS_REPEAT = 4;
  46. const STATUS_QUEUED = 5;
  47. /**
  48. * Constructor
  49. * @param string $moduleName
  50. * @param bool $useTriggers
  51. */
  52. function eZModuleOperationInfo( $moduleName, $useTriggers = true )
  53. {
  54. $this->ModuleName = $moduleName;
  55. $this->IsValid = false;
  56. $this->OperationList = array();
  57. $this->Memento = null;
  58. $this->UseTriggers = $useTriggers;
  59. }
  60. /**
  61. * ???
  62. *
  63. * @return bool
  64. */
  65. function isValid()
  66. {
  67. return $this->IsValid;
  68. }
  69. /**
  70. * Loads the operations definition for the current module
  71. * @return bool true if the operations were loaded, false if an error occured
  72. */
  73. function loadDefinition()
  74. {
  75. $pathList = eZModule::globalPathList();
  76. foreach ( $pathList as $path )
  77. {
  78. $definitionFile = $path . '/' . $this->ModuleName . '/operation_definition.php';
  79. if ( file_exists( $definitionFile ) )
  80. break;
  81. $definitionFile = null;
  82. }
  83. if ( $definitionFile === null )
  84. {
  85. eZDebug::writeError( 'Missing operation definition file for module: ' . $this->ModuleName, __METHOD__ );
  86. return false;
  87. }
  88. unset( $OperationList );
  89. include( $definitionFile );
  90. if ( !isset( $OperationList ) )
  91. {
  92. eZDebug::writeError( 'Missing operation definition list for module: ' . $this->ModuleName, __METHOD__ );
  93. return false;
  94. }
  95. $this->OperationList = $OperationList;
  96. $this->IsValid = true;
  97. return true;
  98. }
  99. function makeOperationKeyArray( $operationDefinition, $operationParameters )
  100. {
  101. $keyDefinition = null;
  102. if ( array_key_exists( 'keys', $operationDefinition ) and
  103. is_array( $operationDefinition['keys'] ) )
  104. {
  105. $keyDefinition = $operationDefinition['keys'];
  106. }
  107. return $this->makeKeyArray( $keyDefinition, $operationDefinition['parameters'], $operationParameters );
  108. }
  109. function makeKeyArray( $keyDefinition, $parameterDefinition, $operationParameters )
  110. {
  111. $keyArray = array();
  112. if ( $keyDefinition !== null )
  113. {
  114. foreach ( $keyDefinition as $key )
  115. {
  116. $keyArray[$key] = $operationParameters[$key];
  117. }
  118. }
  119. else
  120. {
  121. foreach ( $parameterDefinition as $operationParameter )
  122. {
  123. $keyArray[$operationParameter['name']] = $operationParameters[$operationParameter['name']];
  124. }
  125. }
  126. return $keyArray;
  127. }
  128. /**
  129. * Executes the operation
  130. *
  131. * @param string $operationName
  132. * @param array $operationParameters
  133. * @param array $mementoData
  134. * @return mixed the operation execution result, or null if an error occured
  135. */
  136. function execute( $operationName, $operationParameters, $mementoData = null )
  137. {
  138. $moduleName = $this->ModuleName;
  139. if ( !isset( $this->OperationList[$operationName] ) )
  140. {
  141. eZDebug::writeError( "No such operation '$operationName' in module '$moduleName'", __METHOD__ );
  142. return null;
  143. }
  144. $operationDefinition = $this->OperationList[$operationName];
  145. if ( !isset( $operationName['default_call_method'] ) )
  146. {
  147. eZDebug::writeError( "No call method defined for operation '$operationName' in module '$moduleName'", __METHOD__ );
  148. return null;
  149. }
  150. if ( !isset( $operationName['body'] ) )
  151. {
  152. eZDebug::writeError( "No body for operation '$operationName' in module '$moduleName'", __METHOD__ );
  153. return null;
  154. }
  155. if ( !isset( $operationName['parameters'] ) )
  156. {
  157. eZDebug::writeError( "No parameters defined for operation '$operationName' in module '$moduleName'", __METHOD__ );
  158. return null;
  159. }
  160. $callMethod = $operationDefinition['default_call_method'];
  161. $resultArray = null;
  162. $this->Memento = null;
  163. if ( isset( $callMethod['include_file'] ) and
  164. isset( $callMethod['class'] ) )
  165. {
  166. $bodyCallCount = array( 'loop_run' => array() );
  167. $operationKeys = null;
  168. if ( isset( $operationDefinition['keys'] ) )
  169. $operationKeys = $operationDefinition['keys'];
  170. $operationParameterDefinitions = $operationDefinition['parameters'];
  171. $db = eZDB::instance();
  172. $db->begin();
  173. $this->storeOperationMemento( $operationKeys, $operationParameterDefinitions, $operationParameters, $bodyCallCount, $operationName );
  174. $runOperation = true;
  175. if ( $mementoData === null )
  176. {
  177. $keyArray = $this->makeOperationKeyArray( $operationDefinition, $operationParameters );
  178. $http = eZHTTPTool::instance();
  179. $keyArray['session_key'] = $http->getSessionKey();
  180. $mainMemento = null;
  181. if ( $this->UseTriggers )
  182. $mainMemento = eZOperationMemento::fetchMain( $keyArray );
  183. if ( $mainMemento !== null )
  184. {
  185. $this->Memento = $mainMemento;
  186. $mementoOperationData = $this->Memento->data();
  187. if ( isset( $mementoOperationData['loop_run'] ) )
  188. $bodyCallCount['loop_run'] = $mementoOperationData['loop_run'];
  189. }
  190. $mementoList = null;
  191. if ( $this->UseTriggers )
  192. $mementoList = eZOperationMemento::fetchList( $keyArray );
  193. if ( count( $mementoList ) > 0 )
  194. {
  195. $lastResultArray = array();
  196. $mementoRestoreSuccess = true;
  197. // restoring running operation
  198. foreach ( $mementoList as $memento )
  199. {
  200. $mementoData = $memento->data();
  201. $memento->remove();
  202. $resultArray = $this->executeBody( $callMethod['include_file'], $callMethod['class'], $operationDefinition['body'],
  203. $operationKeys, $operationParameterDefinitions, $operationParameters,
  204. $mementoData, $bodyCallCount, $operationDefinition['name'] );
  205. if ( is_array( $resultArray ) )
  206. {
  207. $lastResultArray = array_merge( $lastResultArray, $resultArray );
  208. if ( !$resultArray['status'] )
  209. $mementoRestoreSuccess = false;
  210. }
  211. }
  212. $resultArray = $lastResultArray;
  213. // $resultArray['status'] = $mementoRestoreSuccess;
  214. $runOperation = false;
  215. }
  216. }
  217. if ( $runOperation )
  218. {
  219. // start new operation
  220. $resultArray = $this->executeBody( $callMethod['include_file'], $callMethod['class'], $operationDefinition['body'],
  221. $operationKeys, $operationParameterDefinitions, $operationParameters,
  222. $mementoData, $bodyCallCount, $operationDefinition['name'] );
  223. }
  224. if ( is_array( $resultArray ) and
  225. isset( $resultArray['status'] ) and
  226. ( $resultArray['status'] == eZModuleOperationInfo::STATUS_HALTED
  227. or $resultArray['status'] == eZModuleOperationInfo::STATUS_REPEAT ) )
  228. {
  229. if ( $this->Memento !== null )
  230. {
  231. // $bodyCallCount stores an indexed array of each operation method that was executed
  232. // it must be store in the memento on HALT/REPEAT so that the operation can be resumed
  233. // where it was stopped (same behaviour as triggers)
  234. $this->storeOperationMemento( $operationKeys, $operationParameterDefinitions, $operationParameters, $bodyCallCount, $operationName );
  235. $data = $this->Memento->data();
  236. $data['loop_run'] = $bodyCallCount['loop_run'];
  237. $this->Memento->setData( $data );
  238. $this->Memento->store();
  239. }
  240. }
  241. else if ( $this->Memento !== null and
  242. $this->Memento->attribute( 'id' ) !== null )
  243. {
  244. // eZDebug::writeDebug( $this->Memento, 'ezmodule operation result not halted' );
  245. $this->Memento->remove();
  246. }
  247. // if ( $resultArray['status'] == eZModuleOperationInfo::STATUS_CANCELLED )
  248. // {
  249. // return null;
  250. // }
  251. /*
  252. else if ( isset( $mementoData['memento_key'] ) )
  253. {
  254. $memento = eZOperationMemento::fetch( $mementoData['mementoKey'] );
  255. if ( $memento->attribute( 'main_key') != $mementoData['mementoKey'] )
  256. {
  257. $mainMemento = eZOperationMemento::fetch( $memento->attribute( 'main_key') );
  258. }
  259. $memento->remove();
  260. }
  261. */
  262. $this->Memento = null;
  263. $db->commit();
  264. }
  265. else
  266. {
  267. eZDebug::writeError( "No valid call methods found for operation '$operationName' in module '$moduleName'", __METHOD__ );
  268. return null;
  269. }
  270. if ( !is_array( $resultArray ) )
  271. {
  272. eZDebug::writeError( "Operation '$operationName' in module '$moduleName' did not return a result array", __METHOD__ );
  273. return null;
  274. }
  275. if ( isset( $resultArray['internal_error'] ) )
  276. {
  277. switch ( $resultArray['internal_error'] )
  278. {
  279. case eZModuleOperationInfo::ERROR_NO_CLASS:
  280. {
  281. $className = $resultArray['internal_error_class_name'];
  282. eZDebug::writeError( "No class '$className' available for operation '$operationName' in module '$moduleName'", __METHOD__ );
  283. return null;
  284. } break;
  285. case eZModuleOperationInfo::ERROR_NO_CLASS_METHOD:
  286. {
  287. $className = $resultArray['internal_error_class_name'];
  288. $classMethodName = $resultArray['internal_error_class_method_name'];
  289. eZDebug::writeError( "No method '$classMethodName' in class '$className' available for operation '$operationName' in module '$moduleName'", __METHOD__ );
  290. return null;
  291. } break;
  292. case eZModuleOperationInfo::ERROR_CLASS_INSTANTIATE_FAILED:
  293. {
  294. $className = $resultArray['internal_error_class_name'];
  295. eZDebug::writeError( "Failed instantiating class '$className' which is needed for operation '$operationName' in module '$moduleName'", __METHOD__ );
  296. return null;
  297. } break;
  298. case eZModuleOperationInfo::ERROR_MISSING_PARAMETER:
  299. {
  300. $parameterName = $resultArray['internal_error_parameter_name'];
  301. eZDebug::writeError( "Missing parameter '$parameterName' for operation '$operationName' in module '$moduleName'", __METHOD__ );
  302. return null;
  303. } break;
  304. default:
  305. {
  306. $internalError = $resultArray['internal_error'];
  307. eZDebug::writeError( "Unknown internal error '$internalError' for operation '$operationName' in module '$moduleName'", __METHOD__ );
  308. return null;
  309. } break;
  310. }
  311. return null;
  312. }
  313. else if ( isset( $resultArray['error'] ) )
  314. {
  315. }
  316. else if ( isset( $resultArray['status'] ) )
  317. {
  318. return $resultArray;
  319. }
  320. else
  321. {
  322. eZDebug::writeError( "Operation '$operationName' in module '$moduleName' did not return a result value", __METHOD__ );
  323. }
  324. return null;
  325. }
  326. /**
  327. * Executes the operation body
  328. *
  329. * @param string $includeFile Path to the file where the operation class is defined
  330. * @param string $className Name of the class holding the operation methods (@see $includeFile)
  331. * @param array $bodyStructure
  332. * @param array $operationKeys
  333. * @param array $operationParameterDefinitions
  334. * @param array $operationParameters
  335. * @param array $mementoData
  336. * @param int $bodyCallCount
  337. * @param string $operationName
  338. * @param array $currentLoopData
  339. * @return array
  340. */
  341. function executeBody( $includeFile, $className, $bodyStructure,
  342. $operationKeys, $operationParameterDefinitions, $operationParameters,
  343. &$mementoData, &$bodyCallCount, $operationName, $currentLoopData = null )
  344. {
  345. $bodyReturnValue = array( 'status' => eZModuleOperationInfo::STATUS_CONTINUE );
  346. foreach ( $bodyStructure as $body )
  347. {
  348. if ( !isset( $body['type'] ) )
  349. {
  350. eZDebug::writeError( 'No type for body element, skipping', __METHOD__ );
  351. continue;
  352. }
  353. if ( !isset( $body['name'] ) )
  354. {
  355. eZDebug::writeError( 'No name for body element, skipping', __METHOD__ );
  356. continue;
  357. }
  358. $bodyName = $body['name'];
  359. if ( !isset( $bodyCallCount['loop_run'][$bodyName] ) )
  360. $bodyCallCount['loop_run'][$bodyName] = 0;
  361. $type = $body['type'];
  362. switch ( $type )
  363. {
  364. case 'loop':
  365. {
  366. $children = $body['children'];
  367. $tmpOperationParameterDefinitions = $operationParameterDefinitions;
  368. if ( isset( $body['child_parameters'] ) )
  369. $tmpOperationParameterDefinitions = $body['child_parameters'];
  370. $loopName = $body['name'];
  371. if ( $mementoData !== null )
  372. {
  373. $returnValue = $this->executeBody( $includeFile, $className, $children,
  374. $operationKeys, $tmpOperationParameterDefinitions, $operationParameters,
  375. $mementoData, $bodyCallCount, $operationName, null );
  376. if ( !$returnValue['status'] )
  377. return $returnValue;
  378. }
  379. else
  380. {
  381. ++$bodyCallCount['loop_run'][$bodyName];
  382. $method = $body['method'];
  383. $resultArray = $this->executeClassMethod( $includeFile, $className, $method,
  384. $operationParameterDefinitions, $operationParameters );
  385. $parameters = array();
  386. if ( isset( $resultArray['parameters'] ) )
  387. {
  388. $parameters = $resultArray['parameters'];
  389. }
  390. $count = 0;
  391. $countDone = 0;
  392. $countHalted = 0;
  393. $countCanceled = 0;
  394. $countRepeated = 0;
  395. foreach ( $parameters as $parameterStructure )
  396. {
  397. $tmpOperationParameters = $operationParameters;
  398. foreach ( $parameterStructure as $parameterName => $parameterValue )
  399. {
  400. $tmpOperationParameters[$parameterName] = $parameterValue;
  401. }
  402. ++$count;
  403. $returnValue = $this->executeBody( $includeFile, $className, $children,
  404. $operationKeys, $tmpOperationParameterDefinitions, $tmpOperationParameters,
  405. $mementoData, $bodyCallCount, $operationName, array( 'name' => $loopName,
  406. 'count' => count( $parameters ),
  407. 'index' => $count ) );
  408. switch( $returnValue['status'] )
  409. {
  410. case eZModuleOperationInfo::STATUS_CANCELLED:
  411. {
  412. $bodyReturnValue = $returnValue;
  413. ++$countCanceled;
  414. }break;
  415. case eZModuleOperationInfo::STATUS_CONTINUE:
  416. {
  417. $bodyReturnValue = $returnValue;
  418. ++$countDone;
  419. }break;
  420. case eZModuleOperationInfo::STATUS_HALTED:
  421. {
  422. $bodyReturnValue = $returnValue;
  423. ++$countHalted;
  424. }break;
  425. case eZModuleOperationInfo::STATUS_REPEAT:
  426. {
  427. $bodyReturnValue = $returnValue;
  428. ++$countRepeated;
  429. }break;
  430. }
  431. }
  432. if ( $body['continue_operation'] == 'all' )
  433. {
  434. if ( $count == $countDone )
  435. {
  436. // continue operation
  437. }
  438. if ( $countCanceled > 0 )
  439. {
  440. return $bodyReturnValue;
  441. //cancel operation
  442. }
  443. if ( $countHalted > 0 )
  444. {
  445. return $bodyReturnValue; //show tempalate
  446. }
  447. }
  448. }
  449. } break;
  450. case 'trigger':
  451. {
  452. if ( !$this->UseTriggers )
  453. {
  454. $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_CONTINUE;
  455. continue;
  456. }
  457. $triggerName = $body['name'];
  458. $triggerRestored = false;
  459. $executeTrigger = true;
  460. if ( $mementoData !== null )
  461. {
  462. if ( $mementoData['name'] == $triggerName )
  463. {
  464. $executeTrigger = $this->restoreBodyMementoData( $bodyName, $mementoData,
  465. $operationParameters, $bodyCallCount, $currentLoopData );
  466. $triggerRestored = true;
  467. }
  468. else
  469. {
  470. $executeTrigger = false;
  471. }
  472. }
  473. if ( $executeTrigger )
  474. {
  475. $status = $this->executeTrigger( $bodyReturnValue, $body,
  476. $operationParameterDefinitions, $operationParameters,
  477. $bodyCallCount, $currentLoopData,
  478. $triggerRestored, $operationName, $operationKeys );
  479. switch( $status )
  480. {
  481. case eZModuleOperationInfo::STATUS_CONTINUE:
  482. {
  483. $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_CONTINUE;
  484. }break;
  485. case eZModuleOperationInfo::STATUS_CANCELLED:
  486. {
  487. $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_CANCELLED;
  488. return $bodyReturnValue;
  489. }break;
  490. case eZModuleOperationInfo::STATUS_HALTED:
  491. {
  492. $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_HALTED;
  493. return $bodyReturnValue;
  494. }
  495. case eZModuleOperationInfo::STATUS_REPEAT:
  496. {
  497. $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_REPEAT;
  498. return $bodyReturnValue;
  499. }
  500. }
  501. }else
  502. {
  503. $bodyReturnValue['status'] = eZModuleOperationInfo::STATUS_CONTINUE;
  504. }
  505. } break;
  506. case 'method':
  507. {
  508. if ( $mementoData === null )
  509. {
  510. $method = $body['method'];
  511. $frequency = $body['frequency'];
  512. $executeMethod = true;
  513. if ( $frequency == 'once' and
  514. $bodyCallCount['loop_run'][$bodyName] != 0 )
  515. $executeMethod = false;
  516. $tmpOperationParameterDefinitions = $operationParameterDefinitions;
  517. if ( isset( $body['parameters'] ) )
  518. $tmpOperationParameterDefinitions = $body['parameters'];
  519. if ( $executeMethod )
  520. {
  521. $result = $this->executeClassMethod( $includeFile, $className, $method,
  522. $tmpOperationParameterDefinitions, $operationParameters );
  523. if ( $result && array_key_exists( 'status', $result ) )
  524. {
  525. switch( $result['status'] )
  526. {
  527. case eZModuleOperationInfo::STATUS_CONTINUE:
  528. default:
  529. {
  530. // moved from outside the case:
  531. // we don't want to count the method as executed if it doesn't return a CONTINUE status,
  532. // or it won't be executed next run
  533. ++$bodyCallCount['loop_run'][$bodyName];
  534. $result['status'] = eZModuleOperationInfo::STATUS_CONTINUE;
  535. $bodyReturnValue = $result;
  536. } break;
  537. case eZModuleOperationInfo::STATUS_CANCELLED:
  538. case eZModuleOperationInfo::STATUS_HALTED:
  539. {
  540. return $result;
  541. } break;
  542. }
  543. }
  544. }
  545. }
  546. } break;
  547. default:
  548. {
  549. eZDebug::writeError( "Unknown operation type $type", __METHOD__ );
  550. }
  551. }
  552. }
  553. return $bodyReturnValue;
  554. }
  555. /**
  556. * Executes an operation trigger
  557. *
  558. * @param array $bodyReturnValue The current return value
  559. * @param array $body Body data for the trigger being executed
  560. * @param array $operationParameterDefinitions Operation parameters definition
  561. * @param array $operationParameters Operation parameters values
  562. * @param int $bodyCallCount Number of times the body was called
  563. * @param array $currentLoopData Memento data for the operation
  564. * @param bool $triggerRestored Boolean that indicates if operation data (memento) was restored
  565. * @param string $operationName The operation name
  566. * @param array $operationKeys Additional parameters. Only used by looping so far.
  567. * @return
  568. */
  569. function executeTrigger( &$bodyReturnValue, $body,
  570. $operationParameterDefinitions, $operationParameters,
  571. &$bodyCallCount, $currentLoopData,
  572. $triggerRestored, $operationName, &$operationKeys )
  573. {
  574. $triggerName = $body['name'];
  575. $triggerKeys = $body['keys'];
  576. $status = eZTrigger::runTrigger( $triggerName, $this->ModuleName, $operationName, $operationParameters, $triggerKeys );
  577. if ( $status['Status'] == eZTrigger::WORKFLOW_DONE ||
  578. $status['Status'] == eZTrigger::NO_CONNECTED_WORKFLOWS )
  579. {
  580. ++$bodyCallCount['loop_run'][$triggerName];
  581. return eZModuleOperationInfo::STATUS_CONTINUE;
  582. }
  583. else if ( $status['Status'] == eZTrigger::STATUS_CRON_JOB ||
  584. $status['Status'] == eZTrigger::FETCH_TEMPLATE ||
  585. $status['Status'] == eZTrigger::FETCH_TEMPLATE_REPEAT ||
  586. $status['Status'] == eZTrigger::REDIRECT )
  587. {
  588. $bodyMemento = $this->storeBodyMemento( $triggerName, $triggerKeys,
  589. $operationKeys, $operationParameterDefinitions, $operationParameters,
  590. $bodyCallCount, $currentLoopData, $operationName );
  591. $workflowProcess = $status['WorkflowProcess'];
  592. if ( $workflowProcess !== null )
  593. {
  594. $workflowProcess->setAttribute( 'memento_key', $bodyMemento->attribute( 'memento_key' ) );
  595. $workflowProcess->store();
  596. }
  597. $bodyReturnValue['result'] = $status['Result'];
  598. if ( $status['Status'] == eZTrigger::REDIRECT )
  599. {
  600. $bodyReturnValue['redirect_url'] = $status['Result'];
  601. }
  602. if ( $status['Status'] == eZTrigger::FETCH_TEMPLATE_REPEAT )
  603. {
  604. // Hack for project issue #14371 (fetch template repeat)
  605. // The object version's status is set to REPEAT so that it can
  606. // be submitted again
  607. if ( $operationName == 'publish' && $this->ModuleName == 'content' )
  608. {
  609. eZContentOperationCollection::setVersionStatus( $operationParameters['object_id'],
  610. $operationParameters['version'], eZContentObjectVersion::STATUS_REPEAT );
  611. }
  612. return eZModuleOperationInfo::STATUS_REPEAT;
  613. }
  614. else
  615. {
  616. return eZModuleOperationInfo::STATUS_HALTED;
  617. }
  618. }
  619. else if ( $status['Status'] == eZTrigger::WORKFLOW_CANCELLED or
  620. $status['Status'] == eZTrigger::WORKFLOW_RESET )
  621. {
  622. return eZModuleOperationInfo::STATUS_CANCELLED;
  623. $bodyReturnValue['result'] = $status['Result'];
  624. }
  625. }
  626. function storeOperationMemento( $operationKeys, $operationParameterDefinitions, $operationParameters,
  627. &$bodyCallCount, $operationName )
  628. {
  629. $mementoData = array();
  630. $mementoData['module_name'] = $this->ModuleName;
  631. $mementoData['operation_name'] = $operationName;
  632. if ( $this->Memento === null )
  633. {
  634. $keyArray = $this->makeKeyArray( $operationKeys, $operationParameterDefinitions, $operationParameters );
  635. $http = eZHTTPTool::instance();
  636. $keyArray['session_key'] = $http->getSessionKey();
  637. $mementoData['loop_run'] = $bodyCallCount['loop_run'];
  638. $memento = eZOperationMemento::create( $keyArray, $mementoData, true );
  639. $this->Memento = $memento;
  640. }
  641. else
  642. {
  643. $mementoData = $this->Memento->data();
  644. $mementoData['loop_run'] = $bodyCallCount['loop_run'];
  645. $this->Memento->setData( $mementoData );
  646. }
  647. }
  648. function removeBodyMemento( $bodyName, $bodyKeys,
  649. $operationKeys, $operationParameterDefinitions, $operationParameters,
  650. &$bodyCallCount, $currentLoopData, $operationName )
  651. {
  652. $keyArray = $this->makeKeyArray( $operationKeys, $operationParameterDefinitions, $operationParameters );
  653. }
  654. /**
  655. * Packs the current body data (memento) for save & re-use
  656. *
  657. * @param string $bodyName
  658. * @param array $bodyKeys
  659. * @param array $operationKeys
  660. * @param array $operationParameterDefinitions
  661. * @param array $operationParameters
  662. * @param int $bodyCallCount
  663. * @param array $currentLoopData
  664. * @param string $operationName
  665. * @return The memento
  666. */
  667. function storeBodyMemento( $bodyName, $bodyKeys,
  668. $operationKeys, $operationParameterDefinitions, $operationParameters,
  669. &$bodyCallCount, $currentLoopData, $operationName )
  670. {
  671. $this->storeOperationMemento( $operationKeys, $operationParameterDefinitions, $operationParameters, $bodyCallCount, $operationName );
  672. $keyArray = $this->makeKeyArray( $operationKeys, $operationParameterDefinitions, $operationParameters );
  673. $http = eZHTTPTool::instance();
  674. $keyArray['session_key'] = $http->getSessionKey();
  675. $mementoData = array();
  676. $mementoData['name'] = $bodyName;
  677. $mementoData['parameters'] = $operationParameters;
  678. $mementoData['loop_data'] = $currentLoopData;
  679. $mementoData['module_name'] = $this->ModuleName;
  680. $mementoData['operation_name'] = $operationName;
  681. $memento = eZOperationMemento::create( $keyArray, $mementoData, false, $this->Memento->attribute( 'memento_key' ) );
  682. $memento->store();
  683. return $memento;
  684. }
  685. function restoreBodyMementoData( $bodyName, &$mementoData,
  686. &$operationParameters, &$bodyCallCount, &$currentLoopData )
  687. {
  688. $operationParameters = array();
  689. if ( isset( $mementoData['parameters'] ) )
  690. $operationParameters = $mementoData['parameters'];
  691. if ( isset( $mementoData[ 'main_memento' ] ) )
  692. {
  693. $this->Memento = $mementoData[ 'main_memento' ];
  694. $mainMementoData = $this->Memento->data();
  695. if ( isset( $mainMementoData['loop_run'] ) )
  696. {
  697. $bodyCallCount['loop_run'] = $mainMementoData['loop_run'];
  698. }
  699. }
  700. // if ( $this->Memento !== null )
  701. // {
  702. // $mementoOperationData = $this->Memento->data();
  703. // if ( isset( $mementoOperationData['loop_run'] ) )
  704. // $bodyCallCount['loop_run'] = $mementoOperationData['loop_run'];
  705. // }
  706. if ( isset( $mementoData['loop_data'] ) )
  707. $currentLoopData = $mementoData['loop_data'];
  708. if ( isset( $mementoData['skip_trigger'] ) && $mementoData['skip_trigger'] == true )
  709. {
  710. $mementoData = null;
  711. return false;
  712. }
  713. else
  714. {
  715. $mementoData = null;
  716. return true;
  717. }
  718. return true;
  719. }
  720. /**
  721. * Executes a class method in an operation body
  722. *
  723. * @param string $includeFile The file where the class & method are defined
  724. * @param string $className The class where the method is implemented
  725. * @param string $methodName The method to call
  726. * @param mixed $operationParameterDefinitions The method parameters definition
  727. * @param mixed $operationParameters The method parameters values
  728. * @return array
  729. */
  730. function executeClassMethod( $includeFile, $className, $methodName,
  731. $operationParameterDefinitions, $operationParameters )
  732. {
  733. include_once( $includeFile );
  734. if ( !class_exists( $className ) )
  735. {
  736. return array( 'internal_error' => eZModuleOperationInfo::ERROR_NO_CLASS,
  737. 'internal_error_class_name' => $className );
  738. }
  739. $classObject = $this->objectForClass( $className );
  740. if ( $classObject === null )
  741. {
  742. return array( 'internal_error' => eZModuleOperationInfo::ERROR_CLASS_INSTANTIATE_FAILED,
  743. 'internal_error_class_name' => $className );
  744. }
  745. if ( !method_exists( $classObject, $methodName ) )
  746. {
  747. return array( 'internal_error' => eZModuleOperationInfo::ERROR_NO_CLASS_METHOD,
  748. 'internal_error_class_name' => $className,
  749. 'internal_error_class_method_name' => $methodName );
  750. }
  751. $parameterArray = array();
  752. foreach ( $operationParameterDefinitions as $operationParameterDefinition )
  753. {
  754. $parameterName = $operationParameterDefinition['name'];
  755. if ( isset( $operationParameterDefinition['constant'] ) )
  756. {
  757. $constantValue = $operationParameterDefinition['constant'];
  758. $parameterArray[] = $constantValue;
  759. }
  760. else if ( isset( $operationParameters[$parameterName] ) )
  761. {
  762. // Do type checking
  763. $parameterArray[] = $operationParameters[$parameterName];
  764. }
  765. else
  766. {
  767. if ( $operationParameterDefinition['required'] )
  768. {
  769. return array( 'internal_error' => eZModuleOperationInfo::ERROR_MISSING_PARAMETER,
  770. 'internal_error_parameter_name' => $parameterName );
  771. }
  772. else if ( isset( $operationParameterDefinition['default'] ) )
  773. {
  774. $parameterArray[] = $operationParameterDefinition['default'];
  775. }
  776. else
  777. {
  778. $parameterArray[] = null;
  779. }
  780. }
  781. }
  782. return call_user_func_array( array( $classObject, $methodName ), $parameterArray );
  783. }
  784. /**
  785. * Helper method that keeps and returns the instances of operation objects
  786. * @param string $className The class the method should return an object for
  787. * @return $className
  788. * @private
  789. * @todo Use a static variable instead of globals
  790. */
  791. function objectForClass( $className )
  792. {
  793. if ( !isset( $GLOBALS['eZModuleOperationClassObjectList'] ) )
  794. {
  795. $GLOBALS['eZModuleOperationClassObjectList'] = array();
  796. }
  797. if ( isset( $GLOBALS['eZModuleOperationClassObjectList'][$className] ) )
  798. {
  799. return $GLOBALS['eZModuleOperationClassObjectList'][$className];
  800. }
  801. return $GLOBALS['eZModuleOperationClassObjectList'][$className] = new $className();
  802. }
  803. /**
  804. * @deprecated use call_user_func_array() instead
  805. */
  806. function callClassMethod( $methodName, $classObject, $parameterArray )
  807. {
  808. return call_user_func_array( array( $classObject, $methodName ), $parameterArray );
  809. }
  810. /// \privatesection
  811. public $ModuleName;
  812. public $FunctionList;
  813. public $IsValid;
  814. public $UseTriggers = false;
  815. /**
  816. * @var eZOperationMemento
  817. */
  818. public $Memento;
  819. }
  820. ?>