1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
repository.php
См. документацию.
1<?php
2
3namespace Bitrix\Location\Source\Google;
4
5use Bitrix\Location\Entity\Location;
6use Bitrix\Location\Entity\Generic\Collection;
7use Bitrix\Location\Entity\Location\Parents;
8use Bitrix\Location\Exception\RuntimeException;
9use Bitrix\Location\Repository\Location\Capability\IFindByCoords;
10use Bitrix\Location\Repository\Location\Capability\IFindByExternalId;
11use Bitrix\Location\Repository\Location\Capability\IFindByText;
12use Bitrix\Location\Repository\Location\Capability\IFindParents;
13use Bitrix\Location\Repository\Location\IRepository;
14use Bitrix\Location\Repository\Location\ISource;
15use Bitrix\Location\Service\LocationService;
16use Bitrix\Location\Source\BaseRepository;
17use Bitrix\Location\Source\Google\Converters;
18use Bitrix\Location\Source\Google\Converters\BaseConverter;
19use Bitrix\Location\Source\Google\Requesters;
20use Bitrix\Location\Source\Google\Requesters\BaseRequester;
21use \Bitrix\Location\Common\CachedPool;
22use Bitrix\Main\Localization\Loc;
23use Bitrix\Main\Web\HttpClient;
24
25Loc::loadMessages(__FILE__);
26
31class Repository extends BaseRepository implements
38{
40 protected $apiKey = '';
42 protected static $sourceCode = 'GOOGLE';
44 protected $httpClient = null;
46 protected $cachePool = null;
48 protected $googleSource = null;
49
50 public function __construct(
51 string $apiKey,
55 )
56 {
57 $this->apiKey = $apiKey;
58 $this->httpClient = $httpClient;
59 $this->cachePool = $cachePool;
60 $this->googleSource = $googleSource;
61 }
62
64 public function findByExternalId(string $locationExternalId, string $sourceCode, string $languageId)
65 {
66 if ($sourceCode !== self::$sourceCode || $locationExternalId === '')
67 {
68 return null;
69 }
70
71 return $this->find(
72 new Requesters\ByIdRequester($this->httpClient, $this->cachePool),
73 new Converters\ByIdConverter($languageId),
74 [
75 'placeid' => $locationExternalId,
76 'language' => $this->googleSource->convertLang($languageId),
77 ]
78 );
79 }
80
81 public function findByCoords(float $lat, float $lng, int $zoom, string $languageId): ?Location
82 {
83 $foundLocations = $this->find(
84 new Requesters\ByCoordsRequester($this->httpClient, $this->cachePool),
85 new Converters\ByCoordsConverter($languageId),
86 [
87 'latlng' => implode(',', [$lat, $lng]),
88 'language' => $this->googleSource->convertLang($languageId),
89 ]
90 );
91
92 return $foundLocations[0] ?? null;
93 }
94
98 public function findByText(string $query, string $languageId)
99 {
100 if ($query == '')
101 {
102 return null;
103 }
104
105 return $this->find(
106 new Requesters\ByQueryRequester($this->httpClient, $this->cachePool),
107 new Converters\ByQueryConverter($languageId),
108 [
109 'query' => $query,
110 'language' => $this->googleSource->convertLang($languageId)
111 ]
112 );
113 }
114
115 protected function isCollectionContainLocation(Location $location, Collection $collection): bool
116 {
117 foreach ($collection->getItems() as $item)
118 {
119 if ($location->getExternalId() === $item->getExternalId())
120 {
121 return true;
122 }
123 }
124
125 return false;
126 }
127
128 protected function chooseParentFromCollection(
130 Collection $collection,
131 Parents $parentResultCollection,
132 array $parentTypes
133 ): ?Location
134 {
135 if ($collection->count() <= 0)
136 {
137 return null;
138 }
139
140 $candidatesTypes = [];
141
142 for ($i = 0, $l = $collection->count(); $i < $l; $i++)
143 {
144 $candidate = $collection[$i];
145
146 if ($location->getExternalId() === $candidate->getExternalId())
147 {
148 continue;
149 }
150
151 $candidateType = $candidate->getType();
152
153 if ($candidateType === Location\Type::UNKNOWN)
154 {
155 continue;
156 }
157
158 if ($location->getType() !== Location\Type::UNKNOWN && $candidate->getType() >= $location->getType())
159 {
160 continue;
161 }
162
163 // check if we already have the same location in result parents collection
164 if ($this->isCollectionContainLocation($candidate, $parentResultCollection))
165 {
166 continue;
167 }
168
169 if (in_array($candidateType, $parentTypes, true))
170 {
171 return $candidate;
172 }
173
174 $candidatesTypes[] = [$i, $candidateType];
175 }
176
177 if (count($candidatesTypes) <= 0)
178 {
179 return null;
180 }
181
182 if (count($candidatesTypes) > 1)
183 {
184 $typeColumn = array_column($candidatesTypes, 1);
185 array_multisort($typeColumn, SORT_ASC, $candidatesTypes);
186 }
187
188 return $collection[$candidatesTypes[0][0]];
189 }
190
192 /*
193 * Needs tests
194 */
195 public function findParents(Location $location, string $languageId): ?Parents
196 {
197 if ($location->getSourceCode() !== self::$sourceCode || $location->getExternalId() == '')
198 {
199 return null;
200 }
201
202 $result = (new Parents())
203 ->setDescendant($location);
204
205 /* Temporary. To decrease the usage of the Google API */
206 return $result;
207 /* */
208
209 //We need full information about the location
210 $rawData = $this->find(
211 new Requesters\ByIdRequester($this->httpClient, $this->cachePool),
212 null,
213 [
214 'placeid' => $location->getExternalId(),
215 'language' => $languageId,
216 ]
217 );
218
219 $ancestorDataConverter = new Converters\AncestorDataConverter();
220 $ancestorsRawData = $ancestorDataConverter->convert($rawData, $location->getType());
221
222 //is it always available?
223 $latLon = $location->getLatitude().','.$location->getLongitude();
224
225 foreach ($ancestorsRawData as $data)
226 {
227 //Just searching by query taking into account lat and lon
228 $res = $this->find(
229 new Requesters\ByQueryRequester($this->httpClient, $this->cachePool),
230 new Converters\ByQueryConverter($languageId),
231 [
232 'query' => $data['NAME'],
233 //todo: may be restrict by several types?
234 'location' => $latLon,
235 'language' => $languageId,
236 ]
237 );
238
239 if ($res instanceof Collection && $res->count() > 0)
240 {
241 if (!($parentSource = $this->chooseParentFromCollection($location, $res, $result, $data['TYPES'])))
242 {
243 continue;
244 }
245
246 $localParent = $this->findLocalLocationByExternalId($parentSource);
247
248 //the parent location have already been saved
249 if ($localParent)
250 {
251 $result->addItem($localParent);
252
253 if ($llParents = $localParent->getParents())
254 {
255 foreach ($llParents as $localParent)
256 {
257 $result->addItem($localParent);
258 }
259 }
260
261 break;
262 }
263 else
264 {
265 //we need detailed info
266 $detailedParent = $this->findByExternalId(
267 $parentSource->getExternalId(),
268 self::$sourceCode,
269 $languageId
270 );
271
272 if ($detailedParent)
273 {
274 $result->addItem($detailedParent);
275 }
276 }
277 }
278 }
279
280 return $result;
281 }
282
289 {
290 return LocationService::getInstance()->findByExternalId(
291 $location->getExternalId(),
292 $location->getSourceCode(),
293 $location->getLanguageId(),
295 );
296 }
297
303 protected function buildFinder($requester, $converter)
304 {
305 return new Finder($requester, $converter);
306 }
307
314 protected function find($requester, $converter = null, array $findParams = [])
315 {
316 if ($this->apiKey === '')
317 {
318 throw new RuntimeException(
319 Loc::getMessage('LOCATION_ADDRESS_REPOSITORY_API_KEY_ERROR'),
321 );
322 }
323
324 $finder = $this->buildFinder($requester, $converter);
325 $findParams['key'] = $this->apiKey;
326
327 return $finder->find($findParams);
328 }
329
331 public static function getSourceCode(): string
332 {
333 return self::$sourceCode;
334 }
335}
const REPOSITORY_FIND_API_KEY_ERROR
Определения errorcodes.php:17
findParents(Location $location, string $languageId)
Определения repository.php:195
findByCoords(float $lat, float $lng, int $zoom, string $languageId)
Определения repository.php:81
isCollectionContainLocation(Location $location, Collection $collection)
Определения repository.php:115
buildFinder($requester, $converter)
Определения repository.php:303
findLocalLocationByExternalId(Location $location)
Определения repository.php:288
chooseParentFromCollection(Location $location, Collection $collection, Parents $parentResultCollection, array $parentTypes)
Определения repository.php:128
find($requester, $converter=null, array $findParams=[])
Определения repository.php:314
findByText(string $query, string $languageId)
Определения repository.php:98
findByExternalId(string $locationExternalId, string $sourceCode, string $languageId)
Определения repository.php:64
__construct(string $apiKey, HttpClient $httpClient, GoogleSource $googleSource, CachedPool $cachePool=null)
Определения repository.php:50
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$result
Определения get_property_values.php:14
$query
Определения get_search.php:11
const LOCATION_SEARCH_SCOPE_INTERNAL
Определения include.php:4
$l
Определения options.php:783
$i
Определения factura.php:643
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$location
Определения options.php:2729