classes/XLite/Model/Zone.php line 16

Open in your IDE?
  1. <?php
  2. /**
  3.  * Copyright (c) 2011-present Qualiteam software Ltd. All rights reserved.
  4.  * See https://www.x-cart.com/license-agreement.html for license details.
  5.  */
  6. namespace XLite\Model;
  7. use Doctrine\ORM\Mapping as ORM;
  8. /**
  9.  * Zone model
  10.  *
  11.  * @ORM\Entity
  12.  * @ORM\Table  (name="zones",
  13.  *      indexes={
  14.  *          @ORM\Index (name="zone_name", columns={"zone_name"}),
  15.  *          @ORM\Index (name="zone_default", columns={"is_default"})
  16.  *      }
  17.  * )
  18.  */
  19. class Zone extends \XLite\Model\AEntity
  20. {
  21.     /**
  22.      * Zone unique id
  23.      *
  24.      * @var integer
  25.      *
  26.      * @ORM\Id
  27.      * @ORM\GeneratedValue (strategy="AUTO")
  28.      * @ORM\Column         (type="integer")
  29.      */
  30.     protected $zone_id;
  31.     /**
  32.      * Zone name
  33.      *
  34.      * @var string
  35.      *
  36.      * @ORM\Column (type="string", length=64)
  37.      */
  38.     protected $zone_name '';
  39.     /**
  40.      * Zone default flag
  41.      *
  42.      * @var integer
  43.      *
  44.      * @ORM\Column (type="boolean")
  45.      */
  46.     protected $is_default false;
  47.     /**
  48.      * Zone elements (relation)
  49.      *
  50.      * @var \Doctrine\Common\Collections\ArrayCollection
  51.      *
  52.      * @ORM\OneToMany (targetEntity="XLite\Model\ZoneElement", mappedBy="zone", cascade={"all"})
  53.      */
  54.     protected $zone_elements;
  55.     /**
  56.      * Shipping rates (relation)
  57.      *
  58.      * @var \Doctrine\Common\Collections\ArrayCollection
  59.      *
  60.      * @ORM\OneToMany (targetEntity="XLite\Model\Shipping\Markup", mappedBy="zone", cascade={"all"})
  61.      */
  62.     protected $shipping_markups;
  63.     /**
  64.      * Comparison states function for usort()
  65.      *
  66.      * @param \XLite\Model\State $a First state object
  67.      * @param \XLite\Model\State $b Second state object
  68.      *
  69.      * @return integer
  70.      */
  71.     public static function sortStates($a$b)
  72.     {
  73.         $aCountry $a->getCountry()->getCountry();
  74.         $aState $a->getState();
  75.         $bCountry $b->getCountry()->getCountry();
  76.         $bState $b->getState();
  77.         if ($aCountry == $bCountry && $aState == $bState) {
  78.             $result 0;
  79.         } elseif ($aCountry == $bCountry) {
  80.             $result = ($aState $bState) ? : -1;
  81.         } else {
  82.             $result = ($aCountry $bCountry) ? : -1;
  83.         }
  84.         return $result;
  85.     }
  86.     /**
  87.      * Constructor
  88.      *
  89.      * @param array $data Entity properties OPTIONAL
  90.      *
  91.      * @return void
  92.      */
  93.     public function __construct(array $data = [])
  94.     {
  95.         $this->zone_elements    = new \Doctrine\Common\Collections\ArrayCollection();
  96.         $this->shipping_markups = new \Doctrine\Common\Collections\ArrayCollection();
  97.         parent::__construct($data);
  98.     }
  99.     /**
  100.      * Get zone's countries list
  101.      *
  102.      * @param boolean $excluded Flag: true - get countries except zone countries OPTIONAL
  103.      *
  104.      * @return array
  105.      */
  106.     public function getZoneCountries($excluded false)
  107.     {
  108.         $zoneCountries = [];
  109.         $countryCodes  $this->getElementsByType(\XLite\Model\ZoneElement::ZONE_ELEMENT_COUNTRY);
  110.         if (!empty($countryCodes) || $excluded) {
  111.             $allCountries \XLite\Core\Database::getRepo('XLite\Model\Country')->findAllCountries();
  112.             foreach ($allCountries as $country) {
  113.                 $condition in_array($country->getCode(), $countryCodes);
  114.                 if (
  115.                     ($condition && !$excluded)
  116.                     || (!$condition && $excluded)
  117.                 ) {
  118.                     $zoneCountries[] = $country;
  119.                 }
  120.             }
  121.         }
  122.         return $zoneCountries;
  123.     }
  124.     /**
  125.      * Get zone's states list
  126.      *
  127.      * @param boolean $excluded Flag: true - get states except zone states OPTIONAL
  128.      *
  129.      * @return array
  130.      */
  131.     public function getZoneStates($excluded false)
  132.     {
  133.         $zoneStates = [];
  134.         $stateCodes $this->getElementsByType(\XLite\Model\ZoneElement::ZONE_ELEMENT_STATE);
  135.         if (!empty($stateCodes) || $excluded) {
  136.             $allStates \XLite\Core\Database::getRepo('XLite\Model\State')->findAllStates();
  137.             usort($allStates, ['\XLite\Model\Zone''sortStates']);
  138.             foreach ($allStates as $state) {
  139.                 $condition in_array($state->getCountry()->getCode() . '_' $state->getCode(), $stateCodes);
  140.                 if (
  141.                     ($condition && !$excluded)
  142.                     || (!$condition && $excluded)
  143.                 ) {
  144.                     $zoneStates[] = $state;
  145.                 }
  146.             }
  147.         }
  148.         return $zoneStates;
  149.     }
  150.     /**
  151.      * Get zone's city masks list
  152.      *
  153.      * @param boolean $asString As string OPTIONAL
  154.      *
  155.      * @return array|string
  156.      */
  157.     public function getZoneCities($asString false)
  158.     {
  159.         $elements $this->getElementsByType(\XLite\Model\ZoneElement::ZONE_ELEMENT_TOWN);
  160.         return $asString ? (!empty($elements) ? implode(PHP_EOL$elements) : '') : $elements;
  161.     }
  162.     /**
  163.      * Get zone's zip code masks list
  164.      *
  165.      * @param boolean $asString As string OPTIONAL
  166.      *
  167.      * @return array|string
  168.      */
  169.     public function getZoneZipCodes($asString false)
  170.     {
  171.         $elements $this->getElementsByType(\XLite\Model\ZoneElement::ZONE_ELEMENT_ZIPCODE);
  172.         return $asString ? (!empty($elements) ? implode(PHP_EOL$elements) : '') : $elements;
  173.     }
  174.     /**
  175.      * Get zone's address masks list
  176.      *
  177.      * @param boolean $asString As string OPTIONAL
  178.      *
  179.      * @return array|string
  180.      */
  181.     public function getZoneAddresses($asString false)
  182.     {
  183.         $elements $this->getElementsByType(\XLite\Model\ZoneElement::ZONE_ELEMENT_ADDRESS);
  184.         return $asString ? (!empty($elements) ? implode(PHP_EOL$elements) : '') : $elements;
  185.     }
  186.     /**
  187.      * hasZoneElements
  188.      *
  189.      * @return boolean
  190.      */
  191.     public function hasZoneElements()
  192.     {
  193.         return count($this->getZoneElements());
  194.     }
  195.     /**
  196.      * Returns the list of zone elements by specified element type
  197.      *
  198.      * @param string $elementType Element type
  199.      *
  200.      * @return array
  201.      */
  202.     public function getElementsByType($elementType)
  203.     {
  204.         $result = [];
  205.         if ($this->hasZoneElements()) {
  206.             foreach ($this->getZoneElements() as $element) {
  207.                 if ($elementType == $element->getElementType()) {
  208.                     $result[] = trim($element->getElementValue());
  209.                 }
  210.             }
  211.         }
  212.         return $result;
  213.     }
  214.     /**
  215.      * getZoneWeight
  216.      *
  217.      * @param mixed $address Address
  218.      *
  219.      * @return integer
  220.      */
  221.     public function getZoneWeight($address)
  222.     {
  223.         $zoneWeight 0;
  224.         $elementTypesData \XLite\Model\ZoneElement::getElementTypesData();
  225.         if ($this->hasZoneElements()) {
  226.             foreach ($elementTypesData as $type => $data) {
  227.                 $checkFuncName 'checkZone' $data['funcSuffix'];
  228.                 // Get zone elements
  229.                 $elements $this->getElementsByType($type);
  230.                 if (!empty($elements)) {
  231.                     // Check if address field belongs to the elements
  232.                     $found $this->$checkFuncName($address$elements);
  233.                     if ($found) {
  234.                         // Increase the total zone weight
  235.                         $zoneWeight += $data['weight'];
  236.                     } elseif ($data['required']) {
  237.                         // Break the comparing
  238.                         $zoneWeight 0;
  239.                         break;
  240.                     }
  241.                 }
  242.             }
  243.             if ($zoneWeight) {
  244.                 $zoneWeight++;
  245.             }
  246.         } else {
  247.             $zoneWeight 1;
  248.         }
  249.         return $zoneWeight;
  250.     }
  251.     /**
  252.      * checkZoneCountries
  253.      *
  254.      * @param mixed $address  Address
  255.      * @param mixed $elements Elements
  256.      *
  257.      * @return boolean
  258.      */
  259.     protected function checkZoneCountries($address$elements)
  260.     {
  261.         return !empty($elements)
  262.             && isset($address['country'])
  263.             && in_array($address['country'], $elements);
  264.     }
  265.     /**
  266.      * checkZoneStates
  267.      *
  268.      * @param mixed $address  Address
  269.      * @param mixed $elements Elements
  270.      *
  271.      * @return boolean
  272.      */
  273.     protected function checkZoneStates($address$elements)
  274.     {
  275.         $found false;
  276.         $need = !empty($elements);
  277.         if (
  278.             $need
  279.             && isset($address['country'])
  280.         ) {
  281.             $need false;
  282.             /** @var \XLite\Model\Country $countryObj */
  283.             $countryObj \XLite\Core\Database::getRepo('XLite\Model\Country')->findOneByCode(
  284.                 $address['country']
  285.             );
  286.             $hasStates $countryObj && $countryObj->hasStates();
  287.             $state = isset($address['state']) && $hasStates
  288.                 $address['state']
  289.                 : '';
  290.             if (!$state) {
  291.                 $stateObj \XLite\Core\Database::getRepo('XLite\Model\State')->findOneBy([
  292.                     'state'   => $address['custom_state'],
  293.                     'country' => $countryObj,
  294.                 ]);
  295.                 $state $stateObj
  296.                     $stateObj->getCode()
  297.                     : '';
  298.             }
  299.             foreach ($elements as $code) {
  300.                 if ($code === $address['country'] . '_' $state) {
  301.                     $found true;
  302.                     break;
  303.                 } elseif (strpos($code$address['country'] . '_') === 0) {
  304.                     $need true;
  305.                 }
  306.             }
  307.         }
  308.         return $found || !$need;
  309.     }
  310.     /**
  311.      * checkZoneZipCodes
  312.      *
  313.      * @param mixed $address  Address
  314.      * @param mixed $elements Elements
  315.      *
  316.      * @return boolean
  317.      */
  318.     protected function checkZoneZipCodes($address$elements)
  319.     {
  320.         return empty($elements)
  321.             || (
  322.                 isset($address['zipcode'])
  323.                 && $this->checkMasks($address['zipcode'], $elements)
  324.             );
  325.     }
  326.     /**
  327.      * checkZoneCities
  328.      *
  329.      * @param mixed $address  Address
  330.      * @param mixed $elements Elements
  331.      *
  332.      * @return boolean
  333.      */
  334.     protected function checkZoneCities($address$elements)
  335.     {
  336.         return empty($elements)
  337.             || (
  338.                 isset($address['city'])
  339.                 && $this->checkMasks($address['city'], $elements)
  340.             );
  341.     }
  342.     /**
  343.      * checkZoneAddresses
  344.      *
  345.      * @param mixed $address  Address
  346.      * @param mixed $elements Elements
  347.      *
  348.      * @return boolean
  349.      */
  350.     protected function checkZoneAddresses($address$elements)
  351.     {
  352.         return empty($elements)
  353.             || (
  354.                 isset($address['address'])
  355.                 && $this->checkMasks($address['address'], $elements)
  356.             );
  357.     }
  358.     /**
  359.      * checkMasks
  360.      *
  361.      * @param mixed $value     Value
  362.      * @param mixed $masksList Mask list
  363.      *
  364.      * @return boolean
  365.      */
  366.     protected function checkMasks($value$masksList)
  367.     {
  368.         $found false;
  369.         foreach ($masksList as $mask) {
  370.             $mask str_replace([
  371.                 '%',
  372.                 '\?',
  373.             ], [
  374.                 '.*',
  375.                 '.',
  376.             ], preg_quote($mask));
  377.             if (preg_match('/^' $mask '$/i'$value)) {
  378.                 $found true;
  379.                 break;
  380.             }
  381.         }
  382.         return $found;
  383.     }
  384.     /**
  385.      * Get zone_id
  386.      *
  387.      * @return integer
  388.      */
  389.     public function getZoneId()
  390.     {
  391.         return $this->zone_id;
  392.     }
  393.     /**
  394.      * Set zone_name
  395.      *
  396.      * @param string $zoneName
  397.      * @return Zone
  398.      */
  399.     public function setZoneName($zoneName)
  400.     {
  401.         $this->zone_name $zoneName;
  402.         return $this;
  403.     }
  404.     /**
  405.      * Get zone_name
  406.      *
  407.      * @return string
  408.      */
  409.     public function getZoneName()
  410.     {
  411.         return $this->zone_name;
  412.     }
  413.     /**
  414.      * Set is_default
  415.      *
  416.      * @param boolean $isDefault
  417.      * @return Zone
  418.      */
  419.     public function setIsDefault($isDefault)
  420.     {
  421.         $this->is_default $isDefault;
  422.         return $this;
  423.     }
  424.     /**
  425.      * Get is_default
  426.      *
  427.      * @return boolean
  428.      */
  429.     public function getIsDefault()
  430.     {
  431.         return $this->is_default;
  432.     }
  433.     /**
  434.      * Add zone_elements
  435.      *
  436.      * @param \XLite\Model\ZoneElement $zoneElements
  437.      * @return Zone
  438.      */
  439.     public function addZoneElements(\XLite\Model\ZoneElement $zoneElements)
  440.     {
  441.         $this->zone_elements[] = $zoneElements;
  442.         return $this;
  443.     }
  444.     /**
  445.      * Get zone_elements
  446.      *
  447.      * @return \Doctrine\Common\Collections\Collection
  448.      */
  449.     public function getZoneElements()
  450.     {
  451.         return $this->zone_elements;
  452.     }
  453.     /**
  454.      * Add shipping_markups
  455.      *
  456.      * @param \XLite\Model\Shipping\Markup $shippingMarkups
  457.      * @return Zone
  458.      */
  459.     public function addShippingMarkups(\XLite\Model\Shipping\Markup $shippingMarkups)
  460.     {
  461.         $this->shipping_markups[] = $shippingMarkups;
  462.         return $this;
  463.     }
  464.     /**
  465.      * Get shipping_markups
  466.      *
  467.      * @return \Doctrine\Common\Collections\Collection
  468.      */
  469.     public function getShippingMarkups()
  470.     {
  471.         return $this->shipping_markups;
  472.     }
  473. }