magento1Connection = 'magento1'; $this->magento2Connection = 'magento2'; $this->magento1Prefix = config('database.connections.magento1.prefix', ''); $this->magento2Prefix = config('database.connections.magento2.prefix', ''); } /** * Get all stores from Magento 1 */ public function getMagento1Stores() { try { $stores = DB::connection($this->magento1Connection) ->table($this->magento1Prefix . 'core_store') ->select('store_id', 'code', 'name', 'website_id', 'group_id') ->where('store_id', '>', 0) ->get(); return $stores; } catch (Exception $e) { Log::error('Error fetching Magento 1 stores: ' . $e->getMessage()); return collect([]); } } /** * Get all stores from Magento 2 */ public function getMagento2Stores() { try { $stores = DB::connection($this->magento2Connection) ->table($this->magento2Prefix . 'store') ->select('store_id', 'code', 'name', 'website_id') ->where('store_id', '>', 0) ->get(); return $stores; } catch (Exception $e) { Log::error('Error fetching Magento 2 stores: ' . $e->getMessage()); return collect([]); } } /** * Get all categories from Magento 1 for a specific store */ public function getMagento1Categories($storeId = null) { try { // Get entity type ID $entityTypeId = DB::connection($this->magento1Connection) ->table($this->magento1Prefix . 'eav_entity_type') ->where('entity_type_code', 'catalog_category') ->value('entity_type_id'); if (!$entityTypeId) { return collect([]); } // Get attribute IDs $nameAttributeId = DB::connection($this->magento1Connection) ->table($this->magento1Prefix . 'eav_attribute') ->where('entity_type_id', $entityTypeId) ->where('attribute_code', 'name') ->value('attribute_id'); $isActiveAttributeId = DB::connection($this->magento1Connection) ->table($this->magento1Prefix . 'eav_attribute') ->where('entity_type_id', $entityTypeId) ->where('attribute_code', 'is_active') ->value('attribute_id'); $urlKeyAttributeId = DB::connection($this->magento1Connection) ->table($this->magento1Prefix . 'eav_attribute') ->where('entity_type_id', $entityTypeId) ->where('attribute_code', 'url_key') ->value('attribute_id'); $targetStoreId = $storeId ?? 0; // Get base category data $categories = DB::connection($this->magento1Connection) ->table($this->magento1Prefix . 'catalog_category_entity') ->select('entity_id', 'parent_id', 'level', 'path', 'position') ->orderBy('level') ->orderBy('position') ->get(); // Get attribute values $nameValues = []; $isActiveValues = []; $urlKeyValues = []; if ($nameAttributeId) { $nameValues = DB::connection($this->magento1Connection) ->table($this->magento1Prefix . 'catalog_category_entity_varchar') ->where('attribute_id', $nameAttributeId) ->where('store_id', $targetStoreId) ->pluck('value', 'entity_id') ->toArray(); } if ($isActiveAttributeId) { $isActiveValues = DB::connection($this->magento1Connection) ->table($this->magento1Prefix . 'catalog_category_entity_int') ->where('attribute_id', $isActiveAttributeId) ->where('store_id', $targetStoreId) ->pluck('value', 'entity_id') ->toArray(); } if ($urlKeyAttributeId) { $urlKeyValues = DB::connection($this->magento1Connection) ->table($this->magento1Prefix . 'catalog_category_entity_varchar') ->where('attribute_id', $urlKeyAttributeId) ->where('store_id', $targetStoreId) ->pluck('value', 'entity_id') ->toArray(); } // Combine data return $categories->map(function($category) use ($nameValues, $isActiveValues, $urlKeyValues) { $category->name = $nameValues[$category->entity_id] ?? null; $category->is_active = $isActiveValues[$category->entity_id] ?? null; $category->url_key = $urlKeyValues[$category->entity_id] ?? null; return $category; }); } catch (Exception $e) { Log::error('Error fetching Magento 1 categories: ' . $e->getMessage()); return collect([]); } } /** * Migrate categories from Magento 1 to Magento 2 */ public function migrateCategories($storeMapping = []) { $this->storeMapping = $storeMapping; $this->migrationLog = []; $this->categoryMapping = []; try { DB::connection($this->magento2Connection)->beginTransaction(); // Get root category ID for Magento 2 (usually 2) $rootCategoryId = $this->getMagento2RootCategoryId(); // Get all categories from Magento 1 $m1Categories = $this->getMagento1Categories(); // Build category tree $categoryTree = $this->buildCategoryTree($m1Categories); // Migrate categories level by level foreach ($categoryTree as $level => $categories) { foreach ($categories as $m1Category) { $this->migrateCategory($m1Category, $rootCategoryId); } } // Migrate category attributes for each store foreach ($this->storeMapping as $m1StoreId => $m2StoreId) { $this->migrateCategoryAttributes($m1StoreId, $m2StoreId); } DB::connection($this->magento2Connection)->commit(); return [ 'success' => true, 'message' => 'Categories migrated successfully', 'migrated_count' => count($this->categoryMapping), 'log' => $this->migrationLog ]; } catch (Exception $e) { DB::connection($this->magento2Connection)->rollBack(); Log::error('Category migration error: ' . $e->getMessage()); return [ 'success' => false, 'message' => 'Migration failed: ' . $e->getMessage(), 'log' => $this->migrationLog ]; } } /** * Build category tree organized by level */ protected function buildCategoryTree($categories) { $tree = []; foreach ($categories as $category) { $level = $category->level ?? 1; if (!isset($tree[$level])) { $tree[$level] = []; } $tree[$level][] = $category; } ksort($tree); return $tree; } /** * Migrate a single category */ protected function migrateCategory($m1Category, $parentId = null) { try { // Check if category already exists if (isset($this->categoryMapping[$m1Category->entity_id])) { return $this->categoryMapping[$m1Category->entity_id]; } // Determine parent ID if ($m1Category->parent_id == 1 || $m1Category->parent_id == 0) { $m2ParentId = $parentId ?? $this->getMagento2RootCategoryId(); } else { $m2ParentId = $this->categoryMapping[$m1Category->parent_id] ?? $parentId; } // Insert category entity $m2EntityId = DB::connection($this->magento2Connection) ->table($this->magento2Prefix . 'catalog_category_entity') ->insertGetId([ 'attribute_set_id' => 3, // Default category attribute set 'parent_id' => $m2ParentId, 'created_at' => now(), 'updated_at' => now(), 'path' => '', 'position' => $m1Category->position ?? 0, 'level' => $m1Category->level ?? 1, 'children_count' => 0, ]); // Update path $path = $this->buildCategoryPath($m2EntityId, $m2ParentId); DB::connection($this->magento2Connection) ->table($this->magento2Prefix . 'catalog_category_entity') ->where('entity_id', $m2EntityId) ->update(['path' => $path]); // Store mapping $this->categoryMapping[$m1Category->entity_id] = $m2EntityId; $this->migrationLog[] = "Migrated category ID {$m1Category->entity_id} -> {$m2EntityId} ({$m1Category->name})"; return $m2EntityId; } catch (Exception $e) { Log::error("Error migrating category {$m1Category->entity_id}: " . $e->getMessage()); $this->migrationLog[] = "ERROR: Failed to migrate category ID {$m1Category->entity_id}: " . $e->getMessage(); throw $e; } } /** * Build category path */ protected function buildCategoryPath($entityId, $parentId) { if ($parentId == $this->getMagento2RootCategoryId()) { return "1/{$parentId}/{$entityId}"; } $parent = DB::connection($this->magento2Connection) ->table($this->magento2Prefix . 'catalog_category_entity') ->where('entity_id', $parentId) ->first(); if ($parent && $parent->path) { return $parent->path . '/' . $entityId; } return "1/{$parentId}/{$entityId}"; } /** * Migrate category attributes for a specific store */ protected function migrateCategoryAttributes($m1StoreId, $m2StoreId) { try { // Get attribute IDs for Magento 2 $attributeIds = $this->getMagento2AttributeIds(); // Get categories with their attributes from Magento 1 $m1Categories = $this->getMagento1Categories($m1StoreId); foreach ($m1Categories as $m1Category) { if (!isset($this->categoryMapping[$m1Category->entity_id])) { continue; } $m2EntityId = $this->categoryMapping[$m1Category->entity_id]; // Migrate name if ($m1Category->name) { $this->insertCategoryAttribute( $m2EntityId, $attributeIds['name'], $m2StoreId, $m1Category->name ); } // Migrate is_active if ($m1Category->is_active !== null) { $this->insertCategoryAttribute( $m2EntityId, $attributeIds['is_active'], $m2StoreId, $m1Category->is_active ); } // Migrate url_key if ($m1Category->url_key) { $this->insertCategoryAttribute( $m2EntityId, $attributeIds['url_key'], $m2StoreId, $m1Category->url_key ); } } $this->migrationLog[] = "Migrated attributes for store mapping: M1 Store {$m1StoreId} -> M2 Store {$m2StoreId}"; } catch (Exception $e) { Log::error("Error migrating category attributes: " . $e->getMessage()); $this->migrationLog[] = "ERROR: Failed to migrate attributes for store {$m1StoreId}: " . $e->getMessage(); throw $e; } } /** * Insert category attribute value */ protected function insertCategoryAttribute($entityId, $attributeId, $storeId, $value) { // Determine which table to use based on attribute type $attribute = DB::connection($this->magento2Connection) ->table($this->magento2Prefix . 'eav_attribute') ->where('attribute_id', $attributeId) ->first(); if (!$attribute) { return; } $table = $this->magento2Prefix . 'catalog_category_entity_' . $attribute->backend_type; // Check if value already exists $exists = DB::connection($this->magento2Connection) ->table($table) ->where('entity_id', $entityId) ->where('attribute_id', $attributeId) ->where('store_id', $storeId) ->exists(); if ($exists) { DB::connection($this->magento2Connection) ->table($table) ->where('entity_id', $entityId) ->where('attribute_id', $attributeId) ->where('store_id', $storeId) ->update(['value' => $value]); } else { DB::connection($this->magento2Connection) ->table($table) ->insert([ 'attribute_id' => $attributeId, 'store_id' => $storeId, 'entity_id' => $entityId, 'value' => $value, ]); } } /** * Get Magento 2 attribute IDs */ protected function getMagento2AttributeIds() { $entityTypeId = DB::connection($this->magento2Connection) ->table($this->magento2Prefix . 'eav_entity_type') ->where('entity_type_code', 'catalog_category') ->value('entity_type_id'); $attributes = DB::connection($this->magento2Connection) ->table($this->magento2Prefix . 'eav_attribute') ->where('entity_type_id', $entityTypeId) ->whereIn('attribute_code', ['name', 'is_active', 'url_key']) ->pluck('attribute_id', 'attribute_code') ->toArray(); return $attributes; } /** * Get Magento 2 root category ID */ protected function getMagento2RootCategoryId() { // Root category is usually ID 2 in Magento 2 $rootId = DB::connection($this->magento2Connection) ->table($this->magento2Prefix . 'catalog_category_entity') ->where('level', 0) ->where('parent_id', 0) ->value('entity_id'); return $rootId ?: 2; } /** * Test database connections */ public function testConnections() { $results = [ 'magento1' => false, 'magento2' => false, ]; try { DB::connection($this->magento1Connection)->select('SELECT 1'); $results['magento1'] = true; } catch (Exception $e) { $results['magento1_error'] = $e->getMessage(); } try { DB::connection($this->magento2Connection)->select('SELECT 1'); $results['magento2'] = true; } catch (Exception $e) { $results['magento2_error'] = $e->getMessage(); } return $results; } }