Added feature #5610: Extend TCEFORM_confObj on Page TSconfig by property keepItems
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / layout / db_new_content_el.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2008 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 * New content elements wizard
29 * (Part of the 'cms' extension)
30 *
31 * $Id$
32 * Revised for TYPO3 3.6 November/2003 by Kasper Skaarhoj
33 * XHTML compatible.
34 *
35 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
36 */
37 /**
38 * [CLASS/FUNCTION INDEX of SCRIPT]
39 *
40 *
41 *
42 * 101: class ext_posMap extends t3lib_positionMap
43 * 111: function wrapRecordTitle($str,$row)
44 * 125: function onClickInsertRecord($row,$vv,$moveUid,$pid,$sys_lang=0)
45 *
46 *
47 * 153: class SC_db_new_content_el
48 * 176: function init()
49 * 212: function main()
50 * 359: function printContent()
51 *
52 * SECTION: OTHER FUNCTIONS:
53 * 388: function getWizardItems()
54 * 398: function wizardArray()
55 * 549: function removeInvalidElements(&$wizardItems)
56 *
57 * TOTAL FUNCTIONS: 8
58 * (This index is automatically created/updated by the extension "extdeveval")
59 *
60 */
61
62
63 unset($MCONF);
64 require('conf.php');
65 require($BACK_PATH.'init.php');
66 require($BACK_PATH.'template.php');
67
68 // Unset MCONF/MLANG since all we wanted was back path etc. for this particular script.
69 unset($MCONF);
70 unset($MLANG);
71
72 // Merging locallang files/arrays:
73 $LANG->includeLLFile('EXT:lang/locallang_misc.xml');
74 $LOCAL_LANG_orig = $LOCAL_LANG;
75 $LANG->includeLLFile('EXT:cms/layout/locallang_db_new_content_el.xml');
76 $LOCAL_LANG = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG_orig,$LOCAL_LANG);
77
78 // Exits if 'cms' extension is not loaded:
79 t3lib_extMgm::isLoaded('cms',1);
80
81 // Include needed libraries:
82 require_once(PATH_t3lib.'class.t3lib_page.php');
83 require_once(PATH_t3lib.'class.t3lib_positionmap.php');
84
85
86
87
88
89
90
91
92
93
94 /**
95 * Local position map class
96 *
97 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
98 * @package TYPO3
99 * @subpackage core
100 */
101 class ext_posMap extends t3lib_positionMap {
102 var $dontPrintPageInsertIcons = 1;
103
104 /**
105 * Wrapping the title of the record - here we just return it.
106 *
107 * @param string The title value.
108 * @param array The record row.
109 * @return string Wrapped title string.
110 */
111 function wrapRecordTitle($str,$row) {
112 return $str;
113 }
114
115 /**
116 * Create on-click event value.
117 *
118 * @param array The record.
119 * @param string Column position value.
120 * @param integer Move uid
121 * @param integer PID value.
122 * @param integer System language
123 * @return string
124 */
125 function onClickInsertRecord($row,$vv,$moveUid,$pid,$sys_lang=0) {
126 $table='tt_content';
127
128 $location=$this->backPath.'alt_doc.php?edit[tt_content]['.(is_array($row)?-$row['uid']:$pid).']=new&defVals[tt_content][colPos]='.$vv.'&defVals[tt_content][sys_language_uid]='.$sys_lang.'&returnUrl='.rawurlencode($GLOBALS['SOBE']->R_URI);
129
130 return 'window.location.href=\''.$location.'\'+document.editForm.defValues.value; return false;';
131 }
132 }
133
134
135
136
137
138
139
140
141
142
143
144
145
146 /**
147 * Script Class for the New Content element wizard
148 *
149 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
150 * @package TYPO3
151 * @subpackage core
152 */
153 class SC_db_new_content_el {
154
155 // Internal, static (from GPvars):
156 var $id; // Page id
157 var $sys_language=0; // Sys language
158 var $R_URI=''; // Return URL.
159 var $colPos; // If set, the content is destined for a specific column.
160 var $uid_pid; //
161
162 // Internal, static:
163 var $modTSconfig=array(); // Module TSconfig.
164
165 /**
166 * Internal backend template object
167 *
168 * @var mediumDoc
169 */
170 var $doc;
171
172 // Internal, dynamic:
173 var $include_once = array(); // Includes a list of files to include between init() and main() - see init()
174 var $content; // Used to accumulate the content of the module.
175 var $access; // Access boolean.
176
177 /**
178 * Constructor, initializing internal variables.
179 *
180 * @return void
181 */
182 function init() {
183 global $BE_USER,$BACK_PATH,$TBE_MODULES_EXT;
184
185 // Setting class files to include:
186 if (is_array($TBE_MODULES_EXT['xMOD_db_new_content_el']['addElClasses'])) {
187 $this->include_once = array_merge($this->include_once,$TBE_MODULES_EXT['xMOD_db_new_content_el']['addElClasses']);
188 }
189
190 // Setting internal vars:
191 $this->id = intval(t3lib_div::_GP('id'));
192 $this->sys_language = intval(t3lib_div::_GP('sys_language_uid'));
193 $this->R_URI = t3lib_div::_GP('returnUrl');
194 $this->colPos = t3lib_div::_GP('colPos');
195 $this->uid_pid = intval(t3lib_div::_GP('uid_pid'));
196
197 $this->MCONF['name'] = 'xMOD_db_new_content_el';
198 $this->modTSconfig = t3lib_BEfunc::getModTSconfig($this->id,'mod.'.$this->MCONF['name']);
199
200 // Starting the document template object:
201 $this->doc = t3lib_div::makeInstance('template');
202 $this->doc->backPath = $BACK_PATH;
203 $this->doc->setModuleTemplate('templates/db_new_content_el.html');
204 $this->doc->JScode='';
205 $this->doc->form='<form action="" name="editForm"><input type="hidden" name="defValues" value="" />';
206
207 // Setting up the context sensitive menu:
208 $this->doc->getContextMenuCode();
209
210 // Getting the current page and receiving access information (used in main())
211 $perms_clause = $BE_USER->getPagePermsClause(1);
212 $this->pageinfo = t3lib_BEfunc::readPageAccess($this->id,$perms_clause);
213 $this->access = is_array($this->pageinfo) ? 1 : 0;
214 }
215
216 /**
217 * Creating the module output.
218 *
219 * @return void
220 */
221 function main() {
222 global $LANG,$BACK_PATH;
223
224 if ($this->id && $this->access) {
225
226 // Init position map object:
227 $posMap = t3lib_div::makeInstance('ext_posMap');
228 $posMap->cur_sys_language = $this->sys_language;
229 $posMap->backPath = $BACK_PATH;
230
231 if ((string)$this->colPos!='') { // If a column is pre-set:
232 if ($this->uid_pid<0) {
233 $row=array();
234 $row['uid']=abs($this->uid_pid);
235 } else {
236 $row='';
237 }
238 $onClickEvent = $posMap->onClickInsertRecord($row,$this->colPos,'',$this->uid_pid,$this->sys_language);
239 } else {
240 $onClickEvent='';
241 }
242
243 $this->doc->JScode=$this->doc->wrapScriptTags('
244 function goToalt_doc() { //
245 '.$onClickEvent.'
246 }
247 ');
248
249
250 // ***************************
251 // Creating content
252 // ***************************
253 $this->content='';
254 $this->content.=$this->doc->header($LANG->getLL('newContentElement'));
255 $this->content.=$this->doc->spacer(5);
256
257 // Wizard
258 $code='';
259 $lines=array();
260 $wizardItems = $this->getWizardItems();
261
262 // Traverse items for the wizard.
263 // An item is either a header or an item rendered with a radio button and title/description and icon:
264 $cc=0;
265 foreach ($wizardItems as $k => $wInfo) {
266 if ($wInfo['header']) {
267 if ($cc>0) $lines[]='
268 <tr>
269 <td colspan="3"><br /></td>
270 </tr>';
271 $lines[]='
272 <tr class="bgColor5">
273 <td colspan="3"><strong>'.htmlspecialchars($wInfo['header']).'</strong></td>
274 </tr>';
275 } else {
276 $tL=array();
277
278 // Radio button:
279 $oC = "document.editForm.defValues.value=unescape('".rawurlencode($wInfo['params'])."');goToalt_doc();".(!$onClickEvent?"window.location.hash='#sel2';":'');
280 $tL[]='<input type="radio" name="tempB" value="'.htmlspecialchars($k).'" onclick="'.htmlspecialchars($this->doc->thisBlur().$oC).'" />';
281
282 // Onclick action for icon/title:
283 $aOnClick = 'document.getElementsByName(\'tempB\')['.$cc.'].checked=1;'.$this->doc->thisBlur().$oC.'return false;';
284
285 // Icon:
286 $iInfo = @getimagesize($wInfo['icon']);
287 $tL[]='<a href="#" onclick="'.htmlspecialchars($aOnClick).'"><img'.t3lib_iconWorks::skinImg($this->doc->backPath,$wInfo['icon'],'').' alt="" /></a>';
288
289 // Title + description:
290 $tL[]='<a href="#" onclick="'.htmlspecialchars($aOnClick).'"><strong>'.htmlspecialchars($wInfo['title']).'</strong><br />'.nl2br(htmlspecialchars(trim($wInfo['description']))).'</a>';
291
292 // Finally, put it together in a table row:
293 $lines[]='
294 <tr>
295 <td valign="top">'.implode('</td>
296 <td valign="top">',$tL).'</td>
297 </tr>';
298 $cc++;
299 }
300 }
301 // Add the wizard table to the content:
302 $code.=$LANG->getLL('sel1',1).'<br /><br />
303
304
305 <!--
306 Content Element wizard table:
307 -->
308 <table border="0" cellpadding="1" cellspacing="2" id="typo3-ceWizardTable">
309 '.implode('',$lines).'
310 </table>';
311 $this->content.= $this->doc->section(!$onClickEvent?$LANG->getLL('1_selectType'):'',$code,0,1);
312
313
314
315 // If the user must also select a column:
316 if (!$onClickEvent) {
317
318 // Add anchor "sel2"
319 $this->content.= $this->doc->section('','<a name="sel2"></a>');
320 $this->content.= $this->doc->spacer(20);
321
322 // Select position
323 $code = $LANG->getLL('sel2',1).'<br /><br />';
324
325 // Load SHARED page-TSconfig settings and retrieve column list from there, if applicable:
326 $modTSconfig_SHARED = t3lib_BEfunc::getModTSconfig($this->id,'mod.SHARED');
327 $colPosList = strcmp(trim($modTSconfig_SHARED['properties']['colPos_list']),'') ? trim($modTSconfig_SHARED['properties']['colPos_list']) : '1,0,2,3';
328 $colPosList = implode(',',array_unique(t3lib_div::intExplode(',',$colPosList))); // Removing duplicates, if any
329
330 // Finally, add the content of the column selector to the content:
331 $code.= $posMap->printContentElementColumns($this->id,0,$colPosList,1,$this->R_URI);
332 $this->content.= $this->doc->section($LANG->getLL('2_selectPosition'),$code,0,1);
333 }
334 } else { // In case of no access:
335 $this->content = '';
336 $this->content.= $this->doc->header($LANG->getLL('newContentElement'));
337 $this->content.= $this->doc->spacer(5);
338 }
339
340 // Setting up the buttons and markers for docheader
341 $docHeaderButtons = $this->getButtons();
342 $markers['CSH'] = $docHeaderButtons['csh'];
343 $markers['CONTENT'] = $this->content;
344
345 // Build the <body> for the module
346 $this->content = $this->doc->startPage($LANG->getLL('newContentElement'));
347 $this->content.= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
348 $this->content.= $this->doc->endPage();
349 $this->content = $this->doc->insertStylesAndJS($this->content);
350 }
351
352 /**
353 * Print out the accumulated content:
354 *
355 * @return void
356 */
357 function printContent() {
358 echo $this->content;
359 }
360
361 /**
362 * Create the panel of buttons for submitting the form or otherwise perform operations.
363 *
364 * @return array all available buttons as an assoc. array
365 */
366 protected function getButtons() {
367 global $LANG, $BACK_PATH;
368
369 $buttons = array(
370 'csh' => '',
371 'back' => ''
372 );
373
374
375 if ($this->id && $this->access) {
376 // CSH
377 $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'new_ce', $GLOBALS['BACK_PATH'], '', TRUE);
378
379 // Back
380 if ($this->R_URI) {
381 $buttons['back'] = '<a href="' . htmlspecialchars($this->R_URI) . '" class="typo3-goBack">' .
382 '<img' . t3lib_iconWorks::skinImg($this->doc->backPath, 'gfx/goback.gif') . ' alt="" title="' . $LANG->getLL('goBack', 1) . '" />' .
383 '</a>';
384 }
385 }
386
387
388 return $buttons;
389 }
390
391
392
393
394
395
396
397
398
399 /***************************
400 *
401 * OTHER FUNCTIONS:
402 *
403 ***************************/
404
405
406 /**
407 * Returns the content of wizardArray() function...
408 *
409 * @return array Returns the content of wizardArray() function...
410 */
411 function getWizardItems() {
412 return $this->wizardArray();
413 }
414
415 /**
416 * Returns the array of elements in the wizard display.
417 * For the plugin section there is support for adding elements there from a global variable.
418 *
419 * @return array
420 */
421 function wizardArray() {
422 global $LANG,$TBE_MODULES_EXT;
423
424 $wizardItems = array(
425 'common' => array('header'=>$LANG->getLL('common')),
426 'common_regularText' => array( // Regular text element
427 'icon'=>'gfx/c_wiz/regular_text.gif',
428 'title'=>$LANG->getLL('common_regularText_title'),
429 'description'=>$LANG->getLL('common_regularText_description'),
430 'tt_content_defValues' => array(
431 'CType' => 'text'
432 )
433 ),
434 'common_textImage' => array( // Text with image
435 'icon'=>'gfx/c_wiz/text_image_right.gif',
436 'title'=>$LANG->getLL('common_textImage_title'),
437 'description'=>$LANG->getLL('common_textImage_description'),
438 'tt_content_defValues' => array(
439 'CType' => 'textpic',
440 'imageorient' => 17
441 )
442 ),
443 'common_imagesOnly' => array( // Images only
444 'icon'=>'gfx/c_wiz/images_only.gif',
445 'title'=>$LANG->getLL('common_imagesOnly_title'),
446 'description'=>$LANG->getLL('common_imagesOnly_description'),
447 'tt_content_defValues' => array(
448 'CType' => 'image',
449 'imagecols' => 2
450 )
451 ),
452 'common_bulletList' => array( // Bullet list
453 'icon'=>'gfx/c_wiz/bullet_list.gif',
454 'title'=>$LANG->getLL('common_bulletList_title'),
455 'description'=>$LANG->getLL('common_bulletList_description'),
456 'tt_content_defValues' => array(
457 'CType' => 'bullets',
458 )
459 ),
460 'common_table' => array( // Table
461 'icon'=>'gfx/c_wiz/table.gif',
462 'title'=>$LANG->getLL('common_table_title'),
463 'description'=>$LANG->getLL('common_table_description'),
464 'tt_content_defValues' => array(
465 'CType' => 'table',
466 )
467 ),
468 'special' => array('header'=>$LANG->getLL('special')),
469 'special_filelinks' => array( // Filelinks
470 'icon'=>'gfx/c_wiz/filelinks.gif',
471 'title'=>$LANG->getLL('special_filelinks_title'),
472 'description'=>$LANG->getLL('special_filelinks_description'),
473 'tt_content_defValues' => array(
474 'CType' => 'uploads',
475 )
476 ),
477 'special_multimedia' => array( // Multimedia
478 'icon'=>'gfx/c_wiz/multimedia.gif',
479 'title'=>$LANG->getLL('special_multimedia_title'),
480 'description'=>$LANG->getLL('special_multimedia_description'),
481 'tt_content_defValues' => array(
482 'CType' => 'multimedia',
483 )
484 ),
485 'special_sitemap' => array( // Sitemap
486 'icon'=>'gfx/c_wiz/sitemap2.gif',
487 'title'=>$LANG->getLL('special_sitemap_title'),
488 'description'=>$LANG->getLL('special_sitemap_description'),
489 'tt_content_defValues' => array(
490 'CType' => 'menu',
491 'menu_type' => 2
492 )
493 ),
494 'special_plainHTML' => array( // Plain HTML
495 'icon'=>'gfx/c_wiz/html.gif',
496 'title'=>$LANG->getLL('special_plainHTML_title'),
497 'description'=>$LANG->getLL('special_plainHTML_description'),
498 'tt_content_defValues' => array(
499 'CType' => 'html',
500 )
501 ),
502 'forms' => array('header'=>$LANG->getLL('forms')),
503 'forms_mail' => array( // Mail form
504 'icon'=>'gfx/c_wiz/mailform.gif',
505 'title'=>$LANG->getLL('forms_mail_title'),
506 'description'=>$LANG->getLL('forms_mail_description'),
507 'tt_content_defValues' => array(
508 'CType' => 'mailform',
509 'bodytext' => trim('
510 # Example content:
511 Name: | *name = input,40 | Enter your name here
512 Email: | *email=input,40 |
513 Address: | address=textarea,40,5 |
514 Contact me: | tv=check | 1
515
516 |formtype_mail = submit | Send form!
517 |html_enabled=hidden | 1
518 |subject=hidden| This is the subject
519 ')
520 )
521 ),
522 'forms_search' => array( // Search form
523 'icon'=>'gfx/c_wiz/searchform.gif',
524 'title'=>$LANG->getLL('forms_search_title'),
525 'description'=>$LANG->getLL('forms_search_description'),
526 'tt_content_defValues' => array(
527 'CType' => 'search',
528 )
529 ),
530 'forms_login' => array( // Login form
531 'icon'=>'gfx/c_wiz/login_form.gif',
532 'title'=>$LANG->getLL('forms_login_title'),
533 'description'=>$LANG->getLL('forms_login_description'),
534 'tt_content_defValues' => array(
535 'CType' => 'login',
536 )
537 ),
538 'plugins' => array('header'=>$LANG->getLL('plugins')),
539 'plugins_general' => array( // General plugin
540 'icon'=>'gfx/c_wiz/user_defined.gif',
541 'title'=>$LANG->getLL('plugins_general_title'),
542 'description'=>$LANG->getLL('plugins_general_description'),
543 'tt_content_defValues' => array(
544 'CType' => 'list',
545 )
546 ),
547 );
548
549
550 // PLUG-INS:
551 if (is_array($TBE_MODULES_EXT['xMOD_db_new_content_el']['addElClasses'])) {
552 reset($TBE_MODULES_EXT['xMOD_db_new_content_el']['addElClasses']);
553 while(list($class,$path)=each($TBE_MODULES_EXT['xMOD_db_new_content_el']['addElClasses'])) {
554 $modObj = t3lib_div::makeInstance($class);
555 $wizardItems = $modObj->proc($wizardItems);
556 }
557 }
558
559 // Remove elements where preset values are not allowed:
560 $this->removeInvalidElements($wizardItems);
561
562 return $wizardItems;
563 }
564
565 /**
566 * Checks the array for elements which might contain unallowed default values and will unset them!
567 * Looks for the "tt_content_defValues" key in each element and if found it will traverse that array as fieldname / value pairs and check. The values will be added to the "params" key of the array (which should probably be unset or empty by default).
568 *
569 * @param array Wizard items, passed by reference
570 * @return void
571 */
572 function removeInvalidElements(&$wizardItems) {
573 global $TCA;
574
575 // Load full table definition:
576 t3lib_div::loadTCA('tt_content');
577
578 // Get TCEFORM from TSconfig of current page
579 $row = array('pid' => $this->id);
580 $TCEFORM_TSconfig = t3lib_BEfunc::getTCEFORM_TSconfig('tt_content', $row);
581 $removeItems = t3lib_div::trimExplode(',', $TCEFORM_TSconfig['CType']['removeItems'], 1);
582 $keepItems = t3lib_div::trimExplode(',', $TCEFORM_TSconfig['CType']['keepItems'], 1);
583
584 $headersUsed = Array();
585 // Traverse wizard items:
586 foreach($wizardItems as $key => $cfg) {
587
588 // Exploding parameter string, if any (old style)
589 if ($wizardItems[$key]['params']) {
590 // Explode GET vars recursively
591 $tempGetVars = t3lib_div::explodeUrl2Array($wizardItems[$key]['params'],TRUE);
592 // If tt_content values are set, merge them into the tt_content_defValues array, unset them from $tempGetVars and re-implode $tempGetVars into the param string (in case remaining parameters are around).
593 if (is_array($tempGetVars['defVals']['tt_content'])) {
594 $wizardItems[$key]['tt_content_defValues'] = array_merge(is_array($wizardItems[$key]['tt_content_defValues']) ? $wizardItems[$key]['tt_content_defValues'] : array(), $tempGetVars['defVals']['tt_content']);
595 unset($tempGetVars['defVals']['tt_content']);
596 $wizardItems[$key]['params'] = t3lib_div::implodeArrayForUrl('',$tempGetVars);
597 }
598 }
599
600 // If tt_content_defValues are defined...:
601 if (is_array($wizardItems[$key]['tt_content_defValues'])) {
602
603 // Traverse field values:
604 foreach($wizardItems[$key]['tt_content_defValues'] as $fN => $fV) {
605 if (is_array($TCA['tt_content']['columns'][$fN])) {
606 // Get information about if the field value is OK:
607 $config = &$TCA['tt_content']['columns'][$fN]['config'];
608 $authModeDeny = ($config['type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode('tt_content', $fN, $fV, $config['authMode']));
609 $isNotInKeepItems = (count($keepItems) && !in_array($fV, $keepItems));
610
611 if ($authModeDeny || ($fN=='CType' && in_array($fV,$removeItems)) || $isNotInKeepItems) {
612 // Remove element all together:
613 unset($wizardItems[$key]);
614 break;
615 } else {
616 // Add the parameter:
617 $wizardItems[$key]['params'].= '&defVals[tt_content]['.$fN.']='.rawurlencode($fV);
618 $tmp = explode('_', $key);
619 $headersUsed[$tmp[0]] = $tmp[0];
620 }
621 }
622 }
623 }
624 }
625 // remove headers without elements
626 foreach ($wizardItems as $key => $cfg) {
627 $tmp = explode('_',$key);
628 if ($tmp[0] && !$tmp[1] && !in_array($tmp[0], $headersUsed)) {
629 unset($wizardItems[$key]);
630 }
631 }
632 }
633 }
634
635
636 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cms/layout/db_new_content_el.php']) {
637 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cms/layout/db_new_content_el.php']);
638 }
639
640
641
642 // Make instance:
643 $SOBE = t3lib_div::makeInstance('SC_db_new_content_el');
644 $SOBE->init();
645
646 // Include files?
647 foreach($SOBE->include_once as $INC_FILE) include_once($INC_FILE);
648
649 $SOBE->main();
650 $SOBE->printContent();
651
652 ?>