Fix: Updating Product Options Registry and adding handle to the meilisearch index

This commit is contained in:
2026-08-27 11:14:56 +03:00
parent cb3fe095d9
commit e95ea4a43c
8 changed files with 80 additions and 55 deletions
+25 -17
View File
@@ -15,21 +15,23 @@ admin edits that data — without introducing a new model. `ProductOption`/
## Registering a type
A shop enables a type class in `config/core.php`:
A shop registers a type class from its own service provider's `boot()`, the same
shape as `Modules\Core\Notification\NotificationRegistry`:
```php
// config/core.php
'product_option_types' => [
use Modules\Core\Product\Services\ProductOptionTypeManager;
ProductOptionTypeManager::get()->register([
\App\ProductOptions\ColorOptionType::class,
],
]);
```
This is a plain list, **not** keyed by `ProductOption::handle` — a shop's own handle
naming (transliterated Greek, legacy import slugs, whatever an admin happened to type
when creating the option) shouldn't have to match a type's key. Instead, an admin
picks a type per-option from a dropdown on the `ProductOption` edit form itself (see
below); the choice is stored in `ProductOption::meta['option_type']`, not inferred
from anything else.
Not a published config array — the mapping isn't per-`ProductOption`, so there's
nothing for a shop to *key* by. Instead, an admin picks a type per-option from a
dropdown on the `ProductOption` edit form itself (see below); the choice is stored
in `ProductOption::meta['option_type']`, deliberately **not** tied to the option's
`handle` (a shop's own handle naming — transliterated Greek, legacy import slugs —
shouldn't have to match a type's key).
A `ProductOption` with no type selected behaves exactly as stock Lunar does — plain
name/position, no extra meta form.
@@ -68,18 +70,24 @@ plain jsonb column). `getKey()` is the identifier used in the admin's "Option Ty
dropdown and in `ProductOption::meta['option_type']` — it has no relationship to the
`ProductOption::handle`.
A reference implementation ships at `Modules\Core\Product\OptionTypes\ColorOptionType`
— not auto-registered, since registration is always an explicit shop decision.
A reference implementation ships at `Modules\Core\Product\OptionTypes\ColorOptionType`,
registered automatically by `Modules\Core\Providers\ProductServiceProvider` — no shop
setup needed for it to appear in the "Option Type" dropdown, though an admin still
has to pick it per-`ProductOption` for it to take effect.
---
## How it's wired into the admin UI
`Modules\Core\Product\Services\ProductOptionTypeManager`:
- `all(): Collection<string, ProductOptionTypeInterface>` — every enabled type,
keyed by `getKey()`.
- `resolve(?string $key): ?ProductOptionTypeInterface` — looks up one by key (or
`null` if no key / not found).
`Modules\Core\Product\Services\ProductOptionTypeManager` is a singleton registry:
- `get(): static` — the shared instance.
- `register(array $types): void` — registers one or more type classes, keyed
internally by `getKey()`.
- `unregister(string $key): void`
- `resolve(?string $key): ?ProductOptionTypeInterface` — looks up a registered type
by key (or `null` if no key / not found).
- `all(): array<string, class-string>` — every registered type's class, keyed by
`getKey()`.
Two extensions hook into Lunar's admin via its extension system
(`LunarPanel::extensions([...])`, registered in `CorePlugin`) — no forking of Lunar's