Passed
Push — master ( 1162ad...f2c90b )
by Yannick
07:00
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\Session;
16
use Chamilo\CoreBundle\Entity\SettingsCurrent;
17
use Chamilo\CoreBundle\Entity\SettingsOptions;
18
use Chamilo\CoreBundle\Entity\User;
19
use Chamilo\CoreBundle\Repository\Node\UserRepository;
20
use Chamilo\CoreBundle\Repository\ResourceRepository;
21
use Chamilo\CoreBundle\Repository\SessionRepository;
22
use Chamilo\CourseBundle\Repository\CGroupRepository;
23
use DateTime;
24
use DateTimeZone;
25
use Doctrine\DBAL\Connection;
26
use Doctrine\Migrations\AbstractMigration;
27
use Doctrine\ORM\EntityManagerInterface;
28
use Psr\Log\LoggerInterface;
29
use Symfony\Component\DependencyInjection\ContainerInterface;
30
use Symfony\Component\Filesystem\Filesystem;
31
use Symfony\Component\HttpFoundation\File\UploadedFile;
32
33
abstract class AbstractMigrationChamilo extends AbstractMigration
34
{
35
    public const BATCH_SIZE = 20;
36
37
    protected ?EntityManagerInterface $entityManager = null;
38
    protected ?ContainerInterface $container = null;
39
40
    private LoggerInterface $logger;
41
42
    /**
43
     * Constructor
44
     */
45
    public function __construct(Connection $connection, LoggerInterface $logger)
46
    {
47
        parent::__construct($connection, $logger);
48
        $this->logger = $logger;
49
    }
50
51
    protected function getLogger(): LoggerInterface
52
    {
53
        return $this->logger;
54
    }
55
56
    public function setEntityManager(EntityManagerInterface $entityManager): void
57
    {
58
        $this->entityManager = $entityManager;
59
    }
60
61
    public function setContainer(?ContainerInterface $container = null): void
62
    {
63
        $this->container = $container;
64
    }
65
66
    public function adminExist(): bool
67
    {
68
        $sql = 'SELECT user_id FROM admin WHERE user_id IN (SELECT id FROM user) ORDER BY id LIMIT 1';
69
        $result = $this->connection->executeQuery($sql);
70
        $adminRow = $result->fetchAssociative();
71
72
        if (empty($adminRow)) {
73
            return false;
74
        }
75
76
        return true;
77
    }
78
79
    public function getAdmin(): User
80
    {
81
        $admin = $this->entityManager
82
            ->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

82
            ->/** @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...
83
            ->findOneBy([], ['id' => 'ASC'])
84
        ;
85
86
        return $admin->getUser();
87
    }
88
89
    /**
90
     * Speeds up SettingsCurrent creation.
91
     *
92
     * @param string $variable            The variable itself
93
     * @param string $subKey              The subkey
94
     * @param string $type                The type of setting (text, radio, select, etc)
95
     * @param string $category            The category (Platform, User, etc)
96
     * @param string $selectedValue       The default value
97
     * @param string $title               The setting title string name
98
     * @param string $comment             The setting comment string name
99
     * @param string $scope               The scope
100
     * @param string $subKeyText          Text if there is a subKey
101
     * @param int    $accessUrl           What URL it is for
102
     * @param bool   $accessUrlChangeable Whether it can be changed on each url
103
     * @param bool   $accessUrlLocked     Whether the setting for the current URL is
104
     *                                    locked to the current value
105
     * @param array  $options             Optional array in case of a radio-type field,
106
     *                                    to insert options
107
     */
108
    public function addSettingCurrent(
109
        $variable,
110
        $subKey,
111
        $type,
112
        $category,
113
        $selectedValue,
114
        $title,
115
        $comment,
116
        $scope = '',
117
        $subKeyText = '',
118
        $accessUrl = 1,
119
        $accessUrlChangeable = false,
120
        $accessUrlLocked = true,
121
        $options = []
122
    ): void {
123
        $accessUrl = $this->entityManager->find(AccessUrl::class, $accessUrl);
124
125
        $setting = new SettingsCurrent();
126
        $setting
127
            ->setVariable($variable)
128
            ->setSubkey($subKey)
129
            ->setType($type)
130
            ->setCategory($category)
131
            ->setSelectedValue($selectedValue)
132
            ->setTitle($title)
133
            ->setComment($comment)
134
            ->setScope($scope)
135
            ->setSubkeytext($subKeyText)
136
            ->setUrl($accessUrl)
137
            ->setAccessUrlChangeable((int) $accessUrlChangeable)
138
            ->setAccessUrlLocked((int) $accessUrlLocked)
139
        ;
140
141
        $this->entityManager->persist($setting);
142
143
        if (\count($options) > 0) {
144
            foreach ($options as $option) {
145
                if (empty($option['text'])) {
146
                    if ('true' === $option['value']) {
147
                        $option['text'] = 'Yes';
148
                    } else {
149
                        $option['text'] = 'No';
150
                    }
151
                }
152
153
                $settingOption = new SettingsOptions();
154
                $settingOption
155
                    ->setVariable($variable)
156
                    ->setValue($option['value'])
157
                    ->setDisplayText($option['text'])
158
                ;
159
160
                $this->entityManager->persist($settingOption);
161
            }
162
        }
163
        $this->entityManager->flush();
164
    }
165
166
    /**
167
     * @param string     $variable
168
     * @param null|mixed $configuration
169
     */
170
    public function getConfigurationValue($variable, $configuration = null)
171
    {
172
        global $_configuration;
173
174
        if (isset($configuration)) {
175
            $_configuration = $configuration;
176
        }
177
178
        if (isset($_configuration[$variable])) {
179
            return $_configuration[$variable];
180
        }
181
182
        return false;
183
    }
184
185
    public function getMailConfigurationValue(string $variable, array $configuration = []): mixed
186
    {
187
        global $platform_email;
188
189
        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...
190
            $platform_email = $configuration;
191
        }
192
193
        if (isset($platform_email[$variable])) {
194
            return $platform_email[$variable];
195
        }
196
197
        return false;
198
    }
199
200
    /**
201
     * Remove a setting completely.
202
     *
203
     * @param string $variable The setting variable name
204
     */
205
    public function removeSettingCurrent($variable): void
206
    {
207
        // to be implemented
208
    }
209
210
    public function addLegacyFileToResource(
211
        string $filePath,
212
        ResourceRepository $repo,
213
        AbstractResource $resource,
214
        $id,
215
        $fileName = '',
216
        $description = ''
217
    ): bool {
218
        $class = $resource::class;
219
        $documentPath = basename($filePath);
220
221
        if (is_dir($filePath) || (!is_dir($filePath) && !file_exists($filePath))) {
222
            $this->warnIf(true, "Cannot migrate {$class} #'.{$id}.' file not found: {$documentPath}");
223
224
            return false;
225
        }
226
227
        $mimeType = mime_content_type($filePath);
228
        if (empty($fileName)) {
229
            $fileName = basename($documentPath);
230
        }
231
        $file = new UploadedFile($filePath, $fileName, $mimeType, null, true);
232
        $repo->addFile($resource, $file);
233
234
        return true;
235
    }
236
237
    public function fixItemProperty(
238
        $tool,
239
        ResourceRepository $repo,
240
        $course,
241
        $admin,
242
        ResourceInterface $resource,
243
        $parentResource,
244
        array $items = []
245
    ) {
246
        $courseId = $course->getId();
247
        $id = $resource->getResourceIdentifier();
248
249
        if (empty($items)) {
250
            $sql = "SELECT * FROM c_item_property
251
                    WHERE tool = '{$tool}' AND c_id = {$courseId} AND ref = {$id}";
252
            $result = $this->connection->executeQuery($sql);
253
            $items = $result->fetchAllAssociative();
254
        }
255
256
        // For some reason the resource doesn't have a c_item_property value.
257
        if (empty($items)) {
258
            return false;
259
        }
260
261
        $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

261
        /** @scrutinizer ignore-call */ 
262
        $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...
262
        $groupRepo = $this->container->get(CGroupRepository::class);
263
        $userRepo = $this->container->get(UserRepository::class);
264
265
        $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

265
        $resource->/** @scrutinizer ignore-call */ 
266
                   setParent($parentResource);
Loading history...
266
        $resourceNode = null;
267
        $userList = [];
268
        $groupList = [];
269
        $sessionList = [];
270
        foreach ($items as $item) {
271
            $visibility = (int) $item['visibility'];
272
            $userId = (int) $item['insert_user_id'];
273
            $sessionId = $item['session_id'] ?? 0;
274
            $groupId = $item['to_group_id'] ?? 0;
275
            if (empty($item['lastedit_date'])) {
276
                $lastUpdatedAt = new DateTime('now', new DateTimeZone('UTC'));
277
            } else {
278
                $lastUpdatedAt = new DateTime($item['lastedit_date'], new DateTimeZone('UTC'));
279
            }
280
            $newVisibility = ResourceLink::VISIBILITY_DRAFT;
281
282
            // Old 1.11.x visibility (item property) is based in this switch:
283
            switch ($visibility) {
284
                case 0:
285
                    $newVisibility = ResourceLink::VISIBILITY_DRAFT;
286
287
                    break;
288
289
                case 1:
290
                    $newVisibility = ResourceLink::VISIBILITY_PUBLISHED;
291
292
                    break;
293
            }
294
295
            // If c_item_property.insert_user_id doesn't exist we use the first admin id.
296
            $user = null;
297
            if (isset($userList[$userId])) {
298
                $user = $userList[$userId];
299
            } else {
300
                if (!empty($userId)) {
301
                    $userFound = $userRepo->find($userId);
302
                    if ($userFound) {
303
                        $user = $userList[$userId] = $userRepo->find($userId);
304
                    }
305
                }
306
            }
307
308
            if (null === $user) {
309
                $user = $admin;
310
            }
311
312
            $session = null;
313
            if (!empty($sessionId)) {
314
                if (isset($sessionList[$sessionId])) {
315
                    $session = $sessionList[$sessionId];
316
                } else {
317
                    $session = $sessionList[$sessionId] = $sessionRepo->find($sessionId);
318
                }
319
            }
320
321
            $group = null;
322
            if (!empty($groupId)) {
323
                if (isset($groupList[$groupId])) {
324
                    $group = $groupList[$groupId];
325
                } else {
326
                    $group = $groupList[$groupId] = $groupRepo->find($groupId);
327
                }
328
            }
329
330
            if (null === $resourceNode) {
331
                $resourceNode = $repo->addResourceNode($resource, $user, $parentResource);
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 = $rootPath.'/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
        return file_get_contents($fullFilename);
414
    }
415
416
    protected function removeFile(string $filename): void
417
    {
418
        $fullFilename = $this->generateFilePath($filename);
419
420
        $fs = new Filesystem();
421
        $fs->remove($fullFilename);
422
    }
423
}
424