--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/app/Services/LexvoResolver.php Fri Jan 15 15:35:00 2016 +0100
@@ -0,0 +1,101 @@
+<?php
+namespace CorpusParole\Services;
+
+use Cache;
+use CorpusParole\Services\LexvoResolverInterface;
+
+class LexvoResolver implements LexvoResolverInterface {
+
+ public function __construct($sparqlClient) {
+ $this->sparqlClient = $sparqlClient;
+ }
+
+ private function checkLexvoId($id) {
+ $lexvoid = $id;
+ if(strpos($id, config('corpusparole.lexvo_base_url')) !== 0) {
+ $lexvoid = config('corpusparole.lexvo_base_url').$id;
+ }
+ $lexvoid = rtrim($lexvoid, '/');
+ if(preg_match("/^".preg_quote(config('corpusparole.lexvo_base_url'),"/")."[[:alpha:]]{3}$/", $lexvoid) !== 1) {
+ throw new LexvoResolverException("the provided id \"$id\" is not a Lexvo id");
+ }
+ return $lexvoid;
+ }
+ /**
+ * Get name from Viaf id
+ * @param string $id The id to resolve. Can be an url starting with http://viaf.org/viaf/
+ * @return a string with the name
+ */
+ public function getName($id) {
+ $res = $this->getNames([$id,]);
+ assert(array_key_exists($id,$res), "the result must contains $id");
+ return $res[$id];
+ }
+
+ /**
+ * Get a list of names from an array of viaf ids.
+ * @param array $ids The array of ids to resolve.
+ * Each id can be an url starting with http://viaf.org/viaf/
+ * @return array key is id, value is the name
+ */
+ public function getNames(array $ids) {
+
+ $lexvoids = array_map([$this, 'checkLexvoId'], $ids);
+ $lexvoidsMap = array_combine($lexvoids, $ids);
+
+ $results = [];
+ $missingLexvoids = [];
+
+ foreach ($lexvoidsMap as $lexvoid => $lexvoidSource) {
+ $cachedValue = Cache::get("lexvo:$lexvoid");
+ if(is_null($cachedValue)) {
+ array_push($missingLexvoids, $lexvoid);
+ } else {
+ $results[$lexvoidSource] = $cachedValue;
+ }
+ }
+
+ if(count($missingLexvoids) == 0) {
+ return $results;
+ }
+
+ $query = "SELECT ?s ?o WHERE {";
+ foreach ($missingLexvoids as $index => $lid) {
+ if($index > 0) {
+ $query .= " UNION ";
+ }
+ $query .= "{<$lid> rdfs:label ?o. ?s rdfs:label ?o FILTER(?s = <$lid> && (lang(?o) = \"fr\" || lang(?o) = \"en\"))}";
+ }
+ $query .= "}";
+
+
+ $docs = $this->sparqlClient->query($query);
+
+ $resultsRaw = [];
+
+ foreach ($docs as $doc) {
+ $lexvoid = $doc->s->getUri();
+ $lexvoname = $doc->o;
+
+ $lang = $lexvoname->getLang();
+ $value = $lexvoname->getValue();
+
+ if(!array_key_exists($lexvoid, $resultsRaw) ||
+ ($lang == "fr" && ($resultsRaw[$lexvoid]->getLang() == "en" || mb_strlen($resultsRaw[$lexvoid]->getValue()) > mb_strlen($value))) ||
+ ($lang == "en" && $resultsRaw[$lexvoid]->getLang() == "en" && mb_strlen($resultsRaw[$lexvoid]->getValue()) > mb_strlen($value)) ) {
+ $resultsRaw[$lexvoid] = $lexvoname;
+ }
+ }
+
+ foreach ($missingLexvoids as $lexvoid) {
+ $lexvoidSource = $lexvoidsMap[$lexvoid];
+ $missingValue = array_key_exists($lexvoid,$resultsRaw) && $resultsRaw[$lexvoid]?mb_strtolower($resultsRaw[$lexvoid]->getValue()):"";
+ Cache::put("lexvo:$lexvoid", $missingValue, config('corpusparole.lexvo_cache_expiration'));
+ $results[$lexvoidSource] = mb_strlen($missingValue)>0?$missingValue:null;
+ }
+
+ return $results;
+
+ }
+
+}