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

/lib/ezutils/classes/ezmodule.php

https://github.com/aurelienRT1/ezpublish
PHP | 2087 lines | 1118 code | 143 blank | 826 comment | 180 complexity | 7e1ba07de205240e3f2c9da5d1d12bf8 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. //
  3. // Definition of eZModule class
  4. //
  5. // Created on: <17-Apr-2002 11:11:39 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. /**
  31. * The eZModule class is used to instanciate and use modules & views.
  32. *
  33. * Loading the "content" module, and running the "history" view
  34. * <code>
  35. * <?php
  36. * $contentModule = eZModule::findModule( 'content' );
  37. * $result = $contentModule->run( 'history', array( 1 ) );
  38. * ?>
  39. * </code>
  40. *
  41. * Running the CopyVersion action of the content/history view:
  42. * <code>
  43. * <?php
  44. * $contentModule = eZModule::findModule( 'content' );
  45. * $contentModule->setCurrentView( 'history' );
  46. * $contentModule->setCurrentAction( 'CopyVersion' );
  47. * // we will copy version 3
  48. * $contentModule->setActionParameter( 'VersionID', 3 );
  49. * $contentModule->run( 'history', array( 20 ) );
  50. * ?>
  51. * </code>
  52. */
  53. class eZModule
  54. {
  55. /**
  56. * Module execution status: IDLE
  57. * @var int
  58. */
  59. const STATUS_IDLE = 0;
  60. /**
  61. * Module execution status: OK
  62. * @var int
  63. */
  64. const STATUS_OK = 1;
  65. /**
  66. * Module execution status: FAILED
  67. * @var int
  68. */
  69. const STATUS_FAILED = 2;
  70. /**
  71. * Module execution status: REDIRECT
  72. * @var int
  73. */
  74. const STATUS_REDIRECT = 3;
  75. /**
  76. * Module execution status: RERUN
  77. * @var int
  78. */
  79. const STATUS_RERUN = 4;
  80. /**
  81. * Hooks execution status: OK
  82. * @var int
  83. */
  84. const HOOK_STATUS_OK = 0;
  85. /**
  86. * Hooks execution status: CANCEL_RUN
  87. * @var int
  88. */
  89. const HOOK_STATUS_CANCEL_RUN = 1;
  90. /**
  91. * Hooks execution status: FAILED
  92. * @var int
  93. */
  94. const HOOK_STATUS_FAILED = 2;
  95. /**
  96. * Constructor. Initializes the module.
  97. *
  98. * @param string $path
  99. * Relative path to the module, without the module name
  100. * @param string $file
  101. * Relative path to the module definition file module.php
  102. * @param string $moduleName
  103. * @param boolean $checkFileExistence
  104. * Always set to false in the current code base, since the check is
  105. * usually performed before the constructor is called
  106. */
  107. function eZModule( $path, $file, $moduleName, $checkFileExistence = true )
  108. {
  109. $this->initialize( $path, $file, $moduleName, $checkFileExistence);
  110. }
  111. /**
  112. * Initializes the module object.
  113. *
  114. * @param string $path
  115. * Directory where the module is declared, without the modulename
  116. * component
  117. * @param string $file
  118. * Full (relative) path to the module.php file describing the module
  119. * @param string $moduleName
  120. * The module name (content, user...)
  121. * @param bool $checkFileExistence
  122. * Wether or not $file's existence should be checked
  123. *
  124. * @todo Check if it can be marked as private
  125. * @return void
  126. */
  127. function initialize( $path, $file, $moduleName, $checkFileExistence = true )
  128. {
  129. if ( $checkFileExistence === false || file_exists( $file ) )
  130. {
  131. unset( $FunctionList );
  132. unset( $Module );
  133. unset( $ViewList );
  134. include( $file );
  135. $this->Functions = $ViewList;
  136. if ( isset( $FunctionList ) and
  137. is_array( $FunctionList ) and
  138. count( $FunctionList ) > 0 )
  139. {
  140. ksort( $FunctionList, SORT_STRING );
  141. $this->FunctionList = $FunctionList;
  142. }
  143. else
  144. {
  145. $this->FunctionList = array();
  146. }
  147. if ( empty( $Module ) )
  148. {
  149. $Module = array( "name" => "null",
  150. "variable_params" => false,
  151. "function" => array() );
  152. }
  153. $this->Module = $Module;
  154. $this->Name = $moduleName;
  155. $this->Path = $path;
  156. $this->Title = "";
  157. $this->UIContext = 'navigation';
  158. $this->UIComponent = $moduleName;
  159. $uiComponentMatch = 'module';
  160. if ( isset( $this->Module['ui_component_match'] ) )
  161. {
  162. $uiComponentMatch = $this->Module['ui_component_match'];
  163. }
  164. $this->UIComponentMatch = $uiComponentMatch;
  165. foreach( $this->Functions as $key => $dummy)
  166. {
  167. $this->Functions[$key]["uri"] = "/$moduleName/$key";
  168. }
  169. }
  170. else
  171. {
  172. $this->Functions = array();
  173. $this->Module = array( "name" => "null",
  174. "variable_params" => false,
  175. "function" => array() );
  176. $this->Name = $moduleName;
  177. $this->Path = $path;
  178. $this->Title = "";
  179. $this->UIContext = 'navigation';
  180. $this->UIComponent = $moduleName;
  181. $this->UIComponentMatch = 'module';
  182. }
  183. $this->HookList = array();
  184. $this->ExitStatus = eZModule::STATUS_IDLE;
  185. $this->ErrorCode = 0;
  186. $this->ViewActions = array();
  187. $this->OriginalParameters = null;
  188. $this->UserParameters = array();
  189. // Load in navigation part overrides
  190. $ini = eZINI::instance( 'module.ini' );
  191. $this->NavigationParts = $ini->variable( 'ModuleOverrides', 'NavigationPart' );
  192. }
  193. /**
  194. * Returns the module's URI (/content, /user...)
  195. * @return string The module's URI
  196. *
  197. * @see functionURI()
  198. */
  199. function uri()
  200. {
  201. return "/" . $this->Name;
  202. }
  203. /**
  204. * Returns the URI to a module's function
  205. *
  206. * @param string $function The function to return the URI for
  207. * @return string|null
  208. * - the function's URI (content/edit, user/login, etc)
  209. * - if $function is empty or the module is a singleView one,
  210. * the module's uri (content/, user/...)
  211. * - null if the function's not found
  212. *
  213. * @see uri()
  214. */
  215. function functionURI( $function )
  216. {
  217. if ( $this->singleFunction() or
  218. $function == '' )
  219. return $this->uri();
  220. if ( isset( $this->Functions[$function] ) )
  221. return $this->Functions[$function]["uri"];
  222. else
  223. return null;
  224. }
  225. /**
  226. * Returns the title of the last ran view. Normally set by the view itself,
  227. * and displayed as the page's title
  228. *
  229. * @return string
  230. *
  231. * @see setTitle()
  232. */
  233. function title()
  234. {
  235. return $this->Title;
  236. }
  237. /**
  238. * Sets the current view for the module to \a $title.
  239. *
  240. * @param string $title The title to be set
  241. *
  242. * @see title()
  243. */
  244. function setTitle( $title )
  245. {
  246. $this->Title = $title;
  247. }
  248. /**
  249. * Sets the name of the currently running module. The URIs will be updated
  250. * accordingly
  251. *
  252. * @param string $name The name to be set
  253. *
  254. * @return void
  255. *
  256. * @see uri(), functionURI()
  257. */
  258. function setCurrentName( $name )
  259. {
  260. $this->Name = $name;
  261. foreach( $this->Functions as $key => $dummy )
  262. {
  263. $this->Functions[$key]["uri"] = "/$name/$key";
  264. }
  265. }
  266. /**
  267. * Sets the currently executed view
  268. *
  269. * @param string $name The view name
  270. *
  271. * @return void
  272. *
  273. * @see currentView()
  274. */
  275. function setCurrentView( $name )
  276. {
  277. $GLOBALS['eZModuleCurrentView'] = $name;
  278. }
  279. /**
  280. * Checks if the module is a single view one
  281. * @return bool
  282. */
  283. function singleFunction()
  284. {
  285. return count( $this->Functions ) == 0;
  286. }
  287. /**
  288. * Returns the UI context
  289. * @return string The current UI context. Default: 'navigation'
  290. *
  291. * @see setUIContextName()
  292. */
  293. function uiContextName()
  294. {
  295. return $this->UIContext;
  296. }
  297. /**
  298. * Returns the UI component, by default the module name
  299. *
  300. * @return string The current UI component
  301. *
  302. * @see setUIComponentName()
  303. */
  304. function uiComponentName()
  305. {
  306. return $this->UIComponent;
  307. }
  308. /**
  309. * Sets the current context
  310. *
  311. * @param string $context The new context string
  312. *
  313. * @see uiContextName()
  314. *
  315. * @return void
  316. */
  317. function setUIContextName( $context )
  318. {
  319. $this->UIContext = $context;
  320. }
  321. /**
  322. * Sets the current component name
  323. *
  324. * @param string $component The new component name
  325. *
  326. * @see uiComponentName()
  327. *
  328. * @return void
  329. */
  330. function setUIComponentName( $component )
  331. {
  332. $this->UIComponent = $component;
  333. }
  334. /**
  335. * Returns the last exit status after a view has been executed
  336. *
  337. * @return int one of STATUS_* constants
  338. *
  339. * @see setExitStatus()
  340. */
  341. function exitStatus()
  342. {
  343. return $this->ExitStatus;
  344. }
  345. /**
  346. * Sets the exit status. This status will be used to inform the user,
  347. * perform a redirection...
  348. *
  349. * @param int $stat One of the eZModule::STATUS_* constants
  350. *
  351. * @see exitStatus()
  352. * @return void
  353. */
  354. function setExitStatus( $stat )
  355. {
  356. $this->ExitStatus = $stat;
  357. }
  358. /**
  359. * Returns the last error code. An error should only be returned if the
  360. * module's status is eZModule::STATUS_FAILED
  361. *
  362. * @return int The error code, or 0 if no error occured
  363. *
  364. * @see setErrorCode(), exitStatus(), setExitStatus()
  365. */
  366. function errorCode()
  367. {
  368. return $this->ErrorCode;
  369. }
  370. /**
  371. * Sets the current error code.
  372. * @note For the error code to be used, the module's status needs to be set
  373. * to eZModule::STATUS_FAILED
  374. * @see setExitStatus(), errorCode()
  375. * @return void
  376. */
  377. function setErrorCode( $errorCode )
  378. {
  379. $this->ErrorCode = $errorCode;
  380. }
  381. /**
  382. * Returns the error module which will be ran if an error occurs
  383. *
  384. * @return array the error module name (keys: module, view)
  385. *
  386. * @see handleError()
  387. */
  388. function errorModule()
  389. {
  390. if ( !isset( $GLOBALS['eZModuleGlobalErrorModule'] ) )
  391. $GLOBALS['eZModuleGlobalErrorModule'] = array( 'module' => 'error',
  392. 'view' => 'view' );
  393. return $GLOBALS['eZModuleGlobalErrorModule'];
  394. }
  395. /**
  396. * Sets the module to be used to handle errors
  397. *
  398. * @param string $moduleName
  399. * @param string $viewName
  400. *
  401. * @see handleError(), errorModule()
  402. */
  403. function setErrorModule( $moduleName, $viewName )
  404. {
  405. $GLOBALS['eZModuleGlobalErrorModule'] = array( 'module' => $moduleName,
  406. 'view' => $viewName );
  407. }
  408. /**
  409. * Runs the defined error module
  410. * Sets the state of the module object to \c failed and sets the error code.
  411. *
  412. * @param mixed $errorCode
  413. * @param mixed $errorType
  414. * @param array $parameters
  415. * @param mixed $userParameters
  416. *
  417. * @see setErrorModule(), errorModule()
  418. */
  419. function handleError( $errorCode, $errorType = false, $parameters = array(), $userParameters = false )
  420. {
  421. if ( !$errorType )
  422. {
  423. eZDebug::writeWarning( "No error type specified for error code $errorCode, assuming kernel.\nA specific error type should be supplied, please check your code.",
  424. 'eZModule::handleError' );
  425. $errorType = 'kernel';
  426. }
  427. // @todo Make this non static
  428. $errorModule = eZModule::errorModule();
  429. // @todo Does this need to be static ?
  430. $module = eZModule::findModule( $errorModule['module'], $this );
  431. if ( $module === null )
  432. {
  433. return false;
  434. }
  435. $result = $module->run( $errorModule['view'], array( $errorType, $errorCode, $parameters, $userParameters ) );
  436. // The error module may want to redirect to another URL, see error.ini
  437. if ( $this->exitStatus() != eZModule::STATUS_REDIRECT and
  438. $this->exitStatus() != eZModule::STATUS_RERUN )
  439. {
  440. $this->setExitStatus( eZModule::STATUS_FAILED );
  441. $this->setErrorCode( $errorCode );
  442. }
  443. return $result;
  444. }
  445. /**
  446. * Redirects to another module / view
  447. *
  448. * @note Use redirectModule() If the target module object is already available
  449. * @note Use redirectToView() if you want to redirect to another view in the same module
  450. *
  451. * @see redirectionURI(), redirectModule(), redirectToView()
  452. *
  453. * @param string $moduleName Target module name
  454. * @param string $viewName Target view name
  455. * @param array $parameters View parameters array
  456. * @param array $unorderedParameters Unordered parameters array
  457. * @param array $userParameters User parameters array
  458. * @param string $anchor Anchor to use in the redirection (prepended to the URL)
  459. *
  460. * @return bool true if the redirection was performed, false if the module wasn't found
  461. */
  462. function redirect( $moduleName, $viewName, $parameters = array(),
  463. $unorderedParameters = null, $userParameters = false,
  464. $anchor = false )
  465. {
  466. $module = eZModule::exists( $moduleName );
  467. if ( $module )
  468. {
  469. return $this->redirectModule( $module, $viewName, $parameters,
  470. $unorderedParameters, $userParameters, $anchor );
  471. }
  472. else
  473. {
  474. eZDebug::writeError( 'Undefined module: ' . $moduleName, 'eZModule::redirect' );
  475. }
  476. return false;
  477. }
  478. /**
  479. * Redirects to another view in the current module
  480. *
  481. * @see redirectionURI(), redirectModule(), redirect()
  482. *
  483. * @param string $viewName Target view name
  484. * @param array $parameters View parameters
  485. * @param array $unorderedParameters Unordered view parameters
  486. * @param array $userParameters User parameters
  487. * @param string $anchor Redirection URI anchor
  488. *
  489. * @return boolean true if successful, false if the view isn't found
  490. */
  491. function redirectToView( $viewName = '', $parameters = array(),
  492. $unorderedParameters = null, $userParameters = false,
  493. $anchor = false )
  494. {
  495. return $this->redirectModule( $this, $viewName, $parameters,
  496. $unorderedParameters, $userParameters, $anchor );
  497. }
  498. /**
  499. * Redirects to another module / view.
  500. *
  501. * The difference with redirect is that the $module parameter is an object
  502. * instead of a string
  503. *
  504. * @param eZModule $moduleName Target module name
  505. * @param string $viewName Target view name
  506. * @param array $parameters View parameters array
  507. * @param array $unorderedParameters Unordered parameters array
  508. * @param array $userParameters User parameters array
  509. * @param string $anchor Redirection URI anchor
  510. *
  511. * @return boolean true. Just true.
  512. *
  513. * @todo Deprecate; have redirect() check if $module is an eZModule or a string
  514. */
  515. function redirectModule( $module, $viewName, $parameters = array(),
  516. $unorderedParameters = null, $userParameters = false,
  517. $anchor = false )
  518. {
  519. $uri = $this->redirectionURIForModule( $module, $viewName, $parameters,
  520. $unorderedParameters, $userParameters, $anchor );
  521. $this->redirectTo( $uri );
  522. return true;
  523. }
  524. /**
  525. * Creates the redirection URI for a given module, view & parameters.
  526. * Unlike redirectionURIForModule(), the $module parameter is the module name
  527. *
  528. * @param string $moduleName Redirection module name
  529. * @param string $viewName Redirection view name
  530. * @param array $parameters View parameters
  531. * @param array $unorderedParameters Unordered parameters
  532. * @param array $userParameters User parameters
  533. * @param string $anchor Redirection URI anchor
  534. *
  535. * @return string|boolean The redirection URI, or false if the module isn't found
  536. *
  537. * @see redirect(), redirectionURIForModule(), redirectToView(), redirectModule()
  538. */
  539. function redirectionURI( $moduleName, $viewName, $parameters = array(),
  540. $unorderedParameters = null, $userParameters = false,
  541. $anchor = false )
  542. {
  543. $module = eZModule::exists( $moduleName );
  544. if ( $module )
  545. {
  546. return $this->redirectionURIForModule( $module, $viewName, $parameters,
  547. $unorderedParameters, $userParameters, $anchor );
  548. }
  549. else
  550. eZDebug::writeError( 'Undefined module: ' . $moduleName, 'eZModule::redirectionURI' );
  551. return false;
  552. }
  553. /**
  554. * Creates the redirection URI for the current module, view & parameters
  555. *
  556. * @return string The redirection URI
  557. *
  558. * @see redirectionURIForModule()
  559. */
  560. function currentRedirectionURI()
  561. {
  562. $module = $this;
  563. $viewName = eZModule::currentView();
  564. $parameters = $this->OriginalViewParameters;
  565. $unorderedParameters = $this->OriginalUnorderedParameters;
  566. $userParameters = $this->UserParameters;
  567. return $this->redirectionURIForModule( $module, $viewName, $parameters,
  568. $unorderedParameters, $userParameters );
  569. }
  570. /**
  571. * Redirects to the current module and view, it will use currentRedirectionURI() to
  572. * figure out the URL.
  573. *
  574. * @note By changing using setCurrentName() and setCurrentView() first it is
  575. * possible to redirect to another module or view with the same
  576. * parameters.
  577. *
  578. * @see currentRedirectionURI(), redirectTo()
  579. *
  580. * @return void
  581. */
  582. function redirectCurrent()
  583. {
  584. $this->redirectTo( $this->currentRedirectionURI() );
  585. }
  586. /**
  587. * Creates the redirection URI for a given module, view & parameters.
  588. * Unlike redirectionURI(), the $module parameter is a module object
  589. *
  590. * @param string $moduleName Redirection module name
  591. * @param string $viewName
  592. * Redirection view name. If empty, the current view will be used
  593. * @param array $parameters View parameters
  594. * @param array $unorderedParameters Unordered parameters
  595. * @param array $userParameters User parameters
  596. * @param string $anchor Redirection URI anchor
  597. *
  598. * @return string|boolean The redirection URI, or false if the module isn't found
  599. *
  600. * @see redirect(), redirectionURIForModule(), redirectToView(), redirectModule()
  601. */
  602. function redirectionURIForModule( $module, $viewName, $parameters = array(),
  603. $unorderedParameters = null, $userParameters = false,
  604. $anchor = false )
  605. {
  606. if ( $viewName == '' )
  607. $viewName = eZModule::currentView();
  608. $uri = $module->functionURI( $viewName );
  609. $uri .= '/';
  610. $viewParameters = $module->parameters( $viewName );
  611. $parameterIndex = 0;
  612. $unorderedURI = '';
  613. $hasUnorderedParameter = false;
  614. if ( $unorderedParameters !== null )
  615. {
  616. $unorderedViewParameters = $module->unorderedParameters( $viewName );
  617. if ( is_array( $unorderedViewParameters ) )
  618. {
  619. foreach ( $unorderedViewParameters as $unorderedViewParameterName => $unorderedViewParameterVariable )
  620. {
  621. if ( isset( $unorderedParameters[$unorderedViewParameterVariable] ) )
  622. {
  623. $unorderedURI .= $unorderedViewParameterName . '/' . $unorderedParameters[$unorderedViewParameterVariable] . '/';
  624. $hasUnorderedParameter = true;
  625. }
  626. }
  627. }
  628. }
  629. if( !isset( $viewParameters ) )
  630. $viewParameters = array(); // prevent PHP warning below
  631. foreach ( $viewParameters as $viewParameter )
  632. {
  633. if ( !isset( $parameters[$parameterIndex] ) )
  634. {
  635. // We don't show a warning anymore since some parameters can be optional
  636. // In future versions we will need required and optional parameters
  637. // for modules and give warnings for required ones.
  638. // eZDebug::writeWarning( "Missing parameter(s) " . implode( ', ', array_slice( $viewParameters, $parameterIndex ) ) .
  639. // " in view '$viewName'", 'eZModule::redirect' );
  640. }
  641. else
  642. $uri .= $parameters[$parameterIndex] . '/';
  643. ++$parameterIndex;
  644. }
  645. if ( $hasUnorderedParameter )
  646. {
  647. $uri .= $unorderedURI;
  648. }
  649. if ( is_array( $userParameters ) )
  650. {
  651. foreach ( $userParameters as $name => $value )
  652. {
  653. $uri .= '/(' . $name . ')/' . $value;
  654. }
  655. }
  656. $uri = preg_replace( "#(^.*)(//+)$#", "\$1", $uri );
  657. if ( $anchor !== false )
  658. $uri .= '#' . urlencode( $anchor );
  659. return $uri;
  660. }
  661. /**
  662. * Returns the defined parameter for a view.
  663. *
  664. * @param string $viewName
  665. * The view to get parameters for. If not specified, the current view
  666. * is used
  667. *
  668. * @return array The parameters definition
  669. * @see unorderedParameters(), viewData(), currentView(), currentModule()
  670. */
  671. function parameters( $viewName = '' )
  672. {
  673. if ( $viewName == '' )
  674. $viewName = eZModule::currentView();
  675. $viewData = $this->viewData( $viewName );
  676. if ( isset( $viewData['params'] ) )
  677. {
  678. return $viewData['params'];
  679. }
  680. return null;
  681. }
  682. /**
  683. * Returns the unordered parameters definition.
  684. *
  685. * @param string $viewName
  686. * The view to return parameters for. If npt specified, the current
  687. * view is used
  688. *
  689. * @return the unordered parameter definition for the requested view
  690. *
  691. * @see parameters(), viewData(), currentView(), currentModule()
  692. */
  693. function unorderedParameters( $viewName = '' )
  694. {
  695. if ( $viewName == '' )
  696. $viewName = eZModule::currentView();
  697. $viewData = $this->viewData( $viewName );
  698. if ( isset( $viewData['unordered_params'] ) )
  699. {
  700. return $viewData['unordered_params'];
  701. }
  702. return null;
  703. }
  704. /**
  705. * Returns data for a view
  706. *
  707. * @param string $viewName
  708. * The view to return data for. If omited, the current view is used
  709. * @see parameters(), unorderedParameters(), currentView(), currentModule()
  710. *
  711. * @return array
  712. */
  713. function viewData( $viewName = '' )
  714. {
  715. if ( $viewName == '' )
  716. $viewName = eZModule::currentView();
  717. if ( $this->singleFunction() )
  718. $viewData = $this->Module["function"];
  719. else
  720. $viewData = $this->Functions[$viewName];
  721. return $viewData;
  722. }
  723. /**
  724. * Sets the module to redirect at the end of the execution
  725. *
  726. * @param string $uri the URI to redirect to
  727. *
  728. * @see setRedirectURI(), setExitStatus()
  729. *
  730. * @return void
  731. */
  732. function redirectTo( $uri )
  733. {
  734. $originalURI = $uri;
  735. $uri = preg_replace( "#(^.*)(/+)$#", "\$1", $uri );
  736. if ( strlen( $originalURI ) != 0 and
  737. strlen( $uri ) == 0 )
  738. $uri = '/';
  739. $this->RedirectURI = $uri;
  740. $this->setExitStatus( eZModule::STATUS_REDIRECT );
  741. }
  742. /**
  743. * Returns the current redirection URI
  744. *
  745. * @return string
  746. *
  747. * @see setRedirectURI()
  748. */
  749. function redirectURI()
  750. {
  751. return $this->RedirectURI;
  752. }
  753. /**
  754. * Sets the URI which will be redirected to when the function exits
  755. *
  756. * @param string $uri The redirection URI
  757. *
  758. * @return void
  759. **/
  760. function setRedirectURI( $uri )
  761. {
  762. $this->RedirectURI = $uri;
  763. }
  764. /**
  765. * Returns the redirection HTTP status (!)
  766. *
  767. * @return something (probably)
  768. *
  769. * @deprecated 4.3 Not used ANYWHERE in the kernel
  770. */
  771. function redirectStatus()
  772. {
  773. return $this->RedirectStatus;
  774. }
  775. /**
  776. * Sets the HTTP status which will be set when redirecting
  777. *
  778. * @param string $status HTTP status
  779. *
  780. * @note The status must be a valid HTTP status with number and text.
  781. *
  782. * @deprecated 4.3 not used anywyere
  783. */
  784. function setRedirectStatus( $status )
  785. {
  786. $this->RedirectStatus = $status;
  787. }
  788. /**
  789. * Returns the defined object attributes (as in persistent objects)
  790. *
  791. * @return array the persistent object attributes
  792. */
  793. function attributes()
  794. {
  795. return array( "uri",
  796. "functions",
  797. 'views',
  798. "name",
  799. "path",
  800. "info",
  801. "aviable_functions",
  802. "available_functions" );
  803. }
  804. /**
  805. * Checks if an attribute exists
  806. *
  807. * @param string $attr Attribute name
  808. *
  809. * @return bool True if the attribute exists, false otherwise
  810. */
  811. function hasAttribute( $attr )
  812. {
  813. return in_array( $attr, $this->attributes() );
  814. }
  815. /**
  816. * Returns the value of an attribute
  817. *
  818. * @param string $attr Attribute name
  819. *
  820. * @return mixed The attribute value. If the attribute doesn't exist, a
  821. * warning is thrown, and false is returned
  822. */
  823. function attribute( $attr )
  824. {
  825. switch( $attr )
  826. {
  827. case "uri":
  828. return $this->uri();
  829. break;
  830. case "functions":
  831. return $this->Functions;
  832. case "views":
  833. return $this->Functions;
  834. case "name":
  835. return $this->Name;
  836. case "path":
  837. return $this->Path;
  838. case "info":
  839. return $this->Module;
  840. case 'aviable_functions':
  841. case 'available_functions':
  842. return $this->FunctionList;
  843. default:
  844. {
  845. eZDebug::writeError( "Attribute '$attr' does not exist", 'eZModule::attribute' );
  846. return null;
  847. }
  848. break;
  849. }
  850. }
  851. /**
  852. * Sets the current action for a view
  853. *
  854. * @param string $actionName The action to make current
  855. * @param string $view
  856. * The view to set the action for. If omited, the current view is used
  857. *
  858. * @return void
  859. *
  860. * @see currentAction(), isCurrentAction()
  861. */
  862. function setCurrentAction( $actionName, $view = '' )
  863. {
  864. if ( $view == '' )
  865. $view = eZModule::currentView();
  866. if ( $view == '' or $actionName == '' )
  867. return false;
  868. $this->ViewActions[$view] = $actionName;
  869. }
  870. /**
  871. * Returns the current action name.
  872. *
  873. * If the current action is not yet determined it will use the definitions in
  874. * module.php in order to find out the current action. It first looks trough
  875. * the \c single_post_actions array in the selected view mode, the key to
  876. * each element is the name of the post-variable to match, if it matches the
  877. * element value is set as the action.
  878. * \code
  879. * 'single_post_actions' => array( 'PreviewButton' => 'Preview',
  880. * 'PublishButton' => 'Publish' )
  881. * \endcode
  882. * If none of these matches it will use the elements from the \c post_actions
  883. * array to find a match. It uses the element value for each element to match
  884. * agains a post-variable, if it is found the contents of the post-variable
  885. * is set as the action.
  886. * \code
  887. * 'post_actions' => array( 'BrowseActionName' )
  888. * \endcode
  889. *
  890. * @return string The current action, or false if not set nor found
  891. *
  892. * @see setCurrentAction(), isCurrentAction()
  893. */
  894. function currentAction( $view = '' )
  895. {
  896. if ( $view == '' )
  897. $view = eZModule::currentView();
  898. if ( isset( $this->ViewActions[$view] ) )
  899. return $this->ViewActions[$view];
  900. $http = eZHTTPTool::instance();
  901. if ( isset( $this->Functions[$view]['default_action'] ) )
  902. {
  903. $defaultAction = $this->Functions[$view]['default_action'];
  904. foreach ( $defaultAction as $defaultActionStructure )
  905. {
  906. $actionName = $defaultActionStructure['name'];
  907. $type = $defaultActionStructure['type'];
  908. if ( $type == 'post' )
  909. {
  910. $parameters = array();
  911. if ( isset( $defaultActionStructure['parameters'] ) )
  912. $parameters = $defaultActionStructure['parameters'];
  913. $hasParameters = true;
  914. foreach ( $parameters as $parameterName )
  915. {
  916. if ( !$http->hasPostVariable( $parameterName ) )
  917. {
  918. $hasParameters = false;
  919. break;
  920. }
  921. }
  922. if ( $hasParameters )
  923. {
  924. $this->ViewActions[$view] = $actionName;
  925. return $this->ViewActions[$view];
  926. }
  927. }
  928. else
  929. {
  930. eZDebug::writeWarning( 'Unknown default action type: ' . $type, 'eZModule::currentAction' );
  931. }
  932. }
  933. }
  934. if ( isset( $this->Functions[$view]['single_post_actions'] ) )
  935. {
  936. $singlePostActions = $this->Functions[$view]['single_post_actions'];
  937. foreach( $singlePostActions as $postActionName => $realActionName )
  938. {
  939. if ( $http->hasPostVariable( $postActionName ) )
  940. {
  941. $this->ViewActions[$view] = $realActionName;
  942. return $this->ViewActions[$view];
  943. }
  944. }
  945. }
  946. if ( isset( $this->Functions[$view]['post_actions'] ) )
  947. {
  948. $postActions = $this->Functions[$view]['post_actions'];
  949. foreach( $postActions as $postActionName )
  950. {
  951. if ( $http->hasPostVariable( $postActionName ) )
  952. {
  953. $this->ViewActions[$view] = $http->postVariable( $postActionName );
  954. return $this->ViewActions[$view];
  955. }
  956. }
  957. }
  958. $this->ViewActions[$view] = false;
  959. return false;
  960. }
  961. /**
  962. * Sets an action parameter value
  963. *
  964. * @param string $parameterName
  965. * @param mixed $parameterValue
  966. * @param string $view
  967. * The view to set the action parameter for. If omited, the current
  968. * view is used
  969. * @return void
  970. * @see actionParameter(), hasActionParameter()
  971. */
  972. function setActionParameter( $parameterName, $parameterValue, $view = '' )
  973. {
  974. if ( $view == '' )
  975. $view = eZModule::currentView();
  976. $this->ViewActionParameters[$view][$parameterName] = $parameterValue;
  977. }
  978. /**
  979. * Returns an action parameter value
  980. *
  981. * @param string $parameterName
  982. * @param string $view
  983. * The view to return the parameter for. If omited, uses the current view
  984. *
  985. * @return mixed The parameter value, or null + error if not found
  986. * @see setActionParameter(), hasActionParameter()
  987. */
  988. function actionParameter( $parameterName, $view = '' )
  989. {
  990. if ( $view == '' )
  991. $view = eZModule::currentView();
  992. if ( isset( $this->ViewActionParameters[$view][$parameterName] ) )
  993. return $this->ViewActionParameters[$view][$parameterName];
  994. $currentAction = $this->currentAction( $view );
  995. $http = eZHTTPTool::instance();
  996. if ( isset( $this->Functions[$view]['post_action_parameters'][$currentAction] ) )
  997. {
  998. $postParameters = $this->Functions[$view]['post_action_parameters'][$currentAction];
  999. if ( isset( $postParameters[$parameterName] ) &&
  1000. $http->hasPostVariable( $postParameters[$parameterName] ) )
  1001. {
  1002. return $http->postVariable( $postParameters[$parameterName] );
  1003. }
  1004. eZDebug::writeError( "No such action parameter: $parameterName", 'eZModule::actionParameter' );
  1005. }
  1006. if ( isset( $this->Functions[$view]['post_value_action_parameters'][$currentAction] ) )
  1007. {
  1008. $postParameters = $this->Functions[$view]['post_value_action_parameters'][$currentAction];
  1009. if ( isset( $postParameters[$parameterName] ) )
  1010. {
  1011. $postVariables = $http->attribute( 'post' );
  1012. $postVariableNameMatch = $postParameters[$parameterName];
  1013. $regMatch = "/^" . $postVariableNameMatch . "_(.+)$/";
  1014. foreach ( $postVariables as $postVariableName => $postVariableValue )
  1015. {
  1016. if ( preg_match( $regMatch, $postVariableName, $matches ) )
  1017. {
  1018. $parameterValue = $matches[1];
  1019. $this->ViewActionParameters[$view][$parameterName] = $parameterValue;
  1020. return $parameterValue;
  1021. }
  1022. }
  1023. eZDebug::writeError( "No such action parameter: $parameterName", 'eZModule::actionParameter' );
  1024. }
  1025. }
  1026. return null;
  1027. }
  1028. /**
  1029. * Checks if an action parameter is defined for a view
  1030. *
  1031. * @param string $parameterName
  1032. * @param string $view
  1033. * The view to check the parameter for. If omited, uses the current view
  1034. *
  1035. * @return bool
  1036. *
  1037. * @see setActionParameter(), actionParameter()
  1038. */
  1039. function hasActionParameter( $parameterName, $view = '' )
  1040. {
  1041. if ( $view == '' )
  1042. $view = eZModule::currentView();
  1043. if ( isset( $this->ViewActionParameters[$view][$parameterName] ) )
  1044. return true;
  1045. $currentAction = $this->currentAction( $view );
  1046. $http = eZHTTPTool::instance();
  1047. if ( isset( $this->Functions[$view]['post_action_parameters'][$currentAction] ) )
  1048. {
  1049. $postParameters = $this->Functions[$view]['post_action_parameters'][$currentAction];
  1050. if ( isset( $postParameters[$parameterName] ) and
  1051. $http->hasPostVariable( $postParameters[$parameterName] ) )
  1052. {
  1053. return true;
  1054. }
  1055. }
  1056. if ( isset( $this->Functions[$view]['post_value_action_parameters'][$currentAction] ) )
  1057. {
  1058. $postParameters = $this->Functions[$view]['post_value_action_parameters'][$currentAction];
  1059. if ( isset( $postParameters[$parameterName] ) )
  1060. {
  1061. $postVariables = $http->attribute( 'post' );
  1062. $postVariableNameMatch = $postParameters[$parameterName];
  1063. $regMatch = "/^" . $postVariableNameMatch . "_(.+)$/";
  1064. foreach ( $postVariables as $postVariableName => $postVariableValue )
  1065. {
  1066. if ( preg_match( $regMatch, $postVariableName, $matches ) )
  1067. {
  1068. $parameterValue = $matches[1];
  1069. $this->ViewActionParameters[$view][$parameterName] = $parameterValue;
  1070. return true;
  1071. }
  1072. }
  1073. }
  1074. }
  1075. return false;
  1076. }
  1077. /**
  1078. * Checks if the current action is the given one
  1079. *
  1080. * @param string $actionName The action to check
  1081. * @param string $view The view to check the action for. Current view if omited.
  1082. *
  1083. * @return bool
  1084. *
  1085. * @see currentAction(), setCurrentAction()
  1086. */
  1087. function isCurrentAction( $actionName, $view = '' )
  1088. {
  1089. if ( $view == '' )
  1090. $view = eZModule::currentView();
  1091. if ( $view == '' or $actionName == '' )
  1092. return false;
  1093. return $this->currentAction( $view ) == $actionName;
  1094. }
  1095. /**
  1096. * Adds an entry to a hook. The entry is placed before all other existing
  1097. * entries (LIFO) unless $append is set to true.
  1098. * @param string $hookName
  1099. * The hook name.
  1100. * @param string $function
  1101. * Either the name of the function to be run or an array where the
  1102. * first entry is the object and the second is the method name.
  1103. * @param integer $priority
  1104. * The hook priority in the hooks stack.
  1105. * @param boolean $expandParameters
  1106. * Wether or not to expand parameters. If set to true (default), the
  1107. * parameters will be sent as real function parameters to the hooked
  1108. * function/method. If set to false, they will be sent as a single
  1109. * array.
  1110. * In both cases, the eZModule object will be the first parameter sent
  1111. * to each hook.
  1112. * @param boolean $append
  1113. * If set to false (default), the hook will be added at the top of
  1114. * the hooks list. If set to true, it will be added at the end
  1115. *
  1116. * @return void
  1117. */
  1118. function addHook( $hookName, $function, $priority = 1, $expandParameters = true, $append = false )
  1119. {
  1120. $hookEntries = isset( $this->HookList[$hookName] ) ? $this->HookList[$hookName] : false;
  1121. if ( !is_array( $hookEntries ) )
  1122. {
  1123. $hookEntries = array();
  1124. }
  1125. $entry = array( 'function' => $function,
  1126. 'expand_parameters' => $expandParameters );
  1127. $position = $priority;
  1128. if ( $append )
  1129. {
  1130. while ( isset( $hookEntries[$position] ) )
  1131. ++$position;
  1132. }
  1133. else
  1134. {
  1135. while ( isset( $hookEntries[$position] ) )
  1136. --$position;
  1137. }
  1138. $this->HookList[$hookName][$position] = $entry;
  1139. }
  1140. /**
  1141. * Runs all hooks found in the hook list named $hookName.
  1142. *
  1143. * @param string $hookName
  1144. * @param array $parameters
  1145. * Parameters to provide each function with
  1146. *
  1147. * @return integer The hook execution status, as one of the eZModule::HOOK_STATUS_*
  1148. * constants:
  1149. * - HOOK_STATUS_OK: means that every hook was executed correctly.
  1150. * - HOOK_STATUS_CANCEL_RUN: execution was cancelled by one hook
  1151. * - HOOK_STATUS_FAILED: only returned if the last hook failed. In
  1152. * any case, a warning is thrown.
  1153. *
  1154. */
  1155. function runHooks( $hookName, $parameters = null )
  1156. {
  1157. $status = null;
  1158. $hookEntries = isset( $this->HookList[$hookName] ) ? $this->HookList[$hookName] : false;
  1159. if ( isset( $hookEntries ) and
  1160. is_array( $hookEntries ) )
  1161. {
  1162. ksort( $hookEntries );
  1163. foreach ( $hookEntries as $hookEntry )
  1164. {
  1165. $function = $hookEntry['function'];
  1166. $expandParameters = $hookEntry['expand_parameters'];
  1167. if ( is_string( $function ) )
  1168. {
  1169. $functionName = $function;
  1170. if ( function_exists( $functionName ) )
  1171. {
  1172. if ( $parameters === null ||
  1173. $expandParameters === null )
  1174. {
  1175. $retVal = $functionName( $this );
  1176. }
  1177. else if ( $expandParameters )
  1178. {
  1179. $retVal = call_user_func_array( $functionName, array_merge( array( $this ), $parameters ) );
  1180. }
  1181. else
  1182. {
  1183. $retVal = $functionName( $this, $parameters );
  1184. }
  1185. }
  1186. else
  1187. {
  1188. eZDebug::writeError( "Unknown hook function '$functionName' in hook: $hookName", 'eZModule::runHooks' );
  1189. }
  1190. }
  1191. else if ( is_array( $function ) )
  1192. {
  1193. if ( isset( $function[0] ) &&
  1194. isset( $function[1] ) )
  1195. {
  1196. $object = $function[0];
  1197. $functionName = $function[1];
  1198. if ( method_exists( $object, $functionName ) )
  1199. {
  1200. if ( $parameters === null )
  1201. {
  1202. $retVal = $object->$function( $this );
  1203. }
  1204. else if ( $expandParameters )
  1205. {
  1206. $retVal = call_user_func_array( array( $object, $functionName ), array_merge( array( $this ), $parameters ) );
  1207. }
  1208. else
  1209. {
  1210. $retVal = $object->$functionName( $this, $parameters );
  1211. }
  1212. }
  1213. else
  1214. {
  1215. eZDebug::writeError( "Unknown hook method '$functionName' in class '" . strtolower( get_class( $object ) ) . "' in hook: $hookName", 'eZModule::runHooks' );
  1216. }
  1217. }
  1218. else
  1219. {
  1220. eZDebug::writeError( "Missing data for method handling in hook: $hookName", 'eZModule::runHooks' );
  1221. }
  1222. }
  1223. else
  1224. {
  1225. eZDebug::writeError( 'Unknown entry type ' . gettype( $function ) . 'in hook: ' . $hookName, 'eZModule::runHooks' );
  1226. }
  1227. switch( $retVal )
  1228. {
  1229. case eZModule::HOOK_STATUS_OK:
  1230. {
  1231. } break;
  1232. case eZModule::HOOK_STATUS_FAILED:
  1233. {
  1234. eZDebug::writeWarning( 'Hook execution failed in hook: ' . $hookName, 'eZModule::runHooks' );
  1235. } break;
  1236. case eZModule::HOOK_STATUS_CANCEL_RUN:
  1237. {
  1238. return $retVal;
  1239. } break;
  1240. }
  1241. }
  1242. }
  1243. return $status;
  1244. }
  1245. /**
  1246. * Sets the view result
  1247. *
  1248. * @param string $result The (usually HTML) view result
  1249. * @param string $view
  1250. * The view to set the result for. If omited, the current view is used
  1251. *
  1252. * @return void
  1253. * @see hasViewResult(), viewResult()
  1254. */
  1255. function setViewResult( $result, $view = '' )
  1256. {
  1257. if ( $view == '' )
  1258. $view = $this->currentView();
  1259. $this->ViewResult[$view] = $result;
  1260. }
  1261. /**
  1262. * Checks if a view has a result set
  1263. *
  1264. * @param string $view The view to test for. If omited, uses the current view
  1265. * @return bool
  1266. */
  1267. function hasViewResult( $view = '' )
  1268. {
  1269. if ( $view == '' )
  1270. $view = $this->currentView();
  1271. return isset( $this->ViewResult[$view] );
  1272. }
  1273. /**
  1274. * Returns the view result
  1275. *
  1276. * @param string $view
  1277. * The view to return the result for, or the current one if omited
  1278. *
  1279. * @return string|null The view result, or null if not set
  1280. */
  1281. function viewResult( $view = '' )
  1282. {
  1283. if ( $view == '' )
  1284. $view = $this->currentView();
  1285. if ( isset( $this->ViewResult[$view] ) )
  1286. {
  1287. return $this->ViewResult[$view];
  1288. }
  1289. return null;
  1290. }
  1291. /**
  1292. * Forwards the current execution to another module/view with the existing
  1293. * parameters.
  1294. *
  1295. * @param eZModule $module The eZModule object the request will be forwarded to
  1296. * @param string $functionName The function to run in that module
  1297. * @param array $parameters
  1298. * An array of parameters that will be added to the request. These
  1299. * will be merged with the existing parameters
  1300. * @return array The forwarded module/view result
  1301. */
  1302. function forward( $module, $functionName, $parameters = false )
  1303. {
  1304. $Return = null;
  1305. if ( $module && $functionName )
  1306. {
  1307. $viewName = eZModule::currentView();
  1308. if ( $parameters === false)
  1309. {
  1310. $parameters = array();
  1311. }
  1312. $parameters = array_merge( $parameters, $this->OriginalViewParameters );
  1313. $unorderedParameters = $this->OriginalUnorderedParameters;
  1314. $userParameters = $this->UserParameters;
  1315. $Return = $module->run( $functionName, $parameters, $unorderedParameters, $userParameters );
  1316. // override default navigation part
  1317. if ( $Return['is_default_navigation_part'] === true )
  1318. {
  1319. if ( $this->singleFunction() )
  1320. $function = $this->Module["function"];
  1321. else
  1322. $function = $this->Functions[$functionName];
  1323. if ( isset( $function['default_navigation_part'] ) )
  1324. {
  1325. $Return['navigation_part'] = $function['default_navigation_part'];
  1326. }
  1327. }
  1328. $this->RedirectURI = $module->redirectURI();
  1329. $this->setExitStatus( $module->exitStatus() );
  1330. }
  1331. return $Return;
  1332. }
  1333. /**
  1334. * Runs a function in the current module
  1335. *
  1336. * @param string $functionName The function to run
  1337. * @param array $parameters
  1338. * An indexed list of parameters, these will be mapped onto real
  1339. * parameters names using the defined parameters names in the
  1340. * module/function definition.
  1341. * Any unspecified parameter will be assigned null.
  1342. * @param array $overrideParameters
  1343. * An asociative array of parameters that will ultimately override
  1344. * what's in $parameters
  1345. * @param array $userParameters User (custom view) parameters
  1346. *
  1347. * @return array The run result
  1348. */
  1349. function run( $functionName, $parameters = array(), $overrideParameters = false, $userParameters = false )
  1350. {
  1351. if ( count( $this->Functions ) > 0 and
  1352. !isset( $this->Functions[$functionName] ) )
  1353. {
  1354. eZDebug::writeError( "Undefined view: " . $this->Module["name"] . "::$functionName ",
  1355. "eZModule" );
  1356. $this->setExitStatus( eZModule::STATUS_FAILED );
  1357. $Return = null;
  1358. return $Return;
  1359. }
  1360. if ( $this->singleFunction() )
  1361. $function = $this->Module["function"];
  1362. else
  1363. $function = $this->Functions[$functionName];
  1364. $params = array();
  1365. $i = 0;
  1366. $parameterValues = array();
  1367. if ( isset( $function["params"] ) )
  1368. {
  1369. $functionParameterDefinitions = $function["params"];
  1370. foreach ( $functionParameterDefinitions as $param )
  1371. {
  1372. if ( isset( $parameters[$i] ) )
  1373. {
  1374. $params[$param] = $parameters[$i];
  1375. $parameterValues[] = $parameters[$i];
  1376. }
  1377. else
  1378. {
  1379. $params[$param] = null;
  1380. $parameterValues[] = null;
  1381. }
  1382. ++$i;
  1383. }
  1384. }
  1385. $this->ViewParameters = $parameters;
  1386. $this->OriginalParameters = $parameters;
  1387. $this->OriginalViewParameters = $parameterValues;
  1388. $this->NamedParameters = $params;
  1389. $GLOBALS['eZRequestedModuleParams'] = array( 'module_name' => $this->Name,
  1390. 'function_name' => $functionName,
  1391. 'parameters' => $params );
  1392. $this->UserParameters = $userParameters;
  1393. if ( isset( $function['ui_context'] ) )
  1394. {
  1395. $this->UIContext = $function['ui_context'];
  1396. }
  1397. if ( isset( $function['ui_component'] ) )
  1398. {
  1399. $this->UIComponent = $function['ui_component'];

Large files files are truncated, but you can click here to view the full file