PageRenderTime 56ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/ezutils/classes/ezmoduleoperationinfo.php

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