Passed
Pull Request — master (#5462)
by Angel Fernando Quiroz
11:48 queued 04:29
created

AbstractMigrationChamilo::removeSettingCurrent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 1
dl 0
loc 2
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\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\HttpFoundation\File\UploadedFile;
29
30
abstract class AbstractMigrationChamilo extends AbstractMigration
31
{
32
    public const BATCH_SIZE = 20;
33
34
    protected ?EntityManagerInterface $entityManager = null;
35
    protected ?ContainerInterface $container = null;
36
37
    public function setEntityManager(EntityManagerInterface $entityManager): void
38
    {
39
        $this->entityManager = $entityManager;
40
    }
41
42
    public function setContainer(?ContainerInterface $container = null): void
43
    {
44
        $this->container = $container;
45
    }
46
47
    public function adminExist(): bool
48
    {
49
        $sql = 'SELECT user_id FROM admin WHERE user_id IN (SELECT id FROM user) ORDER BY id LIMIT 1';
50
        $result = $this->connection->executeQuery($sql);
51
        $adminRow = $result->fetchAssociative();
52
53
        if (empty($adminRow)) {
54
            return false;
55
        }
56
57
        return true;
58
    }
59
60
    public function getAdmin(): User
61
    {
62
        $admin = $this->entityManager
63
            ->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

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

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

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

315
            $resource->/** @scrutinizer ignore-call */ 
316
                       addCourseLink($course, $session, $group, $newVisibility);
Loading history...
316
317
            if (2 === $visibility) {
318
                $link = $resource->getResourceNode()->getResourceLinkByContext($course, $session, $group);
319
                $link->setDeletedAt($lastUpdatedAt);
320
            }
321
322
            $this->entityManager->persist($resource);
323
        }
324
325
        return true;
326
    }
327
328
    public function fileExists($filePath): bool
329
    {
330
        return file_exists($filePath) && !is_dir($filePath) && is_readable($filePath);
331
    }
332
333
    public function findCourse(int $id): ?Course
334
    {
335
        if (0 === $id) {
336
            return null;
337
        }
338
339
        return $this->entityManager->find(Course::class, $id);
340
    }
341
342
    public function findSession(int $id): ?Session
343
    {
344
        if (0 === $id) {
345
            return null;
346
        }
347
348
        return $this->entityManager->find(Session::class, $id);
349
    }
350
351
    public function getMailConfigurationValueFromFile(string $variable): ?string
352
    {
353
        global $platform_email;
354
355
        $rootPath = $this->container->get('kernel')->getProjectDir();
356
        $oldConfigPath = $rootPath.'/app/config/mail.conf.php';
357
358
        $configFileLoaded = \in_array($oldConfigPath, get_included_files(), true);
359
360
        if (!$configFileLoaded) {
361
            include_once $oldConfigPath;
362
        }
363
364
        $settingValue = $this->getConfigurationValue($variable, $platform_email);
365
366
        if (\is_bool($settingValue)) {
367
            $selectedValue = var_export($settingValue, true);
368
        } else {
369
            $selectedValue = (string) $settingValue;
370
        }
371
372
        return $selectedValue;
373
    }
374
}
375