Advanced Shipping by Owebia

Documentation

Overview

Advanced Shipping is an extension for the e-commerce solution Magento.

The syntax using PHP 7 allows a great flexibility in setting delivery charges.

Technical Informations

The usage of the PHP syntax (with an Abstract Syntax Tree) has been preferred to the usage of a JSON syntax (with regular expressions and the eval function) as in previous versions of the extension. This is the result of considerations on security and performance.

The PHP code defined in the configuration is not evaluated with the eval function for security reasons. The library PHP-Parser is used to obtain an Abstract Syntax Tree (AST). The AST is browsed and only a limited set of functions and variables is allowed.

The AST is not version-dependent, you can use the PHP syntax supported by the parser.

Add-Ons

You want to do more with Advanced Shipping?

Discover our add-ons on Owebia Store.

What's New?

Quick Start

Installation

Please note that you can only install the extension using composer.

  • Backup your store database and web directory
  • Open a terminal and move to Magento root directory
  • Run these commands in your terminal
                    # You must be in Magento root directory
                    composer require owebia/magento2-module-advanced-shipping:^6.0.3
                    php bin/magento cache:clean
                    php bin/magento module:enable Owebia_SharedPhpConfig Owebia_AdvancedShipping
                    php bin/magento setup:upgrade
                    php bin/magento setup:di:compile

                    # Only if the store is in production mode
                    # Deploy static content for each used locale (here for en_US locale only)
                    php bin/magento setup:static-content:deploy en_US
                
  • If you are logged to Magento backend, logout from Magento backend and login again

Configuration

A call to addMethod function adds a shipping method.

addMethod (
string $method_id ,
array $method_properties
) : object

List of method properties:

  • title
  • price
  • description (optional, not available on Magento frontend without code customization)
  • enabled (optional): conditions for displaying the shipping method

More examples

Warning: to avoid conflicts, use only the characters a-z, 0-9 and _ for the method id.
You should also avoid identifiers that already correspond to variable names (quote, request…).

References

Introduction

You can use variables, functions and operators to define a dynamic value (all operators are not supported).

Variables

There are global variables and local variables that you can access with array functions and callbacks.

If you activate the debug option, you can see all data available for each object that you use.
Remember that you don't have access to all methods of the original objects because they are not accessed directly.

Global Variables

These variables are global variables and can be accessed everywhere (use the global keyword when you are inside a function).

The request object (\Magento\Quote\Model\Quote\Address\RateRequest) given by Magento:

  • $request->all_items: array of items in cart
  • The source address:
    • $request->country_id *
    • $request->region_id
    • $request->city
    • $request->postcode
  • The destination address:
  • The package:
    • $request->package_value: value of the package
    • $request->package_value_with_discount: value of the package with discount
    • $request->package_weight: weight of the package
    • $request->package_qty: number of products in the package
  • Other attributes:
    • $request->free_shipping: free shipping calculated by Magento rules
    • $request->*: property of the request object

The quote (\Magento\Quote\Model\Quote): (known issue #2, known issue #3):

  • $quote->subtotal: subtotal (excluding tax)
  • $quote->subtotal_with_discount: subtotal (excluding tax) with discount (known issues #6, use $quote->getShippingAddress()->subtotal_with_discount instead)
  • $quote->grand_total: total (including tax) with discount (known issues #3, you should avoid using this value)
  • $quote->base_subtotal: subtotal (excluding tax) in base currency
  • $quote->base_subtotal_with_discount: subtotal (excluding tax) with discount in base currency
  • $quote->base_grand_total: total (including tax) with discount in base currency (known issues #3, you should avoid using this value)
  • $quote->coupon_code: the coupon code used in cart
  • $quote->*: property of the quote (e.g. $quote->subtotal)

The customer group (\Magento\Customer\Model\Group):

  • $customer_group->id: alias of $customer_group->customer_group_id
  • $customer_group->code: alias of $customer_group->customer_group_code
  • $customer_group->name: alias of $customer_group->customer_group_code
  • $customer_group->*: property of the customer group (e.g. $customer_group->tax_class_id)

The customer (\Magento\Customer\Model\Customer):

  • $customer->id: alias of $customer->entity_id
  • $customer->*: attribute of the customer (e.g. email, lastname, firstname, group_id…)
  • $customer->getCustomAttribute('my_custom_attribute')->value: custom attribute of the customer (where 'my_custom_attribute' should be replaced by custom attribute's code)

Custom variables (\Magento\Variable\Model\Variable, examples):

  • $variable->*: custom variable defined in Magento
    e.g. with $variable->my_var:
    • $variable->my_var->plain_value
    • $variable->my_var->html_value
    • $variable->my_var->code
    • $variable->my_var->name

The store (\Magento\Store\Model\Store):

  • $store->id, $store->code, $store->name, $store->address, $store->phone

The app (see \Magento\Framework\App\State):

  • $app->area_code
  • $app->isAdminArea() (area_code == 'adminhtml')
  • $app->isFrontendArea() (area_code == 'webapi_rest')

* Magento apparently uses the ISO 3166-1 alpha-2 codes.
Note that the country code for United Kingdom is GB and not UK.

Accessing Items

You can use $request->all_items with array functions.

The item (\Magento\Quote\Model\Quote\Item)

  • $item->qty
    quantity of the item
  • $item->weight
    weight of the item
  • $item->base_original_price
    price excluding tax without discount
  • $item->price_incl_tax
    price including tax without discount
  • $item->options->*
    option (the available options depend on the product)

The product (\Magento\Catalog\Model\Product)

  • $item->product->*
    • sku
    • name
    • weight
    • price (as defined in Magento backoffice)
    • special_price: (as defined in Magento backoffice)
    • tax_class_id: the taxclass id
    • getAttributeText('tax_class_id'): the tax class name
      To get the text value of an attribute of type select, use getAttributeText('attribute_code')
    • getSourceItems(): returns an array of \Magento\InventoryApi\Api\Data\SourceItemInterface to handle Inventory Management (Magento ≥ 2.3)
      Source item: (\Magento\InventoryApi\Api\Data\SourceItemInterface)
      • $sourceItem->*: attribute of the source item
        • source_code: the code of the inventory source
        • quantity: the quantity of the product in the inventory source
  • Categories of the product: (\Magento\Catalog\Model\Category)
    • $item->product->category->*
    • attribute of the first category
      • id
      • name
      • is_active
  • All product categories (returns an array, examples)
    • $item->product->category_ids
      array of id of the categories
  • The attribute set (\Magento\Eav\Model\Entity\Attribute\Set)
    • $item->product->attribute_set
      the attribute set
    • $item->product->attribute_set->*
      attribute of the attribute set
      • id
      • attribute_set_name
  • The stock item (\Magento\CatalogInventory\Model\Stock\Item)
    • $item->product->stock_item->*
      attribute of the product stock
      • is_in_stock
      • qty

Functions

Core Functions

  • __ (
    string $string_to_translate
    ) : string

    Translates the input string, see example (known issue #4)

  • addMethod (
    string $method_id ,
    array $method_properties
    ) : object

    Adds a new shipping method

  • addError (
    string $message
    ) : object

    Adds an error, see example

  • getMethods (
    [ bool $only_enabled = false ]
    ) : array

    Gets an array of defined shipping methods, if $only_enabled is true, only enabled methods will be returned, see example

Native Functions Allowed

Look at the PHP documentation if you want to know how to use these functions.

Functions Available with Functions Add-On

  • _country (
    string $country_id1
    [, string $... ]
    ) : bool

    Returns true if the destination country matches one of the given country IDs, see examples

  • _postcode (
    string $postcode_or_pattern1
    [, mixed $... ]
    ) : bool

    Returns true if the destination postcode matches one of the given postcodes or regular expression patterns, see examples

  • _customerGroup (
    mixed $customer_group_id_or_name1
    [, mixed $... ]
    ) : bool

    Returns true if the customer group matches one of the given ids or names, see examples

  • _sum (
    mixed $value1
    [, mixed $... ]
    ) : mixed

    Returns the sum of the given values, see examples

  • _min (
    mixed $value1
    [, mixed $... ]
    ) : mixed

    Returns the minimum of the given values, see examples

  • _max (
    mixed $value1
    [, mixed $... ]
    ) : mixed

    Returns the maximum of the given values, see examples

  • _count (
    callable $callback
    ) : int

    Returns the number of matching items using a callback function, see examples

  • _anyCat (
    object $item ,
    int $category_id1
    [, int $... ]
    ) : bool

    Returns true if the item belongs to one of the given categories, see examples

  • _allCat (
    object $item ,
    int $category_id1
    [, int $... ]
    ) : bool

    Returns true if the item belongs to all given categories, see examples

  • _table (
    array $table
    [, string $attribute_name = 'package_weight'
    [, bool $include_upper_limit = true ]]
    ) : mixed

    Returns true if the item belongs to all given categories, see examples

  • _setStopAtFirstMatch (
    bool $stop_at_first_match
    ) : void
    Sets option to stop adding methods at first match (must be used at the beginning of the configuration)

Examples

Free Shipping

Filter on Destination

France Excluding DOM/TOM

Filter on Customer Group

You can use the name or ID of the customer groups.

Using Formulas

Formulas can be used to calculate the price of the delivery.

Using the configuration of another element:

Using Special Functions

Defining a Table

Using an Associative Table

Using Attributes and Options of Products

Count Items

Get Minimum Value, Get Maximum Value

Sum

Using Categories

Warning: you must notice that in Magento, a product can be in multiple categories.
So be particularly careful how you use this property.

Using Custom Variables

Tips

if/elseif/else Statements

Customer Data

Access New Customer Data (e.g. VAT ID)

Known issue with Magento CE < 2.1.8.

Using Custom Customer Attribute

In the following example, my_custom_attribute is a custom customer attribute created by a custom extension.

Translate a String

You can translate a string by using the __ function (two underscore characters). It will use Magento dictionary to translate the input string.

Method Chaining

Display in Frontend

Display Error When No Method Is Available

Add this at the end of your configuration:

Display Method Description in Frontend

Read Magento DevDocs to understand how to override a template.

Display Custom Method Data in Frontend

Read Magento DevDocs to understand how to override a template.

Anonymous Functions

You can assign an anonymous function to a variable in order use it later.

Known Issues

Issue #1: Magento < 2.1.8

With earlier version than CE 2.1.8, Magento does not correctly update some variables: $request->dest_street, $request->dest_city and $quote->getShippingAddress()->*

Issue #2: Infinite Loop with Quote

With some configurations, you can enter in an infinite loop when using $quote variable.
If you have more information on this issue, please contact us.

Issue #3: Quote Grand Total

You can encounter unexpected behaviors when using $quote->grand_total and $quote->base_grand_total as these values include shipping fees.

Issue #4: Theme Translations

If your translations are defined in a theme, they may not work properly (see Magento issue #26333).

Issue #5: Deprecated Functionality Passing null to parameter (PHP 8.1+)

When running your store under a version of PHP that is greater or equal to 8.1, you may have errors like this: `Deprecated Functionality: preg_match(): Passing null to parameter #2 ($subject) of type string is deprecated`

This is due to the fact that PHP 8.1+ deprecated passing null to non-nullable parameters of built-in functions (see PHP 8.1: Deprecated Features).

You can use the coalesce operator ?? to ensure you have a non-null parameter.

Since version 6.0.1 of the module, we ensure that $request->all_items is an array and that $request->dest_postcode is a string but you will have to use ?? for other variables if necessary.