1 |
efrain |
1 |
<?php
|
|
|
2 |
|
|
|
3 |
namespace Moodle;
|
|
|
4 |
|
|
|
5 |
/**
|
|
|
6 |
* This is a data layer which uses the file system so it isn't specific to any framework.
|
|
|
7 |
*/
|
|
|
8 |
class H5PDevelopment {
|
|
|
9 |
|
|
|
10 |
const MODE_NONE = 0;
|
|
|
11 |
const MODE_CONTENT = 1;
|
|
|
12 |
const MODE_LIBRARY = 2;
|
|
|
13 |
|
|
|
14 |
private $h5pF, $libraries, $language, $filesPath;
|
|
|
15 |
|
|
|
16 |
/**
|
|
|
17 |
* Constructor.
|
|
|
18 |
*
|
|
|
19 |
* @param H5PFrameworkInterface|object $H5PFramework
|
|
|
20 |
* The frameworks implementation of the H5PFrameworkInterface
|
|
|
21 |
* @param string $filesPath
|
|
|
22 |
* Path to where H5P should store its files
|
|
|
23 |
* @param $language
|
|
|
24 |
* @param array $libraries Optional cache input.
|
|
|
25 |
*/
|
|
|
26 |
public function __construct(H5PFrameworkInterface $H5PFramework, $filesPath, $language, $libraries = NULL) {
|
|
|
27 |
$this->h5pF = $H5PFramework;
|
|
|
28 |
$this->language = $language;
|
|
|
29 |
$this->filesPath = $filesPath;
|
|
|
30 |
if ($libraries !== NULL) {
|
|
|
31 |
$this->libraries = $libraries;
|
|
|
32 |
}
|
|
|
33 |
else {
|
|
|
34 |
$this->findLibraries($filesPath . '/development');
|
|
|
35 |
}
|
|
|
36 |
}
|
|
|
37 |
|
|
|
38 |
/**
|
|
|
39 |
* Get contents of file.
|
|
|
40 |
*
|
|
|
41 |
* @param string $file File path.
|
|
|
42 |
* @return mixed String on success or NULL on failure.
|
|
|
43 |
*/
|
|
|
44 |
private function getFileContents($file) {
|
|
|
45 |
if (file_exists($file) === FALSE) {
|
|
|
46 |
return NULL;
|
|
|
47 |
}
|
|
|
48 |
|
|
|
49 |
$contents = file_get_contents($file);
|
|
|
50 |
if ($contents === FALSE) {
|
|
|
51 |
return NULL;
|
|
|
52 |
}
|
|
|
53 |
|
|
|
54 |
return $contents;
|
|
|
55 |
}
|
|
|
56 |
|
|
|
57 |
/**
|
|
|
58 |
* Scans development directory and find all libraries.
|
|
|
59 |
*
|
|
|
60 |
* @param string $path Libraries development folder
|
|
|
61 |
*/
|
|
|
62 |
private function findLibraries($path) {
|
|
|
63 |
$this->libraries = array();
|
|
|
64 |
|
|
|
65 |
if (is_dir($path) === FALSE) {
|
|
|
66 |
return;
|
|
|
67 |
}
|
|
|
68 |
|
|
|
69 |
$contents = scandir($path);
|
|
|
70 |
|
|
|
71 |
for ($i = 0, $s = count($contents); $i < $s; $i++) {
|
|
|
72 |
if ($contents[$i][0] === '.') {
|
|
|
73 |
continue; // Skip hidden stuff.
|
|
|
74 |
}
|
|
|
75 |
|
|
|
76 |
$libraryPath = $path . '/' . $contents[$i];
|
|
|
77 |
$libraryJSON = $this->getFileContents($libraryPath . '/library.json');
|
|
|
78 |
if ($libraryJSON === NULL) {
|
|
|
79 |
continue; // No JSON file, skip.
|
|
|
80 |
}
|
|
|
81 |
|
|
|
82 |
$library = json_decode($libraryJSON, TRUE);
|
|
|
83 |
if ($library === NULL) {
|
|
|
84 |
continue; // Invalid JSON.
|
|
|
85 |
}
|
|
|
86 |
|
|
|
87 |
// TODO: Validate props? Not really needed, is it? this is a dev site.
|
|
|
88 |
|
|
|
89 |
$library['libraryId'] = $this->h5pF->getLibraryId($library['machineName'], $library['majorVersion'], $library['minorVersion']);
|
|
|
90 |
|
|
|
91 |
// Convert metadataSettings values to boolean & json_encode it before saving
|
|
|
92 |
$library['metadataSettings'] = isset($library['metadataSettings']) ?
|
|
|
93 |
H5PMetadata::boolifyAndEncodeSettings($library['metadataSettings']) :
|
|
|
94 |
NULL;
|
|
|
95 |
|
|
|
96 |
// Save/update library.
|
|
|
97 |
$this->h5pF->saveLibraryData($library, $library['libraryId'] === FALSE);
|
|
|
98 |
|
|
|
99 |
// Need to decode it again, since it is served from here.
|
|
|
100 |
$library['metadataSettings'] = isset($library['metadataSettings'])
|
|
|
101 |
? json_decode($library['metadataSettings'])
|
|
|
102 |
: NULL;
|
|
|
103 |
|
|
|
104 |
$library['path'] = 'development/' . $contents[$i];
|
|
|
105 |
$this->libraries[H5PDevelopment::libraryToString($library['machineName'], $library['majorVersion'], $library['minorVersion'])] = $library;
|
|
|
106 |
}
|
|
|
107 |
|
|
|
108 |
// TODO: Should we remove libraries without files? Not really needed, but must be cleaned up some time, right?
|
|
|
109 |
|
|
|
110 |
// Go trough libraries and insert dependencies. Missing deps. will just be ignored and not available. (I guess?!)
|
|
|
111 |
$this->h5pF->lockDependencyStorage();
|
|
|
112 |
foreach ($this->libraries as $library) {
|
|
|
113 |
$this->h5pF->deleteLibraryDependencies($library['libraryId']);
|
|
|
114 |
// This isn't optimal, but without it we would get duplicate warnings.
|
|
|
115 |
// TODO: You might get PDOExceptions if two or more requests does this at the same time!!
|
|
|
116 |
$types = array('preloaded', 'dynamic', 'editor');
|
|
|
117 |
foreach ($types as $type) {
|
|
|
118 |
if (isset($library[$type . 'Dependencies'])) {
|
|
|
119 |
$this->h5pF->saveLibraryDependencies($library['libraryId'], $library[$type . 'Dependencies'], $type);
|
|
|
120 |
}
|
|
|
121 |
}
|
|
|
122 |
}
|
|
|
123 |
$this->h5pF->unlockDependencyStorage();
|
|
|
124 |
// TODO: Deps must be inserted into h5p_nodes_libraries as well... ? But only if they are used?!
|
|
|
125 |
}
|
|
|
126 |
|
|
|
127 |
/**
|
|
|
128 |
* @return array Libraries in development folder.
|
|
|
129 |
*/
|
|
|
130 |
public function getLibraries() {
|
|
|
131 |
return $this->libraries;
|
|
|
132 |
}
|
|
|
133 |
|
|
|
134 |
/**
|
|
|
135 |
* Get library
|
|
|
136 |
*
|
|
|
137 |
* @param string $name of the library.
|
|
|
138 |
* @param int $majorVersion of the library.
|
|
|
139 |
* @param int $minorVersion of the library.
|
|
|
140 |
* @return array library.
|
|
|
141 |
*/
|
|
|
142 |
public function getLibrary($name, $majorVersion, $minorVersion) {
|
|
|
143 |
$library = H5PDevelopment::libraryToString($name, $majorVersion, $minorVersion);
|
|
|
144 |
return isset($this->libraries[$library]) === TRUE ? $this->libraries[$library] : NULL;
|
|
|
145 |
}
|
|
|
146 |
|
|
|
147 |
/**
|
|
|
148 |
* Get semantics for the given library.
|
|
|
149 |
*
|
|
|
150 |
* @param string $name of the library.
|
|
|
151 |
* @param int $majorVersion of the library.
|
|
|
152 |
* @param int $minorVersion of the library.
|
|
|
153 |
* @return string Semantics
|
|
|
154 |
*/
|
|
|
155 |
public function getSemantics($name, $majorVersion, $minorVersion) {
|
|
|
156 |
$library = H5PDevelopment::libraryToString($name, $majorVersion, $minorVersion);
|
|
|
157 |
if (isset($this->libraries[$library]) === FALSE) {
|
|
|
158 |
return NULL;
|
|
|
159 |
}
|
|
|
160 |
return $this->getFileContents($this->filesPath . $this->libraries[$library]['path'] . '/semantics.json');
|
|
|
161 |
}
|
|
|
162 |
|
|
|
163 |
/**
|
|
|
164 |
* Get translations for the given library.
|
|
|
165 |
*
|
|
|
166 |
* @param string $name of the library.
|
|
|
167 |
* @param int $majorVersion of the library.
|
|
|
168 |
* @param int $minorVersion of the library.
|
|
|
169 |
* @param $language
|
|
|
170 |
* @return string Translation
|
|
|
171 |
*/
|
|
|
172 |
public function getLanguage($name, $majorVersion, $minorVersion, $language) {
|
|
|
173 |
$library = H5PDevelopment::libraryToString($name, $majorVersion, $minorVersion);
|
|
|
174 |
|
|
|
175 |
if (isset($this->libraries[$library]) === FALSE) {
|
|
|
176 |
return NULL;
|
|
|
177 |
}
|
|
|
178 |
|
|
|
179 |
return $this->getFileContents($this->filesPath . $this->libraries[$library]['path'] . '/language/' . $language . '.json');
|
|
|
180 |
}
|
|
|
181 |
|
|
|
182 |
/**
|
|
|
183 |
* Writes library as string on the form "name majorVersion.minorVersion"
|
|
|
184 |
*
|
|
|
185 |
* @param string $name Machine readable library name
|
|
|
186 |
* @param integer $majorVersion
|
|
|
187 |
* @param $minorVersion
|
|
|
188 |
* @return string Library identifier.
|
|
|
189 |
*/
|
|
|
190 |
public static function libraryToString($name, $majorVersion, $minorVersion) {
|
|
|
191 |
return $name . ' ' . $majorVersion . '.' . $minorVersion;
|
|
|
192 |
}
|
|
|
193 |
}
|