403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/location/lib/source/google/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/location/lib/source/google/repository.php
<?php

namespace Bitrix\Location\Source\Google;

use Bitrix\Location\Entity\Location;
use Bitrix\Location\Entity\Generic\Collection;
use Bitrix\Location\Entity\Location\Parents;
use Bitrix\Location\Exception\RuntimeException;
use Bitrix\Location\Repository\Location\Capability\IFindByCoords;
use Bitrix\Location\Repository\Location\Capability\IFindByExternalId;
use Bitrix\Location\Repository\Location\Capability\IFindByText;
use Bitrix\Location\Repository\Location\Capability\IFindParents;
use Bitrix\Location\Repository\Location\IRepository;
use Bitrix\Location\Repository\Location\ISource;
use Bitrix\Location\Service\LocationService;
use Bitrix\Location\Source\BaseRepository;
use Bitrix\Location\Source\Google\Converters;
use Bitrix\Location\Source\Google\Converters\BaseConverter;
use Bitrix\Location\Source\Google\Requesters;
use Bitrix\Location\Source\Google\Requesters\BaseRequester;
use \Bitrix\Location\Common\CachedPool;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Web\HttpClient;

Loc::loadMessages(__FILE__);

/**
 * Class Google
 * @package Bitrix\Location\Source
 */
class Repository extends BaseRepository implements
	IRepository,
	IFindByExternalId,
	IFindByCoords,
	IFindByText,
	IFindParents,
	ISource
{
	/** @var string  */
	protected $apiKey = '';
	/** @var string  */
	protected static $sourceCode = 'GOOGLE';
	/** @var HttpClient  */
	protected $httpClient = null;
	/** @var CachedPool */
	protected $cachePool = null;
	/** @var GoogleSource  */
	protected $googleSource = null;

	public function __construct(
		string $apiKey,
		HttpClient $httpClient,
		GoogleSource $googleSource,
		CachedPool $cachePool = null
	)
	{
		$this->apiKey = $apiKey;
		$this->httpClient = $httpClient;
		$this->cachePool = $cachePool;
		$this->googleSource = $googleSource;
	}

	/** @inheritDoc */
	public function findByExternalId(string $locationExternalId, string $sourceCode, string $languageId)
	{
		if ($sourceCode !== self::$sourceCode || $locationExternalId === '')
		{
			return null;
		}

		return $this->find(
			new Requesters\ByIdRequester($this->httpClient, $this->cachePool),
			new Converters\ByIdConverter($languageId),
			[
				'placeid' => $locationExternalId,
				'language' => $this->googleSource->convertLang($languageId),
			]
		);
	}

	public function findByCoords(float $lat, float $lng, int $zoom, string $languageId): ?Location
	{
		$foundLocations = $this->find(
			new Requesters\ByCoordsRequester($this->httpClient, $this->cachePool),
			new Converters\ByCoordsConverter($languageId),
			[
				'latlng' => implode(',', [$lat, $lng]),
				'language' => $this->googleSource->convertLang($languageId),
			]
		);

		return $foundLocations[0] ?? null;
	}

	/**
	 * @inheritDoc
	 */
	public function findByText(string $query, string $languageId)
	{
		if ($query == '')
		{
			return null;
		}

		return $this->find(
			new Requesters\ByQueryRequester($this->httpClient, $this->cachePool),
			new Converters\ByQueryConverter($languageId),
			[
				'query' => $query,
				'language' => $this->googleSource->convertLang($languageId)
			]
		);
	}

	protected function isCollectionContainLocation(Location $location, Collection $collection): bool
	{
		foreach ($collection->getItems() as $item)
		{
			if ($location->getExternalId() === $item->getExternalId())
			{
				return true;
			}
		}

		return false;
	}

	protected function chooseParentFromCollection(
		Location $location,
		Collection $collection,
		Parents $parentResultCollection,
		array $parentTypes
	): ?Location
	{
		if ($collection->count() <= 0)
		{
			return null;
		}

		$candidatesTypes = [];

		for ($i = 0, $l = $collection->count(); $i < $l; $i++)
		{
			$candidate = $collection[$i];

			if ($location->getExternalId() === $candidate->getExternalId())
			{
				continue;
			}

			$candidateType = $candidate->getType();

			if ($candidateType === Location\Type::UNKNOWN)
			{
				continue;
			}

			if ($location->getType() !== Location\Type::UNKNOWN && $candidate->getType() >= $location->getType())
			{
				continue;
			}

			// check if we already have the same location in result parents collection
			if ($this->isCollectionContainLocation($candidate, $parentResultCollection))
			{
				continue;
			}

			if (in_array($candidateType, $parentTypes, true))
			{
				return $candidate;
			}

			$candidatesTypes[] = [$i, $candidateType];
		}

		if (count($candidatesTypes) <= 0)
		{
			return null;
		}

		if (count($candidatesTypes) > 1)
		{
			$typeColumn = array_column($candidatesTypes, 1);
			array_multisort($typeColumn, SORT_ASC, $candidatesTypes);
		}

		return $collection[$candidatesTypes[0][0]];
	}

	/** @inheritDoc */
	/*
	 * Needs tests
	 */
	public function findParents(Location $location, string $languageId): ?Parents
	{
		if ($location->getSourceCode() !== self::$sourceCode || $location->getExternalId() == '')
		{
			return null;
		}

		$result = (new Parents())
			->setDescendant($location);

		/* Temporary. To decrease the usage of the Google API */
		return $result;
		/* */

		//We need full information about the location
		$rawData = $this->find(
			new Requesters\ByIdRequester($this->httpClient, $this->cachePool),
			null,
			[
				'placeid' => $location->getExternalId(),
				'language' => $languageId,
			]
		);

		$ancestorDataConverter = new Converters\AncestorDataConverter();
		$ancestorsRawData = $ancestorDataConverter->convert($rawData, $location->getType());

		//is it always available?
		$latLon = $location->getLatitude().','.$location->getLongitude();

		foreach ($ancestorsRawData as $data)
		{
			//Just searching by query taking into account lat and lon
			$res = $this->find(
				new Requesters\ByQueryRequester($this->httpClient, $this->cachePool),
				new Converters\ByQueryConverter($languageId),
				[
					'query' => $data['NAME'],
					//todo: may be restrict by several types?
					'location' => $latLon,
					'language' => $languageId,
				]
			);

			if ($res instanceof Collection && $res->count() > 0)
			{
				if (!($parentSource = $this->chooseParentFromCollection($location, $res, $result, $data['TYPES'])))
				{
					continue;
				}

				$localParent = $this->findLocalLocationByExternalId($parentSource);

				//the parent location have already been saved
				if ($localParent)
				{
					$result->addItem($localParent);

					if ($llParents = $localParent->getParents())
					{
						foreach ($llParents as $localParent)
						{
							$result->addItem($localParent);
						}
					}

					break;
				}
				else
				{
					//we need detailed info
					$detailedParent = $this->findByExternalId(
						$parentSource->getExternalId(),
						self::$sourceCode,
						$languageId
					);

					if ($detailedParent)
					{
						$result->addItem($detailedParent);
					}
				}
			}
		}

		return $result;
	}

	/**
	 * @param Location $location
	 * @return Location|bool|null
	 * todo: maybe carry out?
	 */
	protected function findLocalLocationByExternalId(Location $location)
	{
		return LocationService::getInstance()->findByExternalId(
			$location->getExternalId(),
			$location->getSourceCode(),
			$location->getLanguageId(),
			LOCATION_SEARCH_SCOPE_INTERNAL,
		);
	}

	/**
	 * @param Requesters\BaseRequester $requester
	 * @param Converters\BaseConverter $converter
	 * @return Finder
	 */
	protected function buildFinder($requester, $converter)
	{
		return new Finder($requester, $converter);
	}

	/**
	 * @param BaseRequester $requester`
	 * @param BaseConverter $converter
	 * @param array $findParams
	 * @return Location|Collection|false|null|array
	 */
	protected function find($requester,  $converter = null, array $findParams = [])
	{
		if ($this->apiKey === '')
		{
			throw new RuntimeException(
				Loc::getMessage('LOCATION_ADDRESS_REPOSITORY_API_KEY_ERROR'),
				ErrorCodes::REPOSITORY_FIND_API_KEY_ERROR
			);
		}

		$finder = $this->buildFinder($requester, $converter);
		$findParams['key'] = $this->apiKey;

		return $finder->find($findParams);
	}

	/** @inheritDoc */
	public static function getSourceCode(): string
	{
		return self::$sourceCode;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit