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