Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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_ajax
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 Moodle\H5PEditorAjaxInterface;
28
use core\dml\table as dml_table;
29
 
30
/**
31
 * Moodle's implementation of the H5P Editor Ajax interface.
32
 *
33
 * Makes it possible for the editor's core ajax functionality 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_ajax implements H5PEditorAjaxInterface {
41
 
42
    /** The component for H5P. */
43
    public const EDITOR_AJAX_TOKEN = 'editorajax';
44
 
45
    /**
46
     * Gets latest library versions that exists locally
47
     *
48
     * @return array Latest version of all local libraries
49
     */
50
    public function getLatestLibraryVersions(): array {
51
        global $DB;
52
 
53
        $sql = "SELECT hl2.id, hl2.machinename as machine_name, hl2.title, hl2.majorversion as major_version,
54
                       hl2.minorversion AS minor_version, hl2.patchversion as patch_version, '' as has_icon, 0 as restricted,
55
                       hl2.enabled
56
                  FROM {h5p_libraries} hl2
57
             LEFT JOIN {h5p_libraries} hl1
58
                        ON hl1.machinename = hl2.machinename
59
                        AND (hl2.majorversion < hl1.majorversion
60
                             OR (hl2.majorversion = hl1.majorversion
61
                                 AND hl2.minorversion < hl1.minorversion)
62
                            )
63
                 WHERE hl2.runnable = 1
64
                       AND hl1.majorversion is null
65
              ORDER BY hl2.title";
66
 
67
        return $DB->get_records_sql($sql);
68
    }
69
 
70
    /**
71
     * Get locally stored Content Type Cache.
72
     *
73
     * If machine name is provided it will only get the given content type from the cache.
74
     *
75
     * @param null|string $machinename
76
     *
77
     * @return mixed|null Returns results from querying the database
78
     */
79
    public function getContentTypeCache($machinename = null) {
80
        global $DB;
81
 
82
        // Added some extra fields to the result because they are expected by functions calling this. They have been
83
        // taken from method getCachedLibsMap() in h5peditor.class.php.
84
        $sql = "SELECT l.id, l.machinename AS machine_name, l.majorversion AS major_version,
85
                       l.minorversion AS minor_version, l.patchversion AS patch_version, l.coremajor AS h5p_major_version,
86
                       l.coreminor AS h5p_minor_version, l.title, l.tutorial, l.example,
87
                       '' AS summary, '' AS description, '' AS icon, 0 AS created_at, 0 AS updated_at, 0 AS is_recommended,
88
 
89
                  FROM {h5p_libraries} l";
90
        $params = [];
91
        if (!empty($machinename)) {
92
            $sql .= ' WHERE l.machinename = :machine_name';
93
            $params = ['machine_name' => $machinename];
94
        }
95
 
96
        return $DB->get_records_sql($sql, $params);
97
    }
98
 
99
    /**
100
     * Gets recently used libraries for the current author
101
     *
102
     * @return array machine names. The first element in the array is the
103
     * most recently used.
104
     */
105
    public function getAuthorsRecentlyUsedLibraries(): array {
106
        // This is to be implemented when the Hub client is used.
107
        return [];
108
    }
109
 
110
    /**
111
     * Checks if the provided token is valid for this endpoint.
112
     *
113
     * @param string $token The token that will be validated for.
114
     *
115
     * @return bool True if successful validation
116
     */
117
    public function validateEditorToken($token): bool {
118
        return core::validToken(self::EDITOR_AJAX_TOKEN, $token);
119
    }
120
 
121
    /**
122
     * Get translations in one language for a list of libraries.
123
     *
124
     * @param array $libraries An array of libraries, in the form "<machineName> <majorVersion>.<minorVersion>
125
     * @param string $languagecode Language code
126
     *
127
     * @return array Translations in $languagecode available for libraries $libraries
128
     */
129
    public function getTranslations($libraries, $languagecode): array {
130
        $translations = [];
131
        $langcache = \cache::make('core', 'h5p_content_type_translations');
132
 
133
        $missing = [];
134
        foreach ($libraries as $libstring) {
135
            // Check if this library has been saved previously into the cache.
136
            $librarykey = helper::get_cache_librarykey($libstring);
137
            $cachekey = "{$librarykey}/{$languagecode}";
138
            $libtranslation = $langcache->get($cachekey);
139
            if ($libtranslation) {
140
                // The library has this language stored into the cache.
141
                $translations[$libstring] = $libtranslation;
142
            } else {
143
                // This language for the library hasn't been stored previously into the cache, so we need to get it from DB.
144
                $missing[] = $libstring;
145
            }
146
        }
147
 
148
        // Get all language files for libraries which aren't stored into the cache and merge them with the cache ones.
149
        return array_merge(
150
            $translations,
151
            $this->get_missing_translations($missing, $languagecode)
152
        );
153
    }
154
 
155
    /**
156
     * Get translation for $language for libraries in $missing.
157
     *
158
     * @param  array  $missing  An array of libraries, in the form "<machineName> <majorVersion>.<minorVersion>
159
     * @param  string $language Language code
160
     * @return array  Translations in $language available for libraries $missing
161
     */
162
    protected function get_missing_translations(array $missing, string $language): array {
163
        global $DB;
164
 
165
        if (empty($missing)) {
166
            return [];
167
        }
168
 
169
        $wheres = [];
170
        $params = [
171
            file_storage::COMPONENT,
172
            file_storage::LIBRARY_FILEAREA,
173
        ];
174
        $sqllike = $DB->sql_like('f.filepath', '?');
175
        $params[] = '%language%';
176
 
177
        foreach ($missing as $library) {
178
            $librarydata = core::libraryFromString($library);
179
            $wheres[] = '(h.machinename = ? AND h.majorversion = ? AND h.minorversion = ?)';
180
            $params[] = $librarydata['machineName'];
181
            $params[] = $librarydata['majorVersion'];
182
            $params[] = $librarydata['minorVersion'];
183
        }
184
        $params[] = "{$language}.json";
185
        $wheresql = implode(' OR ', $wheres);
186
 
187
        $filestable = new dml_table('files', 'f', 'f_');
188
        $filestableselect = $filestable->get_field_select();
189
 
190
        $libtable = new dml_table('h5p_libraries', 'h', 'h_');
191
        $libtableselect = $libtable->get_field_select();
192
 
193
        $sql = "SELECT {$filestableselect}, {$libtableselect}
194
                  FROM {h5p_libraries} h
195
             LEFT JOIN {files} f
196
                    ON h.id = f.itemid AND f.component = ?
197
                   AND f.filearea = ? AND $sqllike
198
                 WHERE ($wheresql) AND f.filename = ?";
199
 
200
        // Get the content of all these language files and put them into the translations array.
201
        $langcache = \cache::make('core', 'h5p_content_type_translations');
202
        $fs = get_file_storage();
203
        $translations = [];
204
        $results = $DB->get_recordset_sql($sql, $params);
205
        $toset = [];
206
        foreach ($results as $result) {
207
            $file = $fs->get_file_instance($filestable->extract_from_result($result));
208
            $library = $libtable->extract_from_result($result);
209
            $libstring = core::record_to_string($library);
210
            $librarykey = helper::get_cache_librarykey($libstring);
211
            $translations[$libstring] = $file->get_content();
212
            $cachekey = "{$librarykey}/{$language}";
213
            $toset[$cachekey] = $translations[$libstring];
214
        }
215
        $langcache->set_many($toset);
216
 
217
        $results->close();
218
 
219
        return $translations;
220
    }
221
}