‪TYPO3CMS  9.5
Clipboard.php
Go to the documentation of this file.
1 <?php
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  */
16 
31 
38 {
42  public ‪$numberTabs = 3;
43 
65  public ‪$clipData = [];
66 
70  public ‪$changed = 0;
71 
75  public ‪$current = '';
76 
80  public ‪$lockToNormal = 0;
81 
87  public ‪$fileMode = false;
88 
92  protected ‪$iconFactory;
93 
97  protected ‪$view;
98 
104  public function ‪__construct()
105  {
106  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
107  $this->view = $this->‪getStandaloneView();
108  }
109 
110  /*****************************************
111  *
112  * Initialize
113  *
114  ****************************************/
118  public function ‪initializeClipboard()
119  {
120  $userTsConfig = $this->‪getBackendUser()->‪getTSConfig();
121  // Get data
122  $clipData = $this->‪getBackendUser()->‪getModuleData('clipboard', $userTsConfig['options.']['saveClipboard'] ? '' : 'ses');
123  $this->numberTabs = ‪MathUtility::forceIntegerInRange((int)($userTsConfig['options.']['clipboardNumberPads'] ?? 3), 0, 20);
124  // Resets/reinstates the clipboard pads
125  $this->clipData['normal'] = is_array(‪$clipData['normal']) ? ‪$clipData['normal'] : [];
126  for ($a = 1; $a <= ‪$this->numberTabs; $a++) {
127  $this->clipData['tab_' . $a] = is_array(‪$clipData['tab_' . $a]) ? ‪$clipData['tab_' . $a] : [];
128  }
129  // Setting the current pad pointer ($this->current))
130  $this->clipData['current'] = ($this->current = isset($this->clipData[‪$clipData['current']]) ? ‪$clipData['current'] : 'normal');
131  }
132 
138  public function ‪lockToNormal()
139  {
140  $this->‪lockToNormal = 1;
141  $this->current = 'normal';
142  }
143 
155  public function ‪setCmd($cmd)
156  {
157  if (is_array($cmd['el'])) {
158  foreach ($cmd['el'] as $k => $v) {
159  if ($this->current === 'normal') {
160  unset($this->clipData['normal']);
161  }
162  if ($v) {
163  $this->clipData[‪$this->current]['el'][$k] = $v;
164  } else {
165  $this->‪removeElement($k);
166  }
167  $this->changed = 1;
168  }
169  }
170  // Change clipboard pad (if not locked to normal)
171  if ($cmd['setP']) {
172  $this->‪setCurrentPad($cmd['setP']);
173  }
174  // Remove element (value = item ident: DB; '[tablename]|[uid]' FILE: '_FILE|[shortmd5 hash of path]'
175  if ($cmd['remove']) {
176  $this->‪removeElement($cmd['remove']);
177  $this->changed = 1;
178  }
179  // Remove all on current pad (value = pad-ident)
180  if ($cmd['removeAll']) {
181  $this->clipData[$cmd['removeAll']] = [];
182  $this->changed = 1;
183  }
184  // Set copy mode of the tab
185  if (isset($cmd['setCopyMode'])) {
186  $this->clipData[‪$this->current]['mode'] = $cmd['setCopyMode'] ? 'copy' : '';
187  $this->changed = 1;
188  }
189  }
190 
196  public function ‪setCurrentPad($padIdent)
197  {
198  // Change clipboard pad (if not locked to normal)
199  if (!$this->‪lockToNormal && $this->current != $padIdent) {
200  if (isset($this->clipData[$padIdent])) {
201  $this->clipData['current'] = ($this->current = $padIdent);
202  }
203  if ($this->current !== 'normal' || !$this->‪isElements()) {
204  $this->clipData[‪$this->current]['mode'] = '';
205  }
206  // Setting mode to default (move) if no items on it or if not 'normal'
207  $this->changed = 1;
208  }
209  }
210 
215  public function ‪endClipboard()
216  {
217  if ($this->changed) {
218  $this->‪saveClipboard();
219  }
220  $this->changed = 0;
221  }
222 
231  public function ‪cleanUpCBC($CBarr, $table, $removeDeselected = 0)
232  {
233  if (is_array($CBarr)) {
234  foreach ($CBarr as $k => $v) {
235  $p = explode('|', $k);
236  if ((string)$p[0] != (string)$table || $removeDeselected && !$v) {
237  unset($CBarr[$k]);
238  }
239  }
240  }
241  return $CBarr;
242  }
243 
244  /*****************************************
245  *
246  * Clipboard HTML renderings
247  *
248  ****************************************/
255  public function ‪printClipboard()
256  {
257  $languageService = $this->‪getLanguageService();
258  $elementCount = count($this->‪elFromTable($this->fileMode ? '_FILE' : ''));
259  // Copymode Selector menu
260  $copymodeUrl = GeneralUtility::linkThisScript();
261 
262  $this->view->assign('actionCopyModeUrl', htmlspecialchars(GeneralUtility::quoteJSvalue($copymodeUrl . '&CB[setCopyMode]=')));
263  $this->view->assign('actionCopyModeUrl1', htmlspecialchars(GeneralUtility::quoteJSvalue($copymodeUrl . '&CB[setCopyMode]=1')));
264  $this->view->assign('currentMode', $this->‪currentMode());
265  $this->view->assign('elementCount', $elementCount);
266 
267  if ($elementCount) {
268  $removeAllUrl = GeneralUtility::linkThisScript(['CB' => ['removeAll' => $this->current]]);
269  $this->view->assign('removeAllUrl', $removeAllUrl);
270 
271  // Selector menu + clear button
272  $optionArray = [];
273  // Import / Export link:
275  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
276  $url = $uriBuilder->buildUriFromRoute('xMOD_tximpexp', $this->‪exportClipElementParameters());
277  $optionArray[] = [
278  'label' => $this->‪clLabel('export', 'rm'),
279  'uri' => (string)$url
280  ];
281  }
282  // Edit:
283  if (!$this->fileMode) {
284  $optionArray[] = [
285  'label' => $this->‪clLabel('edit', 'rm'),
286  'uri' => '#',
287  'additionalAttributes' => [
288  'onclick' => htmlspecialchars('window.location.href=' . GeneralUtility::quoteJSvalue($this->‪editUrl() . '&returnUrl=') . '+top.rawurlencode(window.location.href);'),
289  ]
290  ];
291  }
292 
293  // Delete referenced elements:
294  $confirmationCheck = false;
295  if ($this->‪getBackendUser()->jsConfirmation(‪JsConfirmation::DELETE)) {
296  $confirmationCheck = true;
297  }
298 
299  $confirmationMessage = sprintf(
300  $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:mess.deleteClip'),
301  $elementCount
302  );
303  $title = $languageService
304  ->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.clipboard.delete_elements');
305  $returnUrl = $this->‪deleteUrl(true, $this->fileMode);
306  $btnOkText = $languageService
307  ->sL('LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:buttons.confirm.delete_elements.yes');
308  $btnCancelText = $languageService
309  ->sL('LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:buttons.confirm.delete_elements.no');
310  $optionArray[] = [
311  'label' => htmlspecialchars($title),
312  'uri' => $returnUrl,
313  'additionalAttributes' => [
314  'class' => $confirmationCheck ? 't3js-modal-trigger' : '',
315  ],
316  'data' => [
317  'severity' => 'warning',
318  'button-close-text' => htmlspecialchars($btnCancelText),
319  'button-ok-text' => htmlspecialchars($btnOkText),
320  'content' => htmlspecialchars($confirmationMessage),
321  'title' => htmlspecialchars($title)
322  ]
323  ];
324 
325  // Clear clipboard
326  $optionArray[] = [
327  'label' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.clipboard.clear_clipboard'),
328  'uri' => $removeAllUrl . '#clip_head'
329  ];
330  $this->view->assign('optionArray', $optionArray);
331  }
332 
333  // Print header and content for the NORMAL tab:
334  $this->view->assign('current', $this->current);
335  $tabArray = [];
336  $tabArray['normal'] = [
337  'id' => 'normal',
338  'number' => 0,
339  'url' => GeneralUtility::linkThisScript(['CB' => ['setP' => 'normal']]),
340  'description' => 'labels.normal-description',
341  'label' => 'labels.normal',
342  'padding' => $this->‪padTitle('normal')
343  ];
344  if ($this->current === 'normal') {
345  $tabArray['normal']['content'] = $this->‪getContentFromTab('normal');
346  }
347  // Print header and content for the NUMERIC tabs:
348  for ($a = 1; $a <= ‪$this->numberTabs; $a++) {
349  $tabArray['tab_' . $a] = [
350  'id' => 'tab_' . $a,
351  'number' => $a,
352  'url' => GeneralUtility::linkThisScript(['CB' => ['setP' => 'tab_' . $a]]),
353  'description' => 'labels.cliptabs-description',
354  'label' => 'labels.cliptabs-name',
355  'padding' => $this->‪padTitle('tab_' . $a)
356  ];
357  if ($this->current === 'tab_' . $a) {
358  $tabArray['tab_' . $a]['content'] = $this->‪getContentFromTab('tab_' . $a);
359  }
360  }
361  $this->view->assign('clipboardHeader', ‪BackendUtility::wrapInHelp('xMOD_csh_corebe', 'list_clipboard', $this->‪clLabel('clipboard', 'buttons')));
362  $this->view->assign('tabArray', $tabArray);
363  return $this->view->render();
364  }
365 
373  public function ‪getContentFromTab($pad)
374  {
375  $lines = [];
376  if (is_array($this->clipData[$pad]['el'] ?? false)) {
377  foreach ($this->clipData[$pad]['el'] as $k => $v) {
378  if ($v) {
379  list($table, $uid) = explode('|', $k);
380  // Rendering files/directories on the clipboard
381  if ($table === '_FILE') {
383  if ($fileObject) {
384  $thumb = [];
385  $folder = $fileObject instanceof \TYPO3\CMS\Core\Resource\Folder;
386  $size = $folder ? '' : '(' . GeneralUtility::formatSize($fileObject->getSize()) . 'bytes)';
387  if (
388  !$folder
389  && GeneralUtility::inList(
390  ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],
391  $fileObject->getExtension()
392  )
393  ) {
394  $thumb = [
395  'image' => $fileObject->process(\‪TYPO3\CMS\Core\Resource\ProcessedFile::CONTEXT_IMAGEPREVIEW, [])->getPublicUrl(true),
396  'title' => htmlspecialchars($fileObject->getName())
397  ];
398  }
399  $lines[] = [
400  'icon' => '<span title="' . htmlspecialchars($fileObject->getName() . ' ' . $size) . '">' . $this->iconFactory->getIconForResource(
401  $fileObject,
403  )->render() . '</span>',
404  'title' => $this->‪linkItemText(htmlspecialchars(GeneralUtility::fixed_lgd_cs(
405  $fileObject->getName(),
406  $this->getBackendUser()->uc['titleLen']
407  )), $fileObject->getName()),
408  'thumb' => $thumb,
409  'infoLink' => htmlspecialchars('top.TYPO3.InfoWindow.showItem(' . GeneralUtility::quoteJSvalue($table) . ', ' . GeneralUtility::quoteJSvalue($v) . '); return false;'),
410  'removeLink' => $this->‪removeUrl('_FILE', GeneralUtility::shortMD5($v))
411  ];
412  } else {
413  // If the file did not exist (or is illegal) then it is removed from the clipboard immediately:
414  unset($this->clipData[$pad]['el'][$k]);
415  $this->changed = 1;
416  }
417  } else {
418  // Rendering records:
419  $rec = ‪BackendUtility::getRecordWSOL($table, $uid);
420  if (is_array($rec)) {
421  $lines[] = [
422  'icon' => $this->‪linkItemText($this->iconFactory->getIconForRecord(
423  $table,
424  $rec,
426  )->render(), $rec, $table),
427  'title' => $this->‪linkItemText(htmlspecialchars(GeneralUtility::fixed_lgd_cs(‪BackendUtility::getRecordTitle(
428  $table,
429  $rec
430  ), $this->‪getBackendUser()->uc['titleLen'])), $rec, $table),
431  'infoLink' => htmlspecialchars('top.TYPO3.InfoWindow.showItem(' . GeneralUtility::quoteJSvalue($table) . ', \'' . (int)$uid . '\'); return false;'),
432  'removeLink' => $this->removeUrl($table, $uid)
433  ];
434 
435  $localizationData = $this->getLocalizations($table, $rec);
436  if (!empty($localizationData)) {
437  $lines = array_merge($lines, $localizationData);
438  }
439  } else {
440  unset($this->clipData[$pad]['el'][$k]);
441  $this->changed = 1;
442  }
443  }
444  }
445  }
446  }
447  $this->endClipboard();
448  return $lines;
449  }
450 
456  public function hasElements()
457  {
458  foreach ($this->clipData as $data) {
459  if (isset($data['el']) && is_array($data['el']) && !empty($data['el'])) {
460  return true;
461  }
462  }
463 
464  return false;
465  }
466 
474  public function getLocalizations($table, $parentRec)
475  {
476  $lines = [];
477  $tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
478  if (BackendUtility::isTableLocalizable($table)) {
479  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
480  $queryBuilder->getRestrictions()
481  ->removeAll()
482  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
483 
484  $queryBuilder
485  ->select('*')
486  ->from($table)
487  ->where(
488  $queryBuilder->expr()->eq(
489  $tcaCtrl['transOrigPointerField'],
490  $queryBuilder->createNamedParameter($parentRec['uid'], \PDO::PARAM_INT)
491  ),
492  $queryBuilder->expr()->neq(
493  $tcaCtrl['languageField'],
494  $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
495  ),
496  $queryBuilder->expr()->gt(
497  'pid',
498  $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)
499  )
500  );
501 
502  if (isset($tcaCtrl['versioningWS']) && $tcaCtrl['versioningWS']) {
503  $queryBuilder
504  ->andWhere(
505  $queryBuilder->expr()->eq(
506  't3ver_wsid',
507  $queryBuilder->createNamedParameter($parentRec['t3ver_wsid'], \PDO::PARAM_INT)
508  )
509  );
510  }
511  $rows = $queryBuilder->execute()->fetchAll();
512  if (is_array($rows)) {
513  foreach ($rows as $rec) {
514  $lines[] = [
515  'icon' => $this->iconFactory->getIconForRecord($table, $rec, Icon::SIZE_SMALL)->render(),
516  'title' => htmlspecialchars(GeneralUtility::fixed_lgd_cs(BackendUtility::getRecordTitle($table, $rec), $this->getBackendUser()->uc['titleLen']))
517  ];
518  }
519  }
520  }
521  return $lines;
522  }
523 
530  public function padTitle($pad)
531  {
532  $el = count($this->elFromTable($this->fileMode ? '_FILE' : '', $pad));
533  if ($el) {
534  return ' (' . ($pad === 'normal' ? ($this->clipData['normal']['mode'] === 'copy' ? $this->clLabel('copy', 'cm') : $this->clLabel('cut', 'cm')) : htmlspecialchars($el)) . ')';
535  }
536  return '';
537  }
538 
547  public function linkItemText($str, $rec, $table = '')
548  {
549  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
550  if (is_array($rec) && $table) {
551  if ($this->fileMode) {
552  $str = '<span class="text-muted">' . $str . '</span>';
553  } else {
554  $str = '<a href="' . htmlspecialchars((string)$uriBuilder->buildUriFromRoute('web_list', ['id' => $rec['pid']])) . '">' . $str . '</a>';
555  }
556  } elseif (file_exists($rec)) {
557  if (!$this->fileMode) {
558  $str = '<span class="text-muted">' . $str . '</span>';
559  } elseif (ExtensionManagementUtility::isLoaded('filelist')) {
560  $str = '<a href="' . htmlspecialchars((string)$uriBuilder->buildUriFromRoute('file_list', ['id' => PathUtility::dirname($rec)])) . '">' . $str . '</a>';
561  }
562  }
563  return $str;
564  }
565 
576  public function selUrlDB($table, $uid, $copy = 0, $deselect = 0, $baseArray = [])
577  {
578  $CB = ['el' => [rawurlencode($table . '|' . $uid) => $deselect ? 0 : 1]];
579  if ($copy) {
580  $CB['setCopyMode'] = 1;
581  }
582  $baseArray['CB'] = $CB;
583  return GeneralUtility::linkThisScript($baseArray);
584  }
585 
595  public function selUrlFile($path, $copy = 0, $deselect = 0, $baseArray = [])
596  {
597  $CB = ['el' => [rawurlencode('_FILE|' . GeneralUtility::shortMD5($path)) => $deselect ? '' : $path]];
598  if ($copy) {
599  $CB['setCopyMode'] = 1;
600  }
601  $baseArray['CB'] = $CB;
602  return GeneralUtility::linkThisScript($baseArray);
603  }
604 
616  public function pasteUrl($table, $uid, $setRedirect = true, array $update = null)
617  {
618  $urlParameters = [
619  'CB[paste]' => $table . '|' . $uid,
620  'CB[pad]' => $this->current
621  ];
622  if ($setRedirect) {
623  $urlParameters['redirect'] = GeneralUtility::linkThisScript(['CB' => '']);
624  }
625  if (is_array($update)) {
626  $urlParameters['CB[update]'] = $update;
627  }
628  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
629  return (string)$uriBuilder->buildUriFromRoute($table === '_FILE' ? 'tce_file' : 'tce_db', $urlParameters);
630  }
631 
639  public function deleteUrl($setRedirect = true, $file = false)
640  {
641  $urlParameters = [
642  'CB[delete]' => 1,
643  'CB[pad]' => $this->current
644  ];
645  if ($setRedirect) {
646  $urlParameters['redirect'] = GeneralUtility::linkThisScript(['CB' => '']);
647  }
648  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
649  return (string)$uriBuilder->buildUriFromRoute($file ? 'tce_file' : 'tce_db', $urlParameters);
650  }
651 
659  public function editUrl()
660  {
661  $parameters = [];
662  // All records
663  $elements = $this->elFromTable('');
664  foreach ($elements as $tP => $value) {
665  list($table, $uid) = explode('|', $tP);
666  $parameters['edit[' . $table . '][' . $uid . ']'] = 'edit';
667  }
668  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
669  return (string)$uriBuilder->buildUriFromRoute('record_edit', $parameters);
670  }
671 
680  public function removeUrl($table, $uid)
681  {
682  return GeneralUtility::linkThisScript(['CB' => ['remove' => $table . '|' . $uid]]);
683  }
684 
695  public function confirmMsgText($table, $rec, $type, $clElements, $columnLabel = '')
696  {
697  if ($this->getBackendUser()->jsConfirmation(JsConfirmation::COPY_MOVE_PASTE)) {
698  $labelKey = 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:mess.' . ($this->currentMode() === 'copy' ? 'copy' : 'move') . ($this->current === 'normal' ? '' : 'cb') . '_' . $type;
699  $msg = $this->getLanguageService()->sL($labelKey . ($columnLabel ? '_colPos' : ''));
700  if ($table === '_FILE') {
701  $thisRecTitle = PathUtility::basename($rec);
702  if ($this->current === 'normal') {
703  $selItem = reset($clElements);
704  $selRecTitle = PathUtility::basename($selItem);
705  } else {
706  $selRecTitle = count($clElements);
707  }
708  } else {
709  $thisRecTitle = $table === 'pages' && !is_array($rec) ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] : BackendUtility::getRecordTitle($table, $rec);
710  if ($this->current === 'normal') {
711  $selItem = $this->getSelectedRecord();
712  $selRecTitle = $selItem['_RECORD_TITLE'];
713  } else {
714  $selRecTitle = count($clElements);
715  }
716  }
717  // @TODO
718  // This can get removed as soon as the "_colPos" label is translated
719  // into all available locallang languages.
720  if (!$msg && $columnLabel) {
721  $thisRecTitle .= ' | ' . $columnLabel;
722  $msg = $this->getLanguageService()->sL($labelKey);
723  }
724 
725  // Message
726  $conf = sprintf(
727  $msg,
728  GeneralUtility::fixed_lgd_cs($selRecTitle, 30),
729  GeneralUtility::fixed_lgd_cs($thisRecTitle, 30),
730  GeneralUtility::fixed_lgd_cs($columnLabel, 30)
731  );
732  } else {
733  $conf = '';
734  }
735  return $conf;
736  }
737 
745  public function clLabel($key, $Akey = 'labels')
746  {
747  return htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:' . $Akey . '.' . $key));
748  }
749 
755  protected function exportClipElementParameters()
756  {
757  // Init
758  $pad = $this->current;
759  $params = [];
760  $params['tx_impexp']['action'] = 'export';
761  // Traverse items:
762  if (is_array($this->clipData[$pad]['el'] ?? false)) {
763  foreach ($this->clipData[$pad]['el'] as $k => $v) {
764  if ($v) {
765  list($table, $uid) = explode('|', $k);
766  // Rendering files/directories on the clipboard
767  if ($table === '_FILE') {
768  $file = ResourceFactory::getInstance()->getObjectFromCombinedIdentifier($v);
769  if ($file instanceof AbstractFile) {
770  $params['tx_impexp']['record'][] = 'sys_file:' . $file->getUid();
771  }
772  } else {
773  // Rendering records:
774  $rec = BackendUtility::getRecord($table, $uid);
775  if (is_array($rec)) {
776  $params['tx_impexp']['record'][] = $table . ':' . $uid;
777  }
778  }
779  }
780  }
781  }
782  return $params;
783  }
784 
785  /*****************************************
786  *
787  * Helper functions
788  *
789  ****************************************/
795  public function removeElement($el)
796  {
797  unset($this->clipData[$this->current]['el'][$el]);
798  $this->changed = 1;
799  }
800 
807  public function saveClipboard()
808  {
809  $this->getBackendUser()->pushModuleData('clipboard', $this->clipData);
810  }
811 
817  public function currentMode()
818  {
819  return ($this->clipData[$this->current]['mode'] ?? '') === 'copy' ? 'copy' : 'cut';
820  }
821 
826  public function cleanCurrent()
827  {
828  if (is_array($this->clipData[$this->current]['el'] ?? false)) {
829  foreach ($this->clipData[$this->current]['el'] as $k => $v) {
830  list($table, $uid) = explode('|', $k);
831  if ($table !== '_FILE') {
832  if (!$v || !is_array(BackendUtility::getRecord($table, $uid, 'uid'))) {
833  unset($this->clipData[$this->current]['el'][$k]);
834  $this->changed = 1;
835  }
836  } else {
837  if (!$v) {
838  unset($this->clipData[$this->current]['el'][$k]);
839  $this->changed = 1;
840  } else {
841  try {
842  ResourceFactory::getInstance()->retrieveFileOrFolderObject($v);
843  } catch (\TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException $e) {
844  // The file has been deleted in the meantime, so just remove it silently
845  unset($this->clipData[$this->current]['el'][$k]);
846  }
847  }
848  }
849  }
850  }
851  }
852 
860  public function elFromTable($matchTable = '', $pad = '')
861  {
862  $pad = $pad ? $pad : $this->current;
863  $list = [];
864  if (is_array($this->clipData[$pad]['el'] ?? false)) {
865  foreach ($this->clipData[$pad]['el'] as $k => $v) {
866  if ($v) {
867  list($table, $uid) = explode('|', $k);
868  if ($table !== '_FILE') {
869  if ((!$matchTable || (string)$table == (string)$matchTable) && $GLOBALS['TCA'][$table]) {
870  $list[$k] = $pad === 'normal' ? $v : $uid;
871  }
872  } else {
873  if ((string)$table == (string)$matchTable) {
874  $list[$k] = $v;
875  }
876  }
877  }
878  }
879  }
880  return $list;
881  }
882 
891  public function isSelected($table, $uid)
892  {
893  $k = $table . '|' . $uid;
894  return !empty($this->clipData[$this->current]['el'][$k]) ? ($this->current === 'normal' ? $this->currentMode() : 1) : '';
895  }
896 
906  public function getSelectedRecord($table = '', $uid = '')
907  {
908  if (!$table && !$uid) {
909  $elArr = $this->elFromTable('');
910  reset($elArr);
911  list($table, $uid) = explode('|', key($elArr));
912  }
913  if ($this->isSelected($table, $uid)) {
914  $selRec = BackendUtility::getRecordWSOL($table, $uid);
915  $selRec['_RECORD_TITLE'] = BackendUtility::getRecordTitle($table, $selRec);
916  return $selRec;
917  }
918  return [];
919  }
920 
926  public function isElements()
927  {
928  return is_array($this->clipData[$this->current]['el']) && !empty($this->clipData[$this->current]['el']);
929  }
930 
949  public function makePasteCmdArray($ref, $CMD, array $update = null)
950  {
951  list($pTable, $pUid) = explode('|', $ref);
952  $pUid = (int)$pUid;
953  // pUid must be set and if pTable is not set (that means paste ALL elements)
954  // the uid MUST be positive/zero (pointing to page id)
955  if ($pTable || $pUid >= 0) {
956  $elements = $this->elFromTable($pTable);
957  // So the order is preserved.
958  $elements = array_reverse($elements);
959  $mode = $this->currentMode() === 'copy' ? 'copy' : 'move';
960  // Traverse elements and make CMD array
961  foreach ($elements as $tP => $value) {
962  list($table, $uid) = explode('|', $tP);
963  if (!is_array($CMD[$table])) {
964  $CMD[$table] = [];
965  }
966  if (is_array($update)) {
967  $CMD[$table][$uid][$mode] = [
968  'action' => 'paste',
969  'target' => $pUid,
970  'update' => $update,
971  ];
972  } else {
973  $CMD[$table][$uid][$mode] = $pUid;
974  }
975  if ($mode === 'move') {
976  $this->removeElement($tP);
977  }
978  }
979  $this->endClipboard();
980  }
981  return $CMD;
982  }
983 
990  public function makeDeleteCmdArray($CMD)
991  {
992  // all records
993  $elements = $this->elFromTable('');
994  foreach ($elements as $tP => $value) {
995  list($table, $uid) = explode('|', $tP);
996  if (!is_array($CMD[$table])) {
997  $CMD[$table] = [];
998  }
999  $CMD[$table][$uid]['delete'] = 1;
1000  $this->removeElement($tP);
1001  }
1002  $this->endClipboard();
1003  return $CMD;
1004  }
1005 
1006  /*****************************************
1007  *
1008  * FOR USE IN tce_file.php:
1009  *
1010  ****************************************/
1019  public function makePasteCmdArray_file($ref, $FILE)
1020  {
1021  list($pTable, $pUid) = explode('|', $ref);
1022  $elements = $this->elFromTable('_FILE');
1023  $mode = $this->currentMode() === 'copy' ? 'copy' : 'move';
1024  // Traverse elements and make CMD array
1025  foreach ($elements as $tP => $path) {
1026  $FILE[$mode][] = ['data' => $path, 'target' => $pUid];
1027  if ($mode === 'move') {
1028  $this->removeElement($tP);
1029  }
1030  }
1031  $this->endClipboard();
1032  return $FILE;
1033  }
1034 
1041  public function makeDeleteCmdArray_file($FILE)
1042  {
1043  $elements = $this->elFromTable('_FILE');
1044  // Traverse elements and make CMD array
1045  foreach ($elements as $tP => $path) {
1046  $FILE['delete'][] = ['data' => $path];
1047  $this->removeElement($tP);
1048  }
1049  $this->endClipboard();
1050  return $FILE;
1051  }
1052 
1058  protected function getLanguageService()
1059  {
1060  return $GLOBALS['LANG'];
1061  }
1062 
1068  protected function getBackendUser()
1069  {
1070  return $GLOBALS['BE_USER'];
1071  }
1080  protected function getStandaloneView()
1081  {
1083  $view = GeneralUtility::makeInstance(StandaloneView::class);
1084  $view->setLayoutRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Layouts')]);
1085  $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
1086  $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
1087 
1088  $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/‪Clipboard/Main.html'));
1089 
1090  $view->getRequest()->setControllerExtensionName('Backend');
1091  return $view;
1092  }
1093 }
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:29
‪TYPO3\CMS\Backend\Clipboard\Clipboard\__construct
‪__construct()
Definition: Clipboard.php:96
‪TYPO3\CMS\Backend\Clipboard\Clipboard\setCurrentPad
‪setCurrentPad($padIdent)
Definition: Clipboard.php:188
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:23
‪TYPO3\CMS\Backend\Clipboard\Clipboard
Definition: Clipboard.php:38
‪TYPO3\CMS\Backend\Clipboard\Clipboard\cleanUpCBC
‪array cleanUpCBC($CBarr, $table, $removeDeselected=0)
Definition: Clipboard.php:223
‪TYPO3\CMS\Backend\Clipboard\Clipboard\printClipboard
‪string printClipboard()
Definition: Clipboard.php:247
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:25
‪TYPO3\CMS\Backend\Clipboard\Clipboard\isElements
‪bool isElements()
Definition: Clipboard.php:918
‪TYPO3\CMS\Backend\Clipboard\Clipboard\removeElement
‪removeElement($el)
Definition: Clipboard.php:787
‪TYPO3
‪TYPO3\CMS\Core\Utility\MathUtility\forceIntegerInRange
‪static int forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
‪TYPO3\CMS\Backend\Clipboard\Clipboard\lockToNormal
‪lockToNormal()
Definition: Clipboard.php:130
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getTSConfig
‪array getTSConfig($objectString=null, $config=null)
Definition: BackendUserAuthentication.php:1232
‪TYPO3\CMS\Core\Resource\ResourceFactory\getInstance
‪static ResourceFactory getInstance()
Definition: ResourceFactory.php:39
‪TYPO3\CMS\Backend\Clipboard\Clipboard\removeUrl
‪string removeUrl($table, $uid)
Definition: Clipboard.php:672
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:31
‪TYPO3\CMS\Backend\Clipboard\Clipboard\clLabel
‪string clLabel($key, $Akey='labels')
Definition: Clipboard.php:737
‪TYPO3\CMS\Backend\Clipboard\Clipboard\getLanguageService
‪TYPO3 CMS Core Localization LanguageService getLanguageService()
Definition: Clipboard.php:1050
‪TYPO3\CMS\Backend\Clipboard\Clipboard\initializeClipboard
‪initializeClipboard()
Definition: Clipboard.php:110
‪TYPO3\CMS\Backend\Utility\BackendUtility\wrapInHelp
‪static string wrapInHelp($table, $field, $text='', array $overloadHelpText=[])
Definition: BackendUtility.php:2519
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:36
‪TYPO3\CMS\Core\Type\Bitmask\JsConfirmation\DELETE
‪const DELETE
Definition: JsConfirmation.php:38
‪TYPO3\CMS\Backend\Clipboard\Clipboard\currentMode
‪string currentMode()
Definition: Clipboard.php:809
‪TYPO3\CMS\Core\Resource\AbstractFile
Definition: AbstractFile.php:24
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:35
‪TYPO3\CMS\Backend\Clipboard\Clipboard\getBackendUser
‪TYPO3 CMS Core Authentication BackendUserAuthentication getBackendUser()
Definition: Clipboard.php:1060
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication\getModuleData
‪mixed getModuleData($module, $type='')
Definition: AbstractUserAuthentication.php:1233
‪TYPO3\CMS\Backend\Clipboard\Clipboard\padTitle
‪string padTitle($pad)
Definition: Clipboard.php:522
‪TYPO3\CMS\Backend\Clipboard\Clipboard\setCmd
‪setCmd($cmd)
Definition: Clipboard.php:147
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:33
‪TYPO3\CMS\Backend\Clipboard\Clipboard\$fileMode
‪bool $fileMode
Definition: Clipboard.php:81
‪TYPO3\CMS\Backend\Clipboard\Clipboard\linkItemText
‪string linkItemText($str, $rec, $table='')
Definition: Clipboard.php:539
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordTitle
‪static string getRecordTitle($table, $row, $prep=false, $forceResult=true)
Definition: BackendUtility.php:1811
‪TYPO3\CMS\Backend\Clipboard\Clipboard\$iconFactory
‪IconFactory $iconFactory
Definition: Clipboard.php:85
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static bool isLoaded($key, $exitOnError=null)
Definition: ExtensionManagementUtility.php:115
‪TYPO3\CMS\Backend\Clipboard\Clipboard\$current
‪string $current
Definition: Clipboard.php:71
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:72
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordWSOL
‪static array getRecordWSOL( $table, $uid, $fields=' *', $where='', $useDeleteClause=true, $unsetMovePointers=false)
Definition: BackendUtility.php:174
‪TYPO3\CMS\Backend\Clipboard\Clipboard\$clipData
‪array $clipData
Definition: Clipboard.php:63
‪TYPO3\CMS\Backend\Clipboard\Clipboard\$view
‪StandaloneView $view
Definition: Clipboard.php:89
‪TYPO3\CMS\Backend\Clipboard\Clipboard\endClipboard
‪endClipboard()
Definition: Clipboard.php:207
‪TYPO3\CMS\Backend\Clipboard\Clipboard\deleteUrl
‪string deleteUrl($setRedirect=true, $file=false)
Definition: Clipboard.php:631
‪TYPO3\CMS\Backend\Clipboard\Clipboard\saveClipboard
‪saveClipboard()
Definition: Clipboard.php:799
‪TYPO3\CMS\Fluid\View\StandaloneView
Definition: StandaloneView.php:32
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:26
‪TYPO3\CMS\Backend\Clipboard\Clipboard\getContentFromTab
‪array getContentFromTab($pad)
Definition: Clipboard.php:365
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:21
‪TYPO3\CMS\Backend\Clipboard\Clipboard\$changed
‪int $changed
Definition: Clipboard.php:67
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Backend\Clipboard
Definition: Clipboard.php:2
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Type\Bitmask\JsConfirmation
Definition: JsConfirmation.php:24
‪TYPO3\CMS\Backend\Clipboard\Clipboard\$numberTabs
‪int $numberTabs
Definition: Clipboard.php:41
‪TYPO3\CMS\Backend\Clipboard\Clipboard\getStandaloneView
‪StandaloneView getStandaloneView()
Definition: Clipboard.php:1072
‪TYPO3\CMS\Backend\Clipboard\Clipboard\editUrl
‪string editUrl()
Definition: Clipboard.php:651
‪TYPO3\CMS\Core\Resource\ResourceFactory\retrieveFileOrFolderObject
‪File Folder null retrieveFileOrFolderObject($input)
Definition: ResourceFactory.php:491
‪TYPO3\CMS\Backend\Clipboard\Clipboard\elFromTable
‪array elFromTable($matchTable='', $pad='')
Definition: Clipboard.php:852
‪TYPO3\CMS\Backend\Clipboard\Clipboard\$lockToNormal
‪int $lockToNormal
Definition: Clipboard.php:75
‪TYPO3\CMS\Backend\Clipboard\Clipboard\exportClipElementParameters
‪array exportClipElementParameters()
Definition: Clipboard.php:747