Merge branch 'master' into flat-copyrights
commit
f22cfb05b7
291
h5p.classes.php
291
h5p.classes.php
|
@ -4,6 +4,16 @@
|
||||||
*/
|
*/
|
||||||
interface H5PFrameworkInterface {
|
interface H5PFrameworkInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns info for the current platform
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* An associative array containing:
|
||||||
|
* - name: The name of the plattform, for instance "Wordpress"
|
||||||
|
* - version: The version of the pattform, for instance "4.0"
|
||||||
|
*/
|
||||||
|
public function getPlatformInfo();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the user an error message
|
* Show the user an error message
|
||||||
*
|
*
|
||||||
|
@ -33,59 +43,82 @@ interface H5PFrameworkInterface {
|
||||||
* - @variable: escape plain text to HTML
|
* - @variable: escape plain text to HTML
|
||||||
* - %variable: escape text and theme as a placeholder for user-submitted
|
* - %variable: escape text and theme as a placeholder for user-submitted
|
||||||
* content
|
* content
|
||||||
* @return string Translated string
|
* @return string
|
||||||
|
* Translated string
|
||||||
*/
|
*/
|
||||||
public function t($message, $replacements = array());
|
public function t($message, $replacements = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Path to the last uploaded h5p
|
* Get the Path to the last uploaded h5p
|
||||||
*
|
*
|
||||||
* @return string Path to the folder where the last uploaded h5p for this session is located.
|
* @return string
|
||||||
|
* Path to the folder where the last uploaded h5p for this session is located.
|
||||||
*/
|
*/
|
||||||
public function getUploadedH5pFolderPath();
|
public function getUploadedH5pFolderPath();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string Path to the folder where all h5p files are stored
|
* @return string
|
||||||
|
* Path to the folder where all h5p files are stored
|
||||||
*/
|
*/
|
||||||
public function getH5pPath();
|
public function getH5pPath();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the path to the last uploaded h5p file
|
* Get the path to the last uploaded h5p file
|
||||||
*
|
*
|
||||||
* @return string Path to the last uploaded h5p
|
* @return string
|
||||||
|
* Path to the last uploaded h5p
|
||||||
*/
|
*/
|
||||||
public function getUploadedH5pPath();
|
public function getUploadedH5pPath();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of the current installed libraries
|
* Get a list of the current installed libraries
|
||||||
*
|
*
|
||||||
* @return array Associative array containg one item per machine name. This item contains an array of libraries.
|
* @return array
|
||||||
|
* Associative array containg one entry per machine name.
|
||||||
|
* For each machineName there is a list of libraries(with different versions)
|
||||||
*/
|
*/
|
||||||
public function loadLibraries();
|
public function loadLibraries();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saving the unsupported library list
|
* Saving the unsupported library list
|
||||||
*
|
*
|
||||||
* @param array A list of unsupported libraries
|
* @param array
|
||||||
|
* A list of unsupported libraries. Each list entry contains:
|
||||||
|
* - name: MachineName for the library
|
||||||
|
* - downloadUrl: URL to a location a new version of the library may be downloaded from
|
||||||
|
* - currentVersion: The unsupported version of the library installed on the system.
|
||||||
|
* This is an associative array containing:
|
||||||
|
* - major: The major version of the library
|
||||||
|
* - minor: The minor version of the library
|
||||||
|
* - patch: The patch version of the library
|
||||||
*/
|
*/
|
||||||
public function setUnsupportedLibraries($libraries);
|
public function setUnsupportedLibraries($libraries);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns unsupported libraries
|
* Returns unsupported libraries
|
||||||
*
|
*
|
||||||
* @return array A list of the unsupported libraries
|
* @return array
|
||||||
|
* A list of unsupported libraries. Each entry contains an associative array with:
|
||||||
|
* - name: MachineName for the library
|
||||||
|
* - downloadUrl: URL to a location a new version of the library may be downloaded from
|
||||||
|
* - currentVersion: The unsupported version of the library installed on the system.
|
||||||
|
* This is an associative array containing:
|
||||||
|
* - major: The major version of the library
|
||||||
|
* - minor: The minor version of the library
|
||||||
|
* - patch: The patch version of the library
|
||||||
*/
|
*/
|
||||||
public function getUnsupportedLibraries();
|
public function getUnsupportedLibraries();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URL to the library admin page
|
* Returns the URL to the library admin page
|
||||||
*
|
*
|
||||||
* @return string URL to admin page
|
* @return string
|
||||||
|
* URL to admin page
|
||||||
*/
|
*/
|
||||||
public function getAdminUrl();
|
public function getAdminUrl();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get id to an excisting library
|
* Get id to an existing library
|
||||||
*
|
*
|
||||||
* @param string $machineName
|
* @param string $machineName
|
||||||
* The librarys machine name
|
* The librarys machine name
|
||||||
|
@ -104,8 +137,12 @@ interface H5PFrameworkInterface {
|
||||||
* The default extension list is part of h5p, but admins should be allowed to modify it
|
* The default extension list is part of h5p, but admins should be allowed to modify it
|
||||||
*
|
*
|
||||||
* @param boolean $isLibrary
|
* @param boolean $isLibrary
|
||||||
|
* TRUE if this is the whitelist for a library. FALSE if it is the whitelist
|
||||||
|
* for the content folder we are getting
|
||||||
* @param string $defaultContentWhitelist
|
* @param string $defaultContentWhitelist
|
||||||
|
* A string of file extensions separated by whitespace
|
||||||
* @param string $defaultLibraryWhitelist
|
* @param string $defaultLibraryWhitelist
|
||||||
|
* A string of file extensions separated by whitespace
|
||||||
*/
|
*/
|
||||||
public function getWhitelist($isLibrary, $defaultContentWhitelist, $defaultLibraryWhitelist);
|
public function getWhitelist($isLibrary, $defaultContentWhitelist, $defaultLibraryWhitelist);
|
||||||
|
|
||||||
|
@ -113,9 +150,13 @@ interface H5PFrameworkInterface {
|
||||||
* Is the library a patched version of an existing library?
|
* Is the library a patched version of an existing library?
|
||||||
*
|
*
|
||||||
* @param object $library
|
* @param object $library
|
||||||
* The library data for a library we are checking
|
* An associateve array containing:
|
||||||
|
* - machineName: The library machineName
|
||||||
|
* - majorVersion: The librarys majorVersion
|
||||||
|
* - minorVersion: The librarys minorVersion
|
||||||
|
* - patchVersion: The librarys patchVersion
|
||||||
* @return boolean
|
* @return boolean
|
||||||
* TRUE if the library is a patched version of an excisting library
|
* TRUE if the library is a patched version of an existing library
|
||||||
* FALSE otherwise
|
* FALSE otherwise
|
||||||
*/
|
*/
|
||||||
public function isPatchedLibrary($library);
|
public function isPatchedLibrary($library);
|
||||||
|
@ -144,23 +185,53 @@ interface H5PFrameworkInterface {
|
||||||
* Also fills in the libraryId in the libraryData object if the object is new
|
* Also fills in the libraryId in the libraryData object if the object is new
|
||||||
*
|
*
|
||||||
* @param object $libraryData
|
* @param object $libraryData
|
||||||
* Object holding the information that is to be stored
|
* Associative array containing:
|
||||||
|
* - libraryId: The id of the library if it is an existing library.
|
||||||
|
* - title: The library's name
|
||||||
|
* - machineName: The library machineName
|
||||||
|
* - majorVersion: The library's majorVersion
|
||||||
|
* - minorVersion: The library's minorVersion
|
||||||
|
* - patchVersion: The library's patchVersion
|
||||||
|
* - runnable: 1 if the library is a content type, 0 otherwise
|
||||||
|
* - fullscreen(optional): 1 if the library supports fullscreen, 0 otherwise
|
||||||
|
* - embedTypes(optional): list of supported embed types
|
||||||
|
* - preloadedJs(optional): list of associative arrays containing:
|
||||||
|
* - path: path to a js file relative to the library root folder
|
||||||
|
* - preloadedCss(optional): list of associative arrays containing:
|
||||||
|
* - path: path to css file relative to the library root folder
|
||||||
|
* - dropLibraryCss(optional): list of associative arrays containing:
|
||||||
|
* - machineName: machine name for the librarys that are to drop their css
|
||||||
|
* - semantics(optional): Json describing the content structure for the library
|
||||||
|
* - language(optional): associative array containing:
|
||||||
|
* - languageCode: Translation in json format
|
||||||
*/
|
*/
|
||||||
public function saveLibraryData(&$libraryData, $new = TRUE);
|
public function saveLibraryData(&$libraryData, $new = TRUE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert new content.
|
* Insert new content.
|
||||||
*
|
*
|
||||||
* @param object $content
|
* @param array $content
|
||||||
|
* An associative array containing:
|
||||||
|
* - id: The content id
|
||||||
|
* - params: The content in json format
|
||||||
|
* - library: An associative array containing:
|
||||||
|
* - libraryId: The id of the main library for this content
|
||||||
* @param int $contentMainId
|
* @param int $contentMainId
|
||||||
|
* Main id for the content if this is a system that supports versioning
|
||||||
*/
|
*/
|
||||||
public function insertContent($content, $contentMainId = NULL);
|
public function insertContent($content, $contentMainId = NULL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update old content.
|
* Update old content.
|
||||||
*
|
*
|
||||||
* @param object $content
|
* @param array $content
|
||||||
|
* An associative array containing:
|
||||||
|
* - id: The content id
|
||||||
|
* - params: The content in json format
|
||||||
|
* - library: An associative array containing:
|
||||||
|
* - libraryId: The id of the main library for this content
|
||||||
* @param int $contentMainId
|
* @param int $contentMainId
|
||||||
|
* Main id for the content if this is a system that supports versioning
|
||||||
*/
|
*/
|
||||||
public function updateContent($content, $contentMainId = NULL);
|
public function updateContent($content, $contentMainId = NULL);
|
||||||
|
|
||||||
|
@ -170,21 +241,27 @@ interface H5PFrameworkInterface {
|
||||||
* @param int $libraryId
|
* @param int $libraryId
|
||||||
* Library Id for the library we're saving dependencies for
|
* Library Id for the library we're saving dependencies for
|
||||||
* @param array $dependencies
|
* @param array $dependencies
|
||||||
* List of dependencies in the format used in library.json
|
* List of dependencies as associative arrays containing:
|
||||||
|
* - machineName: The library machineName
|
||||||
|
* - majorVersion: The library's majorVersion
|
||||||
|
* - minorVersion: The library's minorVersion
|
||||||
* @param string $dependency_type
|
* @param string $dependency_type
|
||||||
* What type of dependency this is, for instance it might be an editor dependency
|
* What type of dependency this is, the following values are allowed:
|
||||||
|
* - editor
|
||||||
|
* - preloaded
|
||||||
|
* - dynamic
|
||||||
*/
|
*/
|
||||||
public function saveLibraryDependencies($libraryId, $dependencies, $dependency_type);
|
public function saveLibraryDependencies($libraryId, $dependencies, $dependency_type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies library usage
|
* Give an H5P the same library dependencies as a given H5P
|
||||||
*
|
*
|
||||||
* @param int $contentId
|
* @param int $contentId
|
||||||
* Framework specific id identifying the content
|
* Id identifying the content
|
||||||
* @param int $copyFromId
|
* @param int $copyFromId
|
||||||
* Framework specific id identifying the content to be copied
|
* Id identifying the content to be copied
|
||||||
* @param int $contentMainId
|
* @param int $contentMainId
|
||||||
* Framework specific main id for the content, typically used in frameworks
|
* Main id for the content, typically used in frameworks
|
||||||
* That supports versioning. (In this case the content id will typically be
|
* That supports versioning. (In this case the content id will typically be
|
||||||
* the version id, and the contentMainId will be the frameworks content id
|
* the version id, and the contentMainId will be the frameworks content id
|
||||||
*/
|
*/
|
||||||
|
@ -194,7 +271,7 @@ interface H5PFrameworkInterface {
|
||||||
* Deletes content data
|
* Deletes content data
|
||||||
*
|
*
|
||||||
* @param int $contentId
|
* @param int $contentId
|
||||||
* Framework specific id identifying the content
|
* Id identifying the content
|
||||||
*/
|
*/
|
||||||
public function deleteContentData($contentId);
|
public function deleteContentData($contentId);
|
||||||
|
|
||||||
|
@ -210,11 +287,17 @@ interface H5PFrameworkInterface {
|
||||||
* Saves what libraries the content uses
|
* Saves what libraries the content uses
|
||||||
*
|
*
|
||||||
* @param int $contentId
|
* @param int $contentId
|
||||||
* Framework specific id identifying the content
|
* Id identifying the content
|
||||||
* @param array $librariesInUse
|
* @param array $librariesInUse
|
||||||
* List of libraries the content uses. Libraries consist of arrays with:
|
* List of libraries the content uses. Libraries consist of associative arrays with:
|
||||||
* - libraryId stored in $librariesInUse[<place>]['library']['libraryId']
|
* - library: Associative array containing:
|
||||||
* - libraryId stored in $librariesInUse[<place>]['preloaded']
|
* - dropLibraryCss(optional): commasepareted list of machineNames
|
||||||
|
* - machineName: Machine name for the library
|
||||||
|
* - libraryId: Id of the library
|
||||||
|
* - type: The dependency type. Allowed values:
|
||||||
|
* - editor
|
||||||
|
* - dynamic
|
||||||
|
* - preloaded
|
||||||
*/
|
*/
|
||||||
public function saveLibraryUsage($contentId, $librariesInUse);
|
public function saveLibraryUsage($contentId, $librariesInUse);
|
||||||
|
|
||||||
|
@ -222,9 +305,12 @@ interface H5PFrameworkInterface {
|
||||||
* Get number of content/nodes using a library, and the number of
|
* Get number of content/nodes using a library, and the number of
|
||||||
* dependencies to other libraries
|
* dependencies to other libraries
|
||||||
*
|
*
|
||||||
* @param int $library_id
|
* @param int $libraryId
|
||||||
* @return array The array contains two elements, keyed by 'content' and 'libraries'.
|
* Library identifier
|
||||||
* Each element contains a number
|
* @return array
|
||||||
|
* Associative array containing:
|
||||||
|
* - content: Number of content using the library
|
||||||
|
* - libraries: Number of libraries depending on the library
|
||||||
*/
|
*/
|
||||||
public function getLibraryUsage($libraryId);
|
public function getLibraryUsage($libraryId);
|
||||||
|
|
||||||
|
@ -232,71 +318,140 @@ interface H5PFrameworkInterface {
|
||||||
* Loads a library
|
* Loads a library
|
||||||
*
|
*
|
||||||
* @param string $machineName
|
* @param string $machineName
|
||||||
|
* The library's machine name
|
||||||
* @param int $majorVersion
|
* @param int $majorVersion
|
||||||
|
* The library's major version
|
||||||
* @param int $minorVersion
|
* @param int $minorVersion
|
||||||
|
* The library's minor version
|
||||||
* @return array|FALSE
|
* @return array|FALSE
|
||||||
* Array representing the library with dependency descriptions
|
* FALSE if the library doesn't exist.
|
||||||
* FALSE if the library doesn't exist
|
* Otherwise an associative array containing:
|
||||||
|
* - libraryId: The id of the library if it is an existing library.
|
||||||
|
* - title: The library's name
|
||||||
|
* - machineName: The library machineName
|
||||||
|
* - majorVersion: The library's majorVersion
|
||||||
|
* - minorVersion: The library's minorVersion
|
||||||
|
* - patchVersion: The library's patchVersion
|
||||||
|
* - runnable: 1 if the library is a content type, 0 otherwise
|
||||||
|
* - fullscreen(optional): 1 if the library supports fullscreen, 0 otherwise
|
||||||
|
* - embedTypes(optional): list of supported embed types
|
||||||
|
* - preloadedJs(optional): comma separated string with js file paths
|
||||||
|
* - preloadedCss(optional): comma separated sting with css file paths
|
||||||
|
* - dropLibraryCss(optional): list of associative arrays containing:
|
||||||
|
* - machineName: machine name for the librarys that are to drop their css
|
||||||
|
* - semantics(optional): Json describing the content structure for the library
|
||||||
|
* - preloadedDependencies(optional): list of associative arrays containing:
|
||||||
|
* - machineName: Machine name for a library this library is depending on
|
||||||
|
* - majorVersion: Major version for a library this library is depending on
|
||||||
|
* - minorVersion: Minor for a library this library is depending on
|
||||||
|
* - dynamicDependencies(optional): list of associative arrays containing:
|
||||||
|
* - machineName: Machine name for a library this library is depending on
|
||||||
|
* - majorVersion: Major version for a library this library is depending on
|
||||||
|
* - minorVersion: Minor for a library this library is depending on
|
||||||
|
* - editorDependencies(optional): list of associative arrays containing:
|
||||||
|
* - machineName: Machine name for a library this library is depending on
|
||||||
|
* - majorVersion: Major version for a library this library is depending on
|
||||||
|
* - minorVersion: Minor for a library this library is depending on
|
||||||
*/
|
*/
|
||||||
public function loadLibrary($machineName, $majorVersion, $minorVersion);
|
public function loadLibrary($machineName, $majorVersion, $minorVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads library semantics.
|
* Loads library semantics.
|
||||||
*
|
*
|
||||||
* @param string $name library identifier.
|
* @param string $machineName
|
||||||
* @param int $majorVersion library identifier.
|
* Machine name for the library
|
||||||
* @param int $minorVersion library identifier.
|
* @param int $majorVersion
|
||||||
* @return string semantics.
|
* The library's major version
|
||||||
|
* @param int $minorVersion
|
||||||
|
* The library's minor version
|
||||||
|
* @return string
|
||||||
|
* The library's semantics as json
|
||||||
*/
|
*/
|
||||||
public function loadLibrarySemantics($name, $majorVersion, $minorVersion);
|
public function loadLibrarySemantics($machineName, $majorVersion, $minorVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes it possible to alter the semantics, adding custom fields, etc.
|
* Makes it possible to alter the semantics, adding custom fields, etc.
|
||||||
*
|
*
|
||||||
* @param array $semantics
|
* @param array $semantics
|
||||||
* @param string $name library identifier.
|
* Associative array representing the semantics
|
||||||
* @param int $majorVersion library identifier.
|
* @param string $machineName
|
||||||
* @param int $minorVersion library identifier.
|
* The library's machine name
|
||||||
|
* @param int $majorVersion
|
||||||
|
* The library's major version
|
||||||
|
* @param int $minorVersion
|
||||||
|
* The library's minor version
|
||||||
*/
|
*/
|
||||||
public function alterLibrarySemantics(&$semantics, $name, $majorVersion, $minorVersion);
|
public function alterLibrarySemantics(&$semantics, $machineName, $majorVersion, $minorVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete all dependencies belonging to given library
|
* Delete all dependencies belonging to given library
|
||||||
*
|
*
|
||||||
* @param int $libraryId
|
* @param int $libraryId
|
||||||
* Library Id
|
* Library identifier
|
||||||
*/
|
*/
|
||||||
public function deleteLibraryDependencies($libraryId);
|
public function deleteLibraryDependencies($libraryId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a library from database and file system
|
* Delete a library from database and file system
|
||||||
*
|
*
|
||||||
* @param mixed $library Library
|
* @param stdClass $library
|
||||||
|
* Library object with id, name, major version and minor version.
|
||||||
*/
|
*/
|
||||||
public function deleteLibrary($library);
|
public function deleteLibrary($library);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load content.
|
* Load content.
|
||||||
*
|
*
|
||||||
* @return object Content, null if not found.
|
* @param int $id
|
||||||
|
* Content identifier
|
||||||
|
* @return array
|
||||||
|
* Associative array containing:
|
||||||
|
* - contentId: Identifier for the content
|
||||||
|
* - params: json content as string
|
||||||
|
* - embedType: csv of embed types
|
||||||
|
* - title: The contents title
|
||||||
|
* - language: Language code for the content
|
||||||
|
* - libraryId: Id for the main library
|
||||||
|
* - libraryName: The library machine name
|
||||||
|
* - libraryMajorVersion: The library's majorVersion
|
||||||
|
* - libraryMinorVersion: The library's minorVersion
|
||||||
|
* - libraryEmbedTypes: CSV of the main library's embed types
|
||||||
|
* - libraryFullscreen: 1 if fullscreen is supported. 0 otherwise.
|
||||||
*/
|
*/
|
||||||
public function loadContent($id);
|
public function loadContent($id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load dependencies for the given content of the given type.
|
* Load dependencies for the given content of the given type.
|
||||||
*
|
*
|
||||||
* @param int $id content.
|
* @param int $id
|
||||||
* @param int $type dependency.
|
* Content identifier
|
||||||
|
* @param int $type
|
||||||
|
* Dependency types. Allowed values:
|
||||||
|
* - editor
|
||||||
|
* - preloaded
|
||||||
|
* - dynamic
|
||||||
* @return array
|
* @return array
|
||||||
|
* List of associative arrays containing:
|
||||||
|
* - libraryId: The id of the library if it is an existing library.
|
||||||
|
* - machineName: The library machineName
|
||||||
|
* - majorVersion: The library's majorVersion
|
||||||
|
* - minorVersion: The library's minorVersion
|
||||||
|
* - patchVersion: The library's patchVersion
|
||||||
|
* - preloadedJs(optional): comma separated string with js file paths
|
||||||
|
* - preloadedCss(optional): comma separated sting with css file paths
|
||||||
|
* - dropCss(optional): csv of machine names
|
||||||
*/
|
*/
|
||||||
public function loadContentDependencies($id, $type = NULL);
|
public function loadContentDependencies($id, $type = NULL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get stored setting.
|
* Get stored setting.
|
||||||
*
|
*
|
||||||
* @param string $name Identifier
|
* @param string $name
|
||||||
* @param string $default Optional
|
* Identifier for the setting
|
||||||
* @return mixed data
|
* @param string $default
|
||||||
|
* Optional default value if settings is not set
|
||||||
|
* @return mixed
|
||||||
|
* Whatever has been stored as the setting
|
||||||
*/
|
*/
|
||||||
public function getOption($name, $default = NULL);
|
public function getOption($name, $default = NULL);
|
||||||
|
|
||||||
|
@ -304,8 +459,10 @@ interface H5PFrameworkInterface {
|
||||||
* Stores the given setting.
|
* Stores the given setting.
|
||||||
* For example when did we last check h5p.org for updates to our libraries.
|
* For example when did we last check h5p.org for updates to our libraries.
|
||||||
*
|
*
|
||||||
* @param string $name Identifier
|
* @param string $name
|
||||||
|
* Identifier for the setting
|
||||||
* @param mixed $value Data
|
* @param mixed $value Data
|
||||||
|
* Whatever we want to store as the setting
|
||||||
*/
|
*/
|
||||||
public function setOption($name, $value);
|
public function setOption($name, $value);
|
||||||
|
|
||||||
|
@ -337,10 +494,10 @@ interface H5PFrameworkInterface {
|
||||||
/**
|
/**
|
||||||
* Get number of contents using library as main library.
|
* Get number of contents using library as main library.
|
||||||
*
|
*
|
||||||
* @param int $library_id
|
* @param int $libraryId
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getNumContent($library_id);
|
public function getNumContent($libraryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1369,7 +1526,9 @@ class H5PCore {
|
||||||
public static $defaultContentWhitelist = 'json png jpg jpeg gif bmp tif tiff svg eot ttf woff otf webm mp4 ogg mp3 txt pdf rtf doc docx xls xlsx ppt pptx odt ods odp xml csv diff patch swf md textile';
|
public static $defaultContentWhitelist = 'json png jpg jpeg gif bmp tif tiff svg eot ttf woff otf webm mp4 ogg mp3 txt pdf rtf doc docx xls xlsx ppt pptx odt ods odp xml csv diff patch swf md textile';
|
||||||
public static $defaultLibraryWhitelistExtras = 'js css';
|
public static $defaultLibraryWhitelistExtras = 'js css';
|
||||||
|
|
||||||
public $librariesJsonData, $contentJsonData, $mainJsonData, $h5pF, $path, $development_mode, $h5pD;
|
public $librariesJsonData, $contentJsonData, $mainJsonData, $h5pF, $path, $development_mode, $h5pD, $disableFileCheck;
|
||||||
|
const SECONDS_IN_WEEK = 604800;
|
||||||
|
|
||||||
private $exportEnabled;
|
private $exportEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1996,6 +2155,30 @@ class H5PCore {
|
||||||
$html .= '</ul><span><br>These libraries may cause problems on this site. See <a href="http://h5p.org/releases/h5p-core-1.3">here</a> for more info</div>';
|
$html .= '</ul><span><br>These libraries may cause problems on this site. See <a href="http://h5p.org/releases/h5p-core-1.3">here</a> for more info</div>';
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of libraries' metadata from h5p.org. Cache it, and refetch once a week.
|
||||||
|
*
|
||||||
|
* @return mixed An object of objects keyed by machineName
|
||||||
|
*/
|
||||||
|
public function getLibrariesMetadata() {
|
||||||
|
// Fetch from cache:
|
||||||
|
$metadata = $this->h5pF->cacheGet('libraries','metadata');
|
||||||
|
|
||||||
|
// If not available in cache, or older than a week => refetch!
|
||||||
|
if ($metadata === NULL || $metadata->lastTimeFetched < (time() - self::SECONDS_IN_WEEK)) {
|
||||||
|
$platformInfo = $this->h5pF->getPlatformInfo();
|
||||||
|
$json = file_get_contents('http://h5p.org/libraries-metadata.json?platform=' . json_encode($platformInfo));
|
||||||
|
|
||||||
|
$metadata = new stdClass();
|
||||||
|
$metadata->json = ($json === FALSE ? NULL : json_decode($json));
|
||||||
|
$metadata->lastTimeFetched = time();
|
||||||
|
|
||||||
|
$this->h5pF->cacheSet('libraries','metadata', $metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $metadata->json;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2114,6 +2297,10 @@ class H5PContentValidator {
|
||||||
* FALSE if one or more files fail validation. Error message should be set accordingly by validator.
|
* FALSE if one or more files fail validation. Error message should be set accordingly by validator.
|
||||||
*/
|
*/
|
||||||
public function validateContentFiles($contentPath, $isLibrary = FALSE) {
|
public function validateContentFiles($contentPath, $isLibrary = FALSE) {
|
||||||
|
if ($this->h5pC->disableFileCheck === TRUE) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// Scan content directory for files, recurse into sub directories.
|
// Scan content directory for files, recurse into sub directories.
|
||||||
$files = array_diff(scandir($contentPath), array('.','..'));
|
$files = array_diff(scandir($contentPath), array('.','..'));
|
||||||
$valid = TRUE;
|
$valid = TRUE;
|
||||||
|
|
|
@ -0,0 +1,255 @@
|
||||||
|
var H5PDataView = (function ($) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new H5P data view.
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
* @param {Object} container
|
||||||
|
* Element to clear out and append to.
|
||||||
|
* @param {String} source
|
||||||
|
* URL to get data from. Data format: {num: 123, rows:[[1,2,3],[2,4,6]]}
|
||||||
|
* @param {Array} headers
|
||||||
|
* List with column headers. Can be strings or objects with options like
|
||||||
|
* "text" and "sortable". E.g.
|
||||||
|
* [{text: 'Col 1', sortable: true}, 'Col 2', 'Col 3']
|
||||||
|
* @param {Object} l10n
|
||||||
|
* Localization / translations. e.g.
|
||||||
|
* {
|
||||||
|
* loading: 'Loading data.',
|
||||||
|
* ajaxFailed: 'Failed to load data.',
|
||||||
|
* noData: "There's no data available that matches your criteria.",
|
||||||
|
* currentPage: 'Page $current of $total',
|
||||||
|
* nextPage: 'Next page',
|
||||||
|
* previousPage: 'Previous page',
|
||||||
|
* search: 'Search'
|
||||||
|
* }
|
||||||
|
* @param {Object} classes
|
||||||
|
* Custom html classes to use on elements.
|
||||||
|
* e.g. {tableClass: 'fixed'}.
|
||||||
|
* @param {Array} filters
|
||||||
|
* Make it possible to filter/search in the given column.
|
||||||
|
* e.g. [null, true, null, null] will make it possible to do a text
|
||||||
|
* search in column 2.
|
||||||
|
* @param {Function} loaded
|
||||||
|
* Callback for when data has been loaded.
|
||||||
|
*/
|
||||||
|
function H5PDataView(container, source, headers, l10n, classes, filters, loaded) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.$container = $(container).addClass('h5p-data-view').html('');
|
||||||
|
|
||||||
|
self.source = source;
|
||||||
|
self.headers = headers;
|
||||||
|
self.l10n = l10n;
|
||||||
|
self.classes = (classes === undefined ? {} : classes);
|
||||||
|
self.filters = (filters === undefined ? [] : filters);
|
||||||
|
self.loaded = loaded;
|
||||||
|
|
||||||
|
self.limit = 20;
|
||||||
|
self.offset = 0;
|
||||||
|
self.filterOn = [];
|
||||||
|
|
||||||
|
self.loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load data from source URL.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
H5PDataView.prototype.loadData = function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// Throbb
|
||||||
|
self.setMessage(H5PUtils.throbber(self.l10n.loading));
|
||||||
|
|
||||||
|
// Create URL
|
||||||
|
var url = self.source;
|
||||||
|
url += (url.indexOf('?') === -1 ? '?' : '&') + 'offset=' + self.offset + '&limit=' + self.limit;
|
||||||
|
|
||||||
|
// Add sorting
|
||||||
|
if (self.sortBy !== undefined && self.sortDir !== undefined) {
|
||||||
|
url += '&sortBy=' + self.sortBy + '&sortDir=' + self.sortDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add filters
|
||||||
|
var filtering;
|
||||||
|
for (var i = 0; i < self.filterOn.length; i++) {
|
||||||
|
if (self.filterOn[i] === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
filtering = true;
|
||||||
|
url += '&filters[' + i + ']=' + encodeURIComponent(self.filterOn[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fire ajax request
|
||||||
|
$.ajax({
|
||||||
|
dataType: 'json',
|
||||||
|
cache: true,
|
||||||
|
url: url
|
||||||
|
}).fail(function () {
|
||||||
|
// Error handling
|
||||||
|
self.setMessage($('<p/>', {text: self.l10n.ajaxFailed}));
|
||||||
|
}).done(function (data) {
|
||||||
|
if (!data.rows.length) {
|
||||||
|
self.setMessage($('<p/>', {text: filtering ? self.l10n.noData : self.l10n.empty}));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Update table data
|
||||||
|
self.updateTable(data.rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update pagination widget
|
||||||
|
self.updatePagination(data.num);
|
||||||
|
|
||||||
|
if (self.loaded !== undefined) {
|
||||||
|
self.loaded();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the given message to the user.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @param {jQuery} $message wrapper with message
|
||||||
|
*/
|
||||||
|
H5PDataView.prototype.setMessage = function ($message) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (self.table === undefined) {
|
||||||
|
self.$container.html('').append($message);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.table.setBody($message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update table data.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @param {Array} rows
|
||||||
|
*/
|
||||||
|
H5PDataView.prototype.updateTable = function (rows) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (self.table === undefined) {
|
||||||
|
// Clear out container
|
||||||
|
self.$container.html('');
|
||||||
|
|
||||||
|
// Add filters
|
||||||
|
self.addFilters();
|
||||||
|
|
||||||
|
// Create new table
|
||||||
|
self.table = new H5PUtils.Table(self.classes, self.headers);
|
||||||
|
self.table.setHeaders(self.headers, function (col, dir) {
|
||||||
|
// Sorting column or direction has changed callback.
|
||||||
|
self.sortBy = col;
|
||||||
|
self.sortDir = dir;
|
||||||
|
self.loadData();
|
||||||
|
});
|
||||||
|
self.table.appendTo(self.$container);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add/update rows
|
||||||
|
self.table.setRows(rows);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update pagination widget.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @param {Number} num size of data collection
|
||||||
|
*/
|
||||||
|
H5PDataView.prototype.updatePagination = function (num) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (self.pagination === undefined) {
|
||||||
|
// Create new widget
|
||||||
|
var $pagerContainer = $('<div/>', {'class': 'h5p-pagination'});
|
||||||
|
self.pagination = new H5PUtils.Pagination(num, self.limit, function (offset) {
|
||||||
|
// Handle page changes in pagination widget
|
||||||
|
self.offset = offset;
|
||||||
|
self.loadData();
|
||||||
|
}, self.l10n);
|
||||||
|
|
||||||
|
self.pagination.appendTo($pagerContainer);
|
||||||
|
self.table.setFoot($pagerContainer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Update existing widget
|
||||||
|
self.pagination.update(num, self.limit);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add filters.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
H5PDataView.prototype.addFilters = function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
for (var i = 0; i < self.filters.length; i++) {
|
||||||
|
if (self.filters[i] === true) {
|
||||||
|
// Add text input filter for col i
|
||||||
|
self.addTextFilter(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add text filter for given col num.
|
||||||
|
|
||||||
|
* @public
|
||||||
|
* @param {Number} col
|
||||||
|
*/
|
||||||
|
H5PDataView.prototype.addTextFilter = function (col) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find input value and filter on it.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
var search = function () {
|
||||||
|
var filterOn = $input.val().replace(/^\s+|\s+$/g, '');
|
||||||
|
if (filterOn === '') {
|
||||||
|
filterOn = undefined;
|
||||||
|
}
|
||||||
|
if (filterOn !== self.filterOn[col]) {
|
||||||
|
self.filterOn[col] = filterOn;
|
||||||
|
self.loadData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add text field for filtering
|
||||||
|
var typing;
|
||||||
|
var $input = $('<input/>', {
|
||||||
|
type: 'text',
|
||||||
|
placeholder: self.l10n.search,
|
||||||
|
on: {
|
||||||
|
'blur': function () {
|
||||||
|
clearTimeout(typing);
|
||||||
|
search();
|
||||||
|
},
|
||||||
|
'keyup': function (event) {
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
clearTimeout(typing);
|
||||||
|
search();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clearTimeout(typing);
|
||||||
|
typing = setTimeout(function () {
|
||||||
|
search();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).appendTo(self.$container);
|
||||||
|
};
|
||||||
|
|
||||||
|
return H5PDataView;
|
||||||
|
})(H5P.jQuery);
|
|
@ -1,5 +1,5 @@
|
||||||
/*jshint multistr: true */
|
/*jshint multistr: true */
|
||||||
var H5PLibraryList= H5PLibraryList || {};
|
var H5PLibraryList = H5PLibraryList || {};
|
||||||
|
|
||||||
(function ($) {
|
(function ($) {
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ var H5PLibraryList= H5PLibraryList || {};
|
||||||
$.each (libraries.listData, function (index, library) {
|
$.each (libraries.listData, function (index, library) {
|
||||||
var $libraryRow = H5PUtils.createTableRow([
|
var $libraryRow = H5PUtils.createTableRow([
|
||||||
library.title,
|
library.title,
|
||||||
|
'<input class="h5p-admin-restricted" type="checkbox"/>',
|
||||||
{
|
{
|
||||||
text: library.numContent,
|
text: library.numContent,
|
||||||
class: 'h5p-admin-center'
|
class: 'h5p-admin-center'
|
||||||
|
@ -56,6 +57,8 @@ var H5PLibraryList= H5PLibraryList || {};
|
||||||
</div>'
|
</div>'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
H5PLibraryList.addRestricted($('.h5p-admin-restricted', $libraryRow), library.restrictedUrl, library.restricted);
|
||||||
|
|
||||||
var hasContent = !(library.numContent === '' || library.numContent === 0);
|
var hasContent = !(library.numContent === '' || library.numContent === 0);
|
||||||
if (library.upgradeUrl === null) {
|
if (library.upgradeUrl === null) {
|
||||||
$('.h5p-admin-upgrade-library', $libraryRow).remove();
|
$('.h5p-admin-upgrade-library', $libraryRow).remove();
|
||||||
|
@ -92,6 +95,34 @@ var H5PLibraryList= H5PLibraryList || {};
|
||||||
return $table;
|
return $table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
H5PLibraryList.addRestricted = function ($checkbox, url, selected) {
|
||||||
|
if (selected === null) {
|
||||||
|
$checkbox.remove();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$checkbox.change(function () {
|
||||||
|
$checkbox.attr('disabled', true);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
dataType: 'json',
|
||||||
|
url: url,
|
||||||
|
cache: false
|
||||||
|
}).fail(function () {
|
||||||
|
$checkbox.attr('disabled', false);
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
$checkbox.attr('checked', !$checkbox.is(':checked'));
|
||||||
|
}).done(function (result) {
|
||||||
|
url = result.url;
|
||||||
|
$checkbox.attr('disabled', false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (selected) {
|
||||||
|
$checkbox.attr('checked', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Initialize me:
|
// Initialize me:
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|
349
js/h5p-utils.js
349
js/h5p-utils.js
|
@ -130,4 +130,353 @@ var H5PUtils = H5PUtils || {};
|
||||||
return $container;
|
return $container;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic table class with useful helpers.
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
* @param {Object} classes
|
||||||
|
* Custom html classes to use on elements.
|
||||||
|
* e.g. {tableClass: 'fixed'}.
|
||||||
|
*/
|
||||||
|
H5PUtils.Table = function (classes) {
|
||||||
|
var numCols;
|
||||||
|
var sortByCol;
|
||||||
|
var $sortCol;
|
||||||
|
var sortCol;
|
||||||
|
var sortDir;
|
||||||
|
|
||||||
|
// Create basic table
|
||||||
|
var tableOptions = {};
|
||||||
|
if (classes.table !== undefined) {
|
||||||
|
tableOptions['class'] = classes.table;
|
||||||
|
}
|
||||||
|
var $table = $('<table/>', tableOptions);
|
||||||
|
var $thead = $('<thead/>').appendTo($table);
|
||||||
|
var $tfoot = $('<tfoot/>').appendTo($table);
|
||||||
|
var $tbody = $('<tbody/>').appendTo($table);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add columns to given table row.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {jQuery} $tr Table row
|
||||||
|
* @param {(String|Object)} col Column properties
|
||||||
|
* @param {Number} id Used to seperate the columns
|
||||||
|
*/
|
||||||
|
var addCol = function ($tr, col, id) {
|
||||||
|
var options = {
|
||||||
|
on: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!(col instanceof Object)) {
|
||||||
|
options.text = col;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (col.text !== undefined) {
|
||||||
|
options.text = col.text;
|
||||||
|
}
|
||||||
|
if (col.class !== undefined) {
|
||||||
|
options.class = col.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sortByCol !== undefined && col.sortable === true) {
|
||||||
|
// Make sortable
|
||||||
|
options.role = 'button';
|
||||||
|
options.tabIndex = 1;
|
||||||
|
|
||||||
|
// This is the first sortable column, use as default sort
|
||||||
|
if (sortCol === undefined) {
|
||||||
|
sortCol = id;
|
||||||
|
sortDir = 0;
|
||||||
|
options['class'] = 'h5p-sort';
|
||||||
|
}
|
||||||
|
|
||||||
|
options.on.click = function () {
|
||||||
|
sort($th, id);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append
|
||||||
|
var $th = $('<th>', options).appendTo($tr);
|
||||||
|
if (sortCol === id) {
|
||||||
|
$sortCol = $th; // Default sort column
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the UI when a column header has been clicked.
|
||||||
|
* Triggers sorting callback.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {jQuery} $th Table header
|
||||||
|
* @param {Number} id Used to seperate the columns
|
||||||
|
*/
|
||||||
|
var sort = function ($th, id) {
|
||||||
|
if (id === sortCol) {
|
||||||
|
// Change sorting direction
|
||||||
|
if (sortDir === 0) {
|
||||||
|
sortDir = 1;
|
||||||
|
$th.addClass('h5p-reverse');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sortDir = 0;
|
||||||
|
$th.removeClass('h5p-reverse');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Change sorting column
|
||||||
|
$sortCol.removeClass('h5p-sort').removeClass('h5p-reverse');
|
||||||
|
$sortCol = $th.addClass('h5p-sort');
|
||||||
|
sortCol = id;
|
||||||
|
sortDir = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sortByCol(sortCol, sortDir);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set table headers.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @param {Array} cols
|
||||||
|
* Table header data. Can be strings or objects with options like
|
||||||
|
* "text" and "sortable". E.g.
|
||||||
|
* [{text: 'Col 1', sortable: true}, 'Col 2', 'Col 3']
|
||||||
|
* @param {Function} sort Callback which is runned when sorting changes
|
||||||
|
*/
|
||||||
|
this.setHeaders = function (cols, sort) {
|
||||||
|
numCols = cols.length;
|
||||||
|
sortByCol = sort;
|
||||||
|
|
||||||
|
// Create new head
|
||||||
|
var $newThead = $('<thead/>');
|
||||||
|
var $tr = $('<tr/>').appendTo($newThead);
|
||||||
|
for (var i = 0; i < cols.length; i++) {
|
||||||
|
addCol($tr, cols[i], i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update DOM
|
||||||
|
$thead.replaceWith($newThead);
|
||||||
|
$thead = $newThead;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set table rows.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @param {Array} rows Table rows with cols: [[1,'hello',3],[2,'asd',6]]
|
||||||
|
*/
|
||||||
|
this.setRows = function (rows) {
|
||||||
|
var $newTbody = $('<tbody/>');
|
||||||
|
|
||||||
|
for (var i = 0; i < rows.length; i++) {
|
||||||
|
var $tr = $('<tr/>').appendTo($newTbody);
|
||||||
|
|
||||||
|
for (var j = 0; j < rows[i].length; j++) {
|
||||||
|
$('<td>', {
|
||||||
|
html: rows[i][j]
|
||||||
|
}).appendTo($tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tbody.replaceWith($newTbody);
|
||||||
|
$tbody = $newTbody;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set custom table body content. This can be a message or a throbber.
|
||||||
|
* Will cover all table columns.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @param {jQuery} $content Custom content
|
||||||
|
*/
|
||||||
|
this.setBody = function ($content) {
|
||||||
|
var $newTbody = $('<tbody/>');
|
||||||
|
var $tr = $('<tr/>').appendTo($newTbody);
|
||||||
|
$('<td>', {
|
||||||
|
colspan: numCols
|
||||||
|
}).append($content).appendTo($tr);
|
||||||
|
$tbody.replaceWith($newTbody);
|
||||||
|
$tbody = $newTbody;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set custom table foot content. This can be a pagination widget.
|
||||||
|
* Will cover all table columns.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @param {jQuery} $content Custom content
|
||||||
|
*/
|
||||||
|
this.setFoot = function ($content) {
|
||||||
|
var $newTfoot = $('<tfoot/>');
|
||||||
|
var $tr = $('<tr/>').appendTo($newTfoot);
|
||||||
|
$('<td>', {
|
||||||
|
colspan: numCols
|
||||||
|
}).append($content).appendTo($tr);
|
||||||
|
$tfoot.replaceWith($newTfoot);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends the table to the given container.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @param {jQuery} $container
|
||||||
|
*/
|
||||||
|
this.appendTo = function ($container) {
|
||||||
|
$table.appendTo($container);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic pagination class. Creates a useful pagination widget.
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
* @param {Number} num Total number of items to pagiate.
|
||||||
|
* @param {Number} limit Number of items to dispaly per page.
|
||||||
|
* @param {Function} goneTo
|
||||||
|
* Callback which is fired when the user wants to go to another page.
|
||||||
|
* @param {Object} l10n
|
||||||
|
* Localization / translations. e.g.
|
||||||
|
* {
|
||||||
|
* currentPage: 'Page $current of $total',
|
||||||
|
* nextPage: 'Next page',
|
||||||
|
* previousPage: 'Previous page'
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
H5PUtils.Pagination = function (num, limit, goneTo, l10n) {
|
||||||
|
var current = 0;
|
||||||
|
var pages = Math.ceil(num / limit);
|
||||||
|
|
||||||
|
// Create components
|
||||||
|
|
||||||
|
// Previous button
|
||||||
|
var $left = $('<button/>', {
|
||||||
|
html: '<',
|
||||||
|
'class': 'button',
|
||||||
|
title: l10n.previousPage
|
||||||
|
}).click(function () {
|
||||||
|
goTo(current - 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Current page text
|
||||||
|
var $text = $('<span/>').click(function () {
|
||||||
|
$input.width($text.width()).show().val(current + 1).focus();
|
||||||
|
$text.hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Jump to page input
|
||||||
|
var $input = $('<input/>', {
|
||||||
|
type: 'number',
|
||||||
|
min : 1,
|
||||||
|
max: pages,
|
||||||
|
on: {
|
||||||
|
'blur': function () {
|
||||||
|
gotInput();
|
||||||
|
},
|
||||||
|
'keyup': function (event) {
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
gotInput();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).hide();
|
||||||
|
|
||||||
|
// Next button
|
||||||
|
var $right = $('<button/>', {
|
||||||
|
html: '>',
|
||||||
|
'class': 'button',
|
||||||
|
title: l10n.nextPage
|
||||||
|
}).click(function () {
|
||||||
|
goTo(current + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check what page the user has typed in and jump to it.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
var gotInput = function () {
|
||||||
|
var page = parseInt($input.hide().val());
|
||||||
|
if (!isNaN(page)) {
|
||||||
|
goTo(page - 1);
|
||||||
|
}
|
||||||
|
$text.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update UI elements.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
var updateUI = function () {
|
||||||
|
var next = current + 1;
|
||||||
|
|
||||||
|
// Disable or enable buttons
|
||||||
|
$left.attr('disabled', current === 0);
|
||||||
|
$right.attr('disabled', next === pages);
|
||||||
|
|
||||||
|
// Update counter
|
||||||
|
$text.html(l10n.currentPage.replace('$current', next).replace('$total', pages));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to go to the requested page.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Number} page
|
||||||
|
*/
|
||||||
|
var goTo = function (page) {
|
||||||
|
if (page === current || page < 0 || page >= pages) {
|
||||||
|
return; // Invalid page number
|
||||||
|
}
|
||||||
|
current = page;
|
||||||
|
|
||||||
|
updateUI();
|
||||||
|
|
||||||
|
// Fire callback
|
||||||
|
goneTo(page * limit);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update number of items and limit.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @param {Number} newNum Total number of items to pagiate.
|
||||||
|
* @param {Number} newLimit Number of items to dispaly per page.
|
||||||
|
*/
|
||||||
|
this.update = function (newNum, newLimit) {
|
||||||
|
if (newNum !== num || newLimit !== limit) {
|
||||||
|
// Update num and limit
|
||||||
|
num = newNum;
|
||||||
|
limit = newLimit;
|
||||||
|
pages = Math.ceil(num / limit);
|
||||||
|
$input.attr('max', pages);
|
||||||
|
|
||||||
|
if (current >= pages) {
|
||||||
|
// Content is gone, move to last page.
|
||||||
|
goTo(pages - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUI();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append the pagination widget to the given container.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @param {jQuery} $container
|
||||||
|
*/
|
||||||
|
this.appendTo = function ($container) {
|
||||||
|
$left.add($text).add($input).add($right).appendTo($container);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update UI
|
||||||
|
updateUI();
|
||||||
|
};
|
||||||
|
|
||||||
})(H5P.jQuery);
|
})(H5P.jQuery);
|
||||||
|
|
45
js/h5p.js
45
js/h5p.js
|
@ -28,6 +28,9 @@ else if (document.documentElement.msRequestFullscreen) {
|
||||||
H5P.fullScreenBrowserPrefix = 'ms';
|
H5P.fullScreenBrowserPrefix = 'ms';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep track of when the H5Ps where started
|
||||||
|
H5P.opened = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize H5P content.
|
* Initialize H5P content.
|
||||||
* Scans for ".h5p-content" in the document and initializes H5P instances where found.
|
* Scans for ".h5p-content" in the document and initializes H5P instances where found.
|
||||||
|
@ -87,6 +90,16 @@ H5P.init = function () {
|
||||||
}
|
}
|
||||||
$actions.insertAfter($container);
|
$actions.insertAfter($container);
|
||||||
|
|
||||||
|
// Keep track of when we started
|
||||||
|
H5P.opened[contentId] = new Date();
|
||||||
|
|
||||||
|
// Handle events when the user finishes the content. Useful for logging exercise results.
|
||||||
|
instance.$.on('finish', function (event) {
|
||||||
|
if (event.data !== undefined) {
|
||||||
|
H5P.setFinished(contentId, event.data.score, event.data.maxScore, event.data.time);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (H5P.isFramed) {
|
if (H5P.isFramed) {
|
||||||
// Make it possible to resize the iframe when the content changes size. This way we get no scrollbars.
|
// Make it possible to resize the iframe when the content changes size. This way we get no scrollbars.
|
||||||
var iframe = window.parent.document.getElementById('h5p-iframe-' + contentId);
|
var iframe = window.parent.document.getElementById('h5p-iframe-' + contentId);
|
||||||
|
@ -1021,16 +1034,38 @@ H5P.shuffleArray = function (array) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED! Do not use this function directly, trigger the finish event
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
* Post finished results for user.
|
* Post finished results for user.
|
||||||
* TODO: Should we use events instead? That way the parent can handle the results of the child.
|
|
||||||
*
|
*
|
||||||
* @param {Number} contentId
|
* @param {Number} contentId
|
||||||
* @param {Number} points
|
* @param {Number} score achieved
|
||||||
* @param {Number} maxPoints
|
* @param {Number} maxScore that can be achieved
|
||||||
|
* @param {Number} time optional reported time usage
|
||||||
*/
|
*/
|
||||||
H5P.setFinished = function (contentId, points, maxPoints) {
|
H5P.setFinished = function (contentId, score, maxScore, time) {
|
||||||
if (H5P.postUserStatistics === true) {
|
if (H5P.postUserStatistics === true) {
|
||||||
H5P.jQuery.post(H5P.ajaxPath + 'setFinished', {contentId: contentId, points: points, maxPoints: maxPoints});
|
/**
|
||||||
|
* Return unix timestamp for the given JS Date.
|
||||||
|
*
|
||||||
|
* @param {Date} date
|
||||||
|
* @returns {Number}
|
||||||
|
*/
|
||||||
|
var toUnix = function (date) {
|
||||||
|
return Math.round(date.getTime() / 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Post the results
|
||||||
|
// TODO: Should we use a variable with the complete path?
|
||||||
|
H5P.jQuery.post(H5P.ajaxPath + 'setFinished', {
|
||||||
|
contentId: contentId,
|
||||||
|
score: score,
|
||||||
|
maxScore: maxScore,
|
||||||
|
opened: toUnix(H5P.opened[contentId]),
|
||||||
|
finished: toUnix(new Date()),
|
||||||
|
time: time
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h5p-admin-table tr:nth-child(odd) {
|
.h5p-admin-table tr:nth-child(odd),
|
||||||
|
.h5p-data-view tr:nth-child(odd) {
|
||||||
background-color: #F9F9F9;
|
background-color: #F9F9F9;
|
||||||
}
|
}
|
||||||
.h5p-admin-table tbody tr:hover {
|
.h5p-admin-table tbody tr:hover {
|
||||||
|
@ -248,3 +249,37 @@ button.h5p-admin.disabled:hover {
|
||||||
#h5p-admin-container .h5p-admin-center {
|
#h5p-admin-container .h5p-admin-center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
.h5p-pagination {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.h5p-pagination > span, .h5p-pagination > input {
|
||||||
|
margin: 0 1em;
|
||||||
|
}
|
||||||
|
.h5p-data-view input[type="text"] {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
.h5p-data-view input[type="text"]::-ms-clear {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h5p-data-view th[role="button"] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.h5p-data-view th[role="button"].h5p-sort:after,
|
||||||
|
.h5p-data-view th[role="button"]:hover:after,
|
||||||
|
.h5p-data-view th[role="button"].h5p-sort.h5p-reverse:hover:after {
|
||||||
|
content: "\25BE";
|
||||||
|
position: relative;
|
||||||
|
left: 0.5em;
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
|
.h5p-data-view th[role="button"].h5p-sort.h5p-reverse:after,
|
||||||
|
.h5p-data-view th[role="button"].h5p-sort:hover:after {
|
||||||
|
content: "\25B4";
|
||||||
|
top: -2px;
|
||||||
|
}
|
||||||
|
.h5p-data-view th[role="button"]:hover:after,
|
||||||
|
.h5p-data-view th[role="button"].h5p-sort.h5p-reverse:hover:after,
|
||||||
|
.h5p-data-view th[role="button"].h5p-sort:hover:after {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue