Passed
Push — dependabot/npm_and_yarn/nanoid... ( aaf2c9...c4aa90 )
by
unknown
14:37 queued 06:22
created

AbstractMigrationChamilo::addSettingCurrent()   A

Complexity

Conditions 5
Paths 2

Size

Total Lines 56
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 30
c 0
b 0
f 0
nc 2
nop 13
dl 0
loc 56
rs 9.1288

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Migrations;
8
9
use Chamilo\CoreBundle\Entity\AbstractResource;
10
use Chamilo\CoreBundle\Entity\AccessUrl;
11
use Chamilo\CoreBundle\Entity\Admin;
12
use Chamilo\CoreBundle\Entity\Course;
13
use Chamilo\CoreBundle\Entity\ResourceInterface;
14
use Chamilo\CoreBundle\Entity\ResourceLink;
15
use Chamilo\CoreBundle\Entity\ResourceType;
16
use Chamilo\CoreBundle\Entity\Session;
17
use Chamilo\CoreBundle\Entity\SettingsCurrent;
18
use Chamilo\CoreBundle\Entity\SettingsOptions;
19
use Chamilo\CoreBundle\Entity\User;
20
use Chamilo\CoreBundle\Repository\Node\UserRepository;
21
use Chamilo\CoreBundle\Repository\ResourceRepository;
22
use Chamilo\CoreBundle\Repository\SessionRepository;
23
use Chamilo\CourseBundle\Repository\CGroupRepository;
24
use DateTime;
25
use DateTimeZone;
26
use Doctrine\DBAL\Connection;
27
use Doctrine\Migrations\AbstractMigration;
28
use Doctrine\ORM\EntityManagerInterface;
29
use Psr\Log\LoggerInterface;
30
use Symfony\Component\DependencyInjection\ContainerInterface;
31
use Symfony\Component\Filesystem\Filesystem;
32
use Symfony\Component\HttpFoundation\File\UploadedFile;
33
34
abstract class AbstractMigrationChamilo extends AbstractMigration
35
{
36
    public const BATCH_SIZE = 20;
37
38
    protected ?EntityManagerInterface $entityManager = null;
39
    protected ?ContainerInterface $container = null;
40
41
    private LoggerInterface $logger;
42
43
    public function __construct(Connection $connection, LoggerInterface $logger)
44
    {
45
        parent::__construct($connection, $logger);
46
        $this->logger = $logger;
47
    }
48
49
    protected function getLogger(): LoggerInterface
50
    {
51
        return $this->logger;
52
    }
53
54
    public function setEntityManager(EntityManagerInterface $entityManager): void
55
    {
56
        $this->entityManager = $entityManager;
57
    }
58
59
    public function setContainer(?ContainerInterface $container = null): void
60
    {
61
        $this->container = $container;
62
    }
63
64
    public function adminExist(): bool
65
    {
66
        $sql = 'SELECT user_id FROM admin WHERE user_id IN (SELECT id FROM user) ORDER BY id LIMIT 1';
67
        $result = $this->connection->executeQuery($sql);
68
        $adminRow = $result->fetchAssociative();
69
70
        if (empty($adminRow)) {
71
            return false;
72
        }
73
74
        return true;
75
    }
76
77
    public function getAdmin(): User
78
    {
79
        $admin = $this->entityManager
80
            ->getRepository(Admin::class)
0 ignored issues
show
Bug introduced by
The method getRepository() does not exist on null. ( Ignorable by Annotation )

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

80
            ->/** @scrutinizer ignore-call */ getRepository(Admin::class)

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
81
            ->findOneBy([], ['id' => 'ASC'])
82
        ;
83
84
        return $admin->getUser();
85
    }
86
87
    /**
88
     * Speeds up SettingsCurrent creation.
89
     *
90
     * @param string $variable            The variable itself
91
     * @param string $subKey              The subkey
92
     * @param string $type                The type of setting (text, radio, select, etc)
93
     * @param string $category            The category (Platform, User, etc)
94
     * @param string $selectedValue       The default value
95
     * @param string $title               The setting title string name
96
     * @param string $comment             The setting comment string name
97
     * @param string $scope               The scope
98
     * @param string $subKeyText          Text if there is a subKey
99
     * @param int    $accessUrl           What URL it is for
100
     * @param bool   $accessUrlChangeable Whether it can be changed on each url
101
     * @param bool   $accessUrlLocked     Whether the setting for the current URL is
102
     *                                    locked to the current value
103
     * @param array  $options             Optional array in case of a radio-type field,
104
     *                                    to insert options
105
     */
106
    public function addSettingCurrent(
107
        $variable,
108
        $subKey,
109
        $type,
110
        $category,
111
        $selectedValue,
112
        $title,
113
        $comment,
114
        $scope = '',
115
        $subKeyText = '',
116
        $accessUrl = 1,
117
        $accessUrlChangeable = false,
118
        $accessUrlLocked = true,
119
        $options = []
120
    ): void {
121
        $accessUrl = $this->entityManager->find(AccessUrl::class, $accessUrl);
122
123
        $setting = new SettingsCurrent();
124
        $setting
125
            ->setVariable($variable)
126
            ->setSubkey($subKey)
127
            ->setType($type)
128
            ->setCategory($category)
129
            ->setSelectedValue($selectedValue)
130
            ->setTitle($title)
131
            ->setComment($comment)
132
            ->setScope($scope)
133
            ->setSubkeytext($subKeyText)
134
            ->setUrl($accessUrl)
135
            ->setAccessUrlChangeable((int) $accessUrlChangeable)
136
            ->setAccessUrlLocked((int) $accessUrlLocked)
137
        ;
138
139
        $this->entityManager->persist($setting);
140
141
        if (\count($options) > 0) {
142
            foreach ($options as $option) {
143
                if (empty($option['text'])) {
144
                    if ('true' === $option['value']) {
145
                        $option['text'] = 'Yes';
146
                    } else {
147
                        $option['text'] = 'No';
148
                    }
149
                }
150
151
                $settingOption = new SettingsOptions();
152
                $settingOption
153
                    ->setVariable($variable)
154
                    ->setValue($option['value'])
155
                    ->setDisplayText($option['text'])
156
                ;
157
158
                $this->entityManager->persist($settingOption);
159
            }
160
        }
161
        $this->entityManager->flush();
162
    }
163
164
    /**
165
     * @param string     $variable
166
     * @param null|mixed $configuration
167
     */
168
    public function getConfigurationValue($variable, $configuration = null)
169
    {
170
        global $_configuration;
171
172
        if (isset($configuration)) {
173
            $_configuration = $configuration;
174
        }
175
176
        if (isset($_configuration[$variable])) {
177
            return $_configuration[$variable];
178
        }
179
180
        return false;
181
    }
182
183
    public function getMailConfigurationValue(string $variable, array $configuration = []): mixed
184
    {
185
        global $platform_email;
186
187
        if ($configuration) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $configuration of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
188
            $platform_email = $configuration;
189
        }
190
191
        if (isset($platform_email[$variable])) {
192
            return $platform_email[$variable];
193
        }
194
195
        return false;
196
    }
197
198
    /**
199
     * Remove a setting completely.
200
     *
201
     * @param string $variable The setting variable name
202
     */
203
    public function removeSettingCurrent($variable): void
204
    {
205
        // to be implemented
206
    }
207
208
    public function addLegacyFileToResource(
209
        string $filePath,
210
        ResourceRepository $repo,
211
        AbstractResource $resource,
212
        $id,
213
        $fileName = '',
214
        $description = ''
215
    ): bool {
216
        $class = $resource::class;
217
        $documentPath = basename($filePath);
218
219
        if (is_dir($filePath) || (!is_dir($filePath) && !file_exists($filePath))) {
220
            $this->warnIf(true, "Cannot migrate {$class} #'.{$id}.' file not found: {$documentPath}");
221
222
            return false;
223
        }
224
225
        $mimeType = mime_content_type($filePath);
226
        if (empty($fileName)) {
227
            $fileName = basename($documentPath);
228
        }
229
        $file = new UploadedFile($filePath, $fileName, $mimeType, null, true);
230
        $repo->addFile($resource, $file);
231
232
        return true;
233
    }
234
235
    public function fixItemProperty(
236
        $tool,
237
        ResourceRepository $repo,
238
        $course,
239
        $admin,
240
        ResourceInterface $resource,
241
        $parentResource,
242
        array $items = [],
243
        ?ResourceType $resourceType = null,
244
    ) {
245
        $courseId = $course->getId();
246
        $id = $resource->getResourceIdentifier();
247
248
        if (empty($items)) {
249
            $sql = "SELECT * FROM c_item_property
250
                    WHERE tool = '{$tool}' AND c_id = {$courseId} AND ref = {$id}";
251
            $result = $this->connection->executeQuery($sql);
252
            $items = $result->fetchAllAssociative();
253
        }
254
255
        // For some reason the resource doesn't have a c_item_property value.
256
        if (empty($items)) {
257
            return false;
258
        }
259
260
        $sessionRepo = $this->container->get(SessionRepository::class);
0 ignored issues
show
Bug introduced by
The method get() does not exist on null. ( Ignorable by Annotation )

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

260
        /** @scrutinizer ignore-call */ 
261
        $sessionRepo = $this->container->get(SessionRepository::class);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
261
        $groupRepo = $this->container->get(CGroupRepository::class);
262
        $userRepo = $this->container->get(UserRepository::class);
263
264
        $resourceType = $resourceType ?: $repo->getResourceType();
265
266
        $resource->setParent($parentResource);
0 ignored issues
show
Bug introduced by
The method setParent() does not exist on Chamilo\CoreBundle\Entity\ResourceInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Chamilo\CoreBundle\Entity\ResourceInterface. ( Ignorable by Annotation )

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

266
        $resource->/** @scrutinizer ignore-call */ 
267
                   setParent($parentResource);
Loading history...
267
        $resourceNode = null;
268
        $userList = [];
269
        $groupList = [];
270
        $sessionList = [];
271
        foreach ($items as $item) {
272
            $visibility = (int) $item['visibility'];
273
            $userId = (int) $item['insert_user_id'];
274
            $sessionId = $item['session_id'] ?? 0;
275
            $groupId = $item['to_group_id'] ?? 0;
276
            if (empty($item['lastedit_date'])) {
277
                $lastUpdatedAt = new DateTime('now', new DateTimeZone('UTC'));
278
            } else {
279
                $lastUpdatedAt = new DateTime($item['lastedit_date'], new DateTimeZone('UTC'));
280
            }
281
            $newVisibility = ResourceLink::VISIBILITY_DRAFT;
282
283
            // Old 1.11.x visibility (item property) is based in this switch:
284
            switch ($visibility) {
285
                case 0:
286
                    $newVisibility = ResourceLink::VISIBILITY_DRAFT;
287
288
                    break;
289
290
                case 1:
291
                    $newVisibility = ResourceLink::VISIBILITY_PUBLISHED;
292
293
                    break;
294
            }
295
296
            // If c_item_property.insert_user_id doesn't exist we use the first admin id.
297
            $user = $admin;
298
299
            if ($userId) {
300
                if (isset($userList[$userId])) {
301
                    $user = $userList[$userId];
302
                } elseif ($userFound = $userRepo->find($userId)) {
303
                    $user = $userList[$userId] = $userFound;
304
                }
305
            }
306
307
            $session = null;
308
            if (!empty($sessionId)) {
309
                if (isset($sessionList[$sessionId])) {
310
                    $session = $sessionList[$sessionId];
311
                } else {
312
                    $session = $sessionList[$sessionId] = $sessionRepo->find($sessionId);
313
                }
314
            }
315
316
            $group = null;
317
            if (!empty($groupId)) {
318
                if (isset($groupList[$groupId])) {
319
                    $group = $groupList[$groupId];
320
                } else {
321
                    $group = $groupList[$groupId] = $groupRepo->find($groupId);
322
                }
323
            }
324
325
            if (null === $resourceNode) {
326
                $resourceNode = $repo->addResourceNode(
327
                    $resource,
328
                    $user,
329
                    $parentResource,
330
                    $resourceType
331
                );
332
                $this->entityManager->persist($resourceNode);
333
            }
334
            $resource->addCourseLink($course, $session, $group, $newVisibility);
0 ignored issues
show
Bug introduced by
The method addCourseLink() does not exist on Chamilo\CoreBundle\Entity\ResourceInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Chamilo\CoreBundle\Entity\User. Are you sure you never get one of those? ( Ignorable by Annotation )

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

334
            $resource->/** @scrutinizer ignore-call */ 
335
                       addCourseLink($course, $session, $group, $newVisibility);
Loading history...
335
336
            if (2 === $visibility) {
337
                $link = $resource->getResourceNode()->getResourceLinkByContext($course, $session, $group);
338
                $link->setDeletedAt($lastUpdatedAt);
339
            }
340
341
            $this->entityManager->persist($resource);
342
        }
343
344
        return true;
345
    }
346
347
    public function fileExists($filePath): bool
348
    {
349
        return file_exists($filePath) && !is_dir($filePath) && is_readable($filePath);
350
    }
351
352
    public function findCourse(int $id): ?Course
353
    {
354
        if (0 === $id) {
355
            return null;
356
        }
357
358
        return $this->entityManager->find(Course::class, $id);
359
    }
360
361
    public function findSession(int $id): ?Session
362
    {
363
        if (0 === $id) {
364
            return null;
365
        }
366
367
        return $this->entityManager->find(Session::class, $id);
368
    }
369
370
    public function getMailConfigurationValueFromFile(string $variable): ?string
371
    {
372
        global $platform_email;
373
374
        $rootPath = $this->container->get('kernel')->getProjectDir();
375
        $oldConfigPath = $this->getUpdateRootPath().'/app/config/mail.conf.php';
376
377
        $configFileLoaded = \in_array($oldConfigPath, get_included_files(), true);
378
379
        if (!$configFileLoaded) {
380
            include_once $oldConfigPath;
381
        }
382
383
        $settingValue = $this->getConfigurationValue($variable, $platform_email);
384
385
        if (\is_bool($settingValue)) {
386
            $selectedValue = var_export($settingValue, true);
387
        } else {
388
            $selectedValue = (string) $settingValue;
389
        }
390
391
        return $selectedValue;
392
    }
393
394
    private function generateFilePath(string $filename): string
395
    {
396
        $cacheDir = $this->container->get('kernel')->getCacheDir();
397
398
        return $cacheDir.'/migration_'.$filename;
399
    }
400
401
    protected function writeFile(string $filename, string $content): void
402
    {
403
        $fullFilename = $this->generateFilePath($filename);
404
405
        $fs = new Filesystem();
406
        $fs->dumpFile($fullFilename, $content);
407
    }
408
409
    protected function readFile(string $filename): string
410
    {
411
        $fullFilename = $this->generateFilePath($filename);
412
413
        if ($this->fileExists($fullFilename)) {
414
            return file_get_contents($fullFilename);
415
        }
416
417
        return '';
418
    }
419
420
    protected function removeFile(string $filename): void
421
    {
422
        $fullFilename = $this->generateFilePath($filename);
423
424
        $fs = new Filesystem();
425
        $fs->remove($fullFilename);
426
    }
427
428
    protected function getUpdateRootPath(): string
429
    {
430
        $updateRootPath = getenv('UPDATE_PATH');
431
432
        if (!empty($updateRootPath)) {
433
            error_log('getUpdateRootPath ::: '.$updateRootPath);
434
435
            return rtrim($updateRootPath, '/');
436
        }
437
438
        return $this->container->getParameter('kernel.project_dir');
439
    }
440
}
441