Completed
Push — master ( 989ca3...ab5d30 )
by
unknown
39:06 queued 17:14
created

FileFacade::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
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\IconFactory;
22
use TYPO3\CMS\Core\Localization\LanguageService;
23
use TYPO3\CMS\Core\Resource\AbstractFile;
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 \TYPO3\CMS\Core\Resource\FileInterface
67
     */
68
    public function getResource(): FileInterface
69
    {
70
        return $this->resource;
71
    }
72
73
    /**
74
     * @return bool
75
     */
76
    public function getIsEditable(): bool
77
    {
78
        return $this->getIsWritable()
79
            && $this->resource instanceof AbstractFile
80
            && $this->resource->isTextFile();
81
    }
82
83
    /**
84
     * @return bool
85
     */
86
    public function getIsMetadataEditable(): bool
87
    {
88
        return $this->resource->isIndexed() && $this->getIsWritable() && $this->getBackendUser()->check('tables_modify', 'sys_file_metadata');
89
    }
90
91
    /**
92
     * @return int
93
     */
94
    public function getMetadataUid(): int
95
    {
96
        $uid = 0;
97
        $method = '_getMetadata';
98
        if (is_callable([$this->resource, $method])) {
99
            $metadata = call_user_func([$this->resource, $method]);
100
101
            if (isset($metadata['uid'])) {
102
                $uid = (int)$metadata['uid'];
103
            }
104
        }
105
106
        return $uid;
107
    }
108
109
    /**
110
     * @return string
111
     */
112
    public function getName(): string
113
    {
114
        return $this->resource->getName();
115
    }
116
117
    /**
118
     * @return string
119
     */
120
    public function getPath(): string
121
    {
122
        $method = 'getReadablePath';
123
        if (is_callable([$this->resource->getParentFolder(), $method])) {
124
            return call_user_func([$this->resource->getParentFolder(), $method]);
125
        }
126
127
        return '';
128
    }
129
130
    /**
131
     * @return string|null
132
     */
133
    public function getPublicUrl()
134
    {
135
        return $this->resource->getPublicUrl(true);
136
    }
137
138
    /**
139
     * @return string
140
     */
141
    public function getExtension(): string
142
    {
143
        return strtoupper($this->resource->getExtension());
144
    }
145
146
    /**
147
     * @return string
148
     */
149
    public function getIdentifier(): string
150
    {
151
        return $this->resource->getStorage()->getUid() . ':' . $this->resource->getIdentifier();
152
    }
153
154
    /**
155
     * @return string
156
     */
157
    public function getLastModified(): string
158
    {
159
        return BackendUtility::date($this->resource->getModificationTime());
160
    }
161
162
    /**
163
     * @return string
164
     */
165
    public function getSize(): string
166
    {
167
        return GeneralUtility::formatSize($this->resource->getSize(), htmlspecialchars($this->getLanguageService()->getLL('byteSizeUnits')));
168
    }
169
170
    /**
171
     * @return bool
172
     */
173
    public function getIsReadable()
174
    {
175
        $method = 'checkActionPermission';
176
        if (is_callable([$this->resource, $method])) {
177
            return call_user_func_array([$this->resource, $method], ['read']);
178
        }
179
180
        return false;
181
    }
182
183
    /**
184
     * @return bool
185
     */
186
    public function getIsWritable()
187
    {
188
        $method = 'checkActionPermission';
189
        if (is_callable([$this->resource, $method])) {
190
            return call_user_func_array([$this->resource, $method], ['write']);
191
        }
192
193
        return false;
194
    }
195
196
    /**
197
     * @return bool
198
     */
199
    public function getIsReplaceable()
200
    {
201
        $method = 'checkActionPermission';
202
        if (is_callable([$this->resource, $method])) {
203
            return call_user_func_array([$this->resource, $method], ['replace']);
204
        }
205
206
        return false;
207
    }
208
209
    /**
210
     * @return bool
211
     */
212
    public function getIsRenamable()
213
    {
214
        $method = 'checkActionPermission';
215
        if (is_callable([$this->resource, $method])) {
216
            return call_user_func_array([$this->resource, $method], ['rename']);
217
        }
218
219
        return false;
220
    }
221
222
    /**
223
     * @return bool
224
     */
225
    public function isCopyable()
226
    {
227
        $method = 'checkActionPermission';
228
        if (is_callable([$this->resource, $method])) {
229
            return call_user_func_array([$this->resource, $method], ['copy']);
230
        }
231
232
        return false;
233
    }
234
235
    /**
236
     * @return bool
237
     */
238
    public function isCuttable()
239
    {
240
        $method = 'checkActionPermission';
241
        if (is_callable([$this->resource, $method])) {
242
            return call_user_func_array([$this->resource, $method], ['move']);
243
        }
244
245
        return false;
246
    }
247
248
    /**
249
     * @return bool
250
     */
251
    public function getIsDeletable()
252
    {
253
        $method = 'checkActionPermission';
254
        if (is_callable([$this->resource, $method])) {
255
            return call_user_func_array([$this->resource, $method], ['delete']);
256
        }
257
258
        return false;
259
    }
260
261
    /**
262
     * @return bool
263
     */
264
    public function isSelected()
265
    {
266
        $fullIdentifier = $this->getIdentifier();
267
        $md5 = GeneralUtility::shortMD5($fullIdentifier);
268
269
        /** @var Clipboard $clipboard */
270
        $clipboard = GeneralUtility::makeInstance(Clipboard::class);
271
        $clipboard->initializeClipboard();
272
273
        $isSel = $clipboard->isSelected('_FILE', $md5);
0 ignored issues
show
Bug introduced by
$md5 of type string is incompatible with the type integer expected by parameter $uid of TYPO3\CMS\Backend\Clipbo...Clipboard::isSelected(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

273
        $isSel = $clipboard->isSelected('_FILE', /** @scrutinizer ignore-type */ $md5);
Loading history...
274
275
        if ($isSel) {
276
            return $isSel;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $isSel returns the type string which is incompatible with the documented return type boolean.
Loading history...
277
        }
278
279
        return false;
280
    }
281
282
    /**
283
     * @return bool
284
     */
285
    public function getIsImage()
286
    {
287
        return $this->resource instanceof AbstractFile && $this->resource->isImage();
288
    }
289
290
    /**
291
     * Fetch, cache and return the number of references of a file
292
     *
293
     * @return int
294
     */
295
    public function getReferenceCount(): int
296
    {
297
        $uid = (int)$this->resource->getProperty('uid');
298
299
        if ($uid <= 0) {
300
            return 0;
301
        }
302
303
        if (!isset(static::$referenceCounts[$uid])) {
304
            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex');
305
            $count = $queryBuilder->count('*')
306
                ->from('sys_refindex')
307
                ->where(
308
                    $queryBuilder->expr()->eq('deleted', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)),
309
                    $queryBuilder->expr()->eq(
310
                        'ref_table',
311
                        $queryBuilder->createNamedParameter('sys_file', \PDO::PARAM_STR)
312
                    ),
313
                    $queryBuilder->expr()->eq(
314
                        'ref_uid',
315
                        $queryBuilder->createNamedParameter($this->resource->getProperty('uid'), \PDO::PARAM_INT)
316
                    ),
317
                    $queryBuilder->expr()->neq(
318
                        'tablename',
319
                        $queryBuilder->createNamedParameter('sys_file_metadata', \PDO::PARAM_STR)
320
                    )
321
                )
322
                ->execute()
323
                ->fetchColumn();
324
325
            static::$referenceCounts[$uid] = $count;
326
        }
327
328
        return static::$referenceCounts[$uid];
329
    }
330
331
    /**
332
     * @param string $method
333
     * @param array $arguments
334
     *
335
     * @return mixed
336
     */
337
    public function __call($method, $arguments)
338
    {
339
        if (is_callable([$this->resource, $method])) {
340
            return call_user_func_array([$this->resource, $method], $arguments);
341
        }
342
343
        return null;
344
    }
345
346
    /**
347
     * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
348
     */
349
    protected function getBackendUser(): BackendUserAuthentication
350
    {
351
        return $GLOBALS['BE_USER'];
352
    }
353
354
    /**
355
     * @return \TYPO3\CMS\Core\Localization\LanguageService
356
     */
357
    protected function getLanguageService(): LanguageService
358
    {
359
        return $GLOBALS['LANG'];
360
    }
361
}
362