Passed
Push — master ( f7af3b...d79566 )
by Angel Fernando Quiroz
16:52 queued 14s
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 Symfony\Component\DependencyInjection\ContainerInterface;
28
use Symfony\Component\Filesystem\Filesystem;
29
use Symfony\Component\HttpFoundation\File\UploadedFile;
30
31
abstract class AbstractMigrationChamilo extends AbstractMigration
32
{
33
    public const BATCH_SIZE = 20;
34
35
    protected ?EntityManagerInterface $entityManager = null;
36
    protected ?ContainerInterface $container = null;
37
38
    public function setEntityManager(EntityManagerInterface $entityManager): void
39
    {
40
        $this->entityManager = $entityManager;
41
    }
42
43
    public function setContainer(?ContainerInterface $container = null): void
44
    {
45
        $this->container = $container;
46
    }
47
48
    public function adminExist(): bool
49
    {
50
        $sql = 'SELECT user_id FROM admin WHERE user_id IN (SELECT id FROM user) ORDER BY id LIMIT 1';
51
        $result = $this->connection->executeQuery($sql);
52
        $adminRow = $result->fetchAssociative();
53
54
        if (empty($adminRow)) {
55
            return false;
56
        }
57
58
        return true;
59
    }
60
61
    public function getAdmin(): User
62
    {
63
        $admin = $this->entityManager
64
            ->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

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

243
        /** @scrutinizer ignore-call */ 
244
        $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...
244
        $groupRepo = $this->container->get(CGroupRepository::class);
245
        $userRepo = $this->container->get(UserRepository::class);
246
247
        $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

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

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