[FEATURE] Trigger metadata extraction after file upload 59/43059/5
authorFrans Saris <franssaris@gmail.com>
Thu, 2 Apr 2015 18:14:39 +0000 (20:14 +0200)
committerGeorg Ringer <georg.ringer@gmail.com>
Mon, 7 Sep 2015 20:14:45 +0000 (22:14 +0200)
Releases: master
Resolves: #56726
Change-Id: I8f08403aca72bc9ca3f37dec6f98bf016c79a9ee
Reviewed-on: http://review.typo3.org/43059
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
typo3/sysext/core/Classes/Resource/Index/Indexer.php
typo3/sysext/core/Classes/Resource/ResourceStorage.php
typo3/sysext/core/Configuration/TCA/sys_file_storage.php
typo3/sysext/core/Documentation/Changelog/master/Feature-56726-TriggerMetadataExtractionAfterFileUpload.rst [new file with mode: 0644]
typo3/sysext/core/ext_tables.sql
typo3/sysext/lang/locallang_tca.xlf

index b52b534..9363734 100644 (file)
@@ -40,6 +40,11 @@ class Indexer {
        protected $storage = NULL;
 
        /**
+        * @var ExtractorInterface[]
+        */
+       protected $extractionServices = NULL;
+
+       /**
         * @param ResourceStorage $storage
         */
        public function __construct(ResourceStorage $storage) {
@@ -95,28 +100,46 @@ class Indexer {
         */
        public function runMetaDataExtraction($maximumFileCount = -1) {
                $fileIndexRecords = $this->getFileIndexRepository()->findInStorageWithIndexOutstanding($this->storage, $maximumFileCount);
-
-               $extractionServices = $this->getExtractorRegistry()->getExtractorsWithDriverSupport($this->storage->getDriverType());
                foreach ($fileIndexRecords as $indexRecord) {
                        $fileObject = $this->getResourceFactory()->getFileObject($indexRecord['uid'], $indexRecord);
+                       $this->extractMetaData($fileObject);
+               }
+       }
 
-                       $newMetaData = array(
-                               0 => $fileObject->_getMetaData()
-                       );
-                       foreach ($extractionServices as $service) {
-                               if ($service->canProcess($fileObject)) {
-                                       $newMetaData[$service->getPriority()] = $service->extractMetaData($fileObject, $newMetaData);
-                               }
-                       }
-                       ksort($newMetaData);
-                       $metaData = array();
-                       foreach ($newMetaData as $data) {
-                               $metaData = array_merge($metaData, $data);
+       /**
+        * Extract metadata for given fileObject
+        *
+        * @param File $fileObject
+        */
+       public function extractMetaData(File $fileObject) {
+               $newMetaData = array(
+                       0 => $fileObject->_getMetaData()
+               );
+               foreach ($this->getExtractionServices() as $service) {
+                       if ($service->canProcess($fileObject)) {
+                               $newMetaData[$service->getPriority()] = $service->extractMetaData($fileObject, $newMetaData);
                        }
-                       $fileObject->_updateMetaDataProperties($metaData);
-                       $this->getMetaDataRepository()->update($fileObject->getUid(), $metaData);
-                       $this->getFileIndexRepository()->updateIndexingTime($fileObject->getUid());
                }
+               ksort($newMetaData);
+               $metaData = array();
+               foreach ($newMetaData as $data) {
+                       $metaData = array_merge($metaData, $data);
+               }
+               $fileObject->_updateMetaDataProperties($metaData);
+               $this->getMetaDataRepository()->update($fileObject->getUid(), $metaData);
+               $this->getFileIndexRepository()->updateIndexingTime($fileObject->getUid());
+       }
+
+       /**
+        * Get available extraction services
+        *
+        * @return ExtractorInterface[]
+        */
+       protected function getExtractionServices() {
+               if ($this->extractionServices === NULL) {
+                       $this->extractionServices = $this->getExtractorRegistry()->getExtractorsWithDriverSupport($this->storage->getDriverType());
+               }
+               return $this->extractionServices;
        }
 
        /**
index 13f310d..1de3240 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Core\Resource;
 
 use TYPO3\CMS\Core\Resource\Exception\InvalidTargetFolderException;
 use TYPO3\CMS\Core\Resource\Index\FileIndexRepository;
+use TYPO3\CMS\Core\Resource\Index\Indexer;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\PathUtility;
 
@@ -350,6 +351,15 @@ class ResourceStorage implements ResourceStorageInterface {
        }
 
        /**
+        * Returns TRUE if auto extracting of metadata is enabled
+        *
+        * @return bool
+        */
+       public function autoExtractMetadataEnabled() {
+               return !empty($this->storageRecord['auto_extract_metadata']);
+       }
+
+       /**
         * Blows the "fuse" and marks the storage as offline.
         *
         * Can only be modified by an admin.
@@ -1116,6 +1126,11 @@ class ResourceStorage implements ResourceStorageInterface {
                $fileIdentifier = $this->driver->addFile($localFilePath, $targetFolder->getIdentifier(), $targetFileName);
                $file = ResourceFactory::getInstance()->getFileObjectByStorageAndIdentifier($this->getUid(), $fileIdentifier);
 
+               if ($this->autoExtractMetadataEnabled()) {
+                       $indexer = GeneralUtility::makeInstance(Indexer::class, $this);
+                       $indexer->extractMetaData($file);
+               }
+
                $this->emitPostFileAddSignal($file, $targetFolder);
 
                return $file;
@@ -1199,6 +1214,7 @@ class ResourceStorage implements ResourceStorageInterface {
                if ($this->isOnline()) {
                        // Pre-process the public URL by an accordant slot
                        $this->emitPreGeneratePublicUrlSignal($resourceObject, $relativeToCurrentScript, array('publicUrl' => &$publicUrl));
+
                        // If slot did not handle the signal, use the default way to determine public URL
                        if ($publicUrl === NULL) {
 
@@ -1792,7 +1808,12 @@ class ResourceStorage implements ResourceStorageInterface {
                if ($file instanceof File) {
                        $this->getIndexer()->updateIndexEntry($file);
                }
+               if ($this->autoExtractMetadataEnabled()) {
+                       $indexer = GeneralUtility::makeInstance(Indexer::class, $this);
+                       $indexer->extractMetaData($file);
+               }
                $this->emitPostFileReplaceSignal($file, $localFilePath);
+
                return $file;
        }
 
index d45cfd7..ddf0139 100644 (file)
@@ -16,7 +16,7 @@ return array(
                'searchFields' => 'name,description'
        ),
        'interface' => array(
-               'showRecordFieldList' => 'name,description,driver,processingfolder,configuration'
+               'showRecordFieldList' => 'name,description,driver,processingfolder,configuration,auto_extract_metadata'
        ),
        'columns' => array(
                'name' => array(
@@ -82,6 +82,14 @@ return array(
                                'default' => 1
                        )
                ),
+               'auto_extract_metadata' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:lang/locallang_tca.xlf:sys_file_storage.auto_extract_metadata',
+                       'config' => array(
+                               'type' => 'check',
+                               'default' => 1
+                       )
+               ),
                'processingfolder' => array(
                        'exclude' => 0,
                        'label' => 'LLL:EXT:lang/locallang_tca.xlf:sys_file_storage.processingfolder',
@@ -112,7 +120,7 @@ return array(
                )
        ),
        'types' => array(
-               '0' => array('showitem' => 'name, description, --div--;Configuration, driver, configuration, is_default, processingfolder, --div--;Access, --palette--;Capabilities;capabilities, is_online')
+               '0' => array('showitem' => 'name, description, --div--;Configuration, driver, configuration, is_default, auto_extract_metadata, processingfolder, --div--;Access, --palette--;Capabilities;capabilities, is_online')
        ),
        'palettes' => array(
                'capabilities' => array(
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-56726-TriggerMetadataExtractionAfterFileUpload.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-56726-TriggerMetadataExtractionAfterFileUpload.rst
new file mode 100644 (file)
index 0000000..2da2e58
--- /dev/null
@@ -0,0 +1,20 @@
+===============================================================
+Feature: #56726 - Trigger metadata extraction after file upload
+===============================================================
+
+Description
+===========
+
+Before #56726 the metadata extraction was only called through the extract metadata scheduler task.
+So when a editor uploaded a new file he had to wait until the scheduler task is triggered again and extracted the metadata.
+
+Now the metadata extraction is by default triggered after adding/uploading a file in the BE. Or when the FAL API is used ``ResourceStorage::addFile()``, ``ResourceStorage::replaceFile()`` and ``ResourceStorage::addUploadedFile()``.
+
+In some special situations it isn't desired to have metadata extraction direct after file upload/adding a file to the storage.
+For these cases the automatic extraction can be disabled in File Storage configuration.
+
+
+Impact
+======
+
+The flag is by default set for all existing and new storages. When you have some special use-case where automatic extraction of metadata is not desired the flag needs to be disabled in File Storage configuration.
\ No newline at end of file
index 3568420..7053a53 100644 (file)
@@ -259,6 +259,7 @@ CREATE TABLE sys_file_storage (
        is_public tinyint(4) DEFAULT '0' NOT NULL,
        is_writable tinyint(4) DEFAULT '0' NOT NULL,
        is_online tinyint(4) DEFAULT '1' NOT NULL,
+       auto_extract_metadata tinyint(4) DEFAULT '1' NOT NULL,
        processingfolder tinytext,
 
        PRIMARY KEY (uid),
index 4b77c5b..c8a7dd2 100644 (file)
                        <trans-unit id="sys_file_storage.is_writable">
                                <source>Is writable?</source>
                        </trans-unit>
+                       <trans-unit id="sys_file_storage.auto_extract_metadata">
+                               <source>Automatically extract metadata after upload</source>
+                       </trans-unit>
                        <trans-unit id="sys_file_storage.capabilities">
                                <source>Capabilities</source>
                        </trans-unit>