server/src/app/Services/LexvoResolver.php
changeset 28 b0b56e0f8c7f
child 133 821253d361d1
--- /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;
+
+    }
+
+}