/** * Get main headline based on active folder or storage for backend module * * Folder names are resolved to their special names like done in the tree view. * * @param Folder $folder * @return string */ protected function getFolderName(Folder $folder) { $name = $folder->getName(); if ($name === '') { // Show storage name on storage root if ($folder->getIdentifier() === '/') { $name = $folder->getStorage()->getName(); } } else { $name = key(ListUtility::resolveSpecialFolderNames(array($name => $folder))); } return $name; }
/** * Returns a table with directories and files listed. * * @param array $rowlist Array of files from path * @return string HTML-table */ public function getTable($rowlist) { // prepare space icon $this->spaceIcon = '<span class="btn btn-default disabled">' . IconUtility::getSpriteIcon('empty-empty') . '</span>'; // @todo use folder methods directly when they support filters $storage = $this->folderObject->getStorage(); $storage->resetFileAndFolderNameFiltersToDefault(); // Only render the contents of a browsable storage if ($this->folderObject->getStorage()->isBrowsable()) { try { $foldersCount = $storage->countFoldersInFolder($this->folderObject); $filesCount = $storage->countFilesInFolder($this->folderObject); } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException $e) { $foldersCount = 0; $filesCount = 0; } if ($foldersCount <= $this->firstElementNumber) { $foldersFrom = FALSE; $foldersNum = FALSE; } else { $foldersFrom = $this->firstElementNumber; if ($this->firstElementNumber + $this->iLimit > $foldersCount) { $foldersNum = $foldersCount - $this->firstElementNumber; } else { $foldersNum = $this->iLimit; } } if ($foldersCount >= $this->firstElementNumber + $this->iLimit) { $filesFrom = FALSE; $filesNum = FALSE; } else { if ($this->firstElementNumber <= $foldersCount) { $filesFrom = 0; $filesNum = $this->iLimit - $foldersNum; } else { $filesFrom = $this->firstElementNumber - $foldersCount; if ($filesFrom + $this->iLimit > $filesCount) { $filesNum = $filesCount - $filesFrom; } else { $filesNum = $this->iLimit; } } } $folders = $storage->getFoldersInFolder($this->folderObject, $foldersFrom, $foldersNum, TRUE, FALSE, trim($this->sort), (bool) $this->sortRev); $files = $this->folderObject->getFiles($filesFrom, $filesNum, Folder::FILTER_MODE_USE_OWN_AND_STORAGE_FILTERS, FALSE, trim($this->sort), (bool) $this->sortRev); $this->totalItems = $foldersCount + $filesCount; // Adds the code of files/dirs $out = ''; $titleCol = 'file'; // Cleaning rowlist for duplicates and place the $titleCol as the first column always! $rowlist = '_LOCALIZATION_,' . $rowlist; $rowlist = GeneralUtility::rmFromList($titleCol, $rowlist); $rowlist = GeneralUtility::uniqueList($rowlist); $rowlist = $rowlist ? $titleCol . ',' . $rowlist : $titleCol; if ($this->clipBoard) { $rowlist = str_replace('_LOCALIZATION_,', '_LOCALIZATION_,_CLIPBOARD_,', $rowlist); $this->addElement_tdCssClass['_CLIPBOARD_'] = 'col-clipboard'; } if ($this->bigControlPanel) { $rowlist = str_replace('_LOCALIZATION_,', '_LOCALIZATION_,_CONTROL_,', $rowlist); $this->addElement_tdCssClass['_CONTROL_'] = 'col-control'; } $this->fieldArray = explode(',', $rowlist); // Add classes to table cells $this->addElement_tdCssClass[$titleCol] = 'col-title'; $this->addElement_tdCssClass['_LOCALIZATION_'] = 'col-localizationa'; $folders = ListUtility::resolveSpecialFolderNames($folders); $iOut = ''; // Directories are added $this->eCounter = $this->firstElementNumber; list($flag, $code) = $this->fwd_rwd_nav(); $iOut .= $code; $iOut .= $this->formatDirList($folders); // Files are added $iOut .= $this->formatFileList($files); $this->eCounter = $this->firstElementNumber + $this->iLimit <= $this->totalItems ? $this->firstElementNumber + $this->iLimit : $this->totalItems; list($flag, $code) = $this->fwd_rwd_nav(); $iOut .= $code; // Header line is drawn $theData = array(); foreach ($this->fieldArray as $v) { if ($v == '_CLIPBOARD_' && $this->clipBoard) { $cells = array(); $table = '_FILE'; $elFromTable = $this->clipObj->elFromTable($table); if (!empty($elFromTable) && $this->folderObject->checkActionPermission('write')) { $addPasteButton = TRUE; $elToConfirm = array(); foreach ($elFromTable as $key => $element) { $clipBoardElement = $this->resourceFactory->retrieveFileOrFolderObject($element); if ($clipBoardElement instanceof Folder && $clipBoardElement->getStorage()->isWithinFolder($clipBoardElement, $this->folderObject)) { $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', $this->folderObject->getCombinedIdentifier())) . '" onclick="return ' . htmlspecialchars($this->clipObj->confirmMsg('_FILE', $this->path, 'into', $elToConfirm)) . '" title="' . $this->getLanguageService()->getLL('clip_paste', 1) . '">' . IconUtility::getSpriteIcon('actions-document-paste-after') . '</a>'; } } if ($this->clipObj->current !== 'normal' && $iOut) { $cells[] = $this->linkClipboardHeaderIcon(IconUtility::getSpriteIcon('actions-edit-copy', array('title' => $this->getLanguageService()->getLL('clip_selectMarked', TRUE))), $table, 'setCB'); $cells[] = $this->linkClipboardHeaderIcon(IconUtility::getSpriteIcon('actions-edit-delete', array('title' => $this->getLanguageService()->getLL('clip_deleteMarked'))), $table, 'delete', $this->getLanguageService()->getLL('clip_deleteMarkedWarning')); $onClick = 'checkOffCB(\'' . implode(',', $this->CBnames) . '\', this); return false;'; $cells[] = '<a class="btn btn-default" rel="" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . $this->getLanguageService()->getLL('clip_markRecords', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-select') . '</a>'; } $theData[$v] = implode('', $cells); } else { // Normal row: $theT = $this->linkWrapSort($this->getLanguageService()->getLL('c_' . $v, TRUE), $this->folderObject->getCombinedIdentifier(), $v); $theData[$v] = $theT; } } $out .= '<thead>' . $this->addelement(1, '', $theData, '', '', '', 'th') . '</thead>'; $out .= '<tbody>' . $iOut . '</tbody>'; // half line is drawn // finish $out = ' <!-- File list table: --> <div class="table-fit"> <table class="table table-striped table-hover" id="typo3-filelist"> ' . $out . ' </table> </div>'; } else { /** @var $flashMessage FlashMessage */ $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $this->getLanguageService()->getLL('storageNotBrowsableMessage'), $this->getLanguageService()->getLL('storageNotBrowsableTitle'), FlashMessage::INFO); $out = $flashMessage->render(); } return $out; }
/** * Fetches the data for the tree * * @param \TYPO3\CMS\Core\Resource\Folder $folderObject the folderobject * @param int $depth Max depth (recursivity limit) * @param string $type HTML-code prefix for recursive calls. * @return int The count of items on the level * @see getBrowsableTree() */ public function getFolderTree(\TYPO3\CMS\Core\Resource\Folder $folderObject, $depth = 999, $type = '') { $depth = (int) $depth; // This generates the directory tree /* array of \TYPO3\CMS\Core\Resource\Folder */ if ($folderObject instanceof \TYPO3\CMS\Core\Resource\InaccessibleFolder) { $subFolders = array(); } else { $subFolders = $folderObject->getSubfolders(); $subFolders = \TYPO3\CMS\Core\Resource\Utility\ListUtility::resolveSpecialFolderNames($subFolders); uksort($subFolders, 'strnatcasecmp'); } $totalSubFolders = count($subFolders); $HTML = ''; $subFolderCounter = 0; foreach ($subFolders as $subFolderName => $subFolder) { $subFolderCounter++; // Reserve space. $this->tree[] = array(); // Get the key for this space end($this->tree); $isLocked = $subFolder instanceof \TYPO3\CMS\Core\Resource\InaccessibleFolder; $treeKey = key($this->tree); $specUID = GeneralUtility::md5int($subFolder->getCombinedIdentifier()); $this->specUIDmap[$specUID] = $subFolder->getCombinedIdentifier(); $row = array('uid' => $specUID, 'path' => $subFolder->getCombinedIdentifier(), 'title' => $subFolderName, 'folder' => $subFolder); // Make a recursive call to the next level if (!$isLocked && $depth > 1 && $this->expandNext($specUID)) { $nextCount = $this->getFolderTree($subFolder, $depth - 1, $type); // Set "did expand" flag $isOpen = 1; } else { $nextCount = $isLocked ? 0 : $this->getNumberOfSubfolders($subFolder); // Clear "did expand" flag $isOpen = 0; } // Set HTML-icons, if any: if ($this->makeHTML) { $HTML = $this->PMicon($subFolder, $subFolderCounter, $totalSubFolders, $nextCount, $isOpen); $type = ''; $role = $subFolder->getRole(); if ($role !== FolderInterface::ROLE_DEFAULT) { $row['_title'] = '<strong>' . $subFolderName . '</strong>'; } $icon = IconUtility::getSpriteIconForResource($subFolder, array('title' => $subFolderName, 'folder-open' => (bool) $isOpen)); $HTML .= $this->wrapIcon($icon, $subFolder); } // Finally, add the row/HTML content to the ->tree array in the reserved key. $this->tree[$treeKey] = array('row' => $row, 'HTML' => $HTML, 'hasSub' => $nextCount && $this->expandNext($specUID), 'isFirst' => $subFolderCounter == 1, 'isLast' => FALSE, 'invertedDepth' => $depth, 'bank' => $this->bank); } if ($subFolderCounter > 0) { $this->tree[$treeKey]['isLast'] = TRUE; } return $totalSubFolders; }
/** * Get main headline based on active folder or storage for backend module * Folder names are resolved to their special names like done in the tree view. * * @return string */ protected function getModuleHeadline() { $name = $this->folderObject->getName(); if ($name === '') { // Show storage name on storage root if ($this->folderObject->getIdentifier() === '/') { $name = $this->folderObject->getStorage()->getName(); } } else { $name = key(ListUtility::resolveSpecialFolderNames([$name => $this->folderObject])); } return $name; }
/** * Returns a table with directories and files listed. * * @param array $rowlist Array of files from path * @return string HTML-table * @todo Define visibility */ public function getTable($rowlist) { // TODO use folder methods directly when they support filters $storage = $this->folderObject->getStorage(); $storage->resetFileAndFolderNameFiltersToDefault(); // Only render the contents of a browsable storage if ($this->folderObject->getStorage()->isBrowsable()) { $folders = $storage->getFolderIdentifiersInFolder($this->folderObject->getIdentifier()); $files = $this->folderObject->getFiles(); $this->sort = trim($this->sort); if ($this->sort !== '') { $filesToSort = array(); /** @var $fileObject \TYPO3\CMS\Core\Resource\File */ foreach ($files as $fileObject) { switch ($this->sort) { case 'size': $sortingKey = $fileObject->getSize(); break; case 'rw': $sortingKey = $fileObject->checkActionPermission('read') ? 'R' : '' . $fileObject->checkActionPermission('write') ? 'W' : ''; break; case 'fileext': $sortingKey = $fileObject->getExtension(); break; case 'tstamp': $sortingKey = $fileObject->getModificationTime(); break; case 'file': $sortingKey = $fileObject->getName(); break; default: if ($fileObject->hasProperty($this->sort)) { $sortingKey = $fileObject->getProperty($this->sort); } else { $sortingKey = $fileObject->getName(); } } $i = 1000000; while (isset($filesToSort[$sortingKey . $i])) { $i++; } $filesToSort[$sortingKey . $i] = $fileObject; } uksort($filesToSort, 'strnatcasecmp'); if ((int) $this->sortRev === 1) { $filesToSort = array_reverse($filesToSort); } $files = $filesToSort; } $this->totalItems = count($folders) + count($files); // Adds the code of files/dirs $out = ''; $titleCol = 'file'; // Cleaning rowlist for duplicates and place the $titleCol as the first column always! $rowlist = GeneralUtility::rmFromList($titleCol, $rowlist); $rowlist = GeneralUtility::uniqueList($rowlist); $rowlist = $rowlist ? $titleCol . ',' . $rowlist : $titleCol; if ($this->bigControlPanel || $this->clipBoard) { $rowlist = str_replace('file,', 'file,_CLIPBOARD_,', $rowlist); } $this->fieldArray = explode(',', $rowlist); $folderObjects = array(); foreach ($folders as $folder) { $folderObjects[] = $storage->getFolder($folder, TRUE); } $folderObjects = \TYPO3\CMS\Core\Resource\Utility\ListUtility::resolveSpecialFolderNames($folderObjects); uksort($folderObjects, 'strnatcasecmp'); // Directories are added $iOut = $this->formatDirList($folderObjects); // Files are added $iOut .= $this->formatFileList($files, $titleCol); // Header line is drawn $theData = array(); foreach ($this->fieldArray as $v) { if ($v == '_CLIPBOARD_' && $this->clipBoard) { $cells = array(); $table = '_FILE'; $elFromTable = $this->clipObj->elFromTable($table); if (count($elFromTable) && $this->folderObject->checkActionPermission('write')) { $addPasteButton = TRUE; foreach ($elFromTable as $element) { $clipBoardElement = $this->resourceFactory->retrieveFileOrFolderObject($element); if ($clipBoardElement instanceof Folder && $clipBoardElement->getStorage()->isWithinFolder($clipBoardElement, $this->folderObject)) { $addPasteButton = FALSE; } } if ($addPasteButton) { $cells[] = '<a class="btn" href="' . htmlspecialchars($this->clipObj->pasteUrl('_FILE', $this->folderObject->getCombinedIdentifier())) . '" onclick="return ' . htmlspecialchars($this->clipObj->confirmMsg('_FILE', $this->path, 'into', $elFromTable)) . '" title="' . $GLOBALS['LANG']->getLL('clip_paste', 1) . '">' . IconUtility::getSpriteIcon('actions-document-paste-after') . '</a>'; } } if ($this->clipObj->current != 'normal' && $iOut) { $cells[] = $this->linkClipboardHeaderIcon(IconUtility::getSpriteIcon('actions-edit-copy', array('title' => $GLOBALS['LANG']->getLL('clip_selectMarked', TRUE))), $table, 'setCB'); $cells[] = $this->linkClipboardHeaderIcon(IconUtility::getSpriteIcon('actions-edit-delete', array('title' => $GLOBALS['LANG']->getLL('clip_deleteMarked'))), $table, 'delete', $GLOBALS['LANG']->getLL('clip_deleteMarkedWarning')); $onClick = 'checkOffCB(\'' . implode(',', $this->CBnames) . '\', this); return false;'; $cells[] = '<a class="cbcCheckAll" rel="" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . $GLOBALS['LANG']->getLL('clip_markRecords', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-select') . '</a>'; } $theData[$v] = implode('', $cells); } else { // Normal row: $theT = $this->linkWrapSort($GLOBALS['LANG']->getLL('c_' . $v, TRUE), $this->folderObject->getCombinedIdentifier(), $v); $theData[$v] = $theT; } } $out .= '<thead>' . $this->addelement(1, ' ', $theData) . '</thead>'; $out .= '<tbody>' . $iOut . '</tbody>'; // half line is drawn // finish $out = ' <!-- File list table: --> <table class="t3-table" id="typo3-filelist"> ' . $out . ' </table>'; } else { /** @var $flashMessage \TYPO3\CMS\Core\Messaging\FlashMessage */ $flashMessage = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessage', $GLOBALS['LANG']->getLL('storageNotBrowsableMessage'), $GLOBALS['LANG']->getLL('storageNotBrowsableTitle'), \TYPO3\CMS\Core\Messaging\FlashMessage::INFO); $out = $flashMessage->render(); } return $out; }
/** * Get main headline based on active folder or storage for backend module * * Folder names are resolved to their special names like done in the tree view. * * @return string */ protected function getModuleHeadline() { $name = $this->folderObject->getName(); if ($name === '') { // Show storage name on storage root if ($this->folderObject->getIdentifier() === '/') { $name = $this->folderObject->getStorage()->getName(); } } else { $name = key(\TYPO3\CMS\Core\Resource\Utility\ListUtility::resolveSpecialFolderNames(array($name => $this->folderObject))); } return $name; }