2 Commits

9 changed files with 152 additions and 3 deletions
+2 -1
View File
@@ -13,7 +13,8 @@
"lunarphp/lunar": "1.3.0",
"laravel/framework": "^12.0",
"laravel/tinker": "^3.0",
"symfony/yaml": "^7.0"
"symfony/yaml": "^7.0",
"lunarphp/table-rate-shipping": "^1.3"
},
"require-dev": {
"fakerphp/faker": "^1.23",
+61
View File
@@ -0,0 +1,61 @@
<?php
namespace Modules\Core\Command;
use Illuminate\Console\Command;
use Modules\Core\MigrateImport\ImportSpec;
use Modules\Core\MigrateImport\RunMigrateImportJob;
class MigrateImportCommand extends Command
{
protected $signature = "boboko:migrate:import
{--source= : The source platform to import from}
{--type= : The import mechanism for the chosen source}
{--file= : Path to the export file (when type is export)}";
protected $description = "Migrate data (products, customers, etc.) from an external source";
// Supported sources. Only "shopify" is wired up for now.
private const SOURCES = [
"shopify",
// "woocommerce",
];
// Supported import types per source. Only "export" is wired up for now.
private const TYPES = [
"export",
// "api",
];
public function handle(): void
{
$source = $this->option("source")
?? $this->choice("Select a source:", self::SOURCES, 0);
$type = $this->option("type")
?? $this->choice("Select an import type:", self::TYPES, 0);
if ($type === "api") {
$credentials = [
"api_key" => $this->secret("API key:"),
"api_secret" => $this->secret("API secret:"),
];
$filePath = null;
} else {
$filePath = $this->option("file")
?? $this->ask("Path to the export file:");
$credentials = null;
}
$spec = new ImportSpec(
source: $source,
type: $type,
filePath: $filePath,
credentials: $credentials,
);
RunMigrateImportJob::dispatch($spec);
$this->info("Import queued.");
}
}
+3 -1
View File
@@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Mail;
use Lunar\Admin\Filament\Resources\StaffResource;
use Lunar\Admin\Models\Staff as LunarStaff;
use Lunar\Admin\Support\Facades\LunarPanel;
use Lunar\Shipping\ShippingPlugin;
use Modules\Core\Auth\Extensions\StaffResourceExtension;
use Modules\Core\Auth\Filament\Pages\Login;
use Modules\Core\Auth\Mail\InviteMail;
@@ -25,7 +26,8 @@ class CorePlugin implements Plugin
->brandName('Boboko')
->brandLogo(asset('static/logos/core/boboko-logo.svg'))
->darkModeBrandLogo(asset('static/logos/core/boboko-logo-white.svg'))
->login(Login::class);
->login(Login::class)
->plugin(ShippingPlugin::make());
LunarPanel::extensions([
StaffResource::class => StaffResourceExtension::class,
+14
View File
@@ -0,0 +1,14 @@
<?php
namespace Modules\Core\MigrateImport;
class ImportSpec
{
public function __construct(
public readonly string $source,
public readonly string $type,
public readonly ?string $filePath = null,
public readonly ?array $credentials = null,
) {
}
}
+8
View File
@@ -0,0 +1,8 @@
<?php
namespace Modules\Core\MigrateImport;
interface Importer
{
public function import(ImportSpec $spec): void;
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace Modules\Core\MigrateImport;
use Modules\Core\MigrateImport\Shopify\ShopifyExportImporter;
class ImporterFactory
{
public static function make(ImportSpec $spec): Importer
{
return match ([$spec->source, $spec->type]) {
["shopify", "export"] => new ShopifyExportImporter(),
// ["shopify", "api"] => new ShopifyApiImporter(),
// ["woocommerce", "export"] => new WooCommerceExportImporter(),
// ["woocommerce", "api"] => new WooCommerceApiImporter(),
default => throw new \InvalidArgumentException(
"No importer available for source \"{$spec->source}\" with type \"{$spec->type}\".",
),
};
}
}
+28
View File
@@ -0,0 +1,28 @@
<?php
namespace Modules\Core\MigrateImport;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class RunMigrateImportJob implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
public function __construct(
public readonly ImportSpec $spec,
) {
}
public function handle(): void
{
$importer = ImporterFactory::make($this->spec);
$importer->import($this->spec);
}
}
@@ -0,0 +1,13 @@
<?php
namespace Modules\Core\MigrateImport\Shopify;
use Modules\Core\MigrateImport\ImportSpec;
use Modules\Core\MigrateImport\Importer;
class ShopifyExportImporter implements Importer
{
public function import(ImportSpec $spec): void
{
}
}
+2 -1
View File
@@ -8,6 +8,7 @@ use Modules\Core\Command\AnonymizeCommand;
use Modules\Core\Command\ExportCleanupCommand;
use Modules\Core\Command\ExportCommand;
use Modules\Core\Command\ImportCommand;
use Modules\Core\Command\MigrateImportCommand;
class CoreServiceProvider extends ServiceProvider
{
@@ -32,7 +33,7 @@ class CoreServiceProvider extends ServiceProvider
], 'core-assets');
if ($this->app->runningInConsole()) {
$this->commands([AnonymizeCommand::class, ExportCommand::class, ExportCleanupCommand::class, ImportCommand::class]);
$this->commands([AnonymizeCommand::class, ExportCommand::class, ExportCleanupCommand::class, ImportCommand::class, MigrateImportCommand::class]);
}
}
}