[BUGFIX] Add missing copy and cut button in file list search result
[Packages/TYPO3.CMS.git] / typo3 / sysext / filelist / Classes / FileFacade.php
1 <?php
2 namespace TYPO3\CMS\Filelist;
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 use TYPO3\CMS\Backend\Clipboard\Clipboard;
18 use TYPO3\CMS\Backend\Utility\BackendUtility;
19 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
20 use TYPO3\CMS\Core\Database\ConnectionPool;
21 use TYPO3\CMS\Core\Imaging\Icon;
22 use TYPO3\CMS\Core\Imaging\IconFactory;
23 use TYPO3\CMS\Core\Localization\LanguageService;
24 use TYPO3\CMS\Core\Resource\FileInterface;
25 use TYPO3\CMS\Core\Utility\GeneralUtility;
26
27 /**
28 * Class FileFacade
29 *
30 * This class is meant to be a wrapper for Resource\File objects, which do not
31 * provide necessary methods needed in the views of the filelist extension. It
32 * is a first approach to get rid of the FileList class that mixes up PHP,
33 * HTML and JavaScript.
34 * @internal this is a concrete TYPO3 hook implementation and solely used for EXT:filelist and not part of TYPO3's Core API.
35 */
36 class FileFacade
37 {
38 /**
39 * Cache to count the number of references for each file
40 *
41 * @var array
42 */
43 protected static $referenceCounts = [];
44
45 /**
46 * @var \TYPO3\CMS\Core\Resource\FileInterface
47 */
48 protected $resource;
49
50 /**
51 * @var \TYPO3\CMS\Core\Imaging\IconFactory
52 */
53 protected $iconFactory;
54
55 /**
56 * @param \TYPO3\CMS\Core\Resource\FileInterface $resource
57 * @internal Do not use outside of EXT:filelist!
58 */
59 public function __construct(FileInterface $resource)
60 {
61 $this->resource = $resource;
62 $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
63 }
64
65 /**
66 * @return string
67 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
68 */
69 public function getIcon(): string
70 {
71 trigger_error('FileFacade->getIcon() will be removed in TYPO3 v10.0, use ViewHelper <core:iconForResource /> instead.', E_USER_DEPRECATED);
72 $title = htmlspecialchars($this->resource->getName() . ' [' . (int)$this->resource->getProperty('uid') . ']');
73 return '<span title="' . $title . '">' . $this->iconFactory->getIconForResource($this->resource, Icon::SIZE_SMALL) . '</span>';
74 }
75
76 /**
77 * @return \TYPO3\CMS\Core\Resource\FileInterface
78 */
79 public function getResource(): FileInterface
80 {
81 return $this->resource;
82 }
83
84 /**
85 * @return bool
86 */
87 public function getIsEditable(): bool
88 {
89 return $this->getIsWritable()
90 && GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'], $this->resource->getExtension());
91 }
92
93 /**
94 * @return bool
95 */
96 public function getIsMetadataEditable(): bool
97 {
98 return $this->resource->isIndexed() && $this->getIsWritable() && $this->getBackendUser()->check('tables_modify', 'sys_file_metadata');
99 }
100
101 /**
102 * @return int
103 */
104 public function getMetadataUid(): int
105 {
106 $uid = 0;
107 $method = '_getMetadata';
108 if (is_callable([$this->resource, $method])) {
109 $metadata = call_user_func([$this->resource, $method]);
110
111 if (isset($metadata['uid'])) {
112 $uid = (int)$metadata['uid'];
113 }
114 }
115
116 return $uid;
117 }
118
119 /**
120 * @return string
121 */
122 public function getName(): string
123 {
124 return $this->resource->getName();
125 }
126
127 /**
128 * @return string
129 */
130 public function getPath(): string
131 {
132 $method = 'getReadablePath';
133 if (is_callable([$this->resource->getParentFolder(), $method])) {
134 return call_user_func([$this->resource->getParentFolder(), $method]);
135 }
136
137 return '';
138 }
139
140 /**
141 * @return string|null
142 */
143 public function getPublicUrl()
144 {
145 return $this->resource->getPublicUrl(true);
146 }
147
148 /**
149 * @return string
150 */
151 public function getExtension(): string
152 {
153 return strtoupper($this->resource->getExtension());
154 }
155
156 /**
157 * @return string
158 */
159 public function getIdentifier(): string
160 {
161 return $this->resource->getStorage()->getUid() . ':' . $this->resource->getIdentifier();
162 }
163
164 /**
165 * @return string
166 */
167 public function getLastModified(): string
168 {
169 return BackendUtility::date($this->resource->getModificationTime());
170 }
171
172 /**
173 * @return string
174 */
175 public function getSize(): string
176 {
177 return GeneralUtility::formatSize($this->resource->getSize(), htmlspecialchars($this->getLanguageService()->getLL('byteSizeUnits')));
178 }
179
180 /**
181 * @return bool
182 */
183 public function getIsReadable()
184 {
185 $method = 'checkActionPermission';
186 if (is_callable([$this->resource, $method])) {
187 return call_user_func_array([$this->resource, $method], ['read']);
188 }
189
190 return false;
191 }
192
193 /**
194 * @return bool
195 */
196 public function getIsWritable()
197 {
198 $method = 'checkActionPermission';
199 if (is_callable([$this->resource, $method])) {
200 return call_user_func_array([$this->resource, $method], ['write']);
201 }
202
203 return false;
204 }
205
206 /**
207 * @return bool
208 */
209 public function getIsReplaceable()
210 {
211 $method = 'checkActionPermission';
212 if (is_callable([$this->resource, $method])) {
213 return call_user_func_array([$this->resource, $method], ['replace']);
214 }
215
216 return false;
217 }
218
219 /**
220 * @return bool
221 */
222 public function getIsRenamable()
223 {
224 $method = 'checkActionPermission';
225 if (is_callable([$this->resource, $method])) {
226 return call_user_func_array([$this->resource, $method], ['rename']);
227 }
228
229 return false;
230 }
231
232 /**
233 * @return bool
234 */
235 public function isCopyable()
236 {
237 $method = 'checkActionPermission';
238 if (is_callable([$this->resource, $method])) {
239 return call_user_func_array([$this->resource, $method], ['copy']);
240 }
241
242 return false;
243 }
244
245 /**
246 * @return bool
247 */
248 public function isCuttable()
249 {
250 $method = 'checkActionPermission';
251 if (is_callable([$this->resource, $method])) {
252 return call_user_func_array([$this->resource, $method], ['move']);
253 }
254
255 return false;
256 }
257
258 /**
259 * @return bool
260 */
261 public function getIsDeletable()
262 {
263 $method = 'checkActionPermission';
264 if (is_callable([$this->resource, $method])) {
265 return call_user_func_array([$this->resource, $method], ['delete']);
266 }
267
268 return false;
269 }
270
271 /**
272 * @return bool
273 */
274 public function isSelected()
275 {
276 $fullIdentifier = $this->getIdentifier();
277 $md5 = GeneralUtility::shortMD5($fullIdentifier);
278
279 /** @var Clipboard $clipboard */
280 $clipboard = GeneralUtility::makeInstance(Clipboard::class);
281 $clipboard->initializeClipboard();
282
283 $isSel = $clipboard->isSelected('_FILE', $md5);
284
285 if ($isSel) {
286 return $isSel;
287 }
288
289 return false;
290 }
291
292 /**
293 * @return bool
294 */
295 public function getIsImage()
296 {
297 return GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], strtolower($this->getExtension()));
298 }
299
300 /**
301 * Fetch, cache and return the number of references of a file
302 *
303 * @return int
304 */
305 public function getReferenceCount(): int
306 {
307 $uid = (int)$this->resource->getProperty('uid');
308
309 if ($uid <= 0) {
310 return 0;
311 }
312
313 if (!isset(static::$referenceCounts[$uid])) {
314 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex');
315 $count = $queryBuilder->count('*')
316 ->from('sys_refindex')
317 ->where(
318 $queryBuilder->expr()->eq('deleted', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)),
319 $queryBuilder->expr()->eq(
320 'ref_table',
321 $queryBuilder->createNamedParameter('sys_file', \PDO::PARAM_STR)
322 ),
323 $queryBuilder->expr()->eq(
324 'ref_uid',
325 $queryBuilder->createNamedParameter($this->resource->getProperty('uid'), \PDO::PARAM_INT)
326 ),
327 $queryBuilder->expr()->neq(
328 'tablename',
329 $queryBuilder->createNamedParameter('sys_file_metadata', \PDO::PARAM_STR)
330 )
331 )
332 ->execute()
333 ->fetchColumn();
334
335 static::$referenceCounts[$uid] = $count;
336 }
337
338 return static::$referenceCounts[$uid];
339 }
340
341 /**
342 * @param string $method
343 * @param array $arguments
344 *
345 * @return mixed
346 */
347 public function __call($method, $arguments)
348 {
349 if (is_callable([$this->resource, $method])) {
350 return call_user_func_array([$this->resource, $method], $arguments);
351 }
352
353 return null;
354 }
355
356 /**
357 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
358 */
359 protected function getBackendUser(): BackendUserAuthentication
360 {
361 return $GLOBALS['BE_USER'];
362 }
363
364 /**
365 * @return \TYPO3\CMS\Core\Localization\LanguageService
366 */
367 protected function getLanguageService(): LanguageService
368 {
369 return $GLOBALS['LANG'];
370 }
371 }