From fc8aa440600a10dbc7c82fb63a5fcfa3de8cbf70 Mon Sep 17 00:00:00 2001 From: Daniel Poggenpohl Date: Wed, 17 Jun 2026 13:37:23 +0200 Subject: [PATCH 01/16] fix / GH#597 json_decode called with null The database field is either null or a string. So decode strings and else set null. --- classes/editor_framework.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/classes/editor_framework.php b/classes/editor_framework.php index 4822f3bd2..df1ffb5f4 100644 --- a/classes/editor_framework.php +++ b/classes/editor_framework.php @@ -138,7 +138,8 @@ public function getLibraries($libraries = null) { $library->title = $details->title; $library->runnable = $details->runnable; $library->restricted = $superuser ? false : ($details->restricted === '1' ? true : false); - $library->metadataSettings = json_decode($details->metadata_settings); + $library->metadataSettings = + is_string($details->metadata_settings) ? json_decode($details->metadata_settings) : null; $librarieswithdetails[] = $library; } } From 1e514f40995281f39cc8c3d080963b1c94f71ed4 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Fri, 19 Jun 2026 13:12:36 +0200 Subject: [PATCH 02/16] AU-7178 Fix editor placed on top of sticky footer --- editor.css | 4 ++++ locallib.php | 1 + 2 files changed, 5 insertions(+) create mode 100644 editor.css diff --git a/editor.css b/editor.css new file mode 100644 index 000000000..5d27bd890 --- /dev/null +++ b/editor.css @@ -0,0 +1,4 @@ +#fgroup_id_h5peditor { + z-index: 1; + position: relative; +} \ No newline at end of file diff --git a/locallib.php b/locallib.php index 95974b517..f8282cefe 100644 --- a/locallib.php +++ b/locallib.php @@ -181,6 +181,7 @@ function hvp_add_editor_assets($id = null, $mformid = null) { $PAGE->requires->js(new moodle_url('/mod/hvp/editor/scripts/h5peditor-editor.js' . $cachebuster), true); $PAGE->requires->js(new moodle_url('/mod/hvp/editor/scripts/h5peditor-init.js' . $cachebuster), true); $PAGE->requires->js(new moodle_url('/mod/hvp/editor.js' . $cachebuster), true); + $PAGE->requires->css(new moodle_url('/mod/hvp/editor.css' . $cachebuster), true); // Add translations. $language = \mod_hvp\framework::get_language(); From f3721700ed7a310cf6493e0f800bea118ae1919a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luca=20B=C3=B6sch?= Date: Sun, 12 Apr 2026 09:22:39 +0200 Subject: [PATCH 03/16] =?UTF-8?q?For=20Moodle=20=E2=89=A4=203.11,=20define?= =?UTF-8?q?=20MESSAGE=5FDEFAULT=5FENABLED.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/messages.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/db/messages.php b/db/messages.php index 0fd534489..4871eef59 100644 --- a/db/messages.php +++ b/db/messages.php @@ -24,6 +24,11 @@ defined('MOODLE_INTERNAL') || die(); +// For versions of Moodle prior to 4.0, we need to define that constant here. +if (!defined('MESSAGE_DEFAULT_ENABLED')) { + define('MESSAGE_DEFAULT_ENABLED', 0x01); +} + $messageproviders = array( // Notify teacher that a student has submitted an attempt. 'submission' => array( From 91ea3032d1edcd59d44dce3f2554e861296c01e6 Mon Sep 17 00:00:00 2001 From: Oliver Tacke Date: Tue, 30 Jun 2026 10:08:18 +0200 Subject: [PATCH 04/16] Add extraTableClasses to work with Bootstrap 5 --- locallib.php | 1 + 1 file changed, 1 insertion(+) diff --git a/locallib.php b/locallib.php index 95974b517..d2172af8d 100644 --- a/locallib.php +++ b/locallib.php @@ -261,6 +261,7 @@ function hvp_admin_add_generic_css_and_js($page, $liburl, $settings = null) { 'deleteLibrary' => '', 'upgradeLibrary' => get_string('upgradelibrarycontent', 'hvp') ); + $settings['extraTableClasses'] = 'table-reboot'; $page->requires->data_for_js('H5PAdminIntegration', $settings, true); $page->requires->css(new moodle_url($liburl . 'styles/h5p.css' . hvp_get_cache_buster())); From a7a10eff85a5d22e85e7f2de07b635476ccc2420 Mon Sep 17 00:00:00 2001 From: thisismyurl <122108986+thisismyurl@users.noreply.github.com> Date: Mon, 27 Jul 2026 09:41:19 -0400 Subject: [PATCH 05/16] fix / Remove deprecated FEATURE_GROUPMEMBERSONLY from hvp_supports() FEATURE_GROUPMEMBERSONLY was deprecated in Moodle 2.9 (MDL-44725) when the "group members only" access control was superseded by the availability system, and it is being removed from core entirely (MDL-83231). Listing it as a supported feature in hvp_supports() causes an undefined-constant fatal on Moodle 5.3+, which blocks the plugin from upgrading. Core no longer queries plugins for this feature, so the case can be removed rather than replaced; behaviour on supported older versions is unchanged. closes https://github.com/h5p/moodle-mod_hvp/issues/636 Co-Authored-By: Claude Opus 4.8 --- lib.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib.php b/lib.php index c16286dbe..b73bec1bb 100644 --- a/lib.php +++ b/lib.php @@ -52,8 +52,6 @@ function hvp_supports($feature) { return true; case FEATURE_GROUPINGS: return true; - case FEATURE_GROUPMEMBERSONLY: - return true; case FEATURE_MOD_INTRO: return true; case FEATURE_COMPLETION_TRACKS_VIEWS: From 0aad9f1034536c7bc860b1d5902aa276431f76db Mon Sep 17 00:00:00 2001 From: Philipp Memmel Date: Wed, 5 Aug 2026 08:52:23 +0200 Subject: [PATCH 06/16] MBS-10983: fix / Make look_for_updates task handle errors properly --- classes/task/look_for_updates.php | 53 ++++++++++---- lang/en/hvp.php | 7 ++ lib.php | 2 - tests/look_for_updates_test.php | 110 ++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 16 deletions(-) create mode 100644 tests/look_for_updates_test.php diff --git a/classes/task/look_for_updates.php b/classes/task/look_for_updates.php index 9f2aa09d6..6754c3e00 100644 --- a/classes/task/look_for_updates.php +++ b/classes/task/look_for_updates.php @@ -13,20 +13,11 @@ // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Defines the task which looks for H5P updates. - * - * @package mod_hvp - * @copyright 2016 Joubel AS - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ namespace mod_hvp\task; -defined('MOODLE_INTERNAL') || die(); - /** - * The mod_hvp look for updates task class + * Defines the task which looks for H5P updates. * * @package mod_hvp * @copyright 2016 Joubel AS @@ -38,10 +29,44 @@ public function get_name() { } public function execute() { - // Check to make sure external communications hasn't been disabled. - if (get_config('mod_hvp', 'hub_is_enabled') || get_config('mod_hvp', 'send_usage_statistics')) { - $core = \mod_hvp\framework::instance(); - $core->fetchLibrariesMetadata(); + // Check to make sure external communications have not been disabled. + if (!get_config('mod_hvp', 'hub_is_enabled') && !get_config('mod_hvp', 'send_usage_statistics')) { + mtrace(get_string('lookforupdatesskippeddisabledlog', 'mod_hvp')); + return; + } + + $core = \mod_hvp\framework::instance(); + $result = $core->fetchLibrariesMetadata(); + + if ($result === false) { + mtrace(get_string('fetchlibrariesmetadatafailedlog', 'mod_hvp')); + } else if (is_object($result)) { + $librariescount = 0; + if (isset($result->libraries) && is_array($result->libraries)) { + $librariescount = count($result->libraries); + } + mtrace(get_string('fetchlibrariesmetadatasuccesslog', 'mod_hvp', $librariescount)); + } else { + mtrace(get_string('fetchlibrariesmetadataunexpectedlog', 'mod_hvp')); + } + + $errors = \mod_hvp\framework::messages('error'); + foreach ($errors as $error) { + $code = $error->code ?? 'N/A'; + $text = $error->message ?? 'N/A'; + mtrace(get_string('fetchlibrariesmetadataerrorlog', 'mod_hvp', (object) [ + 'code' => $code, + 'message' => $text, + ])); + } + + $infos = \mod_hvp\framework::messages('info'); + foreach ($infos as $info) { + mtrace(get_string('fetchlibrariesmetadatainfolog', 'mod_hvp', $info)); + } + + if ($result === false) { + throw new \moodle_exception('fetchlibrariesmetadatafailed', 'mod_hvp'); } } } diff --git a/lang/en/hvp.php b/lang/en/hvp.php index 9101622f8..7d6a9bea6 100644 --- a/lang/en/hvp.php +++ b/lang/en/hvp.php @@ -58,6 +58,13 @@ $string['noh5ps'] = 'There\'s no interactive content available for this course.'; $string['lookforupdates'] = 'Look for H5P updates'; +$string['fetchlibrariesmetadatafailed'] = 'Failed to fetch H5P libraries metadata.'; +$string['fetchlibrariesmetadatafailedlog'] = 'Fetching H5P content types from the Hub failed.'; +$string['fetchlibrariesmetadatasuccesslog'] = 'H5P Hub request completed successfully ({$a} content types in the response).'; +$string['fetchlibrariesmetadataunexpectedlog'] = 'H5P Hub request returned an unexpected response.'; +$string['fetchlibrariesmetadataerrorlog'] = 'H5P Hub error: [code: {$a->code}, message: {$a->message}]'; +$string['fetchlibrariesmetadatainfolog'] = 'H5P Hub notice: {$a}'; +$string['lookforupdatesskippeddisabledlog'] = 'Task skipped: both H5P Hub and usage statistics are disabled.'; $string['updatelibraries'] = 'Update All Libraries'; $string['removetmpfiles'] = 'Remove old H5P temporary files'; $string['removeoldlogentries'] = 'Remove old H5P log entries'; diff --git a/lib.php b/lib.php index c16286dbe..b73bec1bb 100644 --- a/lib.php +++ b/lib.php @@ -52,8 +52,6 @@ function hvp_supports($feature) { return true; case FEATURE_GROUPINGS: return true; - case FEATURE_GROUPMEMBERSONLY: - return true; case FEATURE_MOD_INTRO: return true; case FEATURE_COMPLETION_TRACKS_VIEWS: diff --git a/tests/look_for_updates_test.php b/tests/look_for_updates_test.php new file mode 100644 index 000000000..5997ce387 --- /dev/null +++ b/tests/look_for_updates_test.php @@ -0,0 +1,110 @@ +. + +namespace mod_hvp; + +/** + * Unit tests for look_for_updates scheduled task. + * + * @package mod_hvp + * @copyright 2026 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \mod_hvp\task\look_for_updates + */ +final class look_for_updates_test extends \advanced_testcase { + /** + * Verifies + * - that the task exits early exactly when both hub_is_enabled and send_usage_statistics_setting are disabled + * - that the task does proper error handling and logging + * + * @dataProvider execute_provider + * @param int $hubisenabled Hub setting value. + * @param int $sendusagestatistics Usage statistics setting value. + * @param bool $expectearlyexit Whether execute() is expected to return via early-exit. + */ + public function test_execute( + int $hubisenabled, + int $sendusagestatistics, + bool $expectearlyexit, + ): void { + $this->resetAfterTest(); + + set_config('hub_is_enabled', $hubisenabled, 'mod_hvp'); + set_config('send_usage_statistics', $sendusagestatistics, 'mod_hvp'); + // Keep site unregistered so all non-early-exit paths fail deterministically at registration. + set_config('site_uuid', '', 'mod_hvp'); + + if ($hubisenabled || $sendusagestatistics) { + // Force deterministic no-network behavior for all non-early-exit cases. + \curl::mock_response(''); + } + + $task = new \mod_hvp\task\look_for_updates(); + + ob_start(); + try { + $task->execute(); + $output = ob_get_clean(); + if (!$expectearlyexit) { + $this->fail('Expected moodle_exception for failed metadata fetch. Output: ' . $output); + } + } catch (\moodle_exception $exception) { + $output = ob_get_clean(); + if ($expectearlyexit) { + $this->fail('Did not expect moodle_exception. Got: ' . $exception->errorcode); + } + $this->assertEquals('fetchlibrariesmetadatafailed', $exception->errorcode); + } + + if ($expectearlyexit) { + $this->assertStringContainsString(get_string('lookforupdatesskippeddisabledlog', 'mod_hvp'), $output); + } else { + $this->assertStringContainsString(get_string('fetchlibrariesmetadatafailedlog', 'mod_hvp'), $output); + $this->assertStringContainsString('registration-failed-hub-disabled', $output); + $this->assertStringNotContainsString(get_string('lookforupdatesskippeddisabledlog', 'mod_hvp'), $output); + } + } + + /** + * Data provider for test_execute_setting_combinations. + * + * @return array + */ + public static function execute_provider(): array { + return [ + 'both_disabled' => [ + 'hubisenabled' => 0, + 'sendusagestatistics' => 0, + 'expectearlyexit' => true, + ], + 'hub_enabled_only' => [ + 'hubisenabled' => 1, + 'sendusagestatistics' => 0, + 'expectearlyexit' => false, + ], + 'usage_statistics_enabled_only' => [ + 'hubisenabled' => 0, + 'sendusagestatistics' => 1, + 'expectearlyexit' => false, + ], + 'both_enabled' => [ + 'hubisenabled' => 1, + 'sendusagestatistics' => 1, + 'expectearlyexit' => false, + ], + ]; + } +} From fb840b5945dd3950f793767fbba3de34b927399f Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Mon, 10 Aug 2026 10:32:16 +0200 Subject: [PATCH 07/16] Update editor + reporting with latest fixes --- editor | 2 +- reporting | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/editor b/editor index 73dfed607..bc2385092 160000 --- a/editor +++ b/editor @@ -1 +1 @@ -Subproject commit 73dfed6073b8916faa7e8b1a5fca5adb2bde5dc4 +Subproject commit bc2385092fd66a190afc6acd60551184f6b132ee diff --git a/reporting b/reporting index 3f77492cf..2df4ef30f 160000 --- a/reporting +++ b/reporting @@ -1 +1 @@ -Subproject commit 3f77492cf2d8838056eb58f2bd5d67d91e346002 +Subproject commit 2df4ef30f258866c3fdd26636b117058a195def3 From a4029b4e690eb65091cc755b8f112e07410ca6d7 Mon Sep 17 00:00:00 2001 From: Maris Date: Thu, 13 Aug 2026 12:39:24 +0200 Subject: [PATCH 08/16] Prepare for release 1.28.3 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index b308be576..54b7eb89a 100644 --- a/version.php +++ b/version.php @@ -23,9 +23,9 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2026062500; +$plugin->version = 2026081300; $plugin->requires = 2013051403; $plugin->cron = 0; $plugin->component = 'mod_hvp'; $plugin->maturity = MATURITY_STABLE; -$plugin->release = '1.28.2'; +$plugin->release = '1.28.3'; From f0530733ad3d45720a840f7ee0e71162656d25b4 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Fri, 14 Aug 2026 13:22:07 +0200 Subject: [PATCH 09/16] AU-8017 Add option to re-upgrade subcontent This can be used to fix content that was lost during a previous content upgrade --- library | 2 +- library_list.php | 10 +++++++--- locallib.php | 2 +- upgrade_content_page.php | 8 +++++--- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/library b/library index 39d37abd4..fd040690b 160000 --- a/library +++ b/library @@ -1 +1 @@ -Subproject commit 39d37abd4c247e07164a26604581f8553ab3c893 +Subproject commit fd040690b2cf964d85cb11f3389a216ba529b918 diff --git a/library_list.php b/library_list.php index 3d950ae16..61bd517b4 100644 --- a/library_list.php +++ b/library_list.php @@ -28,6 +28,8 @@ // No guest autologin. require_login(0, false); +$fixsubcontent = optional_param('fix_subcontent', false, PARAM_BOOL); // Special fix to re-run upgrade for subcontent only + $pageurl = new moodle_url('/mod/hvp/library_list.php'); $PAGE->set_url($pageurl); @@ -67,11 +69,13 @@ $i = 0; foreach ($libraries as $versions) { foreach ($versions as $library) { + $numContent = $core->h5pF->getNumContent($library->id); $usage = $core->h5pF->getLibraryUsage($library->id, $numnotfiltered ? true : false); if ($library->runnable) { $upgrades = $core->getUpgrades($library, $versions); - $upgradeurl = empty($upgrades) ? false : (new moodle_url('/mod/hvp/upgrade_content_page.php', array( - 'library_id' => $library->id + $upgradeurl = ($fixsubcontent ? empty($numContent) : empty($upgrades)) ? false : (new moodle_url('/mod/hvp/upgrade_content_page.php', array( + 'library_id' => $library->id, + 'fix_subcontent' => $fixsubcontent )))->out(false); $restricted = (isset($library->restricted) && $library->restricted == 1 ? true : false); @@ -91,7 +95,7 @@ 'title' => $library->title . ' (' . \H5PCore::libraryVersion($library) . ')', 'restricted' => $restricted, 'restrictedUrl' => $restrictedurl, - 'numContent' => $core->h5pF->getNumContent($library->id), + 'numContent' => $numContent, 'numContentDependencies' => $usage['content'] === -1 ? '' : $usage['content'], 'numLibraryDependencies' => $usage['libraries'], 'upgradeUrl' => $upgradeurl, diff --git a/locallib.php b/locallib.php index 9ed572086..1ac2588d8 100644 --- a/locallib.php +++ b/locallib.php @@ -429,7 +429,7 @@ function hvp_get_library_upgrade_info($name, $major, $minor) { $response->upgradesScript = "{$basepath}pluginfile.php/{$context->id}/mod_hvp/libraries/{$libraryfoldername}/upgrades.js"; } $response->semantics = $core->loadLibrarySemantics($name, $major, $minor); - + return $response; } diff --git a/upgrade_content_page.php b/upgrade_content_page.php index 5a549a14a..67e0d060b 100644 --- a/upgrade_content_page.php +++ b/upgrade_content_page.php @@ -29,6 +29,7 @@ require_login(0, false); $libraryid = required_param('library_id', PARAM_INT); +$fixsubcontent = optional_param('fix_subcontent', false, PARAM_BOOL); // Special fix to re-run upgrade for subcontent only $pageurl = new moodle_url('/mod/hvp/upgrade_content_page.php', array('library_id' => $libraryid)); $PAGE->set_url($pageurl); admin_externalpage_setup('h5plibraries'); @@ -73,7 +74,7 @@ 'errorTooHighVersion' => get_string('upgradeerrortoohighversion', 'hvp'), 'errorNotSupported' => get_string('upgradeerrornotsupported', 'hvp'), 'done' => get_string('upgradedone', 'hvp', $numcontents) . - ' ' . + ' ' . get_string('upgradereturn', 'hvp') . '', 'library' => array( 'name' => $library->name, @@ -83,13 +84,14 @@ array('action' => 'getlibrarydataforupgrade')))->out(false) . '&library=', 'scriptBaseUrl' => (new moodle_url('/mod/hvp/library/js'))->out(false), 'buster' => hvp_get_cache_buster(), - 'versions' => $upgrades, + 'versions' => true ? [$libraryid => \H5PCore::libraryVersion($versions[$libraryid])] : $upgrades, 'contents' => $numcontents, 'buttonLabel' => get_string('upgradebuttonlabel', 'hvp'), 'infoUrl' => (new moodle_url('/mod/hvp/ajax.php', array('action' => 'libraryupgradeprogress', 'library_id' => $libraryid)))->out(false), 'total' => $numcontents, - 'token' => \H5PCore::createToken('contentupgrade') + 'token' => \H5PCore::createToken('contentupgrade'), + 'fixSubContent' => !!$fixsubcontent, ) ); From 98e26a1d709cd5cbe48f78a7d72f20d630ae611e Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Fri, 14 Aug 2026 14:14:50 +0200 Subject: [PATCH 10/16] AU-8017 Fix regular content upgrade... --- upgrade_content_page.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upgrade_content_page.php b/upgrade_content_page.php index 67e0d060b..bf03871ca 100644 --- a/upgrade_content_page.php +++ b/upgrade_content_page.php @@ -84,7 +84,7 @@ array('action' => 'getlibrarydataforupgrade')))->out(false) . '&library=', 'scriptBaseUrl' => (new moodle_url('/mod/hvp/library/js'))->out(false), 'buster' => hvp_get_cache_buster(), - 'versions' => true ? [$libraryid => \H5PCore::libraryVersion($versions[$libraryid])] : $upgrades, + 'versions' => $fixsubcontent ? [$libraryid => \H5PCore::libraryVersion($versions[$libraryid])] : $upgrades, 'contents' => $numcontents, 'buttonLabel' => get_string('upgradebuttonlabel', 'hvp'), 'infoUrl' => (new moodle_url('/mod/hvp/ajax.php', array('action' => 'libraryupgradeprogress', From 2d3873215cfa946557cccfd08d68467a93d782d6 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Fri, 14 Aug 2026 15:06:30 +0200 Subject: [PATCH 11/16] AU-8017 Fix using content ID to track upgrade process --- classes/framework.php | 6 +++--- library | 2 +- locallib.php | 10 ++++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/classes/framework.php b/classes/framework.php index 5a2db4516..258a17499 100644 --- a/classes/framework.php +++ b/classes/framework.php @@ -1596,13 +1596,13 @@ public function getNumNotFiltered() { * Implements getNumContent(). */ // @codingStandardsIgnoreLine - public function getNumContent($libraryid, $skip = NULL) { + public function getNumContent($libraryid, $skip = NULL, $lastid = 0) { global $DB; $skipquery = empty($skip) ? '' : " AND id NOT IN ($skip)"; return (int) $DB->get_field_sql( - "SELECT COUNT(id) FROM {hvp} WHERE main_library_id = ?{$skipquery}", - array($libraryid)); + "SELECT COUNT(id) FROM {hvp} WHERE main_library_id = ? AND id > ?{$skipquery}", + array($libraryid, $lastid)); } /** diff --git a/library b/library index fd040690b..570db67ae 160000 --- a/library +++ b/library @@ -1 +1 @@ -Subproject commit fd040690b2cf964d85cb11f3389a216ba529b918 +Subproject commit 570db67ae637a89e0301b54b3949439e3811bf43 diff --git a/locallib.php b/locallib.php index 1ac2588d8..c1dd8a18e 100644 --- a/locallib.php +++ b/locallib.php @@ -375,8 +375,13 @@ function hvp_content_upgrade_progress($libraryid) { $out->skipped = array(); } + $lastid = filter_input(INPUT_POST, 'lastId'); + if (empty($lastid) || $lastid != intval($lastid)) { + $lastid = 0; + } + // Get number of contents for this library. - $out->left = $interface->getNumContent($libraryid, $skipped); + $out->left = $interface->getNumContent($libraryid, $skipped, $lastid); if ($out->left) { $skipquery = empty($skipped) ? '' : " AND id NOT IN ($skipped)"; @@ -388,8 +393,9 @@ function hvp_content_upgrade_progress($libraryid) { a11y_title FROM {hvp} WHERE main_library_id = ? + AND id > ? {$skipquery} - ORDER BY name ASC", array($libraryid), 0 , 40 + ORDER BY id ASC", array($libraryid, $lastid), 0 , 40 ); foreach ($results as $content) { From 772b78bff4cdef62f24670d59e7a736ade5ec5c1 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Mon, 17 Aug 2026 14:43:53 +0200 Subject: [PATCH 12/16] AU-8017 Fix lastId not always int --- locallib.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/locallib.php b/locallib.php index c1dd8a18e..174964cc3 100644 --- a/locallib.php +++ b/locallib.php @@ -374,11 +374,7 @@ function hvp_content_upgrade_progress($libraryid) { } else { $out->skipped = array(); } - - $lastid = filter_input(INPUT_POST, 'lastId'); - if (empty($lastid) || $lastid != intval($lastid)) { - $lastid = 0; - } + $lastid = optional_param('lastId', 0, PARAM_INT); // Get number of contents for this library. $out->left = $interface->getNumContent($libraryid, $skipped, $lastid); From a265eb6654b99f4f5034cfca186eef2967720ee2 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Mon, 17 Aug 2026 14:44:26 +0200 Subject: [PATCH 13/16] AU-8017 Fix JS variable name typo --- upgrade_content_page.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upgrade_content_page.php b/upgrade_content_page.php index bf03871ca..941b7a099 100644 --- a/upgrade_content_page.php +++ b/upgrade_content_page.php @@ -91,7 +91,7 @@ 'library_id' => $libraryid)))->out(false), 'total' => $numcontents, 'token' => \H5PCore::createToken('contentupgrade'), - 'fixSubContent' => !!$fixsubcontent, + 'fixSubcontent' => !!$fixsubcontent, ) ); From da87752e58ae5a2c36093d7670e68eb8b8c89243 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Tue, 18 Aug 2026 12:26:15 +0200 Subject: [PATCH 14/16] Update core library --- library | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library b/library index 570db67ae..38d0b7d7a 160000 --- a/library +++ b/library @@ -1 +1 @@ -Subproject commit 570db67ae637a89e0301b54b3949439e3811bf43 +Subproject commit 38d0b7d7a3dee1e9fc58b7048a512fde3f50dbcb From 6527ec556a198f217469f7cefa7d7bdcfcfb6f27 Mon Sep 17 00:00:00 2001 From: Maris Date: Tue, 1 Sep 2026 09:55:44 +0200 Subject: [PATCH 15/16] Prepare for release 1.28.4 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 54b7eb89a..cb1a5c668 100644 --- a/version.php +++ b/version.php @@ -23,9 +23,9 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2026081300; +$plugin->version = 2026090100; $plugin->requires = 2013051403; $plugin->cron = 0; $plugin->component = 'mod_hvp'; $plugin->maturity = MATURITY_STABLE; -$plugin->release = '1.28.3'; +$plugin->release = '1.28.4'; From b0435dce7f209c66ae6d68b5f844dcada259903e Mon Sep 17 00:00:00 2001 From: Niko Hoogeveen Date: Thu, 24 Sep 2026 14:11:43 -0400 Subject: [PATCH 16/16] Fix failing CI unit test --- tests/look_for_updates_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/look_for_updates_test.php b/tests/look_for_updates_test.php index 5997ce387..63e83da03 100644 --- a/tests/look_for_updates_test.php +++ b/tests/look_for_updates_test.php @@ -38,7 +38,7 @@ final class look_for_updates_test extends \advanced_testcase { public function test_execute( int $hubisenabled, int $sendusagestatistics, - bool $expectearlyexit, + bool $expectearlyexit ): void { $this->resetAfterTest();