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

Documentation generated on Mon, 19 Sep 2011 14:12:08 +0200 by phpDocumentor 1.4.3