TYPO3 CMS  TYPO3_8-7
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 
29 
33 class Clipboard
34 {
38  public $numberTabs = 3;
39 
61  public $clipData = [];
62 
66  public $changed = 0;
67 
71  public $current = '';
72 
76  public $lockToNormal = 0;
77 
83  public $fileMode = 0;
84 
88  protected $iconFactory;
89 
93  protected $view;
94 
100  public function __construct()
101  {
102  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
103  $this->view = $this->getStandaloneView();
104  }
105 
106  /*****************************************
107  *
108  * Initialize
109  *
110  ****************************************/
114  public function initializeClipboard()
115  {
116  // Get data
117  $clipData = $this->getBackendUser()->getModuleData('clipboard', $this->getBackendUser()->getTSConfigVal('options.saveClipboard') ? '' : 'ses');
118  // NumberTabs
119  $clNP = $this->getBackendUser()->getTSConfigVal('options.clipboardNumberPads');
120  if (MathUtility::canBeInterpretedAsInteger($clNP) && $clNP >= 0) {
121  $this->numberTabs = MathUtility::forceIntegerInRange($clNP, 0, 20);
122  }
123  // Resets/reinstates the clipboard pads
124  $this->clipData['normal'] = is_array($clipData['normal']) ? $clipData['normal'] : [];
125  for ($a = 1; $a <= $this->numberTabs; $a++) {
126  $this->clipData['tab_' . $a] = is_array($clipData['tab_' . $a]) ? $clipData['tab_' . $a] : [];
127  }
128  // Setting the current pad pointer ($this->current))
129  $this->clipData['current'] = ($this->current = isset($this->clipData[$clipData['current']]) ? $clipData['current'] : 'normal');
130  }
131 
137  public function lockToNormal()
138  {
139  $this->lockToNormal = 1;
140  $this->current = 'normal';
141  }
142 
154  public function setCmd($cmd)
155  {
156  if (is_array($cmd['el'])) {
157  foreach ($cmd['el'] as $k => $v) {
158  if ($this->current === 'normal') {
159  unset($this->clipData['normal']);
160  }
161  if ($v) {
162  $this->clipData[$this->current]['el'][$k] = $v;
163  } else {
164  $this->removeElement($k);
165  }
166  $this->changed = 1;
167  }
168  }
169  // Change clipboard pad (if not locked to normal)
170  if ($cmd['setP']) {
171  $this->setCurrentPad($cmd['setP']);
172  }
173  // Remove element (value = item ident: DB; '[tablename]|[uid]' FILE: '_FILE|[shortmd5 hash of path]'
174  if ($cmd['remove']) {
175  $this->removeElement($cmd['remove']);
176  $this->changed = 1;
177  }
178  // Remove all on current pad (value = pad-ident)
179  if ($cmd['removeAll']) {
180  $this->clipData[$cmd['removeAll']] = [];
181  $this->changed = 1;
182  }
183  // Set copy mode of the tab
184  if (isset($cmd['setCopyMode'])) {
185  $this->clipData[$this->current]['mode'] = $this->isElements() ? ($cmd['setCopyMode'] ? 'copy' : '') : '';
186  $this->changed = 1;
187  }
188  }
189 
195  public function setCurrentPad($padIdent)
196  {
197  // Change clipboard pad (if not locked to normal)
198  if (!$this->lockToNormal && $this->current != $padIdent) {
199  if (isset($this->clipData[$padIdent])) {
200  $this->clipData['current'] = ($this->current = $padIdent);
201  }
202  if ($this->current !== 'normal' || !$this->isElements()) {
203  $this->clipData[$this->current]['mode'] = '';
204  }
205  // Setting mode to default (move) if no items on it or if not 'normal'
206  $this->changed = 1;
207  }
208  }
209 
214  public function endClipboard()
215  {
216  if ($this->changed) {
217  $this->saveClipboard();
218  }
219  $this->changed = 0;
220  }
221 
230  public function cleanUpCBC($CBarr, $table, $removeDeselected = 0)
231  {
232  if (is_array($CBarr)) {
233  foreach ($CBarr as $k => $v) {
234  $p = explode('|', $k);
235  if ((string)$p[0] != (string)$table || $removeDeselected && !$v) {
236  unset($CBarr[$k]);
237  }
238  }
239  }
240  return $CBarr;
241  }
242 
243  /*****************************************
244  *
245  * Clipboard HTML renderings
246  *
247  ****************************************/
254  public function printClipboard()
255  {
256  $languageService = $this->getLanguageService();
257  $elementCount = count($this->elFromTable($this->fileMode ? '_FILE' : ''));
258  // Copymode Selector menu
259  $copymodeUrl = GeneralUtility::linkThisScript();
260 
261  $this->view->assign('actionCopyModeUrl', htmlspecialchars(GeneralUtility::quoteJSvalue($copymodeUrl . '&CB[setCopyMode]=')));
262  $this->view->assign('actionCopyModeUrl1', htmlspecialchars(GeneralUtility::quoteJSvalue($copymodeUrl . '&CB[setCopyMode]=1')));
263  $this->view->assign('currentMode', $this->currentMode());
264  $this->view->assign('elementCount', $elementCount);
265 
266  if ($elementCount) {
267  $removeAllUrl = GeneralUtility::linkThisScript(['CB' => ['removeAll' => $this->current]]);
268  $this->view->assign('removeAllUrl', $removeAllUrl);
269 
270  // Selector menu + clear button
271  $optionArray = [];
272  // Import / Export link:
273  if (ExtensionManagementUtility::isLoaded('impexp')) {
274  $url = BackendUtility::getModuleUrl('xMOD_tximpexp', $this->exportClipElementParameters());
275  $optionArray[] = [
276  'label' => $this->clLabel('export', 'rm'),
277  'uri' => $url
278  ];
279  }
280  // Edit:
281  if (!$this->fileMode) {
282  $optionArray[] = [
283  'label' => $this->clLabel('edit', 'rm'),
284  'uri' => '#',
285  'additionalAttributes' => [
286  'onclick' => htmlspecialchars('window.location.href=' . GeneralUtility::quoteJSvalue($this->editUrl() . '&returnUrl=') . '+top.rawurlencode(window.location.href);'),
287  ]
288  ];
289  }
290 
291  // Delete referenced elements:
292  $confirmationCheck = false;
293  if ($this->getBackendUser()->jsConfirmation(JsConfirmation::DELETE)) {
294  $confirmationCheck = true;
295  }
296 
297  $confirmationMessage = sprintf(
298  $languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:mess.deleteClip'),
299  $elementCount
300  );
301  $title = $languageService
302  ->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.clipboard.delete_elements');
303  $returnUrl = $this->deleteUrl(1, ($this->fileMode ? 1 : 0));
304  $btnOkText = $languageService
305  ->sL('LLL:EXT:lang/Resources/Private/Language/locallang_alt_doc.xlf:buttons.confirm.delete_elements.yes');
306  $btnCancelText = $languageService
307  ->sL('LLL:EXT:lang/Resources/Private/Language/locallang_alt_doc.xlf:buttons.confirm.delete_elements.no');
308  $optionArray[] = [
309  'label' => htmlspecialchars($title),
310  'uri' => $returnUrl,
311  'additionalAttributes' => [
312  'class' => $confirmationCheck ? 't3js-modal-trigger' : '',
313  ],
314  'data' => [
315  'severity' => 'warning',
316  'button-close-text' => htmlspecialchars($btnCancelText),
317  'button-ok-text' => htmlspecialchars($btnOkText),
318  'content' => htmlspecialchars($confirmationMessage),
319  'title' => htmlspecialchars($title)
320  ]
321  ];
322 
323  // Clear clipboard
324  $optionArray[] = [
325  'label' => $languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.clipboard.clear_clipboard', true),
326  'uri' => $removeAllUrl . '#clip_head'
327  ];
328  $this->view->assign('optionArray', $optionArray);
329  }
330 
331  // Print header and content for the NORMAL tab:
332  $this->view->assign('current', $this->current);
333  $tabArray = [];
334  $tabArray['normal'] = [
335  'id' => 'normal',
336  'number' => 0,
337  'url' => GeneralUtility::linkThisScript(['CB' => ['setP' => 'normal']]),
338  'description' => 'normal-description',
339  'label' => 'labels.normal',
340  'padding' => $this->padTitle('normal')
341  ];
342  if ($this->current === 'normal') {
343  $tabArray['normal']['content'] = $this->getContentFromTab('normal');
344  }
345  // Print header and content for the NUMERIC tabs:
346  for ($a = 1; $a <= $this->numberTabs; $a++) {
347  $tabArray['tab_' . $a] = [
348  'id' => 'tab_' . $a,
349  'number' => $a,
350  'url' => GeneralUtility::linkThisScript(['CB' => ['setP' => 'tab_' . $a]]),
351  'description' => 'cliptabs-description',
352  'label' => 'labels.cliptabs-name',
353  'padding' => $this->padTitle('tab_' . $a)
354  ];
355  if ($this->current === 'tab_' . $a) {
356  $tabArray['tab_' . $a]['content'] = $this->getContentFromTab('tab_' . $a);
357  }
358  }
359  $this->view->assign('clipboardHeader', BackendUtility::wrapInHelp('xMOD_csh_corebe', 'list_clipboard', $this->clLabel('clipboard', 'buttons')));
360  $this->view->assign('tabArray', $tabArray);
361  return $this->view->render();
362  }
363 
371  public function getContentFromTab($pad)
372  {
373  $lines = [];
374  if (is_array($this->clipData[$pad]['el'])) {
375  foreach ($this->clipData[$pad]['el'] as $k => $v) {
376  if ($v) {
377  list($table, $uid) = explode('|', $k);
378  // Rendering files/directories on the clipboard
379  if ($table === '_FILE') {
380  $fileObject = ResourceFactory::getInstance()->retrieveFileOrFolderObject($v);
381  if ($fileObject) {
382  $thumb = [];
383  $folder = $fileObject instanceof \TYPO3\CMS\Core\Resource\Folder;
384  $size = $folder ? '' : '(' . GeneralUtility::formatSize($fileObject->getSize()) . 'bytes)';
385  if (
386  !$folder
388  $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],
389  $fileObject->getExtension()
390  )
391  ) {
392  $thumb = [
393  'image' => $fileObject->process(\TYPO3\CMS\Core\Resource\ProcessedFile::CONTEXT_IMAGEPREVIEW, [])->getPublicUrl(true),
394  'title' => htmlspecialchars($fileObject->getName())
395  ];
396  }
397  $lines[] = [
398  'icon' => '<span title="' . htmlspecialchars($fileObject->getName() . ' ' . $size) . '">' . $this->iconFactory->getIconForResource(
399  $fileObject,
401  )->render() . '</span>',
402  'title' => $this->linkItemText(htmlspecialchars(GeneralUtility::fixed_lgd_cs(
403  $fileObject->getName(),
404  $this->getBackendUser()->uc['titleLen']
405  )), $fileObject->getName()),
406  'thumb' => $thumb,
407  'infoLink' => htmlspecialchars('top.launchView(' . GeneralUtility::quoteJSvalue($table) . ', ' . GeneralUtility::quoteJSvalue($v) . '); return false;'),
408  'removeLink' => $this->removeUrl('_FILE', GeneralUtility::shortMD5($v))
409  ];
410  } else {
411  // If the file did not exist (or is illegal) then it is removed from the clipboard immediately:
412  unset($this->clipData[$pad]['el'][$k]);
413  $this->changed = 1;
414  }
415  } else {
416  // Rendering records:
417  $rec = BackendUtility::getRecordWSOL($table, $uid);
418  if (is_array($rec)) {
419  $lines[] = [
420  'icon' => $this->linkItemText($this->iconFactory->getIconForRecord(
421  $table,
422  $rec,
424  )->render(), $rec, $table),
426  $table,
427  $rec
428  ), $this->getBackendUser()->uc['titleLen'])), $rec, $table),
429  'infoLink' => htmlspecialchars('top.launchView(' . GeneralUtility::quoteJSvalue($table) . ', \'' . (int)$uid . '\'); return false;'),
430  'removeLink' => $this->removeUrl($table, $uid)
431  ];
432 
433  $localizationData = $this->getLocalizations($table, $rec, '', '');
434  if (!empty($localizationData)) {
435  $lines = array_merge($lines, $localizationData);
436  }
437  } else {
438  unset($this->clipData[$pad]['el'][$k]);
439  $this->changed = 1;
440  }
441  }
442  }
443  }
444  }
445  $this->endClipboard();
446  return $lines;
447  }
448 
454  public function hasElements()
455  {
456  foreach ($this->clipData as $data) {
457  if (isset($data['el']) && is_array($data['el']) && !empty($data['el'])) {
458  return true;
459  }
460  }
461 
462  return false;
463  }
464 
474  public function getLocalizations($table, $parentRec, $bgColClass, $pad)
475  {
476  $lines = [];
477  $tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
478  if ($table !== 'pages' && BackendUtility::isTableLocalizable($table) && $table !== 'pages_language_overlay') {
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  if (is_array($rec) && $table) {
550  if ($this->fileMode) {
551  $str = '<span class="text-muted">' . $str . '</span>';
552  } else {
553  $str = '<a href="' . htmlspecialchars(BackendUtility::getModuleUrl('web_list', ['id' => $rec['pid']])) . '">' . $str . '</a>';
554  }
555  } elseif (file_exists($rec)) {
556  if (!$this->fileMode) {
557  $str = '<span class="text-muted">' . $str . '</span>';
558  } else {
559  if (ExtensionManagementUtility::isLoaded('filelist')) {
560  $str = '<a href="' . htmlspecialchars(BackendUtility::getModuleUrl('file_list', ['id' => dirname($rec)])) . '">' . $str . '</a>';
561  }
562  }
563  }
564  return $str;
565  }
566 
577  public function selUrlDB($table, $uid, $copy = 0, $deselect = 0, $baseArray = [])
578  {
579  $CB = ['el' => [rawurlencode($table . '|' . $uid) => $deselect ? 0 : 1]];
580  if ($copy) {
581  $CB['setCopyMode'] = 1;
582  }
583  $baseArray['CB'] = $CB;
584  return GeneralUtility::linkThisScript($baseArray);
585  }
586 
596  public function selUrlFile($path, $copy = 0, $deselect = 0, $baseArray = [])
597  {
598  $CB = ['el' => [rawurlencode('_FILE|' . GeneralUtility::shortMD5($path)) => $deselect ? '' : $path]];
599  if ($copy) {
600  $CB['setCopyMode'] = 1;
601  }
602  $baseArray['CB'] = $CB;
603  return GeneralUtility::linkThisScript($baseArray);
604  }
605 
617  public function pasteUrl($table, $uid, $setRedirect = true, array $update = null)
618  {
619  $urlParameters = [
620  'prErr' => 1,
621  'uPT' => 1,
622  'CB[paste]' => $table . '|' . $uid,
623  'CB[pad]' => $this->current
624  ];
625  if ($setRedirect) {
626  $urlParameters['redirect'] = GeneralUtility::linkThisScript(['CB' => '']);
627  }
628  if (is_array($update)) {
629  $urlParameters['CB[update]'] = $update;
630  }
631  return BackendUtility::getModuleUrl($table === '_FILE' ? 'tce_file' : 'tce_db', $urlParameters);
632  }
633 
641  public function deleteUrl($setRedirect = 1, $file = 0)
642  {
643  $urlParameters = [
644  'prErr' => 1,
645  'uPT' => 1,
646  'CB[delete]' => 1,
647  'CB[pad]' => $this->current
648  ];
649  if ($setRedirect) {
650  $urlParameters['redirect'] = GeneralUtility::linkThisScript(['CB' => '']);
651  }
652  return BackendUtility::getModuleUrl($file ? 'tce_file' : 'tce_db', $urlParameters);
653  }
654 
662  public function editUrl()
663  {
664  $parameters = [];
665  // All records
666  $elements = $this->elFromTable('');
667  foreach ($elements as $tP => $value) {
668  list($table, $uid) = explode('|', $tP);
669  $parameters['edit[' . $table . '][' . $uid . ']'] = 'edit';
670  }
671  return BackendUtility::getModuleUrl('record_edit', $parameters);
672  }
673 
682  public function removeUrl($table, $uid)
683  {
684  return GeneralUtility::linkThisScript(['CB' => ['remove' => $table . '|' . $uid]]);
685  }
686 
698  public function confirmMsg($table, $rec, $type, $clElements, $columnLabel = '')
699  {
700  GeneralUtility::logDeprecatedFunction();
701  $message = $this->confirmMsgText($table, $rec, $type, $clElements, $columnLabel);
702  if (!empty($message)) {
703  $message = 'confirm(' . GeneralUtility::quoteJSvalue($message) . ');';
704  }
705  return $message;
706  }
707 
718  public function confirmMsgText($table, $rec, $type, $clElements, $columnLabel = '')
719  {
720  if ($this->getBackendUser()->jsConfirmation(JsConfirmation::COPY_MOVE_PASTE)) {
721  $labelKey = 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:mess.' . ($this->currentMode() === 'copy' ? 'copy' : 'move') . ($this->current === 'normal' ? '' : 'cb') . '_' . $type;
722  $msg = $this->getLanguageService()->sL($labelKey . ($columnLabel ? '_colPos': ''));
723  if ($table === '_FILE') {
724  $thisRecTitle = basename($rec);
725  if ($this->current === 'normal') {
726  $selItem = reset($clElements);
727  $selRecTitle = basename($selItem);
728  } else {
729  $selRecTitle = count($clElements);
730  }
731  } else {
732  $thisRecTitle = $table === 'pages' && !is_array($rec) ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] : BackendUtility::getRecordTitle($table, $rec);
733  if ($this->current === 'normal') {
734  $selItem = $this->getSelectedRecord();
735  $selRecTitle = $selItem['_RECORD_TITLE'];
736  } else {
737  $selRecTitle = count($clElements);
738  }
739  }
740  // @TODO
741  // This can get removed as soon as the "_colPos" label is translated
742  // into all available locallang languages.
743  if (!$msg && $columnLabel) {
744  $thisRecTitle .= ' | ' . $columnLabel;
745  $msg = $this->getLanguageService()->sL($labelKey);
746  }
747 
748  // Message
749  $conf = sprintf(
750  $msg,
751  GeneralUtility::fixed_lgd_cs($selRecTitle, 30),
752  GeneralUtility::fixed_lgd_cs($thisRecTitle, 30),
753  GeneralUtility::fixed_lgd_cs($columnLabel, 30)
754  );
755  } else {
756  $conf = '';
757  }
758  return $conf;
759  }
760 
768  public function clLabel($key, $Akey = 'labels')
769  {
770  return htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:' . $Akey . '.' . $key));
771  }
772 
778  protected function exportClipElementParameters()
779  {
780  // Init
781  $pad = $this->current;
782  $params = [];
783  $params['tx_impexp']['action'] = 'export';
784  // Traverse items:
785  if (is_array($this->clipData[$pad]['el'])) {
786  foreach ($this->clipData[$pad]['el'] as $k => $v) {
787  if ($v) {
788  list($table, $uid) = explode('|', $k);
789  // Rendering files/directories on the clipboard
790  if ($table === '_FILE') {
791  $file = ResourceFactory::getInstance()->getObjectFromCombinedIdentifier($v);
792  if ($file instanceof AbstractFile) {
793  $params['tx_impexp']['record'][] = 'sys_file:' . $file->getUid();
794  }
795  } else {
796  // Rendering records:
797  $rec = BackendUtility::getRecord($table, $uid);
798  if (is_array($rec)) {
799  $params['tx_impexp']['record'][] = $table . ':' . $uid;
800  }
801  }
802  }
803  }
804  }
805  return $params;
806  }
807 
808  /*****************************************
809  *
810  * Helper functions
811  *
812  ****************************************/
818  public function removeElement($el)
819  {
820  unset($this->clipData[$this->current]['el'][$el]);
821  $this->changed = 1;
822  }
823 
830  public function saveClipboard()
831  {
832  $this->getBackendUser()->pushModuleData('clipboard', $this->clipData);
833  }
834 
840  public function currentMode()
841  {
842  return $this->clipData[$this->current]['mode'] === 'copy' ? 'copy' : 'cut';
843  }
844 
849  public function cleanCurrent()
850  {
851  if (is_array($this->clipData[$this->current]['el'])) {
852  foreach ($this->clipData[$this->current]['el'] as $k => $v) {
853  list($table, $uid) = explode('|', $k);
854  if ($table !== '_FILE') {
855  if (!$v || !is_array(BackendUtility::getRecord($table, $uid, 'uid'))) {
856  unset($this->clipData[$this->current]['el'][$k]);
857  $this->changed = 1;
858  }
859  } else {
860  if (!$v) {
861  unset($this->clipData[$this->current]['el'][$k]);
862  $this->changed = 1;
863  } else {
864  try {
865  ResourceFactory::getInstance()->retrieveFileOrFolderObject($v);
866  } catch (\TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException $e) {
867  // The file has been deleted in the meantime, so just remove it silently
868  unset($this->clipData[$this->current]['el'][$k]);
869  }
870  }
871  }
872  }
873  }
874  }
875 
883  public function elFromTable($matchTable = '', $pad = '')
884  {
885  $pad = $pad ? $pad : $this->current;
886  $list = [];
887  if (is_array($this->clipData[$pad]['el'])) {
888  foreach ($this->clipData[$pad]['el'] as $k => $v) {
889  if ($v) {
890  list($table, $uid) = explode('|', $k);
891  if ($table !== '_FILE') {
892  if ((!$matchTable || (string)$table == (string)$matchTable) && $GLOBALS['TCA'][$table]) {
893  $list[$k] = $pad === 'normal' ? $v : $uid;
894  }
895  } else {
896  if ((string)$table == (string)$matchTable) {
897  $list[$k] = $v;
898  }
899  }
900  }
901  }
902  }
903  return $list;
904  }
905 
914  public function isSelected($table, $uid)
915  {
916  $k = $table . '|' . $uid;
917  return $this->clipData[$this->current]['el'][$k] ? ($this->current === 'normal' ? $this->currentMode() : 1) : '';
918  }
919 
929  public function getSelectedRecord($table = '', $uid = '')
930  {
931  if (!$table && !$uid) {
932  $elArr = $this->elFromTable('');
933  reset($elArr);
934  list($table, $uid) = explode('|', key($elArr));
935  }
936  if ($this->isSelected($table, $uid)) {
937  $selRec = BackendUtility::getRecordWSOL($table, $uid);
938  $selRec['_RECORD_TITLE'] = BackendUtility::getRecordTitle($table, $selRec);
939  return $selRec;
940  }
941  return [];
942  }
943 
949  public function isElements()
950  {
951  return is_array($this->clipData[$this->current]['el']) && !empty($this->clipData[$this->current]['el']);
952  }
953 
972  public function makePasteCmdArray($ref, $CMD, array $update = null)
973  {
974  list($pTable, $pUid) = explode('|', $ref);
975  $pUid = (int)$pUid;
976  // pUid must be set and if pTable is not set (that means paste ALL elements)
977  // the uid MUST be positive/zero (pointing to page id)
978  if ($pTable || $pUid >= 0) {
979  $elements = $this->elFromTable($pTable);
980  // So the order is preserved.
981  $elements = array_reverse($elements);
982  $mode = $this->currentMode() === 'copy' ? 'copy' : 'move';
983  // Traverse elements and make CMD array
984  foreach ($elements as $tP => $value) {
985  list($table, $uid) = explode('|', $tP);
986  if (!is_array($CMD[$table])) {
987  $CMD[$table] = [];
988  }
989  if (is_array($update)) {
990  $CMD[$table][$uid][$mode] = [
991  'action' => 'paste',
992  'target' => $pUid,
993  'update' => $update,
994  ];
995  } else {
996  $CMD[$table][$uid][$mode] = $pUid;
997  }
998  if ($mode === 'move') {
999  $this->removeElement($tP);
1000  }
1001  }
1002  $this->endClipboard();
1003  }
1004  return $CMD;
1005  }
1006 
1013  public function makeDeleteCmdArray($CMD)
1014  {
1015  // all records
1016  $elements = $this->elFromTable('');
1017  foreach ($elements as $tP => $value) {
1018  list($table, $uid) = explode('|', $tP);
1019  if (!is_array($CMD[$table])) {
1020  $CMD[$table] = [];
1021  }
1022  $CMD[$table][$uid]['delete'] = 1;
1023  $this->removeElement($tP);
1024  }
1025  $this->endClipboard();
1026  return $CMD;
1027  }
1028 
1029  /*****************************************
1030  *
1031  * FOR USE IN tce_file.php:
1032  *
1033  ****************************************/
1042  public function makePasteCmdArray_file($ref, $FILE)
1043  {
1044  list($pTable, $pUid) = explode('|', $ref);
1045  $elements = $this->elFromTable('_FILE');
1046  $mode = $this->currentMode() === 'copy' ? 'copy' : 'move';
1047  // Traverse elements and make CMD array
1048  foreach ($elements as $tP => $path) {
1049  $FILE[$mode][] = ['data' => $path, 'target' => $pUid];
1050  if ($mode === 'move') {
1051  $this->removeElement($tP);
1052  }
1053  }
1054  $this->endClipboard();
1055  return $FILE;
1056  }
1057 
1064  public function makeDeleteCmdArray_file($FILE)
1065  {
1066  $elements = $this->elFromTable('_FILE');
1067  // Traverse elements and make CMD array
1068  foreach ($elements as $tP => $path) {
1069  $FILE['delete'][] = ['data' => $path];
1070  $this->removeElement($tP);
1071  }
1072  $this->endClipboard();
1073  return $FILE;
1074  }
1075 
1081  protected function getLanguageService()
1082  {
1083  return $GLOBALS['LANG'];
1084  }
1085 
1091  protected function getBackendUser()
1092  {
1093  return $GLOBALS['BE_USER'];
1094  }
1095 
1103  protected function getStandaloneView()
1104  {
1106  $view = GeneralUtility::makeInstance(StandaloneView::class);
1107  $view->setLayoutRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Layouts')]);
1108  $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
1109  $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
1110 
1111  $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/Clipboard/Main.html'));
1112 
1113  $view->getRequest()->setControllerExtensionName('Backend');
1114  return $view;
1115  }
1116 }
static getRecordWSOL( $table, $uid, $fields=' *', $where='', $useDeleteClause=true, $unsetMovePointers=false)
static forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
deleteUrl($setRedirect=1, $file=0)
Definition: Clipboard.php:641
cleanUpCBC($CBarr, $table, $removeDeselected=0)
Definition: Clipboard.php:230
static linkThisScript(array $getParams=[])
static makeInstance($className,... $constructorArguments)
static getRecordTitle($table, $row, $prep=false, $forceResult=true)
static fixed_lgd_cs($string, $chars, $appendString='...')
static formatSize($sizeInBytes, $labels='', $base=0)
linkItemText($str, $rec, $table='')
Definition: Clipboard.php:547
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
elFromTable($matchTable='', $pad='')
Definition: Clipboard.php:883