public function convert(Manifest $manifest, array $rules = [])
 {
     $activityReference = $manifest->getIdentifier();
     $tagsWriter = new TagsWriter();
     // Does not handle submanifest tyvm!
     if (!empty($manifest->getManifest())) {
         LogService::log('Does not handle sub-manifest element thus it is ignored');
     }
     // Atm, we only have tags rules and this need to be validated and user shall be provided with a nice error message
     // TODO: Validation need to be done in future
     $tagRules = isset($rules['tags']) ? $rules['tags'] : [];
     // Let's map package metadatas as activity tags
     // We can write custom replacer or remover to fix the messy `identifier:catalog:` afterwards
     $activityTags = [];
     $metadatas = $manifest->getMetadata();
     if (!empty($metadatas)) {
         $tags = $tagsWriter->convert($metadatas, $tagRules);
         if (!empty($tags)) {
             $activityTags = ['reference' => $activityReference, 'tags' => $tags];
         }
     }
     $itemReferences = [];
     $itemsTags = [];
     // Build item reference and item tags JSON
     $organisations = $manifest->getOrganizations();
     if (!empty($organisations)) {
         foreach ($organisations as $organisation) {
             foreach ($organisation->getItems() as $item) {
                 $itemReferences[] = $item->getIdentifier();
             }
         }
     }
     // Build item reference and item tags JSON
     $resources = $manifest->getResources();
     if (!empty($resources)) {
         foreach ($resources as $resource) {
             // Just add `item` resource as items, and leave css and any other resources alone
             if (StringUtil::startsWith($resource->getType(), 'imsqti_item')) {
                 /** @var Resource $resource */
                 $itemReference = $resource->getIdentifier();
                 $itemReferences[] = $itemReference;
                 $tags = $tagsWriter->convert($resource->getMetadata(), $tagRules);
                 if (!empty($tags)) {
                     $itemsTags[] = ['reference' => $itemReference, 'tags' => $tags];
                 }
             }
         }
     }
     // Build activity JSON
     $activity = ['reference' => $activityReference, 'data' => ['items' => array_values(array_unique($itemReferences))], 'status' => 'published'];
     // Obvious here that these `items` hasn't and wouldn't be validated against
     // Should do it later by the function that calls this
     return [$activity, $activityTags, $itemsTags];
 }
 public function parseManifestElement(\DOMElement $rootElement)
 {
     // Manifest mapping start!
     $manifest = new Manifest();
     $manifest->setIdentifier(Marshaller::getDOMElementAttributeAs($rootElement, 'identifier'));
     // Mapping <resource>(s) to Resource model
     $resourcesElement = Marshaller::getChildElementsByTagName($rootElement, 'resources');
     if (!empty($resourcesElement)) {
         if (count($resourcesElement) !== 1) {
             throw new MappingException('Resources tag must occur once');
         }
         $resourceMapper = new ResourcesMapper();
         $resourcesListElements = Marshaller::getChildElementsByTagName($resourcesElement[0], 'resource');
         $resources = $resourceMapper->map($resourcesListElements);
         $manifest->setResources($resources);
     }
     // Mapping <organisation>(s) to Organisation model
     $organizationElements = Marshaller::getChildElementsByTagName($rootElement, 'organizations');
     if (!empty($organizationElements)) {
         if (count($organizationElements) !== 1) {
             throw new MappingException('Organisations tag must occur once');
         }
         $organisationsMapper = new OrganizationsMapper();
         $organisationListElements = Marshaller::getChildElementsByTagName($organizationElements[0], 'organization');
         $organisations = $organisationsMapper->map($organisationListElements);
         $manifest->setOrganizations($organisations);
     }
     // Mapping package Metadata
     $metadataElement = Marshaller::getChildElementsByTagName($rootElement, 'metadata');
     if (!empty($metadataElement)) {
         if (count($metadataElement) !== 1) {
             throw new MappingException('Metadata tag must occur once');
         }
         $metadataMapper = new MetadataMapper();
         $manifest->setMetadata($metadataMapper->map($metadataElement[0]));
     }
     // Mapping sub-manifest
     $subManifestElement = Marshaller::getChildElementsByTagName($rootElement, 'manifest');
     if (!empty($subManifestElement)) {
         if (count($subManifestElement) !== 1) {
             throw new MappingException('Manifest tag must occur once');
         }
         $manifest->setManifest($this->parseManifestElement($subManifestElement[0]));
     }
     return $manifest;
 }