AutorÃa | Ultima modificación | Ver Log |
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace mod_edusharing;
use coding_exception;
use dml_exception;
use DOMDocument;
use EduSharingApiClient\MissingRightsException;
use EduSharingApiClient\Usage;
use Exception;
use moodle_exception;
use stdClass;
/**
* Class RestoreHelper
*
* @author Marian Ziegler <ziegler@edu-sharing.net>
* @package mod_edusharing
*/
class RestoreHelper {
/**
* @var EduSharingService
*/
private EduSharingService $service;
/**
* @var UtilityFunctions
*/
private UtilityFunctions $utils;
/**
* RestoreHelper constructor
*
* @param EduSharingService $service
*/
public function __construct(EduSharingService $service) {
$this->service = $service;
$this->init();
}
/**
* Function init
*
* @return void
*/
private function init(): void {
$this->utils = new UtilityFunctions();
}
/**
* Function convert_inline_options
*
* @param int $courseid
* @return void
*
* @throws coding_exception
* @throws dml_exception
* @throws moodle_exception
*/
public function convert_inline_options($courseid): void {
global $DB;
$sections = $DB->get_records('course_sections', ['course' => $courseid]);
foreach ($sections as $section) {
$esmatches = $this->get_inline_objects($section->summary ?? '');
if (!empty($esmatches)) {
foreach ($esmatches as $match) {
$section->summary = str_replace($match, $this->convert_object($match, $courseid), $section->summary);
$DB->update_record('course_sections', $section);
}
}
}
$modules = get_course_mods($courseid);
$course = get_course($courseid);
foreach ($modules as $module) {
$modinfo = get_fast_modinfo($course);
$cm = $modinfo->get_cm($module->id);
if (!empty($cm->content)) {
$esmatches = $this->get_inline_objects($cm->content);
if (!empty($esmatches)) {
foreach ($esmatches as $match) {
$cm->set_content(str_replace($match, $this->convert_object($match, $courseid), $cm->content));
}
}
}
try {
$module = $DB->get_record($cm->name, ['id' => $cm->instance], '*', MUST_EXIST);
} catch (Exception $exception) {
debugging($exception->getMessage());
continue;
}
if (!empty($module->intro)) {
$esmatches = $this->get_inline_objects($module->intro);
if (!empty($esmatches)) {
foreach ($esmatches as $match) {
$module->intro = str_replace($match, $this->convert_object($match, $courseid), $module->intro);
}
}
}
$DB->update_record($cm->name, $module);
}
rebuild_course_cache((int)$courseid, true);
}
/**
* Function get_inline_objects
*
* @param string $text
* @return array
*/
private function get_inline_objects(string $text): array {
if (!str_contains($text, 'edusharing_atto')) {
return [];
}
if (isloggedin()) {
try {
$this->service->get_ticket();
} catch (Exception $exception) {
trigger_error($exception->getMessage(), E_USER_WARNING);
return [];
}
}
return $this->utils->get_inline_object_matches($text);
}
/**
* Function convert_object
*
* @param mixed $object
* @param mixed $courseid
* @return mixed
* @throws coding_exception
* @throws dml_exception
* @throws Exception
*/
private function convert_object($object, $courseid): string {
global $DB;
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadHTML($object, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$errors = libxml_get_errors();
if (!empty($errors)) {
debugging("Html parsing error(s): " . json_encode($errors));
debugging($object);
return get_string('error_parsing_on_restore', 'edusharing');
}
$node = $doc->getElementsByTagName('a')->item(0);
$type = 'a';
if (empty($node)) {
$node = $doc->getElementsByTagName('img')->item(0);
$qs = $node->getAttribute('src');
$type = 'img';
} else {
$qs = $node->getAttribute('href');
}
if (empty($node)) {
throw new Exception(get_string('error_loading_node', 'filter_edusharing'));
}
$params = [];
$queryparams = parse_url($qs, PHP_URL_QUERY);
if (empty($queryparams)) {
debugging("ES object url could not be retrieved or parsed.");
debugging($object);
return get_string('error_parsing_on_restore', 'edusharing');
}
parse_str($queryparams, $params);
$edusharing = new stdClass();
$edusharing->course = $courseid;
$edusharing->name = $params['title'];
$edusharing->introformat = 0;
$edusharing->object_url = $params['object_url'];
$edusharing->object_version = $params['window_version'];
$edusharing->timecreated = time();
$edusharing->timemodified = time();
$id = $DB->insert_record('edusharing', $edusharing);
if ($id !== false) {
try {
$usage = $this->add_usage($edusharing, $id);
} catch (MissingRightsException $missingrightsexception) {
unset($missingrightsexception);
return get_string('error_missing_rights_on_restore', 'edusharing') . ': ' . ($params['nodeId'] ?? 'blank nodeId');
} catch (Exception $exception) {
unset($exception);
return get_string('error_unexpected_on_restore', 'edusharing') . ': ' . ($params['nodeId'] ?? 'blank nodeId');
}
if ($usage !== null) {
if (isset($usage->usageId)) {
$edusharing->id = $id;
$edusharing->usageId = $usage->usageId;
$DB->update_record(Constants::EDUSHARING_TABLE, $edusharing);
}
$params['resourceId'] = $id;
$url = strtok($qs, '?') . '?';
foreach ($params as $paramn => $paramv) {
$url .= $paramn . '=' . $paramv . '&';
}
$node->setAttribute($type === 'a' ? 'href' : 'src', $url);
} else {
$DB->delete_records('edusharing', ['id' => $id]);
return $object;
}
}
return $doc->saveHTML();
}
/**
* Function add_usage
*
* @param stdClass $data
* @param int $newitemid
* @return Usage|null
* @throws \JsonException
* @throws Exception
* @throws MissingRightsException
*/
public function add_usage(stdClass $data, int $newitemid): ?Usage {
$usagedata = new stdClass();
$usagedata->containerId = $data->course;
$usagedata->resourceId = $newitemid;
$utils = new UtilityFunctions();
$usagedata->nodeId = $utils->get_object_id_from_url($data->object_url);
$usagedata->nodeVersion = $data->object_version;
return $this->service->create_usage($usagedata);
}
}