[BUGFIX] Implement check against File type restriction in Extractors 74/36674/4
authorFabien Udriot <fabien.udriot@ecodev.ch>
Thu, 5 Feb 2015 17:20:23 +0000 (18:20 +0100)
committerWouter Wolters <typo3@wouterwolters.nl>
Fri, 13 Nov 2015 19:28:12 +0000 (20:28 +0100)
The Metadata Extractor interface provides the possibility to limit
the scope of the extraction to only certain file types, e.g. text, image,
video, audio, application. This can be defined in every Extactor
in method ExtractorInterface::getFileTypeRestrictions()

However, this check is not implemented in the Indexer and defining
any value as File type restriction will have no effect currently.
This patch fixes the situation.

Change-Id: Iffc01f98eec89de818acaa8ceb759a2b781759fa
Resolves: #64883
Releases: master, 6.2
Reviewed-on: https://review.typo3.org/36674
Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Reviewed-by: Daniel Goerz <ervaude@gmail.com>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
typo3/sysext/core/Classes/Resource/Index/Indexer.php
typo3/sysext/core/Tests/Unit/Resource/Index/IndexerTest.php [new file with mode: 0644]

index c67e0d3..3aa53a3 100644 (file)
@@ -121,12 +121,18 @@ class Indexer
         $newMetaData = array(
             0 => $fileObject->_getMetaData()
         );
+
+        // Loop through available extractors and fetch metadata for the given file.
         foreach ($this->getExtractionServices() as $service) {
-            if ($service->canProcess($fileObject)) {
+            if ($this->isFileTypeSupportedByExtractor($fileObject, $service) && $service->canProcess($fileObject)) {
                 $newMetaData[$service->getPriority()] = $service->extractMetaData($fileObject, $newMetaData);
             }
         }
+
+        // Sort metadata by priority so that merging happens in order of precedence.
         ksort($newMetaData);
+
+        // Merge the collected metadata.
         $metaData = array();
         foreach ($newMetaData as $data) {
             $metaData = array_merge($metaData, $data);
@@ -168,6 +174,23 @@ class Indexer
     }
 
     /**
+     * Check whether the extractor service supports this file according to file type restrictions.
+     *
+     * @param File $file
+     * @param ExtractorInterface $extractor
+     * @return bool
+     */
+    protected function isFileTypeSupportedByExtractor(File $file, ExtractorInterface $extractor)
+    {
+        $isSupported = true;
+        $fileTypeRestrictions = $extractor->getFileTypeRestrictions();
+        if (!empty($fileTypeRestrictions) && !in_array($file->getType(), $fileTypeRestrictions)) {
+            $isSupported = false;
+        }
+        return $isSupported;
+    }
+
+    /**
      * Adds updated files to the processing queue
      *
      * @param array $fileIdentifierArray
diff --git a/typo3/sysext/core/Tests/Unit/Resource/Index/IndexerTest.php b/typo3/sysext/core/Tests/Unit/Resource/Index/IndexerTest.php
new file mode 100644 (file)
index 0000000..46eb25d
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+namespace TYPO3\CMS\Core\Tests\Unit\Resource\Index;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Resource\File;
+use TYPO3\CMS\Core\Resource\Index\Indexer;
+use TYPO3\CMS\Core\Resource\Index\ExtractorInterface;
+use TYPO3\CMS\Core\Tests\UnitTestCase;
+
+/**
+ * Class IndexerTest
+ */
+class IndexerTest extends UnitTestCase
+{
+
+    /**
+     * @test
+     */
+    public function isFileTypeSupportedByExtractorReturnsFalesForFileTypeTextAndExtractorLimitedToFileTypeImage()
+    {
+
+        $mockStorage = $this->getMock(\TYPO3\CMS\Core\Resource\ResourceStorage::class, [], [], '', false);
+        $mockFile = $this->getMock(File::class, [], [], '', false);
+        $mockFile->expects($this->any())->method('getType')->will($this->returnValue(
+            File::FILETYPE_TEXT
+        ));
+
+        $mockExtractor = $this->getMock(ExtractorInterface::class, [], [], '', false);
+        $mockExtractor->expects($this->any())->method('getFileTypeRestrictions')->will($this->returnValue(
+            [File::FILETYPE_IMAGE]
+        ));
+
+        $method = new \ReflectionMethod(Indexer::class, 'isFileTypeSupportedByExtractor');
+        $method->setAccessible(true);
+        $arguments = [
+            $mockFile,
+            $mockExtractor
+        ];
+
+        $result = $method->invokeArgs(new Indexer($mockStorage), $arguments);
+        $this->assertFalse($result);
+    }
+
+    /**
+     * @test
+     */
+    public function isFileTypeSupportedByExtractorReturnsTrueForFileTypeImageAndExtractorLimitedToFileTypeImage()
+    {
+
+        $mockStorage = $this->getMock(\TYPO3\CMS\Core\Resource\ResourceStorage::class, [], [], '', false);
+        $mockFile = $this->getMock(File::class, [], [], '', false);
+        $mockFile->expects($this->any())->method('getType')->will($this->returnValue(
+            File::FILETYPE_IMAGE
+        ));
+
+        $mockExtractor = $this->getMock(ExtractorInterface::class, [], [], '', false);
+        $mockExtractor->expects($this->any())->method('getFileTypeRestrictions')->will($this->returnValue(
+            [File::FILETYPE_IMAGE]
+        ));
+
+        $method = new \ReflectionMethod(Indexer::class, 'isFileTypeSupportedByExtractor');
+        $method->setAccessible(true);
+        $arguments = [
+            $mockFile,
+            $mockExtractor
+        ];
+
+        $result = $method->invokeArgs(new Indexer($mockStorage), $arguments);
+        $this->assertTrue($result);
+    }
+
+    /**
+     * @test
+     */
+    public function isFileTypeSupportedByExtractorReturnsTrueForFileTypeTextAndExtractorHasNoFileTypeLimitation()
+    {
+
+        $mockStorage = $this->getMock(\TYPO3\CMS\Core\Resource\ResourceStorage::class, [], [], '', false);
+        $mockFile = $this->getMock(File::class, [], [], '', false);
+        $mockFile->expects($this->any())->method('getType')->will($this->returnValue(
+            File::FILETYPE_TEXT
+        ));
+
+        $mockExtractor = $this->getMock(ExtractorInterface::class, [], [], '', false);
+        $mockExtractor->expects($this->any())->method('getFileTypeRestrictions')->will($this->returnValue(
+            []
+        ));
+
+        $method = new \ReflectionMethod(Indexer::class, 'isFileTypeSupportedByExtractor');
+        $method->setAccessible(true);
+        $arguments = [
+            $mockFile,
+            $mockExtractor
+        ];
+
+        $result = $method->invokeArgs(new Indexer($mockStorage), $arguments);
+        $this->assertTrue($result);
+    }
+}