Files
core/src/Command/InstallLunarCommand.php
T

285 lines
10 KiB
PHP
Raw Normal View History

<?php
namespace Modules\Core\Command;
use Illuminate\Console\Command;
use Lunar\Facades\DB;
use Lunar\FieldTypes\TranslatedText;
use Lunar\Models\Attribute;
use Lunar\Models\AttributeGroup;
use Lunar\Models\Channel;
use Lunar\Models\Collection;
use Lunar\Models\CollectionGroup;
use Lunar\Models\Country;
use Lunar\Models\Currency;
use Lunar\Models\CustomerGroup;
use Lunar\Models\Language;
use Lunar\Models\Product;
use Lunar\Models\ProductType;
use Lunar\Models\TaxClass;
use Lunar\Models\TaxZone;
2026-08-06 00:13:13 +03:00
use Spatie\TranslationLoader\LanguageLine;
/**
* Overrides Lunar's own lunar:install to skip the interactive prompts (migrate
* confirmation, admin creation, GitHub star), so it's safe to run unattended from
2026-07-10 12:38:48 +03:00
* the entrypoint on every boot. Migrations already run as a separate, earlier
* entrypoint step; the admin user is created manually.
*/
class InstallLunarCommand extends Command
{
protected $signature = 'lunar:install';
2026-07-10 12:38:48 +03:00
protected $description = 'Seed the default Lunar store data (countries, channel, currency, tax zone, attributes, product type)';
public function handle(): void
{
$this->components->info('Seeding default Lunar store data...');
2026-07-10 12:38:48 +03:00
if (! Country::count()) {
$this->components->info('Importing countries');
$this->call('lunar:import:address-data');
}
DB::transaction(function () {
if (! Channel::whereDefault(true)->exists()) {
$this->components->info('Setting up default channel');
Channel::create([
'name' => 'Webstore',
'handle' => 'webstore',
'default' => true,
'url' => 'http://localhost',
]);
}
if (! Language::count()) {
$this->components->info('Adding default language');
Language::create([
'code' => 'en',
'name' => 'English',
'default' => true,
]);
}
if (! Currency::whereDefault(true)->exists()) {
$this->components->info('Adding a default currency (USD)');
Currency::create([
'code' => 'USD',
'name' => 'US Dollar',
'exchange_rate' => 1,
'decimal_places' => 2,
'default' => true,
'enabled' => true,
]);
}
if (! CustomerGroup::whereDefault(true)->exists()) {
$this->components->info('Adding a default customer group.');
CustomerGroup::create([
'name' => 'Retail',
'handle' => 'retail',
'default' => true,
]);
}
if (! CollectionGroup::count()) {
$this->components->info('Adding an initial collection group');
CollectionGroup::create([
'name' => 'Main',
'handle' => 'main',
]);
}
if (! TaxClass::count()) {
$this->components->info('Adding a default tax class.');
TaxClass::create([
'name' => 'Default Tax Class',
'default' => true,
]);
}
if (! TaxZone::count()) {
$this->components->info('Adding a default tax zone.');
$taxZone = TaxZone::create([
'name' => 'Default Tax Zone',
'zone_type' => 'country',
'price_display' => 'tax_exclusive',
'default' => true,
'active' => true,
]);
$taxZone->countries()->createMany(
Country::get()->map(fn ($country) => [
'country_id' => $country->id,
])
);
}
if (! Attribute::count()) {
$this->components->info('Setting up initial attributes');
$group = AttributeGroup::create([
'attributable_type' => Product::morphName(),
'name' => collect([
'en' => 'Details',
]),
'handle' => 'details',
'position' => 1,
]);
$collectionGroup = AttributeGroup::create([
'attributable_type' => Collection::morphName(),
'name' => collect([
'en' => 'Details',
]),
'handle' => 'collection_details',
'position' => 1,
]);
Attribute::create([
'attribute_type' => 'product',
'attribute_group_id' => $group->id,
'position' => 1,
'name' => [
'en' => 'Name',
],
'handle' => 'name',
'section' => 'main',
'type' => TranslatedText::class,
'required' => true,
'default_value' => null,
'configuration' => [
'richtext' => false,
],
'system' => true,
'description' => [
'en' => '',
],
]);
Attribute::create([
'attribute_type' => 'collection',
'attribute_group_id' => $collectionGroup->id,
'position' => 1,
'name' => [
'en' => 'Name',
],
'handle' => 'name',
'section' => 'main',
'type' => TranslatedText::class,
'required' => true,
'default_value' => null,
'configuration' => [
'richtext' => false,
],
'system' => true,
'description' => [
'en' => '',
],
]);
Attribute::create([
'attribute_type' => 'product',
'attribute_group_id' => $group->id,
'position' => 2,
'name' => [
'en' => 'Description',
],
'handle' => 'description',
'section' => 'main',
'type' => TranslatedText::class,
'required' => false,
'default_value' => null,
'configuration' => [
'richtext' => true,
],
'system' => false,
'description' => [
'en' => '',
],
]);
Attribute::create([
'attribute_type' => 'collection',
'attribute_group_id' => $collectionGroup->id,
'position' => 2,
'name' => [
'en' => 'Description',
],
'handle' => 'description',
'section' => 'main',
'type' => TranslatedText::class,
'required' => false,
'default_value' => null,
'configuration' => [
'richtext' => true,
],
'system' => false,
'description' => [
'en' => '',
],
]);
}
if (! ProductType::count()) {
$this->components->info('Adding a product type.');
$type = ProductType::create([
'name' => 'Stock',
]);
$type->mappedAttributes()->attach(
Attribute::whereAttributeType(
Product::morphName()
)->get()->pluck('id')
);
}
});
2026-08-06 00:13:13 +03:00
if (! LanguageLine::where('group', 'storefront')->exists()) {
$this->components->info('Seeding storefront label translations');
$this->seedStorefrontLabels();
}
$this->components->info('Publishing Filament assets');
$this->call('filament:assets');
$this->components->info('Lunar default data seeded.');
}
2026-08-06 00:13:13 +03:00
private function seedStorefrontLabels(): void
{
$labels = [
'nav.home' => ['en' => 'Home', 'el' => 'Αρχική'],
'nav.products' => ['en' => 'Products', 'el' => 'Προϊόντα'],
'nav.cart' => ['en' => 'Cart', 'el' => 'Καλάθι'],
'nav.account' => ['en' => 'Account', 'el' => 'Λογαριασμός'],
'nav.back' => ['en' => 'Back', 'el' => 'Πίσω'],
'cart.empty' => ['en' => 'Your cart is empty', 'el' => 'Το καλάθι σας είναι άδειο'],
'cart.checkout' => ['en' => 'Checkout', 'el' => 'Ολοκλήρωση Παραγγελίας'],
'cart.total' => ['en' => 'Total', 'el' => 'Σύνολο'],
'cart.remove' => ['en' => 'Remove', 'el' => 'Αφαίρεση'],
'product.add_to_cart' => ['en' => 'Add to Cart', 'el' => 'Προσθήκη στο Καλάθι'],
'product.out_of_stock' => ['en' => 'Out of Stock', 'el' => 'Εξαντλήθηκε'],
'product.price' => ['en' => 'Price', 'el' => 'Τιμή'],
'auth.login' => ['en' => 'Log In', 'el' => 'Σύνδεση'],
'auth.logout' => ['en' => 'Log Out', 'el' => 'Αποσύνδεση'],
'search.placeholder' => ['en' => 'Search products…', 'el' => 'Αναζήτηση προϊόντων…'],
];
foreach ($labels as $key => $text) {
LanguageLine::create([
'group' => 'storefront',
'key' => $key,
'text' => $text,
]);
}
}
}