Source for file jConfigCompiler.class.php

Documentation is available at jConfigCompiler.class.php

  1. <?php
  2. /**
  3. @package      jelix
  4. @subpackage   core
  5. @author       Laurent Jouanneau
  6. @contributor  Thibault Piront (nuKs), Christophe Thiriot, Philippe Schelté
  7. @copyright    2006-2012 Laurent Jouanneau
  8. @copyright    2007 Thibault Piront, 2008 Christophe Thiriot, 2008 Philippe Schelté
  9. @link         http://www.jelix.org
  10. @licence      GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html
  11. */
  12.  
  13. /**
  14.  * jConfigCompiler merge two ini file in a single array and store it in a temporary file
  15.  * This is a static class
  16.  * @package  jelix
  17.  * @subpackage core
  18.  * @static
  19.  */
  20. class jConfigCompiler {
  21.  
  22.     static protected $commonConfig;
  23.  
  24.     private function __construct ()}
  25.  
  26.     /**
  27.      * read the given ini file, for the current entry point, or for the entrypoint given
  28.      * in $pseudoScriptName. Merge it with the content of defaultconfig.ini.php
  29.      * It also calculates some options.
  30.      * If you are in a CLI script but you want to load a configuration file for a web entry point
  31.      * or vice-versa, you need to indicate the $pseudoScriptName parameter with the name of the entry point
  32.      * @param string $configFile the config file name
  33.      * @param boolean $allModuleInfo may be true for the installer, which needs all informations
  34.      *                                else should be false, these extra informations are
  35.      *                                not needed to run the application
  36.      * @param boolean $isCli  indicate if the configuration to read is for a CLI script or no
  37.      * @param string $pseudoScriptName the name of the entry point, relative to the base path,
  38.      *               corresponding to the readed configuration
  39.      * @return object an object which contains configuration values
  40.      */
  41.     static public function read($configFile$allModuleInfo false$isCli false$pseudoScriptName=''){
  42.  
  43.         $tempPath jApp::tempBasePath();
  44.         $configPath jApp::configPath();
  45.  
  46.         if($tempPath=='/'){
  47.             // if it equals to '/', this is because realpath has returned false in the application.init.php
  48.             // so this is because the path doesn't exist.
  49.             throw new Exception('Application temp directory doesn\'t exist !'3);
  50.         }
  51.  
  52.         if(!is_writable($tempPath)){
  53.             throw new Exception('Application temp base directory is not writable -- ('.$tempPath.')'4);
  54.         }
  55.  
  56.         if(!is_writable(jApp::logPath())) {
  57.             throw new Exception('Application log directory is not writable -- ('.jApp::logPath().')'4);
  58.         }
  59.  
  60.         $config jelix_read_ini(JELIX_LIB_CORE_PATH.'defaultconfig.ini.php');
  61.         self::$commonConfig clone $config;
  62.  
  63.         @jelix_read_ini($configPath.'defaultconfig.ini.php'$config);
  64.  
  65.         if($configFile != 'defaultconfig.ini.php'){
  66.             if(!file_exists($configPath.$configFile))
  67.                 throw new Exception("Configuration file is missing -- $configFile"5);
  68.             iffalse === @jelix_read_ini($configPath.$configFile$config))
  69.                 throw new Exception("Syntax error in the configuration file -- $configFile"6);
  70.         }
  71.  
  72.         self::prepareConfig($config$allModuleInfo$isCli$pseudoScriptName);
  73.         self::$commonConfig null;
  74.         return $config;
  75.     }
  76.  
  77.     /**
  78.      * Identical to read(), but also stores the result in a temporary file
  79.      * @param string $configFile the config file name
  80.      * @param boolean $isCli 
  81.      * @param string $pseudoScriptName 
  82.      * @return object an object which contains configuration values
  83.      */
  84.     static public function readAndCache($configFile$isCli null$pseudoScriptName ''{
  85.  
  86.         if ($isCli === null)
  87.             $isCli jServer::isCLI();
  88.  
  89.         $config self::read($configFilefalse$isCli$pseudoScriptName);
  90.         $tempPath jApp::tempPath();
  91.         jFile::createDir($tempPath);
  92.         $filename $tempPath.str_replace('/','~',$configFile);
  93.  
  94.         if(BYTECODE_CACHE_EXISTS){
  95.             $filename .= '.conf.php';
  96.             if ($f @fopen($filename'wb')) {
  97.                 fwrite($f'<?php $config = '.var_export(get_object_vars($config),true).";\n?>");
  98.                 fclose($f);
  99.             else {
  100.                 throw new Exception('Error while writing configuration cache file -- '.$filename);
  101.             }
  102.         }else{
  103.             jIniFile::write(get_object_vars($config)$filename.'.resultini.php'";<?php die('');?>\n");
  104.         }
  105.         return $config;
  106.     }
  107.  
  108.     /**
  109.      * fill some config properties with calculated values
  110.      * @param object $config  the config object
  111.      * @param boolean $allModuleInfo may be true for the installer, which needs all informations
  112.      *                                else should be false, these extra informations are
  113.      *                                not needed to run the application
  114.      * @param boolean $isCli  indicate if the configuration to read is for a CLI script or no
  115.      * @param string $pseudoScriptName the name of the entry point, relative to the base path,
  116.      *               corresponding to the readed configuration
  117.      */
  118.     static protected function prepareConfig($config$allModuleInfo$isCli$pseudoScriptName){
  119.  
  120.         self::checkMiscParameters($config);
  121.         self::getPaths($config->urlengine$pseudoScriptName$isCli);
  122.         self::_loadModuleInfo($config$allModuleInfo);
  123.         self::_loadPluginsPathList($config);
  124.         self::checkCoordPluginsPath($config);
  125.         self::runConfigCompilerPlugins($config);
  126.     }
  127.  
  128.     static protected function checkMiscParameters($config{
  129.         $config->isWindows (DIRECTORY_SEPARATOR === '\\');
  130.         if(trim$config->startAction== ''{
  131.             $config->startAction ':';
  132.         }
  133.  
  134.         if ($config->domainName == "" && isset($_SERVER['SERVER_NAME']))
  135.             $config->domainName $_SERVER['SERVER_NAME'];
  136.  
  137.         $config->_allBasePath array();
  138.  
  139.         if ($config->urlengine['engine'== 'simple')
  140.             trigger_error("The 'simple' url engine is deprecated. use 'basic_significant' or 'significant' url engine"E_USER_NOTICE);
  141.     }
  142.  
  143.     static protected function checkCoordPluginsPath($config{
  144.         $coordplugins array();
  145.         foreach ($config->coordplugins as $name=>$conf{
  146.             if (strpos($name'.'!== false)  {
  147.                 $coordplugins[$name$conf;
  148.                 continue;
  149.             }
  150.             if (!isset($config->_pluginsPathList_coord[$name])) {
  151.                 throw new Exception("Error in the main configuration. A plugin doesn't exist -- The coord plugin $name is unknown."7);
  152.             }
  153.             if ($conf{
  154.                 if ($conf != '1' && !file_exists(jApp::configPath($conf))) {
  155.                     throw new Exception("Error in the main configuration. A plugin configuration file doesn't exist -- Configuration file for the coord plugin $name doesn't exist: '$conf'"8);
  156.                 }
  157.                 $coordplugins[$name$conf;
  158.             }
  159.         }
  160.         $config->coordplugins $coordplugins;
  161.     }
  162.  
  163.     static protected function runConfigCompilerPlugins($config{
  164.         if (!isset($config->_pluginsPathList_configcompiler)) {
  165.             return;
  166.         }
  167.  
  168.         // load plugins
  169.         $plugins array();
  170.         foreach($config->_pluginsPathList_configcompiler as $pluginName => $path{
  171.             $file $path.$pluginName.'.configcompiler.php';
  172.             if (!file_exists($file) ){
  173.                 continue;
  174.             }
  175.  
  176.             require_once($file);
  177.             $classname $pluginName.'ConfigCompilerPlugin';
  178.             $plugins[new $classname();
  179.         }
  180.         if (!count($plugins))
  181.             return;
  182.  
  183.         // sort plugins by priority
  184.         usort($pluginsfunction($a$b)return $a->getPriority($b->getPriority();});
  185.  
  186.         // run plugins
  187.         foreach($plugins as $plugin)
  188.             $plugin->atStart($config);
  189.  
  190.         foreach($config->_modulesPathList as $moduleName=>$modulePath{
  191.             $moduleXml simplexml_load_file($modulePath.'module.xml');
  192.             foreach($plugins as $plugin{
  193.                 $plugin->onModule($config$moduleName$modulePath$moduleXml);
  194.             }
  195.         }
  196.  
  197.         foreach($plugins as $plugin)
  198.             $plugin->atEnd($config);
  199.     }
  200.     
  201.     /**
  202.      * Analyse and check the "lib:" and "app:" path.
  203.      * @param object $config  the config object
  204.      * @param boolean $allModuleInfo may be true for the installer, which needs all informations
  205.      *                                else should be false, these extra informations are
  206.      *                                not needed to run the application
  207.      */
  208.     static protected function _loadModuleInfo($config$allModuleInfo{
  209.  
  210.         $installerFile jApp::configPath('installer.ini.php');
  211.  
  212.         if ($config->disableInstallers{
  213.             $installation array ();
  214.         }
  215.         else if (!file_exists($installerFile)) {
  216.             if ($allModuleInfo)
  217.                 $installation array ();
  218.             else
  219.                 throw new Exception("The application is not installed -- installer.ini.php doesn't exist!\n"9);
  220.         }
  221.         else
  222.             $installation parse_ini_file($installerFile,true);
  223.  
  224.         $section $config->urlengine['urlScriptId'];
  225.  
  226.         if (!isset($installation[$section]))
  227.             $installation[$sectionarray();
  228.  
  229.         $list preg_split('/ *, */',$config->modulesPath);
  230.         if (isset(self::$commonConfig->modulesPath))
  231.             $list array_merge($listpreg_split('/ *, */',self::$commonConfig->modulesPath));
  232.         array_unshift($listJELIX_LIB_PATH.'core-modules/');
  233.         $pathChecked array();
  234.  
  235.         foreach($list as $k=>$path){
  236.             if(trim($path== ''continue;
  237.             $p str_replace(array('lib:','app:')array(LIB_PATHjApp::appPath())$path);
  238.             if (!file_exists($p)) {
  239.                 throw new Exception('Error in the configuration file -- The path, '.$path.' given in the jelix config, doesn\'t exist'10);
  240.             }
  241.             if (substr($p,-1!='/')
  242.                 $p.='/';
  243.             if (in_array($p$pathChecked))
  244.                 continue;
  245.             $pathChecked[$p;
  246.  
  247.              // don't include the core-modules into the list of base path. this list is to verify
  248.              // if modules have been modified into repositories
  249.             if ($k!=&& $config->compilation['checkCacheFiletime'])
  250.                 $config->_allBasePath[]=$p;
  251.  
  252.             if ($handle opendir($p)) {
  253.                 while (false !== ($f readdir($handle))) {
  254.                     if ($f[0!= '.' && is_dir($p.$f)) {
  255.  
  256.                         if ($config->disableInstallers)
  257.                             $installation[$section][$f.'.installed'1;
  258.                         else if (!isset($installation[$section][$f.'.installed']))
  259.                             $installation[$section][$f.'.installed'0;
  260.  
  261.                         if ($f == 'jelix'{
  262.                             $config->modules['jelix.access'2// the jelix module should always be public
  263.                         }
  264.                         else {
  265.                             if ($config->enableAllModules{
  266.                                 if ($config->disableInstallers
  267.                                     || $installation[$section][$f.'.installed']
  268.                                     || $allModuleInfo)
  269.                                     $config->modules[$f.'.access'2;
  270.                                 else
  271.                                     $config->modules[$f.'.access'0;
  272.                             }
  273.                             else if (!isset($config->modules[$f.'.access'])) {
  274.                                 // no given access in defaultconfig and ep config
  275.                                 $config->modules[$f.'.access'0;
  276.                             }
  277.                             else if($config->modules[$f.'.access'== 0){
  278.                                 // we want to activate the module if it is not activated
  279.                                 // for the entry point, but is declared activated
  280.                                 // in the default config file. In this case, it means
  281.                                 // that it is activated for an other entry point,
  282.                                 // and then we want the possibility to retrieve its
  283.                                 // urls, at least
  284.                                 if (isset(self::$commonConfig->modules[$f.'.access'])
  285.                                     && self::$commonConfig->modules[$f.'.access'0)
  286.                                     $config->modules[$f.'.access'3;
  287.                             }
  288.                             else if (!$installation[$section][$f.'.installed']{
  289.                                 // module is not installed.
  290.                                 // outside installation mode, we force the access to 0
  291.                                 // so the module is unusable until it is installed
  292.                                 if (!$allModuleInfo)
  293.                                     $config->modules[$f.'.access'0;
  294.                             }
  295.                         }
  296.  
  297.                         if (!isset($installation[$section][$f.'.dbprofile']))
  298.                             $config->modules[$f.'.dbprofile''default';
  299.                         else
  300.                             $config->modules[$f.'.dbprofile'$installation[$section][$f.'.dbprofile'];
  301.  
  302.                         if ($allModuleInfo{
  303.                             if (!isset($installation[$section][$f.'.version']))
  304.                                 $installation[$section][$f.'.version''';
  305.  
  306.                             if (!isset($installation[$section][$f.'.dataversion']))
  307.                                 $installation[$section][$f.'.dataversion''';
  308.  
  309.                             if (!isset($installation['__modules_data'][$f.'.contexts']))
  310.                                 $installation['__modules_data'][$f.'.contexts''';
  311.  
  312.                             $config->modules[$f.'.version'$installation[$section][$f.'.version'];
  313.                             $config->modules[$f.'.dataversion'$installation[$section][$f.'.dataversion'];
  314.                             $config->modules[$f.'.installed'$installation[$section][$f.'.installed'];
  315.  
  316.                             $config->_allModulesPathList[$f]=$p.$f.'/';
  317.                         }
  318.  
  319.                         if ($config->modules[$f.'.access'== 3{
  320.                             $config->_externalModulesPathList[$f]=$p.$f.'/';
  321.                         }
  322.                         elseif ($config->modules[$f.'.access']{
  323.                             $config->_modulesPathList[$f]=$p.$f.'/';
  324.                             if (file_exists$p.$f.'/plugins')) {
  325.                                 $config->pluginsPath .= ',module:'.$f;
  326.                             }
  327.                         }
  328.                     }
  329.                 }
  330.                 closedir($handle);
  331.             }
  332.         }
  333.     }
  334.  
  335.     /**
  336.      * Analyse plugin paths
  337.      * @param object $config the config container
  338.      */
  339.     static protected function _loadPluginsPathList($config{
  340.         $list preg_split('/ *, */',$config->pluginsPath);
  341.         array_unshift($listJELIX_LIB_PATH.'plugins/');
  342.         foreach($list as $k=>$path){
  343.             if(trim($path== ''continue;
  344.             if (preg_match('@^module:([^/]+)(/.*)?$@'$path$m)) {
  345.                 $mod $m[1];
  346.                 if (isset($config->_modulesPathList[$mod])) {
  347.                     $p $config->_modulesPathList[$mod];
  348.                     if (isset($m[2]&& strlen($m[2]1)
  349.                         $p.=$m[2];
  350.                     else
  351.                         $p.= '/plugins/';
  352.                 }
  353.                 else {
  354.                     trigger_error('Error in main configuration on pluginsPath -- Path given in pluginsPath for the module '.$mod.' is ignored, since this module is unknown or deactivated'E_USER_NOTICE);
  355.                     continue;
  356.                 }
  357.             }
  358.             else {
  359.                 $p str_replace(array('lib:','app:')array(LIB_PATHjApp::appPath())$path);
  360.             }
  361.             if(!file_exists($p)){
  362.                 trigger_error('Error in main configuration on pluginsPath -- The path, '.$path.' given in the jelix config, doesn\'t exists !',E_USER_ERROR);
  363.                 exit;
  364.             }
  365.             if(substr($p,-1!='/')
  366.                 $p.='/';
  367.  
  368.             if ($handle opendir($p)) {
  369.                 while (false !== ($f readdir($handle))) {
  370.                     if ($f[0!= '.' && is_dir($p.$f)) {
  371.                         if($subdir opendir($p.$f)){
  372.                             if($k!=&& $config->compilation['checkCacheFiletime'])
  373.                                $config->_allBasePath[]=$p.$f.'/';
  374.                             while (false !== ($subf readdir($subdir))) {
  375.                                 if ($subf[0!= '.' && is_dir($p.$f.'/'.$subf)) {
  376.                                     if($f == 'tpl'){
  377.                                         $prop '_tplpluginsPathList_'.$subf;
  378.                                         $config->{$prop}[$p.$f.'/'.$subf.'/';
  379.                                     }else{
  380.                                         $prop '_pluginsPathList_'.$f;
  381.                                         $config->{$prop}[$subf$p.$f.'/'.$subf.'/';
  382.                                     }
  383.                                 }
  384.                             }
  385.                             closedir($subdir);
  386.                         }
  387.                     }
  388.                 }
  389.                 closedir($handle);
  390.             }
  391.         }
  392.     }
  393.  
  394.     /**
  395.      * calculate miscelaneous path, depending of the server configuration and other informations
  396.      * in the given array : script path, script name, documentRoot ..
  397.      * @param array $urlconf  urlengine configuration. scriptNameServerVariable, basePath,
  398.      *  jelixWWWPath and jqueryPath should be present
  399.      */
  400.     static public function getPaths(&$urlconf$pseudoScriptName =''$isCli false{
  401.         // retrieve the script path+name.
  402.         // for cli, it will be the path from the directory were we execute the script (given to the php exec).
  403.         // for web, it is the path from the root of the url
  404.  
  405.         if ($pseudoScriptName{
  406.             $urlconf['urlScript'$pseudoScriptName;
  407.         }
  408.         else {
  409.             if($urlconf['scriptNameServerVariable'== ''{
  410.                 $urlconf['scriptNameServerVariable'self::findServerName('.php'$isCli);
  411.             }
  412.             $urlconf['urlScript'$_SERVER[$urlconf['scriptNameServerVariable']];
  413.         }
  414.  
  415.         // now we separate the path and the name of the script, and then the basePath
  416.         if ($isCli{
  417.             $lastslash strrpos ($urlconf['urlScript']DIRECTORY_SEPARATOR);
  418.             if ($lastslash === false{
  419.                 $urlconf['urlScriptPath'($pseudoScriptNamejApp::appPath('/scripts/')getcwd().'/');
  420.                 $urlconf['urlScriptName'$urlconf['urlScript'];
  421.             }
  422.             else {
  423.                 $urlconf['urlScriptPath'getcwd().'/'.substr ($urlconf['urlScript']0$lastslash ).'/';
  424.                 $urlconf['urlScriptName'substr ($urlconf['urlScript']$lastslash+1);
  425.             }
  426.             $basepath $urlconf['urlScriptPath'];
  427.             $snp $urlconf['urlScriptName'];
  428.             $urlconf['urlScript'$basepath.$snp;
  429.         }
  430.         else {
  431.             $lastslash strrpos ($urlconf['urlScript']'/');
  432.             $urlconf['urlScriptPath'substr ($urlconf['urlScript']0$lastslash ).'/';
  433.             $urlconf['urlScriptName'substr ($urlconf['urlScript']$lastslash+1);
  434.  
  435.             $basepath $urlconf['basePath'];
  436.             if ($basepath == ''{
  437.                 // for beginners or simple site, we "guess" the base path
  438.                 $basepath $localBasePath $urlconf['urlScriptPath'];
  439.             }
  440.             else {
  441.                 if ($basepath != '/'{
  442.                     if($basepath[0!= '/'$basepath='/'.$basepath;
  443.                     if(substr($basepath,-1!= '/'$basepath.='/';
  444.                 }
  445.  
  446.                 if ($pseudoScriptName{
  447.                     // with pseudoScriptName, we aren't in a true context, we could be in a cli context
  448.                     // (the installer), and we want the path like when we are in a web context.
  449.                     // $pseudoScriptName is supposed to be relative to the basePath
  450.                     $urlconf['urlScriptPath'substr($basepath,0,-1).$urlconf['urlScriptPath'];
  451.                     $urlconf['urlScript'$urlconf['urlScriptPath'].$urlconf['urlScriptName'];
  452.                 }
  453.                 $localBasePath $basepath;
  454.                 if ($urlconf['backendBasePath']{
  455.                     $localBasePath $urlconf['backendBasePath'];
  456.                     // we have to change urlScriptPath. it may contains the base path of the backend server
  457.                     // we should replace this base path by the basePath of the frontend server
  458.                     if (strpos($urlconf['urlScriptPath']$urlconf['backendBasePath']=== 0{
  459.                         $urlconf['urlScriptPath'$basepath.substr$urlconf['urlScriptPath']strlen($urlconf['backendBasePath']));
  460.                     }
  461.                     else  {
  462.                         $urlconf['urlScriptPath'$basepath.substr($urlconf['urlScriptPath']1);
  463.                     }
  464.  
  465.                 }elseif(strpos($urlconf['urlScriptPath']$basepath!== 0{
  466.                     throw new Exception('Error in main configuration on basePath -- basePath ('.$basepath.') in config file doesn\'t correspond to current base path. You should setup it to '.$urlconf['urlScriptPath']);
  467.                 }
  468.             }
  469.  
  470.             $urlconf['basePath'$basepath;
  471.  
  472.             if($urlconf['jelixWWWPath'][0!= '/')
  473.                 $urlconf['jelixWWWPath'$basepath.$urlconf['jelixWWWPath'];
  474.             if($urlconf['jqueryPath'][0!= '/')
  475.                 $urlconf['jqueryPath'$basepath.$urlconf['jqueryPath'];
  476.             $snp substr($urlconf['urlScript'],strlen($localBasePath));
  477.  
  478.             if ($localBasePath == '/')
  479.                 $urlconf['documentRoot'jApp::wwwPath();
  480.             else if(strpos(jApp::wwwPath()$localBasePath=== false{
  481.                 if (isset($_SERVER['DOCUMENT_ROOT']))
  482.                     $urlconf['documentRoot'$_SERVER['DOCUMENT_ROOT'];
  483.                 else
  484.                     $urlconf['documentRoot'jApp::wwwPath();
  485.             }
  486.             else
  487.                 $urlconf['documentRoot'substr(jApp::wwwPath()0(strlen($localBasePath)));
  488.         }
  489.  
  490.         $pos strrpos($snp'.php');
  491.         if($pos !== false){
  492.             $snp substr($snp,0,$pos);
  493.         }
  494.         $urlconf['urlScriptId'$snp;
  495.         $urlconf['urlScriptIdenc'rawurlencode($snp);
  496.     }
  497.  
  498.     static public function findServerName($ext '.php'$isCli false{
  499.         $varname '';
  500.         $extlen strlen($ext);
  501.  
  502.         if(strrpos($_SERVER['SCRIPT_NAME']$ext=== (strlen($_SERVER['SCRIPT_NAME']$extlen)
  503.            || $isCli{
  504.             return 'SCRIPT_NAME';
  505.         }else if (isset($_SERVER['REDIRECT_URL'])
  506.                   && strrpos$_SERVER['REDIRECT_URL']$ext=== (strlen$_SERVER['REDIRECT_URL']-$extlen)) {
  507.             return 'REDIRECT_URL';
  508.         }else if (isset($_SERVER['ORIG_SCRIPT_NAME'])
  509.                   && strrpos$_SERVER['ORIG_SCRIPT_NAME']$ext=== (strlen$_SERVER['ORIG_SCRIPT_NAME']$extlen)) {
  510.             return 'ORIG_SCRIPT_NAME';
  511.         }
  512.         throw new Exception('Error in main configuration on URL engine parameters -- In config file the parameter urlengine:scriptNameServerVariable is empty and Jelix doesn\'t find
  513.             the variable in $_SERVER which contains the script name. You must see phpinfo and setup this parameter in your config file.'11);
  514.     }
  515.  
  516.  
  517. }

Documentation generated on Wed, 04 Jan 2017 22:52:38 +0100 by phpDocumentor 1.4.3