Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 96
0.00% covered (danger)
0.00%
0 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
PortableCustomInteraction
0.00% covered (danger)
0.00%
0 / 96
0.00% covered (danger)
0.00%
0 / 18
930
0.00% covered (danger)
0.00%
0 / 1
 setTypeIdentifier
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setEntryPoint
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTypeIdentifier
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEntryPoint
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getProperties
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setProperties
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getStylesheets
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setStylesheets
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getMediaFiles
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setMediaFiles
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getVersion
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setVersion
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getLibraries
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setLibraries
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 toArray
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
2
 getTemplateQti
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTemplateQtiVariables
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 feed
0.00% covered (danger)
0.00%
0 / 51
0.00% covered (danger)
0.00%
0 / 1
110
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) 2013-2023 (original work) Open Assessment Technologies SA;
19 */
20
21declare(strict_types=1);
22
23namespace oat\taoQtiItem\model\qti\interaction;
24
25use InvalidArgumentException;
26use oat\taoQtiItem\model\qti\ParserFactory;
27use oat\taoQtiItem\model\qti\exception\QtiModelException;
28use DOMElement;
29use oat\taoQtiItem\model\qti\PortableElementTrait;
30use oat\taoQtiItem\model\qti\QtiNamespace;
31
32/**
33 * The PortableCustomInteraction is the class of the OAT specific PCI implementation
34 *
35 * @see http://www.imsglobal.org/question/qtiv2p1/imsqti_infov2p1.html#element10267
36 */
37class PortableCustomInteraction extends CustomInteraction
38{
39    use PortableElementTrait;
40
41    public const NS_NAME = 'pci';
42    public const NS_URI = 'http://www.imsglobal.org/xsd/portableCustomInteraction';
43
44    protected $markupNs = 'html5';
45    protected $properties = [];
46    protected $libraries = [];
47    protected $stylesheets = [];
48    protected $mediaFiles = [];
49    protected $typeIdentifier = '';
50    protected $entryPoint = '';
51    protected $version = '0.0.0';
52
53    public function setTypeIdentifier($typeIdentifier)
54    {
55        $this->typeIdentifier = $typeIdentifier;
56    }
57
58    public function setEntryPoint($entryPoint)
59    {
60        $this->entryPoint = $entryPoint;
61    }
62
63    public function getTypeIdentifier()
64    {
65        return $this->typeIdentifier;
66    }
67
68    public function getEntryPoint()
69    {
70        return $this->entryPoint;
71    }
72
73    public function getProperties()
74    {
75        return $this->properties;
76    }
77
78    public function setProperties($properties)
79    {
80        if (is_array($properties)) {
81            $this->properties = $properties;
82        } else {
83            throw new InvalidArgumentException('properties should be an array');
84        }
85    }
86
87    public function getStylesheets()
88    {
89        return $this->stylesheets;
90    }
91
92    public function setStylesheets($stylesheets)
93    {
94        $this->stylesheets = $stylesheets;
95    }
96
97    public function getMediaFiles()
98    {
99        return $this->mediaFiles;
100    }
101
102    public function setMediaFiles($mediaFiles)
103    {
104        $this->mediaFiles = $mediaFiles;
105    }
106
107    public function getVersion()
108    {
109        return $this->version;
110    }
111
112    public function setVersion($version)
113    {
114        return $this->version = $version;
115    }
116
117    public function getLibraries()
118    {
119        return $this->libraries;
120    }
121
122    public function setLibraries($libraries)
123    {
124        if (is_array($libraries)) {
125            $this->libraries = $libraries;
126        } else {
127            throw new InvalidArgumentException('libraries should be an array');
128        }
129    }
130
131    public function toArray($filterVariableContent = false, &$filtered = [])
132    {
133        $returnValue = parent::toArray($filterVariableContent, $filtered);
134
135        $properties = $this->getArraySerializedPrimitiveCollection(
136            $this->getProperties(),
137            $filterVariableContent,
138            $filtered
139        );
140
141        $returnValue['typeIdentifier'] = $this->typeIdentifier;
142        $returnValue['version'] = $this->version;
143        $returnValue['entryPoint'] = $this->entryPoint;
144        $returnValue['libraries'] = $this->libraries;
145        $returnValue['stylesheets'] = $this->stylesheets;
146        $returnValue['mediaFiles'] = $this->mediaFiles;
147        $returnValue['properties'] = $properties;
148        $returnValue['xmlns']  = $this->getNamespace()->getUri();
149
150        return $returnValue;
151    }
152
153    public static function getTemplateQti()
154    {
155        return static::getTemplatePath() . 'interactions/qti.portableCustomInteraction.tpl.php';
156    }
157
158    protected function getTemplateQtiVariables()
159    {
160        $variables = parent::getTemplateQtiVariables();
161        $variables['libraries'] = $this->libraries;
162        $variables['stylesheets'] = $this->stylesheets;
163        $variables['mediaFiles'] = $this->mediaFiles;
164        $variables['serializedProperties'] = $this->serializePortableProperties($this->properties);
165        $variables['entryPoint'] = $this->entryPoint;
166        $variables['typeIdentifier'] = $this->typeIdentifier;
167        $variables['xmlns'] = isset($this->ns) ? $this->ns->getUri() : self::NS_URI;
168        $this->getRelatedItem()->addNamespace($this->markupNs, $this->markupNs);
169
170        return $variables;
171    }
172
173    /**
174     * Feed the pci instance with data provided in the pci dom node
175     *
176     * @params ParserFactory $parser
177     * @params DOMElement $data
178     * @params QtiNamespace|null $xmlns
179     * @return void
180     * @throws QtiModelException
181     */
182    public function feed(ParserFactory $parser, DOMElement $data, QtiNamespace $xmlns = null)
183    {
184        $this->setNamespace($xmlns);
185        $xmlnsName = $xmlns->getName();
186
187        $pciNodes = $parser->queryXPathChildren(['portableCustomInteraction'], $data, $xmlnsName);
188        if (!$pciNodes->length) {
189            $xmlnsName = '';//even if a namespace has been defined, it may not be used
190            $pciNodes = $parser->queryXPathChildren(['portableCustomInteraction'], $data, $xmlnsName);
191        }
192        if (!$pciNodes->length) {
193            throw new QtiModelException('no oat portableCustomInteraction node found');
194        }
195
196        $typeIdentifier = $pciNodes->item(0)->getAttribute('customInteractionTypeIdentifier');
197        if (empty($typeIdentifier)) {
198            throw new QtiModelException('the type identifier of the pci is missing');
199        } else {
200            $this->setTypeIdentifier($typeIdentifier);
201        }
202        $this->setEntryPoint($pciNodes->item(0)->getAttribute('hook'));
203
204        $version = $pciNodes->item(0)->getAttribute('version');
205        if ($version) {
206            $this->setVersion($version);
207        }
208
209        $libNodes = $parser->queryXPathChildren(
210            ['portableCustomInteraction', 'resources', 'libraries', 'lib'],
211            $data,
212            $xmlnsName
213        );
214        $libs = [];
215        foreach ($libNodes as $libNode) {
216            $libs[] = $libNode->getAttribute('id');
217        }
218        $this->setLibraries($libs);
219
220        $stylesheetNodes = $parser->queryXPathChildren(
221            ['portableCustomInteraction', 'resources', 'stylesheets', 'link'],
222            $data,
223            $xmlnsName
224        );
225        $stylesheets = [];
226        foreach ($stylesheetNodes as $styleNode) {
227            $stylesheets[] = $styleNode->getAttribute('href');
228        }
229        $this->setStylesheets($stylesheets);
230
231        $mediaNodes = $parser->queryXPathChildren(
232            ['portableCustomInteraction', 'resources', 'mediaFiles', 'file'],
233            $data,
234            $xmlnsName
235        );
236        $media = [];
237        foreach ($mediaNodes as $mediaNode) {
238            $media[] = $mediaNode->getAttribute('src');
239        }
240        $this->setMediaFiles($media);
241
242        $propertyNodes = $parser->queryXPathChildren(['portableCustomInteraction', 'properties'], $data, $xmlnsName);
243        if ($propertyNodes->length) {
244            $properties = $this->extractProperties($propertyNodes->item(0), $xmlnsName);
245            $this->setProperties($properties);
246        }
247
248        $markupNodes = $parser->queryXPathChildren(['portableCustomInteraction', 'markup'], $data, $xmlnsName);
249        if ($markupNodes->length) {
250            $markup = $parser->getBodyData($markupNodes->item(0), true, true);
251            $this->setMarkup($markup);
252        }
253    }
254}