Upgrading
General Upgrade Instructions
Update the package
composer update lunarphp/lunar
Run any migrations
php artisan migrate
Support Policy
Lunar currently provides bug fixes and security updates for only the latest minor release, e.g. 0.8
.
[Unreleased]
High Impact
Shipping methods availability
Shipping methods are now associated to Customer Groups. If you are using the shipping addon then you should ensure that all your shipping methods are associated to the correct customer groups.
Stripe Addon
The Stripe addon will now attempt to update an order's billing and shipping address based on what has been stored against the Payment Intent. This is due to Stripe not always returning this information during their express checkout flows. This can be disabled by setting the lunar.stripe.sync_addresses
config value to false
.
PaymentIntent storage and reference to carts/orders
Currently, PaymentIntent information is stored in the Cart model's meta, which is then transferred to the order when created.
Whilst this works okay it causes for limitations and also means that if the carts meta is ever updated elsewhere, or the intent information is removed, then it will cause unrecoverable loss.
We have now looked to move away from the payment_intent key in the meta to a StripePaymentIntent model, this allows us more flexibility in how payment intents are handled and reacted on. A StripePaymentIntent will be associated to both a cart and an order.
The information we store is now:
intent_id
- This is the PaymentIntent ID which is provided by Stripestatus
- The PaymentIntent statusevent_id
- If the PaymentIntent was placed via the webhook, this will be populated with the ID of that eventprocessing_at
- When a request to place the order is made, this is populatedprocessed_at
- Once the order is placed, this will be populated with the current timestamp
Preventing overlap
Currently, we delay sending the job to place the order to the queue by 20 seconds, this is less than ideal, now the payment type will check whether we are already processing this order and if so, not do anything further. This should prevent overlaps regardless of how they are triggered.
1.0.0-alpha.34
Medium Impact
Stripe Addon
The Stripe driver will now check whether an order has a value for placed_at
against an order and if so, no further processing will take place.
Additionally, the logic in the webhook has been moved to the job queue, which is dispatched with a delay of 20 seconds, this is to allow storefronts to manually process a payment intent, in addition to the webhook, without having to worry about overlap.
The Stripe webhook ENV entry has been changed from STRIPE_WEBHOOK_PAYMENT_INTENT
to LUNAR_STRIPE_WEBHOOK_SECRET
.
The stripe config Lunar looks for in config/services.php
has changed and should now look like:
'stripe' => [
'key' => env('STRIPE_SECRET'),
'public_key' => env('STRIPE_PK'),
'webhooks' => [
'lunar' => env('LUNAR_STRIPE_WEBHOOK_SECRET'),
],
],
1.0.0-alpha.32
High Impact
There is now a new LunarUser
interface you will need to implement on your User
model.
// ...
class User extends Authenticatable implements \Lunar\Base\LunarUser
{
use \Lunar\Base\Traits\LunarUser;
}
1.0.0-alpha.31
High Impact
Certain parts of config/cart.php
which are more specific to when you are interacting with carts via the session have been relocated to a new config/cart_session.php
file.
// Move to config/cart_session.php
'session_key' => 'lunar_cart',
'auto_create' => false,
You should also check this file for any new config values you may need to add.
1.0.0-alpha.29
High Impact
Cart calculate function will no longer recalculate
If you have been using the $cart->calculate()
function it has previously always run the calculations regardless of whether the cart has already been calculated. Now the calculate function will only run if we don't have cart totals. To allow for recalculation we have now introduced $cart->recalculate()
to force the cart to recalculate.
Unique index for Collection Group handle
Collection Group now have unique index on the column handle
. If you are creating Collection Group from the admin panel, there is no changes required.
Medium Impact
Update custom shipping modifiers signature
The \Lunar\Base\ShippingModifier
handle
method now correctly passes a closure as the second parameter. You will need to update any custom shipping modifiers that extend this as follows:
public function handle(\Lunar\Models\Cart $cart, \Closure $next)
{
//..
return $next($cart);
}
1.0.0-alpha.26
High Impact
Model Extending
Model extending has been completely rewritten and will require changes to your Laravel app if you have previously extended Lunar models.
The biggest difference is now Lunar models implement a contract (interface) and support dependency injection across your storefront and the Lunar panel.
You will need to update how you register models in Lunar.
Old
ModelManifest::register(collect([
Product::class => \App\Models\Product::class,
// ...
]));
New
ModelManifest::replace(
\Lunar\Models\Contracts\Product::class,
\App\Models\Product::class
);
TIP
If your models are not extending their Lunar counterpart, you must implement the relevant contract in Lunar\Models\Contracts
Look at the model extending section for all available functionality.
Polymorphic relationships
In order to support model extending better, all polymorphic relationships now use an alias instead of the fully qualified class name, this allows relationships to resolve to your custom model when interacting with Eloquent.
There is an additional config setting in config/lunar/database.php
, where you can set whether these polymorph mappings should be prefixed in Lunar's context.
'morph_prefix' => null,
By default, this is set as null
so the mapping for a product would just be product
.
There is a migration which will handle this change over for Lunar tables and some third party tables, however you may need to add your own migrations to other tables or to switch any custom models you may have.
Medium Impact
If you are using your own classes that implement the Purchasable
interface, you will need to add the following additional methods:
public function canBeFulfilledAtQuantity(int $quantity): bool;
public function getTotalInventory(): int;
If you are checking the ProductVariant
purchasable
attribute in your code, you should update the following check:
// Old
$variant->purchasable == 'backorder';
// New
$variant->purchasable == 'in_stock_or_on_backorder';
1.0.0-alpha.22
Medium Impact
Carts now use soft deletes and a cart will be deleted when CartSession::forget()
is called. If you don't want to delete the cart when you call forget
you can pass delete: false
as a parameter:
\Lunar\Facades\CartSession::forget(delete: false);
1.0.0-alpha.20
High Impact
Stripe addon facade change
If you are using the Stripe addon, you need to update the facade as the name has changed.
// Old
\Lunar\Stripe\Facades\StripeFacade;
// New
\Lunar\Stripe\Facades\Stripe;
1.0
High Impact
Change to Staff model namespace
The Staff model has changed location from Lunar\Hub\Models\Staff
to Lunar\Admin\Models\Staff
so this will need to be updated within your codebase and any polymorphic relations.
Spatie Media Library
This package has been upgrade to version 11, which introduces some breaking changes. See here for more information https://github.com/spatie/laravel-medialibrary/blob/main/UPGRADING.md
Media Conversions
The lunar.media.conversions
configuration has been removed, in favour of registering custom media definitionss instead. Media definition classes allow you to register media collections, conversions and much more. See Media Collections for further information.
Product Options
The position
field has been removed from the product_options
table and is now found on the product_product_option
pivot table. Any position data will be automatically adjusted when running migrations.
Tiers renamed to Price Breaks
The tier
column on pricing has been renamed to min_quantity
, any references in code to tiers
needs to be updated.
Price Model
// Old
$priceModel->tier
// New
$priceModel->min_quantity
// Old
$priceModel->tiers
// New
$priceModel->priceBreaks
Lunar\Base\DataTransferObjects\PricingResponse
// Old
public Collection $tiered,
// New
public Collection $priceBreaks,
Lunar\Base\DataTransferObjects\PaymentAuthorize
Two new properties have been added to the constructor for this DTO.
public ?int $orderId = null,
public ?string $paymentType = null
0.8
No significant changes.
0.7
High Impact
TaxBreakdown casting has been refactored
Database columns which have tax_breakdown
casting will now actually cast back into the TaxBreakdown
object. This means you will need to update any storefront views or API transformers to accommodate this.
Before:
@foreach ($order->tax_breakdown as $tax)
{{ $tax->total->formatted }}
@endforeach
@foreach ($order->tax_breakdown->amounts as $tax)
{{ $tax->price->formatted }}
@endforeach
When migrations are run, a state update routine will trigger to convert all existing tax_breakdown
column. Please ensure you take a backup of your database beforehand and avoid running in production until you are satisfied the data is correct.
Medium Impact
Discount updates
Limitations and exclusions on discounts have had a revamp, please double-check all discounts you have in Lunar to ensure they are all correct. Generally speaking the integrity should be unaffected, but it's better to be sure.
Calculate lines pipeline update
If you are using unit quantities greater than 1
, there was an issue in the calculate lines pipeline which resulted in the unit quantity being applied twice, so if the price was 10
with a unit quantity of 100
it would show the unit price as 0.001
instead of 0.01
. This should be resolved going forward to show correctly.
Low Impact
Click & Collect parameter added to ShippingOption
The Lunar\DataTypes\ShippingOption
class now has an additional collect
parameter. This can be used to determine whether the shipping option is considered "collect in store". This defaults to false
so there are no additional steps if your store doesn't offer click and collect.
ShippingManifest::addOption(
new ShippingOption(
name: 'Pick up in store',
description: 'Pick your order up in store',
identifier: 'PICKUP',
price: new Price(/** .. */),
taxClass: $taxClass,
collect: true
)
);
0.6
High Impact
Search indexing refactor
Search indexing has been completely re-written to be more extendable and performant. You will need to migrate any Observer
classes that use the indexer
event to the new indexer class implementation.
The following methods have also been removed from the Searchable
trait and should be migrated.
addFilterableAttributes
addSearchableAttributes
addSortableAttributes
getObservableEvents
If you still wish to use these methods you will need to re-implement them yourself, however this is highly discouraged.
See the Search Extending
guide for more information about what indexer classes are and how to use them.
Licensing Manager has been removed
You will need ro re-run the addons discover command to update the manifest. No additional steps are required for addons.
$ php artisan lunar:addons:discover
0.5
High Impact
meta
field cast with Illuminate\Database\Eloquent\Casts\AsArrayObject
All models with meta
attribute are now cast with Laravel's AsArrayObject::class
. Change your code to get the value with $model->meta['key'] ?? 'default'
instead of $model->meta->key
, and without the need of is_object/is_array
type checking.
0.4
High Impact
Changed Lunar Hub authorization to use spatie/laravel-permission
Existing assigned staff permissions are migrated, this should not impact your project. If you have custom authorization checking using Staff->authorize('permission')
, change it to Staff->hasPermissionTo('permission')
ShippingManifestInterface
Added addOptions
, getOptionUsing
, getOption
, getShippingOption
to ShippingManifestInterface
MySQL 8.x Requirement
With MySQL 5.7 EOL coming in October 2023 and Lunar's heavy use of JSON fields, Lunar now only supports MySQL 8.x. You may find your project continues to work fine in MySQL 5.7, but we advise upgrading.
Carts
- The
shippingTotal
property now includes the tax in the amount, useshippingSubTotal
instead. - A new
shippingBreakdown
property has been added which will include all shipping costs and be available to pipelines.
If you are modifying the shipping cost outside of your own shipping options in the shipping manifest, you should create a custom cart pipeline and use the shipping breakdown property as this is where the shipping total will be calculated from.
use Lunar\Base\ValueObjects\Cart\ShippingBreakdown;
use Lunar\Base\ValueObjects\Cart\ShippingBreakdownItem;
$shippingBreakdown = $cart->shippingBreakdown ?: new ShippingBreakdown;
$shippingBreakdown->items->put('ADDSHIP',
new ShippingBreakdownItem(
name: 'Additional Shipping Cost',
identifier: 'ADDSHIP',
price: new Price(123, $currency, 1),
)
);
Cart/Order Relationship
The relationship between a cart and an order has been changed, previously the carts
table had an order_id
column, this has been changed so the cart_id
is now on the orders
table.
You should update any code that sets the order_id
on a cart to cart_id
on the order.
We've also introduced the concept of draft
and complete
orders for carts, so you should update any code that references an order from a cart to the following methods:
// Old
$cart->order
// New
/* The order which doesn't have a `placed_at` value */
$cart->draftOrder
/* Any orders which have a `placed_at` value */
$cart->completedOrder
Changes to CreateOrder
action
The Lunar\Actions\Cart\CreateOrder
action has been refactored to run through pipelines, much like how carts are currently calculated. If you are currently using your own CreateOrder
action, you should refactor the logic into pipelines and ues the provided action.
DANGER
The CreateOrder
class is now final, so if you are extending this action you will need to refactor your implementation.
See Extending Orders
Low impact
Add the new fingerprint class reference to config/lunar/carts.php
if you have published the config.
'fingerprint_generator' => Lunar\Actions\Carts\GenerateFingerprint::class,
0.3
High Impact
Support for Laravel 8 removed
To install Lunar 0.3 you will need to be on at least Laravel 9. 0.3 introduces support for Laravel 10.
Low Impact
Changed Auth guard to use Laravel's default driver.
This should not impact your project unless you have customised the admin hub authentication.
Updated db_date
function to return just the formmatted string.
If you were using db_date
helper function, you will now need to wrap it with DB:RAW()
.
0.2.5
Low Impact
If you have a custom DiscountType, you should update the save
method to expect the recently saved discount id to be passed.
// Before
public function save();
// After
public function save($discountId);
0.2
High Impact
Removal of the Cart Manager and Cart Modifiers
This release moves away from Cart Modifiers and the Cart Manager.
You can still extend the Cart in the form of pipelines. See Cart Extending.
You need to replace any instances of $cart->getManager()
and just reference the cart itself i.e.
// Old
$cart->getManager()->setShippingOption();
// New
$cart->setShippingOption();
For calculating the cart totals you should change the following:
// Old
$cart->getManager()->getCart();
// New
$cart->calculate();
0.1.0-rc.5
Changed
Publishing changes
All publishing commands for Lunar now use .
as a separator.
- Rename
lunar-hub-translations
tolunar.hub.translations
- Rename
lunar-hub-views
tolunar.hub.views
- Rename
lunar:hub:public
tolunar.hub.public
- Rename
lunar-migrations
tolunar.migrations
Brand requirement is now configurable.
Whether the product brand is required on your store is now configurable, the default behaviour is set to true
. If you wish to change this, simply update config/lunar-hub/products.php
.
'require_brand' => false,
Migrating from GetCandy to Lunar
The initial release of Lunar will be version 0.1.0
. This allows for a rapid development cycle until we reach 1.0.0
. Understandably, a complete name change is not small task, so we've outlined steps you need to take to bring your install up to the latest Lunar version and move away from GetCandy.
Update composer dependencies
"getcandy/admin": "^2.0-beta",
"getcandy/core": "^2.0-beta"
"lunarphp/lunar": "^0.1"
Any add-ons you are using will need their namespaces updated, the package name should remain the same, i.e.
"getcandy/stripe": "^1.0"
"lunarphp/stripe": "^0.1"
Once done, remember to run composer update
to pull in the latest packages.
Update namespaces
If you are using any GetCandy classes, such as models, you will need to update their namespace:
Models
GetCandy\Models\Product;
Lunar\Models\Product;
A simple find and replace in your code should be sufficient, the strings you should search for are:
GetCandy
get-candy
getcandy
Config changes
- Rename the
config/getcandy
folder toconfig/lunar
- Rename the
config/getcandy-hub
folder toconfig/lunar-hub
- Change the prefix in
config/lunar/database.php
fromgetcandy_
tolunar_
Also make sure any class references in your config files have been updated to the Lunar
namespace.
Meilisearch users
Lunar no longer ships with Meilisearch by default. If you use Meilisearch and wish to carry on using it, you will need to require the new Lunar meilisearch package.
composer require lunarphp/meilisearch
This will install the appropriate packages that Scout needs and also register the set up command so you can keep using it, you just need to update the signature.
php artisan lunar:meilisearch:setup
MySQL Search
If you were previously using the mysql
Scout driver, you should change this to database_index
. This populates the search_index
table with the terms to be searched upon. You may need to run the scout import command:
php artisan scout:import Lunar\Models\Product
Database migration
If you are using the getcandy_
prefix in your database, then you will likely want to update this to lunar_
. We have created a command for this purpose to try make the switch as easy as possible.
php artisan lunar:migrate:getcandy
What this command will do
- Remove any previous GetCandy migrations from the
migrations
table. - Run the migrations again with the
lunar_
prefix, creating new tables. - Copy across the data from the old
getcandy_
tables into the newlunar_
tables. - Update any polymorphic
GetCandy
classes to theLunar
namespace. - Update field types in
attribute_data
to theLunar
namespace.
What this command will not do
- Affect any custom tables that have been added outside the core packages.
The intention of this is to provide a non-destructive way to migrate the data. Once the command has been run your getcandy_
tables should remain intact, so you are free to check the data and remove when ready.