-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathBirdDataImporter.php
108 lines (83 loc) · 3.22 KB
/
BirdDataImporter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
declare(strict_types=1);
namespace App\Importers;
use App\Exceptions\MapboxGeocodingServiceException;
use App\Models\City;
use App\Models\CityAlternativeName;
use App\Models\Country;
use GuzzleHttp\Exception\GuzzleException;
class BirdDataImporter extends DataImporter
{
protected string $html;
public function extract(): static
{
try {
$response = $this->client->get("https://www.bird.co/map/");
$this->html = $response->getBody()->getContents();
} catch (GuzzleException) {
$this->createImportInfoDetails("400", self::getProviderName());
$this->stopExecution = true;
}
return $this;
}
/**
* @throws MapboxGeocodingServiceException
*/
public function transform(): void
{
if ($this->stopExecution) {
return;
}
$existingCityProviders = [];
$coordinatesList = $this->parseData($this->html);
foreach ($coordinatesList as $coordinates) {
if ($coordinates) {
[$lat, $long] = explode(" ", $coordinates);
[$cityName, $countryName] = $this->mapboxService->getPlaceFromApi($lat, $long);
$provider = $this->load($cityName, $countryName, $lat, $long);
if ($provider !== "") {
$existingCityProviders[] = $provider;
}
}
}
$this->deleteMissingProviders(self::getProviderName(), $existingCityProviders);
}
protected function parseData(string $html): array
{
$pattern = '/let features = \[([\s\S]*?)];/';
if (preg_match($pattern, $html, $matches)) {
$fetchedData = $matches[1];
}
if (!isset($fetchedData)) {
$this->createImportInfoDetails("204", self::getProviderName());
$this->stopExecution = true;
}
$fetchedData = str_replace(["{", "}", "\t", "type: 'hq'", ",", "\n", "position: new google.maps.LatLng("], "", $fetchedData);
$coordinates = explode(")", $fetchedData);
$coordinates = array_filter($coordinates, "trim");
return array_map("trim", $coordinates);
}
protected function load(string $cityName, string $countryName, string $lat = "", string $long = "", array $services = ["escooter"]): string
{
$city = City::query()->where("name", $cityName)->first();
$alternativeCityName = CityAlternativeName::query()->where("name", $cityName)->first();
if ($city || $alternativeCityName) {
$cityId = $city ? $city->id : $alternativeCityName->city_id;
$this->createProvider($cityId, self::getProviderName(), $services);
return strval($cityId);
}
$country = Country::query()->where("name", $countryName)->first();
if ($country) {
$city = City::query()->create([
"name" => $cityName,
"latitude" => $lat,
"longitude" => $long,
"country_id" => $country->id,
]);
$this->createProvider($city->id, self::getProviderName(), $services);
return strval($city->id);
}
$this->countryNotFound($cityName, $countryName);
return "";
}
}