Passed
Pull Request — master (#5622)
by
unknown
07:17
created

Version20240506165900::replaceOldURLsWithNew()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 20
c 2
b 0
f 0
nc 9
nop 1
dl 0
loc 32
rs 8.9777
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\PersonalFileRepository;
11
use Chamilo\CoreBundle\Repository\Node\UserRepository;
12
use Doctrine\DBAL\Schema\Schema;
13
14
use const PREG_SET_ORDER;
15
16
final class Version20240506165900 extends AbstractMigrationChamilo
17
{
18
    public function getDescription(): string
19
    {
20
        return 'Update HTML content blocks to replace old file paths with resource links to personal documents (images, videos, audio) in course tools';
21
    }
22
23
    public function up(Schema $schema): void
24
    {
25
        $updateConfigurations = [
26
            ['table' => 'c_tool_intro', 'field' => 'intro_text'],
27
            ['table' => 'c_course_description', 'field' => 'content'],
28
            ['table' => 'c_quiz', 'fields' => ['description', 'text_when_finished']],
29
            ['table' => 'c_quiz_question', 'fields' => ['description', 'question']],
30
            ['table' => 'c_quiz_answer', 'fields' => ['answer', 'comment']],
31
            ['table' => 'c_student_publication', 'field' => 'description'],
32
            ['table' => 'c_student_publication_comment', 'field' => 'comment'],
33
            ['table' => 'c_forum_category', 'field' => 'cat_comment'],
34
            ['table' => 'c_forum_forum', 'field' => 'forum_comment'],
35
            ['table' => 'c_forum_post', 'field' => 'post_text'],
36
            ['table' => 'c_glossary', 'field' => 'description'],
37
            ['table' => 'c_survey', 'fields' => ['title', 'subtitle']],
38
            ['table' => 'c_survey_question', 'fields' => ['survey_question', 'survey_question_comment']],
39
            ['table' => 'c_survey_question_option', 'field' => 'option_text'],
40
        ];
41
42
        foreach ($updateConfigurations as $config) {
43
            $this->updateContent($config);
44
        }
45
    }
46
47
    private function updateContent(array $config): void
48
    {
49
        $fields = isset($config['field']) ? [$config['field']] : $config['fields'] ?? [];
50
51
        foreach ($fields as $field) {
52
            $sql = "SELECT iid, {$field} FROM {$config['table']}";
53
            $result = $this->connection->executeQuery($sql);
54
            $items = $result->fetchAllAssociative();
55
56
            foreach ($items as $item) {
57
                $originalText = $item[$field];
58
                if (!empty($originalText)) {
59
                    $updatedText = $this->replaceOldURLsWithNew($originalText);
60
                    if ($originalText !== $updatedText) {
61
                        $updateSql = "UPDATE {$config['table']} SET {$field} = :newText WHERE iid = :id";
62
                        $this->connection->executeQuery($updateSql, ['newText' => $updatedText, 'id' => $item['iid']]);
63
                    }
64
                }
65
            }
66
        }
67
    }
68
69
    private function replaceOldURLsWithNew(string $content): string
70
    {
71
        $personalRepo = $this->container->get(PersonalFileRepository::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

71
        /** @scrutinizer ignore-call */ 
72
        $personalRepo = $this->container->get(PersonalFileRepository::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...
72
        $userRepo = $this->container->get(UserRepository::class);
73
74
        $pattern = '/(src|href)=["\']?(https?:\/\/[^\/]+)?(\/app\/upload\/users\/(\d+)\/(\d+)\/my_files\/([^\/"\']+))["\']?/i';
75
76
        preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);
77
78
        foreach ($matches as $match) {
79
            $attribute = $match[1];
80
            $baseUrlWithApp = $match[2] ? $match[2].$match[3] : $match[3];
81
            $folderId = (int) $match[4];
82
            $userId = (int) $match[5];
83
            $filename = $match[6];
84
85
            // Decode the filename to handle special characters
86
            $decodedFilename = urldecode($filename);
87
            $user = $userRepo->find($userId);
88
            if (null !== $user) {
89
                $personalFile = $personalRepo->getResourceByCreatorFromTitle($decodedFilename, $user, $user->getResourceNode());
90
                if ($personalFile) {
91
                    $newUrl = $personalRepo->getResourceFileUrl($personalFile);
92
                    if ($newUrl) {
93
                        $content = str_replace($baseUrlWithApp, $newUrl, $content);
94
                        error_log("Replaced old URL: {$baseUrlWithApp} with new URL: {$newUrl}");
95
                    }
96
                }
97
            }
98
        }
99
100
        return $content;
101
    }
102
}
103