--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/app/Services/BnfResolver.php Thu Feb 25 21:26:15 2016 +0100
@@ -0,0 +1,109 @@
+<?php
+namespace CorpusParole\Services;
+
+use Cache;
+use CorpusParole\Services\BnfResolverInterface;
+
+class BnfResolver implements BnfResolverInterface {
+
+ public function __construct($sparqlClient) {
+ $this->sparqlClient = $sparqlClient;
+ }
+
+ private function checkBnfId($id) {
+ $bnfid = $id;
+
+ if(strpos($id, config('corpusparole.bnf_ark_base_url')) === 0) {
+ $bnfid = config('corpusparole.bnf_base_url').substr($id, strlen(config('corpusparole.bnf_ark_base_url')));
+ }
+ elseif(strpos($id, config('corpusparole.bnf_base_url')) !== 0) {
+ $bnfid = config('corpusparole.bnf_base_url').$id;
+ }
+ $bnfid = rtrim($bnfid, '/');
+ if(preg_match("/^".preg_quote(config('corpusparole.bnf_base_url'),"/")."ark\:\/12148\/[[:alnum:]]/", $bnfid) !== 1) {
+ throw new BnfResolverException("the provided id \"$id\" is not a BNF id");
+ }
+ return $bnfid;
+ }
+
+ /**
+ * Get label from BNF id
+ * @param string $id The id to resolve. Can be an url starting with http://data.bnf.fr/ or http://ark.bnf.fr/
+ * @return a string with the name
+ */
+ public function getLabel($id) {
+ $res = $this->getlabels([$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://data.bnf.fr/ or http://ark.bnf.fr/
+ */
+ public function getLabels(array $ids) {
+
+ if(count($ids) > config('corpusparole.bnf_max_ids')) {
+ throw new BnfResolverException("Too manys ids provided");
+ }
+
+ $bnfids = array_map([$this, 'checkBnfId'], $ids);
+ $bnfidsMap = array_combine($bnfids, $ids);
+
+ $results = [];
+ $missingBnfids = [];
+
+ foreach ($bnfidsMap as $bnfid => $bnfidSource) {
+ $cachedValue = Cache::get("bnf:$bnfid");
+ if(is_null($cachedValue)) {
+ array_push($missingBnfids, $bnfid);
+ } else {
+ $results[$bnfidSource] = $cachedValue;
+ }
+ }
+
+ if(count($missingBnfids) == 0) {
+ return $results;
+ }
+
+ $query = "SELECT ?s ?o WHERE {";
+ foreach ($missingBnfids as $index => $bid) {
+ if($index > 0) {
+ $query .= " UNION ";
+ }
+ $query .= "{ <$bid> <http://www.w3.org/2004/02/skos/core#prefLabel> ?o. ?s <http://www.w3.org/2004/02/skos/core#prefLabel> ?o. FILTER(?s = <$bid> && lang(?o) = \"fr\")}";
+ }
+ $query .= "}";
+
+ $docs = $this->sparqlClient->query($query);
+
+ $resultsRaw = [];
+
+ foreach ($docs as $doc) {
+ $bnfid = $doc->s->getUri();
+ $bnflabel = $doc->o;
+
+ $value = $bnflabel->getValue();
+
+ if(!empty($value)) {
+ $resultsRaw[$bnfid] = $bnflabel;
+ }
+ }
+
+ foreach ($missingBnfids as $bnfid) {
+ $bnfidSource = $bnfidsMap[$bnfid];
+ $missingValue = (array_key_exists($bnfid,$resultsRaw) && $resultsRaw[$bnfid])?mb_strtolower($resultsRaw[$bnfid]->getValue()):"";
+ if (mb_strlen($missingValue)>0) {
+ Cache::put("bnf:$bnfid", $missingValue, config('corpusparole.bnf_cache_expiration'));
+ $results[$bnfidSource] = $missingValue;
+ }
+ else {
+ $results[$bnfidSource] = null;
+ }
+ }
+
+ return $results;
+ }
+
+}