sqlSrvClient->query($sql); $masterData = []; foreach ($rows as $row) { $sku = $row['ITEM_NO']; $categories = array_values( array_filter( array_map( fn($value) => // Check if the category ends with '.html' and remove it str_ends_with($value, '.html') ? substr($value, 0, -5) : $value, $row ), fn($value, $key) => // Keep only non-empty category values and keys that start with 'category' str_starts_with($key, 'USR_MAG_CATEG_') && !empty($value), ARRAY_FILTER_USE_BOTH ) ); $masterData[$sku] = $categories; } return $masterData; } /** * Load categories from CSV file * * @return array */ public function loadCsvCategories(): array { $csvData = []; if (($handle = fopen($this->csvFilePath, "r")) !== false) { while (($data = fgetcsv($handle, 1000, ",")) !== false) { //sku, name, category.path $sku = $data[0]; $categories = explode(";", $data[2]); $csvData[$sku] = $categories; } fclose($handle); } return $csvData; } /** * Compare categories between the two systems * * @return array */ public function compareCategories(): array { $masterData = $this->fetchMasterCategories(); $csvData = $this->loadCsvCategories(); $mismatches = []; foreach ($masterData as $sku => $masterCategories) { // If the SKU does not exist in the CSV data, skip it if (!isset($csvData[$sku])) { continue; // Skip to the next SKU since this one might not be synced yet } $csvCategories = $csvData[$sku]; $diffMasterToCsv = array_diff($masterCategories, $csvCategories); $diffCsvToMaster = array_diff($csvCategories, $masterCategories); if ($diffMasterToCsv !== [] || $diffCsvToMaster !== []) { // There are mismatches between the categories $mismatches[$sku] = ['master' => $diffMasterToCsv, 'csv' => $diffCsvToMaster]; } } return $mismatches; } /** * Output the mismatches to the console * * @return void */ public function outputMismatches(): void { $mismatches = $this->compareCategories(); foreach ($mismatches as $sku => $mismatch) { echo "SKU: {$sku}\n"; echo "Counterpoint only categories: " . implode(", ", $mismatch['master']) . "\n"; echo "Magento only categories: " . implode(", ", $mismatch['csv']) . "\n"; echo "-----------------------------------\n"; } } /** * Output the mismatches as an XLSX file * * @param string $outputFilePath The path to the output file * @return void */ public function outputMismatchesAsXlsx(string $outputFilePath): void { $mismatches = $this->compareCategories(); $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); // Set the header $sheet->setCellValue('A1', 'SKU'); $sheet->setCellValue('B1', 'Counterpoint Only Categories'); $sheet->setCellValue('C1', 'Magento Only Categories'); $sheet->getStyle('A1:C1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); $sheet->getStyle('A1:C1')->getFont()->setBold(true); $row = 2; // Start from the second row to leave space for the header foreach ($mismatches as $sku => $mismatch) { $sheet->setCellValue('A' . $row, $sku); $sheet->setCellValue('B' . $row, implode(", ", $mismatch['master'])); $sheet->setCellValue('C' . $row, implode(", ", $mismatch['csv'])); $row++; } // Auto size columns for content foreach (range('A', 'C') as $columnID) { $sheet->getColumnDimension($columnID)->setAutoSize(true); } $writer = new Xlsx($spreadsheet); $writer->save($outputFilePath); } /** * Output the missing categories as a CSV file * * @param string $outputFilePath */ public function outputMissingCategoriesAsCsv(string $outputFilePath): void { $mismatches = $this->compareCategories(); if (($handle = fopen($outputFilePath, 'w')) !== false) { foreach ($mismatches as $sku => $missingCategories) { foreach ($missingCategories['csv'] as $category) { fputcsv($handle, ['-CCP', $category, $sku]); } } fclose($handle); } } }