eCommerce for php7

The long term future of concrete5.6 is now ensured through an update to make it php7 compatible. The update is currently on GitHub and not officially released. However, many sites are now running this c5.6 core version and with php7 compatibility comes an approximate 30% update is speed.

Having updated Zone Based Shipping to be fully compatible, the next hurdle was to get the core eCommerce addon running as smoothly as possible under php7 and the prospective c5.6.4 on github.

For anyone else doing similar, here is a summary of the code changes I have found necessary. Line numbers may not be precise because the cumulative effect of changes can shift them down a bit.

core_commerce/libraries/discount/controller.php [controller.php at line 34, column 50]

public function setupAndRun($method=null) // php7, make optional

core_commerce/libraries/payment/controller.php [controller.php at line 19, column 50]

public function setupAndRun($method=null) // php7, make optional

core_commerce/libraries/shipping/controller.php [controller.php at line 25, column 50]

public function setupAndRun($method=null) // php7, make optional

core_commerce/models/attribute/categories/core_commerce_order.php [core_commerce_order.php at line 15, column 54]

public function load($akID, $loadBy = 'akID') // php7, match parameters

core_commerce/models/attribute/categories/core_commerce_product.php [core_commerce_product.php at line 55, column 54]

public function load($akID, $loadBy = 'akID') // php7, match parameters

core_commerce/models/attribute/categories/core_commerce_product_option.php [core_commerce_product_option.php at line 95, column 62]

public static function sortListByDisplayOrder($a, $b) // php7

[core_commerce_product_option.php at line 156, column 54]

public function load($akID, $loadBy = 'akID') // php7, match parameters

[core_commerce_product_option.php at line 166, column 55]

public function duplicate($product = array())  // php7 =array(). This is actually be a product object, the array() is misdirection to be compatible with the parent class.

core_commerce/models/attribute/types/product_price_adjustment_select/controller.php [controller.php at line 432, column 51]

public function validateKey($args = false) // php7, match parameters

[controller.php at line 523, column 79]

public function getSelectAttributeOptionDisplayValue($format = 'html') // php7, match parameters

[controller.php at line 584, column 63]

public static function getByValue($value, $ak = false) // php7, match parameters

This resolves everything in a benign way, except for one really bad parameter mismatch in core_commerce/models/attribute/types/product_price_adjustment_select/controller.php,

CoreCommerceProductAdjustmentSelectAttributeTypeOption::add

The solution to that is a bit more hacky, to suppress the warning. I found and adapted a trick on stack overflow. Rather than suppress all warnings, or all declaration warnings, I adapted this to catch the specific warning.

if (PHP_MAJOR_VERSION >= 7) {
    set_error_handler(function ($errno, $errstr) {
        if(strpos($errstr, 'Declaration of CoreCommerceProductAdjustmentSelectAttributeTypeOption::add') === 0){
            return true;
        }
    }, E_WARNING);
}

For convenience I currently have this code at the bottom of /config/site.php.

The snippet could be adapted to target other specific warnings, though it is always better to resolve the source of the problem.

I now have eCommerce running under php7 with Zone Based Shipping.

php7.2 Compatibility

 For compatibility with php7.2 we need some further changes because 'Object' is now reserved. In the core this is replaced with 'ConcreteObject'.

// file models/cart.php
class CoreCommerceCart extends ConcreteObject

// file models/discount/type.php
class CoreCommerceDiscountType extends ConcreteObject

// file models/discount/model.php
class CoreCommerceDiscount extends ConcreteObject

// file models/attribute/types/product_price_adjustment_select/controller.php
class SelectAttributeTypeOptionList extends ConcreteObject implements Iterator {

// file models/product/tiered_price.php
class CoreCommerceProductTieredPrice extends ConcreteObject

// file models/product/set.php
class CoreCommerceProductSet extends ConcreteObject

// file models/product/display_property.php
class CoreCommerceProductDisplayPropertyList extends ConcreteObject

// file models/product/model.php
class CoreCommerceProduct extends ConcreteObject

// file models/shipping/type.php
class CoreCommerceShippingType extends ConcreteObject

// file models/shipping/method.php
class CoreCommerceShippingMethod extends ConcreteObject

// file models/payment/method.php
class CoreCommercePaymentMethod extends ConcreteObject

// file models/sales/tax/rate.php
class CoreCommerceSalesTaxRate extends ConcreteObject

// file models/order/line_item.php
class CoreCommerceOrderLineItem extends ConcreteObject

// file models/order/status_history.php
class CoreCommerceOrderStatusHistory extends ConcreteObject

// file models/order/product.php
class CoreCommerceOrderProduct extends ConcreteObject

// file models/order/model.php
class CoreCommerceOrder extends ConcreteObject

Finally, if we also require the edited code to be backwards compatible, we need to make sure ConcreteObject is declared. A convenient place to add this is at the end of the package controller, but it can be declared pretty much anywhere as long as it is evaluated before it is referenced. It doesn't matter if you have the code in multiple places, so it could also be added at the top of all the above files.

if(!class_exists('ConcreteObject') && class_exists('Object')){
    class ConcreteObject extends Object {}
}

 

Last updated: last month