TYPO3 API  SVNRelease
class.t3lib_extmgm.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 1999-2011 Kasper Skårhøj (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  * Contains a class with Extension Management functions
00029  *
00030  * $Id: class.t3lib_extmgm.php 10485 2011-02-17 20:51:23Z steffenk $
00031  * Revised for TYPO3 3.6 July/2003 by Kasper Skårhøj
00032  *
00033  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00034  */
00035 /**
00036  * [CLASS/FUNCTION INDEX of SCRIPT]
00037  *
00038  *
00039  *
00040  *  114: class t3lib_extMgm
00041  *
00042  *            SECTION: PATHS and other evaluation
00043  *  131:     function isLoaded($key,$exitOnError = 0)
00044  *  147:     function extPath($key,$script='')
00045  *  165:     function extRelPath($key)
00046  *  182:     function siteRelPath($key)
00047  *  194:     function getCN($key)
00048  *
00049  *            SECTION: Adding BACKEND features
00050  *  227:     function addTCAcolumns($table,$columnArray,$addTofeInterface=0)
00051  *  251:     function addToAllTCAtypes($table,$str,$specificTypesList='',$position='')
00052  *  309:     function allowTableOnStandardPages($table)
00053  *  326:     function addModule($main,$sub='',$position='',$path='')
00054  *  389:     function insertModuleFunction($modname,$className,$classPath,$title,$MM_key='function',$WS='')
00055  *  408:     function addPageTSConfig($content)
00056  *  422:     function addUserTSConfig($content)
00057  *  437:     function addLLrefForTCAdescr($tca_descr_key,$file_ref)
00058  *
00059  *            SECTION: Adding SERVICES features
00060  *  479:     function addService($extKey, $serviceType, $serviceKey, $info)
00061  *  547:     function findService($serviceType, $serviceSubType='', $excludeServiceKeys=array())
00062  *  618:     function deactivateService($serviceType, $serviceKey)
00063  *
00064  *            SECTION: Adding FRONTEND features
00065  *  657:     function addPlugin($itemArray,$type='list_type')
00066  *  682:     function addPiFlexFormValue($piKeyToMatch,$value)
00067  *  702:     function addToInsertRecords($table,$content_table='tt_content',$content_field='records')
00068  *  733:     function addPItoST43($key,$classFile='',$prefix='',$type='list_type',$cached=0)
00069  *  808:     function addStaticFile($extKey,$path,$title)
00070  *  827:     function addTypoScriptSetup($content)
00071  *  841:     function addTypoScriptConstants($content)
00072  *  858:     function addTypoScript($key,$type,$content,$afterStaticUid=0)
00073  *
00074  *            SECTION: INTERNAL EXTENSION MANAGEMENT:
00075  *  921:     function typo3_loadExtensions()
00076  *  998:     function _makeIncludeHeader($key,$file)
00077  * 1019:     function isCacheFilesAvailable($cacheFilePrefix)
00078  * 1032:     function isLocalconfWritable()
00079  * 1045:     function cannotCacheFilesWritable($cacheFilePrefix)
00080  * 1069:     function currentCacheFiles()
00081  * 1092:     function writeCacheFiles($extensions,$cacheFilePrefix)
00082  * 1130:     function removeCacheFiles()
00083  *
00084  * TOTAL FUNCTIONS: 32
00085  * (This index is automatically created/updated by the extension "extdeveval")
00086  *
00087  */
00088 
00089 
00090 /**
00091  * Extension Management functions
00092  *
00093  * This class is never instantiated, rather the methods inside is called as functions like
00094  *       t3lib_extMgm::isLoaded('my_extension');
00095  *
00096  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00097  * @package TYPO3
00098  * @subpackage t3lib
00099  */
00100 final class t3lib_extMgm {
00101     protected static $extensionKeyMap;
00102 
00103 
00104     /**************************************
00105      *
00106      * PATHS and other evaluation
00107      *
00108      ***************************************/
00109 
00110     /**
00111      * Returns true if the extension with extension key $key is loaded.
00112      * Usage: 109
00113      *
00114      * @param   string      Extension key to test
00115      * @param   boolean     If $exitOnError is true and the extension is not loaded the function will die with an error message
00116      * @return  boolean
00117      */
00118     public static function isLoaded($key, $exitOnError = 0) {
00119         global $TYPO3_LOADED_EXT;
00120         if ($exitOnError && !isset($TYPO3_LOADED_EXT[$key])) {
00121             throw new BadFunctionCallException(
00122                 'TYPO3 Fatal Error: Extension "' . $key . '" was not loaded!',
00123                 1270853910
00124             );
00125         }
00126         return isset($TYPO3_LOADED_EXT[$key]);
00127     }
00128 
00129     /**
00130      * Returns the absolute path to the extension with extension key $key
00131      * If the extension is not loaded the function will die with an error message
00132      * Useful for internal fileoperations
00133      * Usage: 136
00134      *
00135      * @param   string      Extension key
00136      * @param   string      $script is appended to the output if set.
00137      * @return  string
00138      */
00139     public static function extPath($key, $script = '') {
00140         global $TYPO3_LOADED_EXT;
00141         if (!isset($TYPO3_LOADED_EXT[$key])) {
00142             throw new BadFunctionCallException(
00143                 'TYPO3 Fatal Error: Extension key "' . $key . '" was NOT loaded!',
00144                 1270853878
00145             );
00146         }
00147         return PATH_site . $TYPO3_LOADED_EXT[$key]['siteRelPath'] . $script;
00148     }
00149 
00150     /**
00151      * Returns the relative path to the extension as measured from from the TYPO3_mainDir
00152      * If the extension is not loaded the function will die with an error message
00153      * Useful for images and links from backend
00154      * Usage: 54
00155      *
00156      * @param   string      Extension key
00157      * @return  string
00158      */
00159     public static function extRelPath($key) {
00160         global $TYPO3_LOADED_EXT;
00161         if (!isset($TYPO3_LOADED_EXT[$key])) {
00162             throw new BadFunctionCallException(
00163                 'TYPO3 Fatal Error: Extension key "' . $key . '" was NOT loaded!',
00164                 1270853879
00165             );
00166         }
00167         return $TYPO3_LOADED_EXT[$key]['typo3RelPath'];
00168     }
00169 
00170     /**
00171      * Returns the relative path to the extension as measured from the PATH_site (frontend)
00172      * If the extension is not loaded the function will die with an error message
00173      * Useful for images and links from the frontend
00174      * Usage: 6
00175      *
00176      * @param   string      Extension key
00177      * @return  string
00178      */
00179     public static function siteRelPath($key) {
00180         return substr(self::extPath($key), strlen(PATH_site));
00181     }
00182 
00183     /**
00184      * Returns the correct class name prefix for the extension key $key
00185      * Usage: 3
00186      *
00187      * @param   string      Extension key
00188      * @return  string
00189      * @internal
00190      */
00191     public static function getCN($key) {
00192         return substr($key, 0, 5) == 'user_' ? 'user_' . str_replace('_', '', substr($key, 5)) : 'tx_' . str_replace('_', '', $key);
00193     }
00194 
00195     /**
00196      * Returns the real extension key like 'tt_news' from an extension prefix like 'tx_ttnews'.
00197      *
00198      * @param   string      $prefix: The extension prefix (e.g. 'tx_ttnews')
00199      * @return  mixed       Real extension key (string) or false (boolean) if something went wrong
00200      */
00201     public static function getExtensionKeyByPrefix($prefix) {
00202         $result = FALSE;
00203             // Build map of short keys referencing to real keys:
00204         if (!isset(self::$extensionKeyMap)) {
00205             self::$extensionKeyMap = array();
00206             foreach (array_keys($GLOBALS['TYPO3_LOADED_EXT']) as $extensionKey) {
00207                 $shortKey = str_replace('_', '', $extensionKey);
00208                 self::$extensionKeyMap[$shortKey] = $extensionKey;
00209             }
00210         }
00211             // Lookup by the given short key:
00212         $parts = explode('_', $prefix);
00213         if (isset(self::$extensionKeyMap[$parts[1]])) {
00214             $result = self::$extensionKeyMap[$parts[1]];
00215         }
00216         return $result;
00217     }
00218 
00219     /**
00220      * Clears the extension key map.
00221      *
00222      * @return  void
00223      */
00224     public static function clearExtensionKeyMap() {
00225         self::$extensionKeyMap = NULL;
00226     }
00227 
00228     /**
00229      * Retrieves the version of an installed extension.
00230      * If the extension is not installed, this function returns an empty string.
00231      *
00232      * @param string $key the key of the extension to look up, must not be empty
00233      * @return string the extension version as a string in the format "x.y.z",
00234      *              will be an empty string if the extension is not loaded
00235      */
00236     public static function getExtensionVersion($key) {
00237         if (!is_string($key) || empty($key)) {
00238             throw new InvalidArgumentException('Extension key must be a non-empty string.');
00239         }
00240         if (!self::isLoaded($key)) {
00241             return '';
00242         }
00243 
00244         $EM_CONF = array();
00245         $_EXTKEY = $key;
00246         include(self::extPath($key) . 'ext_emconf.php');
00247 
00248         return $EM_CONF[$key]['version'];
00249     }
00250 
00251 
00252     /**************************************
00253      *
00254      *   Adding BACKEND features
00255      *   (related to core features)
00256      *
00257      ***************************************/
00258 
00259     /**
00260      * Adding fields to an existing table definition in $TCA
00261      * Adds an array with $TCA column-configuration to the $TCA-entry for that table.
00262      * This function adds the configuration needed for rendering of the field in TCEFORMS - but it does NOT add the field names to the types lists!
00263      * So to have the fields displayed you must also call fx. addToAllTCAtypes or manually add the fields to the types list.
00264      * FOR USE IN ext_tables.php FILES
00265      * Usage: 4
00266      *
00267      * @param   string      $table is the table name of a table already present in $TCA with a columns section
00268      * @param   array       $columnArray is the array with the additional columns (typical some fields an extension wants to add)
00269      * @param   boolean     If $addTofeInterface is true the list of fields are also added to the fe_admin_fieldList.
00270      * @return  void
00271      */
00272     public static function addTCAcolumns($table, $columnArray, $addTofeInterface = 0) {
00273         global $TCA;
00274         t3lib_div::loadTCA($table);
00275         if (is_array($columnArray) && is_array($TCA[$table]) && is_array($TCA[$table]['columns'])) {
00276             $TCA[$table]['columns'] = array_merge($TCA[$table]['columns'], $columnArray); // Candidate for t3lib_div::array_merge() if integer-keys will some day make trouble...
00277             if ($addTofeInterface) {
00278                 $TCA[$table]['feInterface']['fe_admin_fieldList'] .= ',' . implode(',', array_keys($columnArray));
00279             }
00280         }
00281     }
00282 
00283     /**
00284      * Makes fields visible in the TCEforms, adding them to the end of (all) "types"-configurations
00285      *
00286      * Adds a string $str (comma list of field names) to all ["types"][xxx]["showitem"] entries for table $table (unless limited by $specificTypesList)
00287      * This is needed to have new fields shown automatically in the TCEFORMS of a record from $table.
00288      * Typically this function is called after having added new columns (database fields) with the addTCAcolumns function
00289      * FOR USE IN ext_tables.php FILES
00290      * Usage: 1
00291      *
00292      * @param   string      Table name
00293      * @param   string      Field list to add.
00294      * @param   string      List of specific types to add the field list to. (If empty, all type entries are affected)
00295      * @param   string      Insert fields before (default) or after one
00296      *                      of this fields (commalist with "before:", "after:" or "replace:" commands).
00297      *                      Example: "before:keywords,--palette--;;4,after:description".
00298      *                      Palettes must be passed like in the example no matter how the palette definition looks like in TCA.
00299      *                      It will add the list of new fields before or after a palette or replace the field inside the palette,
00300      *                      when the field given in $position is found inside a palette used by the type.
00301      * @return  void
00302      */
00303     public static function addToAllTCAtypes($table, $str, $specificTypesList = '', $position = '') {
00304         t3lib_div::loadTCA($table);
00305         $str = trim($str);
00306 
00307         if ($str && is_array($GLOBALS['TCA'][$table]) && is_array($GLOBALS['TCA'][$table]['types'])) {
00308             foreach ($GLOBALS['TCA'][$table]['types'] as $type => &$typeDetails) {
00309                 if ($specificTypesList === '' || t3lib_div::inList($specificTypesList, $type)) {
00310                     $fieldExists = FALSE;
00311                     if ($position != '' && is_array($GLOBALS['TCA'][$table]['palettes'])) {
00312                         $positionArray = t3lib_div::trimExplode(':', $position);
00313                         if ($positionArray[0] == 'replace') {
00314                             foreach ($GLOBALS['TCA'][$table]['palettes'] as $palette => $paletteDetails) {
00315                                 if (preg_match('/\b' . $palette . '\b/', $typeDetails['showitem']) > 0
00316                                         && preg_match('/\b' . $positionArray[1] . '\b/', $paletteDetails['showitem']) > 0) {
00317                                     self::addFieldsToPalette($table, $palette, $str, $position);
00318                                     $fieldExists = TRUE;
00319                                 }
00320                             }
00321                         } else {
00322                             if (strpos($typeDetails['showitem'], $str) !== FALSE) {
00323                                 $fieldExists = TRUE;
00324                             } else {
00325                                 foreach ($GLOBALS['TCA'][$table]['palettes'] as $palette => $paletteDetails) {
00326                                     if (preg_match('/\b' . $palette . '\b/', $typeDetails['showitem']) > 0
00327                                     && preg_match('/\b' . $positionArray[1] . '\b/', $paletteDetails['showitem']) > 0) {
00328                                         $position = $positionArray[0] . ':--palette--;;' . $palette;
00329                                     }
00330                                 }
00331                             }
00332                         }
00333                     } else {
00334                         if (strpos($typeDetails['showitem'], $str) !== FALSE) {
00335                             $fieldExists = TRUE;
00336                         } else if(is_array($GLOBALS['TCA'][$table]['palettes'])) {
00337                             foreach ($GLOBALS['TCA'][$table]['palettes'] as $palette => $paletteDetails) {
00338                                 if (preg_match('/\b' . $palette . '\b/', $typeDetails['showitem']) > 0
00339                                 && strpos($paletteDetails['showitem'], $str) !== FALSE) {
00340                                     $fieldExists = TRUE;
00341                                 }
00342                             }
00343                         }
00344                     }
00345                     if ($fieldExists === FALSE) {
00346                         $typeDetails['showitem'] = self::executePositionedStringInsertion(
00347                             $typeDetails['showitem'],
00348                             $str,
00349                             $position
00350                         );
00351                     }
00352                 }
00353             }
00354         }
00355     }
00356 
00357     /**
00358      * Adds new fields to all palettes of an existing field.
00359      * If the field does not have a palette yet, it's created automatically and
00360      * gets called "generatedFor-$field".
00361      *
00362      * @param   string      $table: Name of the table
00363      * @param   string      $field: Name of the field that has the palette to be extended
00364      * @param   string      $addFields: List of fields to be added to the palette
00365      * @param   string      $insertionPosition: Insert fields before (default) or after one
00366      *                       of this fields (commalist with "before:", "after:" or "replace:" commands).
00367      *                       Example: "before:keywords,--palette--;;4,after:description".
00368      *                       Palettes must be passed like in the example no matter how the
00369      *                       palette definition looks like in TCA.
00370      * @return  void
00371      */
00372     public static function addFieldsToAllPalettesOfField($table, $field, $addFields, $insertionPosition = '') {
00373         $generatedPalette = '';
00374         $processedPalettes = array();
00375         t3lib_div::loadTCA($table);
00376 
00377         if (isset($GLOBALS['TCA'][$table]['columns'][$field])) {
00378             $types =& $GLOBALS['TCA'][$table]['types'];
00379             if (is_array($types)) {
00380                     // Iterate through all types and search for the field that defines the palette to be extended:
00381                 foreach (array_keys($types) as $type) {
00382                     $items = self::explodeItemList($types[$type]['showitem']);
00383                     if (isset($items[$field])) {
00384                             // If the field already has a palette, extend it:
00385                         if ($items[$field]['details']['palette']) {
00386                             $palette = $items[$field]['details']['palette'];
00387                             if (!isset($processedPalettes[$palette])) {
00388                                 self::addFieldsToPalette($table, $palette, $addFields, $insertionPosition);
00389                                 $processedPalettes[$palette] = TRUE;
00390                             }
00391                             // If there's not palette yet, create one:
00392                         } else {
00393                             if ($generatedPalette) {
00394                                 $palette = $generatedPalette;
00395                             } else {
00396                                 $palette = $generatedPalette = 'generatedFor-' . $field;
00397                                 self::addFieldsToPalette($table, $palette, $addFields, $insertionPosition);
00398                             }
00399                             $items[$field]['details']['palette'] = $palette;
00400                             $types[$type]['showitem'] = self::generateItemList($items);
00401                         }
00402                     }
00403                 }
00404             }
00405         }
00406     }
00407 
00408     /**
00409      * Adds new fields to a palette.
00410      * If the palette does not exist yet, it's created automatically.
00411      *
00412      * @param   string      $table: Name of the table
00413      * @param   string      $palette: Name of the palette to be extended
00414      * @param   string      $addFields: List of fields to be added to the palette
00415      * @param   string      $insertionPosition: Insert fields before (default) or after one
00416      *                       of this fields (commalist with "before:", "after:" or "replace:" commands).
00417      *                       Example: "before:keywords,--palette--;;4,after:description".
00418      *                       Palettes must be passed like in the example no matter how the
00419      *                       palette definition looks like in TCA.
00420      * @return  void
00421      */
00422     public static function addFieldsToPalette($table, $palette, $addFields, $insertionPosition = '') {
00423         t3lib_div::loadTCA($table);
00424 
00425         if (isset($GLOBALS['TCA'][$table])) {
00426             $paletteData =& $GLOBALS['TCA'][$table]['palettes'][$palette];
00427                 // If palette already exists, merge the data:
00428             if (is_array($paletteData)) {
00429                 $paletteData['showitem'] = self::executePositionedStringInsertion(
00430                     $paletteData['showitem'],
00431                     $addFields,
00432                     $insertionPosition
00433                 );
00434                 // If it's a new palette, just set the data:
00435             } else {
00436                 $paletteData['showitem'] = self::removeDuplicatesForInsertion($addFields);
00437             }
00438         }
00439     }
00440 
00441     /**
00442      * Adds a list of new fields to the TYPO3 USER SETTINGS configuration "showitem" list, the array with
00443      * the new fields itself needs to be added additionally to show up in the user setup, like
00444      * $GLOBALS['TYPO3_USER_SETTINGS']['columns'] += $tempColumns
00445      *
00446      * @param   string  $addFields: List of fields to be added to the user settings
00447      * @param   string  $insertionPosition: Insert fields before (default) or after one
00448      *                   of this fields (commalist with "before:", "after:" or "replace:" commands).
00449      *                   Example: "before:password,after:email".
00450      * @return void
00451      */
00452     public function addFieldsToUserSettings($addFields, $insertionPosition = '') {
00453         $GLOBALS['TYPO3_USER_SETTINGS']['showitem'] = self::executePositionedStringInsertion(
00454             $GLOBALS['TYPO3_USER_SETTINGS']['showitem'],
00455             $addFields,
00456             $insertionPosition
00457         );
00458     }
00459 
00460     /**
00461      * Inserts as list of data into an existing list.
00462      * The insertion position can be defined accordant before of after existing list items.
00463      *
00464      * @param   string      $list: The list of items to be extended
00465      * @param   string      $insertionList: The list of items to inserted
00466      * @param   string      $insertionPosition: Insert fields before (default) or after one
00467      *                       of this fields (commalist with "before:" or "after:" commands).
00468      *                       Example: "before:keywords,--palette--;;4,after:description".
00469      *                       Palettes must be passed like in the example no matter how the
00470      *                       palette definition looks like in TCA.
00471      * @return  string      The extended list
00472      */
00473     protected static function executePositionedStringInsertion($list, $insertionList, $insertionPosition = '') {
00474         $list = trim($list);
00475         $insertionList = self::removeDuplicatesForInsertion($insertionList, $list);
00476 
00477         if ($insertionList) {
00478                 // Append data to the end (default):
00479             if ($insertionPosition === '') {
00480                 $list .= ($list ? ', ' : '') . $insertionList;
00481                 // Insert data before or after insertion points:
00482             } else {
00483                 $positions = t3lib_div::trimExplode(',', $insertionPosition, TRUE);
00484                 $items = self::explodeItemList($list);
00485                 $isInserted = FALSE;
00486                     // Iterate through all fields an check whether it's possible to inserte there:
00487                 foreach ($items as $item => &$itemDetails) {
00488                     $needles = self::getInsertionNeedles($item, $itemDetails['details']);
00489                         // Insert data before:
00490                     foreach ($needles['before'] as $needle) {
00491                         if (in_array($needle, $positions)) {
00492                             $itemDetails['rawData'] = $insertionList . ', ' . $itemDetails['rawData'];
00493                             $isInserted = TRUE;
00494                             break;
00495                         }
00496                     }
00497                         // Insert data after:
00498                     foreach ($needles['after'] as $needle) {
00499                         if (in_array($needle, $positions)) {
00500                             $itemDetails['rawData'] .= ', ' . $insertionList;
00501                             $isInserted = TRUE;
00502                             break;
00503                         }
00504                     }
00505                         // Replace with data:
00506                     foreach ($needles['replace'] as $needle) {
00507                         if (in_array($needle, $positions)) {
00508                             $itemDetails['rawData'] = $insertionList;
00509                             $isInserted = TRUE;
00510                             break;
00511                         }
00512                     }
00513                         // Break if insertion was already done:
00514                     if ($isInserted) {
00515                         break;
00516                     }
00517                 }
00518                     // If insertion point could not be determined, append the data:
00519                 if (!$isInserted) {
00520                     $list .= ($list ? ', ' : '') . $insertionList;
00521                     // If data was correctly inserted before or after existing items, recreate the list:
00522                 } else {
00523                     $list = self::generateItemList($items, TRUE);
00524                 }
00525             }
00526         }
00527 
00528         return $list;
00529     }
00530 
00531     /**
00532      * Compares an existing list of items and a list of items to be inserted
00533      * and returns a duplicate-free variant of that insertion list.
00534      *
00535      * Example:
00536      *  + list: 'field_a, field_b;;;;2-2-2, field_c;;;;3-3-3'
00537      *  + insertion: 'field_b, field_d, field_c;;;4-4-4'
00538      * -> new insertion: 'field_d'
00539      *
00540      * @param   string      $insertionList: The list of items to inserted
00541      * @param   string      $list: The list of items to be extended (default: '')
00542      * @return  string      Duplicate-free list of items to be inserted
00543      */
00544     protected static function removeDuplicatesForInsertion($insertionList, $list = '') {
00545         $pattern = '/(^|,)\s*\b([^;,]+)\b[^,]*/';
00546         $listItems = array();
00547 
00548         if ($list && preg_match_all($pattern, $list, $listMatches)) {
00549             $listItems = $listMatches[2];
00550         }
00551 
00552         if ($insertionList && preg_match_all($pattern, $insertionList, $insertionListMatches)) {
00553             $insertionItems = array();
00554             $insertionDuplicates = FALSE;
00555 
00556             foreach ($insertionListMatches[2] as $insertionIndex => $insertionItem) {
00557                 if (!isset($insertionItems[$insertionItem]) && !in_array($insertionItem, $listItems)) {
00558                     $insertionItems[$insertionItem] = TRUE;
00559                 } else {
00560                     unset($insertionListMatches[0][$insertionIndex]);
00561                     $insertionDuplicates = TRUE;
00562                 }
00563             }
00564 
00565             if ($insertionDuplicates) {
00566                 $insertionList = implode('', $insertionListMatches[0]);
00567             }
00568         }
00569 
00570         return $insertionList;
00571     }
00572 
00573     /**
00574      * Generates search needles that are used for inserting fields/items into an existing list.
00575      *
00576      * @see     executePositionedStringInsertion
00577      * @param   string      $item: The name of the field/item
00578      * @param   array       $itemDetails: Additional details of the field/item like e.g. palette information
00579      *                       (this array gets created by the function explodeItemList())
00580      * @return  array       The needled to be used for inserting content before or after existing fields/items
00581      */
00582     protected static function getInsertionNeedles($item, array $itemDetails) {
00583         if (strstr($item, '--')) {
00584                 // If $item is a separator (--div--) or palette (--palette--) then it may have been appended by a unique number. This must be stripped away here.
00585             $item = preg_replace('/[0-9]+$/', '', $item);
00586         }
00587 
00588         $needles = array(
00589             'before' => array($item, 'before:' . $item),
00590             'after' => array('after:' . $item),
00591             'replace' => array('replace:' . $item),
00592         );
00593 
00594         if ($itemDetails['palette']) {
00595             $palette = $item . ';;' . $itemDetails['palette'];
00596             $needles['before'][] = $palette;
00597             $needles['before'][] = 'before:' . $palette;
00598             $needles['after'][] = 'after:' . $palette;
00599             $needles['replace'][] = 'replace:' . $palette;
00600         }
00601 
00602         return $needles;
00603     }
00604 
00605     /**
00606      * Generates an array of fields/items with additional information such as e.g. the name of the palette.
00607      *
00608      * @param   string      $itemList: List of fields/items to be splitted up
00609      *                       (this mostly reflects the data in $TCA[<table>]['types'][<type>]['showitem'])
00610      * @return  array       An array with the names of the fields/items as keys and additional information
00611      */
00612     protected static function explodeItemList($itemList) {
00613         $items = array();
00614         $itemParts = t3lib_div::trimExplode(',', $itemList, TRUE);
00615 
00616         foreach ($itemParts as $itemPart) {
00617             $itemDetails = t3lib_div::trimExplode(';', $itemPart, FALSE, 5);
00618             $key = $itemDetails[0];
00619             if (strstr($key, '--')) {
00620                     // If $key is a separator (--div--) or palette (--palette--) then it will be appended by a unique number. This must be removed again when using this value!
00621                 $key .= count($items);
00622             }
00623 
00624             if (!isset($items[$key])) {
00625                 $items[$key] = array(
00626                     'rawData' => $itemPart,
00627                     'details' => array(
00628                         'field' => $itemDetails[0],
00629                         'label' => $itemDetails[1],
00630                         'palette' => $itemDetails[2],
00631                         'special' => $itemDetails[3],
00632                         'styles' => $itemDetails[4],
00633                     ),
00634                 );
00635             }
00636         }
00637 
00638         return $items;
00639     }
00640 
00641     /**
00642      * Generates a list of fields/items out of an array provided by the function getFieldsOfFieldList().
00643      *
00644      * @see     explodeItemList
00645      * @param   array       $items: The array of fields/items with optional additional information
00646      * @param   boolean     $useRawData: Use raw data instead of building by using the details (default: false)
00647      * @return  string      The list of fields/items which gets used for $TCA[<table>]['types'][<type>]['showitem']
00648      *                       or $TCA[<table>]['palettes'][<palette>]['showitem'] in most cases
00649      */
00650     protected static function generateItemList(array $items, $useRawData = FALSE) {
00651         $itemParts = array();
00652 
00653         foreach ($items as $item => $itemDetails) {
00654             if (strstr($item, '--')) {
00655                     // If $item is a separator (--div--) or palette (--palette--) then it may have been appended by a unique number. This must be stripped away here.
00656                 $item = preg_replace('/[0-9]+$/', '', $item);
00657             }
00658 
00659             if ($useRawData) {
00660                 $itemParts[] = $itemDetails['rawData'];
00661             } else {
00662                 $itemParts[] = (count($itemDetails['details']) > 1 ? implode(';', $itemDetails['details']) : $item);
00663             }
00664         }
00665 
00666         return implode(', ', $itemParts);
00667     }
00668 
00669     /**
00670      * Add tablename to default list of allowed tables on pages (in $PAGES_TYPES)
00671      * Will add the $table to the list of tables allowed by default on pages as setup by $PAGES_TYPES['default']['allowedTables']
00672      * FOR USE IN ext_tables.php FILES
00673      * Usage: 11
00674      *
00675      * @param   string      Table name
00676      * @return  void
00677      */
00678     public static function allowTableOnStandardPages($table) {
00679         global $PAGES_TYPES;
00680 
00681         $PAGES_TYPES['default']['allowedTables'] .= ',' . $table;
00682     }
00683 
00684     /**
00685      * Adds a module (main or sub) to the backend interface
00686      * FOR USE IN ext_tables.php FILES
00687      * Usage: 18
00688      *
00689      * @param   string      $main is the main module key, $sub is the submodule key. So $main would be an index in the $TBE_MODULES array and $sub could be an element in the lists there.
00690      * @param   string      $sub is the submodule key. If $sub is not set a blank $main module is created.
00691      * @param   string      $position can be used to set the position of the $sub module within the list of existing submodules for the main module. $position has this syntax: [cmd]:[submodule-key]. cmd can be "after", "before" or "top" (or blank which is default). If "after"/"before" then submodule will be inserted after/before the existing submodule with [submodule-key] if found. If not found, the bottom of list. If "top" the module is inserted in the top of the submodule list.
00692      * @param   string      $path is the absolute path to the module. If this value is defined the path is added as an entry in $TBE_MODULES['_PATHS'][  main_sub  ] = $path; and thereby tells the backend where the newly added modules is found in the system.
00693      * @return  void
00694      */
00695     public static function addModule($main, $sub = '', $position = '', $path = '') {
00696         global $TBE_MODULES;
00697 
00698         if (isset($TBE_MODULES[$main]) && $sub) { // If there is already a main module by this name:
00699 
00700                 // Adding the submodule to the correct position:
00701             list($place, $modRef) = t3lib_div::trimExplode(':', $position, 1);
00702             $mods = t3lib_div::trimExplode(',', $TBE_MODULES[$main], 1);
00703             if (!in_array($sub, $mods)) {
00704                 switch (strtolower($place)) {
00705                     case 'after':
00706                     case 'before':
00707                         $pointer = 0;
00708                         $found = FALSE;
00709                         foreach ($mods as $k => $m) {
00710                             if (!strcmp($m, $modRef)) {
00711                                 $pointer = strtolower($place) == 'after' ? $k + 1 : $k;
00712                                 $found = TRUE;
00713                             }
00714                         }
00715                         if ($found) {
00716                             array_splice(
00717                                 $mods, // The modules array
00718                                 $pointer, // To insert one position from the end of the list
00719                                 0, // Don't remove any items, just insert
00720                                 $sub // Module to insert
00721                             );
00722                         } else {
00723                                 // If requested module is not found: Add at the end
00724                             array_push($mods, $sub);
00725                         }
00726                     break;
00727                     default:
00728                         if (strtolower($place) == 'top') {
00729                             array_unshift($mods, $sub);
00730                         } else {
00731                             array_push($mods, $sub);
00732                         }
00733                     break;
00734                 }
00735             }
00736                 // Re-inserting the submodule list:
00737             $TBE_MODULES[$main] = implode(',', $mods);
00738         } else { // Create new main modules with only one submodule, $sub (or none if $sub is blank)
00739             $TBE_MODULES[$main] = $sub;
00740         }
00741 
00742             // Adding path:
00743         if ($path) {
00744             $TBE_MODULES['_PATHS'][$main . ($sub ? '_' . $sub : '')] = $path;
00745         }
00746     }
00747 
00748     /**
00749      * Adds a module path to TBE_MODULES for used with the module dispatcher, mod.php
00750      * Used only for modules that are not placed in the main/sub menu hierarchy by the traditional mechanism of addModule()
00751      * Examples for this is context menu functionality (like import/export) which runs as an independent module through mod.php
00752      * FOR USE IN ext_tables.php FILES
00753      * Example:  t3lib_extMgm::addModulePath('xMOD_tximpexp', t3lib_extMgm::extPath($_EXTKEY).'app/');
00754      *
00755      * @param   string      $name is the name of the module, refer to conf.php of the module.
00756      * @param   string      $path is the absolute path to the module directory inside of which "index.php" and "conf.php" is found.
00757      * @return  void
00758      */
00759     public static function addModulePath($name, $path) {
00760         global $TBE_MODULES;
00761 
00762         $TBE_MODULES['_PATHS'][$name] = $path;
00763     }
00764 
00765     /**
00766      * Adds a "Function menu module" ('third level module') to an existing function menu for some other backend module
00767      * The arguments values are generally determined by which function menu this is supposed to interact with
00768      * See Inside TYPO3 for information on how to use this function.
00769      * FOR USE IN ext_tables.php FILES
00770      * Usage: 26
00771      *
00772      * @param   string      Module name
00773      * @param   string      Class name
00774      * @param   string      Class path
00775      * @param   string      Title of module
00776      * @param   string      Menu array key - default is "function"
00777      * @param   string      Workspace conditions. Blank means all workspaces, any other string can be a comma list of "online", "offline" and "custom"
00778      * @return  void
00779      * @see t3lib_SCbase::mergeExternalItems()
00780      */
00781     public static function insertModuleFunction($modname, $className, $classPath, $title, $MM_key = 'function', $WS = '') {
00782         global $TBE_MODULES_EXT;
00783         $TBE_MODULES_EXT[$modname]['MOD_MENU'][$MM_key][$className] = array(
00784             'name' => $className,
00785             'path' => $classPath,
00786             'title' => $title,
00787             'ws' => $WS
00788         );
00789     }
00790 
00791     /**
00792      * Adds $content to the default Page TSconfig as set in $TYPO3_CONF_VARS[BE]['defaultPageTSconfig']
00793      * Prefixed with a [GLOBAL] line
00794      * FOR USE IN ext_tables.php/ext_localconf.php FILES
00795      * Usage: 5
00796      *
00797      * @param   string      Page TSconfig content
00798      * @return  void
00799      */
00800     public static function addPageTSConfig($content) {
00801         global $TYPO3_CONF_VARS;
00802         $TYPO3_CONF_VARS['BE']['defaultPageTSconfig'] .= "\n[GLOBAL]\n" . $content;
00803     }
00804 
00805     /**
00806      * Adds $content to the default User TSconfig as set in $TYPO3_CONF_VARS[BE]['defaultUserTSconfig']
00807      * Prefixed with a [GLOBAL] line
00808      * FOR USE IN ext_tables.php/ext_localconf.php FILES
00809      * Usage: 3
00810      *
00811      * @param   string      User TSconfig content
00812      * @return  void
00813      */
00814     public static function addUserTSConfig($content) {
00815         global $TYPO3_CONF_VARS;
00816         $TYPO3_CONF_VARS['BE']['defaultUserTSconfig'] .= "\n[GLOBAL]\n" . $content;
00817     }
00818 
00819     /**
00820      * Adds a reference to a locallang file with TCA_DESCR labels
00821      * FOR USE IN ext_tables.php FILES
00822      * eg. t3lib_extMgm::addLLrefForTCAdescr('pages', 'EXT:lang/locallang_csh_pages.xml'); for the pages table or t3lib_extMgm::addLLrefForTCAdescr('_MOD_web_layout', 'EXT:cms/locallang_csh_weblayout.php'); for the Web > Page module.
00823      * Usage: 31
00824      *
00825      * @param   string      Description key. Typically a database table (like "pages") but for applications can be other strings, but prefixed with "_MOD_")
00826      * @param   string      File reference to locallang file, eg. "EXT:lang/locallang_csh_pages.php" (or ".xml")
00827      * @return  void
00828      */
00829     public static function addLLrefForTCAdescr($tca_descr_key, $file_ref) {
00830         global $TCA_DESCR;
00831         if ($tca_descr_key) {
00832             if (!is_array($TCA_DESCR[$tca_descr_key])) {
00833                 $TCA_DESCR[$tca_descr_key] = array();
00834             }
00835             if (!is_array($TCA_DESCR[$tca_descr_key]['refs'])) {
00836                 $TCA_DESCR[$tca_descr_key]['refs'] = array();
00837             }
00838             $TCA_DESCR[$tca_descr_key]['refs'][] = $file_ref;
00839         }
00840     }
00841 
00842     /**
00843      * Registers a navigation component
00844      *
00845      * @param string $module
00846      * @param string $componentId
00847      * @return void
00848      */
00849     public static function addNavigationComponent($module, $componentId) {
00850         $GLOBALS['TBE_MODULES']['_navigationComponents'][$module] = array(
00851             'componentId' => $componentId,
00852             'extKey' => $GLOBALS['_EXTKEY'],
00853             'isCoreComponent' => FALSE,
00854         );
00855     }
00856 
00857     /**
00858      * Registers a core navigation component
00859      *
00860      * @param string $module
00861      * @param string $componentId
00862      * @return void
00863      */
00864     public static function addCoreNavigationComponent($module, $componentId) {
00865         self::addNavigationComponent($module, $componentId);
00866         $GLOBALS['TBE_MODULES']['_navigationComponents'][$module]['isCoreComponent'] = TRUE;
00867     }
00868 
00869 
00870     /**************************************
00871      *
00872      *   Adding SERVICES features
00873      *
00874      * @author  René Fritz <r.fritz@colorcube.de>
00875      *
00876      ***************************************/
00877 
00878     /**
00879      * Adds a service to the global services array
00880      *
00881      * @param   string      Extension key
00882      * @param   string      Service type, cannot be prefixed "tx_"
00883      * @param   string      Service key, must be prefixed "tx_" or "user_"
00884      * @param   array       Service description array
00885      * @return  void
00886      * @author  René Fritz <r.fritz@colorcube.de>
00887      */
00888     public static function addService($extKey, $serviceType, $serviceKey, $info) {
00889         global $T3_SERVICES, $TYPO3_CONF_VARS;
00890 
00891             // even not available services will be included to make it possible to give the admin a feedback of non-available services.
00892             // but maybe it's better to move non-available services to a different array??
00893 
00894         if ($serviceType &&
00895                 !t3lib_div::isFirstPartOfStr($serviceType, 'tx_') &&
00896                 (t3lib_div::isFirstPartOfStr($serviceKey, 'tx_') || t3lib_div::isFirstPartOfStr($serviceKey, 'user_')) &&
00897                 is_array($info)) {
00898 
00899             $info['priority'] = max(0, min(100, $info['priority']));
00900 
00901             $T3_SERVICES[$serviceType][$serviceKey] = $info;
00902 
00903             $T3_SERVICES[$serviceType][$serviceKey]['extKey'] = $extKey;
00904             $T3_SERVICES[$serviceType][$serviceKey]['serviceKey'] = $serviceKey;
00905             $T3_SERVICES[$serviceType][$serviceKey]['serviceType'] = $serviceType;
00906 
00907 
00908                 // mapping a service key to a service type
00909                 // all service keys begin with tx_ - service types don't
00910                 // this way a selection of a special service key as service type is easy
00911             $T3_SERVICES[$serviceKey][$serviceKey] = &$T3_SERVICES[$serviceType][$serviceKey];
00912 
00913 
00914                 // change the priority (and other values) from TYPO3_CONF_VARS
00915                 // $TYPO3_CONF_VARS['T3_SERVICES'][$serviceType][$serviceKey]['priority']
00916                 // even the activation is possible (a unix service might be possible on windows for some reasons)
00917             if (is_array($TYPO3_CONF_VARS['T3_SERVICES'][$serviceType][$serviceKey])) {
00918 
00919                     // no check is done here - there might be configuration values only the service type knows about, so we pass everything
00920                 $T3_SERVICES[$serviceType][$serviceKey] = array_merge($T3_SERVICES[$serviceType][$serviceKey], $TYPO3_CONF_VARS['T3_SERVICES'][$serviceType][$serviceKey]);
00921             }
00922 
00923 
00924                 // OS check
00925                 // empty $os means 'not limited to one OS', therefore a check is not needed
00926             if ($T3_SERVICES[$serviceType][$serviceKey]['available'] && $T3_SERVICES[$serviceType][$serviceKey]['os'] != '') {
00927 
00928                     // TYPO3_OS is not yet defined
00929                 $os_type = stristr(PHP_OS, 'win') && !stristr(PHP_OS, 'darwin') ? 'WIN' : 'UNIX';
00930 
00931                 $os = t3lib_div::trimExplode(',', strtoupper($T3_SERVICES[$serviceType][$serviceKey]['os']));
00932 
00933                 if (!in_array($os_type, $os)) {
00934                     self::deactivateService($serviceType, $serviceKey);
00935                 }
00936             }
00937 
00938                 // convert subtype list to array for quicker access
00939             $T3_SERVICES[$serviceType][$serviceKey]['serviceSubTypes'] = array();
00940             $serviceSubTypes = t3lib_div::trimExplode(',', $info['subtype']);
00941             foreach ($serviceSubTypes as $subtype) {
00942                 $T3_SERVICES[$serviceType][$serviceKey]['serviceSubTypes'][$subtype] = $subtype;
00943             }
00944         }
00945     }
00946 
00947     /**
00948      * Find the available service with highest priority
00949      *
00950      * @param   string      Service type
00951      * @param   string      Service sub type
00952      * @param   mixed       Service keys that should be excluded in the search for a service. Array or comma list.
00953      * @return  mixed       Service info array if a service was found, FLASE otherwise
00954      * @author  René Fritz <r.fritz@colorcube.de>
00955      */
00956     public static function findService($serviceType, $serviceSubType = '', $excludeServiceKeys = array()) {
00957         global $T3_SERVICES, $TYPO3_CONF_VARS;
00958 
00959         $serviceKey = FALSE;
00960         $serviceInfo = FALSE;
00961         $priority = 0;
00962         $quality = 0;
00963 
00964         if (!is_array($excludeServiceKeys)) {
00965             $excludeServiceKeys = t3lib_div::trimExplode(',', $excludeServiceKeys, 1);
00966         }
00967 
00968         if (is_array($T3_SERVICES[$serviceType])) {
00969             foreach ($T3_SERVICES[$serviceType] as $key => $info) {
00970 
00971                 if (in_array($key, $excludeServiceKeys)) {
00972                     continue;
00973                 }
00974 
00975                     // select a subtype randomly
00976                     // usefull to start a service by service key without knowing his subtypes - for testing purposes
00977                 if ($serviceSubType == '*') {
00978                     $serviceSubType = key($info['serviceSubTypes']);
00979                 }
00980 
00981                     // this matches empty subtype too
00982                 if ($info['available'] && ($info['subtype'] == $serviceSubType || $info['serviceSubTypes'][$serviceSubType]) && $info['priority'] >= $priority) {
00983 
00984                         // has a lower quality than the already found, therefore we skip this service
00985                     if ($info['priority'] == $priority && $info['quality'] < $quality) {
00986                         continue;
00987                     }
00988 
00989                         // service depends on external programs - check if they exists
00990                     if (trim($info['exec'])) {
00991                         $executables = t3lib_div::trimExplode(',', $info['exec'], 1);
00992                         foreach ($executables as $executable) {
00993                             if (!t3lib_exec::checkCommand($executable)) {
00994                                 self::deactivateService($serviceType, $key);
00995                                 $info['available'] = FALSE;
00996                                 break;
00997                             }
00998                         }
00999                     }
01000 
01001                         // still available after exec check?
01002                     if ($info['available']) {
01003                         $serviceKey = $key;
01004                         $priority = $info['priority'];
01005                         $quality = $info['quality'];
01006                     }
01007                 }
01008             }
01009         }
01010 
01011         if ($serviceKey) {
01012             $serviceInfo = $T3_SERVICES[$serviceType][$serviceKey];
01013         }
01014         return $serviceInfo;
01015     }
01016 
01017     /**
01018      * Deactivate a service
01019      *
01020      * @param   string      Service type
01021      * @param   string      Service key
01022      * @return  void
01023      * @author  René Fritz <r.fritz@colorcube.de>
01024      */
01025     public static function deactivateService($serviceType, $serviceKey) {
01026         global $T3_SERVICES;
01027 
01028             // ... maybe it's better to move non-available services to a different array??
01029         $T3_SERVICES[$serviceType][$serviceKey]['available'] = FALSE;
01030     }
01031 
01032 
01033     /**************************************
01034      *
01035      *   Adding FRONTEND features
01036      *   (related specifically to "cms" extension)
01037      *
01038      ***************************************/
01039 
01040     /**
01041      * Adds an entry to the list of plugins in content elements of type "Insert plugin"
01042      * Takes the $itemArray (label, value[,icon]) and adds to the items-array of $TCA[tt_content] elements with CType "listtype" (or another field if $type points to another fieldname)
01043      * If the value (array pos. 1) is already found in that items-array, the entry is substituted, otherwise the input array is added to the bottom.
01044      * Use this function to add a frontend plugin to this list of plugin-types - or more generally use this function to add an entry to any selectorbox/radio-button set in the TCEFORMS
01045      * FOR USE IN ext_tables.php FILES
01046      * Usage: 13
01047      *
01048      * @param   array       Item Array
01049      * @param   string      Type (eg. "list_type") - basically a field from "tt_content" table
01050      * @return  void
01051      */
01052     public static function addPlugin($itemArray, $type = 'list_type') {
01053         global $TCA;
01054 
01055         $_EXTKEY = $GLOBALS['_EXTKEY'];
01056         if ($_EXTKEY && !$itemArray[2]) {
01057             $itemArray[2] = self::extRelPath($_EXTKEY) . 'ext_icon.gif';
01058         }
01059 
01060         t3lib_div::loadTCA('tt_content');
01061         if (is_array($TCA['tt_content']['columns']) && is_array($TCA['tt_content']['columns'][$type]['config']['items'])) {
01062             foreach ($TCA['tt_content']['columns'][$type]['config']['items'] as $k => $v) {
01063                 if (!strcmp($v[1], $itemArray[1])) {
01064                     $TCA['tt_content']['columns'][$type]['config']['items'][$k] = $itemArray;
01065                     return;
01066                 }
01067             }
01068             $TCA['tt_content']['columns'][$type]['config']['items'][] = $itemArray;
01069         }
01070     }
01071 
01072     /**
01073      * Adds an entry to the "ds" array of the tt_content field "pi_flexform".
01074      * This is used by plugins to add a flexform XML reference / content for use when they are selected as plugin or content element.
01075      * Usage: 0
01076      *
01077      * @param   string      Plugin key as used in the list_type field. Use the asterisk * to match all list_type values.
01078      * @param   string      Either a reference to a flex-form XML file (eg. "FILE:EXT:newloginbox/flexform_ds.xml") or the XML directly.
01079      * @param   string      Value of tt_content.CType (Content Type) to match. The default is "list" which corresponds to the "Insert Plugin" content element.  Use the asterisk * to match all CType values.
01080      * @return  void
01081      * @see addPlugin()
01082      */
01083     public static function addPiFlexFormValue($piKeyToMatch, $value, $CTypeToMatch = 'list') {
01084         global $TCA;
01085         t3lib_div::loadTCA('tt_content');
01086 
01087         if (is_array($TCA['tt_content']['columns']) && is_array($TCA['tt_content']['columns']['pi_flexform']['config']['ds'])) {
01088             $TCA['tt_content']['columns']['pi_flexform']['config']['ds'][$piKeyToMatch . ',' . $CTypeToMatch] = $value;
01089         }
01090     }
01091 
01092     /**
01093      * Adds the $table tablename to the list of tables allowed to be includes by content element type "Insert records"
01094      * By using $content_table and $content_field you can also use the function for other tables.
01095      * FOR USE IN ext_tables.php FILES
01096      * Usage: 9
01097      *
01098      * @param   string      Table name to allow for "insert record"
01099      * @param   string      Table name TO WHICH the $table name is applied. See $content_field as well.
01100      * @param   string      Field name in the database $content_table in which $table is allowed to be added as a reference ("Insert Record")
01101      * @return  void
01102      */
01103     public static function addToInsertRecords($table, $content_table = 'tt_content', $content_field = 'records') {
01104         global $TCA;
01105         t3lib_div::loadTCA($content_table);
01106         if (is_array($TCA[$content_table]['columns']) && isset($TCA[$content_table]['columns'][$content_field]['config']['allowed'])) {
01107             $TCA[$content_table]['columns'][$content_field]['config']['allowed'] .= ',' . $table;
01108         }
01109     }
01110 
01111     /**
01112      * Add PlugIn to Static Template #43
01113      *
01114      * When adding a frontend plugin you will have to add both an entry to the TCA definition of tt_content table AND to the TypoScript template which must initiate the rendering.
01115      * Since the static template with uid 43 is the "content.default" and practically always used for rendering the content elements it's very useful to have this function automatically adding the necessary TypoScript for calling your plugin. It will also work for the extension "css_styled_content"
01116      * $type determines the type of frontend plugin:
01117      *       "list_type" (default)  - the good old "Insert plugin" entry
01118      *       "menu_type"    - a "Menu/Sitemap" entry
01119      *       "splash_layout" - a "Textbox" entry
01120      *       "CType" - a new content element type
01121      *       "header_layout" - an additional header type (added to the selection of layout1-5)
01122      *       "includeLib" - just includes the library for manual use somewhere in TypoScript.
01123      *   (Remember that your $type definition should correspond to the column/items array in $TCA[tt_content] where you added the selector item for the element! See addPlugin() function)
01124      * FOR USE IN ext_localconf.php FILES
01125      * Usage: 2
01126      *
01127      * @param   string      $key is the extension key
01128      * @param   string      $classFile is the PHP-class filename relative to the extension root directory. If set to blank a default value is chosen according to convensions.
01129      * @param   string      $prefix is used as a - yes, suffix - of the class name (fx. "_pi1")
01130      * @param   string      $type, see description above
01131      * @param   boolean     If $cached is set as USER content object (cObject) is created - otherwise a USER_INT object is created.
01132      * @return  void
01133      */
01134     public static function addPItoST43($key, $classFile = '', $prefix = '', $type = 'list_type', $cached = 0) {
01135         global $TYPO3_LOADED_EXT;
01136         $classFile = $classFile ? $classFile : 'pi/class.tx_' . str_replace('_', '', $key) . $prefix . '.php';
01137         $cN = self::getCN($key);
01138 
01139             // General plugin:
01140         $pluginContent = trim('
01141 plugin.' . $cN . $prefix . ' = USER' . ($cached ? '' : '_INT') . '
01142 plugin.' . $cN . $prefix . ' {
01143   includeLibs = ' . $TYPO3_LOADED_EXT[$key]['siteRelPath'] . $classFile . '
01144   userFunc = ' . $cN . $prefix . '->main
01145 }');
01146         self::addTypoScript($key, 'setup', '
01147 # Setting ' . $key . ' plugin TypoScript
01148 ' . $pluginContent);
01149 
01150             // After ST43:
01151         switch ($type) {
01152             case 'list_type':
01153                 $addLine = 'tt_content.list.20.' . $key . $prefix . ' = < plugin.' . $cN . $prefix;
01154             break;
01155             case 'menu_type':
01156                 $addLine = 'tt_content.menu.20.' . $key . $prefix . ' = < plugin.' . $cN . $prefix;
01157             break;
01158             case 'splash_layout':
01159                 $addLine = 'tt_content.splash.' . $key . $prefix . ' = < plugin.' . $cN . $prefix;
01160             break;
01161             case 'CType':
01162                 $addLine = trim('
01163 tt_content.' . $key . $prefix . ' = COA
01164 tt_content.' . $key . $prefix . ' {
01165     10 = < lib.stdheader
01166     20 = < plugin.' . $cN . $prefix . '
01167 }
01168                 ');
01169             break;
01170             case 'header_layout':
01171                 $addLine = 'lib.stdheader.10.' . $key . $prefix . ' = < plugin.' . $cN . $prefix;
01172             break;
01173             case 'includeLib':
01174                 $addLine = 'page.1000 = < plugin.' . $cN . $prefix;
01175             break;
01176             default:
01177                 $addLine = '';
01178             break;
01179         }
01180         if ($addLine) {
01181             self::addTypoScript($key, 'setup', '
01182 # Setting ' . $key . ' plugin TypoScript
01183 ' . $addLine . '
01184 ', 43);
01185         }
01186     }
01187 
01188     /**
01189      * Call this method to add an entry in the static template list found in sys_templates
01190      * "static template files" are the modern equalent (provided from extensions) to the traditional records in "static_templates"
01191      * FOR USE IN ext_localconf.php FILES
01192      * Usage: 3
01193      *
01194      * @param   string      $extKey is of course the extension key
01195      * @param   string      $path is the path where the template files (fixed names) include_static.txt (integer list of uids from the table "static_templates"), constants.txt, setup.txt, editorcfg.txt, and include_static_file.txt is found (relative to extPath, eg. 'static/'). The file include_static_file.txt, allows you to include other static templates defined in files, from your static template, and thus corresponds to the field 'include_static_file' in the sys_template table. The syntax for this is a commaseperated list of static templates to include, like:  EXT:css_styled_content/static/,EXT:da_newsletter_subscription/static/,EXT:cc_random_image/pi2/static/
01196      * @param   string      $title is the title in the selector box.
01197      * @return  void
01198      * @see addTypoScript()
01199      */
01200     public static function addStaticFile($extKey, $path, $title) {
01201         global $TCA;
01202         t3lib_div::loadTCA('sys_template');
01203         if ($extKey && $path && is_array($TCA['sys_template']['columns'])) {
01204             $value = str_replace(',', '', 'EXT:' . $extKey . '/' . $path);
01205             $itemArray = array(trim($title . ' (' . $extKey . ')'), $value);
01206             $TCA['sys_template']['columns']['include_static_file']['config']['items'][] = $itemArray;
01207         }
01208     }
01209 
01210     /**
01211      * Adds $content to the default TypoScript setup code as set in $TYPO3_CONF_VARS[FE]['defaultTypoScript_setup']
01212      * Prefixed with a [GLOBAL] line
01213      * FOR USE IN ext_localconf.php FILES
01214      * Usage: 6
01215      *
01216      * @param   string      TypoScript Setup string
01217      * @return  void
01218      */
01219     public static function addTypoScriptSetup($content) {
01220         global $TYPO3_CONF_VARS;
01221         $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup'] .= "\n[GLOBAL]\n" . $content;
01222     }
01223 
01224     /**
01225      * Adds $content to the default TypoScript constants code as set in $TYPO3_CONF_VARS[FE]['defaultTypoScript_constants']
01226      * Prefixed with a [GLOBAL] line
01227      * FOR USE IN ext_localconf.php FILES
01228      * Usage: 0
01229      *
01230      * @param   string      TypoScript Constants string
01231      * @return  void
01232      */
01233     public static function addTypoScriptConstants($content) {
01234         global $TYPO3_CONF_VARS;
01235         $TYPO3_CONF_VARS['FE']['defaultTypoScript_constants'] .= "\n[GLOBAL]\n" . $content;
01236     }
01237 
01238     /**
01239      * Adds $content to the default TypoScript code for either setup, constants or editorcfg as set in $TYPO3_CONF_VARS[FE]['defaultTypoScript_*']
01240      * (Basically this function can do the same as addTypoScriptSetup and addTypoScriptConstants - just with a little more hazzle, but also with some more options!)
01241      * FOR USE IN ext_localconf.php FILES
01242      * Usage: 7
01243      *
01244      * @param   string      $key is the extension key (informative only).
01245      * @param   string      $type is either "setup", "constants" or "editorcfg" and obviously determines which kind of TypoScript code we are adding.
01246      * @param   string      $content is the TS content, prefixed with a [GLOBAL] line and a comment-header.
01247      * @param   string      $afterStaticUid is either an integer pointing to a uid of a static_template or a string pointing to the "key" of a static_file template ([reduced extension_key]/[local path]). The points is that the TypoScript you add is included only IF that static template is included (and in that case, right after). So effectively the TypoScript you set can specifically overrule settings from those static templates.
01248      * @return  void
01249      */
01250     public static function addTypoScript($key, $type, $content, $afterStaticUid = 0) {
01251         global $TYPO3_CONF_VARS;
01252 
01253         if ($type == 'setup' || $type == 'editorcfg' || $type == 'constants') {
01254             $content = '
01255 
01256 [GLOBAL]
01257 #############################################
01258 ## TypoScript added by extension "' . $key . '"
01259 #############################################
01260 
01261 ' . $content;
01262             if ($afterStaticUid) {
01263                 $TYPO3_CONF_VARS['FE']['defaultTypoScript_' . $type . '.'][$afterStaticUid] .= $content;
01264                     // If 'content (default)' is targeted, also add to other 'content rendering templates', eg. css_styled_content
01265                 if ($afterStaticUid == 43 && is_array($TYPO3_CONF_VARS['FE']['contentRenderingTemplates'])) {
01266                     foreach ($TYPO3_CONF_VARS['FE']['contentRenderingTemplates'] as $templateName) {
01267                         $TYPO3_CONF_VARS['FE']['defaultTypoScript_' . $type . '.'][$templateName] .= $content;
01268                     }
01269                 }
01270             } else {
01271                 $TYPO3_CONF_VARS['FE']['defaultTypoScript_' . $type] .= $content;
01272             }
01273         }
01274     }
01275 
01276 
01277     /**************************************
01278      *
01279      *   INTERNAL EXTENSION MANAGEMENT:
01280      *
01281      ***************************************/
01282 
01283     /**
01284      * Loading extensions configured in $TYPO3_CONF_VARS['EXT']['extList']
01285      *
01286      * CACHING ON: ($TYPO3_CONF_VARS['EXT']['extCache'] = 1 or 2)
01287      *       If caching is enabled (and possible), the output will be $extensions['_CACHEFILE'] set to the cacheFilePrefix. Subsequently the cache files must be included then since those will eventually set up the extensions.
01288      *       If cachefiles are not found they will be generated
01289      * CACHING OFF: ($TYPO3_CONF_VARS['EXT']['extCache'] = 0)
01290      *       The returned value will be an array where each key is an extension key and the value is an array with filepaths for the extension.
01291      *       This array will later be set in the global var $TYPO3_LOADED_EXT
01292      *
01293      * Usages of this function can be seen in config_default.php
01294      * Extensions are always detected in the order local - global - system.
01295      * Usage: 1
01296      *
01297      * @return  array       Extension Array
01298      * @internal
01299      */
01300     public static function typo3_loadExtensions() {
01301         global $TYPO3_CONF_VARS;
01302 
01303             // Caching behaviour of ext_tables.php and ext_localconf.php files:
01304         $extensionCacheBehaviour = self::getExtensionCacheBehaviour();
01305             // Full list of extensions includes both required and extList:
01306         $rawExtList = self::getEnabledExtensionList();
01307 
01308             // Empty array as a start.
01309         $extensions = array();
01310 
01311             //
01312         if ($rawExtList) {
01313                 // The cached File prefix.
01314             $cacheFilePrefix = self::getCacheFilePrefix();
01315 
01316                 // If cache files available, set cache file prefix and return:
01317             if ($extensionCacheBehaviour && self::isCacheFilesAvailable($cacheFilePrefix)) {
01318                     // Return cache file prefix:
01319                 $extensions['_CACHEFILE'] = $cacheFilePrefix;
01320             } else { // ... but if not, configure...
01321 
01322                     // Prepare reserved filenames:
01323                 $files = array('ext_localconf.php', 'ext_tables.php', 'ext_tables.sql', 'ext_tables_static+adt.sql', 'ext_typoscript_constants.txt', 'ext_typoscript_editorcfg.txt', 'ext_typoscript_setup.txt');
01324                     // Traverse extensions and check their existence:
01325                 clearstatcache(); // Clear file state cache to make sure we get good results from is_dir()
01326                 $temp_extensions = array_unique(t3lib_div::trimExplode(',', $rawExtList, 1));
01327                 foreach ($temp_extensions as $temp_extKey) {
01328                         // Check local, global and system locations:
01329                     if (@is_dir(PATH_typo3conf . 'ext/' . $temp_extKey . '/')) {
01330                         $extensions[$temp_extKey] = array('type' => 'L', 'siteRelPath' => 'typo3conf/ext/' . $temp_extKey . '/', 'typo3RelPath' => '../typo3conf/ext/' . $temp_extKey . '/');
01331                     } elseif (@is_dir(PATH_typo3 . 'ext/' . $temp_extKey . '/')) {
01332                         $extensions[$temp_extKey] = array('type' => 'G', 'siteRelPath' => TYPO3_mainDir . 'ext/' . $temp_extKey . '/', 'typo3RelPath' => 'ext/' . $temp_extKey . '/');
01333                     } elseif (@is_dir(PATH_typo3 . 'sysext/' . $temp_extKey . '/')) {
01334                         $extensions[$temp_extKey] = array('type' => 'S', 'siteRelPath' => TYPO3_mainDir . 'sysext/' . $temp_extKey . '/', 'typo3RelPath' => 'sysext/' . $temp_extKey . '/');
01335                     }
01336 
01337                         // If extension was found, check for reserved filenames:
01338                     if (isset($extensions[$temp_extKey])) {
01339                         foreach ($files as $fName) {
01340                             $temp_filename = PATH_site . $extensions[$temp_extKey]['siteRelPath'] . trim($fName);
01341                             if (is_array($extensions[$temp_extKey]) && @is_file($temp_filename)) {
01342                                 $extensions[$temp_extKey][$fName] = $temp_filename;
01343                             }
01344                         }
01345                     }
01346                 }
01347                 unset($extensions['_CACHEFILE']);
01348 
01349                     // write cache?
01350                 if ($extensionCacheBehaviour &&
01351                         @is_dir(PATH_typo3 . 'sysext/') &&
01352                                 @is_dir(PATH_typo3 . 'ext/')) { // Must also find global and system extension directories to exist, otherwise caching cannot be allowed (since it is most likely a temporary server problem). This might fix a rare, unrepeatable bug where global/system extensions are not loaded resulting in fatal errors if that is cached!
01353                     $wrError = self::cannotCacheFilesWritable($cacheFilePrefix);
01354                     if ($wrError) {
01355                         $TYPO3_CONF_VARS['EXT']['extCache'] = 0;
01356                     } else {
01357                             // Write cache files:
01358                         $extensions = self::writeCacheFiles($extensions, $cacheFilePrefix);
01359                     }
01360                 }
01361             }
01362         }
01363 
01364         return $extensions;
01365     }
01366 
01367     /**
01368      * Returns the section headers for the compiled cache-files.
01369      *
01370      * @param   string      $key is the extension key
01371      * @param   string      $file is the filename (only informative for comment)
01372      * @return  string
01373      * @internal
01374      */
01375     public static function _makeIncludeHeader($key, $file) {
01376         return '<?php
01377 ###########################
01378 ## EXTENSION: ' . $key . '
01379 ## FILE:      ' . $file . '
01380 ###########################
01381 
01382 $_EXTKEY = \'' . $key . '\';
01383 $_EXTCONF = $TYPO3_CONF_VARS[\'EXT\'][\'extConf\'][$_EXTKEY];
01384 
01385 ?>';
01386     }
01387 
01388     /**
01389      * Returns true if both the localconf and tables cache file exists (with $cacheFilePrefix)
01390      * Usage: 2
01391      *
01392      * @param   string      Prefix of the cache file to check
01393      * @return  boolean
01394      * @internal
01395      */
01396     public static function isCacheFilesAvailable($cacheFilePrefix) {
01397         return
01398                 @is_file(PATH_typo3conf . $cacheFilePrefix . '_ext_localconf.php') &&
01399                         @is_file(PATH_typo3conf . $cacheFilePrefix . '_ext_tables.php');
01400     }
01401 
01402     /**
01403      * Returns true if the "localconf.php" file in "typo3conf/" is writable
01404      * Usage: 1
01405      *
01406      * @return  boolean
01407      * @internal
01408      */
01409     public static function isLocalconfWritable() {
01410         return @is_writable(PATH_typo3conf) && @is_writable(PATH_typo3conf . 'localconf.php');
01411     }
01412 
01413     /**
01414      * Returns an error string if typo3conf/ or cache-files with $cacheFilePrefix are NOT writable
01415      * Returns false if no problem.
01416      * Usage: 1
01417      *
01418      * @param   string      Prefix of the cache file to check
01419      * @return  string
01420      * @internal
01421      */
01422     public static function cannotCacheFilesWritable($cacheFilePrefix) {
01423         $error = array();
01424         if (!@is_writable(PATH_typo3conf)) {
01425             $error[] = PATH_typo3conf;
01426         }
01427         if (@is_file(PATH_typo3conf . $cacheFilePrefix . '_ext_localconf.php') &&
01428                 !@is_writable(PATH_typo3conf . $cacheFilePrefix . '_ext_localconf.php')) {
01429             $error[] = PATH_typo3conf . $cacheFilePrefix . '_ext_localconf.php';
01430         }
01431         if (@is_file(PATH_typo3conf . $cacheFilePrefix . '_ext_tables.php') &&
01432                 !@is_writable(PATH_typo3conf . $cacheFilePrefix . '_ext_tables.php')) {
01433             $error[] = PATH_typo3conf . $cacheFilePrefix . '_ext_tables.php';
01434         }
01435         return implode(', ', $error);
01436     }
01437 
01438     /**
01439      * Returns an array with the two cache-files (0=>localconf, 1=>tables) from typo3conf/ if they (both) exist. Otherwise false.
01440      * Evaluation relies on $TYPO3_LOADED_EXT['_CACHEFILE']
01441      * Usage: 2
01442      *
01443      * @param string $cacheFilePrefix Cache file prefix to be used (optional)
01444      * @return  array
01445      * @internal
01446      */
01447     public static function currentCacheFiles($cacheFilePrefix = NULL) {
01448         if (is_null($cacheFilePrefix)) {
01449             $cacheFilePrefix = $GLOBALS['TYPO3_LOADED_EXT']['_CACHEFILE'];
01450         }
01451 
01452         if ($cacheFilePrefix) {
01453             $cacheFilePrefixFE = str_replace('temp_CACHED', 'temp_CACHED_FE', $cacheFilePrefix);
01454             $files = array();
01455             if (self::isCacheFilesAvailable($cacheFilePrefix)) {
01456                 $files[] = PATH_typo3conf . $cacheFilePrefix . '_ext_localconf.php';
01457                 $files[] = PATH_typo3conf . $cacheFilePrefix . '_ext_tables.php';
01458             }
01459             if (self::isCacheFilesAvailable($cacheFilePrefixFE)) {
01460                 $files[] = PATH_typo3conf . $cacheFilePrefixFE . '_ext_localconf.php';
01461                 $files[] = PATH_typo3conf . $cacheFilePrefixFE . '_ext_tables.php';
01462             }
01463             if (!empty($files)) {
01464                 return $files;
01465             }
01466         }
01467     }
01468 
01469     /**
01470      * Compiles/Creates the two cache-files in typo3conf/ based on $cacheFilePrefix
01471      * Returns a array with the key "_CACHEFILE" set to the $cacheFilePrefix value
01472      * Usage: 1
01473      *
01474      * @param   array       Extension information array
01475      * @param   string      Prefix for the cache files
01476      * @return  array
01477      * @internal
01478      */
01479     public static function writeCacheFiles($extensions, $cacheFilePrefix) {
01480             // Making cache files:
01481         $extensions['_CACHEFILE'] = $cacheFilePrefix;
01482         $cFiles = array();
01483         $cFiles['ext_localconf'] .= '<?php
01484 
01485 $TYPO3_LOADED_EXT = unserialize(stripslashes(\'' . addslashes(serialize($extensions)) . '\'));
01486 
01487 ?>';
01488 
01489         foreach ($extensions as $key => $conf) {
01490             if (is_array($conf)) {
01491                 if ($conf['ext_localconf.php']) {
01492                     $cFiles['ext_localconf'] .= self::_makeIncludeHeader($key, $conf['ext_localconf.php']);
01493                     $cFiles['ext_localconf'] .= trim(t3lib_div::getUrl($conf['ext_localconf.php']));
01494                 }
01495                 if ($conf['ext_tables.php']) {
01496                     $cFiles['ext_tables'] .= self::_makeIncludeHeader($key, $conf['ext_tables.php']);
01497                     $cFiles['ext_tables'] .= trim(t3lib_div::getUrl($conf['ext_tables.php']));
01498                 }
01499             }
01500         }
01501 
01502         $cFiles['ext_localconf'] = "<?php\n" . preg_replace('/<\?php|\?>/is', '', $cFiles['ext_localconf']) . "?>\n";
01503         $cFiles['ext_tables'] = "<?php\n" . preg_replace('/<\?php|\?>/is', '', $cFiles['ext_tables']) . "?>\n";
01504 
01505         t3lib_div::writeFile(PATH_typo3conf . $cacheFilePrefix . '_ext_localconf.php', $cFiles['ext_localconf']);
01506         t3lib_div::writeFile(PATH_typo3conf . $cacheFilePrefix . '_ext_tables.php', $cFiles['ext_tables']);
01507 
01508         $extensions = array();
01509         $extensions['_CACHEFILE'] = $cacheFilePrefix;
01510 
01511         return $extensions;
01512     }
01513 
01514     /**
01515      * Unlink (delete) cache files
01516      *
01517      * @param string $cacheFilePrefix Cache file prefix to be used (optional)
01518      * @return  integer     Number of deleted files.
01519      */
01520     public static function removeCacheFiles($cacheFilePrefix = NULL) {
01521         $cacheFiles = self::currentCacheFiles($cacheFilePrefix);
01522 
01523         $out = 0;
01524         if (is_array($cacheFiles)) {
01525             reset($cacheFiles);
01526             foreach ($cacheFiles as $cfile) {
01527                 @unlink($cfile);
01528                 clearstatcache();
01529                 $out++;
01530             }
01531         }
01532         return $out;
01533     }
01534 
01535     /**
01536      * Gets the behaviour for caching ext_tables.php and ext_localconf.php files
01537      * (see $TYPO3_CONF_VARS['EXT']['extCache'] setting in the install tool).
01538      *
01539      * @param boolean $usePlainValue Whether to use the value as it is without modifications
01540      * @return integer
01541      */
01542     public static function getExtensionCacheBehaviour($usePlainValue = FALSE) {
01543         $extensionCacheBehaviour = intval($GLOBALS['TYPO3_CONF_VARS']['EXT']['extCache']);
01544 
01545             // Caching of extensions is disabled when install tool is used:
01546         if (!$usePlainValue && defined('TYPO3_enterInstallScript') && TYPO3_enterInstallScript) {
01547             $extensionCacheBehaviour = 0;
01548         }
01549 
01550         return $extensionCacheBehaviour;
01551     }
01552 
01553     /**
01554      * Gets the prefix used for the ext_tables.php and ext_localconf.php cached files.
01555      *
01556      * @return string
01557      */
01558     public static function getCacheFilePrefix() {
01559         $extensionCacheBehaviour = self::getExtensionCacheBehaviour(TRUE);
01560 
01561         $cacheFileSuffix = (TYPO3_MODE == 'FE' ? '_FE' : '');
01562         $cacheFilePrefix = 'temp_CACHED' . $cacheFileSuffix;
01563 
01564         if ($extensionCacheBehaviour == 1) {
01565             $cacheFilePrefix .= '_ps' . substr(t3lib_div::shortMD5(PATH_site . '|' . $GLOBALS['TYPO_VERSION']), 0, 4);
01566         } elseif ($extensionCacheBehaviour == 2) {
01567             $cacheFilePrefix .= '_' . t3lib_div::shortMD5(self::getEnabledExtensionList());
01568         }
01569 
01570         return $cacheFilePrefix;
01571     }
01572 
01573     /**
01574      * Gets the list of enabled extensions for the accordant context (frontend or backend).
01575      *
01576      * @return string
01577      */
01578     public static function getEnabledExtensionList() {
01579             // Select mode how to load extensions in order to speed up the FE
01580         if (TYPO3_MODE == 'FE') {
01581             if (!($extLoadInContext = $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList_FE'])) {
01582                     // fall back to standard 'extList' if 'extList_FE' is not (yet) set
01583                 $extLoadInContext = $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList'];
01584             }
01585         } else {
01586             $extLoadInContext = $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList'];
01587         }
01588 
01589         $extensionList = self::getRequiredExtensionList() . ',' . $extLoadInContext;
01590         $ignoredExtensionList = self::getIgnoredExtensionList();
01591 
01592             // Remove the extensions to be ignored:
01593         if ($ignoredExtensionList && (defined('TYPO3_enterInstallScript') && TYPO3_enterInstallScript) === FALSE) {
01594             $extensions = array_diff(
01595                 explode(',', $extensionList),
01596                 explode(',', $ignoredExtensionList)
01597             );
01598             $extensionList = implode(',', $extensions);
01599         }
01600 
01601         return $extensionList;
01602     }
01603 
01604     /**
01605      * Gets the list of required extensions.
01606      *
01607      * @return string
01608      */
01609     public static function getRequiredExtensionList() {
01610         $requiredExtensionList = t3lib_div::uniqueList(
01611             REQUIRED_EXTENSIONS . ',' . $GLOBALS['TYPO3_CONF_VARS']['EXT']['requiredExt']
01612         );
01613 
01614         return $requiredExtensionList;
01615     }
01616 
01617     /**
01618      * Gets the list of extensions to be ignored (not to be loaded).
01619      *
01620      * @return string
01621      */
01622     public static function getIgnoredExtensionList() {
01623         $ignoredExtensionList = t3lib_div::uniqueList(
01624             $GLOBALS['TYPO3_CONF_VARS']['EXT']['ignoredExt']
01625         );
01626 
01627         return $ignoredExtensionList;
01628     }
01629 }
01630 
01631 ?>