186dd653c696cb27ca9559756e66c18a8b681634
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Resource / StorageRepository.php
1 <?php
2 namespace TYPO3\CMS\Core\Resource;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Repository for accessing the file mounts
19 *
20 * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
21 * @author Ingmar Schlecht <ingmar@typo3.org>
22 */
23 class StorageRepository extends AbstractRepository {
24
25 /**
26 * @var null|array‚
27 */
28 protected static $storageRowCache = NULL;
29
30 /**
31 * @var string
32 */
33 protected $objectType = \TYPO3\CMS\Core\Resource\ResourceStorage::class;
34
35 /**
36 * @var string
37 */
38 protected $table = 'sys_file_storage';
39
40 /**
41 * @var string
42 */
43 protected $typeField = 'driver';
44
45 /**
46 * @var string
47 */
48 protected $driverField = 'driver';
49
50 /**
51 * @var \TYPO3\CMS\Core\Log\Logger
52 */
53 protected $logger;
54
55 /**
56 * @var \TYPO3\CMS\Core\Database\DatabaseConnection
57 */
58 protected $db;
59
60 public function __construct() {
61 parent::__construct();
62
63 /** @var $logManager \TYPO3\CMS\Core\Log\LogManager */
64 $logManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Log\LogManager::class);
65 $this->logger = $logManager->getLogger(__CLASS__);
66 $this->db = $GLOBALS['TYPO3_DB'];
67 }
68
69 /**
70 * @param int $uid
71 *
72 * @return null|ResourceStorage
73 */
74 public function findByUid($uid) {
75 $this->initializeLocalCache();
76 if (isset(self::$storageRowCache[$uid])) {
77 return $this->factory->getStorageObject($uid, self::$storageRowCache[$uid]);
78 }
79 return NULL;
80 }
81
82
83 /**
84 * Initializes the Storage
85 *
86 * @return void
87 */
88 protected function initializeLocalCache() {
89 if (static::$storageRowCache === NULL) {
90
91 static::$storageRowCache = $this->db->exec_SELECTgetRows(
92 '*',
93 $this->table,
94 '1=1' . $this->getWhereClauseForEnabledFields(),
95 '',
96 'name',
97 '',
98 'uid'
99 );
100 // if no storage is created before or the user has not access to a storage
101 // static::$storageRowCache would have the value array()
102 // so check if there is any record. If no record is found, create the fileadmin/ storage
103 // selecting just one row is enoung
104
105 if (static::$storageRowCache === array()) {
106 $storageObjectsExists = $this->db->exec_SELECTgetSingleRow('uid', $this->table, '');
107 if ($storageObjectsExists !== NULL) {
108 if ($this->createLocalStorage(
109 'fileadmin/ (auto-created)',
110 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'],
111 'relative',
112 'This is the local fileadmin/ directory. This storage mount has been created automatically by TYPO3.',
113 TRUE
114 ) > 0 ) {
115 // reset to null to force reloading of storages
116 static::$storageRowCache = NULL;
117 // call self for initialize Cache
118 $this->initializeLocalCache();
119 }
120 }
121 }
122 }
123 }
124
125 /**
126 * Finds storages by type, i.e. the driver used
127 *
128 * @param string $storageType
129 * @return ResourceStorage[]
130 */
131 public function findByStorageType($storageType) {
132 $this->initializeLocalCache();
133
134 /** @var $driverRegistry Driver\DriverRegistry */
135 $driverRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Driver\DriverRegistry::class);
136
137 $storageObjects = array();
138 foreach (static::$storageRowCache as $storageRow) {
139 if ($storageRow['driver'] !== $storageType) {
140 continue;
141 }
142 if ($driverRegistry->driverExists($storageRow['driver'])) {
143 $storageObjects[] = $this->factory->getStorageObject($storageRow['uid'], $storageRow);
144 } else {
145 $this->logger->warning(
146 sprintf('Could not instantiate storage "%s" because of missing driver.', array($storageRow['name'])),
147 $storageRow
148 );
149 }
150 }
151 return $storageObjects;
152 }
153
154 /**
155 * Returns a list of mountpoints that are available in the VFS.
156 * In case no storage exists this automatically created a storage for fileadmin/
157 *
158 * @return ResourceStorage[]
159 */
160 public function findAll() {
161 $this->initializeLocalCache();
162
163 /** @var $driverRegistry Driver\DriverRegistry */
164 $driverRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Driver\DriverRegistry::class);
165
166 $storageObjects = array();
167 foreach (static::$storageRowCache as $storageRow) {
168 if ($driverRegistry->driverExists($storageRow['driver'])) {
169 $storageObjects[] = $this->factory->getStorageObject($storageRow['uid'], $storageRow);
170 } else {
171 $this->logger->warning(
172 sprintf('Could not instantiate storage "%s" because of missing driver.', array($storageRow['name'])),
173 $storageRow
174 );
175 }
176 }
177 return $storageObjects;
178 }
179
180 /**
181 * Create the initial local storage base e.g. for the fileadmin/ directory.
182 *
183 * @param string $name
184 * @param string $basePath
185 * @param string $pathType
186 * @param string $description
187 * @param bool $default set to default storage
188 * @return int uid of the inserted record
189 */
190 public function createLocalStorage($name, $basePath, $pathType, $description = '', $default = FALSE) {
191 $caseSensitive = $this->testCaseSensitivity($pathType === 'relative' ? PATH_site . $basePath : $basePath);
192 // create the FlexForm for the driver configuration
193 $flexFormData = array(
194 'data' => array(
195 'sDEF' => array(
196 'lDEF' => array(
197 'basePath' => array('vDEF' => rtrim($basePath, '/') . '/'),
198 'pathType' => array('vDEF' => $pathType),
199 'caseSensitive' => array('vDEF' => $caseSensitive)
200 )
201 )
202 )
203 );
204
205 /** @var $flexObj \TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools */
206 $flexObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools::class);
207 $flexFormXml = $flexObj->flexArray2Xml($flexFormData, TRUE);
208
209 // create the record
210 $field_values = array(
211 'pid' => 0,
212 'tstamp' => $GLOBALS['EXEC_TIME'],
213 'crdate' => $GLOBALS['EXEC_TIME'],
214 'name' => $name,
215 'description' => $description,
216 'driver' => 'Local',
217 'configuration' => $flexFormXml,
218 'is_online' => 1,
219 'is_browsable' => 1,
220 'is_public' => 1,
221 'is_writable' => 1,
222 'is_default' => $default ? 1 : 0
223 );
224 $this->db->exec_INSERTquery('sys_file_storage', $field_values);
225 return (int)$this->db->sql_insert_id();
226 }
227
228 /**
229 * Creates an object managed by this repository.
230 *
231 * @param array $databaseRow
232 * @return ResourceStorage
233 */
234 protected function createDomainObject(array $databaseRow) {
235 return $this->factory->getStorageObject($databaseRow['uid'], $databaseRow);
236 }
237
238 /**
239 * Test if the local filesystem is case sensitive
240 *
241 * @param string $absolutePath
242 * @return bool
243 */
244 protected function testCaseSensitivity($absolutePath) {
245 $caseSensitive = TRUE;
246 $path = rtrim($absolutePath, '/') . '/aAbB';
247 $testFileExists = @file_exists($path);
248
249 // create test file
250 if (!$testFileExists) {
251 touch($path);
252 }
253
254 // do the actual sensitivity check
255 if (@file_exists(strtoupper($path)) && @file_exists(strtolower($path))) {
256 $caseSensitive = FALSE;
257 }
258
259 // clean filesystem
260 if (!$testFileExists) {
261 unlink($path);
262 }
263
264 return $caseSensitive;
265 }
266
267 }