/** * This function analyzes the manifest. In order to perform faster, manifest entities are analyzed one-by-one (on the fly) * during parsing and not stored into memory * Algorithm: * 1. Detect organization elements. Each one will consist a separate units structure inside efront * 2. Dive inside an organization and detect item elements. Each <item> corresponds to a "unit" in efront * * * * * @param $manifest * @return unknown_type */ public static function import2($lesson, $manifest) { //@todo: parse $lesson //foreach ($namespaces as $prefix => $ns) { //$xml->registerXPathNamespace($prefix, $ns); //} //pr($xml -> xpath("$dfn:organizations/$dfn:organization/$dfn:item/adlcp:timeLimitAction")); $xml = simplexml_load_file(G_SCORMPATH . 'imsmanifest.xml', 'SimpleXMLIterator'); $namespaces = $xml->getNamespaces(true); if (isset($namespaces[""])) { //See notes for xpath() in php.net site $dfn = "default"; $xml->registerXPathNamespace($dfn, $namespaces[""]); // register a prefix for that default namespace: //$xml -> organizations -> registerXPathNamespace($dfn, $namespaces[""]); // register a prefix for that default namespace: } /** * Manifest (1/1): may contain the following elements: * - metadata (1/1) * - organizations (1/1) * - resources (1/1) * - manifest * - imsss:sequencingCollection (0/1) * And the following attributes * - identifier (xs:ID, m): unique identifier * - version (xs:string, o): manifest version * - xml:base (xs:anyURI, o): provides a relative path offset for the content file(s) contained in the manifest */ $manifest['identifier'] = (string) $xml->attributes()->identifier; $manifest['version'] = (string) $xml->attributes()->version; //@todo: handle 'xml:base' //$manifest['xml:base'] = (string)$xml -> attributes() -> xml:base; /** * Metadata: may contain the following elements: * - schema (1/1) * - schemaversion (1/1) * - {metadata} (0/1) */ $metadata['schema'] = (string) $xml->metadata->schema; $metadata['schemaversion'] = (string) $xml->metadata->schemaversion; //@todo: handle metadata /* * Organizations: may contain the following elements: * - organization (1/M) * And the following attributes: * - default (xs:IDREF, m): The id of the default organization */ $organizations['default'] = (string) $xml->organizations->attributes(); //@todo: check that default is actually an existing organization /* * Organization: may contain the following elements: * - title (1/1) * - item (1/M) * - metadata (0/1) * - imsss:sequencing * And the following attributes: * - identifier (xs:ID, m): identifier (unique within the manifest) * - structure (xs:string, o): Describes the shape of the organization (default: hierarchical) * - adlseq:objectivesGlobalToSystem (xs:boolean, o): self-explanatory ;) */ foreach ($xml->organizations->organization as $org) { $org->registerXPathNamespace($dfn, $namespaces[""]); // register a prefix for that default namespace: $id = (string) $org->attributes()->identifier; $org->attributes()->structure ? $organization[$id]['structure'] = $org->attributes()->structure : ($organization[$id]['structure'] = 'hierarchical'); $organization[$id]['title'] = $org->attributes()->title; //@todo: the importing may be done below existing elements, take this into account when considering $previousContentId (its initial value may not be 0) $contentTree = new EfrontContentTree($lesson); $previousContent = $contentTree->getLastNode() or $previousContent = array('id' => 0); //Create the "holding" unit, an empty unit that will hold this organization's elements $previousContent = $parentContent = EfrontUnit::createUnit(array('name' => $organization[$id]['title'], 'parent_content_ID' => 0, 'previous_content_ID' => $previousContent['id'], 'lessons_ID' => $lesson)); //Get contents of the organization foreach ($org as $key => $value) { /* * Item: may contain the following elements: * - title (1/1) * - item 0/M * - metadata 0/1 * - adlcp: timeLimitAction 0/1 * - adlcp: dataFromLMS 0/1 * - adlcp: completionThreshold 0/1 * - imsss:sequencing * - adlnav:presentation * And the following attributes: * - identifier (xs:ID, m): a unique identifier * - identifierref (xs:string, o): a reference to a resource * - isvisible (xs:boolean, o): whether this item is displayed when the structure of the package is displayed or rendered (Default true) * - parameters (xs:string, o): static parameters to be passed to the resource at launch time (max 1000 chars) */ if ($key == 'item') { $itemId = (string) $value->attributes()->identifier; //pr($value -> attributes() -> identifier); $item = array('identifier' => $itemId, 'identifierref' => (string) $value->attributes()->identifierref, 'isvisible' => (string) $value->attributes()->isvisible, 'parameters' => (string) $value->attributes()->parameters, 'title' => (string) $value->title, 'timeLimitAction' => (string) reset($org->xpath("{$dfn}:item[@identifier='{$itemId}']/adlcp:timeLimitAction")), 'dataFromLMS' => (string) reset($org->xpath("{$dfn}:item[@identifier='{$itemId}']/adlcp:dataFromLMS")), 'completionThreshold' => (string) reset($org->xpath("{$dfn}:item[@identifier='{$itemId}']/adlcp:completionThreshold"))); //@todo:<imsss:sequencing>, <adlnav:presentation> //@todo: nested items //@todo: metadata $previousContent = EfrontUnit::createUnit(array('name' => $item['title'], 'parent_content_ID' => $parentContent['id'], 'previous_content_ID' => $previousContent['id'], 'lessons_ID' => $lesson)); $items[$itemId] = $item['identifierref']; } } //@todo: handle adlseq:objectivesGlobalToSystem } /* * Resources: may contain the following elements: * - resource (0/M) * And the following attributes: * - xml:base (xs:anyURI, o): provides a relative path offset for the content file(s) */ $resources = $xml->resources; $resources->registerXPathNamespace($dfn, $namespaces[""]); // register a prefix for that default namespace: /* * Resource: may contain the following elements: * - metadata (0/1) * - file (0/M) * - dependency (0/M) * And the following attributes: * - identifier (xs:ID, m): a unique identifier * - type (xs:string, m): the type of the resource * - href (xs:string, o): the �entry point� or �launching point� of this resource * - xml:base (xs:anyURI, o): a relative path offset for the files contained in the manifest * - adlcp:scormType (xs:string, m): the type of SCORM resource ("sco" or "asset") */ foreach ($resources->resource as $key => $value) { $resourceId = (string) $value->attributes()->identifier; $resource = array('identifier' => $resourceId, 'type' => (string) $value->attributes()->type, 'href' => (string) $value->attributes()->href, 'base' => (string) $value->attributes($namespaces['xml'])->base, 'scormType' => (string) $value->attributes($namespaces['adlcp'])->scormType); /** * File: may contain the following elements: * - metadata (0/1) * And the following attributes: * - href (xs:string, m): identifies the location of the file */ foreach ($value->file as $f) { $file = array('href' => (string) $f->attributes()->href); } /** * Dependency: may contain the following elements: * <none> * And the following attributes: * - identifierref (xs:string, m): an identifier attribute of a resource */ foreach ($value->dependency as $d) { $dependency = array('identifierref' => (string) $d->attributes()->identifierref); } } //@todo: sequencingCollection //pr($organization); // $result = $xml -> xpath("//$dfn:manifest/$dfn:organizations/$dfn:organization"); /* $iterator = new SimpleXMLIterator($xml -> asXML()); foreach (new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST) as $key => $value) { } */ /* //$iterator = new SimpleXMLIterator($data); //$iterator = simplexml_load_string($data, 'SimpleXMLIterator'); */ }