[TASK] Create new processor registry
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Resource / Processing / FileProcessorRegistry.php
1 <?php
2 namespace TYPO3\CMS\Core\Resource\Processing;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2014 Frans Saris <franssaris@gmail.com>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the text file GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29
30 /**
31 * Registry for File Processors
32 */
33 class FileProcessorRegistry implements \TYPO3\CMS\Core\SingletonInterface {
34
35 /**
36 * Registered FileProcessor ClassNames
37 *
38 * @var array
39 */
40 protected $fileProcessors = array();
41
42 /**
43 * Instance Cache for Processors
44 *
45 * @var array FileProcessorInterface[]
46 */
47 protected $instances;
48
49 /**
50 * Returns an instance of this class
51 *
52 * @return FileProcessorRegistry
53 */
54 public static function getInstance() {
55 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\Processing\\FileProcessorRegistry');
56 }
57
58 /**
59 * Constructor
60 */
61 public function __construct() {
62 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['fal']['fileProcessors'])) {
63 foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['fal']['fileProcessors'] as $class) {
64 $this->registerFileProcessorClass($class);
65 }
66 }
67 }
68
69 /**
70 * Allows to register a FileProcessor
71 *
72 * @param string $className
73 * @throws \InvalidArgumentException
74 */
75 public function registerFileProcessorClass($className) {
76 if (!class_exists($className)) {
77 throw new \InvalidArgumentException('The Class you are registering is not available', 1393614709);
78 } elseif (!in_array('TYPO3\\CMS\\Core\\Resource\\Processing\\FileProcessorInterface', class_implements($className))) {
79 throw new \InvalidArgumentException('The Processor needs to implement the FileProcessorInterface', 1393614710);
80 } else {
81 $this->fileProcessors[] = $className;
82 }
83 }
84
85 /**
86 * Get all registered processors
87 *
88 * @return array FileProcessorInterface[]
89 */
90 public function getFileProcessors() {
91 if ($this->instances === NULL) {
92 $this->instances = array();
93
94 // as the result is in reverse order we need to reverse
95 // the array before processing to keep the items with same
96 // priority in the same order as they were added to the registry.
97 $fileProcessors = array_reverse($this->fileProcessors);
98 foreach ($fileProcessors as $className) {
99 /** @var FileProcessorInterface $object */
100 $object = $this->createFileProcessorInstance($className);
101 $this->instances[] = $object;
102 }
103
104 if (count($this->instances) > 1) {
105 usort($this->instances, array($this, 'compareProcessorPriority'));
106 }
107 }
108 return $this->instances;
109 }
110
111 /**
112 * Create an instance of a certain FileProcessor class
113 *
114 * @param $className
115 * @return FileProcessorInterface
116 */
117 protected function createFileProcessorInstance($className) {
118 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($className);
119 }
120
121 /**
122 * Compare the priority of 2 File Processors
123 * Is used for sorting array of FileProcessor instances by priority
124 * We want the result to be ordered from high to low so a higher
125 * priority comes before a lower.
126 *
127 * @param FileProcessorInterface $processorA
128 * @param FileProcessorInterface $processorB
129 * @return int -1 a > b, 0 a == b, 1 a < b
130 */
131 protected function compareProcessorPriority(FileProcessorInterface $processorA, FileProcessorInterface $processorB) {
132 $return = 0;
133 if ($processorA->getPriority() < $processorB->getPriority()) {
134 $return = 1;
135 } elseif ($processorA->getPriority() > $processorB->getPriority()) {
136 $return = -1;
137 }
138 return $return;
139 }
140
141 /**
142 * Get FileProcessors which work for a special driver
143 *
144 * @param string $driverType
145 * @return array FileProcessorInterface[]
146 */
147 public function getFileProcessorsWithDriverSupport($driverType) {
148 $allProcessors = $this->getFileProcessors();
149 $filteredProcessors = array();
150
151 /** @var FileProcessorInterface $processorObject */
152 foreach ($allProcessors as $processorObject) {
153 if ($processorObject->getDriverRestrictions() === array()) {
154 $filteredProcessors[] = $processorObject;
155 } elseif (in_array($driverType, $processorObject->getDriverRestrictions())) {
156 $filteredProcessors[] = $processorObject;
157 }
158 }
159 return $filteredProcessors;
160 }
161
162 /**
163 * Get matching file processor with highest priority
164 *
165 * @param \TYPO3\CMS\Core\Resource\FileInterface $file
166 * @param ProcessingRequestInterface $processingRequest
167 * @return NULL|FileProcessorInterface
168 */
169 public function getProcessorFor(\TYPO3\CMS\Core\Resource\FileInterface $file, ProcessingRequestInterface $processingRequest) {
170 $driverType = $file->getStorage()->getDriverType();
171 $matchingFileProcessor = NULL;
172
173 /** @var FileProcessorInterface $fileProcessor */
174 foreach ($this->getFileProcessorsWithDriverSupport($driverType) as $fileProcessor) {
175 if ($fileProcessor->canProcess($file, $processingRequest)) {
176 $matchingFileProcessor = $fileProcessor;
177 break;
178 }
179 }
180 return $matchingFileProcessor;
181 }
182 }