TypedData properties are not defined/loaded correctly

Created on 9 April 2024, 8 months ago
Updated 24 April 2024, 8 months ago

I added a phone_number field to my Customer profile in Commerce, in order to collect the customer's phone number at the time of checkout. When I mark the phone number field as "required" and click the button to proceed, it returns the error message "Phone number in Phone is required." there are no log entries. How can I resolve this issue?

πŸ› Bug report
Status

Active

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States hockey2112

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @hockey2112
  • πŸ‡·πŸ‡ΈSerbia vaish

    Are you getting this error even after you populate the Phone field? Please clarify. Screenshot might be helpful here.

  • πŸ‡ΊπŸ‡ΈUnited States hockey2112

    Yes, even after I populate the field with a phone number. Screenshots attached. First screenshot is when I type the phone number. Then I click "proceed". Second screenshot is the error message that appears.

  • πŸ‡·πŸ‡ΈSerbia vaish

    Thanks for the screenshots. I looked into this and I can reproduce the issue.

    If checkbox "My billing information is the same as my shipping information." is checked during the checkout, commerce will populate "Billing information" fields with the values taken from the "Shipping information" section. Value of the Phone field is not copied successfully and Phone field in the "Billing information" remains empty causing the validation error reported here. So, this error refers to the empty field in the "Billing information" section.

    Copy of the values is initiated in the Drupal\commerce_shipping\ProfileFieldCopy::alterForm()

          // Copy over the current shipping field values, allowing widgets such as
          // TaxNumberDefaultWidget to rely on them. These values might change
          // during submit, so the profile is populated again in submitForm().
          $billing_profile->populateFromProfile($shipping_profile, $shipping_fields);
    

    Drupal\profile\Entity::populateFromProfile() depends on the TypeData plugins to correctly set values for each of the fields. Both Phone number and Address fields implement Drupal\Core\TypedData\Plugin\DataType\Map plugin. Map::setValue() method is responsible for setting the values.

        // Update any existing property objects.
        foreach ($this->properties as $name => $property) {
          $value = $values[$name] ?? NULL;
          $property->setValue($value, FALSE);
          // Remove the value from $this->values to ensure it does not contain any
          // value for computed properties.
          unset($this->values[$name]);
        }
    

    Problem is that in the case of the Phone Number $this->properties is empty (properties are not set) and therefore no values are set. Phone field defines the following properties: 'value', 'country', 'local_number', and 'extension' but for some reason those properties are not available in the setValues() method.

    As a comparison, Address field defines its own properties ('address_line1', 'locality', 'country_code', etc) and those are all available in the setValue() method and values are correctly copied.

    Unfortunately, I don't have time to look into this further right now. I hope somebody else can chime in.

  • πŸ‡ΊπŸ‡ΈUnited States hockey2112

    Interesting, thank you for looking into this. Hopefully a fix can be added sometime in the near future.

Production build 0.71.5 2024