diff --git a/src/fields/GeoAddressField.php b/src/fields/GeoAddressField.php index 9e74fb5..968aad0 100644 --- a/src/fields/GeoAddressField.php +++ b/src/fields/GeoAddressField.php @@ -21,8 +21,6 @@ class GeoAddressField extends Field implements PreviewableFieldInterface { /** - * Returns the display name of this class. - * * @return string The display name of this class. */ public static function displayName(): string @@ -31,12 +29,7 @@ public static function displayName(): string } /** - * @param $value - * @param \craft\base\ElementInterface|NULL $element - * - * @return string - * @throws \Twig_Error_Loader - * @throws \yii\base\Exception + * @inheritDoc */ public function getInputHtml($value, ElementInterface $element = null): string { @@ -62,43 +55,52 @@ public function getInputHtml($value, ElementInterface $element = null): string } /** - * @param $value - * @param \craft\base\ElementInterface|NULL $element - * - * @return array|mixed + * @inheritDoc */ public function normalizeValue($value, ElementInterface $element = NULL) { - if (empty($value)) { - $model = new GeoAddressModel(); - $value = $model->getAttributes(); - } - - if (!is_array($value)) { - $value = json_decode($value, true); - } + if (is_string($value)) { + $value = Json::decodeIfJson($value); + } - $value['zip'] = str_replace(' ', '', $value['zip'] ?? ''); + if ($value instanceof GeoAddressModel) { + $model = $value; + } elseif (is_array($value)) { + $model = new GeoAddressModel($value); + } else { + $model = new GeoAddressModel(); + } - return $value; + return $model; } - /** - * @param array $value - * @param \craft\base\ElementInterface|NULL $element - * - * @return array - */ - public function serializeValue($value, ElementInterface $element = NULL) - { - return array_merge( - $value, - GeoAddress::getInstance()->geoAddressService->getCoordsByAddress($value) - ); - } + /** + * @inheritDoc + */ + public function serializeValue($value, ElementInterface $element = null) + { + /** @var GeoAddressModel $model */ + $model = $value; + + // normalize zip + $model->zip = trim(str_replace(' ', '', $model->zip)); + + $isChanged = !$element || ($element && $model->getAddress() !== $element->getFieldValue($this->handle)->getAddress()); + if ($isChanged || (!($model->lat && $model->lng) && $model->getAddress())) { + $result = GeoAddress::getInstance()->geoAddressService->getCoordsByAddress($model->getAddress(), $model->country); + + $model->setAttributes(array_filter($result)); + } + + if ($element) { + $element->setFieldValue($this->handle, $model); + } + + return $model; + } /** - * @return string + * @inheritDoc */ public function getContentColumnType(): string { @@ -106,35 +108,36 @@ public function getContentColumnType(): string } /** - * @param string $value - * @param ElementInterface $element - * @return string + * @inheritDoc */ public function getTableAttributeHtml($value, ElementInterface $element): string { + /** @var GeoAddressModel $model */ + $model = $value; + $label = ''; - if (!empty($value['street'])) { - $label .= $value['street']; + if ($model->street) { + $label .= $model->street; } - if (!empty($value['city'])) { - $label .= (!empty($label) ? ', ' : '') . $value['city']; + if ($model->city) { + $label .= ($label ? ', ' : '') . $model->city; } - if (!empty($value['countryName'])) { - $label .= (!empty($label) ? ', ' : '') . $value['countryName']; + if ($model->countryName) { + $label .= ($label ? ', ' : '') . $model->countryName; } - if (empty($label)) { + if (!$label) { return ''; } $html = Html::tag('span', $label); - if (!empty($value['lat']) && !empty($value['lng'])) { + if ($model->lat && $model->lng) { $html = Html::tag('a', $html, [ - 'href' => sprintf('https://maps.google.com/?q=%s,%s', $value['lat'], $value['lng']), + 'href' => sprintf('https://maps.google.com/?q=%s,%s', $model->lat, $model->lng), 'target' => '_blank', ]); } diff --git a/src/models/GeoAddressModel.php b/src/models/GeoAddressModel.php index 5495081..17babd8 100644 --- a/src/models/GeoAddressModel.php +++ b/src/models/GeoAddressModel.php @@ -27,16 +27,17 @@ class GeoAddressModel extends Model */ public $city; - /** - * @var string - */ - public $state; - /** * @var string */ public $zip; + /** + * @var string + * @deprecated Not in use anymore, but cant be removed as it corrupts existing models + */ + public $state; + /** * @var string */ @@ -72,20 +73,46 @@ class GeoAddressModel extends Model * * @return array */ - public function rules() + public function rules(): array { return [ ['name', 'string'], ['street', 'string'], ['city', 'string'], - ['state', 'string'], ['zip', 'string'], + ['state', 'string'], ['country', 'string'], ['countryName', 'string'], ['countryCode', 'string'], - ['lat', 'float'], - ['lng', 'float'], + ['lat', 'number'], + ['lng', 'number'], ['formattedAddress', 'string'] ]; } + + /** + * @return string + */ + public function getAddress(): string + { + $address = ''; + + if ($this->street) { + $address .= ($address ? ' ' : '') . $this->street; + } + + if ($this->city) { + $address .= ($address ? ' ' : '') . $this->city; + } + + if ($this->zip) { + $address .= ($address ? ' ' : '') . $this->zip; + } + + if ($this->country) { + $address .= ($address ? ' ' : '') . $this->country; + } + + return $address; + } } diff --git a/src/services/GeoAddressService.php b/src/services/GeoAddressService.php index 6282b42..8aeae9f 100644 --- a/src/services/GeoAddressService.php +++ b/src/services/GeoAddressService.php @@ -14,21 +14,25 @@ class GeoAddressService extends Component { /** - * @param array $value + * @param string $address + * @param string $country * @return array */ - public function getCoordsByAddress(array $value) + public function getCoordsByAddress(string $address, string $country) { - $address = [ - 'lat' => null, - 'lng' => null, - 'formattedAddress' => null, - 'countryName' => null, - 'countryCode' => null, - ]; + $requestUrl = 'https://maps.googleapis.com/maps/api/geocode/json'; + $requestUrl .= '?address=' . rawurlencode($address); + $requestUrl .= '&key=' . GeoAddress::getInstance()->getSettings()->googleApiKey; - $requestUrl = 'https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=' . urlencode(json_encode($value)) . '&key=' . GeoAddress::getInstance()->getSettings()->googleApiKey; - $result = json_decode(file_get_contents($requestUrl)); + $result = json_decode(file_get_contents($requestUrl)); + + $address = [ + 'lat' => null, + 'lng' => null, + 'formattedAddress' => null, + 'countryName' => null, + 'countryCode' => null, + ]; // no results if ($result->status !== 'OK' || empty($result->results)) { @@ -50,11 +54,7 @@ public function getCoordsByAddress(array $value) continue; } - if (!isset($value['country'])) { - continue; - } - - if ($component->long_name !== $value['country']) { + if ($component->long_name !== $country) { continue; }