. */ declare(strict_types=1); namespace Fisharebest\Webtrees\Module; use Fig\Http\Message\StatusCodeInterface; use Fisharebest\Webtrees\Registry; use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Psr7\Request; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; /** * Trait ModuleMapAutocompleteTrait - default implementation of ModuleMapAutocompleteInterface */ trait ModuleMapAutocompleteTrait { /** * A unique internal name for this module (based on the installation folder). * * @return string */ abstract public function name(): string; /** * @param string $place * * @return array */ public function searchPlaceNames(string $place): array { if (strlen($place) <= 2) { return []; } $key = $this->name() . $place; $cache = Registry::cache()->file(); $ttl = 86400; try { return $cache->remember($key, function () use ($place) { $request = $this->createPlaceNameSearchRequest($place); $client = new Client([ 'timeout' => 3, ]); $response = $client->send($request); if ($response->getStatusCode() === StatusCodeInterface::STATUS_OK) { return $this->parsePlaceNameSearchResponse($response); } return []; }, $ttl); } catch (GuzzleException $ex) { // Service down? Quota exceeded? // Don't try for another hour. $cache->remember($key, fn () => [], 3600); return []; } } /** * @param string $place * * @return RequestInterface */ protected function createPlaceNameSearchRequest(/** @scrutinizer ignore-unused */ string $place): RequestInterface { return new Request('GET', ''); } /** * @param ResponseInterface $response * * @return array */ protected function parsePlaceNameSearchResponse(/** @scrutinizer ignore-unused */ ResponseInterface $response): array { return []; } }