Upgrade Guide: v2.4 to v3.0
Overview
Simple Commerce v3.0 comes with a bunch of new features, including some big quality of life improvements, for both developers and back-office users. In addition, there's a number of breaking changes, especially if you're doing custom 'things' with Simple Commerce.
To get started with the upgrade process, follow the below steps:
1. In your composer.json
file, update the doublethreedigital/simple-commerce
version constraint:
1"doublethreedigital/simple-commerce": "3.0.*"
2. Then run:
1composer update doublethreedigital/simple-commerce --with-dependencies
3. You may also want to clear your route & view caches:
1php artisan route:clear2php artisan view:clear
4. Simple Commerce will have attempted upgrading some things for you (config changes, blueprint updates, etc). However, it's highly likely you will need to make some manual changes, along with some testing. Please test before you push to production!
Changes
High: API Changes
Internally, a lot has changed in terms of how things are structured, how you access data, etc. If you've written any kind of custom code at all, you'll need to make some manual code changes.
I've noted all of the changes below - however, this isn't by far everything - you may review the related PR for more information.
Content Drivers
SC v3 changes the way 'content drivers' work. Instead of the driver being the Order/Customer class itself, it's a repository (which is inline with how Statamic does it). Essentially, if you need to use a database or third-party to store your data, you'd create a repository which implements the required methods, instead of creating an entire Order/Customer class - hopefully that explanation makes sense.
During the upgrade process, Simple Commerce should have updated your config to represent this change:
1'content' => [ 2 'coupons' => [ 3 'repository' => \DoubleThreeDigital\SimpleCommerce\Coupons\EntryCouponRepository::class, 4 'collection' => 'coupons', 5 ], 6 7 'customers' => [ 8 'repository' => \DoubleThreeDigital\SimpleCommerce\Customers\EntryCustomerRepository::class, 9 'collection' => 'customers',10 ],11 12 'orders' => [13 'repository' => \DoubleThreeDigital\SimpleCommerce\Orders\EntryOrderRepository::class,14 'collection' => 'orders',15 ],16 17 'products' => [18 'repository' => \DoubleThreeDigital\SimpleCommerce\Products\EntryProductRepository::class,19 'collection' => 'products',20 ],21],
Important!
During the upgrade, SC will reset the 'repositories' to the new defaults. If you were using another content driver, you must re-configure this post-update.
If you were implementing a custom 'content driver' previously for something, you will need to review the changes and refactor your implementation. If it helps, here's a link to view the 'interfaces' behind SC's Data stuff.
Changes to how you access data
Along with content drivers working differently - how you access/save data will have also changed:
Creating Products/Customers/Orders/Coupons
Previously:
1$order = Order::create([ 2 'items' => [ 3 [ 4 'product' => 'abc', 5 'quantity' => 1, 6 'total' => 1255, 7 ], 8 ], 9 'items_total' => 1255,10 'gift_note' => 'This is a very special note.',11]);
Now:
1$order = Order::make() 2 ->lineItems([ 3 [ 4 'product' => 'abc', 5 'quantity' => 1, 6 'total' => 1255, 7 ], 8 ]) 9 ->itemsTotal(1255)10 ->data([11 'gift_note' => 'This is a very special note.',12 ]);13 14$order->save();
A lot of 'things' on Data Models are now properties which can be modified using fluent getter/setters. Anything outside of a property can be set using ->data()
, ->set()
or ->merge()
. We're now using the same pattern for making/saving as Statamic itself.
Getting the 'grand total' from an order
Previously:
1$order = Order::find('123');2 3$order->get('grand_total');
Now:
1$order = Order::find('123');2 3$order->grandTotal();
Getting the original entry
Previously:
1$order = Order::find('123');2 3$order->entry();
Now:
1$order = Order::find('123');2 3$order->resource();
Line Items
When accessing Line Items, you'll no longer receive an array, you'll now receive an instance of the LineItem
class.
Previously:
1$lineItem = $order->lineItems()->first();2 3$product = Product::find($lineItem['product']);4$quantity = $lineItem['quantity'];5$giftNote = $lineItem['metadata']['gift_note'];
Now:
1$lineItem = $order->lineItems()->first();2 3$product = $lineItem->product();4$quantity = $lineItem->quantity();5$giftNote = $lineItem->metdata()->get('gift_note');
Namespace changes
If you were previously referencing any of these classes, you should update your references to their new namespaces:
-
DoubleThreeDigital\SimpleCommerce\Support\Currency
->DoubleThreeDigital\SimpleCommerce\Currency
-
DoubleThreeDigital\SimpleCommerce\Support\Country
->DoubleThreeDigital\SimpleCommerce\Country
-
DoubleThreeDigital\SimpleCommerce\Support\Regions
->DoubleThreeDigital\SimpleCommerce\Regions
You should also note that any references to the Currency/Country/Region facades should now be updated to these new namespaces. The usage remains the same.
High: Field Whitelisting (Partially automated)
To improve the security of your site, we've introduced a 'whitelist' for the fields that will be saved from Simple Commerce's front-end forms.
Previously, Simple Commerce would save anything provided in a request (for example: on the request to add a product to the cart) to your order entry.
Now, Simple Commerce will only save the request data from the fields you've whitelisted in the Simple Commerce config.
1// config/simple-commerce.php 2 3/* 4|-------------------------------------------------------------------------- 5| Field Whitelist 6|-------------------------------------------------------------------------- 7| 8| You may configure the fields you wish to be editable via front-end forms 9| below. Wildcards are not accepted due to security concerns.10|11| https://simple-commerce.duncanmcclean.com/tags#field-whitelisting12|13*/14 15'field_whitelist' => [16 'orders' => [17 'shipping_name', 'shipping_address', 'shipping_address_line1', 'shipping_address_line2', 'shipping_city',18 'shipping_region', 'shipping_postal_code', 'shipping_country', 'shipping_note', 'shipping_method',19 'use_shipping_address_for_billing', 'billing_name', 'billing_address', 'billing_address_line2',20 'billing_city', 'billing_region', 'billing_postal_code', 'billing_country',21 ],22 23 'line_items' => [],24 25 'customers' => ['name', 'email'],26],
This step should be partially automated during the upgrade process. After upgrading, you should see the field_whitelist
array appear in your simple-commerce.php
config file. Simple Commerce will have pulled any fields from your order blueprint that aren't 'reserved' (eg. fields like is_paid
, they're ones you probably don't want users to be able to fill).
High: Shipping Method configs
Simple Commerce now allows for passing configuration arrays for shipping methods. However, for this to work, shipping methods must be updated to extend upon the BaseShippingMethod
class provided by Simple Commerce.
1<?php 2 3namespace App\ShippingMethods; 4 5use DoubleThreeDigital\SimpleCommerce\Contracts\ShippingMethod; 6use DoubleThreeDigital\SimpleCommerce\Shipping\BaseShippingMethod; 7 8class FirstClass extends BaseShippingMethod implements ShippingMethod 9{10 //11}
If you wish to start passing in config variables to your shipping methods, you may do it like so:
1'sites' => [ 2 'default' => [ 3 ... 4 5 'shipping' => [ 6 'methods' => [ 7 \DoubleThreeDigital\SimpleCommerce\Shipping\StandardPost::class => [ 8 'config' => 'setting', 9 'foo' => 'bar',10 ],11 ],12 ],13 ],14],
And inside the shipping method, you may do $this->config()->get('key')
to get a specific config value.
Medium: Order Emails
Previously, Simple Commerce would send a fairly basic email with a PDF receipt attached.
In v3, the receipt PDF has been removed from order emails. Instead, email body's contain a table with the order line items, along with any customer information which is displayed below.
Continue with previous behaviour
If you wish to continue using the previous behaviour (where you get a simple email, along with a PDF receipt), follow these steps:
- Copy the notification class from inside Simple Commerce and place it inside an
app/Notifications
folder. Keep the same filename. - Change the namespace for the notification from SC's one to your
App
one:
1<?php 2 3namespace DoubleThreeDigital\SimpleCommerce\Notifications; 4namespace App\Notifications; 5 6use Barryvdh\DomPDF\Facade as PDF; 7use DoubleThreeDigital\SimpleCommerce\Contracts\Order; 8use Illuminate\Bus\Queueable; 9use Illuminate\Notifications\Messages\MailMessage;10use Illuminate\Notifications\Notification;11 12class CustomerOrderPaid extends Notification13{
- Next, you'll need to require the DomPDF library which is no longer required for you by Simple Commerce. DomPDF is the library which generates the receipt PDFs.
1composer require dompdf/dompdf
- Last but not least, update your Simple Commerce config file to use your copy of the built-in notifications.
1// config/simple-commerce.php 2 3'notifications' => [ 4 'order_paid' => [ 5 \DoubleThreeDigital\SimpleCommerce\Notifications\CustomerOrderPaid::class => [ 6 \App\Notifications\CustomerOrderPaid::class => [ 7 'to' => 'customer', 8 ], 9 ],10 11 // ...12],
Medium: Order Confirmation page
Although not technically a breaking change, it's worth noting as it may help to cleaup your code.
On the 'Order Confirmation' page (the one after checking out), you'd previously have to use the {{ session:cart }}
tag in order to access the previous cart. However, now you may use Simple Commerce's cart tags like normal.
Previously:
1{{ session:cart }}2 Thanks for your order ({{ title }}), {{ customer:title }}3{{ /session:cart }}
Now:
1{{ sc:cart }}2 Thanks for your order ({{ title }}), {{ customer:title }}3{{ /sc:cart }}
Medium: Removed 'Sales Widget'
Simple Commerce v3.0 drops the Sales Widget which could optionally be added to your Control Panel Dashboard. It's now recommended to take advantage of the Overview page for this same (and more) functionality.
Low: Gateway & Shipping Method fields
During the upgrade process, Simple Commerce should have added two new fields to your Order blueprint. A Gateway field and a Shipping Method field. These fields should hopefully be useful for your CP users to be able to see the gateway/shipping method that's being used for an order.
The fields will automatically be pushed into the Sidebar of the Order blueprint, you may move it as you wish.
Note!
When using the Stripe Gateway, past orders will show 'Unknown' as the payment ID. Future orders will show the payment ID as expected - this is due to some data which was missing prior to v3.
Low: Higher System Requirements
Simple Commerce v3 requires you to be using PHP 8.0 (and above), along with Laravel 8 (and above) and Statamic 3.3. Adjusting the system requirements encourages developers to stay up to date and means Simple Commerce can take advantage of new features.
Low: Order Numbers (Automated)
In the past, order numbers would be stored as part of the title on Order entries.
However, SC v3 has taken advantage of a Statamic feature called 'title formats'. This means we store the order number in it's own field, order_number
(hidden field, added during upgrade).
Then, Simple Commerce will configure the title format to be like so: #xxxx
.
Running into an issue upgrading?
Like I say, quite a lot has changed between v2.4 and v3.0 so if you're running into issues upgrading, please either open a GitHub Issue or send me an email. I'll try and help as best I can.