Skip to content

Commit 1a9de96

Browse files
authored
[TASK][!!!] Update code to PHP 8 and add compatibility with TYPO3 12 LTS (#18)
1 parent 050898b commit 1a9de96

9 files changed

Lines changed: 130 additions & 290 deletions

File tree

.gitignore

Lines changed: 0 additions & 33 deletions
This file was deleted.

.php_cs

Lines changed: 0 additions & 72 deletions
This file was deleted.

Classes/Service/GeoService.php

Lines changed: 74 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -10,92 +10,73 @@
1010
* of the License, or any later version.
1111
*/
1212

13-
use TYPO3\CMS\Core\Cache\CacheManager;
1413
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
1514
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
1615
use TYPO3\CMS\Core\Database\ConnectionPool;
1716
use TYPO3\CMS\Core\Database\Query\QueryHelper;
1817
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
18+
use TYPO3\CMS\Core\Http\RequestFactory;
19+
use TYPO3\CMS\Core\SingletonInterface;
1920
use TYPO3\CMS\Core\Utility\GeneralUtility;
2021

2122
/**
2223
* Calculate the geo coordinates of an address, using the google geocoding
2324
* API, an API key is needed, as this is a server-side process.
2425
*/
25-
class GeoService
26+
class GeoService implements SingletonInterface
2627
{
27-
/**
28-
* @var int
29-
*/
30-
protected $cacheTime = 7776000; // 90 days
31-
32-
/**
33-
* @var int
34-
*/
35-
protected $maxRetries = 0;
36-
37-
/**
38-
* base URL to fetch the Coordinates (Latitude, Longitude of a Address String.
39-
* @var string
40-
*/
41-
protected $geocodingUrl = 'https://maps.googleapis.com/maps/api/geocode/json?language=de&sensor=false';
42-
43-
/**
44-
* constructor method.
45-
*
46-
* sets the google code API key
47-
*
48-
* @param string $apiKey (optional) the API key from google, if empty, the default from the configuration is taken
49-
*/
50-
public function __construct($apiKey = null)
51-
{
52-
if (class_exists(ExtensionConfiguration::class)) {
53-
$geoCodingConfig = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('geocoding');
54-
} else {
55-
$geoCodingConfig = $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['geocoding'] ?: unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['geocoding'], ['allowed_classes' => false]);
56-
}
28+
/** base URL to fetch the Coordinates (Latitude, Longitude of a Address String.*/
29+
protected string $geocodingUrl = 'https://maps.googleapis.com/maps/api/geocode/json?language=de&sensor=false';
30+
protected int $cacheTime = 7776000; // 90 days
31+
protected int $maxRetries = 0;
32+
33+
public function __construct(
34+
protected readonly FrontendInterface $cache,
35+
protected readonly ExtensionConfiguration $extensionConfiguration,
36+
protected readonly RequestFactory $requestFactory
37+
) {
38+
$geoCodingConfig = $extensionConfiguration->get('geocoding');
5739
// load from extension configuration
58-
if ($apiKey === null) {
59-
$apiKey = $geoCodingConfig['googleApiKey'] ?: '';
60-
}
40+
$apiKey = $geoCodingConfig['googleApiKey'] ?? '';
6141
if (!empty($apiKey)) {
6242
$this->geocodingUrl .= '&key=' . $apiKey;
6343
}
64-
$this->maxRetries = (int)$geoCodingConfig['maxRetries'];
44+
$this->maxRetries = (int)($geoCodingConfig['maxRetries'] ?? 0);
6545
}
6646

6747
/**
6848
* core functionality: asks google for the coordinates of an address
6949
* stores known addresses in a local cache.
7050
*
71-
* @param $street
72-
* @param $zip
73-
* @param $city
74-
* @param $country
75-
*
7651
* @return array an array with latitude and longitude
7752
*/
78-
public function getCoordinatesForAddress($street = null, $zip = null, $city = null, $country = 'Germany'): array
53+
public function getCoordinatesForAddress(?string $street = null, ?string $zip = null, ?string $city = null, ?string $country = 'Germany'): array
7954
{
8055
$addressParts = [];
8156
foreach ([$street, $zip . ' ' . $city, $country] as $addressPart) {
57+
if ($addressPart === null) {
58+
continue;
59+
}
8260
if (strlen(trim($addressPart)) <= 0) {
8361
continue;
8462
}
8563
$addressParts[] = trim($addressPart);
8664
}
8765

66+
if ($addressParts === []) {
67+
return [];
68+
}
69+
8870
$address = ltrim(implode(',', $addressParts), ',');
8971
if (empty($address)) {
9072
return [];
9173
}
9274

93-
$cacheObject = $this->initializeCache();
9475
$cacheKey = 'geocode-' . strtolower(str_replace(' ', '-', preg_replace('/[^0-9a-zA-Z ]/m', '', $address)));
9576

9677
// Found in cache? Return it.
97-
if ($cacheObject->has($cacheKey)) {
98-
return $cacheObject->get($cacheKey);
78+
if ($this->cache->has($cacheKey)) {
79+
return $this->cache->get($cacheKey);
9980
}
10081

10182
$result = $this->getApiCallResult(
@@ -112,7 +93,7 @@ public function getCoordinatesForAddress($street = null, $zip = null, $city = nu
11293
'longitude' => $geometry['location']['lng'],
11394
];
11495
// Now store the $result in cache and return
115-
$cacheObject->set($cacheKey, $result, [], $this->cacheTime);
96+
$this->cache->set($cacheKey, $result, [], $this->cacheTime);
11697
return $result;
11798
}
11899

@@ -122,27 +103,17 @@ public function getCoordinatesForAddress($street = null, $zip = null, $city = nu
122103
*
123104
* only works if your DB table has the necessary fields
124105
* helpful when calculating a batch of addresses and save the latitude/longitude automatically
125-
* @param string $tableName
126-
* @param string $latitudeField
127-
* @param string $longitudeField
128-
* @param string $streetField
129-
* @param string $zipField
130-
* @param string $cityField
131-
* @param string $countryField
132-
* @param string $addWhereClause
133-
* @return int
134106
*/
135107
public function calculateCoordinatesForAllRecordsInTable(
136-
$tableName,
137-
$latitudeField = 'latitude',
138-
$longitudeField = 'longitude',
139-
$streetField = 'street',
140-
$zipField = 'zip',
141-
$cityField = 'city',
142-
$countryField = 'country',
143-
$addWhereClause = ''
144-
): int
145-
{
108+
string $tableName,
109+
string $latitudeField = 'latitude',
110+
string $longitudeField = 'longitude',
111+
string $streetField = 'street',
112+
string $zipField = 'zip',
113+
string $cityField = 'city',
114+
string $countryField = 'country',
115+
string $addWhereClause = ''
116+
): int {
146117
// Fetch all records without latitude/longitude
147118
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($tableName);
148119
$queryBuilder = $connection->createQueryBuilder();
@@ -168,82 +139,61 @@ public function calculateCoordinatesForAllRecordsInTable(
168139
$queryBuilder->andWhere(QueryHelper::stripLogicalOperatorPrefix($addWhereClause));
169140
}
170141

171-
$records = $queryBuilder->execute()->fetchAll();
172-
173-
if (count($records) > 0) {
174-
foreach ($records as $record) {
175-
$country = $record[$countryField];
176-
// resolve the label for the country
177-
if ($GLOBALS['TCA'][$tableName]['columns'][$countryField]['config']['type'] == 'select') {
178-
foreach ($GLOBALS['TCA'][$tableName]['columns'][$countryField]['config']['items'] as $itm) {
179-
if ($itm[1] == $country) {
180-
if (is_object($GLOBALS['TSFE'])) {
181-
$country = $GLOBALS['TSFE']->sL($itm[0]);
182-
} else {
183-
$country = $GLOBALS['LANG']->sL($itm[0]);
184-
}
142+
$records = $queryBuilder->executeQuery()->fetchAllAssociative();
143+
144+
foreach ($records as $record) {
145+
$country = $record[$countryField] ?? '';
146+
// resolve the label for the country
147+
if (($GLOBALS['TCA'][$tableName]['columns'][$countryField]['config']['type'] ?? '') === 'select') {
148+
foreach ($GLOBALS['TCA'][$tableName]['columns'][$countryField]['config']['items'] ?? [] as $itm) {
149+
if (($itm[1] ?? null) === $country) {
150+
if (is_object($GLOBALS['TSFE'])) {
151+
$country = $GLOBALS['TSFE']->sL($itm[0]);
152+
} else {
153+
$country = $GLOBALS['LANG']->sL($itm[0]);
185154
}
186155
}
187156
}
188-
// do the geocoding
189-
if (!empty($record[$zipField]) || !empty($record[$cityField])) {
190-
$coords = $this->getCoordinatesForAddress($record[$streetField], $record[$zipField], $record[$cityField], $country);
191-
if ($coords) {
192-
// Update the record to fill in the latitude and longitude values in the DB
193-
$connection->update(
194-
$tableName,
195-
[
196-
$latitudeField => $coords['latitude'],
197-
$longitudeField => $coords['longitude'],
198-
],
199-
[
200-
'uid' => $record['uid']
201-
]
202-
);
203-
}
157+
}
158+
// do the geocoding
159+
if (!empty($record[$zipField]) || !empty($record[$cityField])) {
160+
$coords = $this->getCoordinatesForAddress($record[$streetField] ?? null, $record[$zipField] ?? null, $record[$cityField] ?? null, $country);
161+
if ($coords) {
162+
// Update the record to fill in the latitude and longitude values in the DB
163+
$connection->update(
164+
$tableName,
165+
[
166+
$latitudeField => $coords['latitude'],
167+
$longitudeField => $coords['longitude'],
168+
],
169+
[
170+
'uid' => $record['uid'],
171+
]
172+
);
204173
}
205174
}
206175
}
207176

208177
return count($records);
209178
}
210179

211-
/**
212-
* Initializes the cache for the DB requests.
213-
*
214-
* @return FrontendInterface Cache Object
215-
*/
216-
protected function initializeCache(): FrontendInterface
217-
{
218-
try {
219-
$cacheManager = GeneralUtility::makeInstance(CacheManager::class);
220-
return $cacheManager->getCache('geocoding');
221-
} catch (\TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException $e) {
222-
throw new \RuntimeException('Unable to load Cache!', 1487138924);
223-
}
224-
}
225-
226-
/**
227-
* @param string $url
228-
* @param int $remainingTries
229-
* @return array
230-
*/
231180
protected function getApiCallResult(string $url, int $remainingTries = 10): array
232181
{
233-
$response = GeneralUtility::getUrl($url);
234-
$result = json_decode($response, true);
235-
236-
if($result['status'] !== 'OK'){
182+
$response = $this->requestFactory->request($url);
183+
184+
$result = json_decode($response->getBody()->getContents(), true) ?? [];
185+
if (!in_array(($result['status'] ?? ''), ['OK', 'OVER_QUERY_LIMIT'], true)) {
237186
throw new \RuntimeException(
238187
sprintf(
239-
'Request to Google Maps API returned status "%s". Got following error message: "%s"',
240-
$result['status'],
241-
$result['error_message']),
188+
'Request to Google Maps API returned status "%s". Got following error message: "%s"',
189+
$result['status'] ?? 0,
190+
$result['error_message'] ?? ''
191+
),
242192
1621512170
243193
);
244194
}
245-
246-
if ($result['status'] !== 'OVER_QUERY_LIMIT' || $remainingTries <= 0) {
195+
196+
if (($result['status'] ?? '') === 'OVER_QUERY_LIMIT' || $remainingTries <= 0) {
247197
return $result;
248198
}
249199
return $this->getApiCallResult($url, $remainingTries - 1);

0 commit comments

Comments
 (0)