Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1874c277e | ||
|
|
05f00ed1fd | ||
|
|
569eb310e9 | ||
|
|
0387b38ab3 | ||
|
|
0a51d912a0 | ||
|
|
1214f9b748 |
@@ -4,6 +4,32 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||||
|
|
||||||
|
## [0.26.2] - 2026-09-28
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Checkout line-item custom fields (`checkout/partials/line-custom-fields.blade.php`):
|
||||||
|
non-file fields now render inline as a single muted `Label: value` line instead of a
|
||||||
|
separate `<dt>`/`<dd>` pair. File fields keep the stacked label/link layout, with a
|
||||||
|
colon after the label and a small top margin on the value.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Wishlist routes are now registered inside the `web` middleware group
|
||||||
|
(`WishlistServiceProvider`). Before, `loadRoutesFrom()` loaded them with no middleware,
|
||||||
|
so they had no session, cookies, CSRF protection or authenticated user. That broke
|
||||||
|
anything that depends on the current guest or logged-in user.
|
||||||
|
|
||||||
|
## [0.26.1] - 2026-09-28
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- `Modules\Core\Order\Support\OrderReferenceDisplay` — a human-facing form of
|
||||||
|
`Order::reference` for emails and storefront views. `Lunar\Base\OrderReferenceGenerator`
|
||||||
|
zero-pads the order's own id out to a fixed length (8 characters by default), so a shop's
|
||||||
|
first real orders read as `#00000001` rather than `#1`. This strips leading zeros until the
|
||||||
|
first non-zero digit (falling back to `0` if none remain), purely for display — the raw,
|
||||||
|
padded `reference` is untouched everywhere else (DB lookups, the order-status API, staff
|
||||||
|
search, GDPR exports). Wired into the checkout confirmation page and all customer-facing
|
||||||
|
order notification emails.
|
||||||
|
|
||||||
## [0.26.0] - 2026-09-28
|
## [0.26.0] - 2026-09-28
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"name": "boboko/core",
|
"name": "boboko/core",
|
||||||
"description": "Core module — authentication and shared panel behaviour",
|
"description": "Core module — authentication and shared panel behaviour",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"version": "0.26.0",
|
"version": "0.26.2",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Modules\\Core\\": "src/"
|
"Modules\\Core\\": "src/"
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@boboko/core",
|
"name": "@boboko/core",
|
||||||
"version": "0.26.0",
|
"version": "0.26.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "Portable Stimulus controllers and styles for boboko-core's cart + checkout module. Installed as a real npm dependency (file:../boboko-core in dev, a tagged git install in prod) so a consuming app's `npm install` resolves this package's own dependencies (leaflet, @hotwired/stimulus) transitively, the same way `composer update boboko/*` does for PHP. See CONTRIBUTE.md's \"JS/CSS: a real npm package\" section.",
|
"description": "Portable Stimulus controllers and styles for boboko-core's cart + checkout module. Installed as a real npm dependency (file:../boboko-core in dev, a tagged git install in prod) so a consuming app's `npm install` resolves this package's own dependencies (leaflet, @hotwired/stimulus) transitively, the same way `composer update boboko/*` does for PHP. See CONTRIBUTE.md's \"JS/CSS: a real npm package\" section.",
|
||||||
|
|||||||
@@ -223,13 +223,13 @@ a.bbk-cart-item-title:hover { text-decoration: underline; }
|
|||||||
font-size: 0.8125rem;
|
font-size: 0.8125rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bbk-line-field span,
|
||||||
.bbk-line-field dt {
|
.bbk-line-field dt {
|
||||||
color: var(--bbk-color-muted);
|
color: var(--bbk-color-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
.bbk-line-field dd {
|
.bbk-line-field dd {
|
||||||
margin: 0;
|
margin: 3px 0 0 0;
|
||||||
white-space: pre-line;
|
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<dl class="bbk-confirmation-meta">
|
<dl class="bbk-confirmation-meta">
|
||||||
<div class="bbk-confirmation-meta-row">
|
<div class="bbk-confirmation-meta-row">
|
||||||
<dt>{{ __('checkout.page.confirmation_order_number') }}</dt>
|
<dt>{{ __('checkout.page.confirmation_order_number') }}</dt>
|
||||||
<dd>{{ $order->reference }}</dd>
|
<dd>{{ \Modules\Core\Order\Support\OrderReferenceDisplay::resolve($order) }}</dd>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if ($order->billingAddress?->contact_email)
|
@if ($order->billingAddress?->contact_email)
|
||||||
|
|||||||
@@ -19,9 +19,9 @@
|
|||||||
<dl class="bbk-line-fields">
|
<dl class="bbk-line-fields">
|
||||||
@foreach ($fields as $field)
|
@foreach ($fields as $field)
|
||||||
<div class="bbk-line-field">
|
<div class="bbk-line-field">
|
||||||
<dt>{{ $field['label'] }}</dt>
|
@if ($field['type'] === 'file')
|
||||||
<dd>
|
<dt>{{ $field['label'] }}:</dt>
|
||||||
@if ($field['type'] === 'file')
|
<dd>
|
||||||
@php
|
@php
|
||||||
$file = \Modules\Core\File\Models\File::find($field['file_id'] ?? null);
|
$file = \Modules\Core\File\Models\File::find($field['file_id'] ?? null);
|
||||||
@endphp
|
@endphp
|
||||||
@@ -39,11 +39,12 @@
|
|||||||
@endif
|
@endif
|
||||||
<span>{{ $file->original_name }}</span>
|
<span>{{ $file->original_name }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@endif
|
@endif
|
||||||
@else
|
</dd>
|
||||||
{{ $field['value'] }}
|
@else
|
||||||
@endif
|
<span>{{ $field['label'] }}: {{ $field['value'] }}</span>
|
||||||
</dd>
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
</dl>
|
</dl>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use Illuminate\Notifications\Messages\MailMessage;
|
|||||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||||
use Modules\Core\Notification\BaseNotification;
|
use Modules\Core\Notification\BaseNotification;
|
||||||
use Modules\Core\Order\Events\OrderCaptured;
|
use Modules\Core\Order\Events\OrderCaptured;
|
||||||
|
use Modules\Core\Order\Support\OrderReferenceDisplay;
|
||||||
|
|
||||||
class OrderCapturedNotification extends BaseNotification
|
class OrderCapturedNotification extends BaseNotification
|
||||||
{
|
{
|
||||||
@@ -40,10 +41,12 @@ class OrderCapturedNotification extends BaseNotification
|
|||||||
{
|
{
|
||||||
$order = $this->event->order;
|
$order = $this->event->order;
|
||||||
|
|
||||||
|
$reference = OrderReferenceDisplay::resolve($order);
|
||||||
|
|
||||||
return (new MailMessage)
|
return (new MailMessage)
|
||||||
->subject(__('Payment captured for your order :reference', ['reference' => $order->reference]))
|
->subject(__('Payment captured for your order :reference', ['reference' => $reference]))
|
||||||
->view('core::order.notifications.captured', [
|
->view('core::order.notifications.captured', [
|
||||||
'reference' => $order->reference,
|
'reference' => $reference,
|
||||||
'amount' => $this->event->transaction->amount->formatted,
|
'amount' => $this->event->transaction->amount->formatted,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use Illuminate\Notifications\Messages\MailMessage;
|
|||||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||||
use Modules\Core\Notification\BaseNotification;
|
use Modules\Core\Notification\BaseNotification;
|
||||||
use Modules\Core\Order\Events\OrderCompleted;
|
use Modules\Core\Order\Events\OrderCompleted;
|
||||||
|
use Modules\Core\Order\Support\OrderReferenceDisplay;
|
||||||
|
|
||||||
class OrderCompletedNotification extends BaseNotification
|
class OrderCompletedNotification extends BaseNotification
|
||||||
{
|
{
|
||||||
@@ -40,10 +41,12 @@ class OrderCompletedNotification extends BaseNotification
|
|||||||
{
|
{
|
||||||
$order = $this->event->order;
|
$order = $this->event->order;
|
||||||
|
|
||||||
|
$reference = OrderReferenceDisplay::resolve($order);
|
||||||
|
|
||||||
return (new MailMessage)
|
return (new MailMessage)
|
||||||
->subject(__('Your order :reference is complete', ['reference' => $order->reference]))
|
->subject(__('Your order :reference is complete', ['reference' => $reference]))
|
||||||
->view('core::order.notifications.completed', [
|
->view('core::order.notifications.completed', [
|
||||||
'reference' => $order->reference,
|
'reference' => $reference,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use Illuminate\Notifications\Messages\MailMessage;
|
|||||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||||
use Modules\Core\Notification\BaseNotification;
|
use Modules\Core\Notification\BaseNotification;
|
||||||
use Modules\Core\Order\Events\OrderDelivered;
|
use Modules\Core\Order\Events\OrderDelivered;
|
||||||
|
use Modules\Core\Order\Support\OrderReferenceDisplay;
|
||||||
|
|
||||||
class OrderDeliveredNotification extends BaseNotification
|
class OrderDeliveredNotification extends BaseNotification
|
||||||
{
|
{
|
||||||
@@ -40,10 +41,12 @@ class OrderDeliveredNotification extends BaseNotification
|
|||||||
{
|
{
|
||||||
$order = $this->event->order;
|
$order = $this->event->order;
|
||||||
|
|
||||||
|
$reference = OrderReferenceDisplay::resolve($order);
|
||||||
|
|
||||||
return (new MailMessage)
|
return (new MailMessage)
|
||||||
->subject(__('Your order :reference has been delivered', ['reference' => $order->reference]))
|
->subject(__('Your order :reference has been delivered', ['reference' => $reference]))
|
||||||
->view('core::order.notifications.delivered', [
|
->view('core::order.notifications.delivered', [
|
||||||
'reference' => $order->reference,
|
'reference' => $reference,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use Illuminate\Notifications\Messages\MailMessage;
|
|||||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||||
use Modules\Core\Notification\BaseNotification;
|
use Modules\Core\Notification\BaseNotification;
|
||||||
use Modules\Core\Order\Events\OrderDispatched;
|
use Modules\Core\Order\Events\OrderDispatched;
|
||||||
|
use Modules\Core\Order\Support\OrderReferenceDisplay;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills a real, previously-unfilled customer-communication gap — before
|
* Fills a real, previously-unfilled customer-communication gap — before
|
||||||
@@ -45,10 +46,12 @@ class OrderDispatchedNotification extends BaseNotification
|
|||||||
{
|
{
|
||||||
$order = $this->event->order;
|
$order = $this->event->order;
|
||||||
|
|
||||||
|
$reference = OrderReferenceDisplay::resolve($order);
|
||||||
|
|
||||||
return (new MailMessage)
|
return (new MailMessage)
|
||||||
->subject(__('Your order :reference is on its way', ['reference' => $order->reference]))
|
->subject(__('Your order :reference is on its way', ['reference' => $reference]))
|
||||||
->view('core::order.notifications.dispatched', [
|
->view('core::order.notifications.dispatched', [
|
||||||
'reference' => $order->reference,
|
'reference' => $reference,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use Illuminate\Notifications\Messages\MailMessage;
|
|||||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||||
use Modules\Core\Notification\BaseNotification;
|
use Modules\Core\Notification\BaseNotification;
|
||||||
use Modules\Core\Order\Events\OrderReadyForPickup;
|
use Modules\Core\Order\Events\OrderReadyForPickup;
|
||||||
|
use Modules\Core\Order\Support\OrderReferenceDisplay;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Your order is ready to collect" — listens to the specific
|
* "Your order is ready to collect" — listens to the specific
|
||||||
@@ -50,10 +51,12 @@ class OrderPickupReadyNotification extends BaseNotification
|
|||||||
{
|
{
|
||||||
$order = $this->event->order;
|
$order = $this->event->order;
|
||||||
|
|
||||||
|
$reference = OrderReferenceDisplay::resolve($order);
|
||||||
|
|
||||||
return (new MailMessage)
|
return (new MailMessage)
|
||||||
->subject(__('Your order :reference is ready for pickup', ['reference' => $order->reference]))
|
->subject(__('Your order :reference is ready for pickup', ['reference' => $reference]))
|
||||||
->view('core::order.notifications.pickup-ready', [
|
->view('core::order.notifications.pickup-ready', [
|
||||||
'reference' => $order->reference,
|
'reference' => $reference,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use Illuminate\Notifications\Messages\MailMessage;
|
|||||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||||
use Modules\Core\Checkout\Events\OrderPlaced;
|
use Modules\Core\Checkout\Events\OrderPlaced;
|
||||||
use Modules\Core\Notification\BaseNotification;
|
use Modules\Core\Notification\BaseNotification;
|
||||||
|
use Modules\Core\Order\Support\OrderReferenceDisplay;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The order confirmation email — fires once, for every capture_mode and
|
* The order confirmation email — fires once, for every capture_mode and
|
||||||
@@ -51,10 +52,12 @@ class OrderPlacedNotification extends BaseNotification
|
|||||||
{
|
{
|
||||||
$order = $this->event->order;
|
$order = $this->event->order;
|
||||||
|
|
||||||
|
$reference = OrderReferenceDisplay::resolve($order);
|
||||||
|
|
||||||
return (new MailMessage)
|
return (new MailMessage)
|
||||||
->subject(__('Your order :reference is confirmed', ['reference' => $order->reference]))
|
->subject(__('Your order :reference is confirmed', ['reference' => $reference]))
|
||||||
->view('core::order.notifications.placed', [
|
->view('core::order.notifications.placed', [
|
||||||
'reference' => $order->reference,
|
'reference' => $reference,
|
||||||
'total' => $order->total->formatted,
|
'total' => $order->total->formatted,
|
||||||
'lines' => $order->lines,
|
'lines' => $order->lines,
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use Illuminate\Notifications\Messages\MailMessage;
|
|||||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||||
use Modules\Core\Notification\BaseNotification;
|
use Modules\Core\Notification\BaseNotification;
|
||||||
use Modules\Core\Order\Events\OrderRefunded;
|
use Modules\Core\Order\Events\OrderRefunded;
|
||||||
|
use Modules\Core\Order\Support\OrderReferenceDisplay;
|
||||||
|
|
||||||
class OrderRefundedNotification extends BaseNotification
|
class OrderRefundedNotification extends BaseNotification
|
||||||
{
|
{
|
||||||
@@ -40,10 +41,12 @@ class OrderRefundedNotification extends BaseNotification
|
|||||||
{
|
{
|
||||||
$order = $this->event->order;
|
$order = $this->event->order;
|
||||||
|
|
||||||
|
$reference = OrderReferenceDisplay::resolve($order);
|
||||||
|
|
||||||
return (new MailMessage)
|
return (new MailMessage)
|
||||||
->subject(__('A refund has been issued for your order :reference', ['reference' => $order->reference]))
|
->subject(__('A refund has been issued for your order :reference', ['reference' => $reference]))
|
||||||
->view('core::order.notifications.refunded', [
|
->view('core::order.notifications.refunded', [
|
||||||
'reference' => $order->reference,
|
'reference' => $reference,
|
||||||
'amount' => $this->event->transaction->amount->formatted,
|
'amount' => $this->event->transaction->amount->formatted,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use Illuminate\Notifications\Messages\MailMessage;
|
|||||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||||
use Modules\Core\Notification\BaseNotification;
|
use Modules\Core\Notification\BaseNotification;
|
||||||
use Modules\Core\Order\Events\OrderStatusUpdated;
|
use Modules\Core\Order\Events\OrderStatusUpdated;
|
||||||
|
use Modules\Core\Order\Support\OrderReferenceDisplay;
|
||||||
|
|
||||||
class OrderStatusUpdatedNotification extends BaseNotification
|
class OrderStatusUpdatedNotification extends BaseNotification
|
||||||
{
|
{
|
||||||
@@ -52,10 +53,12 @@ class OrderStatusUpdatedNotification extends BaseNotification
|
|||||||
{
|
{
|
||||||
$order = $this->event->order;
|
$order = $this->event->order;
|
||||||
|
|
||||||
|
$reference = OrderReferenceDisplay::resolve($order);
|
||||||
|
|
||||||
return (new MailMessage)
|
return (new MailMessage)
|
||||||
->subject(__('Your order :reference has been updated', ['reference' => $order->reference]))
|
->subject(__('Your order :reference has been updated', ['reference' => $reference]))
|
||||||
->view('core::order.notifications.status-updated', [
|
->view('core::order.notifications.status-updated', [
|
||||||
'reference' => $order->reference,
|
'reference' => $reference,
|
||||||
'statusLabel' => config("lunar.orders.statuses.{$order->status}.label", $order->status),
|
'statusLabel' => config("lunar.orders.statuses.{$order->status}.label", $order->status),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Core\Order\Support;
|
||||||
|
|
||||||
|
use Lunar\Models\Order;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shorter, human-facing form of Order::reference for emails/views —
|
||||||
|
* Lunar\Base\OrderReferenceGenerator pads the order's own id out to a fixed
|
||||||
|
* length (config('lunar.orders.reference_format'), 8 characters/'0'-padded
|
||||||
|
* by default), so a shop's first real orders read as "#00000001" rather
|
||||||
|
* than "#1". Strips leading zeros until the first non-zero digit; if
|
||||||
|
* nothing but zeros remain (or the reference is empty), shows "0".
|
||||||
|
*
|
||||||
|
* $order->reference itself is untouched anywhere else (DB lookups, the
|
||||||
|
* order-status API, staff search) — this is purely a display helper.
|
||||||
|
*/
|
||||||
|
class OrderReferenceDisplay
|
||||||
|
{
|
||||||
|
public static function resolve(Order $order): string
|
||||||
|
{
|
||||||
|
$reference = ltrim((string) $order->reference, '0');
|
||||||
|
|
||||||
|
return $reference !== '' ? $reference : '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace Modules\Core\Providers;
|
namespace Modules\Core\Providers;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Modules\Core\Auth\Events\UserAuthenticated;
|
use Modules\Core\Auth\Events\UserAuthenticated;
|
||||||
use Modules\Core\Wishlist\Listeners\MergeGuestWishlistOnLogin;
|
use Modules\Core\Wishlist\Listeners\MergeGuestWishlistOnLogin;
|
||||||
@@ -19,7 +20,7 @@ class WishlistServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
$this->loadRoutesFrom(__DIR__.'/../Wishlist/routes/web.php');
|
Route::middleware('web')->group(__DIR__.'/../Wishlist/routes/web.php');
|
||||||
|
|
||||||
Event::listen(UserAuthenticated::class, MergeGuestWishlistOnLogin::class);
|
Event::listen(UserAuthenticated::class, MergeGuestWishlistOnLogin::class);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user