<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use JsonSerializable;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Table( options={"comment":"Obsahuje dorucovani zpetne i fakturacni adresy"},
* indexes={
* @ORM\Index(name="address_name", columns={"name"}),
* @ORM\Index(name="address_address1", columns={"address1"}),
* @ORM\Index(name="address_address2", columns={"address2"}),
* @ORM\Index(name="address_zip_code", columns={"zip_code"}),
* @ORM\Index(name="address_phone", columns={"phone"}),
* @ORM\Index(name="address_email", columns={"email"})
* })
* @ORM\Entity()
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discriminator", type="string")
*/
class Address implements JsonSerializable
{
public const DEFAULT_COUNTRY_ID = 1;
public const DEFAULT_COUNTRY_ISO = 'de';
/**
* @ORM\Id()
* @ORM\GeneratedValue(strategy="IDENTITY")
* @ORM\Column( type="integer")
*/
private $id;
/**
* @Assert\NotBlank(
* message="validators.Address.country.notBlank"
* )
* @ORM\ManyToOne(targetEntity="App\Entity\Country")
* @ORM\JoinColumn( nullable=false)
*/
private $country;
/**
* @Assert\NotBlank(
* message="validators.Address.name.notBlank"
* )
* @Assert\Length(
* min = 2,
* max = 50,
* minMessage = "validators.Address.name.minMessage",
* maxMessage = "validators.Address.name.maxMessage",
* )
* @ORM\Column(type="string", length=255, options={"comment":"Jmeno zakaznika"})
*/
private $name;
/**
* @Assert\NotBlank(
* message="validators.Address.address1.notBlank"
* )
* @Assert\Length(
* min = 2,
* max = 50,
* minMessage = "validators.Address.address1.minMessage",
* maxMessage = "validators.Address.address1.maxMessage",
* )
* @ORM\Column(type="string", length=255, options={"comment":"Hlavni radek adresy (ulice a cislo)"})
*/
private $address1;
/**
* @Assert\Length(
* min = 2,
* max = 50,
* minMessage = "validators.Address.address1.minMessage",
* maxMessage = "validators.Address.address1.maxMessage",
* )
* @ORM\Column(type="string", length=255, nullable=true, options={"comment":"Dodatecny radek adresy (firma, byt)"})
*/
private $address2;
/**
* @Assert\NotBlank(
* message="validators.Address.zipCode.notBlank"
* )
* @Assert\Length(
* min = 4,
* max = 6,
* minMessage = "validators.Address.zipCode.minMessage",
* maxMessage = "validators.Address.zipCode.maxMessage",
* )
* @Assert\Regex(
* pattern="/^[a-zA-Z\s\d\-,]+$/",
* message="validators.Address.zipcode.regex"
* )
* @ORM\Column(type="string", length=10, options={"comment":"Postovni smerovaci cislo nebo ekvivalent"})
*/
private $zipCode;
/**
* @Assert\NotBlank(
* message="validators.Address.phone.notBlank"
* )
* @Assert\Regex(
* pattern="/^\+?[\d\s\.\-\*\#\(\)\\\/]{6,20}$/",
* message="validators.Address.phone.regex"
* )
* @ORM\Column(type="string", length=18, options={"comment":"Telefonni cislo koncoveho zakaznika"})
*/
private $phone;
/**
* @Assert\Email(
* message="validators.Address.email.email"
* )
/**
* @ORM\Column(type="string", length=255, nullable=true, options={"comment":"emailova adresa"})
*/
private $email;
/**
* @ORM\Column(type="string", length=255, nullable=true, options={"comment":"Pojmenovani pro ulozene adresy"})
*/
private $alias;
/**
* @Assert\NotBlank(
* message="validators.Address.city.notBlank"
* )
* @Assert\Length(
* min = 2,
* max = 50,
* minMessage = "validators.Address.city.minMessage",
* maxMessage = "validators.Address.city.maxMessage",
* )
* @ORM\Column(type="string", length=64, options={"comment":"Mesto"})
*/
private $city;
/**
* @Assert\Length(
* min = 2,
* max = 63,
* minMessage = "validators.Address.district.minMessage",
* maxMessage = "validators.Address.district.maxMessage",
* )
* @ORM\Column(type="string", length=63, nullable=true, options={"comment":"Městská čtvrť"})
*/
private $district;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName($name): self
{
$this->name = trim($name);
return $this;
}
public function getAddress1(): ?string
{
return $this->address1;
}
public function setAddress1(string $address1): self
{
$this->address1 = trim($address1);
return $this;
}
public function getAddress2(): ?string
{
return $this->address2;
}
public function setAddress2($address2): self
{
$this->address2 = $address2;
return $this;
}
public function getZipCode(): ?string
{
return $this->zipCode;
}
public function setZipCode($zipCode): self
{
$this->zipCode = mb_ereg_replace('\s+', '', $zipCode);
return $this;
}
public function getPhone(): ?string
{
return $this->phone;
}
public function setPhone($phone): self
{
$this->phone = mb_ereg_replace('\s+', '', $phone);
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail($email): self
{
$this->email = trim($email);
return $this;
}
public function getAlias(): ?string
{
return $this->alias;
}
public function setAlias($alias): self
{
$this->alias = $alias;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity($city): self
{
$this->city = trim($city);
return $this;
}
public function getDistrict(): ?string
{
return $this->district;
}
public function setDistrict($district): self
{
$this->district = $district;
return $this;
}
public function getCountry(): ?Country
{
return $this->country;
}
public function setCountry($country): self
{
$this->country = $country;
return $this;
}
/**
* pomocna funkce k vytvoreni adresy
* @param string $name
* @param string $address1
* @param string|null $address2
* @param string $city
* @param string $zipCode
* @param Country|int $country
* @param string $phone
* @param string|null $email
*
* @return self
*/
public static function createNewAddress(
string $name,
string $address1,
string $city,
string $zipCode,
Country|int $country,
string $phone,
string|null $address2 = null,
string|null $email = null,
): self {
$address = new self();
$address->setName($name);
$address->setAddress1($address1);
!$address2 ?: $address->setAddress2($address2);
$address->setCity($city);
$address->setZipCode($zipCode);
$address->setCountry($country);
$address->setPhone($phone);
!$email ?: $address->setEmail($email);
return $address;
}
public function jsonSerialize(): mixed
{
return [
'name' => $this->name,
'address1' => $this->address1,
'address2' => $this->address2,
'city' => $this->city,
'district' => $this->district,
'zipCode' => $this->zipCode,
'country' => $this->country->getIso3(),
];
}
/**
* Pokusi se extrahovat jmeno ulice z adresy
* Pozor ma to jista omezeni viz AddressTest::getTestDataAddress1
* @return string
*/
public function getStreet(): string
{
return $this->divideStreetAndHouseNumber($this->getAddress1())[0];
}
/**
* zkopirovano z CME
* vrací pole o třech prvcích [0] => ulice, [1] => číslo popisne, [2] => číslo orientacni
* matchuje podle predpokladu:
* - ulice neni povinna (male vsi bez ulic)
* - ulice muze obsahovat cislice (17. listopadu)
* - pokud ulice obsahuje carku nebo lomitko, text pred nimi se ignoruje (prum. areal Kyblov, Zelena 11 )
* - pokud je carka nebo strednik mezi ulici a cislem, ignoruje se
* - pokud je za ulici jen jedno cislo, je to cislo orientacni (posta si to umi prehodit)
* - za orientacnim cislem muze nasledovat jedno pismeno (vchod)
* - dalsi text za cislem domu se ignoruje (obvykle patro, cislo bytu etc)
* - okolostojici mezery se zahazuji
* - kdyz se nezadari, vrati se cely vstup jako ulice
*
* @param null|string $bothData
* @param bool $splitHouseNumberData pokud je true, vrací pole o dvou prvcích [0] => ulice, [1] => číslo
* @return array<string>
*/
public function divideStreetAndHouseNumber(?string $bothData, bool $splitHouseNumberData = true): array
{
if (!$bothData) {
$bothData = '';
}
// nejdriv zkusime samotna cisla
if (preg_match('~^\s*((?P<cp>[0-9]+)\s*/\s*)?(?P<co>[0-9]+[a-zA-Z]?)\s*$~', $bothData, $matches)) {
$return = array('', $matches['cp'], $matches['co']);
} elseif (preg_match('~\s*(?P<ulice>[^/,]+)\s*[,;]?\s+((?P<cp>[0-9]+)\s*/\s*)?(?P<co>[0-9]+[a-zA-Z]?)~', $bothData, $matches)) {
$return = array(trim($matches['ulice']), $matches['cp'], $matches['co']);
} else {
$return = array($bothData, '', '');
}
if (!$splitHouseNumberData) {
if ($return[1] && $return[2]) {
$houseNumber = $return[1] . "/" . $return[2];
} elseif ($return[1] || $return[2]) {
//jedno z polí je prázdné
$houseNumber = $return[1] . $return[2];
} else {
$houseNumber = '';
}
return array($return[0], $houseNumber);
}
return $return;
}
}