server/src/app/Services/BnfResolver.php
changeset 133 821253d361d1
child 158 366509ae2f37
equal deleted inserted replaced
132:d97eda8bc8ec 133:821253d361d1
       
     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 }