|
1 <?php |
|
2 namespace CorpusParole\Services; |
|
3 |
|
4 use Cache; |
|
5 use CorpusParole\Services\BnfResolverInterface; |
|
6 |
|
7 class BnfResolver implements BnfResolverInterface { |
|
8 |
|
9 public function __construct($sparqlClient) { |
|
10 $this->sparqlClient = $sparqlClient; |
|
11 } |
|
12 |
|
13 private function checkBnfId($id) { |
|
14 $bnfid = $id; |
|
15 |
|
16 if(strpos($id, config('corpusparole.bnf_ark_base_url')) === 0) { |
|
17 $bnfid = config('corpusparole.bnf_base_url').substr($id, strlen(config('corpusparole.bnf_ark_base_url'))); |
|
18 } |
|
19 elseif(strpos($id, config('corpusparole.bnf_base_url')) !== 0) { |
|
20 $bnfid = config('corpusparole.bnf_base_url').$id; |
|
21 } |
|
22 $bnfid = rtrim($bnfid, '/'); |
|
23 if(preg_match("/^".preg_quote(config('corpusparole.bnf_base_url'),"/")."ark\:\/12148\/[[:alnum:]]/", $bnfid) !== 1) { |
|
24 throw new BnfResolverException("the provided id \"$id\" is not a BNF id"); |
|
25 } |
|
26 return $bnfid; |
|
27 } |
|
28 |
|
29 /** |
|
30 * Get label from BNF id |
|
31 * @param string $id The id to resolve. Can be an url starting with http://data.bnf.fr/ or http://ark.bnf.fr/ |
|
32 * @return a string with the name |
|
33 */ |
|
34 public function getLabel($id) { |
|
35 $res = $this->getlabels([$id,]); |
|
36 assert(array_key_exists($id,$res), "the result must contains $id"); |
|
37 return $res[$id]; |
|
38 } |
|
39 |
|
40 /** |
|
41 * Get a list of names from an array of viaf ids. |
|
42 * @param array $ids The array of ids to resolve. |
|
43 * Each id can be an url starting with http://data.bnf.fr/ or http://ark.bnf.fr/ |
|
44 */ |
|
45 public function getLabels(array $ids) { |
|
46 |
|
47 if(count($ids) > config('corpusparole.bnf_max_ids')) { |
|
48 throw new BnfResolverException("Too manys ids provided"); |
|
49 } |
|
50 |
|
51 $bnfids = array_map([$this, 'checkBnfId'], $ids); |
|
52 $bnfidsMap = array_combine($bnfids, $ids); |
|
53 |
|
54 $results = []; |
|
55 $missingBnfids = []; |
|
56 |
|
57 foreach ($bnfidsMap as $bnfid => $bnfidSource) { |
|
58 $cachedValue = Cache::get("bnf:$bnfid"); |
|
59 if(is_null($cachedValue)) { |
|
60 array_push($missingBnfids, $bnfid); |
|
61 } else { |
|
62 $results[$bnfidSource] = $cachedValue; |
|
63 } |
|
64 } |
|
65 |
|
66 if(count($missingBnfids) == 0) { |
|
67 return $results; |
|
68 } |
|
69 |
|
70 $query = "SELECT ?s ?o WHERE {"; |
|
71 foreach ($missingBnfids as $index => $bid) { |
|
72 if($index > 0) { |
|
73 $query .= " UNION "; |
|
74 } |
|
75 $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\")}"; |
|
76 } |
|
77 $query .= "}"; |
|
78 |
|
79 $docs = $this->sparqlClient->query($query); |
|
80 |
|
81 $resultsRaw = []; |
|
82 |
|
83 foreach ($docs as $doc) { |
|
84 $bnfid = $doc->s->getUri(); |
|
85 $bnflabel = $doc->o; |
|
86 |
|
87 $value = $bnflabel->getValue(); |
|
88 |
|
89 if(!empty($value)) { |
|
90 $resultsRaw[$bnfid] = $bnflabel; |
|
91 } |
|
92 } |
|
93 |
|
94 foreach ($missingBnfids as $bnfid) { |
|
95 $bnfidSource = $bnfidsMap[$bnfid]; |
|
96 $missingValue = (array_key_exists($bnfid,$resultsRaw) && $resultsRaw[$bnfid])?mb_strtolower($resultsRaw[$bnfid]->getValue()):""; |
|
97 if (mb_strlen($missingValue)>0) { |
|
98 Cache::put("bnf:$bnfid", $missingValue, config('corpusparole.bnf_cache_expiration')); |
|
99 $results[$bnfidSource] = $missingValue; |
|
100 } |
|
101 else { |
|
102 $results[$bnfidSource] = null; |
|
103 } |
|
104 } |
|
105 |
|
106 return $results; |
|
107 } |
|
108 |
|
109 } |