[FEATURE] Limit file extensions in FAL element browser
authorIngmar Schlecht <ingmar@typo3.org>
Thu, 17 May 2012 10:47:43 +0000 (12:47 +0200)
committerAndreas Wolf <andreas.wolf@ikt-werk.de>
Wed, 30 May 2012 19:58:27 +0000 (21:58 +0200)
Change-Id: Ic34befbdf4541a2837701cb75a51d500daada8d5
Releases: 6.0
Resolves: #36816
Reviewed-on: http://review.typo3.org/10895
Reviewed-by: Tolleiv Nietsch
Tested-by: Tolleiv Nietsch
Reviewed-by: Andreas Wolf
Tested-by: Andreas Wolf
t3lib/core_autoload.php
t3lib/file/Utility/FileExtensionFilter.php [new file with mode: 0644]
typo3/browser.php
typo3/class.browse_links.php

index ecbbecf..8271c49 100644 (file)
@@ -154,6 +154,7 @@ $t3libClasses = array(
        't3lib_file_service_userfilemountservice' => PATH_t3lib . 'file/Service/UserfilemountService.php',
        't3lib_file_storage' => PATH_t3lib . 'file/Storage.php',
        't3lib_file_utility_filenamefilters' => PATH_t3lib . 'file/Utility/FilenameFilters.php',
+       't3lib_file_utility_fileextensionfilter' => PATH_t3lib . 'file/Utility/FileExtensionFilter.php',
        't3lib_flashmessage' => PATH_t3lib . 'class.t3lib_flashmessage.php',
        't3lib_flashmessagequeue' => PATH_t3lib . 'class.t3lib_flashmessagequeue.php',
        't3lib_flexformtools' => PATH_t3lib . 'class.t3lib_flexformtools.php',
diff --git a/t3lib/file/Utility/FileExtensionFilter.php b/t3lib/file/Utility/FileExtensionFilter.php
new file mode 100644 (file)
index 0000000..a63a1a6
--- /dev/null
@@ -0,0 +1,188 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2012 Ingmar Schlecht <ingmar.schlecht@typo3.org>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Utility methods for filtering filenames
+ *
+ * @author Ingmar Schlecht <ingmar.schlecht@typo3.org>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_file_Utility_FileExtensionFilter {
+
+       /**
+        * Allowed file extensions. If NULL, all extensions are allowed.
+        *
+        * @var array
+        */
+       protected $allowedFileExtensions = NULL;
+
+       /**
+        * Disallowed file extensions. If NULL, no extension is disallowed (i.e. all are allowed).
+        *
+        * @var array
+        */
+       protected $disallowedFileExtensions = NULL;
+
+       /**
+        * Entry method for use as TCEMain "inline" field filter
+        *
+        * @param $parameters
+        * @param $tceMain
+        * @return array
+        */
+       public function filterInlineChildren($parameters, t3lib_TCEmain $tceMain) {
+               $values = $parameters['values'];
+
+               if ($parameters['allowedFileExtensions']) {
+                       $this->setAllowedFileExtensions($parameters['allowedFileExtensions']);
+               }
+
+               if ($parameters['disallowedFileExtensions']) {
+                       $this->setDisallowedFileExtensions($parameters['disallowedFileExtensions']);
+               }
+
+               $cleanValues = array();
+
+               foreach ($values as $value) {
+                       $parts = t3lib_div::revExplode('_', $value, 2);
+                       $fileReferenceUid = $parts[count($parts)-1];
+
+                       $fileReferenceRecord = t3lib_BEfunc::getRecord('sys_file_reference', $fileReferenceUid);
+                       $fileUid = $fileReferenceRecord['uid_local'];
+
+                       $file = t3lib_file_Factory::getInstance()->getFileObject($fileUid);
+
+                       if ($this->isAllowed($file)) {
+                               $cleanValues[] = $value;
+                       } else {
+                                       // Remove the erroneously created reference record again
+                               $tceMain->deleteAction('sys_file_reference', $fileReferenceUid);
+                       }
+               }
+
+               return $cleanValues;
+       }
+
+       /**
+        * Entry method for use as file list filter.
+        *
+        * We have to use -1 as the „don't include“ return value, as call_user_func() will return FALSE
+        * if calling the method failed and thus we can't use that as a return value.
+        *
+        * @param string $itemName
+        * @param string $itemIdentifier
+        * @param string $parentIdentifier
+        * @param array $additionalInformation Additional information about the inspected item
+        * @param t3lib_file_Driver_AbstractDriver $driver
+        * @return boolean|integer -1 if the file should not be included in a listing
+        */
+       public function filterFileList($itemName, $itemIdentifier, $parentIdentifier, array $additionalInformation, t3lib_file_Driver_AbstractDriver $driver) {
+               $returnCode = TRUE;
+
+                       // Early return in case no file filters are set at all
+               if ($this->allowedFileExtensions === NULL && $this->disallowedFileExtensions === NULL) {
+                       return $returnCode;
+               }
+
+                       // Check that this is a file and not a folder
+               if ($driver->fileExists($itemIdentifier)) {
+                       $file = $driver->getFile($itemIdentifier);
+
+                       if (!$this->isAllowed($file)) {
+                               $returnCode = -1;
+                       }
+               }
+
+               return $returnCode;
+       }
+
+       /**
+        * Checks whether a file is allowed according to the criteria defined in the class variables ($this->allowedFileExtensions etc.)
+        *
+        * @param t3lib_file_FileInterface $file
+        * @return bool
+        */
+       protected function isAllowed(t3lib_file_FileInterface $file) {
+               $result = TRUE;
+
+               $fileExt = $file->getExtension();
+
+                       // Check allowed file extensions
+               if ($this->allowedFileExtensions !== NULL && count($this->allowedFileExtensions) > 0 && !in_array($fileExt, $this->allowedFileExtensions)) {
+                       $result = FALSE;
+               }
+
+                       // Check disallowed file extensions
+               if ($this->disallowedFileExtensions !== NULL && count($this->disallowedFileExtensions) > 0 && in_array($fileExt, $this->disallowedFileExtensions)) {
+
+                       $result = FALSE;
+               }
+
+               return $result;
+       }
+
+
+       /**
+        * Set allowed file extensions
+        *
+        * @param mixed $allowedFileExtensions  Comma-separated list or array, of allowed file extensions
+        */
+       public function setAllowedFileExtensions($allowedFileExtensions) {
+               $this->allowedFileExtensions = $this->convertToArray($allowedFileExtensions);
+       }
+
+
+       /**
+        * Set disallowed file extensions
+        *
+        * @param mixed $disallowedFileExtensions  Comma-separated list or array, of allowed file extensions
+        */
+       public function setDisallowedFileExtensions($disallowedFileExtensions) {
+               $this->disallowedFileExtensions = $this->convertToArray($disallowedFileExtensions);
+       }
+
+       /**
+        * Converts mixed (string or array) input arguments into an array, NULL if empty.
+        *
+        * @param mixed $inputArgument Comma-separated list or array.
+        * @return array
+        */
+       protected function convertToArray($inputArgument) {
+               $returnValue = NULL;
+
+               if (is_array($inputArgument)) {
+                       $returnValue = $inputArgument;
+               } elseif (strlen($inputArgument) > 0) {
+                       $returnValue = t3lib_div::trimExplode(',', $inputArgument);
+               }
+
+               return $returnValue;
+       }
+}
+
+?>
\ No newline at end of file
index 239492b..f2bdc84 100644 (file)
@@ -66,15 +66,6 @@ class SC_browser {
                $mode =t3lib_div::_GP('mode');
                $bparams = t3lib_div::_GP('bparams');
 
-               // workaround for FAL: previously, we had file as a mode, now we have sys_file db records
-               // check if we need to "translate" sys_file queries to mode=file queries
-               // @todo: handle this the right way in the TYPO3 core
-               $bParamElements = explode('|', $bparams);
-               if ($mode == 'db' && $bParamElements[3] == 'sys_file') {
-                       $mode = 'file';
-               }
-
-
 
                        // Set doktype:
                $GLOBALS['TBE_TEMPLATE']->docType='xhtml_frames';
index b32cef0..19d88a2 100644 (file)
@@ -1700,6 +1700,29 @@ class browse_links {
 
                        // Init variable:
                $pArr = explode('|', $this->bparams);
+
+                       // The key number 3 of the pArr contains the "allowed" string. Disallowed is not passed to the element browser at all but only filtered out in TCEMain afterwards
+               $allowed = $pArr[3];
+
+               if ($allowed !== 'sys_file') {
+                       $allowedFileExtensions = $allowed;
+               }
+
+
+               $this->storages = $GLOBALS['BE_USER']->getFileStorages();
+
+               if (isset($allowedFileExtensions)) {
+                               // Create new filter object
+                       $filterObject = t3lib_div::makeInstance('t3lib_file_Utility_FileExtensionFilter');
+                       $filterObject->setAllowedFileExtensions($allowedFileExtensions);
+
+                               // Set file extension filters on all storages
+                       /** @var $storage t3lib_file_Storage */
+                       foreach ($this->storages as $storage) {
+                               $storage->addFileAndFolderNameFilter(array($filterObject, 'filterFileList'));
+                       }
+               }
+
                        // Create upload/create folder forms, if a path is given:
                if ($this->expandFolder) {
                        $this->selectedFolder = t3lib_file_Factory::getInstance()->getFolderObjectFromCombinedIdentifier($this->expandFolder);