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 cached_cm_info;
22
use coding_exception;
23
use context_course;
24
use context_system;
25
use dml_exception;
26
use DOMDocument;
27
use Exception;
28
use stdClass;
29
 
30
/**
31
 * Class UtilityFunctions
32
 *
33
 * @author Marian Ziegler <ziegler@edu-sharing.net>
34
 * @package mod_edusharing
35
 */
36
class UtilityFunctions {
37
    /**
38
     * @var AppConfig|null
39
     */
40
    private ?AppConfig $appconfig;
41
 
42
    /**
43
     * UtilityFunctions constructor
44
     *
45
     * @param AppConfig|null $config
46
     */
47
    public function __construct(?AppConfig $config = null) {
48
        $this->appconfig = $config;
49
        $this->init();
50
    }
51
 
52
    /**
53
     * Function init
54
     *
55
     * @return void
56
     */
57
    private function init(): void {
58
        if ($this->appconfig === null) {
59
            $this->appconfig = new DefaultAppConfig();
60
        }
61
    }
62
 
63
    /**
64
     * Function get_object_id_from_url
65
     *
66
     * Get the object-id from object-url.
67
     * E.g. "abc-123-xyz-456789" for "ccrep://homeRepository/abc-123-xyz-456789"
68
     *
69
     * @param string $url
70
     * @return string
71
     */
72
    public function get_object_id_from_url(string $url): string {
73
        $objectid = parse_url($url, PHP_URL_PATH);
74
        if ($objectid === false) {
75
            try {
76
                trigger_error(get_string('error_get_object_id_from_url', 'edusharing'), E_USER_WARNING);
77
            } catch (Exception $exception) {
78
                unset($exception);
79
                trigger_error('error_get_object_id_from_url', E_USER_WARNING);
80
            }
81
            return '';
82
        }
83
 
84
        return str_replace('/', '', $objectid);
85
    }
86
 
87
    /**
88
     * Function get_repository_id_from_url
89
     *
90
     * Get the repository-id from object-url.
91
     * E.g. "homeRepository" for "ccrep://homeRepository/abc-123-xyz-456789"
92
     *
93
     * @param string $url
94
     * @return string
95
     * @throws Exception
96
     */
97
    public function get_repository_id_from_url(string $url): string {
98
        $repoid = parse_url($url, PHP_URL_HOST);
99
        if ($repoid === false) {
100
            throw new Exception(get_string('error_get_repository_id_from_url', 'edusharing'));
101
        }
102
 
103
        return $repoid;
104
    }
105
 
106
    /**
107
     * Functions get_redirect_url
108
     *
109
     * @param stdClass $edusharing
110
     * @param string $displaymode
111
     * @return string
112
     * @throws coding_exception
113
     * @throws dml_exception
114
     */
115
    public function get_redirect_url(
116
        stdClass $edusharing,
117
        string $displaymode = Constants::EDUSHARING_DISPLAY_MODE_DISPLAY
118
    ): string {
119
        global $USER;
120
        $url = rtrim($this->get_config_entry('application_cc_gui_url'), '/');
121
        $url .= '/renderingproxy';
122
        $url .= '?app_id=' . urlencode($this->get_config_entry('application_appid'));
123
        $url .= '&session=' . urlencode(session_id());
124
        try {
125
            $repoid = $this->get_repository_id_from_url($edusharing->object_url);
126
        } catch (Exception $exception) {
127
            debugging($exception->getMessage());
128
            return '';
129
        }
130
        $url     .= '&rep_id=' . urlencode($repoid);
131
        $url     .= '&obj_id=' . urlencode($this->get_object_id_from_url($edusharing->object_url));
132
        $url     .= '&resource_id=' . urlencode($edusharing->id);
133
        $url     .= '&course_id=' . urlencode($edusharing->course);
134
        $context = context_course::instance($edusharing->course);
135
        $roles   = get_user_roles($context, $USER->id);
136
        foreach ($roles as $role) {
137
            $url .= '&role=' . urlencode($role->shortname);
138
        }
139
        $url .= '&display=' . urlencode($displaymode);
140
        $url .= '&version=' . urlencode($edusharing->object_version);
141
        $url .= '&locale=' . urlencode(current_language());
142
        $url .= '&language=' . urlencode(current_language());
143
        $url .= '&u=' . rawurlencode(base64_encode($this->encrypt_with_repo_key($this->get_auth_key())));
144
 
145
        return $url;
146
    }
147
 
148
    /**
149
     * Function get_auth_key
150
     *
151
     * @throws dml_exception
152
     */
153
    public function get_auth_key(): string {
154
        global $USER, $SESSION;
155
 
156
        // Set by external sso script.
157
        if (!empty($SESSION->edusharing_sso) && $this->get_config_entry('obfuscate_auth_param') === '1') {
158
            return $SESSION->edusharing_sso[$this->get_config_entry('EDU_AUTH_PARAM_NAME_USERID')];
159
        }
160
        $guestoption = $this->get_config_entry('edu_guest_option');
161
        if (!empty($guestoption)) {
162
            $guestid = $this->get_config_entry('edu_guest_guest_id');
163
 
164
            return !empty($guestid) ? $guestid : 'esguest';
165
        }
166
        $eduauthkey = $this->get_config_entry('EDU_AUTH_KEY');
167
        if ($eduauthkey == 'id') {
168
            return $USER->id;
169
        }
170
        if ($eduauthkey == 'idnumber') {
171
            return $USER->idnumber;
172
        }
173
        if ($eduauthkey == 'email') {
174
            return $USER->email;
175
        }
176
        if (isset($USER->profile[$eduauthkey])) {
177
            return $USER->profile[$eduauthkey];
178
        }
179
        return $USER->username . $this->get_config_entry('auth_suffix');
180
    }
181
 
182
    /**
183
     * Function encrypt_with_repo_key
184
     *
185
     * @param string $data
186
     * @return string
187
     * @throws coding_exception
188
     * @throws dml_exception
189
     */
190
    public function encrypt_with_repo_key(string $data): string {
191
        $encrypted = '';
192
        $key       = openssl_get_publickey($this->get_config_entry('repository_public_key'));
193
        if (!openssl_public_encrypt($data, $encrypted, $key)) {
194
            trigger_error(get_string('error_encrypt_with_repo_public', 'edusharing'), E_USER_WARNING);
195
            return '';
196
        }
197
        return $encrypted;
198
    }
199
 
200
    /**
201
     * Function set_moodle_ids_in_edusharing_entries
202
     *
203
     * @param string $text
204
     * @param int $sectionid
205
     * @param int $moduleid
206
     *
207
     * @throws dml_exception
208
     */
209
    public function set_moodle_ids_in_edusharing_entries(string $text, int $sectionid, int $moduleid = 0): void {
210
        global $DB;
211
        $esmatches = $this->get_inline_object_matches($text);
212
        foreach ($esmatches as $match) {
213
            $resourceid = $this->get_resource_id_from_match($match);
214
            $edusharing = $DB->get_record('edusharing', ['id' => $resourceid], '*', MUST_EXIST);
215
            $edusharing->section_id = $sectionid;
216
            if ($moduleid !== 0) {
217
                $edusharing->module_id = $moduleid;
218
            }
219
            $DB->update_record('edusharing', $edusharing);
220
        }
221
    }
222
 
223
    /**
224
     * Function get_resource_id_from_match
225
     *
226
     * @param string $match
227
     * @return string
228
     */
229
    public function get_resource_id_from_match(string $match): string {
230
        $resourceid = '';
231
        $pos        = strpos($match, 'resourceid="');
232
        $offset     = 12;
233
        if ($pos === false) {
234
            $pos = strpos($match, "resourceId=");
235
            $offset = 11;
236
        }
237
        if ($pos !== false) {
238
            $resourceid = substr($match, $pos + $offset);
239
            $resourceid = substr($resourceid, 0, strpos($resourceid, "&"));
240
        }
241
        return $resourceid;
242
    }
243
 
244
    /**
245
     * Function update_settings_images
246
     *
247
     * @param string $settingname
248
     * @return void
249
     */
250
    public function update_settings_images(string $settingname): void {
251
        global $CFG;
252
        // The setting name that was updated comes as a string like 's_theme_photo_loginbackgroundimage'.
253
        // We split it on '_' characters.
254
        $parts = explode('_', $settingname);
255
        // And get the last one to get the setting name..
256
        $settingname = end($parts);
257
        // Admin settings are stored in system context.
258
        try {
259
            $syscontext = context_system::instance();
260
            $filename   = $this->get_config_entry($settingname);
261
        } catch (Exception $exception) {
262
            debugging($exception->getMessage());
263
            return;
264
        }
265
        // This is the value of the admin setting which is the filename of the uploaded file.
266
        // We extract the file extension because we want to preserve it.
267
        $extension = substr($filename, strrpos($filename, '.') + 1);
268
        // This is the path in the moodle internal file system.
269
        $fullpath = "/{$syscontext->id}/" . 'edusharing' . "/{$settingname}/0{$filename}";
270
        // Get an instance of the moodle file storage.
271
        $fs = get_file_storage();
272
        // This is an efficient way to get a file if we know the exact path.
273
        if ($file = $fs->get_file_by_hash(sha1($fullpath))) {
274
            // We got the stored file - copy it to data root.
275
            // This location matches the searched for location in theme_config::resolve_image_location.
276
            $pathname = $CFG->dataroot . '/pix_plugins/mod/edusharing/icon.' . $extension;
277
            // This pattern matches any previous files with maybe different file extensions.
278
            $pathpattern = $CFG->dataroot . '/pix_plugins/mod/edusharing/icon.*';
279
            // Make sure this dir exists.
280
            @mkdir($CFG->dataroot . '/pix_plugins/mod/edusharing/', $CFG->directorypermissions, true);
281
            // Delete any existing files for this setting.
282
            foreach (glob($pathpattern) as $filename) {
283
                @unlink($filename);
284
            }
285
            // Copy the current file to this location.
286
            $file->copy_content_to($pathname);
287
        } else {
288
            $pathpattern = $CFG->dataroot . '/pix_plugins/mod/edusharing/icon.*';
289
            // Make sure this dir exists.
290
            @mkdir($CFG->dataroot . '/pix_plugins/mod/edusharing/', $CFG->directorypermissions, true);
291
            // Delete any existing files for this setting.
292
            foreach (glob($pathpattern) as $filename) {
293
                @unlink($filename);
294
            }
295
        }
296
        // Reset theme caches.
297
        theme_reset_all_caches();
298
    }
299
 
300
    /**
301
     * Function get_course_module_info
302
     *
303
     * @param stdClass $coursemodule
304
     * @return cached_cm_info|bool
305
     */
306
    public function get_course_module_info(stdClass $coursemodule): cached_cm_info|bool {
307
        global $DB;
308
        try {
309
            $edusharing = $DB->get_record(
310
                'edusharing',
311
                ['id' => $coursemodule->instance],
312
                'id, name, intro, introformat',
313
                MUST_EXIST
314
            );
315
        } catch (Exception $exception) {
316
            debugging($exception->getMessage());
317
            return false;
318
        }
319
        $info = new cached_cm_info();
320
        if ($coursemodule->showdescription) {
321
            // Convert intro to html. Do not filter cached version, filters run at display time.
322
            $info->content = format_module_intro('edusharing', $edusharing, $coursemodule->id, false);
323
        }
324
        try {
325
            $resource = $DB->get_record('edusharing', ['id' => $coursemodule->instance], '*', MUST_EXIST);
326
            if (!empty($resource->popup_window)) {
327
                $info->onclick = 'this.target=\'_blank\';';
328
            }
329
        } catch (Exception $exception) {
330
            debugging($exception->getMessage());
331
        }
332
        return $info;
333
    }
334
 
335
    /**
336
     * Function get_inline_object_matches
337
     *
338
     * @param string $inputtext
339
     * @return array
340
     */
341
    public function get_inline_object_matches(string $inputtext): array {
342
        $contenttype = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
343
        $dom = new DOMDocument();
344
        $dom->loadHTML($contenttype . $inputtext, LIBXML_NOERROR);
345
        $allelements = $dom->getElementsByTagName("*");
346
        $matches = [];
347
        foreach ($allelements as $item) {
348
            $classes = $item->attributes->getNamedItem('class')->nodeValue ?? '';
349
            if (str_contains($classes, 'edusharing_atto')) {
350
                $matches[] = $dom->saveHTML($item);
351
            }
352
        }
353
        return $matches;
354
    }
355
 
356
    /**
357
     * Function get_config_entry
358
     *
359
     * @param string $name
360
     * @return mixed
361
     * @throws dml_exception
362
     */
363
    public function get_config_entry(string $name): mixed {
364
        return $this->appconfig->get($name);
365
    }
366
 
367
    /**
368
     * Function set_config_entry
369
     *
370
     * @param string $name
371
     * @param mixed $value
372
     * @return void
373
     */
374
    public function set_config_entry(string $name, mixed $value): void {
375
        $this->appconfig->set($name, $value);
376
    }
377
 
378
    /**
379
     * Function get_internal_url
380
     *
381
     * Retrieves the internal URL from config.
382
     *
383
     * @return string
384
     */
385
    public function get_internal_url(): string {
386
        try {
387
            $internalurl = $this->appconfig->get('application_docker_network_url');
388
            if (empty($internalurl)) {
389
                $internalurl = $this->appconfig->get('application_cc_gui_url');
390
            }
391
            return rtrim($internalurl, '/');
392
        } catch (Exception $exception) {
393
            debugging($exception->getMessage());
394
            unset($exception);
395
        }
396
        return '';
397
    }
398
}