Your IP : 18.219.89.207


Current Path : /var/www/axolotl/data/www/murmansk.axolotls.ru/bitrix/modules/location/lib/entity/
Upload File :
Current File : /var/www/axolotl/data/www/murmansk.axolotls.ru/bitrix/modules/location/lib/entity/address.php

<?php

namespace Bitrix\Location\Entity;

use Bitrix\Location\Common\IPoint;
use Bitrix\Location\Entity\Address\AddressLink;
use Bitrix\Location\Entity\Address\AddressLinkCollection;
use Bitrix\Location\Entity\Address\Converter\ArrayConverter;
use Bitrix\Location\Entity\Address\Converter\StringConverter;
use Bitrix\Location\Entity\Address\Field;
use Bitrix\Location\Entity\Address\FieldCollection;
use Bitrix\Location\Service\AddressService;
use Bitrix\Main\ArgumentNullException;
use Bitrix\Main\ORM\Data\DeleteResult;
use Bitrix\Main\SystemException;
use Bitrix\Main\Web\Json;

/**
 * Class Address
 * @package Bitrix\Location\Entity
 */
final class Address implements IPoint
{
	/** @var int  */
	private $id = 0;
	/** @var string */
	private $languageId;
	/** @var string  */
	protected $latitude = '';
	/** @var string  */
	protected $longitude = '';
	/** @var Location  */
	private $location;
	/** @var FieldCollection */
	private $fieldCollection;
	/** @var AddressLinkCollection */
	private $linkCollection = null;

	/**
	 * Address constructor.
	 * @param string $languageId
	 */
	public function __construct(string $languageId)
	{
		$this->languageId = $languageId;
		$this->fieldCollection = new FieldCollection();
		$this->linkCollection = new AddressLinkCollection();
	}

	/**
	 * @return int
	 */
	public function getId(): int
	{
		return $this->id;
	}

	/**
	 * @param int $id
	 * @return $this
	 */
	public function setId(int $id): Address
	{
		$this->id = $id;
		return $this;
	}
	
	/**
	 * @return string
	 */
	public function getLatitude(): string
	{
		return $this->latitude;
	}

	/**
	 * @param string $latitude
	 * @return Address
	 */
	public function setLatitude(string $latitude): Address
	{
		$this->latitude = $latitude;
		return $this;
	}

	/**
	 * @return string
	 */
	public function getLongitude(): string
	{
		return $this->longitude;
	}

	/**
	 * @param string $longitude
	 * @return Address
	 */
	public function setLongitude(string $longitude): Address
	{
		$this->longitude = $longitude;
		return $this;
	}

	/**
	 * @return string
	 */
	public function getLanguageId(): string
	{
		return $this->languageId;
	}

	/**
	 * @return FieldCollection
	 */
	public function getFieldCollection(): FieldCollection
	{
		return $this->fieldCollection;
	}

	/**
	 * @return Location
	 */
	public function getLocation():? Location
	{
		return $this->location;
	}

	/**
	 * @param Location|null $location
	 * @return self
	 */
	public function setLocation(?Location $location): self
	{
		if($location)
		{
			foreach($this->getFieldCollection()->getItems() as $idx => $item)
			{
				$itemType = $item->getType();

				if($location->getType() === $itemType) //|| (bool)$location->getParentByType($itemType)
				{
					$this->getFieldCollection()->offsetUnset($idx);
				}
			}
		}

		//todo: may be copy fields values to address from the location before the unsetting? ($location === null)
		$this->location = $location;
		return $this;
	}

	/**
	 * @param int $type
	 * @param $value
	 * @return $this
	 */
	public function setFieldValue(int $type, $value): self
	{
		//todo: here the behavior seems strange. What we can do? Exception? Return false?
		if(!$this->isFieldWritable($type))
		{
			return $this;
		}

		if($field = $this->getFieldCollection()->getItemByType($type))
		{
			$field->setValue($value);
		}
		else
		{
			$this->fieldCollection->addItem(
				(new Field($type))
					->setValue($value)
			);
		}

		return $this;
	}

	/**
	 * @return array
	 */
	public function getAllFieldsValues(): array
	{
		$result = [];

		foreach ($this->getFieldCollection() as $field)
		{
			$result[$field->getType()] = $field->getValue();
		}

		if($this->location)
		{
			$result[$this->location->getType()] = $this->location->getName();

			if($parents = $this->location->getParents())
			{
				foreach ($parents as $parent)
				{
					$result[$parent->getType()] = $parent->getName();
				}
			}
		}

		return $result;
	}

	/**
	 * @param int $type
	 * @return string|null
	 */
	public function getFieldValue(int $type): ?string
	{
		$result = null;

		if($this->isFieldValueStoredInLocation($type))
		{
			$result = $this->getFieldValueFromLocation($type);
		}
		elseif($field = $this->getFieldCollection()->getItemByType($type))
		{
			$result = $field->getValue();
		}

		return $result;
	}

	public function isFieldWritable(int $type): bool
	{
		return !$this->isFieldValueStoredInLocation($type);
	}

	private function isFieldValueStoredInLocation(int $type): bool
	{
		if(!($location = $this->getLocation()))
		{
			$result =  false;
		}
		elseif($location->getType() === $type)
		{
			$result = true;
		}
		else
		{
			$result = $location->getParentByType($type) ? true : false;
		}

		return $result;
	}

	private function getFieldValueFromLocation(int $type):? string
	{
		if(!$this->isFieldValueStoredInLocation($type))
		{
			throw new SystemException('We need check that the field value for sure is storied in location');
		}

		$result = null;

		if($location = $this->getLocation())
		{
			if($location->getType() === $type)
			{
				$result = $location->getName();
			}
			elseif($location->isFieldExist($type))
			{
				$result = $location->getFieldValue($type);
			}
			elseif($parent = $location->getParentByType($type))
			{
				$result = $parent->getName();
			}
		}

		return $result;
	}

	/**
	 * @param int $type
	 * @return bool
	 */
	public function isFieldExist(int $type): bool
	{
		$result = (bool)$this->getFieldCollection()->getItemByType($type);

		if(!$result && $this->location)
		{
			$result = (bool)$this->location->getParentByType($type);
		}

		return $result;
	}

	/**
	 * @param int $id
	 * @return Address|bool|null
	 * @throws SystemException
	 * @throws \Bitrix\Main\ArgumentException
	 * @throws \Bitrix\Main\ObjectPropertyException
	 */
	public static function load(int $id)
	{
		return AddressService::getInstance()->findById($id);
	}

	/**
	 * @return \Bitrix\Main\ORM\Data\AddResult|\Bitrix\Main\ORM\Data\Result|\Bitrix\Main\ORM\Data\UpdateResult
	 */
	public function save()
	{
		return AddressService::getInstance()->save($this);
	}

	/**
	 * @return \Bitrix\Main\ORM\Data\DeleteResult
	 * @throws \Exception
	 */
	public function delete(): DeleteResult
	{
		return AddressService::getInstance()->delete($this->getId());
	}

	/**
	 * @return string Json
	 * @throws \Bitrix\Main\ArgumentException
	 */
	public function toJson(): string
	{
		return Json::encode(ArrayConverter::convertToArray($this));
	}

	/**
	 * @return array
	 */
	public function toArray(): array
	{
		return ArrayConverter::convertToArray($this);
	}

	/**
	 * @param string $jsonData
	 * @return Address
	 * @throws \Bitrix\Main\ArgumentException
	 */
	public static function fromJson($jsonData): Address
	{
		return ArrayConverter::convertFromArray(Json::decode($jsonData));
	}

	/**
	 * @param array $arrayData
	 * @return Address
	 */
	public static function fromArray(array $arrayData): Address
	{
		return ArrayConverter::convertFromArray($arrayData);
	}

	/**
	 * @param AddressLinkCollection $collection
	 */
	public function setLinks(AddressLinkCollection $collection): void
	{
		$this->linkCollection = $collection;
	}

	/**
	 * @return AddressLinkCollection
	 */
	public function getLinks(): AddressLinkCollection
	{
		return $this->linkCollection;
	}

	/**
	 * Removes all links
	 */
	public function clearLinks(): void
	{
		$this->linkCollection->clear();
	}

	/**
	 * Link entity to address
	 * @param string $entityId
	 * @param string $entityType
	 */
	public function addLink(string $entityId, string $entityType): void
	{
		if($entityId == '')
		{
			throw new ArgumentNullException('entityId');
		}

		if($entityType == '')
		{
			throw new ArgumentNullException('entityType');
		}

		$this->linkCollection->addItem(
			new AddressLink($entityId, $entityType)
		);
	}

	/**
	 * Returns information is Address has links or not
	 * @return bool
	 */
	public function hasLinks(): bool
	{
		return $this->linkCollection->count() > 0;
	}

	/**
	 * Converts Address to String
	 * @param Format $format
	 * @param string $strategyType
	 * @param string $contentType
	 * @return string
	 */
	public function toString(
		Format $format,
		string $strategyType = StringConverter::STRATEGY_TYPE_TEMPLATE,
		string $contentType = StringConverter::CONTENT_TYPE_HTML
	): string
	{
		return StringConverter::convertToString($this, $format, $strategyType, $contentType);
	}
}