Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
repository.php
1<?php
2
4
20use \Bitrix\Location\Common\CachedPool;
23
24Loc::loadMessages(__FILE__);
25
31{
33 protected $apiKey = '';
35 protected static $sourceCode = 'GOOGLE';
37 protected $httpClient = null;
39 protected $cachePool = null;
41 protected $googleSource = null;
42
43 public function __construct(
44 string $apiKey,
48 )
49 {
50 $this->apiKey = $apiKey;
51 $this->httpClient = $httpClient;
52 $this->cachePool = $cachePool;
53 $this->googleSource = $googleSource;
54 }
55
57 public function findByExternalId(string $locationExternalId, string $sourceCode, string $languageId)
58 {
59 if($sourceCode !== self::$sourceCode || $locationExternalId === '')
60 {
61 return null;
62 }
63
64 return $this->find(
65 new Requesters\ByIdRequester($this->httpClient, $this->cachePool),
66 new Converters\ByIdConverter($languageId),
67 [
68 'placeid' => $locationExternalId,
69 'language' => $this->googleSource->convertLang($languageId)
70 ]
71 );
72 }
73
77 public function findByText(string $query, string $languageId)
78 {
79 if($query == '')
80 {
81 return null;
82 }
83
84 return $this->find(
85 new Requesters\ByQueryRequester($this->httpClient, $this->cachePool),
86 new Converters\ByQueryConverter($languageId),
87 [
88 'query' => $query,
89 'language' => $this->googleSource->convertLang($languageId)
90 ]
91 );
92 }
93
94 protected function isCollectionContainLocation(Location $location, Collection $collection): bool
95 {
96 foreach ($collection->getItems() as $item)
97 {
98 if($location->getExternalId() === $item->getExternalId())
99 {
100 return true;
101 }
102 }
103
104 return false;
105 }
106
107 protected function chooseParentFromCollection(
108 Location $location,
109 Collection $collection,
110 Parents $parentResultCollection,
111 array $parentTypes
112 ): ?Location
113 {
114 if($collection->count() <= 0)
115 {
116 return null;
117 }
118
119 $candidatesTypes = [];
120 $result = null;
121
122 for($i = 0, $l = $collection->count(); $i < $l; $i++)
123 {
124 $candidate = $collection[$i];
125
126 if($location->getExternalId() === $candidate->getExternalId())
127 {
128 continue;
129 }
130
131 $candidateType = $candidate->getType();
132
133 if($candidateType === Location\Type::UNKNOWN)
134 {
135 continue;
136 }
137
138 if($location->getType() !== Location\Type::UNKNOWN && $candidate->getType() >= $location->getType())
139 {
140 continue;
141 }
142
143 // check if we already have the same location in result parents collection
144 if($this->isCollectionContainLocation($candidate, $parentResultCollection))
145 {
146 continue;
147 }
148
149 if(in_array($candidateType, $parentTypes, true))
150 {
151 return $candidate;
152 }
153
154 $candidatesTypes[] = [$i, $candidateType];
155 }
156
157 if(count($candidatesTypes) <= 0)
158 {
159 return null;
160 }
161
162 if(count($candidatesTypes) > 1)
163 {
164 $typeColumn = array_column($candidatesTypes, 1);
165 array_multisort($typeColumn, SORT_ASC, $candidatesTypes);
166 }
167
168 return $collection[$candidatesTypes[0][0]];
169 }
170
172 /*
173 * Needs tests
174 */
175 public function findParents(Location $location, string $languageId): ?Parents
176 {
177 if($location->getSourceCode() !== self::$sourceCode || $location->getExternalId() == '')
178 {
179 return null;
180 }
181
182 $result = (new Parents())
183 ->setDescendant($location);
184
185 /* Temporary. To decrease the usage of the Google API */
186 return $result;
187 /* */
188
189 //We need full information about the location
190 $rawData = $this->find(
191 new Requesters\ByIdRequester($this->httpClient, $this->cachePool),
192 null,
193 [
194 'placeid' => $location->getExternalId(),
195 'language' => $languageId
196 ]
197 );
198
199 $ancestorDataConverter = new Converters\AncestorDataConverter();
200 $ancestorsRawData = $ancestorDataConverter->convert($rawData, $location->getType());
201
202 //is it always available?
203 $latLon = $location->getLatitude().','.$location->getLongitude();
204
205 foreach ($ancestorsRawData as $data)
206 {
207 //Just searching by query taking into account lat and lon
208 $res = $this->find(
209 new Requesters\ByQueryRequester($this->httpClient, $this->cachePool),
210 new Converters\ByQueryConverter($languageId),
211 [
212 'query' => $data['NAME'],
213 //todo: may be restrict by several types?
214 'location' => $latLon,
215 'language' => $languageId
216 ]
217 );
218
219 if($res instanceof Collection && $res->count() > 0)
220 {
221 if(!($parentSource = $this->chooseParentFromCollection($location, $res, $result, $data['TYPES'])))
222 {
223 continue;
224 }
225
226 $localParent = $this->findLocalLocationByExternalId($parentSource);
227
228 //the parent location have already been saved
229 if ($localParent)
230 {
231 $result->addItem($localParent);
232
233 if ($llParents = $localParent->getParents())
234 {
235 foreach ($llParents as $localParent)
236 {
237 $result->addItem($localParent);
238 }
239 }
240
241 break;
242 }
243 else
244 {
245 //we need detailed info
246 $detailedParent = $this->findByExternalId(
247 $parentSource->getExternalId(),
248 self::$sourceCode,
249 $languageId
250 );
251
252 if($detailedParent)
253 {
254 $result->addItem($detailedParent);
255 }
256 }
257 }
258 }
259
260 return $result;
261 }
262
268 protected function findLocalLocationByExternalId(Location $location)
269 {
270 return LocationService::getInstance()->findByExternalId(
271 $location->getExternalId(),
272 $location->getSourceCode(),
273 $location->getLanguageId(),
274 LOCATION_SEARCH_SCOPE_INTERNAL
275 );
276 }
277
283 protected function buildFinder($requester, $converter)
284 {
285 return new Finder($requester, $converter);
286 }
287
294 protected function find($requester, $converter = null, array $findParams = [])
295 {
296 if($this->apiKey === '')
297 {
298 throw new RuntimeException(
299 Loc::getMessage('LOCATION_ADDRESS_REPOSITORY_API_KEY_ERROR'),
301 );
302 }
303
304 $finder = $this->buildFinder($requester, $converter);
305 $findParams['key'] = $this->apiKey;
306 return $finder->find($findParams);
307 }
308
310 public static function getSourceCode(): string
311 {
312 return self::$sourceCode;
313 }
314}
findParents(Location $location, string $languageId)
isCollectionContainLocation(Location $location, Collection $collection)
findLocalLocationByExternalId(Location $location)
chooseParentFromCollection(Location $location, Collection $collection, Parents $parentResultCollection, array $parentTypes)
find($requester, $converter=null, array $findParams=[])
findByText(string $query, string $languageId)
findByExternalId(string $locationExternalId, string $sourceCode, string $languageId)
__construct(string $apiKey, HttpClient $httpClient, GoogleSource $googleSource, CachedPool $cachePool=null)
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29