Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
7.38% |
22 / 298 |
|
0.00% |
0 / 21 |
CRAP | |
0.00% |
0 / 1 |
core_kernel_persistence_smoothsql_Class | |
7.38% |
22 / 298 |
|
0.00% |
0 / 21 |
5961.91 | |
0.00% |
0 / 1 |
getSubClasses | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
12 | |||
getRecursiveSubClasses | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
30 | |||
isSubClassOf | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
30 | |||
getParentClasses | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
42 | |||
getProperties | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
30 | |||
getInstances | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
20 | |||
setInstance | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setSubClassOf | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
setProperty | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
createInstance | |
82.35% |
14 / 17 |
|
0.00% |
0 / 1 |
6.20 | |||
createSubClass | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
30 | |||
createProperty | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
6 | |||
searchInstances | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
12 | |||
countInstances | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
20 | |||
getInstancesPropertyValues | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
30 | |||
unsetProperty | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
createInstanceWithProperties | |
72.73% |
8 / 11 |
|
0.00% |
0 / 1 |
2.08 | |||
deleteInstances | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
42 | |||
getFilteredQuery | |
0.00% |
0 / 48 |
|
0.00% |
0 / 1 |
342 | |||
updateUri | |
0.00% |
0 / 24 |
|
0.00% |
0 / 1 |
2 | |||
getInstanceUris | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
6 |
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 | * 2012-2017 (update and modification) Open Assessment Technologies SA (under the project TAO-PRODUCT); |
25 | */ |
26 | |
27 | use oat\generis\model\data\event\ClassPropertyCreatedEvent; |
28 | use oat\generis\model\GenerisRdf; |
29 | use oat\generis\model\OntologyRdf; |
30 | use oat\generis\model\OntologyRdfs; |
31 | use oat\oatbox\event\EventManagerAwareTrait; |
32 | use oat\generis\model\kernel\persistence\smoothsql\search\ComplexSearchService; |
33 | use Doctrine\DBAL\DBALException; |
34 | use oat\generis\model\kernel\uri\UriProvider; |
35 | |
36 | /** |
37 | * Short description of class core_kernel_persistence_smoothsql_Class |
38 | * |
39 | */ |
40 | class core_kernel_persistence_smoothsql_Class extends core_kernel_persistence_smoothsql_Resource implements |
41 | core_kernel_persistence_ClassInterface |
42 | { |
43 | use EventManagerAwareTrait; |
44 | |
45 | /** |
46 | * (non-PHPdoc) |
47 | * @see core_kernel_persistence_ClassInterface::getSubClasses() |
48 | */ |
49 | public function getSubClasses(core_kernel_classes_Class $resource, $recursive = false) |
50 | { |
51 | if (!$recursive) { |
52 | $returnValue = []; |
53 | $sqlQuery = 'SELECT subject FROM statements WHERE predicate = ? and ' |
54 | . $this->getPersistence()->getPlatForm()->getObjectTypeCondition() . ' = ?'; |
55 | $sqlResult = $this->getPersistence()->query( |
56 | $sqlQuery, |
57 | [OntologyRdfs::RDFS_SUBCLASSOF, $resource->getUri()] |
58 | ); |
59 | while ($row = $sqlResult->fetch()) { |
60 | $returnValue[$row['subject']] = $this->getModel()->getClass($row['subject']); |
61 | } |
62 | return $returnValue; |
63 | } else { |
64 | return $this->getRecursiveSubClasses($resource); |
65 | } |
66 | } |
67 | |
68 | /** |
69 | * Improved recursive class traversal (reduced to 1 query per tree depth) |
70 | * @param core_kernel_classes_Class $resource |
71 | * @return array |
72 | */ |
73 | private function getRecursiveSubClasses(core_kernel_classes_Class $resource) |
74 | { |
75 | $returnValue = []; |
76 | $todo = [$resource]; |
77 | while (!empty($todo)) { |
78 | $classString = ''; |
79 | foreach ($todo as $class) { |
80 | $classString .= ", " . $this->getPersistence()->quote($class->getUri()) ; |
81 | } |
82 | $sqlQuery = 'SELECT subject FROM statements WHERE predicate = ? and ' |
83 | . $this->getPersistence()->getPlatForm()->getObjectTypeCondition() . ' in (' |
84 | . substr($classString, 1) . ')'; |
85 | $sqlResult = $this->getPersistence()->query($sqlQuery, [OntologyRdfs::RDFS_SUBCLASSOF]); |
86 | $todo = []; |
87 | while ($row = $sqlResult->fetch()) { |
88 | $subClass = $this->getModel()->getClass($row['subject']); |
89 | if (!isset($returnValue[$subClass->getUri()])) { |
90 | $todo[] = $subClass; |
91 | } |
92 | $returnValue[$subClass->getUri()] = $subClass; |
93 | } |
94 | } |
95 | return (array) $returnValue; |
96 | } |
97 | |
98 | /** |
99 | * (non-PHPdoc) |
100 | * @see core_kernel_persistence_ClassInterface::isSubClassOf() |
101 | */ |
102 | public function isSubClassOf(core_kernel_classes_Class $resource, core_kernel_classes_Class $parentClass) |
103 | { |
104 | $returnValue = false; |
105 | |
106 | $query = 'SELECT object FROM statements WHERE subject = ? AND predicate = ? AND ' |
107 | . $this->getPersistence()->getPlatForm()->getObjectTypeCondition() . ' = ?'; |
108 | $result = $this->getPersistence()->query($query, [ |
109 | $resource->getUri(), |
110 | OntologyRdfs::RDFS_SUBCLASSOF, |
111 | $parentClass->getUri() |
112 | ]); |
113 | |
114 | while ($row = $result->fetch()) { |
115 | $returnValue = true; |
116 | break; |
117 | } |
118 | |
119 | if (!$returnValue) { |
120 | $parentSubClasses = $parentClass->getSubClasses(true); |
121 | foreach ($parentSubClasses as $subClass) { |
122 | if ($subClass->getUri() == $resource->getUri()) { |
123 | $returnValue = true; |
124 | break; |
125 | } |
126 | } |
127 | } |
128 | |
129 | return $returnValue; |
130 | } |
131 | |
132 | /** |
133 | * (non-PHPdoc) |
134 | * @see core_kernel_persistence_ClassInterface::getParentClasses() |
135 | */ |
136 | public function getParentClasses(core_kernel_classes_Class $resource, $recursive = false) |
137 | { |
138 | $returnValue = []; |
139 | |
140 | $sqlQuery = 'SELECT object FROM statements WHERE subject = ? AND predicate = ?'; |
141 | |
142 | $sqlResult = $this->getPersistence()->query($sqlQuery, [$resource->getUri(), OntologyRdfs::RDFS_SUBCLASSOF]); |
143 | |
144 | while ($row = $sqlResult->fetch()) { |
145 | $parentClass = $this->getModel()->getClass($row['object']); |
146 | |
147 | $returnValue[$parentClass->getUri()] = $parentClass ; |
148 | if ( |
149 | $recursive == true |
150 | && $parentClass->getUri() != OntologyRdfs::RDFS_CLASS |
151 | && $parentClass->getUri() != OntologyRdfs::RDFS_RESOURCE |
152 | ) { |
153 | if ($parentClass->getUri() == GenerisRdf::CLASS_GENERIS_RESOURCE) { |
154 | $returnValue[OntologyRdfs::RDFS_RESOURCE] = $this->getModel()->getClass( |
155 | OntologyRdfs::RDFS_RESOURCE |
156 | ); |
157 | } else { |
158 | $plop = $parentClass->getParentClasses(true); |
159 | $returnValue = array_merge($returnValue, $plop); |
160 | } |
161 | } |
162 | } |
163 | |
164 | return $returnValue; |
165 | } |
166 | |
167 | /** |
168 | * (non-PHPdoc) |
169 | * @see core_kernel_persistence_ClassInterface::getProperties() |
170 | */ |
171 | public function getProperties(core_kernel_classes_Class $resource, $recursive = false) |
172 | { |
173 | $returnValue = []; |
174 | |
175 | $sqlQuery = 'SELECT subject FROM statements WHERE predicate = ? AND ' |
176 | . $this->getPersistence()->getPlatForm()->getObjectTypeCondition() . ' = ?'; |
177 | $sqlResult = $this->getPersistence()->query($sqlQuery, [ |
178 | OntologyRdfs::RDFS_DOMAIN, |
179 | $resource->getUri() |
180 | ]); |
181 | |
182 | while ($row = $sqlResult->fetch()) { |
183 | $property = $this->getModel()->getProperty($row['subject']); |
184 | $returnValue[$property->getUri()] = $property; |
185 | } |
186 | |
187 | if ($recursive == true) { |
188 | $parentClasses = $this->getParentClasses($resource, true); |
189 | foreach ($parentClasses as $parent) { |
190 | if ($parent->getUri() != OntologyRdfs::RDFS_CLASS) { |
191 | $returnValue = array_merge($returnValue, $parent->getProperties(false)); |
192 | } |
193 | } |
194 | } |
195 | |
196 | return $returnValue; |
197 | } |
198 | |
199 | /** |
200 | * (non-PHPdoc) |
201 | * @see core_kernel_persistence_ClassInterface::getInstances() |
202 | */ |
203 | public function getInstances(core_kernel_classes_Class $resource, $recursive = false, $params = []) |
204 | { |
205 | $returnValue = []; |
206 | |
207 | if (empty($params)) { |
208 | $resourceIds = $this->getInstanceUris($resource->getUri(), $recursive); |
209 | |
210 | foreach ($resourceIds as $resourceId) { |
211 | $returnValue[$resourceId] = $this->getModel()->getResource($resourceId); |
212 | } |
213 | |
214 | return $returnValue; |
215 | } |
216 | |
217 | $params = array_merge($params, ['like' => false, 'recursive' => $recursive]); |
218 | |
219 | $query = $this->getFilteredQuery($resource, [], $params); |
220 | $result = $this->getPersistence()->query($query); |
221 | |
222 | while ($row = $result->fetch()) { |
223 | $foundInstancesUri = $row['subject']; |
224 | $returnValue[$foundInstancesUri] = $this->getModel()->getResource($foundInstancesUri); |
225 | } |
226 | |
227 | return $returnValue; |
228 | } |
229 | |
230 | /** |
231 | * |
232 | * @param core_kernel_classes_Class $resource |
233 | * @param core_kernel_classes_Resource $instance |
234 | * @throws common_exception_DeprecatedApiMethod |
235 | * @return core_kernel_classes_Resource |
236 | * @deprecated |
237 | */ |
238 | public function setInstance(core_kernel_classes_Class $resource, core_kernel_classes_Resource $instance) |
239 | { |
240 | throw new common_exception_DeprecatedApiMethod(__METHOD__ . ' is deprecated. '); |
241 | } |
242 | |
243 | /** |
244 | * Short description of method setSubClassOf |
245 | * |
246 | * @access public |
247 | * @author Jerome Bogaerts, <jerome.bogaerts@tudor.lu> |
248 | * @param core_kernel_classes_Class resource |
249 | * @param Class iClass |
250 | * @return boolean |
251 | * |
252 | */ |
253 | public function setSubClassOf(core_kernel_classes_Class $resource, core_kernel_classes_Class $iClass) |
254 | { |
255 | $returnValue = (bool) false; |
256 | |
257 | $subClassOf = $this->getModel()->getProperty(OntologyRdfs::RDFS_SUBCLASSOF); |
258 | $returnValue = $this->setPropertyValue($resource, $subClassOf, $iClass->getUri()); |
259 | |
260 | return (bool) $returnValue; |
261 | } |
262 | |
263 | /** |
264 | * Short description of method setProperty |
265 | * |
266 | * @access public |
267 | * @author Jerome Bogaerts, <jerome.bogaerts@tudor.lu> |
268 | * @param core_kernel_classes_Class resource |
269 | * @param Property property |
270 | * @return boolean |
271 | * @deprecated |
272 | * |
273 | */ |
274 | public function setProperty(core_kernel_classes_Class $resource, core_kernel_classes_Property $property) |
275 | { |
276 | throw new common_exception_DeprecatedApiMethod(__METHOD__ . ' is deprecated. '); |
277 | } |
278 | |
279 | /** |
280 | * (non-PHPdoc) |
281 | * @see core_kernel_persistence_ClassInterface::createInstance() |
282 | */ |
283 | public function createInstance(core_kernel_classes_Class $resource, $label = '', $comment = '', $uri = '') |
284 | { |
285 | $returnValue = null; |
286 | |
287 | $subject = ''; |
288 | if ($uri == '') { |
289 | $subject = $this->getServiceLocator()->get(UriProvider::SERVICE_ID)->provide(); |
290 | } elseif ($uri[0] == '#') { //$uri should start with # and be well formed |
291 | $modelUri = common_ext_NamespaceManager::singleton()->getLocalNamespace()->getUri(); |
292 | $subject = rtrim($modelUri, '#') . $uri; |
293 | } else { |
294 | $subject = $uri; |
295 | } |
296 | |
297 | $returnValue = $this->getModel()->getResource($subject); |
298 | if (!$returnValue->hasType($resource)) { |
299 | $returnValue->setType($resource); |
300 | } else { |
301 | common_Logger::e('already had type ' . $resource); |
302 | } |
303 | |
304 | if (!empty($label)) { |
305 | $returnValue->setLabel($label); |
306 | } |
307 | if (!empty($comment)) { |
308 | $returnValue->setComment($comment); |
309 | } |
310 | |
311 | return $returnValue; |
312 | } |
313 | |
314 | /** |
315 | * (non-PHPdoc) |
316 | * @see core_kernel_persistence_ClassInterface::createSubClass() |
317 | */ |
318 | public function createSubClass(core_kernel_classes_Class $resource, $label = '', $comment = '', $uri = '') |
319 | { |
320 | if (!empty($uri)) { |
321 | common_Logger::w('Use of parameter uri in ' . __METHOD__ . ' is deprecated'); |
322 | } |
323 | $uri = empty($uri) ? $this->getServiceLocator()->get(UriProvider::SERVICE_ID)->provide() : $uri; |
324 | $returnValue = $this->getModel()->getClass($uri); |
325 | $properties = [ |
326 | OntologyRdfs::RDFS_SUBCLASSOF => $resource, |
327 | ]; |
328 | if (!empty($label)) { |
329 | $properties[OntologyRdfs::RDFS_LABEL] = $label; |
330 | } |
331 | if (!empty($comment)) { |
332 | $properties[OntologyRdfs::RDFS_COMMENT] = $comment; |
333 | } |
334 | |
335 | $returnValue->setPropertiesValues($properties); |
336 | return $returnValue; |
337 | } |
338 | |
339 | /** |
340 | * (non-PHPdoc) |
341 | * @see core_kernel_persistence_ClassInterface::createProperty() |
342 | */ |
343 | public function createProperty( |
344 | core_kernel_classes_Class $resource, |
345 | $label = '', |
346 | $comment = '', |
347 | $isLgDependent = false |
348 | ) { |
349 | $returnValue = null; |
350 | |
351 | |
352 | $property = $this->getModel()->getClass(OntologyRdf::RDF_PROPERTY); |
353 | $propertyInstance = $property->createInstance($label, $comment); |
354 | $returnValue = $this->getModel()->getProperty($propertyInstance->getUri()); |
355 | $returnValue->setLgDependent($isLgDependent); |
356 | |
357 | if (!$returnValue->setDomain($resource)) { |
358 | throw new common_Exception('problem creating property'); |
359 | } |
360 | |
361 | $this->getEventManager()->trigger( |
362 | new ClassPropertyCreatedEvent( |
363 | $resource, |
364 | [ |
365 | 'propertyUri' => $propertyInstance->getUri(), |
366 | 'propertyLabel' => $propertyInstance->getLabel() |
367 | ] |
368 | ) |
369 | ); |
370 | |
371 | return $returnValue; |
372 | } |
373 | |
374 | /** |
375 | * (non-PHPdoc) |
376 | * prefer use |
377 | * @deprecated since 3.0 |
378 | * @see core_kernel_persistence_ClassInterface::searchInstances() |
379 | */ |
380 | public function searchInstances(core_kernel_classes_Class $resource, $propertyFilters = [], $options = []) |
381 | { |
382 | $returnValue = []; |
383 | |
384 | // Avoid a 'like' search on OntologyRdf::RDF_TYPE! |
385 | if (count($propertyFilters) === 0) { |
386 | $options = array_merge($options, ['like' => false]); |
387 | } |
388 | |
389 | $query = $this->getFilteredQuery($resource, $propertyFilters, $options); |
390 | $result = $this->getPersistence()->query($query); |
391 | |
392 | while ($row = $result->fetch()) { |
393 | $foundInstancesUri = $row['subject']; |
394 | $returnValue[$foundInstancesUri] = $this->getModel()->getResource($foundInstancesUri); |
395 | } |
396 | |
397 | return $returnValue; |
398 | } |
399 | |
400 | /** |
401 | * (non-PHPdoc) |
402 | * @see core_kernel_persistence_ClassInterface::countInstances() |
403 | */ |
404 | public function countInstances(core_kernel_classes_Class $resource, $propertyFilters = [], $options = []) |
405 | { |
406 | if (isset($options['offset'])) { |
407 | unset($options['offset']); |
408 | } |
409 | |
410 | if (isset($options['limit'])) { |
411 | unset($options['limit']); |
412 | } |
413 | |
414 | if (isset($options['order'])) { |
415 | unset($options['order']); |
416 | } |
417 | |
418 | $query = 'SELECT count(subject) FROM (' . $this->getFilteredQuery($resource, $propertyFilters, $options) |
419 | . ') as countq'; |
420 | return (int)$this->getPersistence()->query($query)->fetchColumn(); |
421 | } |
422 | |
423 | /** |
424 | * (non-PHPdoc) |
425 | * @see core_kernel_persistence_ClassInterface::getInstancesPropertyValues() |
426 | */ |
427 | public function getInstancesPropertyValues( |
428 | core_kernel_classes_Class $resource, |
429 | core_kernel_classes_Property $property, |
430 | $propertyFilters = [], |
431 | $options = [] |
432 | ) { |
433 | $returnValue = []; |
434 | |
435 | $distinct = isset($options['distinct']) ? $options['distinct'] : false; |
436 | |
437 | if (count($propertyFilters) === 0) { |
438 | $options = array_merge($options, ['like' => false]); |
439 | } |
440 | |
441 | $filteredQuery = $this->getFilteredQuery($resource, $propertyFilters, $options); |
442 | |
443 | // Get all the available property values in the subset of instances |
444 | $query = 'SELECT'; |
445 | if ($distinct) { |
446 | $query .= ' DISTINCT'; |
447 | } |
448 | |
449 | $query .= " object FROM (SELECT overq.subject, valuesq.object FROM (${filteredQuery}) as overq JOIN statements " |
450 | . "AS valuesq ON (overq.subject = valuesq.subject AND valuesq.predicate = ?)) AS overrootq"; |
451 | |
452 | $sqlResult = $this->getPersistence()->query($query, [$property->getUri()]); |
453 | while ($row = $sqlResult->fetch()) { |
454 | $returnValue[] = common_Utils::toResource($row['object']); |
455 | } |
456 | |
457 | return (array) $returnValue; |
458 | } |
459 | |
460 | /** |
461 | * Remove a Property from its Class definition. |
462 | * |
463 | * @param core_kernel_classes_Class $resource |
464 | * @param core_kernel_classes_Property $property |
465 | * @deprecated |
466 | * @throws common_exception_DeprecatedApiMethod |
467 | */ |
468 | public function unsetProperty(core_kernel_classes_Class $resource, core_kernel_classes_Property $property) |
469 | { |
470 | throw new common_exception_DeprecatedApiMethod(__METHOD__ . ' is deprecated. '); |
471 | } |
472 | |
473 | /** |
474 | * (non-PHPdoc) |
475 | * @see core_kernel_persistence_ClassInterface::createInstanceWithProperties() |
476 | */ |
477 | public function createInstanceWithProperties(core_kernel_classes_Class $type, $properties) |
478 | { |
479 | $returnValue = null; |
480 | |
481 | if (isset($properties[OntologyRdf::RDF_TYPE])) { |
482 | throw new core_kernel_persistence_Exception( |
483 | 'Additional types in createInstanceWithProperties not permited' |
484 | ); |
485 | } |
486 | |
487 | $properties[OntologyRdf::RDF_TYPE] = $type; |
488 | $returnValue = $this->getModel()->getResource( |
489 | $this->getServiceLocator()->get(UriProvider::SERVICE_ID)->provide() |
490 | ); |
491 | $returnValue->setPropertiesValues($properties); |
492 | |
493 | return $returnValue; |
494 | } |
495 | |
496 | /** |
497 | * (non-PHPdoc) |
498 | * @see core_kernel_persistence_ClassInterface::deleteInstances() |
499 | */ |
500 | public function deleteInstances(core_kernel_classes_Class $resource, $resources, $deleteReference = false) |
501 | { |
502 | $returnValue = false; |
503 | |
504 | $class = $this->getModel()->getClass($resource->getUri()); |
505 | $uris = []; |
506 | |
507 | foreach ($resources as $r) { |
508 | $uri = (($r instanceof core_kernel_classes_Resource) ? $r->getUri() : $r); |
509 | $uris[] = $this->getPersistence()->quote($uri); |
510 | } |
511 | |
512 | if ($class->exists()) { |
513 | $inValues = implode(',', $uris); |
514 | $query = 'DELETE FROM statements WHERE subject IN (' . $inValues . ')'; |
515 | |
516 | if (true === $deleteReference) { |
517 | $params[] = $resource->getUri(); |
518 | $query .= ' OR object IN (' . $inValues . ')'; |
519 | } |
520 | |
521 | try { |
522 | // Even if now rows are affected, we consider the resources |
523 | // as deleted. |
524 | $this->getPersistence()->exec($query); |
525 | $returnValue = true; |
526 | } catch (DBALException $e) { |
527 | throw new core_kernel_persistence_smoothsql_Exception( |
528 | "An error occured while deleting resources: " . $e->getMessage() |
529 | ); |
530 | } |
531 | } |
532 | |
533 | return $returnValue; |
534 | } |
535 | |
536 | /** |
537 | * |
538 | * @param core_kernel_classes_Class $resource |
539 | * @param array $propertyFilters |
540 | * @param array $options |
541 | * @return string |
542 | */ |
543 | public function getFilteredQuery(core_kernel_classes_Class $resource, $propertyFilters = [], $options = []) |
544 | { |
545 | $rdftypes = []; |
546 | |
547 | // Check recursivity... |
548 | if (isset($options['recursive']) && $options['recursive']) { |
549 | foreach ($this->getSubClasses($resource, $options['recursive']) as $subClass) { |
550 | $rdftypes[] = $subClass->getUri(); |
551 | } |
552 | } |
553 | |
554 | // Check additional classes... |
555 | if (isset($options['additionalClasses'])) { |
556 | foreach ($options['additionalClasses'] as $aC) { |
557 | $rdftypes[] = ($aC instanceof core_kernel_classes_Resource) ? $aC->getUri() : $aC; |
558 | $rdftypes = array_unique($rdftypes); |
559 | } |
560 | } |
561 | |
562 | // Add the class type of the given class |
563 | if (!in_array($resource->getUri(), $rdftypes)) { |
564 | $rdftypes[] = $resource->getUri(); |
565 | } |
566 | |
567 | $and = (isset($options['chaining']) === false) |
568 | ? true |
569 | : ((strtolower($options['chaining']) === 'and') ? true : false); |
570 | $like = (isset($options['like']) === false) ? true : $options['like']; |
571 | $lang = (isset($options['lang']) === false) ? '' : $options['lang']; |
572 | $offset = (isset($options['offset']) === false) ? 0 : $options['offset']; |
573 | $limit = (isset($options['limit']) === false) ? 0 : $options['limit']; |
574 | $order = (isset($options['order']) === false) ? '' : $options['order']; |
575 | $orderdir = (isset($options['orderdir']) === false) ? 'ASC' : $options['orderdir']; |
576 | $onlyClass = (isset($options['onlyClass']) === false) ? false : $options['onlyClass']; |
577 | |
578 | if ($this->getServiceLocator()->has(ComplexSearchService::SERVICE_ID)) { |
579 | $search = $this->getModel()->getSearchInterface(); |
580 | $query = $search->getQuery( |
581 | $this->getModel(), |
582 | $rdftypes, |
583 | $propertyFilters, |
584 | $and, |
585 | $like, |
586 | $lang, |
587 | $offset, |
588 | $limit, |
589 | $order, |
590 | $orderdir, |
591 | $onlyClass |
592 | ); |
593 | } else { |
594 | $query = core_kernel_persistence_smoothsql_Utils::buildFilterQuery( |
595 | $this->getModel(), |
596 | $rdftypes, |
597 | $propertyFilters, |
598 | $and, |
599 | $like, |
600 | $lang, |
601 | $offset, |
602 | $limit, |
603 | $order, |
604 | $orderdir |
605 | ); |
606 | } |
607 | |
608 | return $query; |
609 | } |
610 | |
611 | public function updateUri(core_kernel_classes_Class $resource, string $newUri): void |
612 | { |
613 | $query = $this->getPersistence()->getPlatForm()->getQueryBuilder(); |
614 | |
615 | $expressionBuilder = $query->expr(); |
616 | |
617 | $query |
618 | ->update('statements') |
619 | ->set('subject', ':uri') |
620 | ->where($expressionBuilder->eq('subject', ':original_uri')); |
621 | |
622 | $this->getPersistence()->exec( |
623 | $query, |
624 | [ |
625 | 'uri' => $newUri, |
626 | 'original_uri' => $resource->getUri(), |
627 | ] |
628 | ); |
629 | |
630 | $query |
631 | ->update('statements') |
632 | ->set('object', ':uri') |
633 | ->where($expressionBuilder->eq('object', ':original_uri')); |
634 | |
635 | $this->getPersistence()->exec( |
636 | $query, |
637 | [ |
638 | 'uri' => $newUri, |
639 | 'original_uri' => $resource->getUri(), |
640 | ] |
641 | ); |
642 | } |
643 | |
644 | public function getInstanceUris(string $classUri, bool $recursive = false): array |
645 | { |
646 | if (!$recursive) { |
647 | $query = 'SELECT subject FROM statements WHERE predicate = ? AND object = ?'; |
648 | $params = [ |
649 | OntologyRdf::RDF_TYPE, |
650 | $classUri, |
651 | ]; |
652 | } else { |
653 | $query = <<<'SQL' |
654 | WITH RECURSIVE statements_tree AS ( |
655 | SELECT |
656 | r.subject, |
657 | r.predicate |
658 | FROM statements r |
659 | WHERE r.subject = ? |
660 | AND r.predicate IN (?, ?) |
661 | UNION ALL |
662 | SELECT |
663 | s.subject, |
664 | s.predicate |
665 | FROM statements s |
666 | JOIN statements_tree st |
667 | ON s.object = st.subject |
668 | WHERE s.predicate IN (?, ?) |
669 | ) |
670 | SELECT subject FROM statements_tree WHERE predicate = ?; |
671 | SQL; |
672 | $params = [ |
673 | $classUri, |
674 | OntologyRdfs::RDFS_SUBCLASSOF, |
675 | OntologyRdf::RDF_TYPE, |
676 | OntologyRdfs::RDFS_SUBCLASSOF, |
677 | OntologyRdf::RDF_TYPE, |
678 | OntologyRdf::RDF_TYPE, |
679 | ]; |
680 | } |
681 | |
682 | $statement = $this->getPersistence()->query($query, $params); |
683 | |
684 | return array_column($statement->fetchAll(), 'subject'); |
685 | } |
686 | } |