Passed
Push — master ( b349f1...7e5caa )
by Angel Fernando Quiroz
09:34
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\Finder\Finder;
33
use Symfony\Component\HttpFoundation\File\UploadedFile;
34
35
abstract class AbstractMigrationChamilo extends AbstractMigration
36
{
37
    public const BATCH_SIZE = 20;
38
39
    protected ?EntityManagerInterface $entityManager = null;
40
    protected ?ContainerInterface $container = null;
41
42
    private LoggerInterface $logger;
43
44
    public function __construct(Connection $connection, LoggerInterface $logger)
45
    {
46
        parent::__construct($connection, $logger);
47
        $this->logger = $logger;
48
    }
49
50
    protected function getLogger(): LoggerInterface
51
    {
52
        return $this->logger;
53
    }
54
55
    public function setEntityManager(EntityManagerInterface $entityManager): void
56
    {
57
        $this->entityManager = $entityManager;
58
    }
59
60
    public function setContainer(?ContainerInterface $container = null): void
61
    {
62
        $this->container = $container;
63
    }
64
65
    public function adminExist(): bool
66
    {
67
        $sql = 'SELECT user_id FROM admin WHERE user_id IN (SELECT id FROM user) ORDER BY id LIMIT 1';
68
        $result = $this->connection->executeQuery($sql);
69
        $adminRow = $result->fetchAssociative();
70
71
        if (empty($adminRow)) {
72
            return false;
73
        }
74
75
        return true;
76
    }
77
78
    public function getAdmin(): User
79
    {
80
        $admin = $this->entityManager
81
            ->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

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

267
        $resource->/** @scrutinizer ignore-call */ 
268
                   setParent($parentResource);
Loading history...
268
        $resourceNode = null;
269
        $userList = [];
270
        $groupList = [];
271
        $sessionList = [];
272
        foreach ($items as $item) {
273
            $visibility = (int) $item['visibility'];
274
            $userId = (int) $item['insert_user_id'];
275
            $sessionId = $item['session_id'] ?? 0;
276
            $groupId = $item['to_group_id'] ?? 0;
277
            if (empty($item['lastedit_date'])) {
278
                $lastUpdatedAt = new DateTime('now', new DateTimeZone('UTC'));
279
            } else {
280
                $lastUpdatedAt = new DateTime($item['lastedit_date'], new DateTimeZone('UTC'));
281
            }
282
            $newVisibility = ResourceLink::VISIBILITY_DRAFT;
283
284
            // Old 1.11.x visibility (item property) is based in this switch:
285
            switch ($visibility) {
286
                case 0:
287
                    $newVisibility = ResourceLink::VISIBILITY_DRAFT;
288
289
                    break;
290
291
                case 1:
292
                    $newVisibility = ResourceLink::VISIBILITY_PUBLISHED;
293
294
                    break;
295
            }
296
297
            // If c_item_property.insert_user_id doesn't exist we use the first admin id.
298
            $user = $admin;
299
300
            if ($userId) {
301
                if (isset($userList[$userId])) {
302
                    $user = $userList[$userId];
303
                } elseif ($userFound = $userRepo->find($userId)) {
304
                    $user = $userList[$userId] = $userFound;
305
                }
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(
328
                    $resource,
329
                    $user,
330
                    $parentResource,
331
                    $resourceType
332
                );
333
                $this->entityManager->persist($resourceNode);
334
            }
335
            $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

335
            $resource->/** @scrutinizer ignore-call */ 
336
                       addCourseLink($course, $session, $group, $newVisibility);
Loading history...
336
337
            if (2 === $visibility) {
338
                $link = $resource->getResourceNode()->getResourceLinkByContext($course, $session, $group);
339
                $link->setDeletedAt($lastUpdatedAt);
340
            }
341
342
            $this->entityManager->persist($resource);
343
        }
344
345
        return true;
346
    }
347
348
    public function fileExists($filePath): bool
349
    {
350
        return file_exists($filePath) && !is_dir($filePath) && is_readable($filePath);
351
    }
352
353
    public function findCourse(int $id): ?Course
354
    {
355
        if (0 === $id) {
356
            return null;
357
        }
358
359
        return $this->entityManager->find(Course::class, $id);
360
    }
361
362
    public function findSession(int $id): ?Session
363
    {
364
        if (0 === $id) {
365
            return null;
366
        }
367
368
        return $this->entityManager->find(Session::class, $id);
369
    }
370
371
    public function getMailConfigurationValueFromFile(string $variable): ?string
372
    {
373
        global $platform_email;
374
375
        $rootPath = $this->container->get('kernel')->getProjectDir();
376
        $oldConfigPath = $this->getUpdateRootPath().'/app/config/mail.conf.php';
377
378
        $configFileLoaded = \in_array($oldConfigPath, get_included_files(), true);
379
380
        if (!$configFileLoaded) {
381
            include_once $oldConfigPath;
382
        }
383
384
        $settingValue = $this->getConfigurationValue($variable, $platform_email);
385
386
        if (\is_bool($settingValue)) {
387
            $selectedValue = var_export($settingValue, true);
388
        } else {
389
            $selectedValue = (string) $settingValue;
390
        }
391
392
        return $selectedValue;
393
    }
394
395
    private function generateFilePath(string $filename): string
396
    {
397
        $cacheDir = $this->container->get('kernel')->getCacheDir();
398
399
        return $cacheDir.'/migration_'.$filename;
400
    }
401
402
    protected function writeFile(string $filename, string $content): void
403
    {
404
        $fullFilename = $this->generateFilePath($filename);
405
406
        $fs = new Filesystem();
407
        $fs->dumpFile($fullFilename, $content);
408
    }
409
410
    protected function readFile(string $filename): string
411
    {
412
        $fullFilename = $this->generateFilePath($filename);
413
414
        if ($this->fileExists($fullFilename)) {
415
            return file_get_contents($fullFilename);
416
        }
417
418
        return '';
419
    }
420
421
    protected function removeFile(string $filename): void
422
    {
423
        $fullFilename = $this->generateFilePath($filename);
424
425
        $fs = new Filesystem();
426
        $fs->remove($fullFilename);
427
    }
428
429
    protected function getUpdateRootPath(): string
430
    {
431
        $updateRootPath = getenv('UPDATE_PATH');
432
433
        if (!empty($updateRootPath)) {
434
            error_log('getUpdateRootPath ::: '.$updateRootPath);
435
436
            return rtrim($updateRootPath, '/');
437
        }
438
439
        return $this->container->getParameter('kernel.project_dir');
440
    }
441
442
    protected static function pluginNameReplacements(): array
443
    {
444
        return [
445
            'bbb' => 'Bbb',
446
            'before_login' => 'BeforeLogin',
447
            'buycourses' => 'BuyCourses',
448
            'card_game' => 'CardGame',
449
            'check_extra_field_author_company' => 'CheckExtraFieldAuthorCompany',
450
            'cleandeletedfiles' => 'CleanDeletedFiles',
451
            'courseblock' => 'CourseBlock',
452
            'coursehomenotify' => 'CourseHomeNotify',
453
            'courselegal' => 'CourseLegal',
454
            'customcertificate' => 'CustomCertificate',
455
            'customfooter' => 'CustomFooter',
456
            'dashboard' => 'Dashboard',
457
            'dictionary' => 'Dictionary',
458
            'embedregistry' => 'EmbedRegistry',
459
            'exercise_signature' => 'ExerciseSignature',
460
            'ext_auth_chamilo_logout_button_behaviour' => 'ExtAuthChamiloLogoutButtonBehaviour',
461
            'externalnotificationconnect' => 'ExternalNotificationConnect',
462
            'extramenufromwebservice' => 'ExtraMenuFromWebservice',
463
            'google_maps' => 'GoogleMaps',
464
            'grading_electronic' => 'GradingElectronic',
465
            'h5pimport' => 'H5pImport',
466
            'hello_world' => 'HelloWorld',
467
            'ims_lti' => 'ImsLti',
468
            'justification' => 'Justification',
469
            'learning_calendar' => 'LearningCalendar',
470
            'lti_provider' => 'LtiProvider',
471
            'maintenancemode' => 'MaintenanceMode',
472
            'migrationmoodle' => 'MigrationMoodle',
473
            'nosearchindex' => 'NoSearchIndex',
474
            'notebookteacher' => 'NotebookTeacher',
475
            'onlyoffice' => 'Onlyoffice',
476
            'pausetraining' => 'PauseTraining',
477
            'pens' => 'Pens',
478
            'positioning' => 'Positioning',
479
            'questionoptionsevaluation' => 'QuestionOptionsEvaluation',
480
            'redirection' => 'Redirection',
481
            'resubscription' => 'Resubscription',
482
            'rss' => 'Rss',
483
            'search_course' => 'SearchCourse',
484
            'show_regions' => 'ShowRegions',
485
            'show_user_info' => 'ShowUserInfo',
486
            'static' => 'Static',
487
            'studentfollowup' => 'StudentFollowUp',
488
            'surveyexportcsv' => 'SurveyExportCsv',
489
            'surveyexporttxt' => 'SurveyExportTxt',
490
            'test2pdf' => 'Test2Pdf',
491
            'toplinks' => 'TopLinks',
492
            'tour' => 'Tour',
493
            'userremoteservice' => 'UserRemoteService',
494
            'xapi' => 'XApi',
495
            'zoom' => 'Zoom',
496
        ];
497
    }
498
}
499