Id of shipping method services type is sometimes an integer

Created on 20 June 2024, 10 months ago

Problem/Motivation

Some shipping method plugins provide lists of services with numerical ids

commerce_ups example:

/**
 * Provides the UPS shipping method.
 *
 * @CommerceShippingMethod(
 *  id = "ups",
 *  label = @Translation("UPS"),
 *  services = {
 *    "01" = @translation("UPS Next Day Air"),
 *    "02" = @translation("UPS Second Day Air"),
 *    "03" = @translation("UPS Ground"),
 *    "07" = @translation("UPS Worldwide Express"),
 *    "08" = @translation("UPS Worldwide Expedited"),
 *    "11" = @translation("UPS Standard"),
 *    "12" = @translation("UPS Three-Day Select"),
 *    "13" = @translation("UPS Next Day Air Saver"),
 *    "14" = @translation("UPS Next Day Air Early AM"),
 *    "54" = @translation("UPS Worldwide Express Plus"),
 *    "59" = @translation("UPS Second Day Air AM"),
 *    "65" = @translation("UPS Saver"),
 *    "70" = @translation("UPS Access Point Economy"),
 *  }
 * )
 */

In src/Plugin/Commerce/ShippingMethod/ShippingMethodBase.php a list of ShippingServices is created when the class is invoked.

Some of the above ids are set as strings eg: "01" while others are integers eg: "65".

src/ShippingService.php makes it clear the id is a string, not an integer

This issue is probably related to this #3179322: Duplicate services in shipping method configuration β†’

Proposed resolution

When creating the list of services ensure the type for $id is set to string

    foreach ($this->pluginDefinition['services'] as $id => $label) {
      $this->services[$id] = new ShippingService((string) $id, (string) $label);
    }
πŸ› Bug report
Status

Active

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States rhovland Oregon

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

Comments & Activities

  • Issue created by @rhovland
  • πŸ‡ΊπŸ‡ΈUnited States rhovland Oregon

    This piece of code seems to be using the array key instead of the service id and that results in automatic type casting to integers

       $services = array_map(function ($service) {
          return $service->getLabel();
        }, $this->services);
  • πŸ‡ΊπŸ‡ΈUnited States rhovland Oregon

    I can't figure out how to fix this because PHP automatically casts array keys to int if they look like one and there is no way to control this behavior. The $services variable is fed into the form options as an array.

    I tried the following

        $services = [];
        foreach ($this->services as $service) {
          $services[(string) $service->getId()] = $service->getLabel();
        }
Production build 0.71.5 2024