<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
- <list default="true" id="80613077-3057-4ff0-bc6f-8170571db117" name="Changes" comment="wip #5045 @0.5">
+ <list default="true" id="80613077-3057-4ff0-bc6f-8170571db117" name="Changes" comment="wip #5045">
+ <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/composer.json" beforeDir="false" afterPath="$PROJECT_DIR$/composer.json" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/Manifest.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Manifest.php" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1643378413530</updated>
- <workItem from="1643378414748" duration="413000" />
+ <workItem from="1643378414748" duration="4185000" />
</task>
<task id="LOCAL-00001" summary="wip #5045 @0.5">
<created>1643378772319</created>
<option name="project" value="LOCAL" />
<updated>1643378772319</updated>
</task>
- <option name="localTasksCounter" value="2" />
+ <task id="LOCAL-00002" summary="wip #5045">
+ <created>1643378839286</created>
+ <option name="number" value="00002" />
+ <option name="presentableId" value="LOCAL-00002" />
+ <option name="project" value="LOCAL" />
+ <updated>1643378839286</updated>
+ </task>
+ <option name="localTasksCounter" value="3" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<component name="VcsManagerConfiguration">
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
<MESSAGE value="wip #5045 @0.5" />
- <option name="LAST_COMMIT_MESSAGE" value="wip #5045 @0.5" />
+ <MESSAGE value="wip #5045" />
+ <option name="LAST_COMMIT_MESSAGE" value="wip #5045" />
</component>
</project>
\ No newline at end of file
<?php
+
namespace Cubist\Scorm;
class Manifest
{
+ const SCORM_1_2 = "1.2";
+ const SCORM_2004 = "2004";
+
+ protected $version = self::SCORM_2004;
+
+ /**
+ * @var string
+ */
+ protected $title;
+
+ /**
+ * @var string
+ */
+ protected $organization = 'ACME_Organization';
+
+ /**
+ * @var string|null
+ */
+ protected $reference = null;
+
+ /**
+ * @var string
+ */
+ protected $start = 'index.html';
+
+ public function __construct($title, $version = self::SCORM_2004, $organization = null, $reference = null, $start = 'index.html')
+ {
+ $this->setVersion($version);
+ $this->setTitle($title);
+ if (null !== $organization) {
+ $this->setOrganization($organization);
+ }
+ if (null !== $reference) {
+ $this->setReference($reference);
+ }
+ $this->setStart($start);
+ }
+
+ public function __toString()
+ {
+ if ($this->getVersion() === self::SCORM_1_2) {
+ return $this->_render12();
+ } else {
+ return $this->_render2004();
+ }
+
+ }
+
+ public function getManifestID()
+ {
+ $hash = '!!' . $this->getTitle() . '//' . $this->getOrganization() . '///' . $this->getReference() . '|||' . $this->getVersion() . '::';
+ return 'MANIFEST-' . mb_strtoupper(sha1($hash));
+ }
+
+ protected function _render2004()
+ {
+ return '<?xml version="1.0" standalone="no" ?>
+<manifest identifier="' . $this->_escape($this->getManifestID()) . '" version="1.3"
+ xmlns="http://www.imsglobal.org/xsd/imscp_v1p1"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3"
+ xmlns:adlseq="http://www.adlnet.org/xsd/adlseq_v1p3"
+ xmlns:adlnav="http://www.adlnet.org/xsd/adlnav_v1p3"
+ xmlns:imsss="http://www.imsglobal.org/xsd/imsss"
+ xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd
+ http://www.adlnet.org/xsd/adlcp_v1p3 adlcp_v1p3.xsd
+ http://www.adlnet.org/xsd/adlseq_v1p3 adlseq_v1p3.xsd
+ http://www.adlnet.org/xsd/adlnav_v1p3 adlnav_v1p3.xsd
+ http://www.imsglobal.org/xsd/imsss imsss_v1p0.xsd">
+ <metadata>
+ <schema>ADL SCORM</schema>
+ <schemaversion>2004 4th Edition</schemaversion>
+ </metadata>
+ <organizations default="' . $this->_escapeAttr($this->getOrganization()) . '">
+ <organization identifier="' . $this->_escapeAttr($this->getOrganization()) . '" adlseq:objectivesGlobalToSystem="false">
+ <title>' . $this->_escape($this->getTitle()) . '</title>
+ <item identifier="' . $this->_escapeAttr($this->getReference()) . '" identifierref="' . $this->_escapeAttr($this->getReference()) . '_RES" isvisible="true">
+ <title>' . $this->_escape($this->getTitle()) . '</title>
+ <adlnav:presentation>
+ <adlnav:navigationInterface>
+ <adlnav:hideLMSUI>continue</adlnav:hideLMSUI>
+ <adlnav:hideLMSUI>previous</adlnav:hideLMSUI>
+ <adlnav:hideLMSUI>exit</adlnav:hideLMSUI>
+ <adlnav:hideLMSUI>exitAll</adlnav:hideLMSUI>
+ <adlnav:hideLMSUI>suspendAll</adlnav:hideLMSUI>
+ <adlnav:hideLMSUI>abandonAll</adlnav:hideLMSUI>
+ </adlnav:navigationInterface>
+ </adlnav:presentation>
+ </item>
+ </organization>
+ </organizations>
+ <resources>
+ <resource identifier="' . $this->_escapeAttr($this->getReference()) . '_RES" type="webcontent" adlcp:scormType="sco" href="' . $this->getStart() . '">
+ <file href="' . $this->getStart() . '"/>
+ </resource>
+ </resources>
+</manifest>';
+ }
+
+ /**
+ * @return string
+ */
+ protected function _render12()
+ {
+ $res = '<?xml version="1.0" encoding="UTF-8"?>
+<manifest
+ xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2"
+ xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_rootv1p2p1"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_rootv1p2"
+ identifier="MANIFEST-90878C16-EB60-D648-94ED-9651972B5F42"
+ xsi:schemaLocation="http://www.imsproject.org/xsd/imscp_rootv1p1p2 imscp_rootv1p1p2.xsd
+ http://www.imsglobal.org/xsd/imsmd_rootv1p2p1 imsmd_rootv1p2p1.xsd
+ http://www.adlnet.org/xsd/adlcp_rootv1p2 adlcp_rootv1p2.xsd">
+ <metadata>
+ <schema>ADL SCORM</schema>
+ <schemaversion>1.2</schemaversion>
+ </metadata>
+ <organizations default="' . $this->_escapeAttr($this->getOrganization()) . '">
+ <organization identifier="' . $this->_escapeAttr($this->getOrganization()) . '" structure="hierarchical">
+ <title>' . $this->_escape($this->getTitle()) . '</title>
+ <item identifier="' . $this->_escapeAttr($this->getReference()) . '" identifierref="' . $this->_escapeAttr($this->getReference()) . '" isvisible="true">
+ <title>' . $this->_escape($this->getTitle()) . '</title>
+ </item>
+ </organization>
+ </organizations>
+ <resources>
+ <resource type="webcontent" adlcp:scormtype="sco" identifier="' . $this->_escapeAttr($this->getReference()) . '" href="' . $this->getStart() . '">
+ <file href="' . $this->getStart() . '"/>
+ </resource>
+ </resources>
+</manifest>';
+
+ return $res;
+ }
+
+ protected function _escape($string, $flags = ENT_XML1)
+ {
+ return htmlspecialchars($string, $flags);
+ }
+
+ protected function _escapeAttr($string)
+ {
+ return $this->_escape($string, ENT_XML1 | ENT_COMPAT);
+ }
+
+ /**
+ * @return string
+ */
+ public function getTitle()
+ {
+ return $this->title;
+ }
+
+ /**
+ * @return string
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * @param string $title
+ */
+ public function setTitle($title)
+ {
+ $this->title = $title;
+ }
+
+ /**
+ * @param string $version
+ */
+ public function setVersion($version)
+ {
+ $this->version = $version;
+ }
+
+ /**
+ * @param string $organization
+ */
+ public function setOrganization($organization)
+ {
+ $this->organization = $organization;
+ }
+
+ /**
+ * @param string $reference
+ */
+ public function setReference($reference)
+ {
+ $this->reference = $reference;
+ }
+
+ /**
+ * @return string
+ */
+ public function getOrganization()
+ {
+ return $this->organization;
+ }
+
+ /**
+ * @return string
+ */
+ public function getReference()
+ {
+ if (null === $this->reference) {
+ $this->reference = 'SCORM_SCO_' . sha1(uniqid());
+ }
+ return $this->reference;
+ }
+
+ /**
+ * @return string
+ */
+ public function getStart()
+ {
+ return $this->start;
+ }
+ /**
+ * @param string $start
+ */
+ public function setStart($start)
+ {
+ $this->start = $start;
+ }
}
\ No newline at end of file