From a419c75d114408d114d33b0c115b36d86bbb52b1 Mon Sep 17 00:00:00 2001 From: Lai Wei Date: Fri, 12 Jun 2026 16:01:33 +0100 Subject: [PATCH] Fix "Event not exist" error when editing a meeting link after saving in Tiny editor --- .../classes/external/get_meeting_details.php | 14 ++++++++++++- .../tiny/plugins/teamsmeeting/db/upgrade.php | 15 +++++++++++++ .../tiny/plugins/teamsmeeting/result.php | 21 ++++++++++++++++--- .../tiny/plugins/teamsmeeting/version.php | 4 ++-- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/lib/editor/tiny/plugins/teamsmeeting/classes/external/get_meeting_details.php b/lib/editor/tiny/plugins/teamsmeeting/classes/external/get_meeting_details.php index 67fe7497b..0a44ada2f 100644 --- a/lib/editor/tiny/plugins/teamsmeeting/classes/external/get_meeting_details.php +++ b/lib/editor/tiny/plugins/teamsmeeting/classes/external/get_meeting_details.php @@ -111,7 +111,19 @@ public static function execute(string $url): array { private static function get_meeting(string $url): ?stdClass { global $DB; - $record = $DB->get_record('tiny_teamsmeeting', ['linkhash' => sha1($url)]); + // Normalise percent-encoding to uppercase before hashing so lookups + // succeed whether or not Moodle re-saved the HTML (which uppercases %xx). + $normalised = preg_replace_callback('/%[0-9a-f]{2}/i', fn($m) => strtoupper($m[0]), $url); + $record = $DB->get_record('tiny_teamsmeeting', ['linkhash' => sha1($normalised)]); + + if (!$record) { + // Fallback for rows created before normalisation: try lowercase hex digits. + $lowercased = preg_replace_callback('/%[0-9A-F]{2}/', fn($m) => strtolower($m[0]), $normalised); + if ($lowercased !== $normalised) { + $record = $DB->get_record('tiny_teamsmeeting', ['linkhash' => sha1($lowercased)]); + } + } + return $record ?: null; } diff --git a/lib/editor/tiny/plugins/teamsmeeting/db/upgrade.php b/lib/editor/tiny/plugins/teamsmeeting/db/upgrade.php index 43403f2cc..34427a981 100644 --- a/lib/editor/tiny/plugins/teamsmeeting/db/upgrade.php +++ b/lib/editor/tiny/plugins/teamsmeeting/db/upgrade.php @@ -121,5 +121,20 @@ function xmldb_tiny_teamsmeeting_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2025100207, 'tiny', 'teamsmeeting'); } + if ($oldversion < 2025100307.01) { + // Recompute linkhash using percent-encoding-normalised URLs so that + // hashes are stable regardless of whether Moodle has uppercased %xx + // sequences when saving HTML content (RFC 3986 normalisation). + $records = $DB->get_records('tiny_teamsmeeting', null, 'id ASC', 'id, link'); + foreach ($records as $record) { + $normalised = preg_replace_callback('/%[0-9a-f]{2}/i', fn($m) => strtoupper($m[0]), $record->link); + $DB->set_field('tiny_teamsmeeting', 'linkhash', sha1($normalised), ['id' => $record->id]); + $DB->set_field('tiny_teamsmeeting', 'link', $normalised, ['id' => $record->id]); + } + unset($records); + + upgrade_plugin_savepoint(true, 2025100307.01, 'tiny', 'teamsmeeting'); + } + return true; } diff --git a/lib/editor/tiny/plugins/teamsmeeting/result.php b/lib/editor/tiny/plugins/teamsmeeting/result.php index ce0b356bb..6bf62db70 100644 --- a/lib/editor/tiny/plugins/teamsmeeting/result.php +++ b/lib/editor/tiny/plugins/teamsmeeting/result.php @@ -30,6 +30,12 @@ $courseid = optional_param('courseid', 0, PARAM_INT); $viewexisting = optional_param('viewexisting', 0, PARAM_INT); $meetinglink = optional_param('link', null, PARAM_URL); +// Normalise percent-encoding to uppercase (RFC 3986) so the SHA1 hash is +// stable regardless of whether Moodle has re-saved the HTML (which uppercases +// %xx sequences) since the meeting was first created. +if ($meetinglink !== null) { + $meetinglink = preg_replace_callback('/%[0-9a-f]{2}/i', fn($m) => strtoupper($m[0]), $meetinglink); +} $title = optional_param('title', null, PARAM_TEXT); $preview = optional_param('preview', null, PARAM_CLEANHTML); $optionslink = optional_param('options', null, PARAM_URL); @@ -37,9 +43,18 @@ if ($viewexisting) { require_sesskey(); - $viewrecord = $meetinglink - ? $DB->get_record('tiny_teamsmeeting', ['linkhash' => sha1($meetinglink)]) - : null; + if ($meetinglink) { + $viewrecord = $DB->get_record('tiny_teamsmeeting', ['linkhash' => sha1($meetinglink)]); + if (!$viewrecord) { + // Fallback for rows stored before normalisation (lowercase hex in %xx sequences). + $lowercased = preg_replace_callback('/%[0-9A-F]{2}/', fn($m) => strtolower($m[0]), $meetinglink); + if ($lowercased !== $meetinglink) { + $viewrecord = $DB->get_record('tiny_teamsmeeting', ['linkhash' => sha1($lowercased)]); + } + } + } else { + $viewrecord = null; + } $context = ($viewrecord && !empty($viewrecord->contextid)) ? context::instance_by_id($viewrecord->contextid) : context_system::instance(); diff --git a/lib/editor/tiny/plugins/teamsmeeting/version.php b/lib/editor/tiny/plugins/teamsmeeting/version.php index a2df09b8f..2ad457c2c 100644 --- a/lib/editor/tiny/plugins/teamsmeeting/version.php +++ b/lib/editor/tiny/plugins/teamsmeeting/version.php @@ -25,8 +25,8 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2025100306; +$plugin->version = 2025100307.01; $plugin->requires = 2025040800; -$plugin->release = '5.0.6'; +$plugin->release = '5.0.7'; $plugin->component = 'tiny_teamsmeeting'; $plugin->maturity = MATURITY_STABLE;