TransWikia.com

How can I programatically add a shipping method to a store?

Drupal Answers Asked by vintorg on September 4, 2020

I am using Commerce with Marketplace, and am using the Shipping module.

In my commerce marketplace, users become sellers via a custom form, where I create the store entity on submit. Currently, to attach a shipping method, it has to be done in commerce admin via a checkbox:

Shipping method admin screen

My marketplace can have an unlimited number of stores, making management of them via checkboxes unfeasible. How can I add a shipping method to a store? There’s a table commerce_shipping_method__stores:

enter image description here

Can I simply make an insert into this table and set the stores_target_id value to the new store id after the new store is created?

One Answer

With custom module code, you can add a new store like this:

function mymodule_entity_insert(DrupalCoreEntityEntityInterface $entity) {

  if ($entity instanceof Drupalcommerce_storeEntityStoreInterface) {

      $sm_id = 1; // I can see Shipping Method ID is 1 from your table screenshot
      $shipping_method = Drupalcommerce_shippingEntityShippingMethod::load($sm_id);
      $store_ids = $shipping_method->getStoreIds(); // get existing IDs
      $new_store_id = $entity->id(); // get new id
      $store_ids[] = $new_store_id; // add new to existing
      $shipping_method->setStoreIds($store_ids); // set
      $shipping_method->save();

  }

}

In the above code, when a store is created, it automatically adds it to the shipping method.


But if your question is to add already existing stores to the shipping method, then run this code only once:

      $sm_id = 1; // I can see Shipping Method ID is 1 from your table screenshot
      $shipping_method = Drupalcommerce_shippingEntityShippingMethod::load($sm_id);
      $store_ids = [1, 2, 3, 4, 5, 6]; // Array of all the store IDs that belong to this shipping method.
      $shipping_method->setStoreIds($store_ids); // set
      $shipping_method->save();

The better API solution

Thanks to 4k4's answer I was able to commeup with a more efficient solution.

function mymodule_entity_insert(DrupalCoreEntityEntityInterface $entity) {

  if ($entity instanceof Drupalcommerce_storeEntityStoreInterface) {

      $sm_id = 1; // I can see Shipping Method ID is 1 from your table screenshot
      $shipping_method = Drupalcommerce_shippingEntityShippingMethod::load($sm_id);
      $new_store_id = $entity->id(); // get new id
      $shipping_method->{'stores'}[] = $new_store_id; // appends new store to existing list.
      $shipping_method->save();

  }

}

Manual Solution

Quick follow up, do I have to load all the stores at once? When I have 1000+ stores and more, that seems like it will be a little resource intensive. Is it possible to just add the new store?

At this point, you wouldn't want to use the entity API and do Drupalcommerce_shippingEntityShippingMethod::load as this would contain all the 1000+ store IDs, you will have to manually DB query & insert:

function mymodule_entity_insert(DrupalCoreEntityEntityInterface $entity) {

  if ($entity instanceof Drupalcommerce_storeEntityStoreInterface) {

    $sm_id = 1; // Shipping Method ID
    $connection = Drupal::database();

    $query = $connection->select('commerce_shipping_method__stores', 'csms');
    $query->range(0, 1)
      ->orderBy('delta', 'DESC')
      ->condition('csms.entity_id', $sm_id)
      ->addField('csms', 'delta');
    $last_delta = $query->execute()->fetchField();
    $new_delta = $last_delta + 1;
    $new_store_id = $entity->id(); // new store ID

    $insert = $connection->insert('commerce_shipping_method__stores')
      ->fields([
        'entity_id' => $sm_id,
        'stores_target_id' => $new_store_id,
        'revision_id' => $sm_id,
        'delta' => $new_delta,
        'bundle' => 'commerce_shipping_method',
        'langcode' => 'en',
      ])
      ->execute();

    $storage = Drupal::entityTypeManager()
      ->getStorage('commerce_shipping_method');
    $storage->resetCache([$sm_id]); // Flush Cache

  }

}

Correct answer by No Sssweat on September 4, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP