server/src/app/Services/LexvoResolver.php
changeset 28 b0b56e0f8c7f
child 133 821253d361d1
equal deleted inserted replaced
27:a2342f26c9de 28:b0b56e0f8c7f
       
     1 <?php
       
     2 namespace CorpusParole\Services;
       
     3 
       
     4 use Cache;
       
     5 use CorpusParole\Services\LexvoResolverInterface;
       
     6 
       
     7 class LexvoResolver implements LexvoResolverInterface {
       
     8 
       
     9     public function __construct($sparqlClient) {
       
    10         $this->sparqlClient = $sparqlClient;
       
    11     }
       
    12 
       
    13     private function checkLexvoId($id) {
       
    14         $lexvoid = $id;
       
    15         if(strpos($id, config('corpusparole.lexvo_base_url')) !== 0) {
       
    16             $lexvoid = config('corpusparole.lexvo_base_url').$id;
       
    17         }
       
    18         $lexvoid = rtrim($lexvoid, '/');
       
    19         if(preg_match("/^".preg_quote(config('corpusparole.lexvo_base_url'),"/")."[[:alpha:]]{3}$/", $lexvoid) !== 1) {
       
    20             throw new LexvoResolverException("the provided id \"$id\" is not a Lexvo id");
       
    21         }
       
    22         return $lexvoid;
       
    23     }
       
    24     /**
       
    25      * Get name from Viaf id
       
    26      * @param string $id The id to resolve. Can be an url starting with http://viaf.org/viaf/
       
    27      * @return a string with the name
       
    28      */
       
    29     public function getName($id) {
       
    30         $res = $this->getNames([$id,]);
       
    31         assert(array_key_exists($id,$res), "the result must contains $id");
       
    32         return $res[$id];
       
    33     }
       
    34 
       
    35     /**
       
    36      * Get a list of names from an array of viaf ids.
       
    37      * @param array $ids The array of ids to resolve.
       
    38      *                   Each id can be an url starting with http://viaf.org/viaf/
       
    39      * @return array key is id, value is the name
       
    40      */
       
    41     public function getNames(array $ids) {
       
    42 
       
    43         $lexvoids = array_map([$this, 'checkLexvoId'], $ids);
       
    44         $lexvoidsMap = array_combine($lexvoids, $ids);
       
    45 
       
    46         $results = [];
       
    47         $missingLexvoids = [];
       
    48 
       
    49         foreach ($lexvoidsMap as $lexvoid => $lexvoidSource) {
       
    50             $cachedValue = Cache::get("lexvo:$lexvoid");
       
    51             if(is_null($cachedValue)) {
       
    52                 array_push($missingLexvoids, $lexvoid);
       
    53             } else {
       
    54                 $results[$lexvoidSource] = $cachedValue;
       
    55             }
       
    56         }
       
    57 
       
    58         if(count($missingLexvoids) == 0) {
       
    59             return $results;
       
    60         }
       
    61 
       
    62         $query = "SELECT ?s ?o WHERE {";
       
    63         foreach ($missingLexvoids as $index => $lid) {
       
    64             if($index > 0) {
       
    65                 $query .= " UNION ";
       
    66             }
       
    67             $query .= "{<$lid> rdfs:label ?o. ?s rdfs:label ?o FILTER(?s = <$lid> && (lang(?o) = \"fr\" || lang(?o) = \"en\"))}";
       
    68         }
       
    69         $query .= "}";
       
    70 
       
    71 
       
    72         $docs = $this->sparqlClient->query($query);
       
    73 
       
    74         $resultsRaw = [];
       
    75 
       
    76         foreach ($docs as $doc) {
       
    77             $lexvoid = $doc->s->getUri();
       
    78             $lexvoname = $doc->o;
       
    79 
       
    80             $lang = $lexvoname->getLang();
       
    81             $value = $lexvoname->getValue();
       
    82 
       
    83             if(!array_key_exists($lexvoid, $resultsRaw) ||
       
    84             ($lang == "fr" && ($resultsRaw[$lexvoid]->getLang() == "en" || mb_strlen($resultsRaw[$lexvoid]->getValue()) > mb_strlen($value))) ||
       
    85             ($lang == "en" && $resultsRaw[$lexvoid]->getLang() == "en" && mb_strlen($resultsRaw[$lexvoid]->getValue()) > mb_strlen($value)) ) {
       
    86                 $resultsRaw[$lexvoid] = $lexvoname;
       
    87             }
       
    88         }
       
    89 
       
    90         foreach ($missingLexvoids as $lexvoid) {
       
    91             $lexvoidSource = $lexvoidsMap[$lexvoid];
       
    92             $missingValue = array_key_exists($lexvoid,$resultsRaw) && $resultsRaw[$lexvoid]?mb_strtolower($resultsRaw[$lexvoid]->getValue()):"";
       
    93             Cache::put("lexvo:$lexvoid", $missingValue, config('corpusparole.lexvo_cache_expiration'));
       
    94             $results[$lexvoidSource] = mb_strlen($missingValue)>0?$missingValue:null;
       
    95         }
       
    96 
       
    97         return $results;
       
    98 
       
    99     }
       
   100 
       
   101 }