TYPO3 CMS  TYPO3_6-2
NewContentElementController.php
Go to the documentation of this file.
1 <?php
3 
20 
27 
28  // Internal, static (from GPvars):
29  // Page id
33  public $id;
34 
35  // Sys language
39  public $sys_language = 0;
40 
41  // Return URL.
45  public $R_URI = '';
46 
47  // If set, the content is destined for a specific column.
51  public $colPos;
52 
56  public $uid_pid;
57 
58  // Internal, static:
59  // Module TSconfig.
63  public $modTSconfig = array();
64 
71  public $doc;
72 
73  // Internal, dynamic:
74  // Includes a list of files to include between init() and main() - see init()
78  public $include_once = array();
79 
80  // Used to accumulate the content of the module.
84  public $content;
85 
86  // Access boolean.
90  public $access;
91 
92  // config of the wizard
96  public $config;
97 
104  public function init() {
105  // Setting class files to include:
106  if (is_array($GLOBALS['TBE_MODULES_EXT']['xMOD_db_new_content_el']['addElClasses'])) {
107  $this->include_once = array_merge($this->include_once, $GLOBALS['TBE_MODULES_EXT']['xMOD_db_new_content_el']['addElClasses']);
108  }
109  // Setting internal vars:
110  $this->id = (int)GeneralUtility::_GP('id');
111  $this->sys_language = (int)GeneralUtility::_GP('sys_language_uid');
112  $this->R_URI = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl'));
113  $this->colPos = GeneralUtility::_GP('colPos') === NULL ? NULL : (int)GeneralUtility::_GP('colPos');
114  $this->uid_pid = (int)GeneralUtility::_GP('uid_pid');
115  $this->MCONF['name'] = 'xMOD_db_new_content_el';
116  $this->modTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.wizards.newContentElement');
118  $this->config = $config['mod.']['wizards.']['newContentElement.'];
119  // Starting the document template object:
120  $this->doc = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
121  $this->doc->backPath = $GLOBALS['BACK_PATH'];
122  $this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/db_new_content_el.html');
123  $this->doc->JScode = '';
124  $this->doc->form = '<form action="" name="editForm"><input type="hidden" name="defValues" value="" />';
125  // Setting up the context sensitive menu:
126  $this->doc->getContextMenuCode();
127  // Getting the current page and receiving access information (used in main())
128  $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
129  $this->pageinfo = BackendUtility::readPageAccess($this->id, $perms_clause);
130  $this->access = is_array($this->pageinfo) ? 1 : 0;
131  }
132 
139  public function main() {
140  if ($this->id && $this->access) {
141  // Init position map object:
142  $posMap = GeneralUtility::makeInstance('ext_posMap');
143  $posMap->cur_sys_language = $this->sys_language;
144  $posMap->backPath = $GLOBALS['BACK_PATH'];
145  // If a column is pre-set:
146  if (isset($this->colPos)) {
147  if ($this->uid_pid < 0) {
148  $row = array();
149  $row['uid'] = abs($this->uid_pid);
150  } else {
151  $row = '';
152  }
153  $this->onClickEvent = $posMap->onClickInsertRecord($row, $this->colPos, '', $this->uid_pid, $this->sys_language);
154  } else {
155  $this->onClickEvent = '';
156  }
157  // ***************************
158  // Creating content
159  // ***************************
160  // use a wrapper div
161  $this->content .= '<div id="user-setup-wrapper">';
162  $this->content .= $this->doc->header($GLOBALS['LANG']->getLL('newContentElement'));
163  $this->content .= $this->doc->spacer(5);
164  // Wizard
165  $code = '';
166  $wizardItems = $this->getWizardItems();
167  // Wrapper for wizards
168  $this->elementWrapper['section'] = array('<ul class="contentelement-wizard list-unstyled">', '</ul>');
169  // Copy wrapper for tabs
170  $this->elementWrapperForTabs = $this->elementWrapper;
171  // Hook for manipulating wizardItems, wrapper, onClickEvent etc.
172  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms']['db_new_content_el']['wizardItemsHook'])) {
173  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms']['db_new_content_el']['wizardItemsHook'] as $classData) {
174  $hookObject = GeneralUtility::getUserObj($classData);
175  if (!$hookObject instanceof \TYPO3\CMS\Backend\Wizard\NewContentElementWizardHookInterface) {
176  throw new \UnexpectedValueException('$hookObject must implement interface TYPO3\\CMS\\Backend\\Wizard\\NewContentElementWizardHookInterface', 1227834741);
177  }
178  $hookObject->manipulateWizardItems($wizardItems, $this);
179  }
180  }
181  if ($this->config['renderMode'] == 'tabs' && $this->elementWrapperForTabs != $this->elementWrapper) {
182  // Restore wrapper for tabs if they are overwritten in hook
183  $this->elementWrapper = $this->elementWrapperForTabs;
184  }
185  // Add document inline javascript
186  $this->doc->JScode = $this->doc->wrapScriptTags('
187  function goToalt_doc() { //
188  ' . $this->onClickEvent . '
189  }
190 
191  if(top.refreshMenu) {
192  top.refreshMenu();
193  } else {
194  top.TYPO3ModuleMenu.refreshMenu();
195  }
196  ');
197  // Traverse items for the wizard.
198  // An item is either a header or an item rendered with a radio button and title/description and icon:
199  $cc = ($key = 0);
200  $menuItems = array();
201  foreach ($wizardItems as $k => $wInfo) {
202  if ($wInfo['header']) {
203  $menuItems[] = array(
204  'label' => htmlspecialchars($wInfo['header']),
205  'content' => $this->elementWrapper['section'][0]
206  );
207  $key = count($menuItems) - 1;
208  } else {
209  $content = '';
210 
211  if (!$this->onClickEvent) {
212  // Radio button:
213  $oC = 'document.editForm.defValues.value=unescape(\'' . rawurlencode($wInfo['params']) . '\');goToalt_doc();' . (!$this->onClickEvent ? 'window.location.hash=\'#sel2\';' : '');
214  $content .= '<div class="contentelement-wizard-item-input"><input type="radio" name="tempB" value="' . htmlspecialchars($k) . '" onclick="' . htmlspecialchars($oC) . '" /></div>';
215  // Onclick action for icon/title:
216  $aOnClick = 'document.getElementsByName(\'tempB\')[' . $cc . '].checked=1;' . $oC . 'return false;';
217  } else {
218  $aOnClick = "document.editForm.defValues.value=unescape('".rawurlencode($wInfo['params'])."');goToalt_doc();".(!$this->onClickEvent?"window.location.hash='#sel2';":'');
219  }
220 
221  $menuItems[$key]['content'] .=
222  '<li>
223  <div class="contentelement-wizard-item">
224  ' . $content . '
225  <div class="contentelement-wizard-item-icon">
226  <a href="#" onclick="' . htmlspecialchars($aOnClick) . '">
227  <img' . IconUtility::skinImg($this->doc->backPath, $wInfo['icon'], '') . ' alt="" />
228  </a>
229  </div>
230  <div class="contentelement-wizard-item-text">
231  <a href="#" onclick="' . htmlspecialchars($aOnClick) . '">
232  <strong>' . htmlspecialchars($wInfo['title']) . '</strong>
233  <br />' . nl2br(htmlspecialchars(trim($wInfo['description']))) .
234  '</a>
235  </div>
236  </div>
237  </li>';
238  $cc++;
239  }
240  }
241  // Add closing section-tag
242  foreach ($menuItems as $key => $val) {
243  $menuItems[$key]['content'] .= $this->elementWrapper['section'][1];
244  }
245  // Add the wizard table to the content, wrapped in tabs:
246  if ($this->config['renderMode'] == 'tabs') {
247  $code = $GLOBALS['LANG']->getLL('sel1', 1) . '<br /><br />' . $this->doc->getDynTabMenu($menuItems, 'new-content-element-wizard', FALSE, FALSE);
248  } else {
249  $code = $GLOBALS['LANG']->getLL('sel1', 1) . '<br /><br />';
250  foreach ($menuItems as $section) {
251  $code .= '<h3 class="divider">' . $section['label'] . '</h3>' . $section['content'];
252  }
253  }
254  $this->content .= $this->doc->section(!$this->onClickEvent ? $GLOBALS['LANG']->getLL('1_selectType') : '', $code, 0, 1);
255  // If the user must also select a column:
256  if (!$this->onClickEvent) {
257  // Add anchor "sel2"
258  $this->content .= $this->doc->section('', '<a name="sel2"></a>');
259  $this->content .= $this->doc->spacer(20);
260  // Select position
261  $code = $GLOBALS['LANG']->getLL('sel2', 1) . '<br /><br />';
262 
263  // Load SHARED page-TSconfig settings and retrieve column list from there, if applicable:
264  $colPosArray = GeneralUtility::callUserFunction('TYPO3\\CMS\\Backend\\View\\BackendLayoutView->getColPosListItemsParsed', $this->id, $this);
265  $colPosIds = array_map(function($element){ return (int)$element[1]; }, $colPosArray);
266  // Removing duplicates, if any
267  $colPosList = implode(',', array_unique($colPosIds));
268  // Finally, add the content of the column selector to the content:
269  $code .= $posMap->printContentElementColumns($this->id, 0, $colPosList, 1, $this->R_URI);
270  $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('2_selectPosition'), $code, 0, 1);
271  }
272  // Close wrapper div
273  $this->content .= '</div>';
274  } else {
275  // In case of no access:
276  $this->content = '';
277  $this->content .= $this->doc->header($GLOBALS['LANG']->getLL('newContentElement'));
278  $this->content .= $this->doc->spacer(5);
279  }
280  // Setting up the buttons and markers for docheader
281  $docHeaderButtons = $this->getButtons();
282  $markers['CSH'] = $docHeaderButtons['csh'];
283  $markers['CONTENT'] = $this->content;
284  // Build the <body> for the module
285  $this->content = $this->doc->startPage($GLOBALS['LANG']->getLL('newContentElement'));
286  $this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
287  $this->content .= $this->doc->sectionEnd();
288  $this->content .= $this->doc->endPage();
289  $this->content = $this->doc->insertStylesAndJS($this->content);
290  }
291 
298  public function printContent() {
299  echo $this->content;
300  }
301 
307  protected function getButtons() {
308  $buttons = array(
309  'csh' => '',
310  'back' => ''
311  );
312  if ($this->id && $this->access) {
313  $buttons['csh'] = BackendUtility::cshItem('xMOD_csh_corebe', 'new_ce', $GLOBALS['BACK_PATH'], '', TRUE);
314  if ($this->R_URI) {
315  $buttons['back'] = '<a href="' . htmlspecialchars($this->R_URI) . '" class="typo3-goBack" title="' . $GLOBALS['LANG']->getLL('goBack', TRUE) . '">' . IconUtility::getSpriteIcon('actions-view-go-back') . '</a>';
316  }
317  }
318  return $buttons;
319  }
320 
321  /***************************
322  *
323  * OTHER FUNCTIONS:
324  *
325  ***************************/
332  public function getWizardItems() {
333  return $this->wizardArray();
334  }
335 
343  public function wizardArray() {
344  if (is_array($this->config)) {
345  $wizards = $this->config['wizardItems.'];
346  }
347  $appendWizards = $this->wizard_appendWizards($wizards['elements.']);
348  $wizardItems = array();
349  if (is_array($wizards)) {
350  foreach ($wizards as $groupKey => $wizardGroup) {
351  $groupKey = preg_replace('/\\.$/', '', $groupKey);
352  $showItems = GeneralUtility::trimExplode(',', $wizardGroup['show'], TRUE);
353  $showAll = in_array('*', $showItems, TRUE);
354  $groupItems = array();
355  if (is_array($appendWizards[$groupKey . '.']['elements.'])) {
356  $wizardElements = array_merge((array) $wizardGroup['elements.'], $appendWizards[$groupKey . '.']['elements.']);
357  } else {
358  $wizardElements = $wizardGroup['elements.'];
359  }
360  if (is_array($wizardElements)) {
361  foreach ($wizardElements as $itemKey => $itemConf) {
362  $itemKey = preg_replace('/\\.$/', '', $itemKey);
363  if ($showAll || in_array($itemKey, $showItems)) {
364  $tmpItem = $this->wizard_getItem($groupKey, $itemKey, $itemConf);
365  if ($tmpItem) {
366  $groupItems[$groupKey . '_' . $itemKey] = $tmpItem;
367  }
368  }
369  }
370  }
371  if (count($groupItems)) {
372  $wizardItems[$groupKey] = $this->wizard_getGroupHeader($groupKey, $wizardGroup);
373  $wizardItems = array_merge($wizardItems, $groupItems);
374  }
375  }
376  }
377  // Remove elements where preset values are not allowed:
378  $this->removeInvalidElements($wizardItems);
379  return $wizardItems;
380  }
381 
387  public function wizard_appendWizards($wizardElements) {
388  if (!is_array($wizardElements)) {
389  $wizardElements = array();
390  }
391  if (is_array($GLOBALS['TBE_MODULES_EXT']['xMOD_db_new_content_el']['addElClasses'])) {
392  foreach ($GLOBALS['TBE_MODULES_EXT']['xMOD_db_new_content_el']['addElClasses'] as $class => $path) {
393  require_once $path;
394  $modObj = GeneralUtility::makeInstance($class);
395  $wizardElements = $modObj->proc($wizardElements);
396  }
397  }
398  $returnElements = array();
399  foreach ($wizardElements as $key => $wizardItem) {
400  preg_match('/^[a-zA-Z0-9]+_/', $key, $group);
401  $wizardGroup = $group[0] ? substr($group[0], 0, -1) . '.' : $key;
402  $returnElements[$wizardGroup]['elements.'][substr($key, strlen($wizardGroup)) . '.'] = $wizardItem;
403  }
404  return $returnElements;
405  }
406 
414  public function wizard_getItem($groupKey, $itemKey, $itemConf) {
415  $itemConf['title'] = $GLOBALS['LANG']->sL($itemConf['title']);
416  $itemConf['description'] = $GLOBALS['LANG']->sL($itemConf['description']);
417  $itemConf['tt_content_defValues'] = $itemConf['tt_content_defValues.'];
418  unset($itemConf['tt_content_defValues.']);
419  return $itemConf;
420  }
421 
428  public function wizard_getGroupHeader($groupKey, $wizardGroup) {
429  return array(
430  'header' => $GLOBALS['LANG']->sL($wizardGroup['header'])
431  );
432  }
433 
442  public function removeInvalidElements(&$wizardItems) {
443  // Get TCEFORM from TSconfig of current page
444  $row = array('pid' => $this->id);
445  $TCEFORM_TSconfig = BackendUtility::getTCEFORM_TSconfig('tt_content', $row);
446  $headersUsed = array();
447  // Traverse wizard items:
448  foreach ($wizardItems as $key => $cfg) {
449  // Exploding parameter string, if any (old style)
450  if ($wizardItems[$key]['params']) {
451  // Explode GET vars recursively
452  $tempGetVars = GeneralUtility::explodeUrl2Array($wizardItems[$key]['params'], TRUE);
453  // If tt_content values are set, merge them into the tt_content_defValues array,
454  // unset them from $tempGetVars and re-implode $tempGetVars into the param string
455  // (in case remaining parameters are around).
456  if (is_array($tempGetVars['defVals']['tt_content'])) {
457  $wizardItems[$key]['tt_content_defValues'] = array_merge(
458  is_array($wizardItems[$key]['tt_content_defValues'])
459  ? $wizardItems[$key]['tt_content_defValues']
460  : array(),
461  $tempGetVars['defVals']['tt_content']
462  );
463  unset($tempGetVars['defVals']['tt_content']);
464  $wizardItems[$key]['params'] = GeneralUtility::implodeArrayForUrl('', $tempGetVars);
465  }
466  }
467  // If tt_content_defValues are defined...:
468  if (is_array($wizardItems[$key]['tt_content_defValues'])) {
469  // Traverse field values:
470  foreach ($wizardItems[$key]['tt_content_defValues'] as $fN => $fV) {
471  if (is_array($GLOBALS['TCA']['tt_content']['columns'][$fN])) {
472  // Get information about if the field value is OK:
473  $config = &$GLOBALS['TCA']['tt_content']['columns'][$fN]['config'];
474  $authModeDeny = $config['type'] == 'select' && $config['authMode']
475  && !$GLOBALS['BE_USER']->checkAuthMode('tt_content', $fN, $fV, $config['authMode']);
476  // explode TSconfig keys only as needed
477  if (!isset($removeItems[$fN])) {
478  $removeItems[$fN] = GeneralUtility::trimExplode(',', $TCEFORM_TSconfig[$fN]['removeItems'], TRUE);
479  }
480  if (!isset($keepItems[$fN])) {
481  $keepItems[$fN] = GeneralUtility::trimExplode(',', $TCEFORM_TSconfig[$fN]['keepItems'], TRUE);
482  }
483  $isNotInKeepItems = count($keepItems[$fN]) && !in_array($fV, $keepItems[$fN]);
484  if ($authModeDeny || $fN === 'CType' && in_array($fV, $removeItems[$fN]) || $isNotInKeepItems) {
485  // Remove element all together:
486  unset($wizardItems[$key]);
487  break;
488  } else {
489  // Add the parameter:
490  $wizardItems[$key]['params'] .= '&defVals[tt_content][' . $fN . ']=' . rawurlencode($fV);
491  $tmp = explode('_', $key);
492  $headersUsed[$tmp[0]] = $tmp[0];
493  }
494  }
495  }
496  }
497  }
498  // remove headers without elements
499  foreach ($wizardItems as $key => $cfg) {
500  $tmp = explode('_', $key);
501  if ($tmp[0] && !$tmp[1] && !in_array($tmp[0], $headersUsed)) {
502  unset($wizardItems[$key]);
503  }
504  }
505  }
506 
507 }
static skinImg($backPath, $src, $wHattribs='', $outputMode=0)
static explodeUrl2Array($string, $multidim=FALSE)
static readPageAccess($id, $perms_clause)
static cshItem($table, $field, $BACK_PATH, $wrap='', $onlyIconMode=FALSE, $styleAttrib='')
static getUserObj($classRef, $checkPrefix='', $silent=FALSE)
static trimExplode($delim, $string, $removeEmptyValues=FALSE, $limit=0)
static callUserFunction($funcName, &$params, &$ref, $checkPrefix='', $errorMode=0)
static getSpriteIcon($iconName, array $options=array(), array $overlays=array())
static implodeArrayForUrl($name, array $theArray, $str='', $skipBlank=FALSE, $rawurlencodeParamName=FALSE)
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
static getPagesTSconfig($id, $rootLine=NULL, $returnPartArray=FALSE)