class.t3lib_extmgm.php

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

Generated on Sat Jul 24 04:17:17 2010 for TYPO3 API by  doxygen 1.4.7