Skip to content

Commit

Permalink
MDL-71050 h5p: account for parent languages retrieving translations.
Browse files Browse the repository at this point in the history
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").
  • Loading branch information
paulholden committed Jul 12, 2021
1 parent 2094d42 commit 37716dc
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 23 deletions.
4 changes: 3 additions & 1 deletion h5p/ajax.php
Expand Up @@ -55,7 +55,9 @@
$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,
Expand Down
76 changes: 54 additions & 22 deletions h5p/classes/editor_framework.php
Expand Up @@ -39,6 +39,59 @@
*/
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.)
Expand All @@ -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');
Expand All @@ -74,27 +126,7 @@ public function getLanguage($name, $major, $minor, $lang) {
}

// 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.
Expand Down

0 comments on commit 37716dc

Please sign in to comment.