Passed
Push — dependabot/npm_and_yarn/microm... ( e84ba6...f2f212 )
by
unknown
10:03
created

Version20240924120200::updateContent()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 12
c 1
b 0
f 0
nc 10
nop 1
dl 0
loc 16
rs 8.8333
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\ResourceNodeRepository;
11
use Chamilo\CourseBundle\Entity\CDocument;
12
use Chamilo\CourseBundle\Repository\CDocumentRepository;
13
use Doctrine\DBAL\Schema\Schema;
14
use Exception;
15
16
final class Version20240924120200 extends AbstractMigrationChamilo
17
{
18
    public function getDescription(): string
19
    {
20
        return 'Update HTML content blocks to replace old CKEditor image paths with new ones and convert .gif references to .png, including HTML files in the document repository';
21
    }
22
23
    public function up(Schema $schema): void
24
    {
25
        $this->entityManager->clear();
0 ignored issues
show
Bug introduced by
The method clear() 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

25
        $this->entityManager->/** @scrutinizer ignore-call */ 
26
                              clear();

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...
26
27
        // Define the content fields to update
28
        $updateConfigurations = [
29
            ['table' => 'c_tool_intro', 'field' => 'intro_text'],
30
            ['table' => 'c_course_description', 'field' => 'content'],
31
            ['table' => 'c_quiz', 'fields' => ['description', 'text_when_finished']],
32
            ['table' => 'c_quiz_question', 'fields' => ['description', 'question']],
33
            ['table' => 'c_quiz_answer', 'fields' => ['answer', 'comment']],
34
            ['table' => 'c_student_publication', 'field' => 'description'],
35
            ['table' => 'c_student_publication_comment', 'field' => 'comment'],
36
            ['table' => 'c_forum_post', 'field' => 'post_text'],
37
            ['table' => 'c_glossary', 'field' => 'description'],
38
            ['table' => 'c_survey', 'fields' => ['title', 'subtitle']],
39
            ['table' => 'c_survey_question', 'fields' => ['survey_question', 'survey_question_comment']],
40
            ['table' => 'c_survey_question_option', 'field' => 'option_text'],
41
        ];
42
43
        foreach ($updateConfigurations as $config) {
44
            $this->updateContent($config);
45
        }
46
47
        $this->updateHtmlFiles();
48
    }
49
50
    private function updateContent(array $config): void
51
    {
52
        $fields = isset($config['field']) ? [$config['field']] : $config['fields'] ?? [];
53
54
        foreach ($fields as $field) {
55
            $sql = "SELECT iid, {$field} FROM {$config['table']}";
56
            $result = $this->connection->executeQuery($sql);
57
            $items = $result->fetchAllAssociative();
58
59
            foreach ($items as $item) {
60
                $originalText = $item[$field];
61
                if (is_string($originalText) && trim($originalText) !== '') {
62
                    $updatedText = $this->replaceGifWithPng($originalText);
63
                    if ($originalText !== $updatedText) {
64
                        $updateSql = "UPDATE {$config['table']} SET {$field} = :newText WHERE iid = :id";
65
                        $this->connection->executeQuery($updateSql, ['newText' => $updatedText, 'id' => $item['iid']]);
66
                    }
67
                }
68
            }
69
        }
70
    }
71
72
    private function updateHtmlFiles(): void
73
    {
74
        $sql = "SELECT iid, resource_node_id FROM c_document WHERE filetype = 'file'";
75
        $result = $this->connection->executeQuery($sql);
76
        $items = $result->fetchAllAssociative();
77
78
        $documentRepo = $this->container->get(CDocumentRepository::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

78
        /** @scrutinizer ignore-call */ 
79
        $documentRepo = $this->container->get(CDocumentRepository::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...
79
        $resourceNodeRepo = $this->container->get(ResourceNodeRepository::class);
80
81
        foreach ($items as $item) {
82
            /** @var CDocument $document */
83
            $document = $documentRepo->find($item['iid']);
84
            if (!$document) {
85
                continue;
86
            }
87
88
            $resourceNode = $document->getResourceNode();
89
            if (!$resourceNode || !$resourceNode->hasResourceFile()) {
90
                continue;
91
            }
92
93
            $resourceFile = $resourceNode->getResourceFiles()->first();
94
            if (!$resourceFile || $resourceFile->getMimeType() !== 'text/html') {
95
                continue;
96
            }
97
98
            try {
99
                $content = $resourceNodeRepo->getResourceNodeFileContent($resourceNode);
100
                if (is_string($content) && trim($content) !== '') {
101
                    $updatedContent = $this->replaceGifWithPng($content);
102
                    if ($content !== $updatedContent) {
103
                        $documentRepo->updateResourceFileContent($document, $updatedContent);
104
                        $documentRepo->update($document);
105
                    }
106
                }
107
            } catch (Exception $e) {
108
               // error_log("Error processing file for document ID {$item['iid']}: " . $e->getMessage());
109
            }
110
        }
111
    }
112
113
    private function replaceGifWithPng(string $content): string
114
    {
115
        $pattern = '/(src=["\'])(https?:\/\/[^\/]+\/)?(\/?web\/assets\/ckeditor\/plugins\/smiley\/images\/([a-zA-Z0-9_\-]+))\.(gif|png)(["\'])/i';
116
117
        return preg_replace_callback($pattern, function ($matches) {
118
            $prefix = $matches[1];
119
            $filename = $matches[4];
120
            $extension = 'png';
121
122
            return "{$prefix}/img/legacy/{$filename}.{$extension}{$matches[6]}";
123
        }, $content);
124
    }
125
}
126