diff --git a/app/Services/MagentoCategoryMigrationService.php b/app/Services/MagentoCategoryMigrationService.php index 968837b..4238f97 100644 --- a/app/Services/MagentoCategoryMigrationService.php +++ b/app/Services/MagentoCategoryMigrationService.php @@ -2204,6 +2204,11 @@ public function migrateProducts($dryRun = false) // Ensure product is enabled and visible (required for products to show in categories after reindex) $this->ensureProductIsEnabledAndVisible($m2ProductId); $this->migrateProductCategories($m1Product->entity_id, $m2ProductId, $categoryMapping); + + // Migrate URL rewrites for new products + if ($isNew) { + $this->migrateProductUrlRewrites($m1Product->entity_id, $m2ProductId); + } } } catch (Exception $e) { @@ -3450,6 +3455,124 @@ protected function migrateProductCategories($m1ProductId, $m2ProductId, $categor } } + /** + * Get store mapping by matching store codes + */ + protected function getStoreMapping() + { + // If store mapping was set during category migration, use it + if (!empty($this->storeMapping)) { + return $this->storeMapping; + } + + // Otherwise, try to build mapping by matching store codes + $mapping = []; + + try { + $m1Stores = $this->getMagento1Stores(); + $m2Stores = $this->getMagento2Stores(); + + // Create a map of M2 stores by code + $m2StoreMap = []; + foreach ($m2Stores as $m2Store) { + $code = strtolower(trim($m2Store->code ?? '')); + if (!empty($code) && !isset($m2StoreMap[$code])) { + $m2StoreMap[$code] = $m2Store->store_id; + } + } + + // Match M1 stores to M2 by code + foreach ($m1Stores as $m1Store) { + $code = strtolower(trim($m1Store->code ?? '')); + if (!empty($code) && isset($m2StoreMap[$code])) { + $mapping[$m1Store->store_id] = $m2StoreMap[$code]; + } else { + // If no match by code, try to match by store_id (default store) + // This is a fallback for stores with same ID + $mapping[$m1Store->store_id] = $m1Store->store_id; + } + } + } catch (Exception $e) { + Log::warning('Error building store mapping: ' . $e->getMessage()); + } + + return $mapping; + } + + /** + * Migrate URL rewrites from M1 core_url_rewrite to M2 url_rewrite for a product + */ + protected function migrateProductUrlRewrites($m1ProductId, $m2ProductId) + { + try { + // Get store mapping + $storeMapping = $this->getStoreMapping(); + + // Get all URL rewrites for this product from M1 + // In M1, product URLs are identified by id_path like "product/{product_id}" or "product/{product_id}/..." + $m1UrlRewrites = DB::connection($this->magento1Connection) + ->table($this->magento1Prefix . 'core_url_rewrite') + ->where(function($query) use ($m1ProductId) { + $query->where('id_path', '=', 'product/' . $m1ProductId) + ->orWhere('id_path', 'like', 'product/' . $m1ProductId . '/%'); + }) + ->get(); + + if ($m1UrlRewrites->isEmpty()) { + return; + } + + foreach ($m1UrlRewrites as $m1Rewrite) { + // Map store ID + $m1StoreId = $m1Rewrite->store_id ?? 0; + $m2StoreId = isset($storeMapping[$m1StoreId]) ? $storeMapping[$m1StoreId] : $m1StoreId; + + // Extract request_path and target_path from M1 + $requestPath = $m1Rewrite->request_path ?? ''; + $targetPath = $m1Rewrite->target_path ?? ''; + + // Skip if paths are empty + if (empty($requestPath) || empty($targetPath)) { + continue; + } + + // Update target_path to use M2 product ID + // M1 target_path format: catalog/product/view/id/{product_id} + // M2 target_path format: catalog/product/view/id/{product_id} + $targetPath = preg_replace('/\/id\/\d+/', '/id/' . $m2ProductId, $targetPath); + + // Check if this URL rewrite already exists in M2 + $exists = DB::connection($this->magento2Connection) + ->table($this->magento2Prefix . 'url_rewrite') + ->where('entity_type', 'product') + ->where('entity_id', $m2ProductId) + ->where('request_path', $requestPath) + ->where('store_id', $m2StoreId) + ->exists(); + + if (!$exists) { + // Insert URL rewrite into M2 + DB::connection($this->magento2Connection) + ->table($this->magento2Prefix . 'url_rewrite') + ->insert([ + 'entity_type' => 'product', + 'entity_id' => $m2ProductId, + 'request_path' => $requestPath, + 'target_path' => $targetPath, + 'redirect_type' => 0, // 0 = No redirect + 'store_id' => $m2StoreId, + 'description' => $m1Rewrite->description ?? null, + 'is_autogenerated' => ($m1Rewrite->is_system ?? 0) ? 1 : 0, // M1 is_system=1 means auto-generated, same as M2 + 'metadata' => null, + ]); + } + } + } catch (Exception $e) { + Log::error("Error migrating URL rewrites for product M1 ID {$m1ProductId}, M2 ID {$m2ProductId}: " . $e->getMessage()); + // Don't throw - just log the error and continue + } + } + /** * Ensure product is enabled and visible (required for products to appear in categories after reindex) */