Issues (2564)

app/Module/ModuleMapGeoLocationTrait.php (1 issue)

Labels
Severity
1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2025 webtrees development team
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Module;
21
22
use Fig\Http\Message\StatusCodeInterface;
23
use Fisharebest\Webtrees\Html;
24
use Fisharebest\Webtrees\I18N;
0 ignored issues
show
The type Fisharebest\Webtrees\I18N was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
use Fisharebest\Webtrees\Registry;
26
use GuzzleHttp\Client;
27
use GuzzleHttp\Psr7\Request;
28
use JsonException;
29
use Psr\Http\Message\RequestInterface;
30
use Psr\Http\Message\ResponseInterface;
31
32
use function json_decode;
33
use function strlen;
34
35
use const JSON_THROW_ON_ERROR;
36
37
/**
38
 * Trait ModuleMapGeoLocationTrait - default implementation of ModuleMapGeoLocationInterface
39
 */
40
trait ModuleMapGeoLocationTrait
41
{
42
    /**
43
     * A unique internal name for this module (based on the installation folder).
44
     *
45
     * @return string
46
     */
47
    abstract public function name(): string;
48
49
    public function description(): string
50
    {
51
        return I18N::translate('Use an external service to find locations.');
52
    }
53
54
    /**
55
     * @param string $place
56
     *
57
     * @return array<string>
58
     */
59
    public function searchPlaceNames(string $place): array
60
    {
61
        if (strlen($place) <= 2) {
62
            return [];
63
        }
64
65
        $key   = $this->name() . $place;
66
        $cache = Registry::cache()->file();
67
        $ttl   = 86400;
68
69
        return $cache->remember($key, function () use ($place) {
70
            $request = $this->searchLocationsRequest($place);
71
72
            $client = new Client([
73
                'timeout' => 3,
74
            ]);
75
76
            $response = $client->send($request);
77
78
            if ($response->getStatusCode() === StatusCodeInterface::STATUS_OK) {
79
                return $this->extractLocationsFromResponse($response);
80
            }
81
82
            return [];
83
        }, $ttl);
84
    }
85
86
    /**
87
     * @param string $place
88
     *
89
     * @return RequestInterface
90
     */
91
    protected function searchLocationsRequest(string $place): RequestInterface
92
    {
93
        $uri = Html::url('https://nominatim.openstreetmap.org/search', [
94
            'accept-language' => I18N::languageTag(),
95
            'format'          => 'jsonv2',
96
            'limit'           => 50,
97
            'q'               => $place,
98
        ]);
99
100
        return new Request('GET', $uri);
101
    }
102
103
    /**
104
     * @param ResponseInterface $response
105
     *
106
     * @return array<string>
107
     */
108
    protected function extractLocationsFromResponse(ResponseInterface $response): array
109
    {
110
        $body = $response->getBody()->getContents();
111
112
        try {
113
            return json_decode($body, false, 512, JSON_THROW_ON_ERROR);
114
        } catch (JsonException) {
115
            return [];
116
        }
117
    }
118
}
119