classes/XLite/Model/Address.php line 107

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 ApiPlatform\Core\Annotation as ApiPlatform;
  8. use Doctrine\ORM\Mapping as ORM;
  9. use XLite\API\Endpoint\ProfileAddress\DTO\ProfileAddressInput as Input;
  10. use XLite\API\Endpoint\ProfileAddress\DTO\ProfileAddressOutput as Output;
  11. /**
  12.  * @ORM\Entity
  13.  * @ORM\Table (
  14.  *     name="profile_addresses",
  15.  *     indexes={
  16.  *         @ORM\Index (name="is_billing", columns={"is_billing"}),
  17.  *         @ORM\Index (name="is_shipping", columns={"is_shipping"})
  18.  *     }
  19.  * )
  20.  * @ApiPlatform\ApiResource(
  21.  *     input=Input::class,
  22.  *     output=Output::class,
  23.  *     itemOperations={
  24.  *          "get"={
  25.  *              "method"="GET",
  26.  *              "path"="/profiles/{profile_id}/addresses/{address_id}.{_format}",
  27.  *              "identifiers"={"profile_id", "address_id"},
  28.  *              "requirements"={"profile_id"="\d+", "address_id"="\d+"},
  29.  *              "openapi_context"={
  30.  *                  "summary"="Retrieve an address from a profile",
  31.  *                  "parameters"={
  32.  *                      {"name"="profile_id", "in"="path", "required"=true, "schema"={"type"="integer"}},
  33.  *                      {"name"="address_id", "in"="path", "required"=true, "schema"={"type"="integer"}}
  34.  *                  }
  35.  *              }
  36.  *          },
  37.  *          "put"={
  38.  *              "method"="PUT",
  39.  *              "path"="/profiles/{profile_id}/addresses/{address_id}.{_format}",
  40.  *              "identifiers"={"profile_id", "address_id"},
  41.  *              "requirements"={"profile_id"="\d+", "address_id"="\d+"},
  42.  *              "openapi_context"={
  43.  *                  "summary"="Update an address of a profile",
  44.  *                  "parameters"={
  45.  *                      {"name"="profile_id", "in"="path", "required"=true, "schema"={"type"="integer"}},
  46.  *                      {"name"="address_id", "in"="path", "required"=true, "schema"={"type"="integer"}}
  47.  *                  }
  48.  *              }
  49.  *          },
  50.  *          "delete"={
  51.  *              "method"="DELETE",
  52.  *              "path"="/profiles/{profile_id}/addresses/{address_id}.{_format}",
  53.  *              "identifiers"={"profile_id", "address_id"},
  54.  *              "requirements"={"profile_id"="\d+", "address_id"="\d+"},
  55.  *              "openapi_context"={
  56.  *                  "summary"="Delete an address from a profile",
  57.  *                  "parameters"={
  58.  *                      {"name"="profile_id", "in"="path", "required"=true, "schema"={"type"="integer"}},
  59.  *                      {"name"="address_id", "in"="path", "required"=true, "schema"={"type"="integer"}}
  60.  *                  }
  61.  *              }
  62.  *          }
  63.  *     },
  64.  *     collectionOperations={
  65.  *          "get"={
  66.  *              "method"="GET",
  67.  *              "path"="/profiles/{profile_id}/addresses.{_format}",
  68.  *              "identifiers"={"profile_id", "address_id"},
  69.  *              "requirements"={"profile_id"="\d+"},
  70.  *              "openapi_context"={
  71.  *                  "summary"="Retrieve a list of addresses from a profile",
  72.  *                  "parameters"={
  73.  *                      {"name"="profile_id", "in"="path", "required"=true, "schema"={"type"="integer"}}
  74.  *                  },
  75.  *              }
  76.  *          },
  77.  *          "post"={
  78.  *              "method"="POST",
  79.  *              "path"="/profiles/{profile_id}/addresses.{_format}",
  80.  *              "controller"="xcart.api.profile_address.controller",
  81.  *              "identifiers"={"profile_id", "address_id"},
  82.  *              "requirements"={"profile_id"="\d+"},
  83.  *              "openapi_context"={
  84.  *                  "summary"="Add an address to a profile",
  85.  *                  "parameters"={
  86.  *                      {"name"="profile_id", "in"="path", "required"=true, "schema"={"type"="integer"}}
  87.  *                  }
  88.  *              }
  89.  *          }
  90.  *     }
  91.  * )
  92.  *
  93.  * @method string getFirstname
  94.  * @method string setFirstname
  95.  * @method string getLastname
  96.  * @method string setLastname
  97.  * @method string getAddress1
  98.  * @method string getAddress2
  99.  * @method string getAddress3
  100.  * @method string setAddress1
  101.  * @method string setAddress2
  102.  * @method string setAddress3
  103.  * @method string getZipcode
  104.  * @method string setZipcode
  105.  * @method string getCity
  106.  * @method string setCity
  107.  * @method string getPhone
  108.  * @method string setPhone
  109.  */
  110. class Address extends \XLite\Model\Base\PersonalAddress
  111. {
  112.     /**
  113.      * Address type codes
  114.      */
  115.     public const BILLING  'b';
  116.     public const SHIPPING 's';
  117.     /**
  118.      * Address fields collection
  119.      *
  120.      * @var \Doctrine\Common\Collections\ArrayCollection
  121.      *
  122.      * @ORM\OneToMany (targetEntity="XLite\Model\AddressFieldValue", mappedBy="address", cascade={"all"})
  123.      */
  124.     protected $addressFields;
  125.     /**
  126.      * Flag: is it a billing address
  127.      *
  128.      * @var bool
  129.      *
  130.      * @ORM\Column (type="boolean")
  131.      */
  132.     protected $is_billing false;
  133.     /**
  134.      * Flag: is it a shipping address
  135.      *
  136.      * @var bool
  137.      *
  138.      * @ORM\Column (type="boolean")
  139.      */
  140.     protected $is_shipping false;
  141.     /**
  142.      * Flag: is it a work address
  143.      *
  144.      * @var bool
  145.      *
  146.      * @ORM\Column (type="boolean")
  147.      */
  148.     protected $isWork false;
  149.     /**
  150.      * @var \XLite\Model\Profile
  151.      *
  152.      * @ORM\ManyToOne (targetEntity="XLite\Model\Profile", inversedBy="addresses", cascade={"persist","merge","detach"})
  153.      * @ORM\JoinColumn (name="profile_id", referencedColumnName="profile_id", onDelete="CASCADE")
  154.      */
  155.     protected $profile;
  156.     /**
  157.      * Constructor
  158.      *
  159.      * @param array $data Entity properties OPTIONAL
  160.      */
  161.     public function __construct(array $data = [])
  162.     {
  163.         $this->addressFields = new \Doctrine\Common\Collections\ArrayCollection();
  164.         parent::__construct($data);
  165.     }
  166.     /**
  167.      * Universal setter
  168.      *
  169.      * @param string $property
  170.      * @param mixed  $value
  171.      *
  172.      * @return true|null Returns TRUE if the setting succeeds. NULL if the setting fails
  173.      */
  174.     public function setterProperty($property$value)
  175.     {
  176.         $result parent::setterProperty($property$value);
  177.         if ($result === null) {
  178.             $addressField \XLite\Core\Database::getRepo('XLite\Model\AddressField')
  179.                 ->findOneBy(['serviceName' => $property]);
  180.             if ($addressField) {
  181.                 $repo \XLite\Core\Database::getRepo('XLite\Model\AddressFieldValue');
  182.                 $addressFieldValue $this->getFieldValue($property);
  183.                 if ($addressFieldValue) {
  184.                     $addressFieldValue->setValue($value);
  185.                     if ($this->isPersistent()) {
  186.                         $repo->update($addressFieldValue);
  187.                     }
  188.                 } else {
  189.                     $addressFieldValue = new \XLite\Model\AddressFieldValue();
  190.                     $addressFieldValue->map([
  191.                         'address'      => $this,
  192.                         'addressField' => $addressField,
  193.                         'value'        => $value,
  194.                     ]);
  195.                     $this->addAddressFields($addressFieldValue);
  196.                     if ($this->isPersistent()) {
  197.                         $repo->insert($addressFieldValue);
  198.                     }
  199.                 }
  200.                 $result true;
  201.             } else {
  202.                 // Log wrong access to property
  203.                 $this->logWrongAddressPropertyAccess($propertyfalse);
  204.             }
  205.         }
  206.         return $result;
  207.     }
  208.     /**
  209.      * Update searchFakeField of profile
  210.      *
  211.      * @return boolean
  212.      */
  213.     public function update()
  214.     {
  215.         $result parent::update();
  216.         if ($this->getProfile()) {
  217.             \XLite\Core\Database::getEM()->refresh($this->getProfile());
  218.             $this->getProfile()->updateSearchFakeField();
  219.             \XLite\Core\Database::getEM()->flush();
  220.         }
  221.         return $result;
  222.     }
  223.     /**
  224.      * Update searchFakeField of profile
  225.      *
  226.      * @return boolean
  227.      */
  228.     public function delete()
  229.     {
  230.         // We are using id because we can't user em->refresh or em->merge
  231.         $profileId $this->getProfile()
  232.             ? $this->getProfile()->getProfileId()
  233.             : null;
  234.         $result parent::delete();
  235.         if ($profileId) {
  236.             $profile \XLite\Core\Database::getRepo('XLite\Model\Profile')->find($profileId);
  237.             $profile->updateSearchFakeField();
  238.         }
  239.         return $result;
  240.     }
  241.     /**
  242.      * Update searchFakeField of profile
  243.      *
  244.      * @return boolean
  245.      */
  246.     public function create()
  247.     {
  248.         $result parent::create();
  249.         if ($this->getProfile()) {
  250.             \XLite\Core\Database::getEM()->refresh($this->getProfile());
  251.             $this->getProfile()->updateSearchFakeField();
  252.         }
  253.         return $result;
  254.     }
  255.     /**
  256.      * Universal getter
  257.      *
  258.      * @param string $property
  259.      *
  260.      * @return mixed|null Returns NULL if it is impossible to get the property
  261.      */
  262.     public function getterProperty($property)
  263.     {
  264.         $result parent::getterProperty($property);
  265.         if ($result === null) {
  266.             $addressField = static::getAddressFieldByServiceName($property);
  267.             if ($addressField) {
  268.                 $addressFieldValue $this->getFieldValue($property);
  269.                 $result $addressFieldValue
  270.                     $addressFieldValue->getValue()
  271.                     : static::getDefaultFieldPlainValue($property);
  272.             } else {
  273.                 // Log wrong access to property
  274.                 $this->logWrongAddressPropertyAccess($property);
  275.             }
  276.         }
  277.         return $result;
  278.     }
  279.     /**
  280.      * Disable default logging of access to wrong property
  281.      *
  282.      * @param string  $property Property name
  283.      * @param boolean $isGetter Flag: is called property getter (true) or setter (false) OPTIONAL
  284.      *
  285.      * @return void
  286.      */
  287.     protected function logWrongPropertyAccess($property$isGetter true)
  288.     {
  289.     }
  290.     /**
  291.      * Log access to unknown address property
  292.      *
  293.      * @param string  $property Property name
  294.      * @param boolean $isGetter Flag: is called property getter (true) or setter (false) OPTIONAL
  295.      *
  296.      * @return void
  297.      */
  298.     protected function logWrongAddressPropertyAccess($property$isGetter true)
  299.     {
  300.         parent::logWrongPropertyAccess($property$isGetter);
  301.     }
  302.     /**
  303.      * Return true if specified property exists
  304.      *
  305.      * @param string $name Property name
  306.      *
  307.      * @return boolean
  308.      */
  309.     public function isPropertyExists($name)
  310.     {
  311.         return parent::isPropertyExists($name)
  312.             || (bool)static::getAddressFieldByServiceName($name);
  313.     }
  314.     /**
  315.      * Get field value
  316.      *
  317.      * @param string $name Field name
  318.      *
  319.      * @return \XLite\Model\AddressFieldValue
  320.      */
  321.     public function getFieldValue($name)
  322.     {
  323.         $addressFieldValue null;
  324.         $addressField = static::getAddressFieldByServiceName($name);
  325.         if ($addressField) {
  326.             foreach ($this->getAddressFields() as $field) {
  327.                 if (
  328.                     $field->getAddressField()
  329.                     && (int)$field->getAddressField()->getId() === (int)$addressField->getId()
  330.                 ) {
  331.                     $addressFieldValue $field;
  332.                     break;
  333.                 }
  334.             }
  335.         }
  336.         return $addressFieldValue;
  337.     }
  338.     public static function createDefaultShippingAddress()
  339.     {
  340.         $address = new \XLite\Model\Address();
  341.         $requiredFields = ['country''state''custom_state''zipcode''city'];
  342.         $data = [];
  343.         foreach ($requiredFields as $fieldName) {
  344.             if (!isset($data[$fieldName]) && \XLite\Model\Address::getDefaultFieldValue($fieldName)) {
  345.                 $data[$fieldName] = \XLite\Model\Address::getDefaultFieldValue($fieldName);
  346.             }
  347.         }
  348.         $address->map($data);
  349.         return $address;
  350.     }
  351.     public function checkAddress()
  352.     {
  353.         /** @var \XLite\Model\AddressFieldValue $addressFieldValue */
  354.         foreach ($this->getAddressFields() as $addressFieldValue) {
  355.             $serviceName $addressFieldValue->getAddressField()
  356.                 ? $addressFieldValue->getAddressField()->getServiceName()
  357.                 : '';
  358.             $val $addressFieldValue->getValue();
  359.             if (!$this->checkAddressField($serviceName$val)) {
  360.                 return false;
  361.             }
  362.         }
  363.         return true;
  364.     }
  365.     public function restoreInvalid()
  366.     {
  367.         /** @var \XLite\Model\AddressFieldValue $addressFieldValue */
  368.         foreach ($this->getAddressFields() as $addressFieldValue) {
  369.             $serviceName $addressFieldValue->getAddressField()
  370.                 ? $addressFieldValue->getAddressField()->getServiceName()
  371.                 : '';
  372.             $val $addressFieldValue->getValue();
  373.             if (!$this->checkAddressField($serviceName$val)) {
  374.                 $addressFieldValue->setValue(static::getDefaultFieldValue($serviceName));
  375.             }
  376.         }
  377.     }
  378.     /**
  379.      * Get default value for the field
  380.      *
  381.      * @param string $fieldName Field service name
  382.      *
  383.      * @return mixed
  384.      */
  385.     public static function getDefaultFieldValue($fieldName)
  386.     {
  387.         $result null;
  388.         switch ($fieldName) {
  389.             case 'country':
  390.                 $code \XLite\Core\Config::getInstance()->Shipping->anonymous_country;
  391.                 $result \XLite\Core\Database::getRepo('XLite\Model\Country')->findOneByCode($code);
  392.                 if ($result && !$result->getEnabled()) {
  393.                     $newResult \XLite\Core\Database::getRepo('XLite\Model\Country')->findOneBy(['enabled' => true]);
  394.                     $result $newResult ?: $result;
  395.                 }
  396.                 break;
  397.             case 'country_code':
  398.                 $code \XLite\Core\Config::getInstance()->Shipping->anonymous_country;
  399.                 $result \XLite\Core\Database::getRepo('XLite\Model\Country')->findOneByCode($code);
  400.                 if ($result && !$result->getEnabled()) {
  401.                     $newResult \XLite\Core\Database::getRepo('XLite\Model\Country')->findOneBy(['enabled' => true]);
  402.                     $result $newResult ?: $result;
  403.                 }
  404.                 $result $result->getCode();
  405.                 break;
  406.             case 'state':
  407.                 $id \XLite\Core\Config::getInstance()->Shipping->anonymous_state;
  408.                 $result \XLite\Core\Database::getRepo('XLite\Model\State')->find($id);
  409.                 break;
  410.             case 'custom_state':
  411.                 $result \XLite\Core\Config::getInstance()->Shipping->anonymous_custom_state;
  412.                 break;
  413.             case 'zipcode':
  414.                 $result \XLite\Core\Config::getInstance()->Shipping->anonymous_zipcode;
  415.                 break;
  416.             case 'city':
  417.                 $result \XLite\Core\Config::getInstance()->Shipping->anonymous_city;
  418.                 break;
  419.             default:
  420.         }
  421.         return $result;
  422.     }
  423.     /**
  424.      * Get required fields by address type
  425.      *
  426.      * @param string $atype Address type code
  427.      *
  428.      * @return array
  429.      */
  430.     public function getRequiredFieldsByType($atype)
  431.     {
  432.         switch ($atype) {
  433.             case static::BILLING:
  434.                 $list \XLite\Core\Database::getRepo('XLite\Model\AddressField')->getBillingRequiredFields();
  435.                 break;
  436.             case static::SHIPPING:
  437.                 $list \XLite\Core\Database::getRepo('XLite\Model\AddressField')->getShippingRequiredFields();
  438.                 break;
  439.             default:
  440.                 $list null;
  441.             // TODO - add throw exception
  442.         }
  443.         return $list;
  444.     }
  445.     /**
  446.      * Returns array of address fields serviceName/value pairs
  447.      *
  448.      * @return array
  449.      */
  450.     public function serialize()
  451.     {
  452.         $fields $this->getAddressFields();
  453.         $result = [];
  454.         if ($fields) {
  455.             $result array_reduce($fields->toArray(), static function ($acc$item) {
  456.                 if ($item->getAddressField()) {
  457.                     $acc[$item->getAddressField()->getServiceName()] = $item->getValue();
  458.                     return $acc;
  459.                 }
  460.             }, []);
  461.         }
  462.         return $result;
  463.     }
  464.     /**
  465.      * Clone
  466.      *
  467.      * @return \XLite\Model\AEntity
  468.      */
  469.     public function cloneEntity()
  470.     {
  471.         $entity parent::cloneEntity();
  472.         foreach (\XLite\Core\Database::getRepo('XLite\Model\AddressField')->findAllEnabled() as $field) {
  473.             if (
  474.                 $field->getServiceName() === 'state_id'
  475.                 && $this->getCountry()
  476.                 && $this->getCountry()->isForcedCustomState()
  477.             ) {
  478.                 continue;
  479.             }
  480.             $entity->setterProperty($field->getServiceName(), $this->getterProperty($field->getServiceName()));
  481.         }
  482.         if ($this->getProfile()) {
  483.             $entity->setProfile($this->getProfile());
  484.         }
  485.         return $entity;
  486.     }
  487.     /**
  488.      * Get country
  489.      *
  490.      * @return \XLite\Model\Country
  491.      */
  492.     public function getCountry()
  493.     {
  494.         $result $this->country;
  495.         if (!$result) {
  496.             $result \XLite\Model\Address::getDefaultFieldValue('country');
  497.         }
  498.         return $result;
  499.     }
  500.     /**
  501.      * Serialize address to array
  502.      *
  503.      * @return array
  504.      */
  505.     public function toArray()
  506.     {
  507.         return [
  508.             'name'         => trim($this->getFirstname() . ' ' $this->getLastname()),
  509.             'address1'     => $this->getAddress1(),
  510.             'address2'     => $this->getAddress2(),
  511.             'address3'     => $this->getAddress3(),
  512.             'city'         => $this->getCity(),
  513.             'state'        => $this->getState() ? $this->getState()->getCode() : '',
  514.             'custom_state' => $this->getCustomState(),
  515.             'zipcode'      => $this->getZipcode(),
  516.             'country'      => $this->getCountry() ? $this->getCountry()->getCode() : '',
  517.             'type'         => $this->getType() ?: \XLite\Core\Config::getInstance()->Shipping->anonymous_address_type,
  518.         ];
  519.     }
  520.     /**
  521.      * Set is_billing
  522.      *
  523.      * @param boolean $isBilling
  524.      *
  525.      * @return Address
  526.      */
  527.     public function setIsBilling($isBilling)
  528.     {
  529.         $this->is_billing $isBilling;
  530.         return $this;
  531.     }
  532.     /**
  533.      * Get is_billing
  534.      *
  535.      * @return boolean
  536.      */
  537.     public function getIsBilling()
  538.     {
  539.         return $this->is_billing;
  540.     }
  541.     /**
  542.      * Set is_shipping
  543.      *
  544.      * @param boolean $isShipping
  545.      *
  546.      * @return Address
  547.      */
  548.     public function setIsShipping($isShipping)
  549.     {
  550.         $this->is_shipping $isShipping;
  551.         return $this;
  552.     }
  553.     /**
  554.      * Get is_shipping
  555.      *
  556.      * @return boolean
  557.      */
  558.     public function getIsShipping()
  559.     {
  560.         return $this->is_shipping;
  561.     }
  562.     /**
  563.      * Set isWork
  564.      *
  565.      * @param boolean $isWork
  566.      *
  567.      * @return Address
  568.      */
  569.     public function setIsWork($isWork)
  570.     {
  571.         $this->isWork $isWork;
  572.         return $this;
  573.     }
  574.     /**
  575.      * Get isWork
  576.      *
  577.      * @return boolean
  578.      */
  579.     public function getIsWork()
  580.     {
  581.         return $this->isWork;
  582.     }
  583.     /**
  584.      * Get address_id
  585.      *
  586.      * @return integer
  587.      */
  588.     public function getAddressId()
  589.     {
  590.         return $this->address_id;
  591.     }
  592.     /**
  593.      * Set address_type
  594.      *
  595.      * @param string $addressType
  596.      *
  597.      * @return Address
  598.      */
  599.     public function setAddressType($addressType)
  600.     {
  601.         $this->address_type $addressType;
  602.         return $this;
  603.     }
  604.     /**
  605.      * Get address_type
  606.      *
  607.      * @return string
  608.      */
  609.     public function getAddressType()
  610.     {
  611.         return $this->address_type;
  612.     }
  613.     /**
  614.      * Add addressFields
  615.      *
  616.      * @param \XLite\Model\AddressFieldValue $addressFields
  617.      *
  618.      * @return Address
  619.      */
  620.     public function addAddressFields(\XLite\Model\AddressFieldValue $addressFields)
  621.     {
  622.         $this->addressFields[] = $addressFields;
  623.         return $this;
  624.     }
  625.     /**
  626.      * Get addressFields
  627.      *
  628.      * @return \Doctrine\Common\Collections\Collection
  629.      */
  630.     public function getAddressFields()
  631.     {
  632.         return $this->addressFields;
  633.     }
  634.     /**
  635.      * Set profile
  636.      *
  637.      * @param \XLite\Model\Profile $profile
  638.      *
  639.      * @return Address
  640.      */
  641.     public function setProfile(\XLite\Model\Profile $profile null)
  642.     {
  643.         $this->profile $profile;
  644.         return $this;
  645.     }
  646.     /**
  647.      * Get profile
  648.      *
  649.      * @return \XLite\Model\Profile
  650.      */
  651.     public function getProfile()
  652.     {
  653.         return $this->profile;
  654.     }
  655.     public function getAddressLinesList(): array
  656.     {
  657.         $result = [];
  658.         for ($i 1$i <= 3$i++) {
  659.             $method "getAddress{$i}";
  660.             $result[] = $this->$method();
  661.         }
  662.         return $result;
  663.     }
  664.     public function getAddressLineConcat(): string
  665.     {
  666.         return trim(
  667.             implode(' 'array_filter($this->getAddressLinesList()))
  668.         );
  669.     }
  670.     public function getAddressLineConcat23(): string
  671.     {
  672.         return $this->getAddress2() . ' ' $this->getAddress3();
  673.     }
  674.     /**
  675.      * @deprecated since CDev-Core 5.5.1, use \XLite\Model\Address::getAddress1() instead
  676.      */
  677.     public function getStreet(): string
  678.     {
  679.         trigger_deprecation('CDev-Core''5.5.1''"%s" is deprecated, use \XLite\Model\Address::getAddress1() instead.'__METHOD__);
  680.         return $this->getAddress1();
  681.     }
  682.     public static function prepareAddressLines(string $address1 ''string $address2 ''string $address3 ''): array
  683.     {
  684.         $result = [
  685.             'address1' => $address1,
  686.             'address2' => $address2,
  687.             'address3' => $address3,
  688.         ];
  689.         if (static::line3Disabled()) {
  690.             $result['address2'] .= ' ' $result['address3'];
  691.             $result['address3'] = '';
  692.         }
  693.         if (static::line2Disabled()) {
  694.             $result['address1'] .= ' ' $result['address2'];
  695.             $result['address2'] = '';
  696.         }
  697.         return $result;
  698.     }
  699.     public static function line2Disabled(): bool
  700.     {
  701.         return !static::getAddressFieldByServiceName('address2')->getEnabled();
  702.     }
  703.     public static function line3Disabled(): bool
  704.     {
  705.         return !static::getAddressFieldByServiceName('address3')->getEnabled();
  706.     }
  707.     public function getAddressLineConcatCommaDivided(): string
  708.     {
  709.         $fields = [];
  710.         foreach (['address1''address2''address3'] as $line) {
  711.             $method 'get' ucfirst($line);
  712.             if (
  713.                 ($fieldValue $this->getFieldValue($line))
  714.                 && $fieldValue->getAddressField()->getEnabled()
  715.                 && !empty($this->$method())
  716.             ) {
  717.                 $fields[] = $this->$method();
  718.             }
  719.         }
  720.         return implode(', '$fields);
  721.     }
  722. }