Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
declare(strict_types=1);
18
 
19
namespace mod_edusharing;
20
 
21
use coding_exception;
22
use dml_exception;
23
use DOMDocument;
24
use EduSharingApiClient\MissingRightsException;
25
use EduSharingApiClient\Usage;
26
use Exception;
27
use moodle_exception;
28
use stdClass;
29
 
30
/**
31
 * Class RestoreHelper
32
 *
33
 * @author Marian Ziegler <ziegler@edu-sharing.net>
34
 * @package mod_edusharing
35
 */
36
class RestoreHelper {
37
    /**
38
     * @var EduSharingService
39
     */
40
    private EduSharingService $service;
41
 
42
    /**
43
     * @var UtilityFunctions
44
     */
45
    private UtilityFunctions $utils;
46
 
47
    /**
48
     * RestoreHelper constructor
49
     *
50
     * @param EduSharingService $service
51
     */
52
    public function __construct(EduSharingService $service) {
53
        $this->service = $service;
54
        $this->init();
55
    }
56
 
57
    /**
58
     * Function init
59
     *
60
     * @return void
61
     */
62
    private function init(): void {
63
        $this->utils = new UtilityFunctions();
64
    }
65
 
66
    /**
67
     * Function convert_inline_options
68
     *
69
     * @param int $courseid
70
     * @return void
71
     *
72
     * @throws coding_exception
73
     * @throws dml_exception
74
     * @throws moodle_exception
75
     */
76
    public function convert_inline_options($courseid): void {
77
        global $DB;
78
        $sections = $DB->get_records('course_sections', ['course' => $courseid]);
79
        foreach ($sections as $section) {
80
            $esmatches = $this->get_inline_objects($section->summary ?? '');
81
            if (!empty($esmatches)) {
82
                foreach ($esmatches as $match) {
83
                    $section->summary = str_replace($match, $this->convert_object($match, $courseid), $section->summary);
84
                    $DB->update_record('course_sections', $section);
85
                }
86
            }
87
        }
88
        $modules = get_course_mods($courseid);
89
        $course  = get_course($courseid);
90
        foreach ($modules as $module) {
91
            $modinfo = get_fast_modinfo($course);
92
            $cm      = $modinfo->get_cm($module->id);
93
            if (!empty($cm->content)) {
94
                $esmatches = $this->get_inline_objects($cm->content);
95
                if (!empty($esmatches)) {
96
                    foreach ($esmatches as $match) {
97
                        $cm->set_content(str_replace($match, $this->convert_object($match, $courseid), $cm->content));
98
                    }
99
                }
100
            }
101
            try {
102
                $module = $DB->get_record($cm->name, ['id' => $cm->instance], '*', MUST_EXIST);
103
            } catch (Exception $exception) {
104
                debugging($exception->getMessage());
105
                continue;
106
            }
107
            if (!empty($module->intro)) {
108
                $esmatches = $this->get_inline_objects($module->intro);
109
                if (!empty($esmatches)) {
110
                    foreach ($esmatches as $match) {
111
                        $module->intro = str_replace($match, $this->convert_object($match, $courseid), $module->intro);
112
                    }
113
                }
114
            }
115
            $DB->update_record($cm->name, $module);
116
        }
117
        rebuild_course_cache((int)$courseid, true);
118
    }
119
 
120
    /**
121
     * Function get_inline_objects
122
     *
123
     * @param string $text
124
     * @return array
125
     */
126
    private function get_inline_objects(string $text): array {
127
        if (!str_contains($text, 'edusharing_atto')) {
128
            return [];
129
        }
130
        if (isloggedin()) {
131
            try {
132
                $this->service->get_ticket();
133
            } catch (Exception $exception) {
134
                trigger_error($exception->getMessage(), E_USER_WARNING);
135
                return [];
136
            }
137
        }
138
 
139
        return $this->utils->get_inline_object_matches($text);
140
    }
141
 
142
    /**
143
     * Function convert_object
144
     *
145
     * @param mixed $object
146
     * @param mixed $courseid
147
     * @return mixed
148
     * @throws coding_exception
149
     * @throws dml_exception
150
     * @throws Exception
151
     */
152
    private function convert_object($object, $courseid): string {
153
        global $DB;
154
        libxml_use_internal_errors(true);
155
        $doc = new DOMDocument();
156
        $doc->loadHTML($object, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
157
        $errors = libxml_get_errors();
158
        if (!empty($errors)) {
159
            debugging("Html parsing error(s): " . json_encode($errors));
160
            debugging($object);
161
            return get_string('error_parsing_on_restore', 'edusharing');
162
        }
163
        $node = $doc->getElementsByTagName('a')->item(0);
164
        $type = 'a';
165
        if (empty($node)) {
166
            $node = $doc->getElementsByTagName('img')->item(0);
167
            $qs   = $node->getAttribute('src');
168
            $type = 'img';
169
        } else {
170
            $qs = $node->getAttribute('href');
171
        }
172
        if (empty($node)) {
173
            throw new Exception(get_string('error_loading_node', 'filter_edusharing'));
174
        }
175
        $params = [];
176
        $queryparams = parse_url($qs, PHP_URL_QUERY);
177
        if (empty($queryparams)) {
178
            debugging("ES object url could not be retrieved or parsed.");
179
            debugging($object);
180
            return get_string('error_parsing_on_restore', 'edusharing');
181
        }
182
        parse_str($queryparams, $params);
183
        $edusharing                 = new stdClass();
184
        $edusharing->course         = $courseid;
185
        $edusharing->name           = $params['title'];
186
        $edusharing->introformat    = 0;
187
        $edusharing->object_url     = $params['object_url'];
188
        $edusharing->object_version = $params['window_version'];
189
        $edusharing->timecreated    = time();
190
        $edusharing->timemodified   = time();
191
        $id                         = $DB->insert_record('edusharing', $edusharing);
192
        if ($id !== false) {
193
            try {
194
                $usage = $this->add_usage($edusharing, $id);
195
            } catch (MissingRightsException $missingrightsexception) {
196
                unset($missingrightsexception);
197
                return get_string('error_missing_rights_on_restore', 'edusharing') . ': ' . ($params['nodeId'] ?? 'blank nodeId');
198
            } catch (Exception $exception) {
199
                unset($exception);
200
                return get_string('error_unexpected_on_restore', 'edusharing')  . ': ' . ($params['nodeId'] ?? 'blank nodeId');
201
            }
202
            if ($usage !== null) {
203
                if (isset($usage->usageId)) {
204
                    $edusharing->id      = $id;
205
                    $edusharing->usageId = $usage->usageId;
206
                    $DB->update_record(Constants::EDUSHARING_TABLE, $edusharing);
207
                }
208
                $params['resourceId'] = $id;
209
                $url                  = strtok($qs, '?') . '?';
210
                foreach ($params as $paramn => $paramv) {
211
                    $url .= $paramn . '=' . $paramv . '&';
212
                }
213
                $node->setAttribute($type === 'a' ? 'href' : 'src', $url);
214
            } else {
215
                $DB->delete_records('edusharing', ['id' => $id]);
216
                return $object;
217
            }
218
        }
219
        return $doc->saveHTML();
220
    }
221
 
222
    /**
223
     * Function add_usage
224
     *
225
     * @param stdClass $data
226
     * @param int $newitemid
227
     * @return Usage|null
228
     * @throws \JsonException
229
     * @throws Exception
230
     * @throws MissingRightsException
231
     */
232
    public function add_usage(stdClass $data, int $newitemid): ?Usage {
233
        $usagedata              = new stdClass();
234
        $usagedata->containerId = $data->course;
235
        $usagedata->resourceId  = $newitemid;
236
        $utils                  = new UtilityFunctions();
237
        $usagedata->nodeId      = $utils->get_object_id_from_url($data->object_url);
238
        $usagedata->nodeVersion = $data->object_version;
239
        return $this->service->create_usage($usagedata);
240
    }
241
}