Total Complexity | 118 |
Total Lines | 643 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like Model often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Model, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
14 | class Model |
||
15 | { |
||
16 | /** cache for Vocabulary objects */ |
||
17 | private $allVocabularies = null; |
||
18 | /** cache for Vocabulary objects */ |
||
19 | private $vocabsByGraph = null; |
||
20 | /** cache for Vocabulary objects */ |
||
21 | private $vocabsByUriSpace = null; |
||
22 | /** how long to store retrieved URI information in APC cache */ |
||
23 | public const URI_FETCH_TTL = 86400; // 1 day |
||
24 | private $globalConfig; |
||
25 | private $logger; |
||
26 | private $resolver; |
||
27 | private $translator; |
||
28 | |||
29 | /** |
||
30 | * Initializes the Model object |
||
31 | */ |
||
32 | public function __construct(string $config_filename = "../../config.ttl") |
||
33 | { |
||
34 | $this->resolver = new Resolver($this); |
||
35 | $this->globalConfig = new GlobalConfig($this, $config_filename); |
||
36 | $this->translator = null; |
||
37 | foreach ($this->globalConfig->getLanguages() as $langcode => $locale) { |
||
38 | if (is_null($this->translator)) { |
||
39 | // use the first configured language as default language |
||
40 | $this->translator = new Translator($langcode); |
||
41 | } |
||
42 | $this->translator->addLoader('json', new JsonFileLoader()); |
||
43 | $this->translator->addResource('json', __DIR__.'/../../resource/translations/messages.' . $langcode . '.json', $langcode); |
||
44 | } |
||
45 | $this->initializeLogging(); |
||
46 | } |
||
47 | |||
48 | /** |
||
49 | * Returns the GlobalConfig object given to the Model as a constructor parameter. |
||
50 | * @return GlobalConfig |
||
51 | */ |
||
52 | public function getConfig() |
||
53 | { |
||
54 | return $this->globalConfig; |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * Configures the logging facility |
||
59 | */ |
||
60 | private function initializeLogging() |
||
61 | { |
||
62 | $this->logger = new \Monolog\Logger('general'); |
||
63 | $formatter = new \Monolog\Formatter\LineFormatter("[%datetime%] %level_name% %message%\n"); |
||
64 | $formatter->allowInlineLineBreaks(true); |
||
65 | if ($this->getConfig()->getLoggingBrowserConsole()) { |
||
66 | $browserHandler = new \Monolog\Handler\BrowserConsoleHandler(\Monolog\Logger::INFO); |
||
|
|||
67 | $browserHandler->setFormatter($formatter); |
||
68 | $this->logger->pushHandler($browserHandler); |
||
69 | } |
||
70 | if ($this->getConfig()->getLoggingFilename() !== null) { |
||
71 | $streamHandler = new \Monolog\Handler\StreamHandler($this->getConfig()->getLoggingFilename(), \Monolog\Logger::INFO); |
||
72 | $streamHandler->setFormatter($formatter); |
||
73 | $this->logger->pushHandler($streamHandler); |
||
74 | } |
||
75 | if (!$this->logger->getHandlers()) { |
||
76 | // add a NullHandler to suppress the default Monolog logging to stderr |
||
77 | $nullHandler = new \Monolog\Handler\NullHandler(); |
||
78 | $this->logger->pushHandler($nullHandler); |
||
79 | } |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * Return the logging facility |
||
84 | * @return object logger |
||
85 | */ |
||
86 | public function getLogger() |
||
87 | { |
||
88 | return $this->logger; |
||
89 | } |
||
90 | |||
91 | /** |
||
92 | * Return the version of this Skosmos installation, or "unknown" if |
||
93 | * it cannot be determined. The version information is based on Git tags. |
||
94 | * @return string version |
||
95 | */ |
||
96 | public function getVersion(): string |
||
97 | { |
||
98 | $ver = \Composer\InstalledVersions::getRootPackage()['pretty_version']; |
||
99 | if ($ver === null) { |
||
100 | return "unknown"; |
||
101 | } |
||
102 | |||
103 | return $ver; |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * Return all the vocabularies available. |
||
108 | * @param boolean $categories whether you want everything included in a subarray of |
||
109 | * a category. |
||
110 | * @param boolean $shortname set to true if you want the vocabularies sorted by |
||
111 | * their shortnames instead of their titles. |
||
112 | */ |
||
113 | public function getVocabularyList($categories = true, $shortname = false) |
||
114 | { |
||
115 | $cats = $this->getVocabularyCategories(); |
||
116 | $ret = array(); |
||
117 | foreach ($cats as $cat) { |
||
118 | $catlabel = $cat->getTitle(); |
||
119 | |||
120 | // find all the vocabs in this category |
||
121 | $vocs = array(); |
||
122 | foreach ($cat->getVocabularies() as $voc) { |
||
123 | $vocs[$shortname ? $voc->getConfig()->getShortname() : $voc->getConfig()->getTitle()] = $voc; |
||
124 | } |
||
125 | uksort($vocs, 'strcoll'); |
||
126 | |||
127 | if (sizeof($vocs) > 0 && $categories) { |
||
128 | $ret[$catlabel] = $vocs; |
||
129 | } elseif (sizeof($vocs) > 0) { |
||
130 | $ret = array_merge($ret, $vocs); |
||
131 | } |
||
132 | |||
133 | } |
||
134 | |||
135 | if (!$categories) { |
||
136 | uksort($ret, 'strcoll'); |
||
137 | } |
||
138 | |||
139 | return $ret; |
||
140 | } |
||
141 | |||
142 | /** |
||
143 | * Return all types (RDFS/OWL classes) present in the specified vocabulary or all vocabularies. |
||
144 | * @return array Array with URIs (string) as key and array of (label, superclassURI) as value |
||
145 | */ |
||
146 | public function getTypes($vocid = null, $lang = null) |
||
147 | { |
||
148 | $sparql = (isset($vocid)) ? $this->getVocabulary($vocid)->getSparql() : $this->getDefaultSparql(); |
||
149 | $result = $sparql->queryTypes($lang); |
||
150 | foreach ($result as $uri => $values) { |
||
151 | if (empty($values)) { |
||
152 | $shorteneduri = EasyRdf\RdfNamespace::shorten($uri); |
||
153 | if ($shorteneduri !== null) { |
||
154 | if (isset($lang)) { |
||
155 | $this->translator->setlocale($lang); |
||
156 | } |
||
157 | $trans = $this->getText($shorteneduri); |
||
158 | if ($trans) { |
||
159 | $result[$uri] = array('label' => $trans); |
||
160 | } |
||
161 | } |
||
162 | } |
||
163 | } |
||
164 | |||
165 | return $result; |
||
166 | } |
||
167 | |||
168 | /** |
||
169 | * Return the languages present in the configured vocabularies. |
||
170 | * @return array Array with lang codes (string) |
||
171 | */ |
||
172 | public function getLanguages($lang) |
||
173 | { |
||
174 | $vocabs = $this->getVocabularyList(false); |
||
175 | $ret = array(); |
||
176 | foreach ($vocabs as $vocab) { |
||
177 | foreach ($vocab->getConfig()->getLanguages() as $langcode) { |
||
178 | $langlit = Punic\Language::getName($langcode, $lang); |
||
179 | $ret[$langlit] = $langcode; |
||
180 | } |
||
181 | } |
||
182 | ksort($ret); |
||
183 | return array_unique($ret); |
||
184 | } |
||
185 | |||
186 | /** |
||
187 | * Return Symfony Translator object for translations in given language. |
||
188 | * @return Translator Translator object from Symfony package |
||
189 | */ |
||
190 | public function getTranslator() |
||
191 | { |
||
192 | return $this->translator; |
||
193 | } |
||
194 | |||
195 | /** |
||
196 | * Sets translation language for Symfony Translator objext |
||
197 | * @param string $lang two character language code 'fi' or compound language (locale) name such as 'fi_FI' |
||
198 | */ |
||
199 | public function setLocale($locale) |
||
200 | { |
||
201 | $this->translator->setlocale($locale); |
||
202 | } |
||
203 | |||
204 | /** |
||
205 | * Gets translation language from Symfony Translator objext |
||
206 | * @return string $lang two character language code 'fi' or compound language (locale) name such as 'fi_FI' |
||
207 | */ |
||
208 | public function getLocale() |
||
209 | { |
||
210 | return $this->translator->getlocale(); |
||
211 | } |
||
212 | |||
213 | /** |
||
214 | * Get text translated in language set by SetLocale function |
||
215 | * |
||
216 | * @param string $text text to be translated |
||
217 | */ |
||
218 | public function getText($text) |
||
219 | { |
||
220 | return $this->translator->trans($text); |
||
221 | } |
||
222 | |||
223 | /** |
||
224 | * returns a concept's RDF data in downloadable format |
||
225 | * @param string $vocid vocabulary id, or null for global data (from all vocabularies) |
||
226 | * @param string $uri concept URI |
||
227 | * @param string $format the format in which you want to get the result, currently this function supports |
||
228 | * text/turtle, application/rdf+xml and application/json |
||
229 | * @return string RDF data in the requested serialization |
||
230 | */ |
||
231 | public function getRDF($vocid, $uri, $format) |
||
232 | { |
||
233 | |||
234 | if ($format == 'text/turtle') { |
||
235 | $retform = 'turtle'; |
||
236 | $serialiser = new EasyRdf\Serialiser\Turtle(); |
||
237 | } elseif ($format == 'application/ld+json' || $format == 'application/json') { |
||
238 | $retform = 'jsonld'; // serve JSON-LD for both JSON-LD and plain JSON requests |
||
239 | $serialiser = new EasyRdf\Serialiser\JsonLd(); |
||
240 | } else { |
||
241 | $retform = 'rdfxml'; |
||
242 | $serialiser = new EasyRdf\Serialiser\RdfXml(); |
||
243 | } |
||
244 | |||
245 | if ($vocid !== null) { |
||
246 | $vocab = $this->getVocabulary($vocid); |
||
247 | $sparql = $vocab->getSparql(); |
||
248 | $arrayClass = $vocab->getConfig()->getArrayClassURI(); |
||
249 | $vocabs = array($vocab); |
||
250 | } else { |
||
251 | $sparql = $this->getDefaultSparql(); |
||
252 | $arrayClass = null; |
||
253 | $vocabs = null; |
||
254 | } |
||
255 | $result = $sparql->queryConceptInfoGraph($uri, $arrayClass, $vocabs); |
||
256 | |||
257 | if (!$result->isEmpty()) { |
||
258 | return $serialiser->serialise($result, $retform); |
||
259 | } |
||
260 | return ""; |
||
261 | } |
||
262 | |||
263 | /** |
||
264 | * Makes a SPARQL-query to the endpoint that retrieves concept |
||
265 | * references as it's search results. |
||
266 | * @param ConceptSearchParameters $params an object that contains all the parameters needed for the search |
||
267 | * @return array search results |
||
268 | */ |
||
269 | public function searchConcepts($params) |
||
270 | { |
||
271 | // don't even try to search for empty prefix if no other search criteria (group or parent concept) has been set |
||
272 | if (($params->getSearchTerm() === "" || !preg_match('/[^*]/', $params->getSearchTerm())) && !$params->getGroupLimit() && !$params->getParentLimit()) { |
||
273 | return array(); |
||
274 | } |
||
275 | |||
276 | $vocabs = $params->getVocabs(); |
||
277 | $showDeprecated = false; |
||
278 | if (sizeof($vocabs) === 1) { // search within vocabulary |
||
279 | $voc = $vocabs[0]; |
||
280 | $sparql = $voc->getSparql(); |
||
281 | $showDeprecated = $voc->getConfig()->getShowDeprecated(); |
||
282 | } else { // multi-vocabulary or global search |
||
283 | $voc = null; |
||
284 | $sparql = $this->getDefaultSparql(); |
||
285 | // @TODO : in a global search showDeprecated will always be false and cannot be set globally |
||
286 | } |
||
287 | |||
288 | $results = $sparql->queryConcepts($vocabs, $params->getAdditionalFields(), $params->getUnique(), $params, $showDeprecated); |
||
289 | if ($params->getRest() && $results && $params->getSearchLimit() !== 0) { |
||
290 | $results = array_slice($results, $params->getOffset(), $params->getSearchLimit()); |
||
291 | } |
||
292 | $ret = array(); |
||
293 | |||
294 | foreach ($results as $hit) { |
||
295 | if (sizeof($vocabs) == 1) { |
||
296 | $hitvoc = $voc; |
||
297 | $hit['vocab'] = $vocabs[0]->getId(); |
||
298 | } else { |
||
299 | try { |
||
300 | $hitvoc = $this->getVocabularyByGraph($hit['graph']); |
||
301 | $hit['vocab'] = $hitvoc->getId(); |
||
302 | } catch (ValueError $e) { |
||
303 | trigger_error($e->getMessage(), E_USER_WARNING); |
||
304 | $hitvoc = null; |
||
305 | $hit['vocab'] = "???"; |
||
306 | } |
||
307 | } |
||
308 | unset($hit['graph']); |
||
309 | |||
310 | $hit['voc'] = $hitvoc; |
||
311 | |||
312 | if ($hitvoc === null || !$hitvoc->containsURI($hit['uri'])) { |
||
313 | // if uri is a external vocab uri that is included in the current vocab |
||
314 | $realvoc = $this->guessVocabularyFromURI($hit['uri'], $voc !== null ? $voc->getId() : null); |
||
315 | if ($realvoc !== $hitvoc) { |
||
316 | unset($hit['localname']); |
||
317 | $hit['exvocab'] = ($realvoc !== null) ? $realvoc->getId() : "???"; |
||
318 | } |
||
319 | } |
||
320 | |||
321 | $ret[] = $hit; |
||
322 | } |
||
323 | |||
324 | return $ret; |
||
325 | } |
||
326 | |||
327 | /** |
||
328 | * Function for performing a search for concepts and their data fields. |
||
329 | * @param ConceptSearchParameters $params an object that contains all the parameters needed for the search |
||
330 | * @return array array with keys 'count' and 'results' |
||
331 | */ |
||
332 | public function searchConceptsAndInfo($params) |
||
333 | { |
||
334 | $params->setUnique(true); |
||
335 | $allhits = $this->searchConcepts($params); |
||
336 | $count = sizeof($allhits); |
||
337 | $hits = array_slice($allhits, intval($params->getOffset()), $params->getSearchLimit()); |
||
338 | |||
339 | $ret = array(); |
||
340 | $uris = array(); |
||
341 | $vocabs = array(); |
||
342 | $uniqueVocabs = array(); |
||
343 | foreach ($hits as $hit) { |
||
344 | $uniqueVocabs[$hit['voc']->getId()] = $hit['voc']->getId(); |
||
345 | $vocabs[] = $hit['voc']; |
||
346 | $uris[] = $hit['uri']; |
||
347 | } |
||
348 | if (sizeof($uniqueVocabs) == 1) { |
||
349 | $voc = $vocabs[0]; |
||
350 | $sparql = $voc->getSparql(); |
||
351 | $arrayClass = $voc->getConfig()->getArrayClassURI(); |
||
352 | } else { |
||
353 | $arrayClass = null; |
||
354 | $sparql = $this->getDefaultSparql(); |
||
355 | } |
||
356 | if (sizeof($uris) > 0) { |
||
357 | $ret = $sparql->queryConceptInfo($uris, $arrayClass, $vocabs, $params->getSearchLang()); |
||
358 | } |
||
359 | |||
360 | // For marking that the concept has been found through an alternative label, hidden |
||
361 | // label or a label in another language |
||
362 | foreach ($hits as $idx => $hit) { |
||
363 | if (isset($hit['altLabel']) && isset($ret[$idx])) { |
||
364 | $ret[$idx]->setFoundBy($hit['altLabel'], 'alt'); |
||
365 | } |
||
366 | |||
367 | if (isset($hit['hiddenLabel']) && isset($ret[$idx])) { |
||
368 | $ret[$idx]->setFoundBy($hit['hiddenLabel'], 'hidden'); |
||
369 | } |
||
370 | |||
371 | if (isset($hit['matchedPrefLabel'])) { |
||
372 | $ret[$idx]->setFoundBy($hit['matchedPrefLabel'], 'lang'); |
||
373 | } |
||
374 | |||
375 | if ($ret[$idx] && isset($hit['lang'])) { |
||
376 | $ret[$idx]->setContentLang($hit['lang']); |
||
377 | } |
||
378 | } |
||
379 | |||
380 | return array('count' => $count, 'results' => $ret); |
||
381 | } |
||
382 | |||
383 | /** |
||
384 | * Creates dataobjects from an input array. |
||
385 | * @param string $class the type of class eg. 'Vocabulary'. |
||
386 | * @param array $resarr contains the EasyRdf\Resources. |
||
387 | */ |
||
388 | private function createDataObjects($class, $resarr) |
||
389 | { |
||
390 | $ret = array(); |
||
391 | foreach ($resarr as $res) { |
||
392 | $ret[] = new $class($this, $res); |
||
393 | } |
||
394 | |||
395 | return $ret; |
||
396 | } |
||
397 | |||
398 | /** |
||
399 | * Returns the cached vocabularies. |
||
400 | * @return array of Vocabulary dataobjects |
||
401 | */ |
||
402 | public function getVocabularies() |
||
403 | { |
||
404 | if ($this->allVocabularies === null) { // initialize cache |
||
405 | $vocs = $this->globalConfig->getGraph()->allOfType('skosmos:Vocabulary'); |
||
406 | $this->allVocabularies = $this->createDataObjects("Vocabulary", $vocs); |
||
407 | foreach ($this->allVocabularies as $voc) { |
||
408 | // register vocabulary ids as RDF namespace prefixes |
||
409 | $prefix = preg_replace('/\W+/', '', $voc->getId()); // strip non-word characters |
||
410 | try { |
||
411 | if ($prefix != '' && EasyRdf\RdfNamespace::get($prefix) === null) { // if not already defined |
||
412 | EasyRdf\RdfNamespace::set($prefix, $voc->getUriSpace()); |
||
413 | } |
||
414 | |||
415 | } catch (Exception $e) { |
||
416 | // not valid as namespace identifier, ignore |
||
417 | } |
||
418 | } |
||
419 | } |
||
420 | |||
421 | return $this->allVocabularies; |
||
422 | } |
||
423 | |||
424 | /** |
||
425 | * Returns the cached vocabularies from a category. |
||
426 | * @param EasyRdf\Resource $cat the category in question |
||
427 | * @return array of vocabulary dataobjects |
||
428 | */ |
||
429 | public function getVocabulariesInCategory($cat) |
||
430 | { |
||
431 | $vocs = $this->globalConfig->getGraph()->resourcesMatching('dc:subject', $cat); |
||
432 | return $this->createDataObjects("Vocabulary", $vocs); |
||
433 | } |
||
434 | |||
435 | /** |
||
436 | * Creates dataobjects of all the different vocabulary categories (Health etc.). |
||
437 | * @return array of Dataobjects of the type VocabularyCategory. |
||
438 | */ |
||
439 | public function getVocabularyCategories() |
||
440 | { |
||
441 | $cats = $this->globalConfig->getGraph()->allOfType('skos:Concept'); |
||
442 | if (empty($cats)) { |
||
443 | return array(new VocabularyCategory($this, null)); |
||
444 | } |
||
445 | |||
446 | return $this->createDataObjects("VocabularyCategory", $cats); |
||
447 | } |
||
448 | |||
449 | /** |
||
450 | * Returns the label defined in config.ttl with the appropriate language. |
||
451 | * @param string $lang language code of returned labels, eg. 'fi' |
||
452 | * @return string the label for vocabulary categories. |
||
453 | */ |
||
454 | public function getClassificationLabel($lang) |
||
455 | { |
||
456 | $cats = $this->globalConfig->getGraph()->allOfType('skos:ConceptScheme'); |
||
457 | return $cats ? $cats[0]->label($lang) : null; |
||
458 | } |
||
459 | |||
460 | /** |
||
461 | * Returns a single cached vocabulary. |
||
462 | * @param string $vocid the vocabulary id eg. 'mesh'. |
||
463 | * @return Vocabulary dataobject |
||
464 | */ |
||
465 | public function getVocabulary($vocid): Vocabulary |
||
466 | { |
||
467 | $vocs = $this->getVocabularies(); |
||
468 | foreach ($vocs as $voc) { |
||
469 | if ($voc->getId() == $vocid) { |
||
470 | return $voc; |
||
471 | } |
||
472 | } |
||
473 | throw new ValueError("Vocabulary id '$vocid' not found in configuration."); |
||
474 | } |
||
475 | |||
476 | /** |
||
477 | * Return the vocabulary that is stored in the given graph on the given endpoint. |
||
478 | * |
||
479 | * @param $graph string graph URI |
||
480 | * @param $endpoint string endpoint URL (default SPARQL endpoint if omitted) |
||
481 | * @return Vocabulary vocabulary of this URI, or null if not found |
||
482 | */ |
||
483 | public function getVocabularyByGraph($graph, $endpoint = null) |
||
501 | } |
||
502 | |||
503 | } |
||
504 | |||
505 | /** |
||
506 | * When multiple vocabularies share same URI namespace, return the |
||
507 | * vocabulary in which the URI is actually defined (has a label). |
||
508 | * |
||
509 | * @param Vocabulary[] $vocabs vocabularies to search |
||
510 | * @param string $uri URI to look for |
||
511 | * @param $preferredVocabId string ID of the preferred vocabulary to return if more than one is found |
||
512 | * @return Vocabulary the vocabulary with the URI |
||
513 | */ |
||
514 | |||
515 | private function disambiguateVocabulary($vocabs, $uri, $preferredVocabId = null) |
||
516 | { |
||
517 | // if there is only one candidate vocabulary, return it |
||
518 | if (sizeof($vocabs) == 1) { |
||
519 | return $vocabs[0]; |
||
520 | } |
||
521 | |||
522 | // if there are multiple vocabularies and one is the preferred vocabulary, return it |
||
523 | if ($preferredVocabId != null) { |
||
524 | foreach ($vocabs as $vocab) { |
||
525 | if ($vocab->getId() == $preferredVocabId) { |
||
526 | try { |
||
527 | // double check that a label exists in the preferred vocabulary |
||
528 | if ($vocab->getConceptLabel($uri, null) !== null) { |
||
529 | return $vocab; |
||
530 | } else { |
||
531 | // not found in preferred vocabulary, fall back to next method |
||
532 | break; |
||
533 | } |
||
534 | } catch (EasyRdf\Http\Exception | EasyRdf\Exception | Throwable $e) { |
||
535 | if ($this->getConfig()->getLogCaughtExceptions()) { |
||
536 | error_log('Caught exception: ' . $e->getMessage()); |
||
537 | } |
||
538 | break; |
||
539 | } |
||
540 | } |
||
541 | } |
||
542 | } |
||
543 | |||
544 | // no preferred vocabulary, or it was not found, search in which vocabulary the concept has a label |
||
545 | foreach ($vocabs as $vocab) { |
||
546 | try { |
||
547 | if ($vocab->getConceptLabel($uri, null) !== null) { |
||
548 | return $vocab; |
||
549 | } |
||
550 | } catch (EasyRdf\Http\Exception | EasyRdf\Exception | Throwable $e) { |
||
551 | if ($this->getConfig()->getLogCaughtExceptions()) { |
||
552 | error_log('Caught exception: ' . $e->getMessage()); |
||
553 | } |
||
554 | break; |
||
555 | } |
||
556 | } |
||
557 | |||
558 | // if the URI couldn't be found, fall back to the first vocabulary |
||
559 | return $vocabs[0]; |
||
560 | } |
||
561 | |||
562 | /** |
||
563 | * Guess which vocabulary a URI originates from, based on the declared |
||
564 | * vocabulary URI spaces. |
||
565 | * |
||
566 | * @param $uri string URI to search |
||
567 | * @param $preferredVocabId string ID of the preferred vocabulary to return if more than one is found |
||
568 | * @return Vocabulary vocabulary of this URI, or null if not found |
||
569 | */ |
||
570 | public function guessVocabularyFromURI($uri, $preferredVocabId = null) |
||
571 | { |
||
572 | if ($this->vocabsByUriSpace === null) { // initialize cache |
||
573 | $this->vocabsByUriSpace = array(); |
||
574 | foreach ($this->getVocabularies() as $voc) { |
||
575 | $uriSpace = $voc->getUriSpace(); |
||
576 | if ($uriSpace) { |
||
577 | $this->vocabsByUriSpace[$uriSpace][] = $voc; |
||
578 | } |
||
579 | } |
||
580 | } |
||
581 | |||
582 | // try to guess the URI space and look it up in the cache |
||
583 | $res = new EasyRdf\Resource($uri); |
||
584 | $namespace = substr(strval($uri), 0, -strlen(strval($res->localName()))); |
||
585 | if ($namespace && array_key_exists($namespace, $this->vocabsByUriSpace)) { |
||
586 | $vocabs = $this->vocabsByUriSpace[$namespace]; |
||
587 | return $this->disambiguateVocabulary($vocabs, $uri, $preferredVocabId); |
||
588 | } |
||
589 | |||
590 | // didn't work, try to match with each URI space separately |
||
591 | foreach ($this->vocabsByUriSpace as $urispace => $vocabs) { |
||
592 | if (strpos($uri, $urispace) === 0) { |
||
593 | return $this->disambiguateVocabulary($vocabs, $uri, $preferredVocabId); |
||
594 | } |
||
595 | } |
||
596 | |||
597 | // not found |
||
598 | return null; |
||
599 | } |
||
600 | |||
601 | /** |
||
602 | * Get the label for a resource, preferring 1. the given language 2. configured languages 3. any language. |
||
603 | * @param EasyRdf\Resource $res resource whose label to return |
||
604 | * @param string $lang preferred language |
||
605 | * @return EasyRdf\Literal label as an EasyRdf\Literal object, or null if not found |
||
606 | */ |
||
607 | public function getResourceLabel($res, $lang) |
||
608 | { |
||
609 | $langs = array_merge(array($lang), array_keys($this->getConfig()->getLanguages())); |
||
610 | foreach ($langs as $l) { |
||
611 | $label = $res->label($l); |
||
612 | if ($label !== null) { |
||
613 | return $label; |
||
614 | } |
||
615 | |||
616 | } |
||
617 | return $res->label(); // desperate check for label in any language; will return null if even this fails |
||
618 | } |
||
619 | |||
620 | public function getResourceFromUri($uri) |
||
621 | { |
||
622 | // using apc cache for the resource if available |
||
623 | if ($this->globalConfig->getCache()->isAvailable()) { |
||
624 | // @codeCoverageIgnoreStart |
||
625 | $key = 'fetch: ' . $uri; |
||
626 | $resource = $this->globalConfig->getCache()->fetch($key); |
||
627 | if ($resource === null || $resource === false) { // was not found in cache, or previous request failed |
||
628 | $resource = $this->resolver->resolve($uri, $this->getConfig()->getHttpTimeout()); |
||
629 | $this->globalConfig->getCache()->store($key, $resource, self::URI_FETCH_TTL); |
||
630 | } |
||
631 | // @codeCoverageIgnoreEnd |
||
632 | } else { // APC not available, parse on every request |
||
633 | $resource = $this->resolver->resolve($uri, $this->getConfig()->getHttpTimeout()); |
||
634 | } |
||
635 | return $resource; |
||
636 | } |
||
637 | |||
638 | /** |
||
639 | * Returns a SPARQL endpoint object. |
||
640 | * @param string $dialect eg. 'JenaText'. |
||
641 | * @param string $endpoint url address of endpoint |
||
642 | * @param string|null $graph uri for the target graph. |
||
643 | */ |
||
644 | public function getSparqlImplementation($dialect, $endpoint, $graph) |
||
645 | { |
||
646 | $classname = $dialect . "Sparql"; |
||
647 | |||
648 | return new $classname($endpoint, $graph, $this); |
||
649 | } |
||
650 | |||
651 | /** |
||
652 | * Returns a SPARQL endpoint object using the default implementation set in the config.ttl. |
||
653 | */ |
||
654 | public function getDefaultSparql() |
||
657 | } |
||
658 | |||
659 | } |
||
660 |
This class constant has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.