Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
43.66% |
62 / 142 |
|
38.46% |
10 / 26 |
CRAP | |
0.00% |
0 / 1 |
core_kernel_classes_Property | |
43.66% |
62 / 142 |
|
38.46% |
10 / 26 |
946.20 | |
0.00% |
0 / 1 |
getImplementation | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
feed | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
feedFromData | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
30 | |||
getDomain | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
getRelatedClass | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
isStatistical | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
setDomain | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
42 | |||
getRange | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
12 | |||
setRange | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
getAlias | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
getDependsOnPropertyCollection | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
20 | |||
setDependsOnPropertyCollection | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
getWidget | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
isLgDependent | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
4 | |||
setLgDependent | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
isMultiple | |
90.91% |
10 / 11 |
|
0.00% |
0 / 1 |
5.02 | |||
setMultiple | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
isRelationship | |
90.48% |
19 / 21 |
|
0.00% |
0 / 1 |
8.06 | |||
delete | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
clearCachedValues | |
91.67% |
11 / 12 |
|
0.00% |
0 / 1 |
5.01 | |||
warmupCachedValues | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
generateIsRelationshipKey | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
generateIsLgDependentKey | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
generateIsMultipleKey | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
supportCache | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
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 | * |
25 | */ |
26 | |
27 | declare(strict_types=1); |
28 | |
29 | use oat\generis\model\OntologyRdf; |
30 | use oat\generis\model\WidgetRdf; |
31 | use oat\generis\model\GenerisRdf; |
32 | use oat\generis\model\OntologyRdfs; |
33 | use oat\generis\model\resource\DependsOnPropertyCollection; |
34 | use oat\generis\model\kernel\persistence\Cacheable; |
35 | |
36 | /** |
37 | * uriProperty must be a valid property otherwis return false, add this as a |
38 | * of uriProperty |
39 | * |
40 | * @access public |
41 | * @author patrick.plichart@tudor.lu |
42 | * @package generis |
43 | |
44 | */ |
45 | class core_kernel_classes_Property extends core_kernel_classes_Resource |
46 | { |
47 | public const RELATIONSHIP_PROPERTIES = [ |
48 | OntologyRdf::RDF_TYPE, |
49 | OntologyRdfs::RDFS_CLASS, |
50 | OntologyRdfs::RDFS_RANGE, |
51 | OntologyRdfs::RDFS_DOMAIN, |
52 | OntologyRdfs::RDFS_SUBCLASSOF, |
53 | OntologyRdfs::RDFS_SUBPROPERTYOF, |
54 | ]; |
55 | |
56 | // --- ASSOCIATIONS --- |
57 | |
58 | |
59 | // --- ATTRIBUTES --- |
60 | |
61 | /** |
62 | * The property domain defines the classes the property is attached to. |
63 | * |
64 | * @access public |
65 | * @var ContainerCollection |
66 | */ |
67 | public $domain = null; |
68 | |
69 | /** |
70 | * The property's range defines either the possibles class' instances |
71 | * or a literal value if the range is the Literal class |
72 | * |
73 | * @access public |
74 | * @var core_kernel_classes_Class |
75 | */ |
76 | public $range = null; |
77 | |
78 | /** |
79 | * The widget the can be used to represents the property. |
80 | * |
81 | * Dev note: this property is set to false because null is also a possible |
82 | * valid value for this property. This will prevent the widget to be property |
83 | * to be retrieved even if in cache, when no widget is set for the property. |
84 | * |
85 | * @access public |
86 | * @var core_kernel_classes_Property |
87 | */ |
88 | public $widget = false; |
89 | |
90 | /** @var DependsOnPropertyCollection */ |
91 | private $dependsOnPropertyCollection; |
92 | |
93 | // --- OPERATIONS --- |
94 | /** |
95 | * @return core_kernel_persistence_PropertyInterface |
96 | */ |
97 | private function getImplementation() |
98 | { |
99 | return $this->getModel()->getRdfsInterface()->getPropertyImplementation(); |
100 | } |
101 | |
102 | /** |
103 | * constructor |
104 | * |
105 | * @access public |
106 | * @author Cédric Alfonsi, <cedric.alfonsi@tudor.lu> |
107 | * @param string uri |
108 | * @param string debug |
109 | * @return void |
110 | */ |
111 | public function __construct($uri, $debug = '') |
112 | { |
113 | parent::__construct($uri, $debug); |
114 | } |
115 | |
116 | /** |
117 | * |
118 | * @author Cédric Alfonsi, <cedric.alfonsi@tudor.lu> |
119 | */ |
120 | public function feed() |
121 | { |
122 | $this->getWidget(); |
123 | $this->getRange(); |
124 | $this->getDomain(); |
125 | $this->isLgDependent(); |
126 | } |
127 | |
128 | public function feedFromData($widget, $range, $domain) |
129 | { |
130 | $this->widget = is_string($widget) ? $this->getModel()->getResource($widget) : $widget; |
131 | $this->range = is_string($range) ? $this->getModel()->getClass($range) : $range; |
132 | |
133 | if (is_string($domain)) { |
134 | $this->domain = new core_kernel_classes_ContainerCollection(new common_Object()); |
135 | $domainValues = [$domain]; |
136 | foreach ($domainValues as $domainValue) { |
137 | $this->domain->add($this->getClass($domainValue)); |
138 | } |
139 | } else { |
140 | $this->domain = $domain; |
141 | } |
142 | |
143 | $this->isLgDependent(); |
144 | } |
145 | |
146 | /** |
147 | * return classes that are described by this property |
148 | * |
149 | * @access public |
150 | * @author Cédric Alfonsi, <cedric.alfonsi@tudor.lu> |
151 | * @return core_kernel_classes_ContainerCollection |
152 | */ |
153 | public function getDomain() |
154 | { |
155 | if (is_null($this->domain)) { |
156 | $this->domain = new core_kernel_classes_ContainerCollection(new common_Object(__METHOD__)); |
157 | $domainValues = $this->getPropertyValues($this->getProperty(OntologyRdfs::RDFS_DOMAIN)); |
158 | foreach ($domainValues as $domainValue) { |
159 | $this->domain->add($this->getClass($domainValue)); |
160 | } |
161 | } |
162 | |
163 | return $this->domain; |
164 | } |
165 | |
166 | public function getRelatedClass(): ?core_kernel_classes_Class |
167 | { |
168 | try { |
169 | $class = $this->getDomain()->get(0); |
170 | |
171 | return $class instanceof core_kernel_classes_Class ? $class : null; |
172 | } catch (common_Exception $exception) { |
173 | return null; |
174 | } |
175 | } |
176 | |
177 | public function isStatistical(): bool |
178 | { |
179 | $value = $this->getOnePropertyValue($this->getProperty(GenerisRdf::PROPERTY_IS_STATISTICAL)); |
180 | |
181 | return $value instanceof core_kernel_classes_Resource && $value->getUri() === GenerisRdf::GENERIS_TRUE; |
182 | } |
183 | |
184 | /** |
185 | * Short description of method setDomain |
186 | * |
187 | * @access public |
188 | * @author Cédric Alfonsi, <cedric.alfonsi@tudor.lu> |
189 | * @param Class class |
190 | * @return boolean |
191 | */ |
192 | public function setDomain(core_kernel_classes_Class $class) |
193 | { |
194 | $returnValue = (bool) false; |
195 | |
196 | if (!is_null($class)) { |
197 | foreach ($this->getDomain()->getIterator() as $domainClass) { |
198 | if ($class->equals($domainClass)) { |
199 | $returnValue = true; |
200 | break; |
201 | } |
202 | } |
203 | if (!$returnValue) { |
204 | $this->setPropertyValue($this->getProperty(OntologyRdfs::RDFS_DOMAIN), $class->getUri()); |
205 | if (!is_null($this->domain)) { |
206 | $this->domain->add($class); |
207 | } |
208 | $returnValue = true; |
209 | } |
210 | } |
211 | return (bool) $returnValue; |
212 | } |
213 | |
214 | /** |
215 | * Short description of method getRange |
216 | * |
217 | * @access public |
218 | * @author Cédric Alfonsi, <cedric.alfonsi@tudor.lu> |
219 | * @return core_kernel_classes_ContainerCollection |
220 | */ |
221 | public function getRange() |
222 | { |
223 | $returnValue = null; |
224 | |
225 | if (is_null($this->range)) { |
226 | $rangeProperty = $this->getProperty(OntologyRdfs::RDFS_RANGE); |
227 | $rangeValues = $this->getPropertyValues($rangeProperty); |
228 | |
229 | if (!empty($rangeValues)) { |
230 | $returnValue = $this->getClass($rangeValues[0]); |
231 | } |
232 | $this->range = $returnValue; |
233 | } |
234 | $returnValue = $this->range; |
235 | return $returnValue; |
236 | } |
237 | |
238 | /** |
239 | * Short description of method setRange |
240 | * |
241 | * @access public |
242 | * @author Cédric Alfonsi, <cedric.alfonsi@tudor.lu> |
243 | * @param Class class |
244 | * @return boolean |
245 | */ |
246 | public function setRange(core_kernel_classes_Class $class): bool |
247 | { |
248 | $returnValue = $this->getImplementation()->setRange($this, $class); |
249 | if ($returnValue) { |
250 | $this->range = $class; |
251 | } |
252 | return (bool)$returnValue; |
253 | } |
254 | |
255 | public function getAlias(): ?string |
256 | { |
257 | $container = $this->getOnePropertyValue($this->getProperty(GenerisRdf::PROPERTY_ALIAS)); |
258 | |
259 | if ($container instanceof core_kernel_classes_Literal) { |
260 | return $container->__toString(); |
261 | } |
262 | |
263 | return null; |
264 | } |
265 | |
266 | public function getDependsOnPropertyCollection(): DependsOnPropertyCollection |
267 | { |
268 | if (!isset($this->dependsOnPropertyCollection)) { |
269 | $dependsOnProperty = $this->getProperty(GenerisRdf::PROPERTY_DEPENDS_ON_PROPERTY); |
270 | $dependsOnPropertyValues = $this->getPropertyValues($dependsOnProperty); |
271 | $this->dependsOnPropertyCollection = new DependsOnPropertyCollection(); |
272 | |
273 | foreach ($dependsOnPropertyValues as $dependsOnPropertyValue) { |
274 | if ($dependsOnPropertyValue !== GenerisRdf::PROPERTY_DEPENDS_ON_PROPERTY) { |
275 | $this->dependsOnPropertyCollection->append( |
276 | $this->getProperty($dependsOnPropertyValue) |
277 | ); |
278 | } |
279 | } |
280 | } |
281 | |
282 | $this->dependsOnPropertyCollection->rewind(); |
283 | |
284 | return $this->dependsOnPropertyCollection; |
285 | } |
286 | |
287 | /** |
288 | * @TODO Improve setter |
289 | */ |
290 | public function setDependsOnPropertyCollection(DependsOnPropertyCollection $dependsOnPropertyCollection): void |
291 | { |
292 | foreach ($dependsOnPropertyCollection as $dependsOnProperty) { |
293 | $this->getImplementation()->setDependsOnProperty($this, $dependsOnProperty); |
294 | } |
295 | |
296 | $this->dependsOnPropertyCollection = $dependsOnPropertyCollection; |
297 | } |
298 | |
299 | /** |
300 | * Get the Property object corresponding to the widget of this Property. |
301 | * |
302 | * @author Cédric Alfonsi <cedric.alfonsi@tudor.lu> |
303 | * @author Antoine Delamarre <antoine.delamarre@vesperiagroup.com> |
304 | * @author Jérôme Bogaerts <jerome@taotesting.com> |
305 | * @return core_kernel_classes_Property The Property object corresponding to the widget of this Property. |
306 | */ |
307 | public function getWidget() |
308 | { |
309 | if ($this->widget === false) { |
310 | $this->widget = $this->getOnePropertyValue($this->getProperty(WidgetRdf::PROPERTY_WIDGET)); |
311 | } |
312 | |
313 | return $this->widget; |
314 | } |
315 | |
316 | /** |
317 | * Is the property translatable? |
318 | * |
319 | * @access public |
320 | * @author Cédric Alfonsi, <cedric.alfonsi@tudor.lu> |
321 | * @return boolean |
322 | */ |
323 | public function isLgDependent(): bool |
324 | { |
325 | if ( |
326 | $this->supportCache() |
327 | && $this->getModel()->getCache()->has($this->generateIsLgDependentKey($this->getUri())) |
328 | ) { |
329 | return (bool)$this->getModel()->getCache()->get($this->generateIsLgDependentKey($this->getUri())); |
330 | } |
331 | |
332 | $isLgDependent = $this->getImplementation()->isLgDependent($this); |
333 | |
334 | if ($this->supportCache()) { |
335 | $this->getModel()->getCache()->set($this->generateIsLgDependentKey($this->getUri()), $isLgDependent); |
336 | } |
337 | |
338 | return $isLgDependent; |
339 | } |
340 | |
341 | /** |
342 | * Set mannually if a property can be translated |
343 | * |
344 | * @access public |
345 | * @author Cédric Alfonsi, <cedric.alfonsi@tudor.lu> |
346 | * @return mixed |
347 | */ |
348 | public function setLgDependent($isLgDependent): void |
349 | { |
350 | $this->getImplementation()->setLgDependent($this, $isLgDependent); |
351 | |
352 | if ($this->supportCache()) { |
353 | $this->getModel()->getCache()->set($this->generateIsLgDependentKey($this->getUri()), $isLgDependent); |
354 | } |
355 | } |
356 | |
357 | /** |
358 | * Check if a property can have multiple values. |
359 | * |
360 | * @access public |
361 | * @author Cédric Alfonsi, <cedric.alfonsi@tudor.lu> |
362 | * @return boolean |
363 | */ |
364 | public function isMultiple(): bool |
365 | { |
366 | if ( |
367 | $this->supportCache() |
368 | && $this->getModel()->getCache()->has($this->generateIsMultipleKey($this->getUri())) |
369 | ) { |
370 | return (bool)$this->getModel()->getCache()->get($this->generateIsMultipleKey($this->getUri())); |
371 | } |
372 | |
373 | $multipleProperty = $this->getProperty(GenerisRdf::PROPERTY_MULTIPLE); |
374 | $multiple = $this->getOnePropertyValue($multipleProperty); |
375 | |
376 | if (is_null($multiple)) { |
377 | $returnValue = false; |
378 | } else { |
379 | $returnValue = ($multiple->getUri() == GenerisRdf::GENERIS_TRUE); |
380 | } |
381 | |
382 | if ($this->supportCache()) { |
383 | $this->getModel()->getCache()->set($this->generateIsMultipleKey($this->getUri()), $returnValue); |
384 | } |
385 | |
386 | return $returnValue; |
387 | } |
388 | |
389 | /** |
390 | * Define mannualy if a property is multiple or not. |
391 | * Usefull on just created property. |
392 | * |
393 | * @access public |
394 | * @author Cédric Alfonsi, <cedric.alfonsi@tudor.lu> |
395 | * @return mixed |
396 | */ |
397 | public function setMultiple($isMultiple): void |
398 | { |
399 | $this->getImplementation()->setMultiple($this, $isMultiple); |
400 | |
401 | if ($this->supportCache()) { |
402 | $this->getModel()->getCache()->set($this->generateIsMultipleKey($this->getUri()), $isMultiple); |
403 | } |
404 | } |
405 | |
406 | /** |
407 | * Checks if property is a relation to other class |
408 | * |
409 | * @return bool |
410 | */ |
411 | public function isRelationship(core_kernel_classes_Class $range = null): bool |
412 | { |
413 | if (in_array($this->getUri(), self::RELATIONSHIP_PROPERTIES)) { |
414 | return true; |
415 | } |
416 | if ($this->getUri() === OntologyRdf::RDF_VALUE) { |
417 | return false; |
418 | } |
419 | |
420 | $model = $this->getModel(); |
421 | |
422 | if ($this->supportCache() && $model->getCache()->has($this->generateIsRelationshipKey($this->getUri()))) { |
423 | $isRelationship = (bool)$model->getCache()->get($this->generateIsRelationshipKey($this->getUri())); |
424 | } else { |
425 | if (empty($range)) { |
426 | $range = $this->getRange(); |
427 | } |
428 | |
429 | $isRelationship = $range |
430 | && !in_array( |
431 | $range->getUri(), |
432 | [ |
433 | OntologyRdfs::RDFS_LITERAL, |
434 | GenerisRdf::CLASS_GENERIS_FILE |
435 | ], |
436 | true |
437 | ); |
438 | |
439 | if ($this->supportCache()) { |
440 | $this->getModel()->getCache()->set($this->generateIsRelationshipKey($this->getUri()), $isRelationship); |
441 | } |
442 | } |
443 | |
444 | return $isRelationship; |
445 | } |
446 | |
447 | /** |
448 | * Short description of method delete |
449 | * |
450 | * @access public |
451 | * @author Cédric Alfonsi, <cedric.alfonsi@tudor.lu> |
452 | * @param boolean deleteReference |
453 | * @return boolean |
454 | */ |
455 | public function delete($deleteReference = false): bool |
456 | { |
457 | $returnValue = $this->getImplementation()->delete($this, $deleteReference); |
458 | |
459 | $this->clearCachedValues(); |
460 | |
461 | return (bool) $returnValue; |
462 | } |
463 | |
464 | /** |
465 | * Clear property cached data |
466 | */ |
467 | public function clearCachedValues(): void |
468 | { |
469 | if (!$this->supportCache()) { |
470 | return; |
471 | } |
472 | |
473 | /** @var \oat\oatbox\cache\SimpleCache $cache */ |
474 | $cache = $this->getModel()->getCache(); |
475 | $isRelationshipKey = $this->generateIsRelationshipKey($this->getUri()); |
476 | $isMultipleKey = $this->generateIsMultipleKey($this->getUri()); |
477 | $isLgDependentKey = $this->generateIsLgDependentKey($this->getUri()); |
478 | |
479 | if ($cache->has($isRelationshipKey)) { |
480 | $cache->delete($isRelationshipKey); |
481 | } |
482 | |
483 | if ($cache->has($isMultipleKey)) { |
484 | $cache->delete($isMultipleKey); |
485 | } |
486 | |
487 | if ($cache->has($isLgDependentKey)) { |
488 | $cache->delete($isLgDependentKey); |
489 | } |
490 | } |
491 | |
492 | /** |
493 | * Warmup property cached data |
494 | */ |
495 | public function warmupCachedValues(): void |
496 | { |
497 | if (!$this->supportCache()) { |
498 | return; |
499 | } |
500 | |
501 | $this->isRelationship(); |
502 | $this->isMultiple(); |
503 | $this->isLgDependent(); |
504 | } |
505 | |
506 | protected function generateIsRelationshipKey(string $uri): string |
507 | { |
508 | return sprintf('PropIsRelationship_%s', $uri); |
509 | } |
510 | |
511 | protected function generateIsLgDependentKey(string $uri): string |
512 | { |
513 | return sprintf('PropIsLgDependent_%s', $uri); |
514 | } |
515 | |
516 | protected function generateIsMultipleKey(string $uri): string |
517 | { |
518 | return sprintf('PropIsMultiple_%s', $uri); |
519 | } |
520 | |
521 | /** |
522 | * @return bool |
523 | */ |
524 | protected function supportCache(): bool |
525 | { |
526 | return $this->getModel() instanceof Cacheable; |
527 | } |
528 | } |