class.t3lib_loadmodules.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2008 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00027 /**
00028  * This document provides a class that loads the modules for the TYPO3 interface.
00029  *
00030  * $Id: class.t3lib_loadmodules.php 4432 2008-11-07 03:52:22Z flyguide $
00031  * Modifications by Rene Fritz, 2001
00032  * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
00033  *
00034  * @author  Kasper Skaarhoj <kasperYYYY@typo3.com>
00035  * @internal
00036  */
00037 /**
00038  * [CLASS/FUNCTION INDEX of SCRIPT]
00039  *
00040  *
00041  *
00042  *   79: class t3lib_loadModules
00043  *   99:     function load($modulesArray,$BE_USER='')
00044  *  370:     function checkExtensionModule($name)
00045  *  389:     function checkMod($name, $fullpath)
00046  *  471:     function checkModAccess($name,$MCONF)
00047  *  495:     function checkModWorkspace($name,$MCONF)
00048  *  519:     function parseModulesArray($arr)
00049  *  548:     function cleanName ($str)
00050  *  559:     function getRelativePath($baseDir,$destDir)
00051  *
00052  * TOTAL FUNCTIONS: 8
00053  * (This index is automatically created/updated by the extension "extdeveval")
00054  *
00055  */
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 /**
00069  * Load Backend Interface modules
00070  *
00071  * Typically instantiated like this:
00072  *      $this->loadModules = t3lib_div::makeInstance('t3lib_loadModules');
00073  *      $this->loadModules->load($TBE_MODULES);
00074  *
00075  * @author  Kasper Skaarhoj <kasperYYYY@typo3.com>
00076  * @package TYPO3
00077  * @subpackage t3lib
00078  */
00079 class t3lib_loadModules {
00080     var $modules = Array();     // After the init() function this array will contain the structure of available modules for the backend user.
00081     var $absPathArray = array();    // Array with paths pointing to the location of modules from extensions
00082 
00083     var $modListGroup = Array();        // this array will hold the elements that should go into the select-list of modules for groups...
00084     var $modListUser = Array();     // this array will hold the elements that should go into the select-list of modules for users...
00085 
00086     /**
00087      * The backend user for use internally
00088      *
00089      * @var t3lib_beUserAuth
00090      */
00091     var $BE_USER = '';
00092     var $observeWorkspaces = FALSE;     // If set true, workspace "permissions" will be observed so non-allowed modules will not be included in the array of modules.
00093 
00094 
00095     /**
00096      * Init.
00097      * The outcome of the load() function will be a $this->modules array populated with the backend module structure available to the BE_USER
00098      * Further the global var $LANG will have labels and images for the modules loaded in an internal array.
00099      *
00100      * @param   array       $modulesArray should be the global var $TBE_MODULES, $BE_USER can optionally be set to an alternative Backend user object than the global var $BE_USER (which is the currently logged in user)
00101      * @param   object      Optional backend user object to use. If not set, the global BE_USER object is used.
00102      * @return  void
00103      */
00104     function load($modulesArray,$BE_USER='')    {
00105             // Setting the backend user for use internally
00106         if (is_object($BE_USER))    {
00107             $this->BE_USER = $BE_USER;
00108         } else {
00109             $this->BE_USER = $GLOBALS['BE_USER'];
00110         }
00111 
00112             /*
00113 
00114              $modulesArray might look like this when entering this function.
00115              Notice the two modules added by extensions - they have a path attached
00116 
00117             Array
00118             (
00119                 [web] => list,info,perm,func
00120                 [file] => list
00121                 [user] =>
00122                 [tools] => em,install,txphpmyadmin
00123                 [help] => about
00124                 [_PATHS] => Array
00125                     (
00126                         [tools_install] => /www/htdocs/typo3/32/coreinstall/typo3/ext/install/mod/
00127                         [tools_txphpmyadmin] => /www/htdocs/typo3/32/coreinstall/typo3/ext/phpmyadmin/modsub/
00128                     )
00129 
00130             )
00131 
00132              */
00133             //
00134         $this->absPathArray = $modulesArray['_PATHS'];
00135         unset($modulesArray['_PATHS']);
00136 
00137             /*
00138                 With the above data for modules the result of this function call will be:
00139 
00140                 Array
00141                 (
00142                     [web] => Array
00143                         (
00144                             [0] => list
00145                             [1] => info
00146                             [2] => perm
00147                             [3] => func
00148                         )
00149 
00150                     [file] => Array
00151                         (
00152                             [0] => list
00153                         )
00154 
00155                     [user] => 1
00156                     [tools] => Array
00157                         (
00158                             [0] => em
00159                             [1] => install
00160                             [2] => txphpmyadmin
00161                         )
00162 
00163                     [help] => Array
00164                         (
00165                             [0] => about
00166                         )
00167 
00168                 )
00169             */
00170         $theMods = $this->parseModulesArray($modulesArray);
00171 
00172             /*
00173                 Originally modules were found in typo3/mod/
00174                 User defined modules were found in ../typo3conf/
00175 
00176                 Today almost all modules reside in extensions and they are found by the _PATHS array of the incoming $TBE_MODULES array
00177             */
00178             // Setting paths for 1) core modules (old concept from mod/) and 2) user-defined modules (from ../typo3conf)
00179         $paths = array();
00180         $paths['defMods'] = PATH_typo3.'mod/';  // Path of static modules
00181         $paths['userMods'] = PATH_typo3.'../typo3conf/';  // local modules (maybe frontend specific)
00182 
00183             // Traverses the module setup and creates the internal array $this->modules
00184         foreach($theMods as $mods => $subMod)   {
00185             $path = NULL;
00186 
00187             $extModRelPath = $this->checkExtensionModule($mods);
00188             if ($extModRelPath) {   // EXTENSION module:
00189                 $theMainMod = $this->checkMod($mods,PATH_site.$extModRelPath);
00190                 if (is_array($theMainMod) || $theMainMod!='notFound')   {
00191                     $path = 1;  // ... just so it goes on... submodules cannot be within this path!
00192                 }
00193             } else {    // 'CLASSIC' module
00194                     // Checking for typo3/mod/ module existence...
00195                 $theMainMod = $this->checkMod($mods,$paths['defMods'].$mods);
00196                 if (is_array($theMainMod) || $theMainMod!='notFound')   {
00197                     $path = $paths['defMods'];
00198                 } else {
00199                         // If not typo3/mod/ then it could be user-defined in typo3conf/ ...?
00200                     $theMainMod = $this->checkMod($mods,$paths['userMods'].$mods);
00201                     if (is_array($theMainMod) || $theMainMod!='notFound')   {
00202                         $path = $paths['userMods'];
00203                     }
00204                 }
00205             }
00206 
00207                 // if $theMainMod is not set (false) there is no access to the module !(?)
00208             if ($theMainMod && !is_null($path)) {
00209                 $this->modules[$mods] = $theMainMod;
00210 
00211                     // SUBMODULES - if any - are loaded
00212                 if (is_array($subMod))  {
00213                     foreach($subMod as $valsub) {
00214                         $extModRelPath = $this->checkExtensionModule($mods.'_'.$valsub);
00215                         if ($extModRelPath) {   // EXTENSION submodule:
00216                             $theTempSubMod = $this->checkMod($mods.'_'.$valsub,PATH_site.$extModRelPath);
00217                             if (is_array($theTempSubMod))   {   // default sub-module in either main-module-path, be it the default or the userdefined.
00218                                 $this->modules[$mods]['sub'][$valsub] = $theTempSubMod;
00219                             }
00220                         } else {    // 'CLASSIC' submodule
00221                                 // Checking for typo3/mod/xxx/ module existence...
00222 // FIXME what about $path = 1; from above and using $path as string here?
00223                             $theTempSubMod = $this->checkMod($mods.'_'.$valsub,$path.$mods.'/'.$valsub);
00224                             if (is_array($theTempSubMod))   {   // default sub-module in either main-module-path, be it the default or the userdefined.
00225                                 $this->modules[$mods]['sub'][$valsub] = $theTempSubMod;
00226                             } elseif ($path == $paths['defMods'])   {       // If the submodule did not exist in the default module path, then check if there is a submodule in the submodule path!
00227                                 $theTempSubMod = $this->checkMod($mods.'_'.$valsub,$paths['userMods'].$mods.'/'.$valsub);
00228                                 if (is_array($theTempSubMod))   {
00229                                     $this->modules[$mods]['sub'][$valsub] = $theTempSubMod;
00230                                 }
00231                             }
00232                         }
00233                     }
00234                 }
00235             } else {    // This must be done in order to fill out the select-lists for modules correctly!!
00236                 if (is_array($subMod))  {
00237                     foreach($subMod as $valsub) {
00238 // FIXME path can only be NULL here, or not?
00239                         $this->checkMod($mods.'_'.$valsub,$path.$mods.'/'.$valsub);
00240                     }
00241                 }
00242             }
00243         }
00244     /*
00245         At this point $this->modules should look like this:
00246         Only modules which were accessible to the $BE_USER is listed in this array.
00247 
00248         Array
00249         (
00250             [web] => Array
00251                 (
00252                     [name] => web
00253                     [script] => dummy.php
00254                     [defaultMod] => list
00255                     [sub] => Array
00256                         (
00257                             [list] => Array
00258                                 (
00259                                     [name] => web_list
00260                                     [script] => mod/web/list/../../../db_list.php
00261                                 )
00262 
00263                             [info] => Array
00264                                 (
00265                                     [name] => web_info
00266                                     [script] => mod/web/info/index.php
00267                                 )
00268 
00269                             [perm] => Array
00270                                 (
00271                                     [name] => web_perm
00272                                     [script] => mod/web/perm/index.php
00273                                 )
00274 
00275                             [func] => Array
00276                                 (
00277                                     [name] => web_func
00278                                     [script] => mod/web/func/index.php
00279                                 )
00280 
00281                         )
00282 
00283                 )
00284 
00285             [file] => Array
00286                 (
00287                     [name] => file
00288                     [script] => dummy.php
00289                     [sub] => Array
00290                         (
00291                             [list] => Array
00292                                 (
00293                                     [name] => file_list
00294                                     [script] => mod/file/list/../../../file_list.php
00295                                 )
00296 
00297                         )
00298 
00299                 )
00300 
00301             [user] => Array
00302                 (
00303                     [name] => user
00304                     [script] => dummy.php
00305                     [defaultMod] => task
00306                 )
00307 
00308             [tools] => Array
00309                 (
00310                     [name] => tools
00311                     [script] => dummy.php
00312                     [sub] => Array
00313                         (
00314                             [em] => Array
00315                                 (
00316                                     [name] => tools_em
00317                                     [script] => mod/tools/em/index.php
00318                                 )
00319 
00320                             [install] => Array
00321                                 (
00322                                     [name] => tools_install
00323                                     [script] => ext/install/mod/../../../install/index.php
00324                                 )
00325 
00326                             [txphpmyadmin] => Array
00327                                 (
00328                                     [name] => tools_txphpmyadmin
00329                                     [script] => ext/phpmyadmin/modsub/index.php
00330                                 )
00331 
00332                         )
00333 
00334                 )
00335 
00336             [help] => Array
00337                 (
00338                     [name] => help
00339                     [script] => dummy.php
00340                     [defaultMod] => welcome
00341                     [sub] => Array
00342                         (
00343                             [about] => Array
00344                                 (
00345                                     [name] => help_about
00346                                     [script] => mod/help/about/index.php
00347                                 )
00348 
00349                         )
00350 
00351                 )
00352 
00353         )
00354 
00355     */
00356 
00357 #debug($this->modules);
00358 #debug($GLOBALS['LANG']->moduleLabels);
00359     }
00360 
00361     /**
00362      * If the module name ($name) is a module from an extension (has path in $this->absPathArray) then that path is returned relative to PATH_site
00363      *
00364      * @param   string      Module name
00365      * @return  string      If found, the relative path from PATH_site
00366      */
00367     function checkExtensionModule($name)    {
00368         global $TYPO3_LOADED_EXT;
00369 
00370         if (isset($this->absPathArray[$name]))  {
00371             return ereg_replace ('\/$', '', substr($this->absPathArray[$name],strlen(PATH_site)));
00372         }
00373     }
00374 
00375     /**
00376      * Here we check for the module.
00377      * Return values:
00378      *  'notFound': If the module was not found in the path (no "conf.php" file)
00379      *  false:      If no access to the module (access check failed)
00380      *  array():    Configuration array, in case a valid module where access IS granted exists.
00381      *
00382      * @param   string      Module name
00383      * @param   string      Absolute path to module
00384      * @return  mixed       See description of function
00385      */
00386     function checkMod($name, $fullpath) {
00387         $modconf=Array();
00388         $path = ereg_replace ('/[^/.]+/\.\./', '/', $fullpath); // because 'path/../path' does not work
00389         if (@is_dir($path) && file_exists($path.'/conf.php'))   {
00390             $MCONF = array();
00391             $MLANG = array();
00392             include($path.'/conf.php'); // The conf-file is included. This must be valid PHP.
00393             if (!$MCONF['shy'] && $this->checkModAccess($name,$MCONF) && $this->checkModWorkspace($name,$MCONF))    {
00394                 $modconf['name']=$name;
00395                     // language processing. This will add module labels and image reference to the internal ->moduleLabels array of the LANG object.
00396                 if (is_object($GLOBALS['LANG']))    {
00397                         // $MLANG['default']['tabs_images']['tab'] is for modules the reference to the module icon.
00398                         // Here the path is transformed to an absolute reference.
00399                     if ($MLANG['default']['tabs_images']['tab'])    {
00400 
00401                             // Initializing search for alternative icon:
00402                         $altIconKey = 'MOD:'.$name.'/'.$MLANG['default']['tabs_images']['tab'];     // Alternative icon key (might have an alternative set in $TBE_STYLES['skinImg']
00403                         $altIconAbsPath = is_array($GLOBALS['TBE_STYLES']['skinImg'][$altIconKey]) ? t3lib_div::resolveBackPath(PATH_typo3.$GLOBALS['TBE_STYLES']['skinImg'][$altIconKey][0]) : '';
00404 
00405                             // Setting icon, either default or alternative:
00406                         if ($altIconAbsPath && @is_file($altIconAbsPath))   {
00407                             $MLANG['default']['tabs_images']['tab']=$this->getRelativePath(PATH_typo3,$altIconAbsPath);
00408                         } else {
00409                                 // Setting default icon:
00410                             $MLANG['default']['tabs_images']['tab']=$this->getRelativePath(PATH_typo3,$fullpath.'/'.$MLANG['default']['tabs_images']['tab']);
00411                         }
00412 
00413                             // Finally, setting the icon with correct path:
00414                         if (substr($MLANG['default']['tabs_images']['tab'],0,3)=='../') {
00415                             $MLANG['default']['tabs_images']['tab'] = PATH_site.substr($MLANG['default']['tabs_images']['tab'],3);
00416                         } else {
00417                             $MLANG['default']['tabs_images']['tab'] = PATH_typo3.$MLANG['default']['tabs_images']['tab'];
00418                         }
00419                     }
00420 
00421                         // If LOCAL_LANG references are used for labels of the module:
00422                     if ($MLANG['default']['ll_ref'])    {
00423                             // Now the 'default' key is loaded with the CURRENT language - not the english translation...
00424                         $MLANG['default']['labels']['tablabel'] = $GLOBALS['LANG']->sL($MLANG['default']['ll_ref'].':mlang_labels_tablabel');
00425                         $MLANG['default']['labels']['tabdescr'] = $GLOBALS['LANG']->sL($MLANG['default']['ll_ref'].':mlang_labels_tabdescr');
00426                         $MLANG['default']['tabs']['tab'] = $GLOBALS['LANG']->sL($MLANG['default']['ll_ref'].':mlang_tabs_tab');
00427                         $GLOBALS['LANG']->addModuleLabels($MLANG['default'],$name.'_');
00428                     } else {    // ... otherwise use the old way:
00429                         $GLOBALS['LANG']->addModuleLabels($MLANG['default'],$name.'_');
00430                         $GLOBALS['LANG']->addModuleLabels($MLANG[$GLOBALS['LANG']->lang],$name.'_');
00431                     }
00432                 }
00433 
00434                     // Default script setup
00435                 if ($MCONF['script']==='_DISPATCH') {
00436                     $modconf['script'] = 'mod.php?M='.rawurlencode($name);
00437                 } elseif ($MCONF['script'] && file_exists($path.'/'.$MCONF['script']))  {
00438                     $modconf['script'] = $this->getRelativePath(PATH_typo3,$fullpath.'/'.$MCONF['script']);
00439                 } else {
00440                     $modconf['script'] = 'dummy.php';
00441                 }
00442                     // Default tab setting
00443                 if ($MCONF['defaultMod'])   {
00444                     $modconf['defaultMod'] = $MCONF['defaultMod'];
00445                 }
00446                     // Navigation Frame Script (GET params could be added)
00447                 if ($MCONF['navFrameScript']) {
00448                     $navFrameScript = explode('?', $MCONF['navFrameScript']);
00449                     $navFrameScript = $navFrameScript[0];
00450                     if (file_exists($path.'/'.$navFrameScript)) {
00451                         $modconf['navFrameScript'] = $this->getRelativePath(PATH_typo3,$fullpath.'/'.$MCONF['navFrameScript']);
00452                     }
00453                 }
00454                     // additional params for Navigation Frame Script: "&anyParam=value&moreParam=1"
00455                 if ($MCONF['navFrameScriptParam']) {
00456                     $modconf['navFrameScriptParam'] = $MCONF['navFrameScriptParam'];
00457                 }
00458             } else return false;
00459         } else $modconf = 'notFound';
00460         return $modconf;
00461     }
00462 
00463     /**
00464      * Returns true if the internal BE_USER has access to the module $name with $MCONF (based on security level set for that module)
00465      *
00466      * @param   string      Module name
00467      * @param   array       MCONF array (module configuration array) from the modules conf.php file (contains settings about what access level the module has)
00468      * @return  boolean     True if access is granted for $this->BE_USER
00469      */
00470     function checkModAccess($name,$MCONF)   {
00471         if ($MCONF['access'])   {
00472             $access=strtolower($MCONF['access']);
00473                 // Checking if admin-access is required
00474             if (strstr($access,'admin'))    {   // If admin-permissions is required then return true if user is admin
00475                 if ($this->BE_USER->isAdmin())  {return true;}
00476             }
00477                 // This will add modules to the select-lists of user and groups
00478             if (strstr($access,'user')) {   $this->modListUser[]=$name;     }
00479             if (strstr($access,'group'))    {   $this->modListGroup[]=$name;    }
00480                 // This checks if a user is permitted to access the module
00481             if ($this->BE_USER->isAdmin() || $this->BE_USER->check('modules',$name))    {return true;}  // If admin you can always access a module
00482 
00483         } else return true; // If conf[access] is not set, then permission IS granted!
00484     }
00485 
00486     /**
00487      * Check if a module is allowed inside the current workspace for be user
00488      * Processing happens only if $this->observeWorkspaces is TRUE
00489      *
00490      * @param   string      Module name
00491      * @param   array       MCONF array (module configuration array) from the modules conf.php file (contains settings about workspace restrictions)
00492      * @return  boolean     True if access is granted for $this->BE_USER
00493      */
00494     function checkModWorkspace($name,$MCONF)    {
00495         if ($this->observeWorkspaces)   {
00496             $status = TRUE;
00497             if ($MCONF['workspaces'])   {
00498                 $status = FALSE;
00499                 if (($this->BE_USER->workspace===0 && t3lib_div::inList($MCONF['workspaces'],'online')) ||
00500                     ($this->BE_USER->workspace===-1 && t3lib_div::inList($MCONF['workspaces'],'offline')) ||
00501                     ($this->BE_USER->workspace>0 && t3lib_div::inList($MCONF['workspaces'],'custom')))  {
00502                         $status = TRUE;
00503                 }
00504             } elseif ($this->BE_USER->workspace===-99)  {
00505                 $status = FALSE;
00506             }
00507             return $status;
00508         } else return TRUE;
00509     }
00510 
00511     /**
00512      * Parses the moduleArray ($TBE_MODULES) into a internally useful structure.
00513      * Returns an array where the keys are names of the module and the values may be true (only module) or an array (of submodules)
00514      *
00515      * @param   array       moduleArray ($TBE_MODULES)
00516      * @return  array       Output structure with available modules
00517      */
00518     function parseModulesArray($arr)    {
00519         $theMods = Array();
00520         if (is_array($arr)) {
00521             foreach($arr as $mod => $subs)  {
00522                 $mod = $this->cleanName($mod);      // clean module name to alphanum
00523                 if ($mod)   {
00524                     if ($subs)  {
00525                         $subsArr = t3lib_div::trimExplode(',', $subs);
00526                         foreach($subsArr as $subMod)    {
00527                             $subMod = $this->cleanName($subMod);
00528                             if ($subMod)    {
00529                                 $theMods[$mod][] = $subMod;
00530                             }
00531                         }
00532                     } else {
00533                         $theMods[$mod] = 1;
00534                     }
00535                 }
00536             }
00537         }
00538         return $theMods;
00539     }
00540 
00541     /**
00542      * The $str is cleaned so that it contains alphanumerical characters only. Modules must only consist of these characters
00543      *
00544      * @param   string      String to clean up
00545      * @return  string
00546      */
00547     function cleanName ($str)   {
00548         return preg_replace('/[^a-z0-9]/i','',$str);
00549     }
00550 
00551     /**
00552      * Get relative path for $destDir compared to $baseDir
00553      *
00554      * @param   string      Base directory
00555      * @param   string      Destination directory
00556      * @return  string      The relative path of destination compared to base.
00557      */
00558     function getRelativePath($baseDir,$destDir){
00559             // By Rene Fritz
00560             // a special case , the dirs are equals
00561         if ($baseDir == $destDir){
00562             return './';
00563         }
00564 
00565         $baseDir = ereg_replace ('^/', '', $baseDir);   // remove beginning
00566         $destDir = ereg_replace ('^/', '', $destDir);
00567 
00568         $found = true;
00569         $slash_pos=0;
00570 
00571         do {
00572             $slash_pos = strpos ($destDir, '/');
00573             if (substr($destDir, 0, $slash_pos) == substr($baseDir, 0, $slash_pos)){
00574                 $baseDir = substr($baseDir, $slash_pos+1);
00575                 $destDir = substr($destDir, $slash_pos+1);
00576             } else {
00577                 $found = false;
00578             }
00579         } while($found == true);
00580 
00581         $slashes = strlen ($baseDir) - strlen (str_replace('/', '', $baseDir));
00582         for($i=0;$i < $slashes;$i++)    {
00583             $destDir = '../'.$destDir;
00584         }
00585         return $destDir;
00586     }
00587 }
00588 
00589 
00590 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_loadmodules.php'])   {
00591     include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_loadmodules.php']);
00592 }
00593 
00594 ?>

Generated on Sat Jan 3 04:23:26 2009 for TYPO3 API by  doxygen 1.4.7