Passed
Pull Request — master (#5640)
by
unknown
07:05
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\Migrations\AbstractMigration;
26
use Doctrine\ORM\EntityManagerInterface;
27
use Psr\Log\LoggerInterface;
28
use Symfony\Component\DependencyInjection\ContainerInterface;
29
use Symfony\Component\Filesystem\Filesystem;
30
use Symfony\Component\HttpFoundation\File\UploadedFile;
31
32
abstract class AbstractMigrationChamilo extends AbstractMigration
33
{
34
    public const BATCH_SIZE = 20;
35
36
    protected ?EntityManagerInterface $entityManager = null;
37
    protected ?ContainerInterface $container = null;
38
39
    private LoggerInterface $logger;
40
41
    public function __construct($connection, LoggerInterface $logger)
42
    {
43
        parent::__construct($connection, $logger);
44
        $this->logger = $logger;
45
    }
46
47
    protected function getLogger(): LoggerInterface
48
    {
49
        return $this->logger;
50
    }
51
52
    public function setEntityManager(EntityManagerInterface $entityManager): void
53
    {
54
        $this->entityManager = $entityManager;
55
    }
56
57
    public function setContainer(?ContainerInterface $container = null): void
58
    {
59
        $this->container = $container;
60
    }
61
62
    public function adminExist(): bool
63
    {
64
        $sql = 'SELECT user_id FROM admin WHERE user_id IN (SELECT id FROM user) ORDER BY id LIMIT 1';
65
        $result = $this->connection->executeQuery($sql);
66
        $adminRow = $result->fetchAssociative();
67
68
        if (empty($adminRow)) {
69
            return false;
70
        }
71
72
        return true;
73
    }
74
75
    public function getAdmin(): User
76
    {
77
        $admin = $this->entityManager
78
            ->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

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

257
        /** @scrutinizer ignore-call */ 
258
        $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...
258
        $groupRepo = $this->container->get(CGroupRepository::class);
259
        $userRepo = $this->container->get(UserRepository::class);
260
261
        $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

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

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