TYPO3 CMS  TYPO3_8-7
FrontendEditPanel.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Feedit;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
26 
31 {
37  protected $cObj;
38 
45 
49  protected $backendUser;
50 
54  protected $iconFactory;
55 
64  {
65  $this->frontendController = $frontendController ?: $GLOBALS['TSFE'];
66  $this->backendUser = $backendUser ?: $GLOBALS['BE_USER'];
67  $this->cObj = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class);
68  $this->cObj->start([]);
69  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
70  }
71 
87  public function editPanel($content, array $conf, $currentRecord = '', array $dataArr = [], $table = '', array $allow = [], $newUID = 0, array $hiddenFields = [])
88  {
89  $hiddenFieldString = $command = '';
90 
91  // Special content is about to be shown, so the cache must be disabled.
92  $this->frontendController->set_no_cache('Frontend edit panel is shown', true);
93 
94  $formName = 'TSFE_EDIT_FORM_' . substr($this->frontendController->uniqueHash(), 0, 4);
95  $formTag = '<form name="' . $formName . '" id ="' . $formName . '" action="' . htmlspecialchars(GeneralUtility::getIndpEnv('REQUEST_URI')) . '" method="post" enctype="multipart/form-data" onsubmit="return TBE_EDITOR.checkSubmit(1);">';
96  $sortField = $GLOBALS['TCA'][$table]['ctrl']['sortby'];
97  $labelField = $GLOBALS['TCA'][$table]['ctrl']['label'];
98  $hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
99 
100  $panel = '';
101  if (isset($allow['toolbar']) && $this->backendUser->adminPanel instanceof AdminPanelView) {
102  $panel .= $this->backendUser->adminPanel->ext_makeToolBar();
103  }
104  if (isset($allow['edit'])) {
105  $icon = '<span title="' . $this->backendUser->extGetLL('p_editRecord') . '">' . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render('inline') . '</span>';
106  $panel .= $this->editPanelLinkWrap($icon, $formName, 'edit', $dataArr['_LOCALIZED_UID'] ? $table . ':' . $dataArr['_LOCALIZED_UID'] : $currentRecord);
107  }
108  // Hiding in workspaces because implementation is incomplete
109  if (isset($allow['move']) && $sortField && $this->backendUser->workspace === 0) {
110  $icon = '<span title="' . $this->backendUser->extGetLL('p_moveUp') . '">' . $this->iconFactory->getIcon('actions-move-up', Icon::SIZE_SMALL)->render('inline') . '</span>';
111  $panel .= $this->editPanelLinkWrap($icon, $formName, 'up');
112  $icon = '<span title="' . $this->backendUser->extGetLL('p_moveDown') . '">' . $this->iconFactory->getIcon('actions-move-down', Icon::SIZE_SMALL)->render('inline') . '</span>';
113  $panel .= $this->editPanelLinkWrap($icon, $formName, 'down');
114  }
115  // Hiding in workspaces because implementation is incomplete
116  // Hiding for localizations because it is unknown what should be the function in that case
117  if (isset($allow['hide']) && $hideField && $this->backendUser->workspace === 0 && !$dataArr['_LOCALIZED_UID']) {
118  if ($dataArr[$hideField]) {
119  $icon = $this->iconFactory->getIcon('actions-edit-unhide', Icon::SIZE_SMALL)->render('inline');
120  $panel .= $this->editPanelLinkWrap($icon, $formName, 'unhide');
121  } else {
122  $icon = $this->iconFactory->getIcon('actions-edit-hide', Icon::SIZE_SMALL)->render('inline');
123  $panel .= $this->editPanelLinkWrap($icon, $formName, 'hide', '', $this->backendUser->extGetLL('p_hideConfirm'));
124  }
125  }
126  if (isset($allow['new'])) {
127  if ($table === 'pages') {
128  $icon = '<span title="' . $this->backendUser->extGetLL('p_newSubpage') . '">'
129  . $this->iconFactory->getIcon('actions-page-new', Icon::SIZE_SMALL)->render('inline')
130  . '</span>';
131  $panel .= $this->editPanelLinkWrap($icon, $formName, 'new', $currentRecord, '');
132  } else {
133  $icon = '<span title="' . $this->backendUser->extGetLL('p_newRecordAfter') . '">'
134  . $this->iconFactory->getIcon('actions-document-new', Icon::SIZE_SMALL)->render('inline')
135  . '</span>';
136  $panel .= $this->editPanelLinkWrap($icon, $formName, 'new', $currentRecord, '', $newUID);
137  }
138  }
139  // Hiding in workspaces because implementation is incomplete
140  // Hiding for localizations because it is unknown what should be the function in that case
141  if (isset($allow['delete']) && $this->backendUser->workspace === 0 && !$dataArr['_LOCALIZED_UID']) {
142  $icon = '<span title="' . $this->backendUser->extGetLL('p_delete') . '">'
143  . $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render('inline')
144  . '</span>';
145  $panel .= $this->editPanelLinkWrap($icon, $formName, 'delete', '', $this->backendUser->extGetLL('p_deleteConfirm'));
146  }
147  // Final
148  $labelTxt = $this->cObj->stdWrap($conf['label'], $conf['label.']);
149  foreach ((array)$hiddenFields as $name => $value) {
150  $hiddenFieldString .= '<input type="hidden" name="TSFE_EDIT[' . htmlspecialchars($name) . ']" value="' . htmlspecialchars($value) . '"/>' . LF;
151  }
152 
153  $panel = '<!-- BE_USER Edit Panel: -->
154  ' . $formTag . $hiddenFieldString . '
155  <input type="hidden" name="TSFE_EDIT[cmd]" value="" />
156  <input type="hidden" name="TSFE_EDIT[record]" value="' . $currentRecord . '" />
157  <div class="typo3-editPanel" style="display: none;">'
158  . '<div class="typo3-editPanel-btn-group">'
159  . $panel
160  . '</div>' .
161  ($labelTxt ? '<div class="typo3-editPanel-label">' . sprintf($labelTxt, htmlspecialchars(GeneralUtility::fixed_lgd_cs($dataArr[$labelField], 50))) . '</div>' : '') . '
162  </div>
163  </form>';
164 
165  // Wrap the panel
166  if ($conf['innerWrap']) {
167  $panel = $this->cObj->wrap($panel, $conf['innerWrap']);
168  }
169  if ($conf['innerWrap.']) {
170  $panel = $this->cObj->stdWrap($panel, $conf['innerWrap.']);
171  }
172 
173  // Wrap the complete panel
174  if ($conf['outerWrap']) {
175  $panel = $this->cObj->wrap($panel, $conf['outerWrap']);
176  }
177  if ($conf['outerWrap.']) {
178  $panel = $this->cObj->stdWrap($panel, $conf['outerWrap.']);
179  }
180  if ($conf['printBeforeContent']) {
181  $finalOut = $panel . $content;
182  } else {
183  $finalOut = $content . $panel;
184  }
185 
186  $hidden = $this->isDisabled($table, $dataArr) ? ' typo3-feedit-element-hidden' : '';
187  $outerWrapConfig = isset($conf['stdWrap.'])
188  ? $conf['stdWrap.']
189  : ['wrap' => '<div class="typo3-feedit-element' . $hidden . '">|</div>'];
190  $finalOut = $this->cObj->stdWrap($finalOut, $outerWrapConfig);
191 
192  return $finalOut;
193  }
194 
210  public function editIcons($content, $params, array $conf = [], $currentRecord = '', array $dataArr = [], $addUrlParamStr = '', $table, $editUid, $fieldList)
211  {
212  // Special content is about to be shown, so the cache must be disabled.
213  $this->frontendController->set_no_cache('Display frontend edit icons', true);
214  $iconTitle = $this->cObj->stdWrap($conf['iconTitle'], $conf['iconTitle.']);
215  $iconImg = '<span title="' . htmlspecialchars($iconTitle, ENT_COMPAT, 'UTF-8', false) . '" style="' . ($conf['styleAttribute'] ? htmlspecialchars($conf['styleAttribute']) : '') . '">'
216  . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render('inline')
217  . '</span>';
218  $nV = GeneralUtility::_GP('ADMCMD_view') ? 1 : 0;
219 
220  $url = BackendUtility::getModuleUrl(
221  'record_edit',
222  [
223  'edit[' . $table . '][' . $editUid . ']' => 'edit',
224  'columnsOnly' => $fieldList,
225  'noView' => $nV,
226  'feEdit' => 1
227  ]
228  ) . $addUrlParamStr;
229  $icon = $this->editPanelLinkWrap_doWrap($iconImg, $url, 'content-link');
230  if ($conf['beforeLastTag'] < 0) {
231  $content = $icon . $content;
232  } elseif ($conf['beforeLastTag'] > 0) {
233  $cBuf = rtrim($content);
234  $secureCount = 30;
235  while ($secureCount && substr($cBuf, -1) === '>' && substr($cBuf, -4) !== '</a>') {
236  $cBuf = rtrim(preg_replace('/<[^<]*>$/', '', $cBuf));
237  $secureCount--;
238  }
239  $content = strlen($cBuf) && $secureCount ? substr($content, 0, strlen($cBuf)) . $icon . substr($content, strlen($cBuf)) : ($content = $icon . $content);
240  } else {
241  $content .= $icon;
242  }
243  return $content;
244  }
245 
258  protected function editPanelLinkWrap($string, $formName, $cmd, $currentRecord = '', $confirm = '', $nPid = '')
259  {
260  $nV = GeneralUtility::_GP('ADMCMD_view') ? 1 : 0;
261  if ($cmd === 'edit') {
262  $rParts = explode(':', $currentRecord);
263  $out = $this->editPanelLinkWrap_doWrap($string, BackendUtility::getModuleUrl('record_edit', ['edit[' . $rParts[0] . '][' . $rParts[1] . ']' => 'edit', 'noView' => $nV, 'feEdit' => 1]), $currentRecord);
264  } elseif ($cmd === 'new') {
265  $rParts = explode(':', $currentRecord);
266  if ($rParts[0] === 'pages') {
267  $out = $this->editPanelLinkWrap_doWrap($string, BackendUtility::getModuleUrl('db_new', ['id' => $rParts[1], 'pagesOnly' => 1]), $currentRecord);
268  } else {
269  if (!(int)$nPid) {
270  $nPid = MathUtility::canBeInterpretedAsInteger($rParts[1]) ? -$rParts[1] : $this->frontendController->id;
271  }
272  $out = $this->editPanelLinkWrap_doWrap($string, BackendUtility::getModuleUrl('record_edit', ['edit[' . $rParts[0] . '][' . $nPid . ']' => 'new', 'noView' => $nV]), $currentRecord);
273  }
274  } else {
275  if ($confirm && $this->backendUser->jsConfirmation(JsConfirmation::FE_EDIT)) {
276  // Gets htmlspecialchared later
277  $cf1 = 'if (confirm(' . GeneralUtility::quoteJSvalue($confirm) . ')) {';
278  $cf2 = '}';
279  } else {
280  $cf1 = ($cf2 = '');
281  }
282  $out = '<a href="#" class="typo3-editPanel-btn typo3-editPanel-btn-default" onclick="' . htmlspecialchars(($cf1 . 'document.' . $formName . '[\'TSFE_EDIT[cmd]\'].value=\'' . $cmd . '\'; document.' . $formName . '.submit();' . $cf2 . ' return false;')) . '">' . $string . '</a>';
283  }
284  return $out;
285  }
286 
296  protected function editPanelLinkWrap_doWrap($string, $url, $additionalClasses = '')
297  {
298  $width = MathUtility::forceIntegerInRange($this->backendUser->getTSConfigVal('options.feedit.popupWidth'), 690, 5000, 690);
299  $height = MathUtility::forceIntegerInRange($this->backendUser->getTSConfigVal('options.feedit.popupHeight'), 500, 5000, 500);
300  $onclick = 'vHWin=window.open(' . GeneralUtility::quoteJSvalue($url . '&returnUrl=' . rawurlencode(PathUtility::getAbsoluteWebPath(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Public/Html/Close.html')))) . ',\'FEquickEditWindow\',\'width=' . $width . ',height=' . $height . ',status=0,menubar=0,scrollbars=1,resizable=1\');vHWin.focus();return false;';
301  return '<a href="#" class="typo3-editPanel-btn typo3-editPanel-btn-default frontEndEditIconLinks ' . htmlspecialchars($additionalClasses) . '" onclick="' . htmlspecialchars($onclick) . '" style="display: none;">' . $string . '</a>';
302  }
303 
311  protected function isDisabled($table, array $row)
312  {
313  $status = false;
314  if (
315  $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'] &&
316  $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']] ||
317  $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group'] &&
318  $this->frontendController->simUserGroup &&
319  $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group']] == $this->frontendController->simUserGroup ||
320  $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['starttime'] &&
321  $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['starttime']] > $GLOBALS['EXEC_TIME'] ||
322  $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime'] &&
323  $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime']] &&
324  $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime']] < $GLOBALS['EXEC_TIME']
325  ) {
326  $status = true;
327  }
328 
329  return $status;
330  }
331 }
editPanel($content, array $conf, $currentRecord='', array $dataArr=[], $table='', array $allow=[], $newUID=0, array $hiddenFields=[])
editPanelLinkWrap($string, $formName, $cmd, $currentRecord='', $confirm='', $nPid='')
editIcons($content, $params, array $conf=[], $currentRecord='', array $dataArr=[], $addUrlParamStr='', $table, $editUid, $fieldList)
static makeInstance($className,... $constructorArguments)
__construct($_=null, TypoScriptFrontendController $frontendController=null, FrontendBackendUserAuthentication $backendUser=null)
editPanelLinkWrap_doWrap($string, $url, $additionalClasses='')
static fixed_lgd_cs($string, $chars, $appendString='...')
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']