See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Class \core_h5p\editor_framework 19 * 20 * @package core_h5p 21 * @copyright 2020 Victor Deniz <victor@moodle.com>, base on code by Joubel AS 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_h5p; 26 27 use H5peditorStorage; 28 use stdClass; 29 30 /** 31 * Moodle's implementation of the H5P Editor storage interface. 32 * 33 * Makes it possible for the editor's core library to communicate with the 34 * database used by Moodle. 35 * 36 * @package core_h5p 37 * @copyright 2020 Victor Deniz <victor@moodle.com>, base on code by Joubel AS 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class editor_framework implements H5peditorStorage { 41 42 /** 43 * Load language file(JSON). 44 * Used to translate the editor fields(title, description etc.) 45 * 46 * @param string $name The machine readable name of the library(content type) 47 * @param int $major Major part of version number 48 * @param int $minor Minor part of version number 49 * @param string $lang Language code 50 * 51 * @return string|boolean Translation in JSON format if available, false otherwise 52 */ 53 public function getLanguage($name, $major, $minor, $lang) { 54 global $DB; 55 56 // Check if this information has been saved previously into the cache. 57 $langcache = \cache::make('core', 'h5p_content_type_translations'); 58 $library = new stdClass(); 59 $library->machinename = $name; 60 $library->majorversion = $major; 61 $library->minorversion = $minor; 62 $librarykey = helper::get_cache_librarykey(core::record_to_string($library)); 63 $cachekey = "{$librarykey}/{$lang}"; 64 $translation = $langcache->get($cachekey); 65 66 if ($translation !== false) { 67 // When there is no translation we store it in the cache as `null`. 68 // This API requires it be returned as `false`. 69 if ($translation === null) { 70 return false; 71 } 72 73 return $translation; 74 } 75 76 // Get the language file for this library. 77 $params = [ 78 file_storage::COMPONENT, 79 file_storage::LIBRARY_FILEAREA, 80 ]; 81 $sqllike = $DB->sql_like('f.filepath', '?'); 82 $params[] = '%language%'; 83 84 $sql = "SELECT hl.id, f.pathnamehash 85 FROM {h5p_libraries} hl 86 LEFT JOIN {files} f 87 ON hl.id = f.itemid AND f.component = ? AND f.filearea = ? AND $sqllike 88 WHERE ((hl.machinename = ? AND hl.majorversion = ? AND hl.minorversion = ?) 89 AND f.filename = ?) 90 ORDER BY hl.patchversion DESC"; 91 $params[] = $name; 92 $params[] = $major; 93 $params[] = $minor; 94 $params[] = $lang.'.json'; 95 96 $result = $DB->get_record_sql($sql, $params); 97 98 if (empty($result)) { 99 // Save the fact that there is no translation into the cache. 100 // The cache API cannot handle setting a literal `false` value so conver to `null` instead. 101 $langcache->set($cachekey, null); 102 103 return false; 104 } 105 106 // Save translation into the cache, and return its content. 107 $fs = get_file_storage(); 108 $file = $fs->get_file_by_hash($result->pathnamehash); 109 $translation = $file->get_content(); 110 111 $langcache->set($cachekey, $translation); 112 113 return $translation; 114 } 115 116 /** 117 * Load a list of available language codes. 118 * 119 * Until translations is implemented, only returns the "en" language. 120 * 121 * @param string $machinename The machine readable name of the library(content type) 122 * @param int $major Major part of version number 123 * @param int $minor Minor part of version number 124 * 125 * @return array List of possible language codes 126 */ 127 public function getAvailableLanguages($machinename, $major, $minor): array { 128 global $DB; 129 130 // Check if this information has been saved previously into the cache. 131 $langcache = \cache::make('core', 'h5p_content_type_translations'); 132 $library = new stdClass(); 133 $library->machinename = $machinename; 134 $library->majorversion = $major; 135 $library->minorversion = $minor; 136 $librarykey = helper::get_cache_librarykey(core::record_to_string($library)); 137 $languages = $langcache->get($librarykey); 138 if ($languages) { 139 // This contains a list of all of the available languages for the library. 140 return $languages; 141 } 142 143 // Get the language files for this library. 144 $params = [ 145 file_storage::COMPONENT, 146 file_storage::LIBRARY_FILEAREA, 147 ]; 148 $filepathsqllike = $DB->sql_like('f.filepath', '?'); 149 $params[] = '%language%'; 150 $filenamesqllike = $DB->sql_like('f.filename', '?'); 151 $params[] = '%.json'; 152 153 $sql = "SELECT DISTINCT f.filename 154 FROM {h5p_libraries} hl 155 LEFT JOIN {files} f 156 ON hl.id = f.itemid AND f.component = ? AND f.filearea = ? 157 AND $filepathsqllike AND $filenamesqllike 158 WHERE hl.machinename = ? AND hl.majorversion = ? AND hl.minorversion = ?"; 159 $params[] = $machinename; 160 $params[] = $major; 161 $params[] = $minor; 162 163 $defaultcode = 'en'; 164 $languages = []; 165 166 $results = $DB->get_recordset_sql($sql, $params); 167 if ($results->valid()) { 168 // Extract the code language from the JS language files. 169 foreach ($results as $result) { 170 if (!empty($result->filename)) { 171 $lang = substr($result->filename, 0, -5); 172 $languages[$lang] = $languages; 173 } 174 } 175 $results->close(); 176 177 // Semantics is 'en' by default. It has to be added always. 178 if (!array_key_exists($defaultcode, $languages)) { 179 $languages = array_keys($languages); 180 array_unshift($languages, $defaultcode); 181 } 182 } else { 183 $results->close(); 184 $params = [ 185 'machinename' => $machinename, 186 'majorversion' => $major, 187 'minorversion' => $minor, 188 ]; 189 if ($DB->record_exists('h5p_libraries', $params)) { 190 // If the library exists (but it doesn't contain any language file), at least defaultcode should be returned. 191 $languages[] = $defaultcode; 192 } 193 } 194 195 // Save available languages into the cache. 196 $langcache->set($librarykey, $languages); 197 198 return $languages; 199 } 200 201 /** 202 * "Callback" for mark the given file as a permanent file. 203 * 204 * Used when saving content that has new uploaded files. 205 * 206 * @param int $fileid 207 */ 208 public function keepFile($fileid): void { 209 // Temporal files will be removed on a task when they are in the "editor" file area and and are at least one day older. 210 } 211 212 /** 213 * Return libraries details. 214 * 215 * Two use cases: 216 * 1. No input, will list all the available content types. 217 * 2. Libraries supported are specified, load additional data and verify 218 * that the content types are available. Used by e.g. the Presentation Tool 219 * Editor that already knows which content types are supported in its 220 * slides. 221 * 222 * @param array $libraries List of library names + version to load info for. 223 * 224 * @return array List of all libraries loaded. 225 */ 226 public function getLibraries($libraries = null): ?array { 227 228 if ($libraries !== null) { 229 // Get details for the specified libraries. 230 $librariesin = []; 231 $fields = 'title, runnable, metadatasettings'; 232 233 foreach ($libraries as $library) { 234 $params = [ 235 'machinename' => $library->name, 236 'majorversion' => $library->majorVersion, 237 'minorversion' => $library->minorVersion 238 ]; 239 240 $details = api::get_library_details($params, true, $fields); 241 242 if ($details) { 243 $library->title = $details->title; 244 $library->runnable = $details->runnable; 245 $library->metadataSettings = json_decode($details->metadatasettings); 246 $librariesin[] = $library; 247 } 248 } 249 } else { 250 $fields = 'id, machinename as name, title, majorversion, minorversion, metadatasettings'; 251 $librariesin = api::get_contenttype_libraries($fields); 252 } 253 254 return $librariesin; 255 } 256 257 /** 258 * Allow for other plugins to decide which styles and scripts are attached. 259 * 260 * This is useful for adding and/or modifying the functionality and look of 261 * the content types. 262 * 263 * @param array $files List of files as objects with path and version as properties. 264 * @param array $libraries List of libraries indexed by machineName with objects as values. The objects have majorVersion and 265 * minorVersion as properties. 266 */ 267 public function alterLibraryFiles(&$files, $libraries): void { 268 global $PAGE; 269 270 // Refactor dependency list. 271 $librarylist = []; 272 foreach ($libraries as $dependency) { 273 $librarylist[$dependency['machineName']] = [ 274 'majorVersion' => $dependency['majorVersion'], 275 'minorVersion' => $dependency['minorVersion'] 276 ]; 277 } 278 279 $renderer = $PAGE->get_renderer('core_h5p'); 280 281 $embedtype = 'editor'; 282 $renderer->h5p_alter_scripts($files['scripts'], $librarylist, $embedtype); 283 $renderer->h5p_alter_styles($files['styles'], $librarylist, $embedtype); 284 } 285 286 /** 287 * Saves a file or moves it temporarily. 288 * 289 * This is often necessary in order to validate and store uploaded or fetched H5Ps. 290 * 291 * @param string $data Uri of data that should be saved as a temporary file. 292 * @param bool $movefile Can be set to TRUE to move the data instead of saving it. 293 * 294 * @return bool|object Returns false if saving failed or an object with path 295 * of the directory and file that is temporarily saved. 296 */ 297 public static function saveFileTemporarily($data, $movefile = false) { 298 // This is to be implemented when the Hub client is used to upload libraries. 299 return false; 300 } 301 302 /** 303 * Marks a file for later cleanup. 304 * 305 * Useful when files are not instantly cleaned up. E.g. for files that are uploaded through the editor. 306 * 307 * @param int $file Id of file that should be cleaned up 308 * @param int|null $contentid Content id of file 309 */ 310 public static function markFileForCleanup($file, $contentid = null): ?int { 311 // Temporal files will be removed on a task when they are in the "editor" file area and and are at least one day older. 312 return null; 313 } 314 315 /** 316 * Clean up temporary files 317 * 318 * @param string $filepath Path to file or directory 319 */ 320 public static function removeTemporarilySavedFiles($filepath): void { 321 // This is to be implemented when the Hub client is used to upload libraries. 322 } 323 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body