*** empty log message ***
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_extmgm.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Contains a class with Extension Management functions
29 *
30 * $Id$
31 * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
32 *
33 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
34 */
35 /**
36 * [CLASS/FUNCTION INDEX of SCRIPT]
37 *
38 *
39 *
40 * 113: class t3lib_extMgm
41 *
42 * SECTION: PATHS and other evaluation
43 * 130: function isLoaded($key,$exitOnError=0)
44 * 146: function extPath($key,$script='')
45 * 164: function extRelPath($key)
46 * 181: function siteRelPath($key)
47 * 193: function getCN($key)
48 *
49 * SECTION: Adding BACKEND features
50 * 226: function addTCAcolumns($table,$columnArray,$addTofeInterface=0)
51 * 250: function addToAllTCAtypes($table,$str,$specificTypesList='',$position='')
52 * 312: function allowTableOnStandardPages($table)
53 * 329: function addModule($main,$sub='',$position='',$path='')
54 * 391: function insertModuleFunction($modname,$className,$classPath,$title,$MM_key='function')
55 * 409: function addPageTSConfig($content)
56 * 423: function addUserTSConfig($content)
57 * 438: function addLLrefForTCAdescr($tca_descr_key,$file_ref)
58 *
59 * SECTION: Adding SERVICES features
60 * 480: function addService($extKey, $serviceType, $serviceKey, $info)
61 * 545: function findService($serviceType, $serviceSubType='', $excludeServiceKeys=array())
62 * 616: function deactivateService($serviceType, $serviceKey)
63 *
64 * SECTION: Adding FRONTEND features
65 * 655: function addPlugin($itemArray,$type='list_type')
66 * 680: function addPiFlexFormValue($piKeyToMatch,$value)
67 * 700: function addToInsertRecords($table,$content_table='tt_content',$content_field='records')
68 * 731: function addPItoST43($key,$classFile='',$prefix='',$type='list_type',$cached=0)
69 * 806: function addStaticFile($extKey,$path,$title)
70 * 825: function addTypoScriptSetup($content)
71 * 839: function addTypoScriptConstants($content)
72 * 856: function addTypoScript($key,$type,$content,$afterStaticUid=0)
73 *
74 * SECTION: INTERNAL EXTENSION MANAGEMENT:
75 * 919: function typo3_loadExtensions()
76 * 998: function _makeIncludeHeader($key,$file)
77 * 1019: function isCacheFilesAvailable($cacheFilePrefix)
78 * 1032: function isLocalconfWritable()
79 * 1045: function cannotCacheFilesWritable($cacheFilePrefix)
80 * 1069: function currentCacheFiles()
81 * 1092: function writeCacheFiles($extensions,$cacheFilePrefix)
82 *
83 * TOTAL FUNCTIONS: 31
84 * (This index is automatically created/updated by the extension "extdeveval")
85 *
86 */
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 /**
104 * Extension Management functions
105 *
106 * This class is never instantiated, rather the methods inside is called as functions like
107 * t3lib_extMgm::isLoaded('my_extension');
108 *
109 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
110 * @package TYPO3
111 * @subpackage t3lib
112 */
113 class t3lib_extMgm {
114
115
116 /**************************************
117 *
118 * PATHS and other evaluation
119 *
120 ***************************************/
121
122 /**
123 * Returns true if the extension with extension key $key is loaded.
124 * Usage: 109
125 *
126 * @param string Extension key to test
127 * @param boolean If $exitOnError is true and the extension is not loaded the function will die with an error message
128 * @return boolean
129 */
130 function isLoaded($key,$exitOnError=0) {
131 global $TYPO3_LOADED_EXT;
132 if ($exitOnError && !isset($TYPO3_LOADED_EXT[$key])) die('Fatal Error: Extension "'.$key.'" was not loaded.');
133 return isset($TYPO3_LOADED_EXT[$key]);
134 }
135
136 /**
137 * Returns the absolute path to the extension with extension key $key
138 * If the extension is not loaded the function will die with an error message
139 * Useful for internal fileoperations
140 * Usage: 136
141 *
142 * @param string Extension key
143 * @param string $script is appended to the output if set.
144 * @return string
145 */
146 function extPath($key,$script='') {
147 global $TYPO3_LOADED_EXT;
148 if (!isset($TYPO3_LOADED_EXT[$key])) {
149 #debug(array(debug_backtrace()));
150 die('TYPO3 Fatal Error: Extension key "'.$key.'" was NOT loaded! (t3lib_extMgm::extPath)');
151 }
152 return PATH_site.$TYPO3_LOADED_EXT[$key]['siteRelPath'].$script;
153 }
154
155 /**
156 * Returns the relative path to the extension as measured from from the TYPO3_mainDir
157 * If the extension is not loaded the function will die with an error message
158 * Useful for images and links from backend
159 * Usage: 54
160 *
161 * @param string Extension key
162 * @return string
163 */
164 function extRelPath($key) {
165 global $TYPO3_LOADED_EXT;
166 if (!isset($TYPO3_LOADED_EXT[$key])) {
167 die('TYPO3 Fatal Error: Extension key "'.$key.'" was NOT loaded! (t3lib_extMgm::extRelPath)');
168 }
169 return $TYPO3_LOADED_EXT[$key]['typo3RelPath'];
170 }
171
172 /**
173 * Returns the relative path to the extension as measured from the PATH_site (frontend)
174 * If the extension is not loaded the function will die with an error message
175 * Useful for images and links from the frontend
176 * Usage: 6
177 *
178 * @param string Extension key
179 * @return string
180 */
181 function siteRelPath($key) {
182 return substr(t3lib_extMgm::extPath($key),strlen(PATH_site));
183 }
184
185 /**
186 * Returns the correct class name prefix for the extension key $key
187 * Usage: 3
188 *
189 * @param string Extension key
190 * @return string
191 * @internal
192 */
193 function getCN($key) {
194 return substr($key,0,5)=='user_' ? 'user_'.str_replace('_','',substr($key,5)) : 'tx_'.str_replace('_','',$key);
195 }
196
197
198
199
200
201
202
203
204
205
206 /**************************************
207 *
208 * Adding BACKEND features
209 * (related to core features)
210 *
211 ***************************************/
212
213 /**
214 * Adding fields to an existing table definition in $TCA
215 * Adds an array with $TCA column-configuration to the $TCA-entry for that table.
216 * 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!
217 * So to have the fields displayed you must also call fx. addToAllTCAtypes or manually add the fields to the types list.
218 * FOR USE IN ext_tables.php FILES
219 * Usage: 4
220 *
221 * @param string $table is the table name of a table already present in $TCA with a columns section
222 * @param array $columnArray is the array with the additional columns (typical some fields an extension wants to add)
223 * @param boolean If $addTofeInterface is true the list of fields are also added to the fe_admin_fieldList.
224 * @return void
225 */
226 function addTCAcolumns($table,$columnArray,$addTofeInterface=0) {
227 global $TCA;
228 t3lib_div::loadTCA($table);
229 if (is_array($columnArray) && is_array($TCA[$table]) && is_array($TCA[$table]['columns'])) {
230 $TCA[$table]['columns'] = array_merge($TCA[$table]['columns'],$columnArray); // Candidate for t3lib_div::array_merge() if integer-keys will some day make trouble...
231 if ($addTofeInterface) $TCA[$table]['feInterface']['fe_admin_fieldList'].=','.implode(',',array_keys($columnArray));
232 }
233 }
234
235 /**
236 * Makes fields visible in the TCEforms, adding them to the end of (all) "types"-configurations
237 *
238 * Adds a string $str (comma list of field names) to all ["types"][xxx]["showitem"] entries for table $table (unless limited by $specificTypesList)
239 * This is needed to have new fields shown automatically in the TCEFORMS of a record from $table.
240 * Typically this function is called after having added new columns (database fields) with the addTCAcolumns function
241 * FOR USE IN ext_tables.php FILES
242 * Usage: 1
243 *
244 * @param string Table name
245 * @param string Field list to add.
246 * @param string List of specific types to add the field list to. (If empty, all type entries are affected)
247 * @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.
248 * @return void
249 */
250 function addToAllTCAtypes($table,$str,$specificTypesList='',$position='') {
251 global $TCA;
252
253 $positionArr=t3lib_div::trimExplode(',',$position,1);
254 $insert=count($position);
255
256 t3lib_div::loadTCA($table);
257 if (trim($str) && is_array($TCA[$table]) && is_array($TCA[$table]['types'])) {
258 foreach($TCA[$table]['types'] as $k => $v) {
259 if (!$specificTypesList || t3lib_div::inList($specificTypesList,$k)) {
260 if ($insert) {
261 $append=true;
262 $showItem = t3lib_div::trimExplode(',',$TCA[$table]['types'][$k]['showitem'],1);
263 foreach($showItem as $key => $fieldInfo) {
264
265 $parts = explode(';',$fieldInfo);
266 $theField = trim($parts[0]);
267 $palette = trim($parts[0]).';;'.trim($parts[2]);
268
269 // insert before: find exact field name or palette with number
270 if (in_array($theField, $positionArr) || in_array($palette, $positionArr) || in_array('before:'.$theField, $positionArr) || in_array('before:'.$palette, $positionArr)) {
271 $showItem[$key]=trim($str).', '.$fieldInfo;
272 $append=false;
273 break;
274 }
275 // insert after
276 if (in_array('after:'.$theField, $positionArr) || in_array('after:'.$palette, $positionArr)) {
277 $showItem[$key]=$fieldInfo.', '.trim($str);
278 $append=false;
279 break;
280 }
281 }
282
283 // Not found? Then append.
284 if($append) {
285 $showItem[]=trim($str);
286 }
287
288 $TCA[$table]['types'][$k]['showitem']=implode(', ', $showItem);
289
290 } else {
291 $TCA[$table]['types'][$k]['showitem'].=', '.trim($str);
292 }
293 }
294 }
295 }
296 }
297
298
299 /**
300 * Add tablename to default list of allowed tables on pages (in $PAGES_TYPES)
301 * Will add the $table to the list of tables allowed by default on pages as setup by $PAGES_TYPES['default']['allowedTables']
302 * FOR USE IN ext_tables.php FILES
303 * Usage: 11
304 *
305 * @param string Table name
306 * @return void
307 */
308 function allowTableOnStandardPages($table) {
309 global $PAGES_TYPES;
310
311 $PAGES_TYPES['default']['allowedTables'].=','.$table;
312 }
313
314 /**
315 * Adds a module (main or sub) to the backend interface
316 * FOR USE IN ext_tables.php FILES
317 * Usage: 18
318 *
319 * @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.
320 * @param string $sub is the submodule key. If $sub is not set a blank $main module is created.
321 * @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.
322 * @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.
323 * @return void
324 */
325 function addModule($main,$sub='',$position='',$path='') {
326 global $TBE_MODULES;
327
328 if (isset($TBE_MODULES[$main]) && $sub) { // If there is already a main module by this name:
329
330 // Adding the submodule to the correct position:
331 list($place,$modRef)=t3lib_div::trimExplode(':',$position,1);
332 $mods = t3lib_div::trimExplode(',',$TBE_MODULES[$main],1);
333 if (!in_array($sub,$mods)) {
334 switch(strtolower($place)) {
335 case 'after':
336 case 'before':
337 $pointer=0;
338 reset($mods);
339 while(list($k,$m)=each($mods)) {
340 if (!strcmp($m,$modRef)) {
341 $pointer=strtolower($place)=='after'?$k+1:$k;
342 }
343 }
344 array_splice(
345 $mods, // The modules array
346 $pointer, // To insert one position from the end of the list
347 0, // Don't remove any items, just insert
348 $sub // Module to insert
349 );
350 break;
351 default:
352 if (strtolower($place)=='top') {
353 array_unshift($mods,$sub);
354 } else {
355 array_push($mods,$sub);
356 }
357 break;
358 }
359 }
360 // Re-inserting the submodule list:
361 $TBE_MODULES[$main]=implode(',',$mods);
362 } else { // Create new main modules with only one submodule, $sub (or none if $sub is blank)
363 $TBE_MODULES[$main]=$sub;
364 }
365
366 // Adding path:
367 if ($path) {
368 $TBE_MODULES['_PATHS'][$main.($sub?'_'.$sub:'')]=$path;
369 }
370 }
371
372 /**
373 * Adds a "Function menu module" ('third level module') to an existing function menu for some other backend module
374 * The arguments values are generally determined by which function menu this is supposed to interact with
375 * See Inside TYPO3 for information on how to use this function.
376 * FOR USE IN ext_tables.php FILES
377 * Usage: 26
378 *
379 * @param string Module name
380 * @param string Class name
381 * @param string Class path
382 * @param string Title of module
383 * @param string Menu array key - default is "function"
384 * @param string Workspace conditions. Blank means all workspaces, any other string can be a comma list of "online", "offline" and "custom"
385 * @return void
386 * @see t3lib_SCbase::mergeExternalItems()
387 */
388 function insertModuleFunction($modname,$className,$classPath,$title,$MM_key='function',$WS='') {
389 global $TBE_MODULES_EXT;
390 $TBE_MODULES_EXT[$modname]['MOD_MENU'][$MM_key][$className]=array(
391 'name' => $className,
392 'path' => $classPath,
393 'title' => $title,
394 'ws' => $WS
395 );
396 }
397
398 /**
399 * Adds $content to the default Page TSconfig as set in $TYPO3_CONF_VARS[BE]['defaultPageTSconfig']
400 * Prefixed with a [GLOBAL] line
401 * FOR USE IN ext_tables.php/ext_locallang.php FILES
402 * Usage: 5
403 *
404 * @param string Page TSconfig content
405 * @return void
406 */
407 function addPageTSConfig($content) {
408 global $TYPO3_CONF_VARS;
409 $TYPO3_CONF_VARS['BE']['defaultPageTSconfig'].="\n[GLOBAL]\n".$content;
410 }
411
412 /**
413 * Adds $content to the default User TSconfig as set in $TYPO3_CONF_VARS[BE]['defaultUserTSconfig']
414 * Prefixed with a [GLOBAL] line
415 * FOR USE IN ext_tables.php/ext_locallang.php FILES
416 * Usage: 3
417 *
418 * @param string User TSconfig content
419 * @return void
420 */
421 function addUserTSConfig($content) {
422 global $TYPO3_CONF_VARS;
423 $TYPO3_CONF_VARS['BE']['defaultUserTSconfig'].="\n[GLOBAL]\n".$content;
424 }
425
426 /**
427 * Adds a reference to a locallang file with TCA_DESCR labels
428 * FOR USE IN ext_tables.php FILES
429 * 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.
430 * Usage: 31
431 *
432 * @param string Description key. Typically a database table (like "pages") but for applications can be other strings, but prefixed with "_MOD_")
433 * @param string File reference to locallang file, eg. "EXT:lang/locallang_csh_pages.php" (or ".xml")
434 * @return void
435 */
436 function addLLrefForTCAdescr($tca_descr_key,$file_ref) {
437 global $TCA_DESCR;
438 if ($tca_descr_key) {
439 if (!is_array($TCA_DESCR[$tca_descr_key])) {
440 $TCA_DESCR[$tca_descr_key]=array();
441 }
442 if (!is_array($TCA_DESCR[$tca_descr_key]['refs'])) {
443 $TCA_DESCR[$tca_descr_key]['refs']=array();
444 }
445 $TCA_DESCR[$tca_descr_key]['refs'][]=$file_ref;
446 }
447 }
448
449
450
451
452
453
454
455
456
457
458
459
460 /**************************************
461 *
462 * Adding SERVICES features
463 *
464 * @author René Fritz <r.fritz@colorcube.de>
465 *
466 ***************************************/
467
468 /**
469 * Adds a service to the global services array
470 *
471 * @param string Extension key
472 * @param string Service type, cannot be prefixed "tx_"
473 * @param string Service key, must be prefixed "tx_" or "user_"
474 * @param array Service description array
475 * @return void
476 * @author René Fritz <r.fritz@colorcube.de>
477 */
478 function addService($extKey, $serviceType, $serviceKey, $info) {
479 global $T3_SERVICES,$TYPO3_CONF_VARS;
480
481 // even not available services will be included to make it possible to give the admin a feedback of non-available services.
482 // but maybe it's better to move non-available services to a different array??
483
484 if ($serviceType AND
485 !t3lib_div::isFirstPartOfStr($serviceType, 'tx_') AND
486 (t3lib_div::isFirstPartOfStr($serviceKey, 'tx_') OR t3lib_div::isFirstPartOfStr($serviceKey, 'user_')) AND
487 is_array($info)) {
488
489 $info['priority'] = max(0,min(100,$info['priority']));
490
491 $T3_SERVICES[$serviceType][$serviceKey]=$info;
492
493 $T3_SERVICES[$serviceType][$serviceKey]['extKey'] = $extKey;
494 $T3_SERVICES[$serviceType][$serviceKey]['serviceKey'] = $serviceKey;
495 $T3_SERVICES[$serviceType][$serviceKey]['serviceType'] = $serviceType;
496
497
498 // mapping a service key to a service type
499 // all service keys begin with tx_ - service types don't
500 // this way a selection of a special service key as service type is easy
501 $T3_SERVICES[$serviceKey][$serviceKey] = &$T3_SERVICES[$serviceType][$serviceKey];
502
503
504 // change the priority (and other values) from TYPO3_CONF_VARS
505 // $TYPO3_CONF_VARS['T3_SERVICES'][$serviceType][$serviceKey]['priority']
506 // even the activation is possible (a unix service might be possible on windows for some reasons)
507 if (is_array($TYPO3_CONF_VARS['T3_SERVICES'][$serviceType][$serviceKey])) {
508
509 // no check is done here - there might be configuration values only the service type knows about, so we pass everything
510 $T3_SERVICES[$serviceType][$serviceKey] = array_merge ($T3_SERVICES[$serviceType][$serviceKey],$TYPO3_CONF_VARS['T3_SERVICES'][$serviceType][$serviceKey]);
511 }
512
513
514 // OS check
515 // empty $os means 'not limited to one OS', therefore a check is not needed
516 if ($T3_SERVICES[$serviceType][$serviceKey]['available'] AND $T3_SERVICES[$serviceType][$serviceKey]['os']!='') {
517
518 // TYPO3_OS is not yet defined
519 $os_type = stristr(PHP_OS,'win')&&!stristr(PHP_OS,'darwin')?'WIN':'UNIX';
520
521 $os = t3lib_div::trimExplode(',',strtoupper($T3_SERVICES[$serviceType][$serviceKey]['os']));
522
523 if (!in_array($os_type,$os)) {
524 t3lib_extMgm::deactivateService($serviceType, $serviceKey);
525 }
526 }
527
528 // convert subtype list to array for quicker access
529 $T3_SERVICES[$serviceType][$serviceKey]['serviceSubTypes'] = array();
530 $serviceSubTypes = t3lib_div::trimExplode(',',$info['subtype']);
531 foreach ($serviceSubTypes as $subtype) {
532 $T3_SERVICES[$serviceType][$serviceKey]['serviceSubTypes'][$subtype] = $subtype;
533 }
534 }
535 }
536
537 /**
538 * Find the available service with highest priority
539 *
540 * @param string Service type
541 * @param string Service sub type
542 * @param mixed Service keys that should be excluded in the search for a service. Array or comma list.
543 * @return mixed Service info array if a service was found, FLASE otherwise
544 * @author René Fritz <r.fritz@colorcube.de>
545 */
546 function findService($serviceType, $serviceSubType='', $excludeServiceKeys=array()) {
547 global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
548
549 $serviceKey = FALSE;
550 $serviceInfo = FALSE;
551 $priority = 0;
552 $quality = 0;
553
554 if (!is_array($excludeServiceKeys) ) {
555 $excludeServiceKeys = t3lib_div::trimExplode(',', $excludeServiceKeys, 1);
556 }
557
558 if (is_array($T3_SERVICES[$serviceType])) {
559 foreach($T3_SERVICES[$serviceType] as $key => $info) {
560
561 if (in_array($key, $excludeServiceKeys)) {
562 continue;
563 }
564
565 // select a subtype randomly
566 // usefull to start a service by service key without knowing his subtypes - for testing purposes
567 if ($serviceSubType=='*') {
568 $serviceSubType = key($info['serviceSubTypes']);
569 }
570
571 // this matches empty subtype too
572 if( $info['available'] AND ($info['subtype']==$serviceSubType OR $info['serviceSubTypes'][$serviceSubType]) AND $info['priority']>=$priority ) {
573
574 // has a lower quality than the already found, therefore we skip this service
575 if($info['priority']==$priority AND $info['quality']<$quality) {
576 continue;
577 }
578
579 // service depends on external programs - check if they exists
580 if(trim($info['exec'])) {
581 require_once(PATH_t3lib.'class.t3lib_exec.php');
582
583 $executables = t3lib_div::trimExplode(',', $info['exec'],1);
584 foreach($executables as $executable) {
585 if(!t3lib_exec::checkCommand($executable)) {
586 t3lib_extMgm::deactivateService($serviceType, $key);
587 $info['available']=FALSE;
588 break;
589 }
590 }
591 }
592
593 // still available after exec check?
594 if($info['available']) {
595 $serviceKey = $key;
596 $priority = $info['priority'];
597 $quality = $info['quality'];
598 }
599 }
600 }
601 }
602
603 if ($serviceKey) {
604 $serviceInfo = $T3_SERVICES[$serviceType][$serviceKey];
605 }
606 return $serviceInfo;
607 }
608
609 /**
610 * Deactivate a service
611 *
612 * @param string Service type
613 * @param string Service key
614 * @return void
615 * @author René Fritz <r.fritz@colorcube.de>
616 */
617 function deactivateService($serviceType, $serviceKey) {
618 global $T3_SERVICES;
619
620 // ... maybe it's better to move non-available services to a different array??
621 $T3_SERVICES[$serviceType][$serviceKey]['available'] = FALSE;
622 }
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637 /**************************************
638 *
639 * Adding FRONTEND features
640 * (related specifically to "cms" extension)
641 *
642 ***************************************/
643
644 /**
645 * Adds an entry to the list of plugins in content elements of type "Insert plugin"
646 * 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)
647 * 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.
648 * 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
649 * FOR USE IN ext_tables.php FILES
650 * Usage: 13
651 *
652 * @param array Item Array
653 * @param string Type (eg. "list_type") - basically a field from "tt_content" table
654 * @return void
655 */
656 function addPlugin($itemArray,$type='list_type') {
657 global $TCA;
658 t3lib_div::loadTCA('tt_content');
659 if (is_array($TCA['tt_content']['columns']) && is_array($TCA['tt_content']['columns'][$type]['config']['items'])) {
660 reset($TCA['tt_content']['columns'][$type]['config']['items']);
661 while(list($k,$v)=each($TCA['tt_content']['columns'][$type]['config']['items'])) {
662 if (!strcmp($v[1],$itemArray[1])) {
663 $TCA['tt_content']['columns'][$type]['config']['items'][$k]=$itemArray;
664 return;
665 }
666 }
667 $TCA['tt_content']['columns'][$type]['config']['items'][]=$itemArray;
668 }
669 }
670
671 /**
672 * Adds an entry to the "ds" array of the tt_content field "pi_flexform".
673 * This is used by plugins to add a flexform XML reference / content for use when they are selected as plugin.
674 * Usage: 0
675 *
676 * @param string The same value as the key for the plugin
677 * @param string Either a reference to a flex-form XML file (eg. "FILE:EXT:newloginbox/flexform_ds.xml") or the XML directly.
678 * @return void
679 * @see addPlugin()
680 */
681 function addPiFlexFormValue($piKeyToMatch,$value) {
682 global $TCA;
683 t3lib_div::loadTCA('tt_content');
684
685 if (is_array($TCA['tt_content']['columns']) && is_array($TCA['tt_content']['columns']['pi_flexform']['config']['ds'])) {
686 $TCA['tt_content']['columns']['pi_flexform']['config']['ds'][$piKeyToMatch] = $value;
687 }
688 }
689
690 /**
691 * Adds the $table tablename to the list of tables allowed to be includes by content element type "Insert records"
692 * By using $content_table and $content_field you can also use the function for other tables.
693 * FOR USE IN ext_tables.php FILES
694 * Usage: 9
695 *
696 * @param string Table name to allow for "insert record"
697 * @param string Table name TO WHICH the $table name is applied. See $content_field as well.
698 * @param string Field name in the database $content_table in which $table is allowed to be added as a reference ("Insert Record")
699 * @return void
700 */
701 function addToInsertRecords($table,$content_table='tt_content',$content_field='records') {
702 global $TCA;
703 t3lib_div::loadTCA($content_table);
704 if (is_array($TCA[$content_table]['columns']) && isset($TCA[$content_table]['columns'][$content_field]['config']['allowed'])) {
705 $TCA[$content_table]['columns'][$content_field]['config']['allowed'].=','.$table;
706 }
707 }
708
709 /**
710 * Add PlugIn to Static Template #43
711 *
712 * 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.
713 * 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"
714 * $type determines the type of frontend plugin:
715 * "list_type" (default) - the good old "Insert plugin" entry
716 * "menu_type" - a "Menu/Sitemap" entry
717 * "splash_layout" - a "Textbox" entry
718 * "CType" - a new content element type
719 * "header_layout" - an additional header type (added to the selection of layout1-5)
720 * "includeLib" - just includes the library for manual use somewhere in TypoScript.
721 * (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)
722 * FOR USE IN ext_locallang.php FILES
723 * Usage: 2
724 *
725 * @param string $key is the extension key
726 * @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.
727 * @param string $prefix is used as a - yes, suffix - of the class name (fx. "_pi1")
728 * @param string $type, see description above
729 * @param boolean If $cached is set as USER content object (cObject) is created - otherwise a USER_INT object is created.
730 * @return void
731 */
732 function addPItoST43($key,$classFile='',$prefix='',$type='list_type',$cached=0) {
733 global $TYPO3_LOADED_EXT;
734 $classFile = $classFile ? $classFile : 'pi/class.tx_'.str_replace('_','',$key).$prefix.'.php';
735 $cN = t3lib_extMgm::getCN($key);
736
737 // General plugin:
738 if ($cached) {
739 $pluginContent = trim('
740 includeLibs.'.$cN.$prefix.' = '.$TYPO3_LOADED_EXT[$key]['siteRelPath'].$classFile.'
741 plugin.'.$cN.$prefix.' = USER
742 plugin.'.$cN.$prefix.' {
743 userFunc = '.$cN.$prefix.'->main
744 }');
745 } else {
746 $pluginContent = trim('
747 plugin.'.$cN.$prefix.' = USER_INT
748 plugin.'.$cN.$prefix.' {
749 includeLibs = '.$TYPO3_LOADED_EXT[$key]['siteRelPath'].$classFile.'
750 userFunc = '.$cN.$prefix.'->main
751 }');
752 }
753 t3lib_extMgm::addTypoScript($key,'setup','
754 # Setting '.$key.' plugin TypoScript
755 '.$pluginContent);
756
757 // After ST43:
758 switch($type) {
759 case 'list_type':
760 $addLine = 'tt_content.list.20.'.$key.$prefix.' = < plugin.'.$cN.$prefix;
761 break;
762 case 'menu_type':
763 $addLine = 'tt_content.menu.20.'.$key.$prefix.' = < plugin.'.$cN.$prefix;
764 break;
765 case 'splash_layout':
766 $addLine = 'tt_content.splash.'.$key.$prefix.' = < plugin.'.$cN.$prefix;
767 break;
768 case 'CType':
769 $addLine = trim('
770 tt_content.'.$key.$prefix.' = COA
771 tt_content.'.$key.$prefix.' {
772 10 = < lib.stdheader
773 20 = < plugin.'.$cN.$prefix.'
774 }
775 ');
776 break;
777 case 'header_layout':
778 $addLine = 'lib.stdheader.10.'.$key.$prefix.' = < plugin.'.$cN.$prefix;
779 break;
780 case 'includeLib':
781 $addLine = 'page.1000 = < plugin.'.$cN.$prefix;
782 break;
783 default:
784 $addLine = '';
785 break;
786 }
787 if ($addLine) {
788 t3lib_extMgm::addTypoScript($key,'setup','
789 # Setting '.$key.' plugin TypoScript
790 '.$addLine.'
791 ',43);
792 }
793 }
794
795 /**
796 * Call this method to add an entry in the static template list found in sys_templates
797 * "static template files" are the modern equalent (provided from extensions) to the traditional records in "static_templates"
798 * FOR USE IN ext_locallang.php FILES
799 * Usage: 3
800 *
801 * @param string $extKey is of course the extension key
802 * @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/
803 * @param string $title is the title in the selector box.
804 * @return void
805 * @see addTypoScript()
806 */
807 function addStaticFile($extKey,$path,$title) {
808 global $TCA;
809 t3lib_div::loadTCA('sys_template');
810 if ($extKey && $path && is_array($TCA['sys_template']['columns'])) {
811 $value = str_replace(',','','EXT:'.$extKey.'/'.$path);
812 $itemArray=array(trim($title.' ('.$extKey.')'),$value);
813 $TCA['sys_template']['columns']['include_static_file']['config']['items'][]=$itemArray;
814 }
815 }
816
817 /**
818 * Adds $content to the default TypoScript setup code as set in $TYPO3_CONF_VARS[FE]['defaultTypoScript_setup']
819 * Prefixed with a [GLOBAL] line
820 * FOR USE IN ext_locallang.php FILES
821 * Usage: 6
822 *
823 * @param string TypoScript Setup string
824 * @return void
825 */
826 function addTypoScriptSetup($content) {
827 global $TYPO3_CONF_VARS;
828 $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup'].="\n[GLOBAL]\n".$content;
829 }
830
831 /**
832 * Adds $content to the default TypoScript constants code as set in $TYPO3_CONF_VARS[FE]['defaultTypoScript_constants']
833 * Prefixed with a [GLOBAL] line
834 * FOR USE IN ext_locallang.php FILES
835 * Usage: 0
836 *
837 * @param string TypoScript Constants string
838 * @return void
839 */
840 function addTypoScriptConstants($content) {
841 global $TYPO3_CONF_VARS;
842 $TYPO3_CONF_VARS['FE']['defaultTypoScript_constants'].="\n[GLOBAL]\n".$content;
843 }
844
845 /**
846 * Adds $content to the default TypoScript code for either setup, constants or editorcfg as set in $TYPO3_CONF_VARS[FE]['defaultTypoScript_*']
847 * (Basically this function can do the same as addTypoScriptSetup and addTypoScriptConstants - just with a little more hazzle, but also with some more options!)
848 * FOR USE IN ext_locallang.php FILES
849 * Usage: 7
850 *
851 * @param string $key is the extension key (informative only).
852 * @param string $type is either "setup", "constants" or "editorcfg" and obviously determines which kind of TypoScript code we are adding.
853 * @param string $content is the TS content, prefixed with a [GLOBAL] line and a comment-header.
854 * @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.
855 * @return void
856 */
857 function addTypoScript($key,$type,$content,$afterStaticUid=0) {
858 global $TYPO3_CONF_VARS;
859
860 if ($type=='setup' || $type=='editorcfg' || $type=='constants') {
861 $content = '
862
863 [GLOBAL]
864 #############################################
865 ## TypoScript added by extension "'.$key.'"
866 #############################################
867
868 '.$content;
869 if ($afterStaticUid) {
870 $TYPO3_CONF_VARS['FE']['defaultTypoScript_'.$type.'.'][$afterStaticUid].=$content;
871 if ($afterStaticUid==43) { // If 'content (default)' is targeted, also add to other 'content rendering templates', eg. css_styled_content
872 $TYPO3_CONF_VARS['FE']['defaultTypoScript_'.$type.'.']['cssstyledcontent/static/'].=$content;
873 }
874 } else {
875 $TYPO3_CONF_VARS['FE']['defaultTypoScript_'.$type].=$content;
876 }
877 }
878 }
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897 /**************************************
898 *
899 * INTERNAL EXTENSION MANAGEMENT:
900 *
901 ***************************************/
902
903 /**
904 * Loading extensions configured in $TYPO3_CONF_VARS['EXT']['extList']
905 *
906 * CACHING ON: ($TYPO3_CONF_VARS['EXT']['extCache'] = 1 or 2)
907 * 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.
908 * If cachefiles are not found they will be generated
909 * CACHING OFF: ($TYPO3_CONF_VARS['EXT']['extCache'] = 0)
910 * 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.
911 * This array will later be set in the global var $TYPO3_LOADED_EXT
912 *
913 * Usages of this function can be seen in config_default.php
914 * Extensions are always detected in the order local - global - system.
915 * Usage: 1
916 *
917 * @return array Extension Array
918 * @internal
919 */
920 function typo3_loadExtensions() {
921 global $TYPO3_CONF_VARS;
922
923 // Full list of extensions includes both required and extList:
924 $rawExtList = $TYPO3_CONF_VARS['EXT']['requiredExt'].','.$TYPO3_CONF_VARS['EXT']['extList'];
925
926 // Empty array as a start.
927 $extensions = array();
928
929 //
930 if ($rawExtList) {
931 // The cached File prefix.
932 $cacheFilePrefix = 'temp_CACHED';
933 // Setting the name for the cache files:
934 if (intval($TYPO3_CONF_VARS['EXT']['extCache'])==1) $cacheFilePrefix.= '_ps'.substr(t3lib_div::shortMD5(PATH_site.'|'.$GLOBALS['TYPO_VERSION']),0,4);
935 if (intval($TYPO3_CONF_VARS['EXT']['extCache'])==2) $cacheFilePrefix.= '_'.t3lib_div::shortMD5($rawExtList);
936
937 // If cache files available, set cache file prefix and return:
938 if ($TYPO3_CONF_VARS['EXT']['extCache'] && t3lib_extMgm::isCacheFilesAvailable($cacheFilePrefix)) {
939 // Return cache file prefix:
940 $extensions['_CACHEFILE'] = $cacheFilePrefix;
941 } else { // ... but if not, configure...
942 // Prepare reserved filenames:
943 $files = t3lib_div::trimExplode(',','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',1);
944
945 // Traverse extensions and check their existence:
946 clearstatcache(); // Clear file state cache to make sure we get good results from is_dir()
947 $temp_extensions = array_unique(t3lib_div::trimExplode(',',$rawExtList,1));
948 foreach($temp_extensions as $temp_extKey) {
949 // Check local, global and system locations:
950 if (@is_dir(PATH_site.'typo3conf/ext/'.$temp_extKey.'/')) {
951 $extensions[$temp_extKey] = array('type'=>'L', 'siteRelPath'=>'typo3conf/ext/'.$temp_extKey.'/', 'typo3RelPath'=>'../typo3conf/ext/'.$temp_extKey.'/');
952 } elseif (@is_dir(PATH_site.TYPO3_mainDir.'ext/'.$temp_extKey.'/')) {
953 $extensions[$temp_extKey] = array('type'=>'G', 'siteRelPath'=>TYPO3_mainDir.'ext/'.$temp_extKey.'/', 'typo3RelPath'=>'ext/'.$temp_extKey.'/');
954 } elseif (@is_dir(PATH_site.TYPO3_mainDir.'sysext/'.$temp_extKey.'/')) {
955 $extensions[$temp_extKey] = array('type'=>'S', 'siteRelPath'=>TYPO3_mainDir.'sysext/'.$temp_extKey.'/', 'typo3RelPath'=>'sysext/'.$temp_extKey.'/');
956 }
957
958 // If extension was found, check for reserved filenames:
959 if (isset($extensions[$temp_extKey])) {
960 foreach($files as $fName) {
961 $temp_filename = PATH_site.$extensions[$temp_extKey]['siteRelPath'].trim($fName);
962 if (is_array($extensions[$temp_extKey]) && @is_file($temp_filename)) {
963 $extensions[$temp_extKey][$fName] = $temp_filename;
964 }
965 }
966 }
967 }
968 unset($extensions['_CACHEFILE']);
969
970 // write cache?
971 if ($TYPO3_CONF_VARS['EXT']['extCache'] &&
972 @is_dir(PATH_site.TYPO3_mainDir.'sysext/') &&
973 @is_dir(PATH_site.TYPO3_mainDir.'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!
974 $wrError = t3lib_extMgm::cannotCacheFilesWritable($cacheFilePrefix);
975 if ($wrError) {
976 $TYPO3_CONF_VARS['EXT']['extCache']=0;
977 } else {
978 // Write cache files:
979 $extensions = t3lib_extMgm::writeCacheFiles($extensions,$cacheFilePrefix);
980 }
981 }
982 }
983 }
984
985 return $extensions;
986 }
987
988 /**
989 * Returns the section headers for the compiled cache-files.
990 *
991 * @param string $key is the extension key
992 * @param string $file is the filename (only informative for comment)
993 * @return string
994 * @internal
995 */
996 function _makeIncludeHeader($key,$file) {
997 return '<?php
998 ###########################
999 ## EXTENSION: '.$key.'
1000 ## FILE: '.$file.'
1001 ###########################
1002
1003 $_EXTKEY = \''.$key.'\';
1004 $_EXTCONF = $TYPO3_CONF_VARS[\'EXT\'][\'extConf\'][$_EXTKEY];
1005
1006 ?>';
1007 }
1008
1009 /**
1010 * Returns true if both the localconf and tables cache file exists (with $cacheFilePrefix)
1011 * Usage: 2
1012 *
1013 * @param string Prefix of the cache file to check
1014 * @return boolean
1015 * @internal
1016 */
1017 function isCacheFilesAvailable($cacheFilePrefix) {
1018 return
1019 @is_file(PATH_typo3conf.$cacheFilePrefix.'_ext_localconf.php') &&
1020 @is_file(PATH_typo3conf.$cacheFilePrefix.'_ext_tables.php');
1021 }
1022
1023 /**
1024 * Returns true if the "localconf.php" file in "typo3conf/" is writable
1025 * Usage: 1
1026 *
1027 * @return boolean
1028 * @internal
1029 */
1030 function isLocalconfWritable() {
1031 return @is_writable(PATH_typo3conf) && @is_writable(PATH_typo3conf.'localconf.php');
1032 }
1033
1034 /**
1035 * Returns an error string if typo3conf/ or cache-files with $cacheFilePrefix are NOT writable
1036 * Returns false if no problem.
1037 * Usage: 1
1038 *
1039 * @param string Prefix of the cache file to check
1040 * @return string
1041 * @internal
1042 */
1043 function cannotCacheFilesWritable($cacheFilePrefix) {
1044 $error=array();
1045 if (!@is_writable(PATH_typo3conf)) {
1046 $error[]=PATH_typo3conf;
1047 }
1048 if (@is_file(PATH_typo3conf.$cacheFilePrefix.'_ext_localconf.php') &&
1049 !@is_writable(PATH_typo3conf.$cacheFilePrefix.'_ext_localconf.php')) {
1050 $error[]=PATH_typo3conf.$cacheFilePrefix.'_ext_localconf.php';
1051 }
1052 if (@is_file(PATH_typo3conf.$cacheFilePrefix.'_ext_tables.php') &&
1053 !@is_writable(PATH_typo3conf.$cacheFilePrefix.'_ext_tables.php')) {
1054 $error[]=PATH_typo3conf.$cacheFilePrefix.'_ext_tables.php';
1055 }
1056 return implode(', ',$error);
1057 }
1058
1059 /**
1060 * Returns an array with the two cache-files (0=>localconf, 1=>tables) from typo3conf/ if they (both) exist. Otherwise false.
1061 * Evaluation relies on $TYPO3_LOADED_EXT['_CACHEFILE']
1062 * Usage: 2
1063 *
1064 * @return array
1065 * @internal
1066 */
1067 function currentCacheFiles() {
1068 global $TYPO3_LOADED_EXT;
1069
1070 if ($TYPO3_LOADED_EXT['_CACHEFILE']) {
1071 if (t3lib_extMgm::isCacheFilesAvailable($TYPO3_LOADED_EXT['_CACHEFILE'])) {
1072 return array(
1073 PATH_typo3conf.$TYPO3_LOADED_EXT['_CACHEFILE'].'_ext_localconf.php',
1074 PATH_typo3conf.$TYPO3_LOADED_EXT['_CACHEFILE'].'_ext_tables.php'
1075 );
1076 }
1077 }
1078 }
1079
1080 /**
1081 * Compiles/Creates the two cache-files in typo3conf/ based on $cacheFilePrefix
1082 * Returns a array with the key "_CACHEFILE" set to the $cacheFilePrefix value
1083 * Usage: 1
1084 *
1085 * @param array Extension information array
1086 * @param string Prefix for the cache files
1087 * @return array
1088 * @internal
1089 */
1090 function writeCacheFiles($extensions,$cacheFilePrefix) {
1091 // Making cache files:
1092 $extensions['_CACHEFILE'] = $cacheFilePrefix;
1093 $cFiles=array();
1094 $cFiles['ext_localconf'].='<?php
1095
1096 $TYPO3_LOADED_EXT = unserialize(stripslashes(\''.addslashes(serialize($extensions)).'\'));
1097
1098 ?>';
1099
1100 reset($extensions);
1101 while(list($key,$conf)=each($extensions)) {
1102 if (is_array($conf)) {
1103 if ($conf['ext_localconf.php']) {
1104 $cFiles['ext_localconf'].=t3lib_extMgm::_makeIncludeHeader($key,$conf['ext_localconf.php']);
1105 $cFiles['ext_localconf'].=trim(t3lib_div::getUrl($conf['ext_localconf.php']));
1106 }
1107 if ($conf['ext_tables.php']) {
1108 $cFiles['ext_tables'].=t3lib_extMgm::_makeIncludeHeader($key,$conf['ext_tables.php']);
1109 $cFiles['ext_tables'].=trim(t3lib_div::getUrl($conf['ext_tables.php']));
1110 }
1111 }
1112 }
1113
1114 t3lib_div::writeFile(PATH_typo3conf.$cacheFilePrefix.'_ext_localconf.php',$cFiles['ext_localconf']);
1115 t3lib_div::writeFile(PATH_typo3conf.$cacheFilePrefix.'_ext_tables.php',$cFiles['ext_tables']);
1116
1117 $extensions=array();
1118 $extensions['_CACHEFILE'] = $cacheFilePrefix;
1119
1120 return $extensions;
1121 }
1122 }
1123
1124 ?>