Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
ManifestConverter
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
42
0.00% covered (danger)
0.00%
0 / 1
 convertToQti2
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2
3/**
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; under version 2
7 * of the License (non-upgradable).
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 *
18 * Copyright (c) 2024 (original work) Open Assessment Technologies SA;
19 */
20
21declare(strict_types=1);
22
23namespace oat\taoQtiItem\model\qti\converter;
24
25use DOMDocument;
26use oat\oatbox\extension\exception\ManifestNotFoundException;
27use taoQtiTest_models_classes_ManifestParser as ManifestParser;
28
29class ManifestConverter
30{
31    private const XML_NS_NAMESPACE = 'http://www.w3.org/2000/xmlns/';
32    private const NEW_MAIN_NAMESPACE = 'http://www.imsglobal.org/xsd/imscp_v1p1';
33    private const XSI_NAMESPACE = 'http://www.w3.org/2001/XMLSchema-instance';
34    private const IMS_MD_NAMESPACE = 'http://ltsc.ieee.org/xsd/LOM';
35    private const SCHEMA_LOCATION = 'http://www.imsglobal.org/xsd/imscp_v1p1 ' .
36    'http://www.imsglobal.org/xsd/qti/qtiv2p2/qtiv2p2_imscpv1p2_v1p0.xsd ' .
37    'http://ltsc.ieee.org/xsd/LOM http://www.imsglobal.org/xsd/imsmd_loose_v1p3p2.xsd';
38    private const QUALIFIED_NAME_NS = 'xmlns';
39    private const QUALIFIED_NAME_XSI = self::QUALIFIED_NAME_NS . ':xsi';
40    private const QUALIFIED_NAME_IMSMD = self::QUALIFIED_NAME_NS . ':imsmd';
41    private const XSI_SCHEMA_LOCATION = 'xsi:schemaLocation';
42    private const QTI3_XSD = 'http://www.imsglobal.org/xsd/qti/qtiv3p0/imscp_v1p1';
43    private const TEST_RESOURCE_TYPE = 'imsqti_test_xmlv3p0';
44    private const ITEM_RESOURCE_TYPE = 'imsqti_item_xmlv3p0';
45    private const RESOURCE_TYPE_REPLACEMENTS = [
46        self::ITEM_RESOURCE_TYPE => 'imsqti_item_xmlv2p2',
47        self::TEST_RESOURCE_TYPE => 'imsqti_test_xmlv2p2',
48    ];
49
50    public function convertToQti2(string $manifestFile, ManifestParser $manifestParser): void
51    {
52        //Check if folder exist and contains QTI 3.0 files
53        if (!is_readable($manifestFile)) {
54            throw new ManifestNotFoundException('Manifest not found!');
55        }
56
57        $dom = new DOMDocument();
58        $dom->load($manifestFile);
59
60        //Check if the file is QTI 3.0 using schemaversion
61        if ($dom->getElementsByTagName('schemaversion')->item(0)->nodeValue !== '3.0.0') {
62            return;
63        }
64        // Get the manifest element
65        $manifestElement = $dom->getElementsByTagName('manifest')->item(0);
66        if (!$manifestElement) {
67            return;
68        }
69
70        // Remove existing namespace attributes
71        $manifestElement->removeAttributeNS(
72            self::QTI3_XSD,
73            ''
74        );
75
76        // Set new main namespace
77        $manifestElement->setAttributeNS(
78            self::XML_NS_NAMESPACE,
79            self::QUALIFIED_NAME_NS,
80            self::NEW_MAIN_NAMESPACE
81        );
82
83        // Ensure xsi namespace
84        $manifestElement->setAttributeNS(
85            self::XML_NS_NAMESPACE,
86            self::QUALIFIED_NAME_XSI,
87            self::XSI_NAMESPACE
88        );
89
90        // Ensure imsmd namespace
91        $manifestElement->setAttributeNS(
92            self::XML_NS_NAMESPACE,
93            self::QUALIFIED_NAME_IMSMD,
94            self::IMS_MD_NAMESPACE
95        );
96
97        $manifestElement->setAttributeNS(
98            self::XSI_NAMESPACE,
99            self::XSI_SCHEMA_LOCATION,
100            self::SCHEMA_LOCATION
101        );
102
103        $dom->getElementsByTagName('schemaversion')->item(0)->nodeValue = '2.2.0';
104        $resources = $dom->getElementsByTagName('resource');
105
106        foreach ($resources as $resource) {
107            // If resource type is mapped replace it with mapped value
108            if (isset(self::RESOURCE_TYPE_REPLACEMENTS[$resource->getAttribute('type')])) {
109                $resource->setAttribute(
110                    'type',
111                    self::RESOURCE_TYPE_REPLACEMENTS[$resource->getAttribute('type')]
112                );
113            }
114        }
115
116        // Save the modified XML
117        $dom->save($manifestFile);
118        $manifestParser->validate();
119    }
120}