Jump to content

hookActionValidate Validate form input


Recommended Posts

PRESTASHOP 1.7.2.0

 

I need to validate the address submitted by the customer during the creation.

In a module i've added:

    public function hookActionValidateCustomerAddressForm($params)
    {
        /** @var CustomerAddressForm $form */


        $form = $params['form'];
        $city = $form->getField("city") ? $form->getField('city')->getValue() : null;


        if (!$this->isValidVillage(129, $city)) {


            $form->getField('city')->addError("The city is not listed");


        }
    }

Just i don't understand how the hookValidate action are supposed to work. 

 

I have to check if the city is listed in a custom table, but how to invalidate the form in the hook and set errors?

 

In classes/form/CustomerAddressForm we got:

public function validate()
    {
        $is_valid = parent::validate();


        if (($postcode = $this->getField('postcode'))) {
            if ($postcode->isRequired()) {
                $country = $this->formatter->getCountry();
                if (!$country->checkZipCode($postcode->getValue())) {
                    // FIXME: the translator adapter is crap at the moment,
                    // but once it is not, the sprintf needs to go away.
                    $postcode->addError(sprintf(
                        $this->translator->trans(
                            'Invalid postcode - should look like "%1$s"', [], 'Shop.Forms.Errors'
                        ),
                        $country->zip_code_format
                    ));
                    $is_valid = false;
                }
            }
        }


        if (($hookReturn = Hook::exec('actionValidateCustomerAddressForm', array('form' => $this))) != '') {
            $is_valid &= (bool) $hookReturn;
        }


        return $is_valid;
    }

So the validation happen is this mode?

 

I have to return or invoke some util class to do this?

 

 

returning boolean fails because get changed with "" by exec().

 

 

Validate method assing $is_valid to the hook return, but will fails if it's not an array because exec()

 

        if ($array_return) {
                        $output[$moduleInstance->name] = $display;
                    } else {
                        if (true === $chain) {
                            $output = $display;
                        } else {
                            $output .= $display;
                        }
                    }

Whewre $display is set to "" and the validate method is bypassing when "".

Edited by yuxblank (see edit history)
  • Like 1
Link to comment
Share on other sites

The thing of using $this->context->controller->errors[] sometimes fails since it get redirected after save also when errors are present!

 

I'm running php 7.0 with built-in server. I can't understand how, but the error is displayed on Addresses page along with succesful save!.

 

I'm seriously start to think that PS 1.7.x isn't stable enough for production.

 
Link to comment
Share on other sites

    public function validate()
    {

        $is_valid = true;

        if (($postcode = $this->getField('postcode'))) {
            if ($postcode->isRequired()) {
                $country = $this->formatter->getCountry();
                if (!$country->checkZipCode($postcode->getValue())) {
                    // FIXME: the translator adapter is crap at the moment,
                    // but once it is not, the sprintf needs to go away.
                    $postcode->addError(sprintf(
                        $this->translator->trans(
                            'Invalid postcode - should look like "%1$s"', [], 'Shop.Forms.Errors'
                        ),
                        $country->zip_code_format
                    ));
                    $is_valid = false;
                }
            }
        }

        if (($hookReturn = Hook::exec('actionValidateCustomerAddressForm', array('form' => $this))) != '' ) {
            $is_valid &= (bool) $hookReturn;
        }

        $is_valid = parent::validate();


        return $is_valid;
    }

This fixes the Core code (parent validation must be called after) ill' try submit a pull request.

Link to comment
Share on other sites

  • 1 year later...

You do not need to use 

$this->context->controller->errors[] = $this->l('Incorrect city');

Look at native validation part of code:

        if (($postcode = $this->getField('postcode'))) {
            if ($postcode->isRequired()) {
                $country = $this->formatter->getCountry();
                if (!$country->checkZipCode($postcode->getValue())) {
                    $postcode->addError($this->translator->trans('Invalid postcode - should look like "%zipcode%"',
                        array('%zipcode%' => $country->zip_code_format),
                        'Shop.Forms.Errors'));
                    $is_valid = false;
                }
            }
        }

By using method "addError" on specific form field, you can display error comment under each field.

And then, if you want NOT to save the form, your "hookActionValidateCustomerAddressForm" have to return 0 - zero. 

Link to comment
Share on other sites

  • 1 year later...

You need to return string. This is my function:

 

    public function hookActionValidateCustomerAddressForm(array $params) {
        $snb = new SohoshopNIPBlock();
        $blocked_nips = $snb->getBlockedNips();
        $vat_number = $params['form']->getField('vat_number');
        if( in_array($vat_number->getValue(), $blocked_nips) ){
            $vat_number->addError( Configuration::get('sohoshop_nipblock_message') );    
            return "0";
        }
        return "1";
    }

 

  • Like 2
Link to comment
Share on other sites

  • 1 month later...
  • 1 year later...

2022:
I did this as others said:
But it is so weird that returning false does not work

    public function hookActionValidateCustomerAddressForm($params)
    {
        // custom method to check and validate address form
        if(!$this->validateCustomerAddressForm($params)) {
            // raise an error if needed
            $this->context->controller->errors[] = $this->l('there was an error');

            // modern translate
            $customVariable = 'error-code-12345';
            $this->context->controller->errors[] = $this->trans('there was an error: %s', [$customVariable], 'Modules.Mymodule.Errors');

            // thats awesome prestashop =)) does not work
            // return false;
            
            // things that work but looks strange =)
            return 0;
            return '0';
        }
    }

    protected function validateCustomerAddressForm($params)
    {
        return false;
    }

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...