diff -r d97eda8bc8ec -r 821253d361d1 server/src/app/Services/BnfResolver.php --- /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 @@ +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> ?o. ?s ?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; + } + +}