TYPO3  7.6
FrontendEditPanel.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Feedit;
3 
27 
32 {
38  protected $cObj;
39 
46 
53 
57  protected $backendUser;
58 
62  protected $iconFactory;
63 
72  {
73  $this->databaseConnection = $databaseConnection ?: $GLOBALS['TYPO3_DB'];
74  $this->frontendController = $frontendController ?: $GLOBALS['TSFE'];
75  $this->backendUser = $backendUser ?: $GLOBALS['BE_USER'];
76  $this->cObj = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class);
77  $this->cObj->start(array());
78  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
79  }
80 
96  public function editPanel($content, array $conf, $currentRecord = '', array $dataArr = array(), $table = '', array $allow = array(), $newUID = 0, array $hiddenFields = array())
97  {
98  $hiddenFieldString = $command = '';
99 
100  // Special content is about to be shown, so the cache must be disabled.
101  $this->frontendController->set_no_cache('Frontend edit panel is shown', true);
102 
103  $formName = 'TSFE_EDIT_FORM_' . substr($this->frontendController->uniqueHash(), 0, 4);
104  $formTag = '<form name="' . $formName . '" id ="' . $formName . '" action="' . htmlspecialchars(GeneralUtility::getIndpEnv('REQUEST_URI')) . '" method="post" enctype="multipart/form-data" onsubmit="return TBE_EDITOR.checkSubmit(1);">';
105  $sortField = $GLOBALS['TCA'][$table]['ctrl']['sortby'];
106  $labelField = $GLOBALS['TCA'][$table]['ctrl']['label'];
107  $hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
108 
109  $panel = '';
110  if (isset($allow['toolbar']) && $this->backendUser->adminPanel instanceof AdminPanelView) {
111  $panel .= $this->backendUser->adminPanel->ext_makeToolBar();
112  }
113  if (isset($allow['edit'])) {
114  $icon = '<span title="' . htmlspecialchars($this->backendUser->extGetLL('p_editRecord')) . '">' . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render() . '</span>';
115  $panel .= $this->editPanelLinkWrap($icon, $formName, 'edit', $dataArr['_LOCALIZED_UID'] ? $table . ':' . $dataArr['_LOCALIZED_UID'] : $currentRecord);
116  }
117  // Hiding in workspaces because implementation is incomplete
118  if (isset($allow['move']) && $sortField && $this->backendUser->workspace === 0) {
119  $icon = '<span title="' . htmlspecialchars($this->backendUser->extGetLL('p_moveUp')) . '">' . $this->iconFactory->getIcon('actions-move-up', Icon::SIZE_SMALL)->render() . '</span>';
120  $panel .= $this->editPanelLinkWrap($icon, $formName, 'up');
121  $icon = '<span title="' . htmlspecialchars($this->backendUser->extGetLL('p_moveDown')) . '">' . $this->iconFactory->getIcon('actions-move-down', Icon::SIZE_SMALL)->render() . '</span>';
122  $panel .= $this->editPanelLinkWrap($icon, $formName, 'down');
123  }
124  // Hiding in workspaces because implementation is incomplete
125  // Hiding for localizations because it is unknown what should be the function in that case
126  if (isset($allow['hide']) && $hideField && $this->backendUser->workspace === 0 && !$dataArr['_LOCALIZED_UID']) {
127  if ($dataArr[$hideField]) {
128  $icon = $this->iconFactory->getIcon('actions-edit-unhide', Icon::SIZE_SMALL)->render();
129  $panel .= $this->editPanelLinkWrap($icon, $formName, 'unhide');
130  } else {
131  $icon = $this->iconFactory->getIcon('actions-edit-hide', Icon::SIZE_SMALL)->render();
132  $panel .= $this->editPanelLinkWrap($icon, $formName, 'hide', '', $this->backendUser->extGetLL('p_hideConfirm'));
133  }
134  }
135  if (isset($allow['new'])) {
136  if ($table === 'pages') {
137  $icon = '<span title="' . htmlspecialchars($this->backendUser->extGetLL('p_newSubpage')) . '">'
138  . $this->iconFactory->getIcon('actions-page-new', Icon::SIZE_SMALL)->render()
139  . '</span>';
140  $panel .= $this->editPanelLinkWrap($icon, $formName, 'new', $currentRecord, '');
141  } else {
142  $icon = '<span title="' . htmlspecialchars($this->backendUser->extGetLL('p_newRecordAfter')) . '">'
143  . $this->iconFactory->getIcon('actions-document-new', Icon::SIZE_SMALL)->render()
144  . '</span>';
145  $panel .= $this->editPanelLinkWrap($icon, $formName, 'new', $currentRecord, '', $newUID);
146  }
147  }
148  // Hiding in workspaces because implementation is incomplete
149  // Hiding for localizations because it is unknown what should be the function in that case
150  if (isset($allow['delete']) && $this->backendUser->workspace === 0 && !$dataArr['_LOCALIZED_UID']) {
151  $icon = '<span title="' . htmlspecialchars($this->backendUser->extGetLL('p_delete')) . '">'
152  . $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render()
153  . '</span>';
154  $panel .= $this->editPanelLinkWrap($icon, $formName, 'delete', '', $this->backendUser->extGetLL('p_deleteConfirm'));
155  }
156  // Final
157  $labelTxt = $this->cObj->stdWrap($conf['label'], $conf['label.']);
158  foreach ((array)$hiddenFields as $name => $value) {
159  $hiddenFieldString .= '<input type="hidden" name="TSFE_EDIT[' . htmlspecialchars($name) . ']" value="' . htmlspecialchars($value) . '"/>' . LF;
160  }
161 
162  $panel = '<!-- BE_USER Edit Panel: -->
163  ' . $formTag . $hiddenFieldString . '
164  <input type="hidden" name="TSFE_EDIT[cmd]" value="" />
165  <input type="hidden" name="TSFE_EDIT[record]" value="' . $currentRecord . '" />
166  <div class="typo3-editPanel">'
167  . '<div class="btn-group">'
168  . $panel
169  . '</div>' .
170  ($labelTxt ? '<div class="typo3-editPanel-label">' . sprintf($labelTxt, htmlspecialchars(GeneralUtility::fixed_lgd_cs($dataArr[$labelField], 50))) . '</div>' : '') . '
171  </div>
172  </form>';
173 
174  // Wrap the panel
175  if ($conf['innerWrap']) {
176  $panel = $this->cObj->wrap($panel, $conf['innerWrap']);
177  }
178  if ($conf['innerWrap.']) {
179  $panel = $this->cObj->stdWrap($panel, $conf['innerWrap.']);
180  }
181 
182  // Wrap the complete panel
183  if ($conf['outerWrap']) {
184  $panel = $this->cObj->wrap($panel, $conf['outerWrap']);
185  }
186  if ($conf['outerWrap.']) {
187  $panel = $this->cObj->stdWrap($panel, $conf['outerWrap.']);
188  }
189  if ($conf['printBeforeContent']) {
190  $finalOut = $panel . $content;
191  } else {
192  $finalOut = $content . $panel;
193  }
194 
195  $hidden = $this->isDisabled($table, $dataArr) ? ' typo3-feedit-element-hidden' : '';
196  $outerWrapConfig = isset($conf['stdWrap.'])
197  ? $conf['stdWrap.']
198  : array('wrap' => '<div class="typo3-feedit-element' . $hidden . '">|</div>');
199  $finalOut = $this->cObj->stdWrap($finalOut, $outerWrapConfig);
200 
201  return $finalOut;
202  }
203 
219  public function editIcons($content, $params, array $conf = array(), $currentRecord = '', array $dataArr = array(), $addUrlParamStr = '', $table, $editUid, $fieldList)
220  {
221  // Special content is about to be shown, so the cache must be disabled.
222  $this->frontendController->set_no_cache('Display frontend edit icons', true);
223  $iconTitle = $this->cObj->stdWrap($conf['iconTitle'], $conf['iconTitle.']);
224  $iconImg = '<span title="' . htmlspecialchars($iconTitle, ENT_COMPAT, 'UTF-8', false) . '" class="frontEndEditIcons" style="' . ($conf['styleAttribute'] ? htmlspecialchars($conf['styleAttribute']) : '') . '">'
225  . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render()
226  . '</span>';
227  $nV = GeneralUtility::_GP('ADMCMD_view') ? 1 : 0;
228 
229  $url = BackendUtility::getModuleUrl(
230  'record_edit',
231  array(
232  'edit[' . $table . '][' . $editUid . ']' => 'edit',
233  'columnsOnly' => $fieldList,
234  'noView' => $nV,
235  'feEdit' => 1
236  )
237  ) . $addUrlParamStr;
238  $icon = $this->editPanelLinkWrap_doWrap($iconImg, $url, 'content-link');
239  if ($conf['beforeLastTag'] < 0) {
240  $content = $icon . $content;
241  } elseif ($conf['beforeLastTag'] > 0) {
242  $cBuf = rtrim($content);
243  $secureCount = 30;
244  while ($secureCount && substr($cBuf, -1) == '>' && substr($cBuf, -4) != '</a>') {
245  $cBuf = rtrim(preg_replace('/<[^<]*>$/', '', $cBuf));
246  $secureCount--;
247  }
248  $content = strlen($cBuf) && $secureCount ? substr($content, 0, strlen($cBuf)) . $icon . substr($content, strlen($cBuf)) : ($content = $icon . $content);
249  } else {
250  $content .= $icon;
251  }
252  return $content;
253  }
254 
267  protected function editPanelLinkWrap($string, $formName, $cmd, $currentRecord = '', $confirm = '', $nPid = '')
268  {
269  $nV = GeneralUtility::_GP('ADMCMD_view') ? 1 : 0;
270  if ($cmd == 'edit') {
271  $rParts = explode(':', $currentRecord);
272  $out = $this->editPanelLinkWrap_doWrap($string, BackendUtility::getModuleUrl('record_edit', array('edit[' . $rParts[0] . '][' . $rParts[1] . ']' => 'edit', 'noView' => $nV, 'feEdit' => 1)), $currentRecord);
273  } elseif ($cmd == 'new') {
274  $rParts = explode(':', $currentRecord);
275  if ($rParts[0] == 'pages') {
276  $out = $this->editPanelLinkWrap_doWrap($string, BackendUtility::getModuleUrl('db_new', ['id' => $rParts[1], 'pagesOnly' => 1]), $currentRecord);
277  } else {
278  if (!(int)$nPid) {
279  $nPid = MathUtility::canBeInterpretedAsInteger($rParts[1]) ? -$rParts[1] : $this->frontendController->id;
280  }
281  $out = $this->editPanelLinkWrap_doWrap($string, BackendUtility::getModuleUrl('record_edit', array('edit[' . $rParts[0] . '][' . $nPid . ']' => 'new', 'noView' => $nV)), $currentRecord);
282  }
283  } else {
284  if ($confirm && $this->backendUser->jsConfirmation(JsConfirmation::FE_EDIT)) {
285  // Gets htmlspecialchared later
286  $cf1 = 'if (confirm(' . GeneralUtility::quoteJSvalue($confirm, true) . ')) {';
287  $cf2 = '}';
288  } else {
289  $cf1 = ($cf2 = '');
290  }
291  $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>';
292  }
293  return $out;
294  }
295 
305  protected function editPanelLinkWrap_doWrap($string, $url, $additionalClasses = '')
306  {
307  $onclick = 'vHWin=window.open(' . GeneralUtility::quoteJSvalue($url . '&returnUrl=sysext/backend/Resources/Private/Templates/Close.html') . ',\'FEquickEditWindow\',\'width=690,height=500,status=0,menubar=0,scrollbars=1,resizable=1\');vHWin.focus();return false;';
308  return '<a href="#" class="btn btn-default btn-sm ' . htmlspecialchars($additionalClasses) . '" onclick="' . htmlspecialchars($onclick) . '" class="frontEndEditIconLinks">' . $string . '</a>';
309  }
310 
318  protected function isDisabled($table, array $row)
319  {
320  $status = false;
321  if (
322  $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'] &&
323  $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']] ||
324  $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group'] &&
325  $this->frontendController->simUserGroup &&
326  $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group']] == $this->frontendController->simUserGroup ||
327  $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['starttime'] &&
328  $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['starttime']] > $GLOBALS['EXEC_TIME'] ||
329  $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime'] &&
330  $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime']] &&
331  $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime']] < $GLOBALS['EXEC_TIME']
332  ) {
333  $status = true;
334  }
335 
336  return $status;
337  }
338 }