Passed
Pull Request — master (#5143)
by Angel Fernando Quiroz
16:06 queued 07:35
created

AbstractMigrationChamilo::setEntityManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
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 Doctrine\Migrations\AbstractMigration;
24
use Doctrine\ORM\EntityManager;
25
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
26
use Symfony\Component\DependencyInjection\ContainerInterface;
27
use Symfony\Component\HttpFoundation\File\UploadedFile;
28
29
abstract class AbstractMigrationChamilo extends AbstractMigration implements ContainerAwareInterface
30
{
31
    public const BATCH_SIZE = 20;
32
33
    private ?EntityManager $manager = null;
34
    private ?ContainerInterface $container = null;
35
36
    public function setEntityManager(EntityManager $manager): void
37
    {
38
        $this->manager = $manager;
39
    }
40
41
    public function setContainer(?ContainerInterface $container = null): void
42
    {
43
        $this->container = $container;
44
    }
45
46
    /**
47
     * @return ContainerInterface
48
     */
49
    public function getContainer()
50
    {
51
        return $this->container;
52
    }
53
54
    public function adminExist(): bool
55
    {
56
        $em = $this->getEntityManager();
57
        $connection = $em->getConnection();
58
59
        $sql = 'SELECT user_id FROM admin WHERE user_id IN (SELECT id FROM user) ORDER BY id LIMIT 1';
60
        $result = $connection->executeQuery($sql);
61
        $adminRow = $result->fetchAssociative();
62
63
        if (empty($adminRow)) {
64
            return false;
65
        }
66
67
        return true;
68
    }
69
70
    public function getAdmin(): User
71
    {
72
        $admin = $this->getEntityManager()
73
            ->getRepository(Admin::class)
74
            ->findOneBy([], ['id' => 'ASC'])
75
        ;
76
77
        return $admin->getUser();
78
    }
79
80
    /**
81
     * @return EntityManager
82
     */
83
    public function getEntityManager()
84
    {
85
        return $this->getContainer()->get('doctrine')->getManager();
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
        $em = $this->getEntityManager();
123
124
        $accessUrl = $em->find(AccessUrl::class, $accessUrl);
125
126
        $setting = new SettingsCurrent();
127
        $setting
128
            ->setVariable($variable)
129
            ->setSubkey($subKey)
130
            ->setType($type)
131
            ->setCategory($category)
132
            ->setSelectedValue($selectedValue)
133
            ->setTitle($title)
134
            ->setComment($comment)
135
            ->setScope($scope)
136
            ->setSubkeytext($subKeyText)
137
            ->setUrl($accessUrl)
138
            ->setAccessUrlChangeable((int) $accessUrlChangeable)
139
            ->setAccessUrlLocked((int) $accessUrlLocked)
140
        ;
141
142
        $em->persist($setting);
143
144
        if (\count($options) > 0) {
145
            foreach ($options as $option) {
146
                if (empty($option['text'])) {
147
                    if ('true' === $option['value']) {
148
                        $option['text'] = 'Yes';
149
                    } else {
150
                        $option['text'] = 'No';
151
                    }
152
                }
153
154
                $settingOption = new SettingsOptions();
155
                $settingOption
156
                    ->setVariable($variable)
157
                    ->setValue($option['value'])
158
                    ->setDisplayText($option['text'])
159
                ;
160
161
                $em->persist($settingOption);
162
            }
163
        }
164
        $em->flush();
165
    }
166
167
    /**
168
     * @param string     $variable
169
     * @param null|mixed $configuration
170
     */
171
    public function getConfigurationValue($variable, $configuration = null)
172
    {
173
        global $_configuration;
174
175
        if (isset($configuration)) {
176
            $_configuration = $configuration;
177
        }
178
179
        if (isset($_configuration[$variable])) {
180
            return $_configuration[$variable];
181
        }
182
183
        return false;
184
    }
185
186
    /**
187
     * Remove a setting completely.
188
     *
189
     * @param string $variable The setting variable name
190
     */
191
    public function removeSettingCurrent($variable): void
192
    {
193
        // to be implemented
194
    }
195
196
    public function addLegacyFileToResource(
197
        string $filePath,
198
        ResourceRepository $repo,
199
        AbstractResource $resource,
200
        $id,
201
        $fileName = '',
202
        $description = ''
203
    ): bool {
204
        $class = $resource::class;
205
        $documentPath = basename($filePath);
206
207
        if (is_dir($filePath) || (!is_dir($filePath) && !file_exists($filePath))) {
208
            $this->warnIf(true, "Cannot migrate {$class} #'.{$id}.' file not found: {$documentPath}");
209
210
            return false;
211
        }
212
213
        $mimeType = mime_content_type($filePath);
214
        if (empty($fileName)) {
215
            $fileName = basename($documentPath);
216
        }
217
        $file = new UploadedFile($filePath, $fileName, $mimeType, null, true);
218
        $repo->addFile($resource, $file);
219
220
        return true;
221
    }
222
223
    public function fixItemProperty(
224
        $tool,
225
        ResourceRepository $repo,
226
        $course,
227
        $admin,
228
        ResourceInterface $resource,
229
        $parentResource,
230
        array $items = []
231
    ) {
232
        $container = $this->getContainer();
233
        $em = $this->getEntityManager();
234
        $connection = $em->getConnection();
235
236
        $courseId = $course->getId();
237
        $id = $resource->getResourceIdentifier();
238
239
        if (empty($items)) {
240
            $sql = "SELECT * FROM c_item_property
241
                    WHERE tool = '{$tool}' AND c_id = {$courseId} AND ref = {$id}";
242
            $result = $connection->executeQuery($sql);
243
            $items = $result->fetchAllAssociative();
244
        }
245
246
        // For some reason the resource doesn't have a c_item_property value.
247
        if (empty($items)) {
248
            return false;
249
        }
250
251
        $sessionRepo = $container->get(SessionRepository::class);
252
        $groupRepo = $container->get(CGroupRepository::class);
253
        $userRepo = $container->get(UserRepository::class);
254
255
        $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

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

321
            $resource->/** @scrutinizer ignore-call */ 
322
                       addCourseLink($course, $session, $group, $newVisibility);
Loading history...
322
323
            if (2 === $visibility) {
324
                $link = $resource->getResourceNode()->getResourceLinkByContext($course, $session, $group);
325
                $link->setDeletedAt($lastUpdatedAt);
326
            }
327
328
            $em->persist($resource);
329
        }
330
331
        return true;
332
    }
333
334
    public function fileExists($filePath): bool
335
    {
336
        return file_exists($filePath) && !is_dir($filePath) && is_readable($filePath);
337
    }
338
339
    public function findCourse(int $id): ?Course
340
    {
341
        if (0 === $id) {
342
            return null;
343
        }
344
345
        return $this->getEntityManager()->find(Course::class, $id);
346
    }
347
348
    public function findSession(int $id): ?Session
349
    {
350
        if (0 === $id) {
351
            return null;
352
        }
353
354
        return $this->getEntityManager()->find(Session::class, $id);
355
    }
356
}
357