Source for file jCoordinator.class.php

Documentation is available at jCoordinator.class.php

  1. <?php
  2. /**
  3. @package      jelix
  4. @subpackage   core
  5. @author       Laurent Jouanneau
  6. @contributor  Thibault Piront (nuKs), Julien Issler, Dominique Papin, Flav
  7. @copyright    2005-2015 laurent Jouanneau
  8. @copyright    2007 Thibault Piront
  9. @copyright    2008 Julien Issler
  10. @copyright    2008-2010 Dominique Papin, 2012 Flav
  11. @link         http://www.jelix.org
  12. @licence      GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html
  13. */
  14.  
  15. /**
  16.  * the main class of the jelix core
  17.  *
  18.  * this is the "chief orchestra" of the framework. Its goal is
  19.  * to load the configuration, to get the request parameters
  20.  * used to instancie the correspondant controllers and to run the right method.
  21.  * @package  jelix
  22.  * @subpackage core
  23.  */
  24. class jCoordinator {
  25.  
  26.     /**
  27.      * plugin list
  28.      * @var  array 
  29.      */
  30.     public $plugins = array();
  31.  
  32.     /**
  33.      * current response object
  34.      * @var jResponse 
  35.      */
  36.     public $response = null;
  37.  
  38.     /**
  39.      * current request object
  40.      * @var jRequest 
  41.      */
  42.     public $request = null;
  43.  
  44.     /**
  45.      * the selector of the current action
  46.      * @var jSelectorAct 
  47.      */
  48.     public $action = null;
  49.  
  50.     /**
  51.      * the original action when there is an internal redirection to an action
  52.      * different from the one corresponding to the request
  53.      * @var jSelectorAct 
  54.      */
  55.     public $originalAction = null;
  56.  
  57.     /**
  58.      * the current module name
  59.      * @var string 
  60.      */
  61.     public $moduleName;
  62.  
  63.     /**
  64.      * the current action name
  65.      * @var string 
  66.      */
  67.     public $actionName;
  68.  
  69.     /**
  70.      * the current error message
  71.      * @var jLogErrorMessage 
  72.      */
  73.     protected $errorMessage = null;
  74.  
  75.     /**
  76.      * @param  string|object $config filename of the ini file to configure the framework, or the config object itself
  77.      *               this parameter is optional if jApp::loadConfig has been already called
  78.      * @param  boolean $enableErrorHandler enable the error handler of jelix.
  79.      *                  keep it to true, unless you have something to debug
  80.      *                  and really have to use the default handler or an other handler
  81.      */
  82.     function __construct ($configFile=''$enableErrorHandler=true{
  83.  
  84.         if ($configFile)
  85.             jApp::loadConfig($configFile$enableErrorHandler);
  86.  
  87.         // temporary init. Remove this line when JELIX_APP_* and $gJConfig support will be removed completely from Jelix
  88.         jApp::initLegacy();
  89.  
  90.         $this->_loadPlugins();
  91.     }
  92.  
  93.     /**
  94.      * load the plugins and their configuration file
  95.      */
  96.     private function _loadPlugins(){
  97.  
  98.         $config jApp::config();
  99.         foreach ($config->coordplugins as $name=>$conf{
  100.             if (strpos($name'.'!== false)
  101.                 continue;
  102.             // the config compiler has removed all deactivated plugins
  103.             // so we don't have to check if the value $conf is empty or not
  104.             if ($conf == '1'{
  105.                 $confname 'coordplugin_'.$name;
  106.                 if (isset($config->$confname))
  107.                     $conf $config->$confname;
  108.                 else
  109.                     $conf array();
  110.             }
  111.             else {
  112.                 $conff jApp::configPath($conf);
  113.                 if (false === ($conf parse_ini_file($conff,true)))
  114.                     throw new Exception("Error in a plugin configuration file -- plugin: $name  file: $conff"13);
  115.             }
  116.             include_once($config->_pluginsPathList_coord[$name].$name.'.coord.php');
  117.             $class$name.'CoordPlugin';
  118.             if (isset($config->coordplugins[$name.'.name']))
  119.                 $name $config->coordplugins[$name.'.name'];
  120.             $this->plugins[strtolower($name)new $class($conf);
  121.         }
  122.     }
  123.  
  124.     /**
  125.     * main method : launch the execution of the action.
  126.     *
  127.     * This method should be called in a entry point.
  128.     * @param  jRequest  $request the request object
  129.     */
  130.     public function process ($request){
  131.  
  132.         $config jApp::config();
  133.         $this->request = $request;
  134.  
  135.         if ($config->enableErrorHandler{
  136.             set_error_handler(array($this'errorHandler'));
  137.             set_exception_handler(array($this'exceptionHandler'));
  138.  
  139.             // let's log messages appeared during init
  140.             foreach(jBasicErrorHandler::$initErrorMessages as $msg{
  141.                 jLog::log($msg$msg->getCategory());
  142.             }
  143.         }
  144.  
  145.         $this->request->init();
  146.         jSession::start();
  147.  
  148.         list($this->moduleName$this->actionName$request->getModuleAction();
  149.  
  150.         jContext::push ($this->moduleName);
  151.         try{
  152.             $this->action = new jSelectorActFast($this->request->type$this->moduleName$this->actionName);
  153.             $this->originalAction = $this->action;
  154.  
  155.             if($config->modules[$this->moduleName.'.access'2){
  156.                 throw new jException('jelix~errors.module.untrusted',$this->moduleName);
  157.             }
  158.  
  159.             $ctrl $this->getController($this->action);
  160.         }catch(jException $e){
  161.             if ($config->urlengine['notfoundAct'==''{
  162.                 throw $e;
  163.             }
  164.             try {
  165.                 $this->action = new jSelectorAct($config->urlengine['notfoundAct']);
  166.                 $ctrl $this->getController($this->action);
  167.             }catch(jException $e2){
  168.                 throw $e;
  169.             }
  170.         }
  171.  
  172.         if (count($this->plugins)) {
  173.             $pluginparams array();
  174.             if(isset($ctrl->pluginParams['*'])){
  175.                 $pluginparams $ctrl->pluginParams['*'];
  176.             }
  177.  
  178.             if(isset($ctrl->pluginParams[$this->action->method])){
  179.                 $pluginparams array_merge($pluginparams$ctrl->pluginParams[$this->action->method]);
  180.             }
  181.  
  182.             foreach ($this->plugins as $name => $obj){
  183.                 $result $this->plugins[$name]->beforeAction ($pluginparams);
  184.                 if($result){
  185.                     $this->action = $result;
  186.                     jContext::pop();
  187.                     jContext::push($result->module);
  188.                     $this->moduleName = $result->module;
  189.                     $this->actionName = $result->resource;
  190.                     $ctrl $this->getController($this->action);
  191.                     break;
  192.                 }
  193.             }
  194.         }
  195.         $this->response = $ctrl->{$this->action->method}();
  196.         if($this->response == null){
  197.             throw new jException('jelix~errors.response.missing',$this->action->toString());
  198.         }
  199.  
  200.         foreach ($this->plugins as $name => $obj){
  201.             $this->plugins[$name]->beforeOutput ();
  202.         }
  203.  
  204.         $this->response->output();
  205.  
  206.         foreach ($this->plugins as $name => $obj){
  207.             $this->plugins[$name]->afterProcess ();
  208.         }
  209.  
  210.         jContext::pop();
  211.         jSession::end();
  212.     }
  213.  
  214.     /**
  215.      * get the controller corresponding to the selector
  216.      * @param jSelectorAct $selector 
  217.      */
  218.     protected function getController($selector){
  219.  
  220.         $ctrlpath $selector->getPath();
  221.         if(!file_exists($ctrlpath)){
  222.             throw new jException('jelix~errors.ad.controller.file.unknown',array($this->actionName,$ctrlpath));
  223.         }
  224.         require_once($ctrlpath);
  225.         $class $selector->getClass();
  226.         if(!class_exists($class,false)){
  227.             throw new jException('jelix~errors.ad.controller.class.unknown',array($this->actionName,$class$ctrlpath));
  228.         }
  229.         $ctrl new $class($this->request);
  230.         if($ctrl instanceof jIRestController){
  231.             $method $selector->method strtolower($_SERVER['REQUEST_METHOD']);
  232.         }elseif(!is_callable(array($ctrl$selector->method))){
  233.             throw new jException('jelix~errors.ad.controller.method.unknown',array($this->actionName$selector->method$class$ctrlpath));
  234.         }
  235.         return $ctrl;
  236.     }
  237.  
  238.  
  239.     /**
  240.      * instancy a response object corresponding to the default response type
  241.      * of the current resquest.
  242.      * Deprecated. use $request->getResponse() instead.
  243.      * @param boolean $originalResponse TRUE to get the original, non overloaded response
  244.      * @deprecated since 1.3
  245.      */
  246.     public function initDefaultResponseOfRequest($originalResponse false){
  247.         try {
  248.             $this->request->getResponse(''$originalResponse);
  249.         }
  250.         catch (Exception $e{
  251.             if (!$originalResponse)
  252.                 $this->initDefaultResponseOfRequest(true);
  253.             else
  254.                 throw $e;
  255.         }
  256.     }
  257.  
  258.     /**
  259.      * says if the currently executed action is the original one
  260.      * @return boolean  true if yes
  261.      */
  262.     public function execOriginalAction({
  263.         if (!$this->originalAction{
  264.             return false;
  265.         }
  266.         return $this->originalAction->isEqualTo($this->action);
  267.     }
  268.  
  269.     /**
  270.      * Error handler using a response object to return the error.
  271.      * Replace the default PHP error handler.
  272.      * @param   integer     $errno      error code
  273.      * @param   string      $errmsg     error message
  274.      * @param   string      $filename   filename where the error appears
  275.      * @param   integer     $linenum    line number where the error appears
  276.      * @param   array       $errcontext 
  277.      * @since 1.4
  278.      */
  279.     function errorHandler($errno$errmsg$filename$linenum$errcontext{
  280.  
  281.         if (error_reporting(== 0)
  282.             return;
  283.  
  284.         if (preg_match('/^\s*\((\d+)\)(.+)$/'$errmsg$m)) {
  285.             $code $m[1];
  286.             $errmsg $m[2];
  287.         }
  288.         else {
  289.             $code 1;
  290.         }
  291.  
  292.         if (!isset (jBasicErrorHandler::$errorCode[$errno])){
  293.             $errno E_ERROR;
  294.         }
  295.         $codestr jBasicErrorHandler::$errorCode[$errno];
  296.  
  297.         $trace debug_backtrace();
  298.         array_shift($trace);
  299.         $this->handleError($codestr$errno$errmsg$filename$linenum$trace);
  300.     }
  301.  
  302.     /**
  303.      * Exception handler using a response object to return the error
  304.      * Replace the default PHP Exception handler
  305.      * @param   Exception   $e  the exception object
  306.      * @since 1.4
  307.      */
  308.     function exceptionHandler($e{
  309.         $this->handleError('error'$e->getCode()$e->getMessage()$e->getFile(),
  310.                           $e->getLine()$e->getTrace());
  311.     }
  312.  
  313.     /**
  314.      * Handle an error event. Called by error handler and exception handler.
  315.      * @param string  $type    error type : 'error', 'warning', 'notice'
  316.      * @param integer $code    error code
  317.      * @param string  $message error message
  318.      * @param string  $file    the file name where the error appear
  319.      * @param integer $line    the line number where the error appear
  320.      * @param array   $trace   the stack trace
  321.      * @since 1.1
  322.      */
  323.     public function handleError($type$code$message$file$line$trace){
  324.  
  325.         $errorLog new jLogErrorMessage($type$code$message$file$line$trace);
  326.  
  327.         $errorLog->setFormat(jApp::config()->error_handling['messageLogFormat']);
  328.         jLog::log($errorLog$type);
  329.  
  330.         // if non fatal error, it is finished, continue the execution of the action
  331.         if ($type != 'error')
  332.             return;
  333.  
  334.         $this->errorMessage = $errorLog;
  335.  
  336.         while (ob_get_level(&& @ob_end_clean());
  337.  
  338.         $resp $this->request->getErrorResponse($this->response);
  339.         $resp->outputErrors();
  340.         jSession::end();
  341.  
  342.         exit(1);
  343.     }
  344.  
  345.     /**
  346.      * return the generic error message (errorMessage in the configuration).
  347.      * Replaced the %code% pattern in the message by the current error code
  348.      * @return string 
  349.      */
  350.     public function getGenericErrorMessage({
  351.         $msg jApp::config()->error_handling['errorMessage'];
  352.         if ($this->errorMessage)
  353.             $code $this->errorMessage->getCode();
  354.         else $code '';
  355.         return str_replace('%code%'$code$msg);
  356.     }
  357.  
  358.     /**
  359.      * @return jLogErrorMessage  the current error
  360.      * @since 1.3a1
  361.      */
  362.     public function getErrorMessage({
  363.         return $this->errorMessage;
  364.     }
  365.  
  366.     /**
  367.     * gets a given coordinator plugin if registered
  368.     * @param string   $pluginName   the name of the plugin
  369.     * @param boolean  $required  says if the plugin is required or not. If true, will generate an exception if the plugin is not registered.
  370.     * @return jICoordPlugin 
  371.     */
  372.     public function getPlugin ($pluginName$required true){
  373.         $pluginName strtolower ($pluginName);
  374.         if (isset ($this->plugins[$pluginName])){
  375.             $plugin $this->plugins[$pluginName];
  376.         }else{
  377.             if ($required){
  378.                 throw new jException('jelix~errors.plugin.unregister'$pluginName);
  379.             }
  380.             $plugin null;
  381.         }
  382.         return $plugin;
  383.     }
  384.  
  385.     /**
  386.     * Says if the given coordinator plugin $name is enabled
  387.     * @param string $pluginName 
  388.     * @return boolean true : plugin is ok
  389.     */
  390.     public function isPluginEnabled ($pluginName){
  391.         return isset ($this->plugins[strtolower ($pluginName)]);
  392.     }
  393.  
  394.     /**
  395.     * deprecated.  use jApp::isModuleEnabled() instead
  396.     * @deprecated
  397.     */
  398.     public function isModuleEnabled ($moduleName$includingExternal false{
  399.         trigger_error("jCoordinator::isModuleEnabled() is deprecated. Use jApp::isModuleEnabled() instead"E_USER_NOTICE);
  400.         return jApp::isModuleEnabled($moduleName$includingExternal);
  401.     }
  402.  
  403.     /**
  404.     * deprecated.  use jApp::getModulePath() instead
  405.     * @deprecated
  406.      */
  407.     public function getModulePath($module$includingExternal false){
  408.         trigger_error("jCoordinator::getModulePath() is deprecated. Use jApp::getModulePath() instead"E_USER_NOTICE);
  409.         return jApp::getModulePath($module$includingExternal);
  410.     }
  411. }

Documentation generated on Mon, 26 Oct 2015 21:52:25 +0100 by phpDocumentor 1.4.3