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
  7. @copyright    2005-2013 laurent Jouanneau
  8. @copyright    2007 Thibault Piront
  9. @copyright    2008 Julien Issler
  10. @copyright    2008-2010 Dominique Papin
  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 current module name
  52.      * @var string 
  53.      */
  54.     public $moduleName;
  55.  
  56.     /**
  57.      * the current action name
  58.      * @var string 
  59.      */
  60.     public $actionName;
  61.  
  62.     /**
  63.      * List of all errors appears during the initialisation
  64.      * @var array array of jLogErrorMessage
  65.      */
  66.     protected $initErrorMessages=array();
  67.  
  68.     /**
  69.      * the current error message
  70.      * @var jLogErrorMessage 
  71.      */
  72.     protected $errorMessage = null;
  73.  
  74.     /**
  75.      * @param  string|object $config filename of the ini file to configure the framework, or the config object itself
  76.      * @param  boolean $enableErrorHandler enable the error handler of jelix.
  77.      *                  keep it to true, unless you have something to debug
  78.      *                  and really have to use the default handler or an other handler
  79.      */
  80.     function __construct ($config$enableErrorHandler=true{
  81.         global $gJCoord$gJConfig;
  82.  
  83.         // temporary init. Remove this line when JELIX_APP_* support will be removed completely from Jelix
  84.         jApp::initLegacy();
  85.  
  86.         $gJCoord =  $this;
  87.  
  88.         if ($enableErrorHandler{
  89.             set_error_handler('jErrorHandler');
  90.             set_exception_handler('JExceptionHandler');
  91.         }
  92.  
  93.         // load configuration data
  94.         if (is_string($config))
  95.             $gJConfig jConfig::load($config);
  96.         else
  97.             $gJConfig $config;
  98.  
  99.         date_default_timezone_set($gJConfig->timeZone);
  100.  
  101.         $this->_loadPlugins();
  102.     }
  103.  
  104.     /**
  105.      * load the plugins and their configuration file
  106.      */
  107.     private function _loadPlugins(){
  108.         global $gJConfig;
  109.  
  110.         foreach ($gJConfig->coordplugins as $name=>$conf{
  111.             // the config compiler has removed all deactivated plugins
  112.             // so we don't have to check if the value $conf is empty or not
  113.             if ($conf == '1'{
  114.                 $confname 'coordplugin_'.$name;
  115.                 if (isset($gJConfig->$confname))
  116.                     $conf $gJConfig->$confname;
  117.                 else
  118.                     $conf array();
  119.             }
  120.             else {
  121.                 $conff jApp::configPath($conf);
  122.                 if (false === ($conf parse_ini_file($conff,true)))
  123.                     throw new Exception("Error in the configuration file of plugin $name ($conff)!"13);
  124.             }
  125.             include$gJConfig->_pluginsPathList_coord[$name].$name.'.coord.php');
  126.             $class$name.'CoordPlugin';
  127.             $this->plugins[strtolower($name)new $class($conf);
  128.         }
  129.     }
  130.  
  131.     /**
  132.     * main method : launch the execution of the action.
  133.     *
  134.     * This method should be called in a entry point.
  135.     * @param  jRequest  $request the request object
  136.     */
  137.     public function process ($request){
  138.         global $gJConfig;
  139.  
  140.         $this->request = $request;
  141.  
  142.         // let's log messages appeared during init
  143.         foreach($this->initErrorMessages as $msg{
  144.             jLog::log($msg$msg->getCategory());
  145.         }
  146.  
  147.         $this->request->init();
  148.         jSession::start();
  149.  
  150.         list($this->moduleName$this->actionName$request->getModuleAction();
  151.  
  152.         jContext::push ($this->moduleName);
  153.         try{
  154.             $this->action = new jSelectorActFast($this->request->type$this->moduleName$this->actionName);
  155.  
  156.             if($gJConfig->modules[$this->moduleName.'.access'2){
  157.                 throw new jException('jelix~errors.module.untrusted',$this->moduleName);
  158.             }
  159.  
  160.             $ctrl $this->getController($this->action);
  161.         }catch(jException $e){
  162.             if ($gJConfig->urlengine['notfoundAct'==''{
  163.                 throw $e;
  164.             }
  165.             try {
  166.                 $this->action = new jSelectorAct($gJConfig->urlengine['notfoundAct']);
  167.                 $ctrl $this->getController($this->action);
  168.             }catch(jException $e2){
  169.                 throw $e;
  170.             }
  171.         }
  172.  
  173.         if (count($this->plugins)) {
  174.             $pluginparams array();
  175.             if(isset($ctrl->pluginParams['*'])){
  176.                 $pluginparams $ctrl->pluginParams['*'];
  177.             }
  178.  
  179.             if(isset($ctrl->pluginParams[$this->action->method])){
  180.                 $pluginparams array_merge($pluginparams$ctrl->pluginParams[$this->action->method]);
  181.             }
  182.  
  183.             foreach ($this->plugins as $name => $obj){
  184.                 $result $this->plugins[$name]->beforeAction ($pluginparams);
  185.                 if($result){
  186.                     $this->action = $result;
  187.                     jContext::pop();
  188.                     jContext::push($result->module);
  189.                     $this->moduleName = $result->module;
  190.                     $this->actionName = $result->resource;
  191.                     $ctrl $this->getController($this->action);
  192.                     break;
  193.                 }
  194.             }
  195.         }
  196.         $this->response = $ctrl->{$this->action->method}();
  197.         if($this->response == null){
  198.             throw new jException('jelix~errors.response.missing',$this->action->toString());
  199.         }
  200.  
  201.         foreach ($this->plugins as $name => $obj){
  202.             $this->plugins[$name]->beforeOutput ();
  203.         }
  204.  
  205.         $this->response->output();
  206.  
  207.         foreach ($this->plugins as $name => $obj){
  208.             $this->plugins[$name]->afterProcess ();
  209.         }
  210.  
  211.         jContext::pop();
  212.         jSession::end();
  213.     }
  214.  
  215.     /**
  216.      * get the controller corresponding to the selector
  217.      * @param jSelectorAct $selector 
  218.      */
  219.     private function getController($selector){
  220.  
  221.         $ctrlpath $selector->getPath();
  222.         if(!file_exists($ctrlpath)){
  223.             throw new jException('jelix~errors.ad.controller.file.unknown',array($this->actionName,$ctrlpath));
  224.         }
  225.         require_once($ctrlpath);
  226.         $class $selector->getClass();
  227.         if(!class_exists($class,false)){
  228.             throw new jException('jelix~errors.ad.controller.class.unknown',array($this->actionName,$class$ctrlpath));
  229.         }
  230.         $ctrl new $class($this->request);
  231.         if($ctrl instanceof jIRestController){
  232.             $method $selector->method strtolower($_SERVER['REQUEST_METHOD']);
  233.         }elseif(!method_exists($ctrl$selector->method)){
  234.             throw new jException('jelix~errors.ad.controller.method.unknown',array($this->actionName$selector->method$class$ctrlpath));
  235.         }
  236.         return $ctrl;
  237.     }
  238.  
  239.  
  240.     /**
  241.      * instancy a response object corresponding to the default response type
  242.      * of the current resquest.
  243.      * Deprecated. use $request->getResponse() instead.
  244.      * @param boolean $originalResponse TRUE to get the original, non overloaded response
  245.      * @deprecated since 1.3
  246.      */
  247.     public function initDefaultResponseOfRequest($originalResponse false){
  248.         try {
  249.             $this->request->getResponse(''$originalResponse);
  250.         }
  251.         catch (Exception $e{
  252.             if (!$originalResponse)
  253.                 $this->initDefaultResponseOfRequest(true);
  254.             else
  255.                 throw $e;
  256.         }
  257.     }
  258.  
  259.     /**
  260.      * Handle an error event. Called by error handler and exception handler.
  261.      * @param string  $type    error type : 'error', 'warning', 'notice'
  262.      * @param integer $code    error code
  263.      * @param string  $message error message
  264.      * @param string  $file    the file name where the error appear
  265.      * @param integer $line    the line number where the error appear
  266.      * @param array   $trace   the stack trace
  267.      * @since 1.1
  268.      */
  269.     public function handleError($type$code$message$file$line$trace){
  270.         global $gJConfig;
  271.  
  272.         $errorLog new jLogErrorMessage($type$code$message$file$line$trace);
  273.  
  274.         if ($this->request{
  275.             // we have config, so we can process "normally"
  276.             $errorLog->setFormat($gJConfig->error_handling['messageLogFormat']);
  277.             jLog::log($errorLog$type);
  278.  
  279.             // if non fatal error, it is finished
  280.             if ($type != 'error')
  281.                 return;
  282.  
  283.             $this->errorMessage = $errorLog;
  284.  
  285.             while (ob_get_level(&& @ob_end_clean());
  286.  
  287.             $resp $this->request->getErrorResponse($this->response);
  288.             $resp->outputErrors();
  289.             jSession::end();
  290.         }
  291.         // for non fatal error appeared during init, let's just store it for loggers later
  292.         elseif ($type != 'error'{
  293.             $this->initErrorMessages[$errorLog;
  294.             return;
  295.         }
  296.         else {
  297.             // fatal error appeared during init, let's display an HTML page
  298.             // since we don't know the request, we cannot return a response
  299.             // corresponding to the expected protocol
  300.  
  301.             while (ob_get_level(&& @ob_end_clean());
  302.  
  303.             // log into file
  304.             @error_log($errorLog->getFormatedMessage()."\n",3jApp::logPath('errors.log'));
  305.             // if accept text/html
  306.             if (isset($_SERVER['HTTP_ACCEPT']&& strstr($_SERVER['HTTP_ACCEPT'],'text/html')) {
  307.                 if (file_exists(jApp::appPath('responses/error.en_US.php')))
  308.                     $file jApp::appPath('responses/error.en_US.php');
  309.                 else
  310.                     $file JELIX_LIB_CORE_PATH.'response/error.en_US.php';
  311.                 $HEADBOTTOM '';
  312.                 $BODYTOP '';
  313.                 $BODYBOTTOM '';
  314.                 $basePath '';
  315.                 header("HTTP/1.1 500 Internal jelix error");
  316.                 header('Content-type: text/html');
  317.                 include($file);
  318.             }
  319.             else {
  320.                 // output text response
  321.                 header("HTTP/1.1 500 Internal jelix error");
  322.                 header('Content-type: text/plain');
  323.                 echo 'Error during initialization.';
  324.             }
  325.         }
  326.         exit(1);
  327.     }
  328.  
  329.     /**
  330.      * return the generic error message (errorMessage in the configuration).
  331.      * Replaced the %code% pattern in the message by the current error code
  332.      * @return string 
  333.      */
  334.     public function getGenericErrorMessage({
  335.         $msg $GLOBALS['gJConfig']->error_handling['errorMessage'];
  336.         if ($this->errorMessage)
  337.             $code $this->errorMessage->getCode();
  338.         else $code '';
  339.         return str_replace('%code%'$code$msg);
  340.     }
  341.  
  342.     /**
  343.      * @return jLogErrorMessage  the current error
  344.      * @since 1.3a1
  345.      */
  346.     public function getErrorMessage({
  347.         return $this->errorMessage;
  348.     }
  349.  
  350.     /**
  351.     * gets a given coordinator plugin if registered
  352.     * @param string   $pluginName   the name of the plugin
  353.     * @param boolean  $required  says if the plugin is required or not. If true, will generate an exception if the plugin is not registered.
  354.     * @return jICoordPlugin 
  355.     */
  356.     public function getPlugin ($pluginName$required true){
  357.         $pluginName strtolower ($pluginName);
  358.         if (isset ($this->plugins[$pluginName])){
  359.             $plugin $this->plugins[$pluginName];
  360.         }else{
  361.             if ($required){
  362.                 throw new jException('jelix~errors.plugin.unregister'$pluginName);
  363.             }
  364.             $plugin null;
  365.         }
  366.         return $plugin;
  367.     }
  368.  
  369.     /**
  370.     * Says if the given coordinator plugin $name is enabled
  371.     * @param string $pluginName 
  372.     * @return boolean true : plugin is ok
  373.     */
  374.     public function isPluginEnabled ($pluginName){
  375.         return isset ($this->plugins[strtolower ($pluginName)]);
  376.     }
  377.  
  378.     /**
  379.     * Says if the given module $name is enabled
  380.     * @param string $moduleName 
  381.     * @param boolean $includingExternal  true if we want to know if the module
  382.     *                is also an external module, e.g. in an other entry point
  383.     * @return boolean true : module is ok
  384.     */
  385.     public function isModuleEnabled ($moduleName$includingExternal false{
  386.         if ($includingExternal && isset($GLOBALS['gJConfig']->_externalModulesPathList[$moduleName])) {
  387.             return true;
  388.         }
  389.         return isset($GLOBALS['gJConfig']->_modulesPathList[$moduleName]);
  390.     }
  391.  
  392.     /**
  393.      * return the real path of a module
  394.      * @param string $module a module name
  395.      * @param boolean $includingExternal  true if we want to know if the module
  396.      *                is also an external module, e.g. in an other entry point
  397.      * @return string the corresponding path
  398.      */
  399.     public function getModulePath($module$includingExternal false){
  400.         global $gJConfig;
  401.         if (!isset($gJConfig->_modulesPathList[$module])) {
  402.             if ($includingExternal && isset($gJConfig->_externalModulesPathList[$module])) {
  403.                 return $gJConfig->_externalModulesPathList[$module];
  404.             }
  405.             throw new Exception('getModulePath : invalid module name');
  406.         }
  407.         return $gJConfig->_modulesPathList[$module];
  408.     }
  409. }

Documentation generated on Wed, 24 Sep 2014 21:57:05 +0200 by phpDocumentor 1.4.3