From 04707a9f8ace4db2491127e6ebb20f0bf26e33dd Mon Sep 17 00:00:00 2001 From: Oliver Tacke Date: Wed, 13 Jun 2018 18:36:23 +0200 Subject: [PATCH 1/8] HFP-1871 Add function to load MathDisplay if params contain math --- h5p.classes.php | 60 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/h5p.classes.php b/h5p.classes.php index 2efebbd..b160abd 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1770,7 +1770,7 @@ abstract class H5PHubEndpoints { * Functions and storage shared by the other H5P classes */ class H5PCore { - + public static $coreApi = array( 'majorVersion' => 1, 'minorVersion' => 16 @@ -1938,6 +1938,14 @@ class H5PCore { } $validator->validateLibrary($params, (object) array('options' => array($params->library))); + // Add MathDisplay. + // TODO: Get library name for MathDisplay dynamically + // TODO: Get regexp from MathDisplay config + // TODO: Find out how to pass settings to MathDisplay + if ($this->containsMath($params->params)) { + $validator->addMathDisplay('H5P.MathDisplay 0.1'); + } + $params = json_encode($params->params); // Update content dependencies. @@ -1970,6 +1978,39 @@ class H5PCore { return $params; } + /** + * Determine if params contain math. + * + * @param {object} params - Parameters. + * @param {string} [mathPattern] - Regular expression to identify math. + * @param {boolean} [found] - Used for recursion. + * @return {boolean} True, if params contain math. + */ + private function containsMath ($params, $mathPattern = '/\$\$.+\$\$|\\\[.+\\\]|\\\(.+\\\)/', $found = false) { + foreach($params as $property => $value) { + if (gettype($value) === 'string') { + if (preg_match($mathPattern, $value) === 1) { + $found = true; + break; + } + } + if ($found === false) { + if (gettype($value) === 'array') { + for ($i = 0; $i < sizeof($value); $i++) { + $found = $this->containsMath($value[$i], $mathPattern, $found); + if ($found === true) { + break; + } + } + } + if (gettype($value) === 'object') { + $found = $this->containsMath($value, $mathPattern, $found); + } + } + } + return $found; + } + /** * Generate content slug * @@ -3204,6 +3245,23 @@ class H5PContentValidator { $this->dependencies = array(); } + /** + * Add MathDisplay. + */ + public function addMathDisplay($libraryName) { + $libSpec = H5PCore::libraryFromString($libraryName); + $library = $this->h5pC->loadLibrary($libSpec['machineName'], $libSpec['majorVersion'], $libSpec['minorVersion']); + $library['semantics'] = $this->h5pC->loadLibrarySemantics($libSpec['machineName'], $libSpec['majorVersion'], $libSpec['minorVersion']); + + $depKey = 'preloaded-' . $library['machineName']; + $this->dependencies[$depKey] = array( + 'library' => $library, + 'type' => 'preloaded' + ); + $this->nextWeight = $this->h5pC->findLibraryDependencies($this->dependencies, $library, $this->nextWeight); + $this->dependencies[$depKey]['weight'] = $this->nextWeight++; + } + /** * Get the flat dependency tree. * From 62b6345c497b9740834257b243382a64a20811cc Mon Sep 17 00:00:00 2001 From: Oliver Tacke Date: Wed, 25 Jul 2018 15:08:29 +0200 Subject: [PATCH 2/8] HFP-1871 Use param from MathDisplay library.json for configuration --- h5p.classes.php | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/h5p.classes.php b/h5p.classes.php index b160abd..a61cb61 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1938,12 +1938,37 @@ class H5PCore { } $validator->validateLibrary($params, (object) array('options' => array($params->library))); - // Add MathDisplay. - // TODO: Get library name for MathDisplay dynamically - // TODO: Get regexp from MathDisplay config + // Add latest MathDisplay version if content contains math // TODO: Find out how to pass settings to MathDisplay - if ($this->containsMath($params->params)) { - $validator->addMathDisplay('H5P.MathDisplay 0.1'); + $libs = $this->h5pF->loadLibraries(); + + // Get latest version of MathDisplay library + $mathLibs = $libs['H5P.MathDisplay']; + foreach($mathLibs as $libVersion) { + if ($libVersion->major_version === $majorMax && $libVersion->minor_version > $minorMax) { + $mathLib = $libVersion; + } + else if ($libVersion->major_version > $majorMax) { + $mathLib = $libVersion; + } + } + + if (isset($mathLib)) { + // Retrieve regular expression from library.json + // Careful: \ will have to be escaped itself inside json + $libParams = $this->loadLibrary($mathLib->name, $mathLib->major_version, $mathLib->minor_version); + // Is there a general function to pass a "path" to that finds a parameter? + $libParamsTypes = $libParams['addTo']['content']['types']; + foreach($libParamsTypes as $type => $property) { + $regex = $property['text']['regex']; + if (isset($regex)) { + break; + } + } + + if ($this->containsMath($params->params, $regex)) { + $validator->addMathDisplay($mathLib->name . ' ' . $mathLib->major_version . '.' . $mathLib->minor_version); + } } $params = json_encode($params->params); @@ -1986,7 +2011,10 @@ class H5PCore { * @param {boolean} [found] - Used for recursion. * @return {boolean} True, if params contain math. */ - private function containsMath ($params, $mathPattern = '/\$\$.+\$\$|\\\[.+\\\]|\\\(.+\\\)/', $found = false) { + private function containsMath ($params, $mathPattern, $found = false) { + if (!isset($mathPattern) == NULL) { + $mathPattern = '/\$\$.+\$\$|\\\[.+\\\]|\\\(.+\\\)/'; + } foreach($params as $property => $value) { if (gettype($value) === 'string') { if (preg_match($mathPattern, $value) === 1) { From 942fd922bc40166e58ab5a4a85e93ac5e0665576 Mon Sep 17 00:00:00 2001 From: Oliver Tacke Date: Thu, 26 Jul 2018 10:37:16 +0200 Subject: [PATCH 3/8] HFP-1871 Add general function to get values from library json config --- h5p.classes.php | 53 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/h5p.classes.php b/h5p.classes.php index a61cb61..f56a284 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1939,7 +1939,6 @@ class H5PCore { $validator->validateLibrary($params, (object) array('options' => array($params->library))); // Add latest MathDisplay version if content contains math - // TODO: Find out how to pass settings to MathDisplay $libs = $this->h5pF->loadLibraries(); // Get latest version of MathDisplay library @@ -1957,14 +1956,7 @@ class H5PCore { // Retrieve regular expression from library.json // Careful: \ will have to be escaped itself inside json $libParams = $this->loadLibrary($mathLib->name, $mathLib->major_version, $mathLib->minor_version); - // Is there a general function to pass a "path" to that finds a parameter? - $libParamsTypes = $libParams['addTo']['content']['types']; - foreach($libParamsTypes as $type => $property) { - $regex = $property['text']['regex']; - if (isset($regex)) { - break; - } - } + $regex = $this->retrieveValue($libParams, 'addTo.content.types.text.regex'); if ($this->containsMath($params->params, $regex)) { $validator->addMathDisplay($mathLib->name . ' ' . $mathLib->major_version . '.' . $mathLib->minor_version); @@ -2003,6 +1995,49 @@ class H5PCore { return $params; } + /** + * Retrieve a value from a nested mixed array structure. + * + * @param Array $params Array to be looked in. + * @param String $path Supposed path to the value. + * @param String [$delimiter='.'] Property delimiter within the path. + * @return Object|NULL The object found or NULL. + */ + private function retrieveValue ($params, $path, $delimiter='.') { + $path = explode($delimiter, $path); + + // Property not found + if (!isset($params[$path[0]])) { + return NULL; + } + + $first = $params[$path[0]]; + + // End of path, done + if (sizeof($path) === 1) { + return $first; + } + + // We cannot go deeper + if (!is_array($first)) { + return NULL; + } + + // Regular Array + if (isset($first[0])) { + foreach($first as $number => $object) { + $found = $this->retrieveValue($object, implode($delimiter, array_slice($path, 1))); + if (isset($found)) { + return $found; + } + } + return NULL; + } + + // Associative Array + return $this->retrieveValue($first, implode('.', array_slice($path, 1))); + } + /** * Determine if params contain math. * From 9314c55994783c58bfb023d23954102bae0cfed9 Mon Sep 17 00:00:00 2001 From: Oliver Tacke Date: Thu, 26 Jul 2018 19:34:46 +0200 Subject: [PATCH 4/8] HFP-1871 Clean code --- h5p.classes.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/h5p.classes.php b/h5p.classes.php index f56a284..78d6d06 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1938,10 +1938,8 @@ class H5PCore { } $validator->validateLibrary($params, (object) array('options' => array($params->library))); - // Add latest MathDisplay version if content contains math - $libs = $this->h5pF->loadLibraries(); - // Get latest version of MathDisplay library + $libs = $this->h5pF->loadLibraries(); $mathLibs = $libs['H5P.MathDisplay']; foreach($mathLibs as $libVersion) { if ($libVersion->major_version === $majorMax && $libVersion->minor_version > $minorMax) { @@ -1952,6 +1950,7 @@ class H5PCore { } } + // Add latest MathDisplay version if content contains math if (isset($mathLib)) { // Retrieve regular expression from library.json // Careful: \ will have to be escaped itself inside json From d068b82ff56f4bad1cc870b7696e0cad833204ea Mon Sep 17 00:00:00 2001 From: Oliver Tacke Date: Mon, 30 Jul 2018 14:52:36 +0200 Subject: [PATCH 5/8] HFP-1871 Fix sanitization of containsMath --- h5p.classes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/h5p.classes.php b/h5p.classes.php index 78d6d06..3478f23 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -2046,7 +2046,7 @@ class H5PCore { * @return {boolean} True, if params contain math. */ private function containsMath ($params, $mathPattern, $found = false) { - if (!isset($mathPattern) == NULL) { + if (!isset($mathPattern)) { $mathPattern = '/\$\$.+\$\$|\\\[.+\\\]|\\\(.+\\\)/'; } foreach($params as $property => $value) { From 64e5ab442437fcee36a733523224737b4e09f8bd Mon Sep 17 00:00:00 2001 From: Oliver Tacke Date: Wed, 1 Aug 2018 10:55:13 +0200 Subject: [PATCH 6/8] HFP-1871 Fix missing variables --- h5p.classes.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/h5p.classes.php b/h5p.classes.php index 3478f23..2aeee76 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1941,12 +1941,18 @@ class H5PCore { // Get latest version of MathDisplay library $libs = $this->h5pF->loadLibraries(); $mathLibs = $libs['H5P.MathDisplay']; + + $majorMax = '0'; + $minorMax = '0'; foreach($mathLibs as $libVersion) { - if ($libVersion->major_version === $majorMax && $libVersion->minor_version > $minorMax) { + if ($libVersion->major_version === $majorMax && $libVersion->minor_version >= $minorMax) { $mathLib = $libVersion; + $minorMax = $libVersion->minor_version; } else if ($libVersion->major_version > $majorMax) { $mathLib = $libVersion; + $majorMax = $libVersion->major_version; + $minorMax = $libVersion->minor_version; } } From 6c4f904079ccbefbd6c3b4ac805b60dc264a2b39 Mon Sep 17 00:00:00 2001 From: Paal Joergensen Date: Thu, 23 Aug 2018 10:24:20 +0200 Subject: [PATCH 7/8] Generalize addons --- h5p.classes.php | 63 +++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/h5p.classes.php b/h5p.classes.php index 2aeee76..04249fc 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -101,6 +101,13 @@ interface H5PFrameworkInterface { */ public function getUploadedH5pPath(); + /** + * Load addon libraries + * + * @return array + */ + public function loadAddons(); + /** * Get a list of the current installed libraries * @@ -1609,7 +1616,7 @@ Class H5PExport { $library['minorVersion'] ); - if ($isDevLibrary !== NULL) { + if ($isDevLibrary !== NULL && isset($library['path'])) { $exportFolder = "/" . $library['path']; } } @@ -1938,33 +1945,20 @@ class H5PCore { } $validator->validateLibrary($params, (object) array('options' => array($params->library))); - // Get latest version of MathDisplay library - $libs = $this->h5pF->loadLibraries(); - $mathLibs = $libs['H5P.MathDisplay']; + // Handle addons: + $addons = $this->h5pF->loadAddons(); + foreach ($addons as $addon) { + $add_to = json_decode($addon['addTo']); - $majorMax = '0'; - $minorMax = '0'; - foreach($mathLibs as $libVersion) { - if ($libVersion->major_version === $majorMax && $libVersion->minor_version >= $minorMax) { - $mathLib = $libVersion; - $minorMax = $libVersion->minor_version; - } - else if ($libVersion->major_version > $majorMax) { - $mathLib = $libVersion; - $majorMax = $libVersion->major_version; - $minorMax = $libVersion->minor_version; - } - } + if (isset($add_to->content->types)) { + foreach($add_to->content->types as $type) { + if ($this->textAddonMatches($params->params, $type->text->regex)) { + $validator->addon($addon); - // Add latest MathDisplay version if content contains math - if (isset($mathLib)) { - // Retrieve regular expression from library.json - // Careful: \ will have to be escaped itself inside json - $libParams = $this->loadLibrary($mathLib->name, $mathLib->major_version, $mathLib->minor_version); - $regex = $this->retrieveValue($libParams, 'addTo.content.types.text.regex'); - - if ($this->containsMath($params->params, $regex)) { - $validator->addMathDisplay($mathLib->name . ' ' . $mathLib->major_version . '.' . $mathLib->minor_version); + // Addon can only be added once + break; + } + } } } @@ -2051,7 +2045,7 @@ class H5PCore { * @param {boolean} [found] - Used for recursion. * @return {boolean} True, if params contain math. */ - private function containsMath ($params, $mathPattern, $found = false) { + private function textAddonMatches($params, $mathPattern, $found = false) { if (!isset($mathPattern)) { $mathPattern = '/\$\$.+\$\$|\\\[.+\\\]|\\\(.+\\\)/'; } @@ -2065,14 +2059,14 @@ class H5PCore { if ($found === false) { if (gettype($value) === 'array') { for ($i = 0; $i < sizeof($value); $i++) { - $found = $this->containsMath($value[$i], $mathPattern, $found); + $found = $this->textAddonMatches($value[$i], $mathPattern, $found); if ($found === true) { break; } } } if (gettype($value) === 'object') { - $found = $this->containsMath($value, $mathPattern, $found); + $found = $this->textAddonMatches($value, $mathPattern, $found); } } } @@ -3314,12 +3308,13 @@ class H5PContentValidator { } /** - * Add MathDisplay. + * Add Addon library. */ - public function addMathDisplay($libraryName) { - $libSpec = H5PCore::libraryFromString($libraryName); - $library = $this->h5pC->loadLibrary($libSpec['machineName'], $libSpec['majorVersion'], $libSpec['minorVersion']); - $library['semantics'] = $this->h5pC->loadLibrarySemantics($libSpec['machineName'], $libSpec['majorVersion'], $libSpec['minorVersion']); + public function addon($library) { + // We need to run loadLibrarySemantics even if we have loadeed semantics from db, in case of + // 1) development foler + // 2) Invocation of semantics alter hook + $library['semantics'] = $this->h5pC->loadLibrarySemantics($library['machineName'], $library['majorVersion'], $library['minorVersion']); $depKey = 'preloaded-' . $library['machineName']; $this->dependencies[$depKey] = array( From ee0e97e17b04830424757cc2dc2b63c660df71ae Mon Sep 17 00:00:00 2001 From: Paal Joergensen Date: Mon, 27 Aug 2018 13:52:33 +0200 Subject: [PATCH 8/8] HFP-1871 Skip loading semantics for addons --- h5p.classes.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/h5p.classes.php b/h5p.classes.php index 04249fc..22bf9ea 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -3311,11 +3311,6 @@ class H5PContentValidator { * Add Addon library. */ public function addon($library) { - // We need to run loadLibrarySemantics even if we have loadeed semantics from db, in case of - // 1) development foler - // 2) Invocation of semantics alter hook - $library['semantics'] = $this->h5pC->loadLibrarySemantics($library['machineName'], $library['majorVersion'], $library['minorVersion']); - $depKey = 'preloaded-' . $library['machineName']; $this->dependencies[$depKey] = array( 'library' => $library,