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

AbstractMigrationChamilo::findSession()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
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