Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — dev-extbase-fluid ( ca9337...5837d7 )
by Alexander
03:40 queued 03:35
created

FileLocationUpdater::executeUpdate()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 13
rs 10
1
<?php
2
3
/**
4
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
5
 *
6
 * This file is part of the Kitodo and TYPO3 projects.
7
 *
8
 * @license GNU General Public License version 3 or later.
9
 * For the full copyright and license information, please read the
10
 * LICENSE.txt file that was distributed with this source code.
11
 */
12
13
namespace Kitodo\Dlf\Updates;
14
15
use TYPO3\CMS\Core\Utility\GeneralUtility;
16
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Install\Update...baseUpdatedPrerequisite was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Install\Updates\UpgradeWizardInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use TYPO3\CMS\Install\Updates\ChattyInterface;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Install\Updates\ChattyInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
20
use Doctrine\DBAL\DBALException;
21
use Psr\Log\LoggerAwareInterface;
22
use Psr\Log\LoggerAwareTrait;
23
use Symfony\Component\Console\Output\OutputInterface;
24
use TYPO3\CMS\Core\Core\Environment;
25
use TYPO3\CMS\Core\Database\ConnectionPool;
26
use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
27
use TYPO3\CMS\Core\Resource\File;
28
use TYPO3\CMS\Core\Resource\ResourceStorage;
29
use TYPO3\CMS\Core\Resource\StorageRepository;
30
31
/**
32
 * Migrate reference of thumbnail image in collections record.
33
 */
34
class FileLocationUpdater implements UpgradeWizardInterface, ChattyInterface, LoggerAwareInterface
35
{
36
    use LoggerAwareTrait;
37
38
    /**
39
     * @var OutputInterface
40
     */
41
    protected $output;
42
43
    /**
44
     * @var ResourceStorage
45
     */
46
    protected $storage;
47
48
    /**
49
     * @var Logger
0 ignored issues
show
Bug introduced by
The type Kitodo\Dlf\Updates\Logger was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
50
     */
51
    protected $logger;
52
53
    /**
54
     * Array with table and fields to migrate
55
     *
56
     * @var string
57
     */
58
    protected $fieldsToMigrate = [
59
        'tx_dlf_collections' => 'thumbnail'
60
    ];
61
62
    /**
63
     * @return string Unique identifier of this updater
64
     */
65
    public function getIdentifier(): string
66
    {
67
        return self::class;
68
    }
69
70
    /**
71
     * Return the speaking name of this wizard
72
     *
73
     * @return string
74
     */
75
    public function getTitle(): string
76
    {
77
        return 'Migrate file references used in EXT:dlf';
78
    }
79
80
    /**
81
     * Get description
82
     *
83
     * @return string Longer description of this updater
84
     */
85
    public function getDescription(): string
86
    {
87
        return 'Convert file reference of thumbnail images in collection records.';
88
    }
89
90
    /**
91
     * Is an update necessary?
92
     *
93
     * Is used to determine whether a wizard needs to be run.
94
     * Check if data for migration exists.
95
     *
96
     * @return bool
97
     */
98
    public function updateNecessary(): bool
99
    {
100
        $numRecords = $this->getRecordsFromTable(true);
101
        if ($numRecords > 0) {
102
            return true;
103
        }
104
        return false;
105
    }
106
107
    /**
108
     * @return string[] All new fields and tables must exist
109
     */
110
    public function getPrerequisites(): array
111
    {
112
        return [
113
            DatabaseUpdatedPrerequisite::class
114
        ];
115
    }
116
117
    /**
118
     * @param OutputInterface $output
119
     */
120
    public function setOutput(OutputInterface $output): void
121
    {
122
        $this->output = $output;
123
    }
124
125
    /**
126
     * Execute the update
127
     *
128
     * Called when a wizard reports that an update is necessary
129
     *
130
     * @return bool
131
     */
132
    public function executeUpdate(): bool
133
    {
134
        $result = true;
135
        try {
136
            $numRecords = $this->getRecordsFromTable(true);
137
            if ($numRecords > 0) {
138
                $this->performUpdate();
139
            }
140
        } catch (\Exception $e) {
141
            // If something goes wrong, migrateField() logs an error
142
            $result = false;
143
        }
144
        return $result;
145
    }
146
147
    /**
148
     * Get records from table where the field to migrate is not empty (NOT NULL and != '')
149
     * and also not numeric (which means that it is migrated)
150
     *
151
     * Work based on BackendLayoutIconUpdateWizard::class
152
     *
153
     * @return array|int
154
     * @throws \RuntimeException
155
     */
156
    protected function getRecordsFromTable($countOnly = false)
157
    {
158
        $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
159
        $allResults = [];
160
        $numResults = 0;
161
        foreach(array_keys($this->fieldsToMigrate) as $table) {
0 ignored issues
show
Bug introduced by
$this->fieldsToMigrate of type string is incompatible with the type array expected by parameter $array of array_keys(). ( Ignorable by Annotation )

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

161
        foreach(array_keys(/** @scrutinizer ignore-type */ $this->fieldsToMigrate) as $table) {
Loading history...
162
            $queryBuilder = $connectionPool->getQueryBuilderForTable($table);
163
            $queryBuilder->getRestrictions()->removeAll();
164
            try {
165
                $result = $queryBuilder
166
                    ->select('uid', 'pid', $this->fieldsToMigrate[$table])
167
                    ->from($table)
168
                    ->where(
169
                        $queryBuilder->expr()->isNotNull($this->fieldsToMigrate[$table]),
170
                        $queryBuilder->expr()->neq(
171
                            $this->fieldsToMigrate[$table],
172
                            $queryBuilder->createNamedParameter('', \PDO::PARAM_STR)
173
                        ),
174
                        $queryBuilder->expr()->comparison(
175
                            'CAST(CAST(' . $queryBuilder->quoteIdentifier($this->fieldsToMigrate[$table]) . ' AS DECIMAL) AS CHAR)',
176
                            ExpressionBuilder::NEQ,
177
                            'CAST(' . $queryBuilder->quoteIdentifier($this->fieldsToMigrate[$table]) . ' AS CHAR)'
178
                        )
179
                    )
180
                    ->orderBy('uid')
181
                    ->execute()
182
                    ->fetchAll();
183
                if ($countOnly === true) {
184
                    $numResults += count($result);
185
                } else {
186
                    $allResults[$table] = $result;
187
                }
188
            } catch (DBALException $e) {
189
                throw new \RuntimeException(
190
                    'Database query failed. Error was: ' . $e->getPrevious()->getMessage(),
191
                    1511950673
192
                );
193
            }
194
        }
195
196
        if ($countOnly === true) {
197
            return $numResults;
198
        } else {
199
            return $allResults;
200
        }
201
    }
202
203
204
    /**
205
     * Performs the database update.
206
     *
207
     * @return bool TRUE on success, FALSE on error
208
     */
209
    protected function performUpdate(): bool
210
    {
211
        $result = true;
212
213
        try {
214
            $storages = GeneralUtility::makeInstance(StorageRepository::class)->findAll();
215
            $this->storage = $storages[0];
216
217
            $records = $this->getRecordsFromTable();
218
            foreach ($records as $table => $recordsInTable) {
219
                foreach ($recordsInTable as $record) {
220
                    $this->migrateField($table, $record);
221
                }
222
            }
223
        } catch (\Exception $e) {
224
            $result = false;
225
        }
226
227
        return $result;
228
    }
229
230
    /**
231
     * Migrates a single field.
232
     *
233
     * @param string $table
234
     * @param array $row
235
     * @throws \Exception
236
     */
237
    protected function migrateField($table, $row)
238
    {
239
        $fieldItem = trim($row[$this->fieldsToMigrate[$table]]);
240
241
        if (empty($fieldItem) || is_numeric($fieldItem)) {
242
            return;
243
        }
244
245
        $storageUid = (int)$this->storage->getUid();
246
        $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
247
248
        $fileUid = null;
249
        $sourcePath = Environment::getPublicPath() . '/'  . $fieldItem;
250
251
        // maybe the file was already moved, so check if the original file still exists
252
        if (file_exists($sourcePath)) {
253
254
            // see if the file already exists in the storage
255
            $fileSha1 = sha1_file($sourcePath);
256
257
            $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_file');
258
            $existingFileRecord = $queryBuilder->select('uid')->from('sys_file')->where(
259
                $queryBuilder->expr()->eq(
260
                    'missing',
261
                    $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
262
                ),
263
                $queryBuilder->expr()->eq(
264
                    'sha1',
265
                    $queryBuilder->createNamedParameter($fileSha1, \PDO::PARAM_STR)
266
                ),
267
                $queryBuilder->expr()->eq(
268
                    'storage',
269
                    $queryBuilder->createNamedParameter($storageUid, \PDO::PARAM_INT)
270
                )
271
            )->execute()->fetch();
272
273
            // the file exists
274
            if (is_array($existingFileRecord)) {
275
                $fileUid = $existingFileRecord['uid'];
276
            }
277
        }
278
279
        if ($fileUid > 0) {
280
            $fields = [
281
                'fieldname' => $this->fieldsToMigrate[$table],
282
                'table_local' => 'sys_file',
283
                'pid' => ($table === 'pages' ? $row['uid'] : $row['pid']),
284
                'uid_foreign' => $row['uid'],
285
                'uid_local' => $fileUid,
286
                'tablenames' => $table,
287
                'crdate' => time(),
288
                'tstamp' => time(),
289
            ];
290
291
            $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_file_reference');
292
293
            $result = $queryBuilder
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
294
                ->insert('sys_file_reference')
295
                ->values($fields)
296
                ->execute();
297
298
            $queryBuilder = $connectionPool->getQueryBuilderForTable($table);
299
            $queryBuilder->update($table)->where(
300
                $queryBuilder->expr()->eq(
301
                    'uid',
302
                    $queryBuilder->createNamedParameter($row['uid'], \PDO::PARAM_INT)
303
                )
304
            )->set($this->fieldsToMigrate[$table])->execute();
305
        }
306
    }
307
}
308