Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FR: Address validation & suggestions #26

Open
Mosnar opened this issue Mar 13, 2020 · 0 comments
Open

FR: Address validation & suggestions #26

Mosnar opened this issue Mar 13, 2020 · 0 comments

Comments

@Mosnar
Copy link
Contributor

Mosnar commented Mar 13, 2020

Description

I would love to see native address validation from the provider. I've been achieving this myself by creating my own validator and attaching it when rules are defined:

<?php

namespace modules\mymodule\validators;

use craft\commerce\models\Address;
use Exception;
use Ups\AddressValidation;
use verbb\postie\Postie;
use verbb\postie\providers\UPS;
use verbb\postie\services\Providers;
use yii\validators\Validator;

class UpsAddressValidator extends Validator
{
    /**
     * @param Address $model
     * @param string $attribute
     */
    public function validateAttribute($model, $attribute)
    {
        $address = new \Ups\Entity\Address();
        $address->setAddressLine1($model->address1);
        $address->setAddressLine2($model->address2);
        $address->setAddressLine3($model->address3);
        $address->setStateProvinceCode($model->getState()->abbreviation);
        $address->setCity($model->city);
        if ($model->country !== null) {
            $address->setCountryCode($model->country->iso);
        } else {
            $address->setCountryCode('US');
        }
        $address->setPostalCode($model->zipCode);
        /** @var Providers $providers */
        $providers = Postie::getInstance()->getProviders();
        /** @var UPS $ups */
        $ups = $providers->getProviderByHandle('ups');
        $settingsContainer = $ups->getSettings();
        $settings = $settingsContainer['settings'];
        $xav = new AddressValidation($settings['apiKey'], $settings['username'], $settings['password']);
        $xav->activateReturnObjectOnValidate();
        try {
            $response = $xav->validate($address, $requestOption = AddressValidation::REQUEST_OPTION_ADDRESS_VALIDATION, $maxSuggestion = 15);
            if (!$response->isValid()) {
                $model->addError('fullAddress', 'We could not verify your address. Please review and try again.');
            }
        } catch (Exception $e) {
            $model->addError('fullAddress', 'We could not validate your address');
        }
    }
}
if (!Craft::$app->request->isCpRequest && !Craft::$app->request->isConsoleRequest) {
            Event::on(Address::class, Address::EVENT_DEFINE_RULES, function (DefineRulesEvent $event) {
                $event->rules[] = [['address1'], UpsAddressValidator::class];
            });
        }

My plan was/is to add address suggestions by attaching a behavior to the Address model with an array of Commerce Address models populated from the UPS suggested addresses then populating the behavior in the validator. On the frontend, you could then render our suggested addresses the same way you render any other address and even allow the user to accept your suggested address.

Additional info

  • Plugin version: 2.1.1
  • Craft version: 3.4.x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants