2da3b9da7af6fe400db7d6617a9479e97cc8c9f2
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Resource / FileReference.php
1 <?php
2 namespace TYPO3\CMS\Core\Resource;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2011 Ingmar Schlecht <ingmar@typo3.org>
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 textfile 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 * Representation of a specific usage of a file with possibilities to override certain
31 * properties of the original file just for this usage of the file.
32 *
33 * It acts as a decorator over the original file in the way that most method calls are
34 * directly passed along to the original file object.
35 *
36 * All file related methods are directly passed along; only meta data functionality is adopted
37 * in this decorator class to priorities possible overrides for the metadata for this specific usage
38 * of the file.
39 *
40 * @author Ingmar Schlecht <ingmar@typo3.org>
41 */
42 class FileReference implements FileInterface {
43
44 /**
45 * Various properties of the FileReference. Note that these information can be different
46 * to the ones found in the originalFile.
47 *
48 * @var array
49 */
50 protected $propertiesOfFileReference;
51
52 /**
53 * The identifier of this file to identify it on the storage.
54 * On some drivers, this is the path to the file, but drivers could also just
55 * provide any other unique identifier for this file on the specific storage.
56 *
57 * @var string
58 */
59 protected $uidOfFileReference;
60
61 /**
62 * The file name of this file. It's either the fileName of the original underlying file,
63 * or the overlay file name supplied by the user for this particular usage (FileReference) of the file.
64 *
65 * @var string
66 */
67 protected $name;
68
69 /**
70 * The FileRepository object. Is needed e.g. for the delete() method to delete the usage record
71 * (sys_file_reference record) of this file usage.
72 *
73 * @var FileRepository
74 */
75 protected $fileRepository;
76
77 /**
78 * Reference to the original File object underlying this FileReference.
79 *
80 * @var File
81 */
82 protected $originalFile;
83
84 /**
85 * Defines properties that are merged with the parent object (File) if
86 * the value is not defined (NULL). Thus, FileReference properties act
87 * as overlays for the defined File properties.
88 *
89 * @var array
90 */
91 protected $parentFallbackProperties = array(
92 'title' => 'title',
93 'description' => 'description',
94 'alternative' => 'alternative',
95 );
96
97 /**
98 * Constructor for a file in use object. Should normally not be used
99 * directly, use the corresponding factory methods instead.
100 *
101 * @param array $fileReferenceData
102 * @param ResourceFactory $factory
103 *
104 * @throws \RuntimeException
105 * @throws \InvalidArgumentException
106 */
107 public function __construct(array $fileReferenceData, $factory = NULL) {
108 $this->propertiesOfFileReference = $fileReferenceData;
109 if (!$fileReferenceData['uid_local']) {
110 throw new \InvalidArgumentException('Incorrect reference to original file given for FileReference.', 1300098528);
111 }
112 if (!$factory) {
113 /** @var $factory ResourceFactory */
114 $factory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
115 }
116 $this->originalFile = $factory->getFileObject($fileReferenceData['uid_local']);
117 $this->fileRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository');
118 if (!is_object($this->originalFile)) {
119 throw new \RuntimeException('Original File not found for FileReference.', 1300098529);
120 }
121 $this->name = $fileReferenceData['name'] !== '' ? $fileReferenceData['name'] : $this->originalFile->getName();
122 }
123
124 /*******************************
125 * VARIOUS FILE PROPERTY GETTERS
126 *******************************/
127 /**
128 * Returns true if the given key exists for this file.
129 *
130 * @param string $key The property to be looked up
131 * @return boolean
132 */
133 public function hasProperty($key) {
134 return array_key_exists($key, $this->propertiesOfFileReference);
135 }
136
137 /**
138 * Gets a property, falling back to values of the parent.
139 *
140 * @param string $key The property to be looked up
141 * @return mixed
142 */
143 public function getProperty($key) {
144 $value = $this->getReferenceProperty($key);
145
146 if ($value === NULL && !empty($this->parentFallbackProperties[$key])) {
147 $value = $this->originalFile->getProperty($key);
148 }
149
150 return $value;
151 }
152
153 /**
154 * Gets a property.
155 *
156 * @param string $key The property to be looked up
157 * @return mixed
158 * @throws \InvalidArgumentException
159 */
160 public function getReferenceProperty($key) {
161 if (!$this->hasProperty($key)) {
162 throw new \InvalidArgumentException('Property "' . $key . '" was not found.', 1314226805);
163 }
164 return $this->propertiesOfFileReference[$key];
165 }
166
167 /**
168 * Gets all properties, falling back to values of the parent.
169 *
170 * @return array
171 */
172 public function getProperties() {
173 $properties = $this->getReferenceProperties();
174 $keys = array_keys($properties);
175
176 foreach ($this->parentFallbackProperties as $localKey => $parentKey) {
177 if (array_key_exists($localKey, $keys) && $properties[$localKey] === NULL) {
178 $properties[$localKey] = $this->originalFile->getProperty($parentKey);
179 }
180 }
181 }
182
183 /**
184 * Gets all properties.
185 *
186 * @return array
187 */
188 public function getReferenceProperties() {
189 return \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule(
190 $this->originalFile->getProperties(),
191 $this->propertiesOfFileReference
192 );
193 }
194
195 /**
196 * Returns the name of this file
197 *
198 * @return string
199 */
200 public function getName() {
201 return $this->originalFile->getName();
202 }
203
204 /**
205 * Returns the title text to this image
206 *
207 * TODO: Possibly move this to the image domain object instead
208 *
209 * @return string
210 */
211 public function getTitle() {
212 return $this->getProperty('title');
213 }
214
215 /**
216 * Returns the alternative text to this image
217 *
218 * TODO: Possibly move this to the image domain object instead
219 *
220 * @return string
221 */
222 public function getAlternative() {
223 return $this->getProperty('alternative');
224 }
225
226 /**
227 * Returns the description text to this file
228 *
229 * TODO: Possibly move this to the image domain object instead
230 *
231 * @return string
232 */
233 public function getDescription() {
234 return $this->getProperty('description');
235 }
236
237 /**
238 * Returns the link that should be active when clicking on this image
239 *
240 * TODO: Move this to the image domain object instead
241 *
242 * @return string
243 */
244 public function getLink() {
245 return $this->propertiesOfFileReference['link'];
246 }
247
248 /**
249 * Returns the uid of this File In Use
250 *
251 * @return integer
252 */
253 public function getUid() {
254 return (int) $this->propertiesOfFileReference['uid'];
255 }
256
257 /**
258 * Returns the size of this file
259 *
260 * @return integer
261 */
262 public function getSize() {
263 return (int) $this->originalFile->getSize();
264 }
265
266 /**
267 * Returns the Sha1 of this file
268 *
269 * @return string
270 */
271 public function getSha1() {
272 return $this->originalFile->getSha1();
273 }
274
275 /**
276 * Get the file extension of this file
277 *
278 * @return string The file extension
279 */
280 public function getExtension() {
281 return $this->originalFile->getExtension();
282 }
283
284 /**
285 * Get the MIME type of this file
286 *
287 * @return array file information
288 */
289 public function getMimeType() {
290 return $this->originalFile->getMimeType();
291 }
292
293 /**
294 * Returns the modification time of the file as Unix timestamp
295 *
296 * @return integer
297 */
298 public function getModificationTime() {
299 return (int) $this->originalFile->getModificationTime();
300 }
301
302 /**
303 * Returns the creation time of the file as Unix timestamp
304 *
305 * @return integer
306 */
307 public function getCreationTime() {
308 return (int) $this->originalFile->getCreationTime();
309 }
310
311 /**
312 * Returns the fileType of this file
313 *
314 * @return integer $fileType
315 */
316 public function getType() {
317 return (int) $this->originalFile->getType();
318 }
319
320 /******************
321 * CONTENTS RELATED
322 ******************/
323 /**
324 * Get the contents of this file
325 *
326 * @return string File contents
327 */
328 public function getContents() {
329 return $this->originalFile->getContents();
330 }
331
332 /**
333 * Replace the current file contents with the given string
334 *
335 * @param string $contents The contents to write to the file.
336 * @return File The file object (allows chaining).
337 */
338 public function setContents($contents) {
339 return $this->originalFile->setContents($contents);
340 }
341
342 /****************************************
343 * STORAGE AND MANAGEMENT RELATED METHDOS
344 ****************************************/
345 /**
346 * Get the storage the original file is located in
347 *
348 * @return ResourceStorage
349 */
350 public function getStorage() {
351 return $this->originalFile->getStorage();
352 }
353
354 /**
355 * Returns the identifier of the underlying original file
356 *
357 * @return string
358 */
359 public function getIdentifier() {
360 return $this->originalFile->getIdentifier();
361 }
362
363 /**
364 * Returns a combined identifier of the underlying original file
365 *
366 * @return string Combined storage and file identifier, e.g. StorageUID:path/and/fileName.png
367 */
368 public function getCombinedIdentifier() {
369 return $this->originalFile->getCombinedIdentifier();
370 }
371
372 /**
373 * Deletes only this particular FileReference from the persistence layer
374 * (database table sys_file_reference) but leaves the original file untouched.
375 *
376 * @throws \BadMethodCallException
377 * @return boolean TRUE if deletion succeeded
378 */
379 public function delete() {
380 // TODO: Implement this function. This should only delete the
381 // FileReference (sys_file_reference) record, not the file itself.
382 throw new \BadMethodCallException('Function not implemented FileReference::delete().', 1333754461);
383 return $this->fileRepository->removeUsageRecord($this);
384 }
385
386 /**
387 * Renames the fileName in this particular usage.
388 *
389 * @param string $newName The new name
390 *
391 * @throws \BadMethodCallException
392 * @return FileReference
393 */
394 public function rename($newName) {
395 // TODO: Implement this function. This should only rename the
396 // FileReference (sys_file_reference) record, not the file itself.
397 throw new \BadMethodCallException('Function not implemented FileReference::rename().', 1333754473);
398 return $this->fileRepository->renameUsageRecord($this, $newName);
399 }
400
401 /*****************
402 * SPECIAL METHODS
403 *****************/
404 /**
405 * Returns a publicly accessible URL for this file
406 *
407 * WARNING: Access to the file may be restricted by further means, e.g.
408 * some web-based authentication. You have to take care of this yourself.
409 *
410 * @param bool $relativeToCurrentScript Determines whether the URL returned should be relative to the current script, in case it is relative at all (only for the LocalDriver)
411 * @return string
412 */
413 public function getPublicUrl($relativeToCurrentScript = FALSE) {
414 return $this->originalFile->getPublicUrl($relativeToCurrentScript);
415 }
416
417 /**
418 * Returns TRUE if this file is indexed.
419 * This is always true for FileReference objects, as they rely on a
420 * sys_file_reference record to be present, which in turn can only exist if
421 * the original file is indexed.
422 *
423 * @return boolean
424 */
425 public function isIndexed() {
426 return TRUE;
427 }
428
429 /**
430 * Returns a path to a local version of this file to process it locally (e.g. with some system tool).
431 * If the file is normally located on a remote storages, this creates a local copy.
432 * If the file is already on the local system, this only makes a new copy if $writable is set to TRUE.
433 *
434 * @param boolean $writable Set this to FALSE if you only want to do read operations on the file.
435 * @return string
436 */
437 public function getForLocalProcessing($writable = TRUE) {
438 return $this->originalFile->getForLocalProcessing($writable);
439 }
440
441 /**
442 * Returns an array representation of the file.
443 * (This is used by the generic listing module vidi when displaying file records.)
444 *
445 * @return array Array of main data of the file. Don't rely on all data to be present here, it's just a selection of the most relevant information.
446 */
447 public function toArray() {
448 $array = array_merge($this->originalFile->toArray(), $this->propertiesOfFileReference);
449 return $array;
450 }
451
452 /**
453 * Gets the original file being referenced.
454 *
455 * @return File
456 */
457 public function getOriginalFile() {
458 return $this->originalFile;
459 }
460
461 }
462
463
464 ?>