Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f2ddea240 | ||
|
|
45df93692a | ||
|
|
b806db611f |
@@ -4,6 +4,21 @@ 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.3] - 2026-09-28
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- `Modules\Core\Localization\Database\Seeders\ValidationTranslationsSeeder` — moved in from
|
||||||
|
3dealer's own `database/seeders/`, alongside the existing
|
||||||
|
`Modules\Core\Checkout\Database\Seeders\CheckoutTranslationsSeeder`, so the `validation` and
|
||||||
|
`checkout` translation groups are seeded from core rather than duplicated per consuming app.
|
||||||
|
Same idempotent per-key upsert as `lunar:install`'s own seeding — a key already present (or
|
||||||
|
since edited via the Filament Language Lines UI) is left untouched. Both are run explicitly
|
||||||
|
via `php artisan db:seed --class=...`, wired into 3dealer's entrypoint right after
|
||||||
|
`lunar:install`.
|
||||||
|
- `storefront.auth.captcha_failed` — was referenced by `HCaptcha`, `LoginController`, and
|
||||||
|
`ContactRequest` but never seeded in `StorefrontLabels`, so it silently fell back to the raw
|
||||||
|
key. Re-running `lunar:install` now fills it in for any existing store.
|
||||||
|
|
||||||
## [0.26.2] - 2026-09-28
|
## [0.26.2] - 2026-09-28
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
+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.2",
|
"version": "0.26.3",
|
||||||
"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.2",
|
"version": "0.26.3",
|
||||||
"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.",
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Core\Localization\Database\Seeders;
|
||||||
|
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Modules\Core\Localization\Services\TranslationService;
|
||||||
|
use Spatie\TranslationLoader\LanguageLine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default `validation` translation lines — Laravel's own error-message group
|
||||||
|
* (`validation.required`, `validation.email`, `validation.attributes.*`, …),
|
||||||
|
* resolved by every `Validator::make()`/`$request->validate()` call in a
|
||||||
|
* consuming app (checkout addresses, cart, product reviews, stock checks).
|
||||||
|
*
|
||||||
|
* Spatie's DB loader (spatie/laravel-translation-loader, wired in
|
||||||
|
* LocalizationServiceProvider) merges this group over Laravel's file-based
|
||||||
|
* validation.php — without this, Greek requests fall back to Laravel's
|
||||||
|
* untranslated English defaults. Only the rule keys and field attributes
|
||||||
|
* actually in use are seeded; add more as new rules/fields show up.
|
||||||
|
*
|
||||||
|
* Additive and idempotent: a key that already exists is left untouched, so
|
||||||
|
* anything edited in the Filament Language Lines UI wins on a re-run. Runs
|
||||||
|
* explicitly — `php artisan db:seed --class="Modules\Core\Localization\
|
||||||
|
* Database\Seeders\ValidationTranslationsSeeder"` — it is not wired into any
|
||||||
|
* app's own DatabaseSeeder.
|
||||||
|
*
|
||||||
|
* Greek copy uses the project's informal register (εσύ/σου).
|
||||||
|
*/
|
||||||
|
class ValidationTranslationsSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$translations = app(TranslationService::class);
|
||||||
|
|
||||||
|
foreach ($this->lines() as $key => [$en, $el]) {
|
||||||
|
$exists = LanguageLine::query()
|
||||||
|
->where('group', 'validation')
|
||||||
|
->where('key', $key)
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($exists) {
|
||||||
|
$this->command?->warn("validation.{$key} already exists — skipped");
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$translations->create('validation', $key, ['en' => $en, 'el' => $el]);
|
||||||
|
$this->command?->info("validation.{$key} added");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* key => [English, Greek].
|
||||||
|
*
|
||||||
|
* @return array<string, array{0: string, 1: string}>
|
||||||
|
*/
|
||||||
|
private function lines(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
// ── Rule messages ─────────────────────────────────────────────
|
||||||
|
'required' => ['The :attribute field is required.', 'Το πεδίο :attribute είναι υποχρεωτικό.'],
|
||||||
|
'email' => ['The :attribute field must be a valid email address.', 'Το πεδίο :attribute πρέπει να είναι έγκυρη διεύθυνση email.'],
|
||||||
|
'string' => ['The :attribute field must be a string.', 'Το πεδίο :attribute πρέπει να είναι κείμενο.'],
|
||||||
|
'integer' => ['The :attribute field must be an integer.', 'Το πεδίο :attribute πρέπει να είναι ακέραιος αριθμός.'],
|
||||||
|
'boolean' => ['The :attribute field must be true or false.', 'Το πεδίο :attribute πρέπει να είναι true ή false.'],
|
||||||
|
'min.numeric' => ['The :attribute field must be at least :min.', 'Το πεδίο :attribute πρέπει να είναι τουλάχιστον :min.'],
|
||||||
|
'max.string' => ['The :attribute field must not be greater than :max characters.', 'Το πεδίο :attribute δεν πρέπει να ξεπερνά τους :max χαρακτήρες.'],
|
||||||
|
'between.numeric' => ['The :attribute field must be between :min and :max.', 'Το πεδίο :attribute πρέπει να είναι μεταξύ :min και :max.'],
|
||||||
|
'exists' => ['The selected :attribute is invalid.', 'Η επιλεγμένη τιμή για το πεδίο :attribute δεν είναι έγκυρη.'],
|
||||||
|
// Product custom-field photo uploads (CustomFieldUploadController, CartController).
|
||||||
|
'file' => ['The :attribute field must be a file.', 'Το πεδίο :attribute πρέπει να είναι αρχείο.'],
|
||||||
|
'mimes' => ['The :attribute field must be a file of type: :values.', 'Το πεδίο :attribute πρέπει να είναι αρχείο τύπου: :values.'],
|
||||||
|
'max.file' => ['The :attribute field must not be greater than :max kilobytes.', 'Το αρχείο στο πεδίο :attribute δεν πρέπει να ξεπερνά τα :max kilobytes.'],
|
||||||
|
'uploaded' => ['The :attribute failed to upload.', 'Η μεταφόρτωση στο πεδίο :attribute απέτυχε.'],
|
||||||
|
|
||||||
|
// ── Field names (checkout: billing/shipping address) ──────────
|
||||||
|
'attributes.contact_email' => ['email', 'email'],
|
||||||
|
'attributes.billing_first_name' => ['first name', 'όνομα'],
|
||||||
|
'attributes.billing_last_name' => ['last name', 'επώνυμο'],
|
||||||
|
'attributes.billing_company_name' => ['company name', 'επωνυμία εταιρείας'],
|
||||||
|
'attributes.billing_tax_identifier' => ['tax ID', 'ΑΦΜ'],
|
||||||
|
'attributes.billing_line_one' => ['address', 'διεύθυνση'],
|
||||||
|
'attributes.billing_line_two' => ['address line 2', 'διεύθυνση (γραμμή 2)'],
|
||||||
|
'attributes.billing_city' => ['city', 'πόλη'],
|
||||||
|
'attributes.billing_state' => ['region', 'νομό / περιοχή'],
|
||||||
|
'attributes.billing_postcode' => ['postcode', 'ταχυδρομικό κώδικα'],
|
||||||
|
'attributes.billing_country_id' => ['country', 'χώρα'],
|
||||||
|
'attributes.billing_contact_phone' => ['phone', 'τηλέφωνο'],
|
||||||
|
'attributes.shipping_first_name' => ['first name', 'όνομα'],
|
||||||
|
'attributes.shipping_last_name' => ['last name', 'επώνυμο'],
|
||||||
|
'attributes.shipping_company_name' => ['company name', 'επωνυμία εταιρείας'],
|
||||||
|
'attributes.shipping_line_one' => ['address', 'διεύθυνση'],
|
||||||
|
'attributes.shipping_line_two' => ['address line 2', 'διεύθυνση (γραμμή 2)'],
|
||||||
|
'attributes.shipping_city' => ['city', 'πόλη'],
|
||||||
|
'attributes.shipping_state' => ['region', 'νομό / περιοχή'],
|
||||||
|
'attributes.shipping_postcode' => ['postcode', 'ταχυδρομικό κώδικα'],
|
||||||
|
'attributes.shipping_country_id' => ['country', 'χώρα'],
|
||||||
|
'attributes.shipping_contact_phone' => ['phone', 'τηλέφωνο'],
|
||||||
|
'attributes.shipping_delivery_instructions' => ['delivery notes', 'σχόλια για την παράδοση'],
|
||||||
|
|
||||||
|
// ── Field names (cart) ─────────────────────────────────────────
|
||||||
|
'attributes.purchasable_id' => ['product', 'προϊόν'],
|
||||||
|
'attributes.quantity' => ['quantity', 'ποσότητα'],
|
||||||
|
'attributes.code' => ['coupon code', 'κωδικό κουπονιού'],
|
||||||
|
|
||||||
|
// ── Field names (product reviews / stock check) ────────────────
|
||||||
|
'attributes.variant' => ['variant', 'παραλλαγή'],
|
||||||
|
'attributes.rating' => ['rating', 'βαθμολογία'],
|
||||||
|
'attributes.content' => ['review text', 'κείμενο κριτικής'],
|
||||||
|
'attributes.name' => ['name', 'όνομα'],
|
||||||
|
'attributes.email' => ['email', 'email'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -108,6 +108,10 @@ class StorefrontLabels
|
|||||||
'en' => 'Too many attempts. Please wait a few minutes and try again.',
|
'en' => 'Too many attempts. Please wait a few minutes and try again.',
|
||||||
'el' => 'Πολλές προσπάθειες. Περίμενε λίγα λεπτά και ξαναδοκίμασε.',
|
'el' => 'Πολλές προσπάθειες. Περίμενε λίγα λεπτά και ξαναδοκίμασε.',
|
||||||
],
|
],
|
||||||
|
'auth.captcha_failed' => [
|
||||||
|
'en' => 'Please complete the captcha and try again.',
|
||||||
|
'el' => 'Παρακαλούμε ολοκλήρωσε το captcha και ξαναδοκίμασε.',
|
||||||
|
],
|
||||||
|
|
||||||
// Account profile page (account/show.blade.php)
|
// Account profile page (account/show.blade.php)
|
||||||
'account.nav_profile' => ['en' => 'Profile', 'el' => 'Προφίλ'],
|
'account.nav_profile' => ['en' => 'Profile', 'el' => 'Προφίλ'],
|
||||||
|
|||||||
Reference in New Issue
Block a user