97 lines
3.1 KiB
PHP
97 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace php;
|
|
|
|
use Exception;
|
|
use Monolog\Logger;
|
|
|
|
|
|
/**
|
|
* Helper class for interacting with Wikipedia's API.
|
|
*/
|
|
class Mediawiki
|
|
{
|
|
/**
|
|
* The URL of Wikipedia's API endpoint.
|
|
*/
|
|
private const API_URL = "https://en.wikipedia.org/w/api.php?";
|
|
/**
|
|
* The user agent used to represent the death notifier to Wikipedia.
|
|
*/
|
|
private const USER_AGENT =
|
|
"death-notifier/%%VERSION_NUMBER%% " .
|
|
"(https://git.fwdekker.com/tools/death-notifier; florine@fwdekker.com)";
|
|
|
|
/**
|
|
* @var Logger The logger to use for logging.
|
|
*/
|
|
private Logger $logger;
|
|
|
|
|
|
/**
|
|
* Creates a new Mediawiki instance.
|
|
*
|
|
* @param Logger $logger the logger to use for logging
|
|
*/
|
|
public function __construct(Logger $logger)
|
|
{
|
|
$this->logger = $logger;
|
|
}
|
|
|
|
|
|
/**
|
|
* Sends a request to Wikipedia's API and returns its response as a JSON object.
|
|
*
|
|
* @param array<string, mixed> $url_param the query parameters to send to the API
|
|
* @return mixed a JSON object containing the API's response
|
|
* @throws Exception if the API could not be reached
|
|
*/
|
|
private function api_fetch(array $url_param): mixed
|
|
{
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
|
curl_setopt($ch, CURLOPT_URL, self::API_URL . http_build_query($url_param));
|
|
curl_setopt($ch, CURLOPT_USERAGENT, self::USER_AGENT);
|
|
|
|
$output = curl_exec($ch);
|
|
curl_close($ch);
|
|
if (is_bool($output) || curl_error($ch))
|
|
throw new Exception(curl_error($ch));
|
|
|
|
return json_decode($output, associative: true);
|
|
}
|
|
|
|
/**
|
|
* Checks for each person whether they are alive according to Wikipedia's categorization.
|
|
*
|
|
* @param array<string> $people_names the names of the people to check aliveness of
|
|
* @return Response responds positively with each person's aliveness, or a negative response explaining what went
|
|
* wrong
|
|
*/
|
|
public function people_are_alive(array $people_names): Response
|
|
{
|
|
// TODO: API has a limit of 50 titles per query!
|
|
try {
|
|
$response = $this->api_fetch(array(
|
|
"action" => "query",
|
|
"format" => "json",
|
|
"prop" => "categories",
|
|
"cllimit" => 500, # Record is 252 categories, so setting to 500 is fine
|
|
"redirects" => true,
|
|
"titles" => implode("|", $people_names)
|
|
));
|
|
} catch (Exception $exception) {
|
|
return new Response($exception->getMessage(), false);
|
|
}
|
|
|
|
$pages = array_values($response["query"]["pages"]);
|
|
$page_names = array_column($pages, "title");
|
|
$page_categories = array_column($pages, "categories");
|
|
// TODO: Differentiate between living, dead, missing, presumed dead, etc.
|
|
$is_alive = fn($it): bool => in_array("Category:Living people", array_column($it, "title"));
|
|
$alive_results = array_combine($page_names, array_map($is_alive, $page_categories));
|
|
|
|
return new Response($alive_results, true);
|
|
}
|
|
}
|