From 37716dc58e40a9fe3cf058fed7edfba2af552dcb Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Wed, 5 May 2021 09:30:30 +0100 Subject: [PATCH] MDL-71050 h5p: account for parent languages retrieving translations. Take account of parent languages when requesting given library translation. For example if we are currently using "de_kids" as the current language, we need to recurse each language pack looking for a matching H5P translation ("de_kids" -> "de_du" -> "de"). --- h5p/ajax.php | 4 +- h5p/classes/editor_framework.php | 76 +++++++++++++++++++++++--------- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/h5p/ajax.php b/h5p/ajax.php index b5d7638be00..915c14538bb 100644 --- a/h5p/ajax.php +++ b/h5p/ajax.php @@ -55,7 +55,9 @@ switch ($action) { $major = optional_param('majorVersion', 0, PARAM_INT); $minor = optional_param('minorVersion', 0, PARAM_INT); - $language = optional_param('default-language', null, PARAM_ALPHA); + // Normalise Moodle language using underscore, as opposed to H5P which uses dash. + $language = optional_param('default-language', null, PARAM_RAW); + $language = clean_param(str_replace('-', '_', $language), PARAM_LANG); if (!empty($name)) { $editor->ajax->action(H5PEditorEndpoints::SINGLE_LIBRARY, $name, diff --git a/h5p/classes/editor_framework.php b/h5p/classes/editor_framework.php index 587b83490f5..8835aea06c4 100644 --- a/h5p/classes/editor_framework.php +++ b/h5p/classes/editor_framework.php @@ -39,6 +39,59 @@ use stdClass; */ class editor_framework implements H5peditorStorage { + /** + * Retrieve library language file from file storage. Note that parent languages will also be checked until a matching + * record is found (e.g. "de_kids" -> "de_du" -> "de") + * + * @param string $name + * @param int $major + * @param int $minor + * @param string $lang + * @return stdClass|bool Translation record if available, false otherwise + */ + private function get_language_record(string $name, int $major, int $minor, string $lang) { + global $DB; + + $params = [ + file_storage::COMPONENT, + file_storage::LIBRARY_FILEAREA, + ]; + $sqllike = $DB->sql_like('f.filepath', '?'); + $params[] = '%language%'; + + $sql = "SELECT hl.id, f.pathnamehash + FROM {h5p_libraries} hl + LEFT JOIN {files} f + ON hl.id = f.itemid AND f.component = ? AND f.filearea = ? AND $sqllike + WHERE ((hl.machinename = ? AND hl.majorversion = ? AND hl.minorversion = ?) + AND f.filename = ?) + ORDER BY hl.patchversion DESC"; + + $params[] = $name; + $params[] = $major; + $params[] = $minor; + $params[] = $lang.'.json'; + + // Add translations, based initially on the given H5P language code. If missing then recurse language dependencies + // until we find a matching H5P language file. + $result = $DB->get_record_sql($sql, $params); + if ($result === false) { + + // Normalise Moodle language using underscore, as opposed to H5P which uses dash. + $moodlelanguage = str_replace('-', '_', $lang); + + $dependencies = get_string_manager()->get_language_dependencies($moodlelanguage); + + // If current language has a dependency, then request it. + if (count($dependencies) > 1) { + $parentlanguage = str_replace('_', '-', $dependencies[count($dependencies) - 2]); + $result = $this->get_language_record($name, $major, $minor, $parentlanguage); + } + } + + return $result; + } + /** * Load language file(JSON). * Used to translate the editor fields(title, description etc.) @@ -51,7 +104,6 @@ class editor_framework implements H5peditorStorage { * @return string|boolean Translation in JSON format if available, false otherwise */ public function getLanguage($name, $major, $minor, $lang) { - global $DB; // Check if this information has been saved previously into the cache. $langcache = \cache::make('core', 'h5p_content_type_translations'); @@ -74,27 +126,7 @@ class editor_framework implements H5peditorStorage { } // Get the language file for this library. - $params = [ - file_storage::COMPONENT, - file_storage::LIBRARY_FILEAREA, - ]; - $sqllike = $DB->sql_like('f.filepath', '?'); - $params[] = '%language%'; - - $sql = "SELECT hl.id, f.pathnamehash - FROM {h5p_libraries} hl - LEFT JOIN {files} f - ON hl.id = f.itemid AND f.component = ? AND f.filearea = ? AND $sqllike - WHERE ((hl.machinename = ? AND hl.majorversion = ? AND hl.minorversion = ?) - AND f.filename = ?) - ORDER BY hl.patchversion DESC"; - $params[] = $name; - $params[] = $major; - $params[] = $minor; - $params[] = $lang.'.json'; - - $result = $DB->get_record_sql($sql, $params); - + $result = $this->get_language_record($name, $major, $minor, $lang); if (empty($result)) { // Save the fact that there is no translation into the cache. // The cache API cannot handle setting a literal `false` value so conver to `null` instead.