3

I got this error when trying to save custom data to customer,

43766 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught TypeError: Argument 2 passed to Magento\Eav\Model\Attribute\Data\Text::validateLength() must be of the type string, null given

This my the my code,

app/code/Test/Customer/Controller/Account/EditPost.php

    <?php
    namespace Test\Customer\Controller\Account;

    /**
     * Class EditPost
     */
    class EditPost extends \Magento\Framework\App\Action\Action
    {       

        /**
         * @var \Magento\Customer\Model\Session
         */
        protected $customerSession;

        /**
         * @var \Magento\Customer\Model\CustomerFactory
         */
        protected $customerFactory;

        /**
         * @var \Magento\Customer\Api\CustomerRepositoryInterface
         */    
        protected $customerRepository;


        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Customer\Model\Session $customerSession,
            \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
            \Magento\Customer\Model\CustomerFactory $customerFactory
        ) {                   
            $this->customerSession = $customerSession;
            $this->customerRepository = $customerRepository;
            $this->customerFactory = $customerFactory;
            parent::__construct($context);
        }


        public function execute()
        {       
            $resultRedirect = $this->resultRedirectFactory->create();
            $resultRedirect->setUrl('../../../customer/account/edit');  

            try {                   
                $company = $this->getRequest()->getParam('company');
                $department = $this->getRequest()->getParam('department');
                $email = $this->getRequest()->getParam('email_hidden');

                $customerId = 0;
                if($this->customerSession->isLoggedIn())
                $customerId = $this->customerSession->getCustomer()->getId();  

                $customer = $this->customerRepository->getById($customerId);


                $customer->setCustomAttribute('company', $company);
                $customer->setCustomAttribute('department', $department);
                $this->customerRepository->save($customer);
        } catch (\Exception $e) {
            $this->messageManager->addError($e->getMessage());


            return $resultRedirect;                 
        }

        return $resultRedirect;
    }

}   

And this is the code I used to created Company and Department attribute

app/code/Test/Test1/Setup/InstallData.php

<?php

namespace Test\Test1\Setup;

use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Customer\Model\Customer;
use Magento\Sales\Setup\SalesSetupFactory;

class InstallData implements InstallDataInterface
{

    private $eavSetupFactory;

    /**
     * Customer setup factory
     *
     * @var CustomerSetupFactory
     */
    private $customerSetupFactory;

    /**
     * Constructor
     *
     * @param EavSetupFactory $eavSetupFactory
     * @param CustomerSetupFactory $customerSetupFactory
     * @param SalesSetupFactory $salesSetupFactory
     */
    public function __construct(
        EavSetupFactory $eavSetupFactory,
        CustomerSetupFactory $customerSetupFactory,
        SalesSetupFactory $salesSetupFactory
    )
    {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->customerSetupFactory = $customerSetupFactory;
        $this->salesSetupFactory = $salesSetupFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function install(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $setup->startSetup();



        //company
        $customerSetup->addAttribute(
            \Magento\Customer\Model\Customer::ENTITY,
            'company',
            [
                'label' => 'Company',
                'type' => 'varchar',
                'input' => 'text',
                'visible'   => true,
                'required'  => false,
                'position'  => 2002,
                'user_defined' => false,
                'system' => false
            ]
        );

        $customerSetup->getEavConfig()->getAttribute(\Magento\Customer\Model\Customer::ENTITY, 'company')
            ->setData('used_in_forms', ['adminhtml_customer'])
            ->save();

        //department
        $customerSetup->addAttribute(
            \Magento\Customer\Model\Customer::ENTITY,
            'department',
            [
                'label' => 'Department',
                'type' => 'varchar',
                'input' => 'text',
                'visible'   => true,
                'required'  => false,
                'position'  => 2003,
                'user_defined' => false,
                'system' => false
            ]
        );

        $customerSetup->getEavConfig()->getAttribute(\Magento\Customer\Model\Customer::ENTITY, 'department')
            ->setData('used_in_forms', ['adminhtml_customer'])
            ->save();


        $setup->endSetup();

    }
}
7
  • please check that you are not getting company or department value blank May 27, 2019 at 12:21
  • @RutveeSojitra I check. I can echo those two values. and I have also tried to manually type the value to setCustomAttribute() instead of using variables. but same error. May 27, 2019 at 12:23
  • Can you add code how did you create attribute ?
    – anonymous
    May 27, 2019 at 12:29
  • @Vivek I just updated the question and add script InstallData.php please have a look May 27, 2019 at 12:40
  • I think error you are getting due to you didn't use required parameter used_in_forms add your form's value EG. customer_register_address. then ttry to save value it might get help you resolve your issue.
    – anonymous
    May 27, 2019 at 14:05

3 Answers 3

3

We can debug which field has got the null value by placing a logger just before passing the value to validateLength function in the file vendor/magento/module-eav/Model/Attribute/Data/Text.php as follows,

public function validateValue($value)
{
    $errors = [];
    $attribute = $this->getAttribute();

    if ($value === false) {
        // try to load original value and validate it
        $value = $this->getEntity()->getDataUsingMethod($attribute->getAttributeCode());
    }

    if (!$attribute->getIsRequired() && empty($value)) {
        return true;
    }

    if (empty($value) && $value !== '0' && $attribute->getDefaultValue() === null) {
        $label = __($attribute->getStoreLabel());
        $errors[] = __('"%1" is a required value.', $label);
    }

    $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/validatelog.log');
    $logger = new \Zend\Log\Logger();
    $logger->addWriter($writer);
    $logger->info($attribute->getName());

    $validateLengthResult = $this->validateLength($attribute, $value);
    $errors = array_merge($errors, $validateLengthResult);

    $validateInputRuleResult = $this->validateInputRule($value);
    $errors = array_merge($errors, $validateInputRuleResult);

    if (count($errors) == 0) {
        return true;
    }

    return $errors;
}

While checking the log file from magento2Root/var/log/validatelog.log, the last attribute will be the cause of the issue. I faced the similar issue while creating a new address programatically and found that lastname is empty which is a required field while saving in address book. Hope by this way you will find yours too.

1

I got the same error and in my case, the root cause was not in the code (it was correct) but in incorrect data. A customer had an attribute with the required value, but the value was null. (Probably the account was created manually with SQL). When I fixed the data, the code began work.

0

There must be some customer attribute that is required and it is not provided while creating the customer.

e.g. Creating Customer programmatically. In that case, you need to additionally set that custom attribute value. Example below:

$customer->setMyAttribute('my attribtue value');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.