Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
34.65% covered (danger)
34.65%
70 / 202
29.79% covered (danger)
29.79%
14 / 47
CRAP
0.00% covered (danger)
0.00%
0 / 1
core_kernel_classes_Resource
34.65% covered (danger)
34.65%
70 / 202
29.79% covered (danger)
29.79%
14 / 47
2350.23
0.00% covered (danger)
0.00%
0 / 1
 getImplementation
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __construct
30.00% covered (danger)
30.00%
3 / 10
0.00% covered (danger)
0.00%
0 / 1
18.35
 __clone
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 isCustom
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 isClass
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 isWritable
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 isProperty
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 getTypes
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLabel
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
4.01
 setLabel
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 getComment
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 setComment
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 getPropertyValues
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getPropertyValuesCollection
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getUniquePropertyValue
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 getOnePropertyValue
76.92% covered (warning)
76.92%
10 / 13
0.00% covered (danger)
0.00%
0 / 1
3.11
 getPropertyValuesByLg
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 setPropertyValue
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 setPropertiesValues
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 setPropertyValueByLg
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 editPropertyValues
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 editPropertyValueByLg
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 removePropertyValue
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 removePropertyValues
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 removePropertyValueByLg
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getRdfTriples
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getUsedLanguages
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 duplicate
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 delete
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 __toString
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPropertiesValues
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 setType
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 removeType
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 hasType
50.00% covered (danger)
50.00%
3 / 6
0.00% covered (danger)
0.00%
0 / 1
4.12
 exists
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 getUri
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 equals
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isInstanceOf
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
20
 getRootId
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getParentClassId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 getParentClassesIds
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getParentClassesResourceIds
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getNestedResources
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getServiceManager
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 toResource
37.50% covered (danger)
37.50%
3 / 8
0.00% covered (danger)
0.00%
0 / 1
7.91
 onUpdate
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getResourceRepository
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-2021 (update and modification) Open Assessment Technologies SA;
25 */
26
27use oat\generis\model\OntologyRdf;
28use oat\generis\model\OntologyRdfs;
29use oat\oatbox\event\EventAggregator;
30use oat\oatbox\service\ServiceManager;
31use oat\generis\model\OntologyAwareTrait;
32use Zend\ServiceManager\ServiceLocatorInterface;
33use oat\generis\model\data\event\ResourceUpdated;
34use Zend\ServiceManager\ServiceLocatorAwareInterface;
35use oat\generis\model\resource\Repository\ResourceRepository;
36use oat\generis\model\resource\Context\ResourceRepositoryContext;
37use oat\generis\model\resource\Contract\ResourceRepositoryInterface;
38
39/**
40 * Resource implements rdf:resource container identified by an uri (a string).
41 * Methods enable meta data management for this resource
42 *
43 * @author patrick.plichart@tudor.lu
44 *
45 * @see http://www.w3.org/RDF/
46 */
47class core_kernel_classes_Resource extends core_kernel_classes_Container
48{
49    use OntologyAwareTrait;
50
51    // --- ASSOCIATIONS ---
52
53
54    // --- ATTRIBUTES ---
55
56    /**
57     * long uri as string (including namespace)
58     * direct access to the uri is deprecated,
59     * please use getUri()
60     *
61     * @access public
62     * @var string
63     * @deprecated
64     */
65    public $uriResource = '';
66
67    /**
68     * The resource label
69     * direct access to the label is deprecated,
70     * please use getLabel()
71     *
72     * @access public
73     * @var string
74     * @deprecated
75     */
76    public $label = null;
77
78    /**
79     * The resource comment
80     * direct access to the comment is deprecated,
81     * please use getComment()
82     *
83     * @access public
84     * @var string
85     * @deprecated
86     */
87    public $comment = '';
88
89    // --- OPERATIONS ---
90    /**
91     *
92     * @return core_kernel_persistence_ResourceInterface
93     */
94    private function getImplementation()
95    {
96        return $this->getModel()->getRdfsInterface()->getResourceImplementation();
97    }
98
99
100    /**
101     * create the object
102     *
103     * @access public
104     * @author Joel Bout, <joel.bout@tudor.lu>
105     * @param  mixed uri
106     * @param  string debug
107     * @return void
108     */
109    public function __construct($uri, $debug = '')
110    {
111        if (empty($uri)) {
112            throw new common_exception_Error(
113                'cannot construct the resource because the uri cannot be empty, debug: ' . $debug
114            );
115        }
116        if (!is_string($uri) && !$uri instanceof self) {
117            throw new common_exception_Error(
118                'could not create resource from ' . (is_object($uri) ? get_class($uri) : gettype($uri))
119                    . ' debug: ' . $debug
120            );
121        }
122        $this->uriResource = $uri instanceof self ? $uri->getUri() : $uri;
123    }
124
125
126    /**
127     * Conveniance method to duplicate a resource using the clone keyword
128     *
129     * @access public
130     * @author Joel Bout, <joel.bout@tudor.lu>
131     */
132    public function __clone()
133    {
134        throw new common_exception_DeprecatedApiMethod(
135            'Use duplicated instead, because clone resource could not share same uri that original'
136        );
137    }
138
139    public function isCustom(): bool
140    {
141        $uri = $this->getUri();
142
143        return strpos($uri, 'www.tao.lu') === false && strpos($uri, 'www.w3.org') === false;
144    }
145
146    /**
147     * returns true if the resource is a valid class (using facts or entailment
148     *
149     * @access public
150     * @author patrick.plichart@tudor.lu
151     * @return boolean
152     * @see http://www.w3.org/RDF/
153     */
154    public function isClass()
155    {
156        $returnValue = (bool) false;
157        if (count($this->getPropertyValues($this->getProperty(OntologyRdfs::RDFS_SUBCLASSOF))) > 0) {
158            $returnValue = true;
159        } else {
160            foreach ($this->getTypes() as $type) {
161                if ($type->getUri() == OntologyRdfs::RDFS_CLASS) {
162                    $returnValue = true;
163                    break;
164                }
165            }
166        }
167        return (bool) $returnValue;
168    }
169
170    public function isWritable(): bool
171    {
172        $implementation = $this->getImplementation();
173
174        if ($implementation instanceof core_kernel_persistence_smoothsql_Resource) {
175            return $implementation->isWritable($this);
176        }
177
178        return true;
179    }
180
181    /**
182     * returns true if the resource is a valid property (using facts or
183     * rules)
184     *
185     * @access public
186     * @author patrick.plichart@tudor.lu
187     * @return boolean
188     * @see http://www.w3.org/RDF/
189     */
190    public function isProperty()
191    {
192        $returnValue = (bool) false;
193        foreach ($this->getTypes() as $type) {
194            if ($type->getUri() == OntologyRdf::RDF_PROPERTY) {
195                $returnValue = true;
196                break;
197            }
198        }
199        return (bool) $returnValue;
200    }
201
202    /**
203     * Returns all the types of this resource as core_kernel_classes_Class objects.
204     *
205     * @author Joel Bout <joel@taotesting.com>
206     * @return core_kernel_classes_Class[] An associative array where keys are class URIs and values are
207     *                                     core_kernel_classes_Class objects.
208     */
209    public function getTypes()
210    {
211        return $this->getImplementation()->getTypes($this);
212    }
213
214    /**
215     * Returns the label of this resource as a string. This method is a convenience
216     * method preventing to call the get getPropertyValues() method for a such common
217     * operation.
218     *
219     * @author Patrick Plichart <patrick@taotesting.com>
220     * @return string A Uniform Resource Identifier (URI).
221     */
222    public function getLabel()
223    {
224        if (is_null($this->label)) {
225            $label =  $this->getOnePropertyValue($this->getProperty(OntologyRdfs::RDFS_LABEL));
226            $this->label = is_null($label)
227                ? ''
228                : (
229                    $label instanceof core_kernel_classes_Resource
230                    ? $label->getUri()
231                    : (string)$label
232                )
233            ;
234        }
235
236        return $this->label;
237    }
238
239    /**
240     * alias to setPropertyValue using rdfs:label property
241     *
242     * @access public
243     * @author patrick.plichart@tudor:lu
244     * @param  string label
245     * @return boolean
246     */
247    public function setLabel($label)
248    {
249        $returnValue = (bool) false;
250        $this->removePropertyValues($this->getProperty(OntologyRdfs::RDFS_LABEL));
251        $this->setPropertyValue($this->getProperty(OntologyRdfs::RDFS_LABEL), $label);
252        $this->label = $label;
253        return (bool) $returnValue;
254    }
255
256    /**
257     * Short description of method getComment
258     *
259     * @access public
260     * @author Joel Bout, <joel.bout@tudor.lu>
261     * @return string
262     */
263    public function getComment()
264    {
265        $returnValue = (string) '';
266        if ($this->comment == '') {
267            $comment =  $this->getOnePropertyValue($this->getProperty(OntologyRdfs::RDFS_COMMENT));
268            $this->comment = $comment != null ? $comment->literal : '';
269        }
270        $returnValue = $this->comment;
271        return (string) $returnValue;
272    }
273
274    /**
275     * alias to setPropertyValue using rdfs:label property
276     *
277     * @access public
278     * @author patrick.plichart
279     * @param  string comment
280     * @return boolean
281     */
282    public function setComment($comment)
283    {
284        $returnValue = (bool) false;
285        $this->removePropertyValues($this->getProperty(OntologyRdfs::RDFS_COMMENT));
286        $this->setPropertyValue($this->getProperty(OntologyRdfs::RDFS_COMMENT), $comment);
287        $this->comment = $comment;
288        return (bool) $returnValue;
289    }
290
291    /**
292     * Returns a collection of triples with all objects found for the provided
293     * regarding the contextual resource.
294     * The return format is an array of strings
295     *
296     * @access public
297     * @author Joel Bout, <joel.bout@tudor.lu>
298     * @param core_kernel_classes_Property $property uriProperty is string and may be short in the case of a locally
299     *                                               defined property (module namespace), or long uri
300     * @param array $options
301     * @return array
302     */
303    public function getPropertyValues(core_kernel_classes_Property $property, $options = [])
304    {
305        $returnValue = $this->getImplementation()->getPropertyValues($this, $property, $options);
306        return $returnValue;
307    }
308
309    /**
310     * Return a collection of values associated to $property
311     *
312     * @param core_kernel_classes_Property $property
313     * @param array $options
314     * @return core_kernel_classes_ContainerCollection
315     */
316    public function getPropertyValuesCollection(core_kernel_classes_Property $property, $options = [])
317    {
318        $returnValue = new core_kernel_classes_ContainerCollection($this);
319        foreach ($this->getPropertyValues($property, $options) as $value) {
320            $returnValue->add($this->toResource($value));
321        }
322        return $returnValue;
323    }
324
325    /**
326     * Short description of method getUniquePropertyValue
327     *
328     * @access public
329     * @author Joel Bout, <joel.bout@tudor.lu>
330     * @param  Property property
331     * @throws common_Exception
332     * @throws core_kernel_classes_EmptyProperty
333     * @return core_kernel_classes_Container
334     */
335    public function getUniquePropertyValue(core_kernel_classes_Property $property)
336    {
337        $returnValue = null;
338
339        $collection = $this->getPropertyValuesCollection($property);
340
341        if ($collection->isEmpty()) {
342            throw new core_kernel_classes_EmptyProperty($this, $property);
343        }
344        if ($collection->count() == 1) {
345            $returnValue = $collection->get(0);
346        } else {
347            throw new core_kernel_classes_MultiplePropertyValuesException($this, $property);
348        }
349        return $returnValue;
350    }
351
352    /**
353     * Helper to return one property value, since there is no order
354     * if there are multiple values the value to be returned will be choosen by random
355     *
356     * optional parameter $last should NOT be used since it is no longer supported
357     * and will be removed in future versions
358     *
359     * @access public
360     * @author Joel Bout, <joel.bout@tudor.lu>
361     * @param  Property property
362     * @param  boolean last
363     * @return core_kernel_classes_Container
364     */
365    public function getOnePropertyValue(core_kernel_classes_Property $property, $last = false)
366    {
367        $returnValue = null;
368        if ($last) {
369            throw new core_kernel_persistence_Exception(
370                'parameter \'last\' for getOnePropertyValue no longer supported'
371            );
372        };
373
374        $options = [
375            'forceDefaultLg' => true,
376            'one' => true
377        ];
378
379        $value = $this->getPropertyValues($property, $options);
380
381        if (count($value)) {
382            $returnValue = $this->toResource(current($value));
383        }
384
385        return $returnValue;
386    }
387
388    /**
389     * Short description of method getPropertyValuesByLg
390     *
391     * @access public
392     * @author Joel Bout, <joel.bout@tudor.lu>
393     * @param  Property property
394     * @param  string lg
395     * @return core_kernel_classes_ContainerCollection
396     */
397    public function getPropertyValuesByLg(core_kernel_classes_Property $property, $lg)
398    {
399        $returnValue = null;
400        $returnValue = $this->getImplementation()->getPropertyValuesByLg($this, $property, $lg);
401        return $returnValue;
402    }
403
404    /**
405     * assign the (string) object for the provided uriProperty reagarding the
406     * resource
407     *
408     * @access public
409     * @author Patrick.plichart
410     * @param  Property property
411     * @param  string object
412     * @return boolean
413     * @version 1.0
414     */
415    public function setPropertyValue(core_kernel_classes_Property $property, $object)
416    {
417        $returnValue = (bool) false;
418        $returnValue = $this->getImplementation()->setPropertyValue($this, $property, $object);
419        $this->onUpdate();
420        return (bool) $returnValue;
421    }
422
423    /**
424     * Set multiple properties and their value at one time.
425     * Conveniance method isntead of adding the property values one by one.
426     *
427     * @access public
428     * @author Joel Bout, <joel.bout@tudor.lu>
429     * @param  array propertiesValues
430     * @return boolean
431     */
432    public function setPropertiesValues($propertiesValues)
433    {
434        $returnValue = (bool) false;
435        $returnValue = $this->getImplementation()->setPropertiesValues($this, $propertiesValues);
436        $this->onUpdate();
437        return (bool) $returnValue;
438    }
439
440    /**
441     * Short description of method setPropertyValueByLg
442     *
443     * @access public
444     * @author Joel Bout, <joel.bout@tudor.lu>
445     * @param  Property property
446     * @param  string value
447     * @param  string lg
448     * @return boolean
449     */
450    public function setPropertyValueByLg(core_kernel_classes_Property $property, $value, $lg)
451    {
452        $returnValue = (bool) false;
453        $returnValue = $this->getImplementation()->setPropertyValueByLg($this, $property, $value, $lg);
454        $this->onUpdate();
455        return (bool) $returnValue;
456    }
457
458    /**
459     * edit the assigned value(s) for the provided uriProperty regarding the
460     * resource using the provided object. Specific assignation edition (a
461     * triple) shouldbe made using triple management
462     *
463     * @access public
464     * @author Joel Bout, <joel.bout@tudor.lu>
465     * @param  Property property
466     * @param  string object
467     * @return boolean
468     */
469    public function editPropertyValues(core_kernel_classes_Property $property, $object)
470    {
471        $returnValue =  $this->removePropertyValues($property);
472        if (is_array($object)) {
473            foreach ($object as $value) {
474                $returnValue = $this->setPropertyValue($property, $value);
475            }
476        } else {
477            $returnValue = $this->setPropertyValue($property, $object);
478        }
479
480        return (bool) $returnValue;
481    }
482
483    /**
484     * Short description of method editPropertyValueByLg
485     *
486     * @access public
487     * @author Joel Bout, <joel.bout@tudor.lu>
488     * @param  Property prop
489     * @param  string value
490     * @param  string lg
491     * @return boolean
492     */
493    public function editPropertyValueByLg(core_kernel_classes_Property $prop, $value, $lg)
494    {
495        $returnValue = (bool) false;
496        $returnValue = $this->removePropertyValueByLg($prop, $lg);
497        $returnValue &= $this->setPropertyValueByLg($prop, $value, $lg);
498        return (bool) $returnValue;
499    }
500
501    /**
502     * remove a single triple with this subject and predicate
503     *
504     * @access public
505     * @author Joel Bout, <joel.bout@tudor.lu>
506     * @param  Property property
507     * @param  mixed value
508     * @return boolean
509     */
510    public function removePropertyValue(core_kernel_classes_Property $property, $value)
511    {
512        $returnValue = (bool) false;
513        $returnValue = $this->getImplementation()->removePropertyValues($this, $property, [
514            'pattern'   => (is_object($value) && $value instanceof self ? $value->getUri() : $value),
515            'like'      => false
516        ]);
517        $this->onUpdate();
518        return (bool) $returnValue;
519    }
520
521    /**
522     * remove all triples with this subject and predicate
523     *
524     * @access public
525     * @author Joel Bout, <joel.bout@tudor.lu>
526     * @param  Property property
527     * @param  array options
528     * @return boolean
529     */
530    public function removePropertyValues(core_kernel_classes_Property $property, $options = [])
531    {
532        $returnValue = (bool) false;
533        $returnValue = $this->getImplementation()->removePropertyValues($this, $property, $options);
534        $this->onUpdate();
535        return (bool) $returnValue;
536    }
537
538    /**
539     * Short description of method removePropertyValueByLg
540     *
541     * @access public
542     * @author Joel Bout, <joel.bout@tudor.lu>
543     * @param  Property prop
544     * @param  string lg
545     * @param  array options
546     * @return boolean
547     */
548    public function removePropertyValueByLg(core_kernel_classes_Property $prop, $lg, $options = [])
549    {
550        $returnValue = (bool) false;
551        $returnValue = $this->getImplementation()->removePropertyValueByLg($this, $prop, $lg, $options);
552        $this->onUpdate();
553        return (bool) $returnValue;
554    }
555
556    /**
557     * returns all generis statements about an uri, rdf level (there is no
558     * inferred by the rdfs level), restricted according to rights priviliges
559     * on statements
560     *
561     * @access public
562     * @author Joel Bout, <joel.bout@tudor.lu>
563     * @return core_kernel_classes_ContainerCollection
564     */
565    public function getRdfTriples()
566    {
567        $returnValue = null;
568        $returnValue = $this->getImplementation()->getRdfTriples($this);
569        return $returnValue;
570    }
571
572    /**
573     * return the languages in which a value exists for uriProperty for this
574     *
575     * @access public
576     * @author aptrick.plichart@tudor.lu
577     * @param  Property property
578     * @return array
579     */
580    public function getUsedLanguages(core_kernel_classes_Property $property)
581    {
582        return $this->getImplementation()->getUsedLanguages($this, $property);
583    }
584
585    /**
586     * Duplicate a resource: create a new URI and duplicate all the triples
587     * those with the predicate listed in excludedProperties.
588     * The method returns the new resource.
589     *
590     * @access public
591     * @author Joel Bout, <joel.bout@tudor.lu>
592     * @param  array excludedProperties
593     * @return core_kernel_classes_Resource
594     */
595    public function duplicate($excludedProperties = [])
596    {
597        $returnValue = $this->getImplementation()->duplicate($this, $excludedProperties);
598        return $returnValue;
599    }
600
601    /**
602     * Remove any assignation made to this resource, the uri is consequently
603     *
604     * @deprecated Use \oat\generis\model\resource\Repository\ResourceRepository::delete() instead
605     *
606     * @author patrick.plichart@tudor.lu
607     *
608     * @param bool $deleteReference set deleteReference to true when you need that all reference to this resource are
609     *                              removed.
610     *
611     * @return bool
612     */
613    public function delete($deleteReference = false)
614    {
615        try {
616            $this->getResourceRepository()->delete(
617                new ResourceRepositoryContext(
618                    [
619                        ResourceRepositoryContext::PARAM_RESOURCE => $this,
620                        ResourceRepositoryContext::PARAM_DELETE_REFERENCE => $deleteReference,
621                    ]
622                )
623            );
624
625            return true;
626        } catch (Throwable $exception) {
627            return false;
628        }
629    }
630
631
632
633    /**
634     * Short description of method __toString
635     *
636     * @access public
637     * @author Joel Bout, <joel.bout@tudor.lu>
638     * @return string
639     */
640    public function __toString(): string
641    {
642        return $this->getUri() . "\n" . $this->getLabel() ;
643    }
644
645    /**
646     * Short description of method getPropertiesValues
647     *
648     * @access public
649     * @author Joel Bout, <joel.bout@tudor.lu>
650     * @param  array properties
651     * @return array
652     */
653    public function getPropertiesValues($properties): array
654    {
655        if (!is_array($properties)) {
656            throw new common_exception_InvalidArgumentType(__CLASS__, __FUNCTION__, 0, 'array', $properties);
657        }
658        $returnValue = $this->getImplementation()->getPropertiesValues($this, $properties/*, $last*/);
659        return (array) $returnValue;
660    }
661
662    /**
663     * Short description of method setType
664     *
665     * @access public
666     * @author Joel Bout, <joel.bout@tudor.lu>
667     * @param  Class type
668     * @return boolean
669     */
670    public function setType(core_kernel_classes_Class $type): bool
671    {
672        $returnValue = $this->getImplementation()->setType($this, $type);
673
674        $this->onUpdate();
675
676        return (bool) $returnValue;
677    }
678
679    /**
680     * Short description of method removeType
681     *
682     * @access public
683     * @author Joel Bout, <joel.bout@tudor.lu>
684     * @param  Class type
685     * @return boolean
686     */
687    public function removeType(core_kernel_classes_Class $type): bool
688    {
689        $returnValue = $this->getImplementation()->removeType($this, $type);
690
691        $this->onUpdate();
692
693        return (bool) $returnValue;
694    }
695
696    /**
697     * Short description of method hasType
698     *
699     * @access public
700     * @author Joel Bout, <joel.bout@tudor.lu>
701     * @param  Class class
702     * @return boolean
703     */
704    public function hasType(core_kernel_classes_Class $class): bool
705    {
706        $returnValue = (bool) false;
707        foreach ($this->getTypes() as $type) {
708            if ($class->equals($type)) {
709                $returnValue = true;
710                break;
711            }
712        }
713        return (bool) $returnValue;
714    }
715
716    /**
717     * Short description of method exists
718     *
719     * @access public
720     * @author Joel Bout, <joel.bout@tudor.lu>
721     * @return boolean
722     */
723    public function exists()
724    {
725        $returnValue = (bool) false;
726        try {
727            $returnValue = count($this->getTypes()) ? true : false;
728        } catch (Exception $e) {
729            ;//return false by default
730        }
731        return (bool) $returnValue;
732    }
733
734    /**
735     * returns the full URI as string (including namespace)
736     *
737     * @access public
738     * @author Joel Bout, <joel.bout@tudor.lu>
739     * @return string
740     */
741    public function getUri(): string
742    {
743        return (string) $this->uriResource;
744    }
745
746    /**
747     * Short description of method equals
748     *
749     * @access public
750     * @author Joel Bout, <joel.bout@tudor.lu>
751     * @param  Resource resource
752     * @return boolean
753     */
754    public function equals(core_kernel_classes_Resource $resource): bool
755    {
756        return $this->getUri() === $resource->getUri();
757    }
758
759    /**
760     * Whenever or not the current resource is an instance of the specified class
761     *
762     * @author Joel Bout, <joel.bout@tudor.lu>
763     */
764    public function isInstanceOf(core_kernel_classes_Class $class): bool
765    {
766        foreach ($this->getTypes() as $type) {
767            if ($class->equals($type) || $type->isSubClassOf($class)) {
768                return true;
769            }
770        }
771
772        return false;
773    }
774
775    public function getRootId(): string
776    {
777        $parentClassesIds = $this->getParentClassesIds();
778
779        return array_pop($parentClassesIds);
780    }
781
782    /**
783     * Return the parent class URI of a resource
784     */
785    public function getParentClassId(): ?string
786    {
787        return current($this->getParentClassesIds()) ?: null;
788    }
789
790    public function getParentClassesIds(): array
791    {
792        $implementation = $this->getImplementation();
793
794        if ($implementation instanceof core_kernel_persistence_smoothsql_Resource) {
795            return $implementation->getParentClassesIds($this->getUri());
796        }
797
798        return [];
799    }
800
801    /**
802     * @return array [
803     *     '{classUri}' => [
804     *         '{resourceUri_1}',
805     *         '{resourceUri_N...}',
806     *     ]
807     * ]
808     */
809    public function getParentClassesResourceIds(array $classIds = null): array
810    {
811        $implementation = $this->getImplementation();
812
813        if ($implementation instanceof core_kernel_persistence_smoothsql_Resource) {
814            return $implementation->getClassesResourceIds($classIds ?? $this->getParentClassesIds());
815        }
816
817        return [];
818    }
819
820    /**
821     * Returns a list of nested resources/classes under a resource
822     *
823     * @return array [
824     *     [
825     *         'id' => '{resourceId}',
826     *         'isClass' => true|false,
827     *         'level' => 1..N,
828     *     ]
829     * ]
830     */
831    public function getNestedResources(): array
832    {
833        $implementation = $this->getImplementation();
834
835        if ($implementation instanceof core_kernel_persistence_smoothsql_Resource) {
836            return $implementation->getNestedResources($this->getUri());
837        }
838
839        return [];
840    }
841
842    public function getServiceManager(): ServiceLocatorInterface
843    {
844        return ($this->getModel() instanceof ServiceLocatorAwareInterface)
845            ? $this->getModel()->getServiceLocator()
846            : ServiceManager::getServiceManager();
847    }
848
849    /**
850     * Moved from common_Utils to not break dependency ingestion chain
851     * @param string $value
852     * @return core_kernel_classes_Literal|core_kernel_classes_Resource|core_kernel_classes_Resource[]
853     */
854    protected function toResource($value)
855    {
856        if (is_array($value)) {
857            $returnValue = [];
858            foreach ($value as $val) {
859                $returnValue[] = $this->toResource($val);
860            }
861            return $returnValue;
862        } else {
863            if (common_Utils::isUri($value)) {
864                return $this->getResource($value);
865            } else {
866                return new core_kernel_classes_Literal($value);
867            }
868        }
869    }
870
871    private function onUpdate(): void
872    {
873        /** @var EventAggregator $eventAggregator */
874        $eventAggregator = $this->getServiceManager()->get(EventAggregator::SERVICE_ID);
875        $eventAggregator->put($this->getUri(), new ResourceUpdated($this));
876    }
877
878    private function getResourceRepository(): ResourceRepositoryInterface
879    {
880        return $this->getServiceManager()->getContainer()->get(ResourceRepository::class);
881    }
882}