Passed
Pull Request — master (#6263)
by
unknown
08:07
created

Version20250501000100::resourceNodeHasFile()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 4
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 8
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Migrations\Schema\V200;
8
9
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
10
use Chamilo\CoreBundle\Repository\Node\CourseRepository;
11
use Chamilo\CourseBundle\Entity\CStudentPublication;
12
use Chamilo\CourseBundle\Entity\CStudentPublicationComment;
13
use Chamilo\CourseBundle\Repository\CStudentPublicationCommentRepository;
14
use Chamilo\CourseBundle\Repository\CStudentPublicationRepository;
15
use Doctrine\DBAL\Schema\Schema;
16
17
final class Version20250501000100 extends AbstractMigrationChamilo
18
{
19
    public function getDescription(): string
20
    {
21
        return 'Migrate student publications (works), corrections, and comments to ResourceNode/ResourceFile';
22
    }
23
24
    public function up(Schema $schema): void
25
    {
26
        $publicationRepo = $this->container->get(CStudentPublicationRepository::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

26
        /** @scrutinizer ignore-call */ 
27
        $publicationRepo = $this->container->get(CStudentPublicationRepository::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...
27
        $commentRepo = $this->container->get(CStudentPublicationCommentRepository::class);
28
        $courseRepo = $this->container->get(CourseRepository::class);
29
        $kernel = $this->container->get('kernel');
30
        $root = $kernel->getProjectDir();
31
32
        $courses = $this->entityManager
33
            ->createQuery('SELECT c FROM Chamilo\\CoreBundle\\Entity\\Course c')
0 ignored issues
show
Bug introduced by
The method createQuery() 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

33
            ->/** @scrutinizer ignore-call */ createQuery('SELECT c FROM Chamilo\\CoreBundle\\Entity\\Course c')

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...
34
            ->toIterable();
35
36
        foreach ($courses as $course) {
37
            $courseDir = $course->getDirectory();
38
            $workPath = "{$root}/app/courses/{$courseDir}/work";
39
            error_log("[MIGRATION] Processing course '{$course->getCode()}' (ID: {$course->getId()})");
40
41
            $publications = $publicationRepo->createQueryBuilder('sp')
42
                ->join('sp.resourceNode', 'rn')
43
                ->join('rn.resourceLinks', 'rl')
44
                ->where('rl.course = :course')
45
                ->andWhere('sp.filetype = :file')
46
                ->setParameter('course', $course)
47
                ->setParameter('file', 'file')
48
                ->getQuery()
49
                ->getResult();
50
51
            foreach ($publications as $publication) {
52
                if (!$publication instanceof CStudentPublication || !$publication->getResourceNode()) {
53
                    continue;
54
                }
55
56
                $row = $this->connection->fetchAssociative(
57
                    'SELECT * FROM c_student_publication WHERE iid = ?',
58
                    [$publication->getIid()]
59
                );
60
                $resourceNode = $publication->getResourceNode();
61
62
                $url = $row['url'] ?? null;
63
                if (!empty($url) && str_starts_with($url, 'work/') && !$this->resourceNodeHasFile($resourceNode, basename($url))) {
64
                    $filename = basename($url);
65
                    $source = "{$workPath}/{$url}";
66
                    error_log("[MIGRATION] Submission source: $source");
67
68
                    if ($this->fileExists($source)) {
69
                        $this->addLegacyFileToResource($source, $publicationRepo, $publication, $row['iid'], $filename);
70
                        $this->entityManager->persist($publication);
71
                    } else {
72
                        error_log("[MIGRATION][ERROR] Submission file not found: $source");
73
                    }
74
                }
75
76
                $correctionUrl = $row['url_correction'] ?? null;
77
                if (!empty($correctionUrl) && str_starts_with($correctionUrl, 'work/') && !$this->resourceNodeHasFile($resourceNode, basename($correctionUrl))) {
78
                    $filename = basename($correctionUrl);
79
                    $source = "{$workPath}/{$correctionUrl}";
80
                    error_log("[MIGRATION] Correction source: $source");
81
82
                    if ($this->fileExists($source)) {
83
                        $this->addLegacyFileToResource($source, $publicationRepo, $publication, $row['iid'], $filename);
84
                        $publication->setExtensions($filename);
85
                        $this->entityManager->persist($publication);
86
                    } else {
87
                        error_log("[MIGRATION][WARN] Correction file not found: $source");
88
                    }
89
                }
90
91
                $this->entityManager->flush();
92
            }
93
94
            $comments = $commentRepo->createQueryBuilder('c')
95
                ->join('c.publication', 'sp')
96
                ->join('sp.resourceNode', 'rn')
97
                ->join('rn.resourceLinks', 'rl')
98
                ->where('rl.course = :course')
99
                ->andWhere('c.file IS NOT NULL')
100
                ->setParameter('course', $course)
101
                ->getQuery()
102
                ->getResult();
103
104
            foreach ($comments as $comment) {
105
                if (!$comment instanceof CStudentPublicationComment || !$comment->getResourceNode()) {
106
                    continue;
107
                }
108
109
                $row = $this->connection->fetchAssociative(
110
                    'SELECT * FROM c_student_publication_comment WHERE iid = ?',
111
                    [$comment->getIid()]
112
                );
113
114
                $filename = basename($row['file']);
115
                $source = "{$workPath}/{$filename}";
116
                $resourceNode = $comment->getResourceNode();
117
                error_log("[MIGRATION] Comment source: $source");
118
119
                if (!$this->resourceNodeHasFile($resourceNode, $filename)) {
120
                    if ($this->fileExists($source)) {
121
                        $this->addLegacyFileToResource($source, $commentRepo, $comment, $row['iid'], $filename);
122
                        $this->entityManager->persist($comment);
123
                        $this->entityManager->flush();
124
                    } else {
125
                        error_log("[MIGRATION][WARN] Comment file not found: $source");
126
                    }
127
                }
128
            }
129
130
            $this->entityManager->clear();
131
            error_log("[MIGRATION] Finished processing course '{$course->getCode()}'");
132
        }
133
    }
134
135
    private function resourceNodeHasFile($resourceNode, string $filename): bool
136
    {
137
        foreach ($resourceNode->getResourceFiles() as $file) {
138
            if ($file->getTitle() === $filename || $file->getOriginalName() === $filename) {
139
                return true;
140
            }
141
        }
142
        return false;
143
    }
144
}
145