/** * Creates the clipboard control pad * * @param File|Folder $fileOrFolderObject Array with information about the file/directory for which to make the clipboard panel for the listing. * @return string HTML-table */ public function makeClip($fileOrFolderObject) { if (!$fileOrFolderObject->checkActionPermission('read')) { return ''; } $cells = array(); $fullIdentifier = $fileOrFolderObject->getCombinedIdentifier(); $fullName = $fileOrFolderObject->getName(); $md5 = GeneralUtility::shortmd5($fullIdentifier); // For normal clipboard, add copy/cut buttons: if ($this->clipObj->current == 'normal') { $isSel = $this->clipObj->isSelected('_FILE', $md5); $cells[] = '<a class="btn btn-default"" href="' . htmlspecialchars($this->clipObj->selUrlFile($fullIdentifier, 1, $isSel == 'copy')) . '">' . IconUtility::getSpriteIcon('actions-edit-copy' . ($isSel == 'copy' ? '-release' : ''), array('title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.copy', TRUE))) . '</a>'; // we can only cut if file can be moved if ($fileOrFolderObject->checkActionPermission('move')) { $cells[] = '<a class="btn btn-default" href="' . htmlspecialchars($this->clipObj->selUrlFile($fullIdentifier, 0, $isSel == 'cut')) . '">' . IconUtility::getSpriteIcon('actions-edit-cut' . ($isSel == 'cut' ? '-release' : ''), array('title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.cut', TRUE))) . '</a>'; } else { $cells[] = $this->spaceIcon; } } else { // For numeric pads, add select checkboxes: $n = '_FILE|' . $md5; $this->CBnames[] = $n; $checked = $this->clipObj->isSelected('_FILE', $md5) ? ' checked="checked"' : ''; $cells[] = '<label class="btn btn-default btn-checkbox"><input type="hidden" name="CBH[' . $n . ']" value="0" /><input type="checkbox" name="CBC[' . $n . ']" value="' . htmlspecialchars($fullIdentifier) . '" ' . $checked . ' /><span class="t3-icon fa"></span></label>'; } // Display PASTE button, if directory: $elFromTable = $this->clipObj->elFromTable('_FILE'); if ($fileOrFolderObject instanceof Folder && !empty($elFromTable) && $fileOrFolderObject->checkActionPermission('write')) { $addPasteButton = TRUE; $elToConfirm = array(); foreach ($elFromTable as $key => $element) { $clipBoardElement = $this->resourceFactory->retrieveFileOrFolderObject($element); if ($clipBoardElement instanceof Folder && $clipBoardElement->getStorage()->isWithinFolder($clipBoardElement, $fileOrFolderObject)) { $addPasteButton = FALSE; } $fileInfo = $clipBoardElement->getStorage()->getFileInfoByIdentifier(substr(strstr($element, ':'), 1)); $elToConfirm[$key] = $fileInfo['name']; } if ($addPasteButton) { $cells[] = '<a class="btn btn-default" href="' . htmlspecialchars($this->clipObj->pasteUrl('_FILE', $fullIdentifier)) . '" onclick="return ' . htmlspecialchars($this->clipObj->confirmMsg('_FILE', $fullName, 'into', $elToConfirm)) . '" title="' . $this->getLanguageService()->getLL('clip_pasteInto', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-paste-into') . '</a>'; } } // Compile items into a DIV-element: return ' <div class="btn-group" role="group">' . implode('', $cells) . '</div>'; }
/** * Creates the clipboard panel for a single record in the listing. * * @param string $table The table * @param mixed[] $row The record for which to make the clipboard panel. * @throws \UnexpectedValueException * @return string HTML table with the clipboard panel (unless disabled) */ public function makeClip($table, $row) { // Return blank, if disabled: if (!$this->getModule()->MOD_SETTINGS['clipBoard']) { return ''; } $cells = array(); $cells['pasteAfter'] = $cells['pasteInto'] = $this->spaceIcon; //enables to hide the copy, cut and paste icons for localized records - doesn't make much sense to perform these options for them $isL10nOverlay = $this->localizationView && $table != 'pages_language_overlay' && $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] != 0; // Return blank, if disabled: // Whether a numeric clipboard pad is active or the normal pad we will see different content of the panel: // For the "Normal" pad: if ($this->clipObj->current === 'normal') { // Show copy/cut icons: $isSel = (string) $this->clipObj->isSelected($table, $row['uid']); if ($isL10nOverlay || !$this->overlayEditLockPermissions($table, $row)) { $cells['copy'] = $this->spaceIcon; $cells['cut'] = $this->spaceIcon; } else { $copyIcon = $this->iconFactory->getIcon('actions-edit-copy', Icon::SIZE_SMALL); $cutIcon = $this->iconFactory->getIcon('actions-edit-cut', Icon::SIZE_SMALL); if ($isSel === 'copy') { $copyIcon = $this->iconFactory->getIcon('actions-edit-copy-release', Icon::SIZE_SMALL); } elseif ($isSel === 'cut') { $cutIcon = $this->iconFactory->getIcon('actions-edit-cut-release', Icon::SIZE_SMALL); } $cells['copy'] = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars('return jumpSelf(' . GeneralUtility::quoteJSvalue($this->clipObj->selUrlDB($table, $row['uid'], 1, $isSel === 'copy', array('returnUrl' => ''))) . ');') . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.copy', true) . '">' . $copyIcon->render() . '</a>'; if (true) { $cells['cut'] = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars('return jumpSelf(' . GeneralUtility::quoteJSvalue($this->clipObj->selUrlDB($table, $row['uid'], 0, $isSel === 'cut', array('returnUrl' => ''))) . ');') . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.cut', true) . '">' . $cutIcon->render() . '</a>'; } else { $cells['cut'] = $this->spaceIcon; } } } else { // For the numeric clipboard pads (showing checkboxes where one can select elements on/off) // Setting name of the element in ->CBnames array: $n = $table . '|' . $row['uid']; $this->CBnames[] = $n; // Check if the current element is selected and if so, prepare to set the checkbox as selected: $checked = $this->clipObj->isSelected($table, $row['uid']) ? 'checked="checked" ' : ''; // If the "duplicateField" value is set then select all elements which are duplicates... if ($this->duplicateField && isset($row[$this->duplicateField])) { $checked = ''; if (in_array($row[$this->duplicateField], $this->duplicateStack)) { $checked = 'checked="checked" '; } $this->duplicateStack[] = $row[$this->duplicateField]; } // Adding the checkbox to the panel: $cells['select'] = $isL10nOverlay ? $this->spaceIcon : '<input type="hidden" name="CBH[' . $n . ']" value="0" /><label class="btn btn-default btn-checkbox"><input type="checkbox"' . ' name="CBC[' . $n . ']" value="1" ' . $checked . '/><span class="t3-icon fa"></span></label>'; } // Now, looking for selected elements from the current table: $elFromTable = $this->clipObj->elFromTable($table); if (!empty($elFromTable) && $GLOBALS['TCA'][$table]['ctrl']['sortby']) { // IF elements are found, they can be individually ordered and are not locked by editlock, then add a "paste after" icon: $cells['pasteAfter'] = $isL10nOverlay || !$this->overlayEditLockPermissions($table, $row) ? $this->spaceIcon : '<a class="btn btn-default" href="' . htmlspecialchars($this->clipObj->pasteUrl($table, -$row['uid'])) . '" onclick="' . htmlspecialchars('return ' . $this->clipObj->confirmMsg($table, $row, 'after', $elFromTable)) . '" title="' . $this->getLanguageService()->getLL('clip_pasteAfter', true) . '">' . $this->iconFactory->getIcon('actions-document-paste-after', Icon::SIZE_SMALL)->render() . '</a>'; } // Now, looking for elements in general: $elFromTable = $this->clipObj->elFromTable(''); if ($table == 'pages' && !empty($elFromTable)) { $cells['pasteInto'] = '<a class="btn btn-default" href="' . htmlspecialchars($this->clipObj->pasteUrl('', $row['uid'])) . '" onclick="' . htmlspecialchars('return ' . $this->clipObj->confirmMsg($table, $row, 'into', $elFromTable)) . '" title="' . $this->getLanguageService()->getLL('clip_pasteInto', true) . '">' . $this->iconFactory->getIcon('actions-document-paste-into', Icon::SIZE_SMALL)->render() . '</a>'; } /** * @hook makeClip: Allows to change clip-icons of records in list-module * @usage This hook method gets passed the current $cells array as third parameter. * This array contains values for the clipboard icons generated for each record in Web>List. * Each array entry is accessible by an index-key. * The order of the icons is depending on the order of those array entries. */ if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData) { $hookObject = GeneralUtility::getUserObj($classData); if (!$hookObject instanceof RecordListHookInterface) { throw new \UnexpectedValueException('$hookObject must implement interface ' . RecordListHookInterface::class, 1195567845); } $cells = $hookObject->makeClip($table, $row, $cells, $this); } } // Compile items into a DIV-element: return '<!-- CLIPBOARD PANEL: ' . $table . ':' . $row['uid'] . ' --> <div class="btn-group" role="group">' . implode('', $cells) . '</div>'; }
/** * Creates the clipboard control pad * * @param \TYPO3\CMS\Core\Resource\File|\TYPO3\CMS\Core\Resource\Folder $fileOrFolderObject Array with information about the file/directory for which to make the clipboard panel for the listing. * @return string HTML-table * @todo Define visibility */ public function makeClip($fileOrFolderObject) { if (!$fileOrFolderObject->checkActionPermission('read')) { return ''; } $cells = array(); $fullIdentifier = $fileOrFolderObject->getCombinedIdentifier(); $md5 = GeneralUtility::shortmd5($fullIdentifier); // For normal clipboard, add copy/cut buttons: if ($this->clipObj->current == 'normal') { $isSel = $this->clipObj->isSelected('_FILE', $md5); $cells[] = '<a href="' . htmlspecialchars($this->clipObj->selUrlFile($fullIdentifier, 1, $isSel == 'copy')) . '">' . IconUtility::getSpriteIcon('actions-edit-copy' . ($isSel == 'copy' ? '-release' : ''), array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:cm.copy', TRUE))) . '</a>'; // we can only cut if file can be moved if ($fileOrFolderObject->checkActionPermission('move')) { $cells[] = '<a href="' . htmlspecialchars($this->clipObj->selUrlFile($fullIdentifier, 0, $isSel == 'cut')) . '">' . IconUtility::getSpriteIcon('actions-edit-cut' . ($isSel == 'cut' ? '-release' : ''), array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:cm.cut', TRUE))) . '</a>'; } else { $cells[] = IconUtility::getSpriteIcon('empty-empty'); } } else { // For numeric pads, add select checkboxes: $n = '_FILE|' . $md5; $this->CBnames[] = $n; $checked = $this->clipObj->isSelected('_FILE', $md5) ? ' checked="checked"' : ''; $cells[] = '<input type="hidden" name="CBH[' . $n . ']" value="0" />' . '<input type="checkbox" name="CBC[' . $n . ']" value="' . htmlspecialchars($fullIdentifier) . '" class="smallCheckboxes"' . $checked . ' />'; } // Display PASTE button, if directory: $elFromTable = $this->clipObj->elFromTable('_FILE'); if (is_a($fileOrFolderObject, 'TYPO3\\CMS\\Core\\Resource\\Folder') && count($elFromTable) && $fileOrFolderObject->checkActionPermission('write')) { $addPasteButton = TRUE; foreach ($elFromTable as $element) { $clipBoardElement = $this->resourceFactory->retrieveFileOrFolderObject($element); if ($clipBoardElement instanceof Folder && $clipBoardElement->getStorage()->isWithinFolder($clipBoardElement, $fileOrFolderObject)) { $addPasteButton = FALSE; } } if ($addPasteButton) { $cells[] = '<a class="btn" href="' . htmlspecialchars($this->clipObj->pasteUrl('_FILE', $fullIdentifier)) . '" onclick="return ' . htmlspecialchars($this->clipObj->confirmMsg('_FILE', $fullIdentifier, 'into', $elFromTable)) . '" title="' . $GLOBALS['LANG']->getLL('clip_pasteInto', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-paste-into') . '</a>'; } } // Compile items into a DIV-element: return ' <!-- CLIPBOARD PANEL: --> <div class="typo3-clipCtrl"> ' . implode(' ', $cells) . ' </div>'; }
/** * Creates the clipboard panel for a single record in the listing. * * @param string $table The table * @param array $row The record for which to make the clipboard panel. * @return string HTML table with the clipboard panel (unless disabled) * @todo Define visibility */ public function makeClip($table, $row) { // Return blank, if disabled: if ($this->dontShowClipControlPanels) { return ''; } $cells = array(); $cells['pasteAfter'] = $cells['pasteInto'] = $this->spaceIcon; //enables to hide the copy, cut and paste icons for localized records - doesn't make much sense to perform these options for them $isL10nOverlay = $this->localizationView && $table != 'pages_language_overlay' && $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] != 0; // Return blank, if disabled: // Whether a numeric clipboard pad is active or the normal pad we will see different content of the panel: // For the "Normal" pad: if ($this->clipObj->current == 'normal') { // Show copy/cut icons: $isSel = (string) $this->clipObj->isSelected($table, $row['uid']); $cells['copy'] = $isL10nOverlay ? $this->spaceIcon : '<a href="#" onclick="' . htmlspecialchars('return jumpSelf(\'' . $this->clipObj->selUrlDB($table, $row['uid'], 1, $isSel == 'copy', array('returnUrl' => '')) . '\');') . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.copy', TRUE) . '">' . (!$isSel == 'copy' ? \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-copy') : \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-copy-release')) . '</a>'; $cells['cut'] = $isL10nOverlay ? $this->spaceIcon : '<a href="#" onclick="' . htmlspecialchars('return jumpSelf(\'' . $this->clipObj->selUrlDB($table, $row['uid'], 0, $isSel == 'cut', array('returnUrl' => '')) . '\');') . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.cut', TRUE) . '">' . (!$isSel == 'cut' ? \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-cut') : \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-cut-release')) . '</a>'; } else { // For the numeric clipboard pads (showing checkboxes where one can select elements on/off) // Setting name of the element in ->CBnames array: $n = $table . '|' . $row['uid']; $this->CBnames[] = $n; // Check if the current element is selected and if so, prepare to set the checkbox as selected: $checked = $this->clipObj->isSelected($table, $row['uid']) ? ' checked="checked"' : ''; // If the "duplicateField" value is set then select all elements which are duplicates... if ($this->duplicateField && isset($row[$this->duplicateField])) { $checked = ''; if (in_array($row[$this->duplicateField], $this->duplicateStack)) { $checked = ' checked="checked"'; } $this->duplicateStack[] = $row[$this->duplicateField]; } // Adding the checkbox to the panel: $cells['select'] = $isL10nOverlay ? $this->spaceIcon : '<input type="hidden" name="CBH[' . $n . ']" value="0" /><input type="checkbox" name="CBC[' . $n . ']" value="1" class="smallCheckboxes"' . $checked . ' />'; } // Now, looking for selected elements from the current table: $elFromTable = $this->clipObj->elFromTable($table); if (count($elFromTable) && $GLOBALS['TCA'][$table]['ctrl']['sortby']) { // IF elements are found and they can be individually ordered, then add a "paste after" icon: $cells['pasteAfter'] = $isL10nOverlay ? $this->spaceIcon : '<a href="' . htmlspecialchars($this->clipObj->pasteUrl($table, -$row['uid'])) . '" onclick="' . htmlspecialchars('return ' . $this->clipObj->confirmMsg($table, $row, 'after', $elFromTable)) . '" title="' . $GLOBALS['LANG']->getLL('clip_pasteAfter', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-paste-after') . '</a>'; } // Now, looking for elements in general: $elFromTable = $this->clipObj->elFromTable(''); if ($table == 'pages' && count($elFromTable)) { $cells['pasteInto'] = '<a href="' . htmlspecialchars($this->clipObj->pasteUrl('', $row['uid'])) . '" onclick="' . htmlspecialchars('return ' . $this->clipObj->confirmMsg($table, $row, 'into', $elFromTable)) . '" title="' . $GLOBALS['LANG']->getLL('clip_pasteInto', TRUE) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-paste-into') . '</a>'; } /** * @hook makeClip: Allows to change clip-icons of records in list-module * @date 2007-11-20 * @request Bernhard Kraft <*****@*****.**> * @usage This hook method gets passed the current $cells array as third parameter. This array contains values for the clipboard icons generated for each record in Web>List. Each array entry is accessible by an index-key. The order of the icons is dependend on the order of those array entries. */ if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData) { $hookObject = \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($classData); if (!$hookObject instanceof \TYPO3\CMS\Recordlist\RecordList\RecordListHookInterface) { throw new \UnexpectedValueException('$hookObject must implement interface TYPO3\\CMS\\Recordlist\\RecordList\\RecordListHookInterface', 1195567845); } $cells = $hookObject->makeClip($table, $row, $cells, $this); } } // Compile items into a DIV-element: return ' <!-- CLIPBOARD PANEL: ' . $table . ':' . $row['uid'] . ' --> <div class="typo3-clipCtrl">' . implode('', $cells) . '</div>'; }
/** * Creates the clipboard control pad * * @param File|Folder $fileOrFolderObject Array with information about the file/directory for which to make the clipboard panel for the listing. * @return string HTML-table */ public function makeClip($fileOrFolderObject) { if (!$fileOrFolderObject->checkActionPermission('read')) { return ''; } $cells = []; $fullIdentifier = $fileOrFolderObject->getCombinedIdentifier(); $fullName = $fileOrFolderObject->getName(); $md5 = GeneralUtility::shortMD5($fullIdentifier); // For normal clipboard, add copy/cut buttons: if ($this->clipObj->current === 'normal') { $isSel = $this->clipObj->isSelected('_FILE', $md5); $copyTitle = htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.copy')); $cutTitle = htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.cut')); $copyIcon = $this->iconFactory->getIcon('actions-edit-copy', Icon::SIZE_SMALL)->render(); $cutIcon = $this->iconFactory->getIcon('actions-edit-cut', Icon::SIZE_SMALL)->render(); if ($isSel === 'copy') { $copyIcon = $this->iconFactory->getIcon('actions-edit-copy-release', Icon::SIZE_SMALL)->render(); } elseif ($isSel === 'cut') { $cutIcon = $this->iconFactory->getIcon('actions-edit-cut-release', Icon::SIZE_SMALL)->render(); } $cells[] = '<a class="btn btn-default"" href="' . htmlspecialchars($this->clipObj->selUrlFile($fullIdentifier, 1, $isSel === 'copy')) . '" title="' . $copyTitle . '">' . $copyIcon . '</a>'; // we can only cut if file can be moved if ($fileOrFolderObject->checkActionPermission('move')) { $cells[] = '<a class="btn btn-default" href="' . htmlspecialchars($this->clipObj->selUrlFile($fullIdentifier, 0, $isSel === 'cut')) . '" title="' . $cutTitle . '">' . $cutIcon . '</a>'; } else { $cells[] = $this->spaceIcon; } } else { // For numeric pads, add select checkboxes: $n = '_FILE|' . $md5; $this->CBnames[] = $n; $checked = $this->clipObj->isSelected('_FILE', $md5) ? ' checked="checked"' : ''; $cells[] = '<input type="hidden" name="CBH[' . $n . ']" value="0" /><label class="btn btn-default btn-checkbox"><input type="checkbox" name="CBC[' . $n . ']" value="' . htmlspecialchars($fullIdentifier) . '" ' . $checked . ' /><span class="t3-icon fa"></span></label>'; } // Display PASTE button, if directory: $elFromTable = $this->clipObj->elFromTable('_FILE'); if ($fileOrFolderObject instanceof Folder && !empty($elFromTable) && $fileOrFolderObject->checkActionPermission('write')) { $addPasteButton = true; $elToConfirm = []; foreach ($elFromTable as $key => $element) { $clipBoardElement = $this->resourceFactory->retrieveFileOrFolderObject($element); if ($clipBoardElement instanceof Folder && $clipBoardElement->getStorage()->isWithinFolder($clipBoardElement, $fileOrFolderObject)) { $addPasteButton = false; } $elToConfirm[$key] = $clipBoardElement->getName(); } if ($addPasteButton) { $cells[] = '<a class="btn btn-default t3js-modal-trigger" ' . ' href="' . htmlspecialchars($this->clipObj->pasteUrl('_FILE', $fullIdentifier)) . '"' . ' data-content="' . htmlspecialchars($this->clipObj->confirmMsgText('_FILE', $fullName, 'into', $elToConfirm)) . '"' . ' data-severity="warning"' . ' data-title="' . htmlspecialchars($this->getLanguageService()->getLL('clip_pasteInto')) . '"' . ' title="' . htmlspecialchars($this->getLanguageService()->getLL('clip_pasteInto')) . '"' . '>' . $this->iconFactory->getIcon('actions-document-paste-into', Icon::SIZE_SMALL)->render() . '</a>'; } } // Compile items into a DIV-element: return ' <div class="btn-group" role="group">' . implode('', $cells) . '</div>'; }