drupal-8

Create custom field for shipping method in Drupal Commerce 2


I'm trying to add a new field called Opening Hours for commerce_shipping_method bundle. I'm having hard time finding examples how to do this and those I tried didn't really work for me. In fact, not even adding a simple numeric field worked for me.

I have 2 YML files in a custom module where I define the testing numeric field.

custom_module.field_instance.yml

langcode: en
status: true
dependencies:
  config:
    - field.storage.commerce_shipping_method.field_opening_hours_x
id: commerce_shipping_method.commerce_shipping_method.field_opening_hours_x
field_name: field_opening_hours_x
entity_type: commerce_shipping_method
bundle: commerce_shipping_method
label: 'Test Numeric Field'
description: 'A test field'
required: false
default_value: {  }
default_value_callback: ''
settings: {  }
third_party_settings: {  }
deleted: false

custom_module.field_storage.yml

langcode: en
status: true
dependencies:
  module:
    - commerce_shipping
id: commerce_shipping_method.field_opening_hours_x
field_name: field_opening_hours_x
entity_type: commerce_shipping_method
type: decimal
module: number
settings:
  precision: 2
locked: false
cardinality: 1
translatable: true
indexes: {  }
persist_with_no_fields: true
custom_storage: false

When I install this module and go to edit my shipping method ( /admin/commerce/shipping-methods/manage/2?destination=/admin/commerce/shipping-methods ), the extra field is not present.

Any help or pointers to the right docs on how to do this would be appreciated.


Solution

  • After some help from the slack commerce community and reviewing a Drupal article on field definitions, I came up with the following resolution:

    my_commerce.module

    Here is where the definition that's shown on form page goes. It didn't work if I simply used it in the update hook (second file below), so I had to duplicate the definition in my .module file as well.

    /**
     * Implements hook_entity_base_field_info().
     */
    function my_commerce_entity_base_field_info( EntityTypeInterface $entity_type ) {
      $fields = array();
    
      // add opening hours text area field to commerce shipping methods
      if ($entity_type->id() === 'commerce_shipping_method') {
        $fields['opening_hours'] = BaseFieldDefinition::create( 'text_long' )
          ->setLabel( t( 'Opening Hours' ) )
          ->setDescription( t( 'You can provide opening hours to physical pickup/payments points.' ) )
          ->setRevisionable(true )
          ->setTranslatable( true )
          ->setSetting( 'target_type', 'commerce_shipping_method' )
          ->setSetting( 'handler', 'default' )
          ->setSetting( 'handler', 'default' )
          ->setDisplayOptions('form', array(
            'type' => 'text_textarea',
            'settings' => array(
              'display_label' => true,
            ),
          ))
          ->setDisplayOptions('view', [
            'label' => 'hidden',
            'type' => 'text_long',
            'weight' => 0,
          ])
          ->setCardinality( 1 )
          ->setDisplayConfigurable( 'form', true );
      }
    
      return $fields;
    }
    

    my_commerce.install

    While the .module file will show the Opening Hours textarea on the opening hours form, this part handles saving the value for that field into the database.

    /**
     * Add opening hours field to all shipping methods.
     */
    function my_commerce_update_9006() {
      $field_storage_definition = BaseFieldDefinition::create( 'text_long' )
        ->setLabel( t( 'Opening Hours' ) )
        ->setDescription( t( 'You can provide opening hours to physical pickup/payments points.' ) )
        ->setRevisionable(true )
        ->setTranslatable( true )
        ->setSetting( 'target_type', 'commerce_shipping_method' )
        ->setSetting( 'handler', 'default' )
        ->setDisplayOptions('form', array(
          'type' => 'text_textarea',
          'settings' => array(
            'display_label' => true,
          ),
        ))
          ->setDisplayOptions('view', [
            'label' => 'hidden',
            'type' => 'text_long',
            'weight' => 0,
          ])
        ->setCardinality( 1 )
        ->setDisplayConfigurable( 'form', true );
    
      \Drupal::entityDefinitionUpdateManager()
        ->installFieldStorageDefinition('opening_hours', 'commerce_shipping_method', 'commerce_shipping_method', $field_storage_definition);
    }