400 lines
13 KiB
PHP
400 lines
13 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Services\MagentoCategoryMigrationService;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class MagentoMigrationController extends Controller
|
|
{
|
|
protected $migrationService;
|
|
|
|
public function __construct(MagentoCategoryMigrationService $migrationService)
|
|
{
|
|
$this->migrationService = $migrationService;
|
|
}
|
|
|
|
/**
|
|
* Show the migration interface
|
|
*/
|
|
public function index()
|
|
{
|
|
$m1Stores = $this->migrationService->getMagento1Stores();
|
|
$m2Stores = $this->migrationService->getMagento2Stores();
|
|
$connectionTest = $this->migrationService->testConnections();
|
|
$m1Categories = $this->migrationService->getMagento1Categories();
|
|
$m2Categories = $this->migrationService->getMagento2Categories();
|
|
$m2CategoriesNotInM1 = $this->migrationService->getM2CategoriesNotInM1();
|
|
$m1Attributes = $this->migrationService->getMagento1Attributes();
|
|
$m2Attributes = $this->migrationService->getMagento2Attributes();
|
|
$m1AttributesMissingInM2 = $this->migrationService->getM1AttributesMissingInM2();
|
|
$m1AttributeGroups = $this->migrationService->getMagento1AttributeGroups();
|
|
$m2AttributeGroups = $this->migrationService->getMagento2AttributeGroups();
|
|
$m1AttributeGroupsMissingInM2 = $this->migrationService->getM1AttributeGroupsMissingInM2();
|
|
$m1Products = $this->migrationService->getMagento1Products();
|
|
$m2Products = $this->migrationService->getMagento2Products();
|
|
$m1ProductsNotInM2 = $this->migrationService->getM1ProductsNotInM2();
|
|
$m2ProductsNotInM1 = $this->migrationService->getM2ProductsNotInM1();
|
|
|
|
return view('migration.index', [
|
|
'm1Stores' => $m1Stores,
|
|
'm2Stores' => $m2Stores,
|
|
'connectionTest' => $connectionTest,
|
|
'm1CategoriesCount' => $m1Categories->count(),
|
|
'm2CategoriesCount' => $m2Categories->count(),
|
|
'm2CategoriesNotInM1' => $m2CategoriesNotInM1,
|
|
'm1Attributes' => $m1Attributes,
|
|
'm2Attributes' => $m2Attributes,
|
|
'm1AttributesMissingInM2' => $m1AttributesMissingInM2,
|
|
'm1AttributeGroups' => $m1AttributeGroups,
|
|
'm2AttributeGroups' => $m2AttributeGroups,
|
|
'm1AttributeGroupsMissingInM2' => $m1AttributeGroupsMissingInM2,
|
|
'm1Products' => $m1Products,
|
|
'm2Products' => $m2Products,
|
|
'm1ProductsNotInM2' => $m1ProductsNotInM2,
|
|
'm2ProductsNotInM1' => $m2ProductsNotInM1,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Test database connections
|
|
*/
|
|
public function testConnections()
|
|
{
|
|
$results = $this->migrationService->testConnections();
|
|
|
|
return response()->json([
|
|
'success' => $results['magento1'] && $results['magento2'],
|
|
'results' => $results,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get Magento 1 categories preview
|
|
*/
|
|
public function getMagento1Categories()
|
|
{
|
|
$categories = $this->migrationService->getMagento1Categories();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'count' => $categories->count(),
|
|
'categories' => $categories->take(50)->map(function($cat) {
|
|
return [
|
|
'id' => $cat->entity_id,
|
|
'name' => $cat->name ?? 'N/A',
|
|
'level' => $cat->level,
|
|
'parent_id' => $cat->parent_id,
|
|
'is_active' => $cat->is_active ?? 0,
|
|
];
|
|
}),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get Magento 1 category tree
|
|
*/
|
|
public function getMagento1CategoryTree()
|
|
{
|
|
try {
|
|
$categories = $this->migrationService->getMagento1Categories();
|
|
$tree = $this->migrationService->buildCategoryTreeHierarchy($categories, 'm1');
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'tree' => $tree,
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error('Error fetching M1 category tree: ' . $e->getMessage());
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Failed to fetch category tree: ' . $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get Magento 1 category tree with products
|
|
*/
|
|
public function getMagento1CategoryTreeWithProducts()
|
|
{
|
|
try {
|
|
$tree = $this->migrationService->getMagento1CategoryTreeWithProducts();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'tree' => $tree
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error('Error fetching M1 category tree with products: ' . $e->getMessage());
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Failed to load category tree with products: ' . $e->getMessage(),
|
|
'tree' => []
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get Magento 2 category tree with products
|
|
*/
|
|
public function getMagento2CategoryTreeWithProducts()
|
|
{
|
|
try {
|
|
$tree = $this->migrationService->getMagento2CategoryTreeWithProducts();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'tree' => $tree
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error('Error fetching M2 category tree with products: ' . $e->getMessage());
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Failed to load category tree with products: ' . $e->getMessage(),
|
|
'tree' => []
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get Magento 2 category tree
|
|
*/
|
|
public function getMagento2CategoryTree()
|
|
{
|
|
try {
|
|
$categories = $this->migrationService->getMagento2Categories();
|
|
$tree = $this->migrationService->buildCategoryTreeHierarchy($categories, 'm2');
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'tree' => $tree,
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error('Error fetching M2 category tree: ' . $e->getMessage());
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Failed to fetch category tree: ' . $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a category
|
|
*/
|
|
public function deleteCategory(Request $request, $categoryId)
|
|
{
|
|
$request->validate([
|
|
'source' => 'nullable|in:m1,m2',
|
|
]);
|
|
|
|
try {
|
|
$source = $request->input('source', 'm2');
|
|
$result = $this->migrationService->deleteCategory($categoryId, $source);
|
|
|
|
return response()->json($result, $result['success'] ? 200 : 400);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Category deletion error: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Deletion failed: ' . $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rename a Magento 2 category
|
|
*/
|
|
public function renameCategory(Request $request, $categoryId)
|
|
{
|
|
$request->validate([
|
|
'name' => 'required|string|max:255',
|
|
'store_id' => 'nullable|integer',
|
|
]);
|
|
|
|
try {
|
|
$newName = $request->input('name');
|
|
$storeId = $request->input('store_id', 0);
|
|
$result = $this->migrationService->renameCategory($categoryId, $newName, $storeId);
|
|
|
|
return response()->json($result, $result['success'] ? 200 : 400);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Category rename error: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Rename failed: ' . $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migrate an attribute from Magento 1 to Magento 2
|
|
*/
|
|
public function migrateAttribute(Request $request, $attributeId)
|
|
{
|
|
try {
|
|
$result = $this->migrationService->migrateAttribute($attributeId);
|
|
|
|
return response()->json($result, $result['success'] ? 200 : 400);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Attribute migration error: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Migration failed: ' . $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migrate an attribute group from Magento 1 to Magento 2
|
|
*/
|
|
public function migrateAttributeGroup(Request $request, $groupId, $setId)
|
|
{
|
|
try {
|
|
$result = $this->migrationService->migrateAttributeGroup($groupId, $setId);
|
|
|
|
return response()->json($result, $result['success'] ? 200 : 400);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Attribute group migration error: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Migration failed: ' . $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migrate all products from Magento 1 to Magento 2
|
|
*/
|
|
public function migrateProducts(Request $request)
|
|
{
|
|
try {
|
|
$dryRun = $request->input('dry_run', false);
|
|
$result = $this->migrationService->migrateProducts($dryRun);
|
|
|
|
return response()->json($result, $result['success'] ? 200 : 400);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Product migration error: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Migration failed: ' . $e->getMessage(),
|
|
'added' => 0,
|
|
'updated' => 0,
|
|
'errors' => 0,
|
|
'log' => [],
|
|
'missing_attributes' => []
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a single product from Magento 2
|
|
*/
|
|
public function deleteM2Product(Request $request, $productId)
|
|
{
|
|
try {
|
|
$result = $this->migrationService->deleteM2Product($productId);
|
|
|
|
return response()->json($result, $result['success'] ? 200 : 400);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Delete M2 product error: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Deletion failed: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sync product category assignments from M1 to M2
|
|
*/
|
|
public function syncProductCategories(Request $request)
|
|
{
|
|
try {
|
|
$result = $this->migrationService->syncProductCategories();
|
|
|
|
return response()->json($result, $result['success'] ? 200 : 400);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Sync product categories error: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Sync failed: ' . $e->getMessage(),
|
|
'updated' => 0,
|
|
'skipped' => 0,
|
|
'errors' => 0,
|
|
'log' => []
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete all products in Magento 2 that have entity_id greater than max M1 product ID
|
|
*/
|
|
public function deleteM2ProductsAboveM1Max(Request $request)
|
|
{
|
|
try {
|
|
$result = $this->migrationService->deleteM2ProductsAboveM1Max();
|
|
|
|
return response()->json($result, $result['success'] ? 200 : 400);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Delete M2 products error: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Deletion failed: ' . $e->getMessage(),
|
|
'deleted' => 0
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Execute the migration
|
|
*/
|
|
public function migrate(Request $request)
|
|
{
|
|
$request->validate([
|
|
'store_mapping' => 'required|array',
|
|
'store_mapping.*' => 'required|integer',
|
|
]);
|
|
|
|
try {
|
|
$storeMapping = $request->input('store_mapping');
|
|
|
|
// Convert array format: ['m1_store_id' => 'm2_store_id']
|
|
$mapping = [];
|
|
foreach ($storeMapping as $m1StoreId => $m2StoreId) {
|
|
$mapping[(int)$m1StoreId] = (int)$m2StoreId;
|
|
}
|
|
|
|
$result = $this->migrationService->migrateCategories($mapping);
|
|
|
|
return response()->json($result);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Migration error: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Migration failed: ' . $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
}
|
|
|