Completed
Push — master ( f65802...ddb531 )
by
unknown
39:08 queued 15:48
created

FileRepository::searchByName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the TYPO3 CMS project.
5
 *
6
 * It is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License, either version 2
8
 * of the License, or any later version.
9
 *
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 *
13
 * The TYPO3 project - inspiring people to share!
14
 */
15
16
namespace TYPO3\CMS\Core\Resource;
17
18
use TYPO3\CMS\Backend\Utility\BackendUtility;
19
use TYPO3\CMS\Core\Database\ConnectionPool;
20
use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
21
use TYPO3\CMS\Core\Database\RelationHandler;
22
use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
23
use TYPO3\CMS\Core\Utility\GeneralUtility;
24
use TYPO3\CMS\Core\Utility\MathUtility;
25
26
/**
27
 * Repository for accessing files
28
 * it also serves as the public API for the indexing part of files in general
29
 */
30
class FileRepository extends AbstractRepository
31
{
32
    /**
33
     * The main object type of this class. In some cases (fileReference) this
34
     * repository can also return FileReference objects, implementing the
35
     * common FileInterface.
36
     *
37
     * @var string
38
     */
39
    protected $objectType = File::class;
40
41
    /**
42
     * Main File object storage table. Note that this repository also works on
43
     * the sys_file_reference table when returning FileReference objects.
44
     *
45
     * @var string
46
     */
47
    protected $table = 'sys_file';
48
49
    /**
50
     * Creates an object managed by this repository.
51
     *
52
     * @param array $databaseRow
53
     * @return File
54
     */
55
    protected function createDomainObject(array $databaseRow)
56
    {
57
        return $this->factory->getFileObject($databaseRow['uid'], $databaseRow);
58
    }
59
60
    /**
61
     * Find FileReference objects by relation to other records
62
     *
63
     * @param string $tableName Table name of the related record
64
     * @param string $fieldName Field name of the related record
65
     * @param int $uid The UID of the related record (needs to be the localized uid, as translated IRRE elements relate to them)
66
     * @return array An array of objects, empty if no objects found
67
     * @throws \InvalidArgumentException
68
     */
69
    public function findByRelation($tableName, $fieldName, $uid)
70
    {
71
        $itemList = [];
72
        if (!MathUtility::canBeInterpretedAsInteger($uid)) {
73
            throw new \InvalidArgumentException(
74
                'UID of related record has to be an integer. UID given: "' . $uid . '"',
75
                1316789798
76
            );
77
        }
78
        $referenceUids = [];
79
        if ($this->getEnvironmentMode() === 'FE') {
80
            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
81
                ->getQueryBuilderForTable('sys_file_reference');
82
83
            $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
84
            $res = $queryBuilder
85
                ->select('uid')
86
                ->from('sys_file_reference')
87
                ->where(
88
                    $queryBuilder->expr()->eq(
89
                        'uid_foreign',
90
                        $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
91
                    ),
92
                    $queryBuilder->expr()->eq(
93
                        'tablenames',
94
                        $queryBuilder->createNamedParameter($tableName, \PDO::PARAM_STR)
95
                    ),
96
                    $queryBuilder->expr()->eq(
97
                        'fieldname',
98
                        $queryBuilder->createNamedParameter($fieldName, \PDO::PARAM_STR)
99
                    )
100
                )
101
                ->orderBy('sorting_foreign')
102
                ->execute();
103
104
            while ($row = $res->fetch()) {
105
                $referenceUids[] = $row['uid'];
106
            }
107
        } else {
108
            /** @var RelationHandler $relationHandler */
109
            $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
110
            $relationHandler->start(
111
                '',
112
                'sys_file_reference',
113
                '',
114
                $uid,
115
                $tableName,
116
                BackendUtility::getTcaFieldConfiguration($tableName, $fieldName)
117
            );
118
            if (!empty($relationHandler->tableArray['sys_file_reference'])) {
119
                $referenceUids = $relationHandler->tableArray['sys_file_reference'];
120
            }
121
        }
122
        if (!empty($referenceUids)) {
123
            foreach ($referenceUids as $referenceUid) {
124
                try {
125
                    // Just passing the reference uid, the factory is doing workspace
126
                    // overlays automatically depending on the current environment
127
                    $itemList[] = $this->factory->getFileReferenceObject($referenceUid);
128
                } catch (ResourceDoesNotExistException $exception) {
129
                    // No handling, just omit the invalid reference uid
130
                }
131
            }
132
            $itemList = $this->reapplySorting($itemList);
133
        }
134
135
        return $itemList;
136
    }
137
138
    /**
139
     * Find FileReference objects by uid
140
     *
141
     * @param int $uid The UID of the sys_file_reference record
142
     * @return FileReference|bool
143
     * @throws \InvalidArgumentException
144
     */
145
    public function findFileReferenceByUid($uid)
146
    {
147
        if (!MathUtility::canBeInterpretedAsInteger($uid)) {
148
            throw new \InvalidArgumentException('The UID of record has to be an integer. UID given: "' . $uid . '"', 1316889798);
149
        }
150
        try {
151
            $fileReferenceObject = $this->factory->getFileReferenceObject($uid);
152
        } catch (\InvalidArgumentException $exception) {
153
            $fileReferenceObject = false;
154
        }
155
        return $fileReferenceObject;
156
    }
157
158
    /**
159
     * As sorting might have changed due to workspace overlays, PHP does the sorting again.
160
     *
161
     * @param array $itemList
162
     */
163
    protected function reapplySorting(array $itemList): array
164
    {
165
        uasort(
166
            $itemList,
167
            function (FileReference $a, FileReference $b) {
168
                $sortA = (int)$a->getReferenceProperty('sorting_foreign');
169
                $sortB = (int)$b->getReferenceProperty('sorting_foreign');
170
171
                if ($sortA === $sortB) {
172
                    return 0;
173
                }
174
175
                return ($sortA < $sortB) ? -1 : 1;
176
            }
177
        );
178
        return $itemList;
179
    }
180
}
181