Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 145
0.00% covered (danger)
0.00%
0 / 16
CRAP
0.00% covered (danger)
0.00%
0 / 1
core_kernel_impl_ApiModelOO
0.00% covered (danger)
0.00%
0 / 144
0.00% covered (danger)
0.00%
0 / 16
1190
0.00% covered (danger)
0.00%
0 / 1
 importXmlRdf
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getResourceDescriptionXML
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
72
 getMetaClasses
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 getRootClasses
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 setStatement
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
12
 getAllClasses
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 getSubject
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
 removeStatement
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 getObject
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 singleton
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getServiceLocator
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 createClassCollection
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addCoreNamespaces
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 addCustomNamespace
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 addNamespace
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
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) 2002-2008 (original work) Public Research Centre Henri Tudor & University of Luxembourg
19 *                         (under the project TAO & TAO2);
20 *               2008-2010 (update and modification) Deutsche Institut für Internationale Pädagogische Forschung
21 *                         (under the project TAO-TRANSFER);
22 *               2009-2012 (update and modification) Public Research Centre Henri Tudor
23 *                         (under the project TAO-SUSTAIN & TAO-DEV);
24 *               2017 (update and modification) Open Assessment Technologies SA (under the project TAO-PRODUCT);
25 */
26
27use oat\generis\model\OntologyRdf;
28use oat\generis\model\OntologyRdfs;
29use Doctrine\DBAL\DBALException;
30use oat\generis\model\data\import\RdfImporter;
31use oat\oatbox\log\LoggerAwareTrait;
32use oat\oatbox\service\ServiceManager;
33use Zend\ServiceManager\ServiceLocatorInterface;
34
35// phpcs:disable PSR1.Files.SideEffects
36error_reporting(E_ALL);
37// phpcs:enable PSR1.Files.SideEffects
38
39/**
40 * Generis Object Oriented API - core\kernel\impl\class.ApiModelOO.php
41 *
42 * Short description of class core_kernel_impl_ApiModelOO
43 *
44 * This file is part of Generis Object Oriented API.
45 *
46 * Automatically generated on 29.03.2010, 15:28:05 with ArgoUML PHP module
47 * (last revised $Date: 2008-04-19 08:22:08 +0200 (Sat, 19 Apr 2008) $)
48 *
49 * @access public
50 * @author firstname and lastname of author, <author@example.org>
51 * @package generis
52
53 */
54class core_kernel_impl_ApiModelOO extends core_kernel_impl_Api implements core_kernel_api_ApiModel
55{
56    use LoggerAwareTrait;
57
58    // --- ASSOCIATIONS ---
59
60
61    // --- ATTRIBUTES ---
62
63    /**
64     * Short description of attribute instance
65     *
66     * @access private
67     * @var self
68     */
69    private static $instance = null;
70
71    /** @var string[] */
72    private $namespaces = [];
73
74    /** @var int */
75    private $customNamespacesCounter = 0;
76
77    // --- OPERATIONS ---
78
79
80    /**
81     * import xml rdf files into the knowledge base
82     *
83     * @access public
84     * @author firstname and lastname of author, <author@example.org>
85     * @param  string targetNameSpace
86     * @param  string fileLocation
87     * @return boolean
88     */
89    public function importXmlRdf($targetNameSpace, $fileLocation)
90    {
91        $importer = $this->getServiceLocator()->get(RdfImporter::class);
92        return $importer->importFile($fileLocation);
93    }
94
95
96
97    /**
98     * returns an xml rdf serialization for uriResource with all meta dat found
99     * inferenced from te knowlege base about this resource
100     *
101     * @access public
102     * @author firstname and lastname of author, <author@example.org>
103     * @param  string uriResource
104     * @return string
105     */
106    public function getResourceDescriptionXML($uriResource)
107    {
108        $returnValue = '';
109
110        $dbWrapper = core_kernel_classes_DbWrapper::singleton();
111        $subject = $dbWrapper->quote($uriResource);
112
113        try {
114            $dom = new DOMDocument();
115            $dom->formatOutput = true;
116            $root = $dom->createElement('rdf:RDF');
117
118            $this->addCoreNamespaces($root);
119            $dom->appendChild($root);
120
121            $description = $dom->createElement('rdf:Description');
122            $description->setAttribute('rdf:about', $uriResource);
123
124            $result = $dbWrapper->query('SELECT * FROM "statements" WHERE "subject" = ' . $subject);
125            while ($row = $result->fetch()) {
126                $predicate  = trim($row['predicate']);
127                $object     = trim($row['object']);
128                $lang       = trim($row['l_language']);
129
130                if (strpos($predicate, '#') === false) {
131                    continue;
132                }
133
134                [$namespace, $property] = explode('#', $predicate, 2);
135
136                $namespaceId = $this->addCustomNamespace($root, $namespace);
137                $nodeName    = "$namespaceId:$property";
138
139                try {
140                    $node = $dom->createElement($nodeName);
141                    if (!empty($lang)) {
142                        $node->setAttribute('xml:lang', $lang);
143                    }
144
145                    if (preg_match("/^http:\/\/(.*)#[a-zA-Z1-9]*/", $object)) {
146                        $node->setAttribute('rdf:resource', $object);
147                    } elseif (!empty($object)) {
148
149                        /**
150                         * Replace the CDATA section inside XML fields by a replacement tag:
151                         * <![CDATA[ ]]> to <CDATA></CDATA>
152                         * @todo check if this behavior is the right
153                         */
154                        $object = str_replace(['<![CDATA[', ']]>'], ['<CDATA>', '</CDATA>'], $object);
155
156                        $node->appendChild($dom->createCDATASection($object));
157                    }
158                    $description->appendChild($node);
159                } catch (DOMException $exception) {
160                    $this->logCritical($exception->getMessage(), ['exception' => $exception]);
161                }
162            }
163            $root->appendChild($description);
164            $returnValue = $dom->saveXml();
165        } catch (DomException $exception) {
166            $this->logError($exception->getMessage(), ['exception' => $exception]);
167            print $exception;
168        }
169
170        return (string) $returnValue;
171    }
172
173    /**
174     * returns metaclasses tat are not subclasses of other metaclasses
175     *
176     * @access public
177     * @author patrick.plichart@tudor.lu
178     * @return core_kernel_classes_ContainerCollection
179     */
180    public function getMetaClasses()
181    {
182        $returnValue = $this->createClassCollection(__METHOD__);
183
184        $classClass = new core_kernel_classes_Class(OntologyRdfs::RDFS_CLASS);
185        foreach ($classClass->getSubClasses(true) as $subClass) {
186            $returnValue->add($subClass);
187        }
188
189
190        return $returnValue;
191    }
192
193    /**
194     * returns classes that are not subclasses of other classes
195     *
196     * @access public
197     * @author patrick.plichart@tudor.lu
198     * @return core_kernel_classes_ContainerCollection
199     */
200    public function getRootClasses()
201    {
202        $returnValue = $this->createClassCollection(__METHOD__);
203
204        $query =  'SELECT DISTINCT subject FROM statements WHERE (predicate = ? AND object = ?) 
205                    AND subject NOT IN (SELECT subject FROM statements WHERE predicate = ?)';
206        $result = core_kernel_classes_DbWrapper::singleton()->query($query, [
207            OntologyRdf::RDF_TYPE,
208            OntologyRdfs::RDFS_CLASS,
209            OntologyRdfs::RDFS_SUBCLASSOF
210        ]);
211
212        while ($row = $result->fetch()) {
213            $returnValue->add(new core_kernel_classes_Class($row['subject']));
214        }
215
216
217
218        return $returnValue;
219    }
220
221    /**
222     * add a new statment to the knowledge base
223     *
224     * @access public
225     * @author patrick.plichart@tudor.lu
226     * @param  string subject
227     * @param  string predicate
228     * @param  string object
229     * @param  string language
230     * @return boolean
231     */
232    public function setStatement($subject, $predicate, $object, $language)
233    {
234        $returnValue = (bool) false;
235
236
237        $dbWrapper  = core_kernel_classes_DbWrapper::singleton();
238        $platform   = $dbWrapper->getPlatForm();
239        $localNs    = common_ext_NamespaceManager::singleton()->getLocalNamespace();
240        $query = 'INSERT INTO statements (modelid,subject,predicate,object,l_language,author,epoch)
241                    VALUES  (?, ?, ?, ?, ?, ? , ?);';
242
243        try {
244            $returnValue = $dbWrapper->exec($query, [
245                $localNs->getModelId(),
246                $subject,
247                $predicate,
248                $object,
249                $language,
250                common_session_SessionManager::getSession()->getUserUri(),
251                $platform->getNowExpression()
252
253            ]);
254        } catch (DBALException $e) {
255            if ($e->getCode() !== '00000') {
256                throw new common_Exception(
257                    "Unable to setStatement (SPO) {$subject}{$predicate}{$object} : " . $e->getMessage()
258                );
259            }
260        }
261
262
263
264        return (bool) $returnValue;
265    }
266
267    /**
268     * Short description of method getAllClasses
269     *
270     * @access public
271     * @author firstname and lastname of author, <author@example.org>
272     * @return core_kernel_classes_ContainerCollection
273     */
274    public function getAllClasses()
275    {
276        $returnValue = $this->createClassCollection(__METHOD__);
277
278        $query =  'SELECT DISTINCT subject FROM statements WHERE (predicate = ? AND object = ?) OR predicate = ?';
279        $result = core_kernel_classes_DbWrapper::singleton()->query($query, [
280            OntologyRdf::RDF_TYPE,
281            OntologyRdfs::RDFS_CLASS,
282            OntologyRdfs::RDFS_SUBCLASSOF
283        ]);
284
285        while ($row = $result->fetch()) {
286            $returnValue->add(new core_kernel_classes_Class($row['subject']));
287        }
288
289
290
291        return $returnValue;
292    }
293
294    /**
295     * Short description of method getSubject
296     *
297     * @access public
298     * @author firstname and lastname of author, <author@example.org>
299     * @param  string predicate
300     * @param  string object
301     * @return core_kernel_classes_ContainerCollection
302     */
303    public function getSubject($predicate, $object)
304    {
305        $sqlQuery = "SELECT subject FROM statements WHERE predicate = ? AND object= ? ";
306        $dbWrapper = core_kernel_classes_DbWrapper::singleton();
307        $sqlResult = $dbWrapper->query($sqlQuery, [
308            $predicate,
309            $object
310        ]);
311        $returnValue = new core_kernel_classes_ContainerCollection(new common_Object());
312        while ($row = $sqlResult->fetch()) {
313            $container = new core_kernel_classes_Resource($row['subject'], __METHOD__);
314            $container->debug = __METHOD__ ;
315            $returnValue->add($container);
316        }
317
318        return $returnValue;
319    }
320
321    /**
322     * Short description of method removeStatement
323     *
324     * @access public
325     * @author firstname and lastname of author, <author@example.org>
326     * @param  string subject
327     * @param  string predicate
328     * @param  string object
329     * @param  string language
330     * @return boolean
331     */
332    public function removeStatement($subject, $predicate, $object, $language)
333    {
334        $dbWrapper  = core_kernel_classes_DbWrapper::singleton();
335
336        $query = "DELETE FROM statements WHERE subject = ?
337                    AND predicate = ? AND object = ?
338                    AND (l_language = ? OR l_language = '')";
339
340        $returnValue = $dbWrapper->exec($query, [
341            $subject,
342            $predicate,
343            $object,
344            $language
345        ]);
346
347        return (bool) $returnValue;
348    }
349
350    /**
351     * Short description of method getObject
352     *
353     * @access public
354     * @author firstname and lastname of author, <author@example.org>
355     * @param  string subject
356     * @param  string predicate
357     * @return core_kernel_classes_ContainerCollection
358     */
359    public function getObject($subject, $predicate)
360    {
361        $sqlQuery = "SELECT object FROM statements WHERE subject = ? AND predicate = ?";
362        $dbWrapper = core_kernel_classes_DbWrapper::singleton();
363        $sqlResult = $dbWrapper->query($sqlQuery, [
364            $subject,
365            $predicate
366        ]);
367        $returnValue = new core_kernel_classes_ContainerCollection(new common_Object());
368        while ($row = $sqlResult->fetch()) {
369            $value = $row['object'];
370            if (!common_Utils::isUri($value)) {
371                $container = new core_kernel_classes_Literal($value);
372            } else {
373                $container = new core_kernel_classes_Resource($value);
374            }
375            $container->debug = __METHOD__ ;
376            $returnValue->add($container);
377        }
378
379
380        return $returnValue;
381    }
382
383    /**
384     * Short description of method singleton
385     *
386     * @access public
387     * @author firstname and lastname of author, <author@example.org>
388     * @return core_kernel_impl_ApiModelOO
389     */
390    public static function singleton()
391    {
392        if (!isset(self::$instance)) {
393            $c = __CLASS__;
394            self::$instance = new $c();
395        }
396
397        return self::$instance;
398    }
399
400    /**
401     * Short description of method __construct
402     *
403     * @access private
404     * @author firstname and lastname of author, <author@example.org>
405     * @return void
406     */
407    private function __construct()
408    {
409    }
410
411    /**
412     * @return ServiceLocatorInterface
413     */
414    public function getServiceLocator()
415    {
416        return ServiceManager::getServiceManager();
417    }
418
419    private function createClassCollection(string $debug = ''): core_kernel_classes_ContainerCollection
420    {
421        return new core_kernel_classes_ContainerCollection(new core_kernel_classes_Container(), $debug);
422    }
423
424    private function addCoreNamespaces(DOMElement $root): void
425    {
426        $this->namespaces = [
427            'http://www.w3.org/1999/02/22-rdf-syntax-ns' => 'rdf',
428            'http://www.w3.org/2000/01/rdf-schema'       => 'rdfs',
429        ];
430
431        foreach ($this->namespaces as $namespace => $namespaceId) {
432            $this->addNamespace($root, $namespaceId, $namespace);
433        }
434
435        $this->customNamespacesCounter = 0;
436        $this->addCustomNamespace($root, LOCAL_NAMESPACE);
437    }
438
439    /**
440     * @param DOMElement $root
441     * @param string $namespace
442     *
443     * @return string|null A namespace ID
444     */
445    private function addCustomNamespace(DOMElement $root, string $namespace): string
446    {
447        if (!isset($this->namespaces[$namespace])) {
448            $namespaceId = sprintf('ns%u', ++$this->customNamespacesCounter);
449            $this->namespaces[$namespace] = $namespaceId;
450            $this->addNamespace($root, $namespaceId, $namespace);
451        }
452
453        return $this->namespaces[$namespace];
454    }
455
456    private function addNamespace(DOMElement $root, string $namespaceId, string $namespace): void
457    {
458        $root->setAttribute("xmlns:$namespaceId", "$namespace#");
459    }
460}