Last active
June 10, 2022 10:56
-
-
Save klevu/e8fb14a2efa90dbc5288af5a20df4f50 to your computer and use it in GitHub Desktop.
bin/klevu-sync-debug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
use Klevu\Search\Api\KlevuSyncRepositoryInterface; | |
use Klevu\Search\Api\MagentoProductSyncRepositoryInterface; | |
use Magento\Eav\Model\Entity;use Magento\Framework\App\Bootstrap; | |
use Magento\Store\Api\Data\StoreInterface; | |
if (PHP_SAPI !== 'cli') { | |
echo 'bin/klevu-sync-debug must be run as a CLI application'; | |
exit(1); | |
} | |
$storeCode = isset($argv[1]) ? trim((string)$argv[1]) : null; | |
if (!$storeCode) { | |
echo 'Please specify a store code'; | |
exit(1); | |
} | |
try { | |
require __DIR__ . '/../app/bootstrap.php'; | |
$bootstrap = Bootstrap::create(BP, $_SERVER); | |
$objectManager = $bootstrap->getObjectManager(); | |
/** @var \Magento\Store\Model\StoreManagerInterface $storeManager */ | |
$storeManager = $objectManager->get(\Magento\Store\Model\StoreManagerInterface::class); | |
} catch (\Exception $e) { | |
echo 'Autoload error: ' . $e->getMessage(); | |
exit(1); | |
} | |
try { | |
$store = $storeManager->getStore($storeCode); | |
} catch (\Exception $e) { | |
echo 'Error loading store: ' . $e->getMessage(); | |
exit(1); | |
} | |
function diffMultiDimensionalArrays(array $array1, array $array2) | |
{ | |
$jsonDiff = array_diff( | |
array_map('json_encode', $array1), | |
array_map('json_encode', $array2) | |
); | |
return array_map('json_decode', $jsonDiff); | |
} | |
function formatMagentoProductIds( | |
$productIds = [], | |
$skipChildProducts = false, | |
$magentoProductSyncRepository = null | |
) { | |
$magentoProductIds = []; | |
if (!$productIds) { | |
return $magentoProductIds; | |
} | |
// getParentRelationsByChild | |
// $parentIds = $this->getParentRelationsByChild($productIds); | |
$list = $magentoProductSyncRepository->getParentProductRelations($productIds); | |
$parentIds = []; | |
foreach ($list as $row) { | |
if (!isset($parentIds[$row['product_id']])) { | |
$parentIds[$row['product_id']] = []; | |
} | |
$parentIds[$row['product_id']][] = $row; | |
} | |
unset($list); | |
// end getParentRelationsByChild | |
foreach ($productIds as $entityId) { | |
$entityParentIds = isset($parentIds[$entityId]) ? $parentIds[$entityId] : []; | |
foreach ($entityParentIds as $entityParentId) { | |
$magentoProductIds[] = [ | |
'product_id' => $entityId, | |
'parent_id' => $entityParentId[Entity::DEFAULT_ENTITY_ID_FIELD] | |
]; | |
} | |
if ($skipChildProducts) { | |
continue; | |
} | |
$magentoProductIds[] = [ | |
'product_id' => $entityId, | |
'parent_id' => \Klevu\Search\Model\Product\MagentoProductActions::PARENT_ID_WHEN_NOT_VISIBLE | |
]; | |
} | |
unset($parentIds); | |
return $magentoProductIds; | |
} | |
function formatProductIdsToDelete(array $productIdsToDelete, StoreInterface $store, $parentProductIds) | |
{ | |
$return = []; | |
foreach ($productIdsToDelete as $productIds) { | |
$productIds = (array)$productIds; | |
$parentId = $productIds[\Klevu\Search\Model\Klevu\Klevu::FIELD_PARENT_ID]; | |
$productId = $productIds[\Klevu\Search\Model\Klevu\Klevu::FIELD_PRODUCT_ID]; | |
$return[$parentId . '-' . $productId] = [ | |
'parent_id' => $parentId, | |
'product_id' => $productId | |
]; | |
if ( | |
!(int)$parentId || | |
($parentId && in_array($parentId, $parentProductIds, true)) | |
) { | |
continue; | |
} | |
$return[$productId] = [ | |
'parent_id' => $parentId, | |
'product_id' => $productId | |
]; | |
} | |
return $return; | |
} | |
function formatProductIdsToAdd(array $productIdsToAdd, StoreInterface $store) | |
{ | |
$productsIds = []; | |
foreach ($productIdsToAdd as $productIds) { | |
$productIds = (array)$productIds; | |
$parentId = $productIds[\Klevu\Search\Model\Klevu\Klevu::FIELD_PARENT_ID]; | |
$productId = $productIds[\Klevu\Search\Model\Klevu\Klevu::FIELD_PRODUCT_ID]; | |
if ((int)$parentId && | |
!in_array($parentId, $this->getParentProductIds($store), true) | |
) { | |
continue; | |
} | |
$productsIds[$parentId . '-' . $productId] = [ | |
'parent_id' => $parentId, | |
'product_id' => $productId | |
]; | |
} | |
return $productsIds; | |
} | |
/** @var Magento\Framework\App\State $appState */ | |
$appState = $objectManager->get(\Magento\Framework\App\State::class); | |
$appState->setAreaCode('frontend'); | |
/** @var Magento\Store\Model\StoreManagerInterface $storeManager */ | |
$storeManager = $objectManager->get(\Magento\Store\Model\StoreManagerInterface::class); | |
$storeManager->setCurrentStore($store); | |
/** @var KlevuSyncRepositoryInterface $klevuSyncRepository */ | |
$klevuSyncRepository = $objectManager->get(KlevuSyncRepositoryInterface::class); | |
/** @var MagentoProductSyncRepositoryInterface $magentoProductSyncRepository */ | |
$magentoProductSyncRepository = $objectManager->get(MagentoProductSyncRepositoryInterface::class); | |
/** @var \Klevu\Search\Model\Product\MagentoProductActionsInterface $magentoProductActions */ | |
$magentoProductActions = $objectManager->get(Klevu\Search\Model\Product\MagentoProductActionsInterface::class); | |
$productIds = [ | |
'delete' => $magentoProductActions->deleteProductCollection($store), | |
'update' => $magentoProductActions->updateProductCollection($store), | |
'add' => $magentoProductActions->addProductCollection($store), | |
]; | |
$maxSyncIds = [ | |
'delete' => $klevuSyncRepository->getMaxSyncId($store), | |
'update' => $klevuSyncRepository->getMaxSyncId($store), | |
'add' => $magentoProductSyncRepository->getMaxProductId($store), | |
]; | |
$colWidths = [20, 15, 15]; | |
$divider = sprintf( | |
'+%s+%s+%s+', | |
str_repeat('-', $colWidths[0]), | |
str_repeat('-', $colWidths[1]), | |
str_repeat('-', $colWidths[2]) | |
); | |
echo "ACTIONS SUMMARY" . PHP_EOL; | |
echo $divider . PHP_EOL; | |
echo sprintf( | |
'|%s|%s|%s|', | |
str_pad(' ACTION ', $colWidths[0], ' ', STR_PAD_RIGHT), | |
str_pad(' COUNT ', $colWidths[1], ' ', STR_PAD_LEFT), | |
str_pad(' MAX SYNC ID ', $colWidths[1], ' ', STR_PAD_LEFT) | |
) . PHP_EOL; | |
foreach ($maxSyncIds as $action => $maxSyncId) { | |
echo $divider . PHP_EOL; | |
echo sprintf( | |
'|%s|%s|%s|', | |
str_pad(' ' . $action . ' ', $colWidths[0], ' ', STR_PAD_RIGHT), | |
str_pad(' ' . number_format(count($productIds[$action])) . ' ', $colWidths[1], ' ', STR_PAD_LEFT), | |
str_pad(' ' . $maxSyncId . ' ', $colWidths[1], ' ', STR_PAD_LEFT) | |
) . PHP_EOL; | |
} | |
echo $divider . PHP_EOL; | |
echo PHP_EOL; | |
echo "PRODUCT IDS FOR ACTION" . PHP_EOL; | |
echo $divider . PHP_EOL; | |
echo sprintf( | |
'|%s|%s|%s|', | |
str_pad(' IDENTIFIER ', $colWidths[0], ' ', STR_PAD_RIGHT), | |
str_pad(' PARENT_ID ', $colWidths[1], ' ', STR_PAD_LEFT), | |
str_pad(' PRODUCT_ID ', $colWidths[1], ' ', STR_PAD_LEFT) | |
) . PHP_EOL; | |
foreach ($productIds as $rowTitle => $rowData) { | |
echo $divider . PHP_EOL; | |
echo sprintf('| %s |', str_pad($rowTitle, array_sum($colWidths))) . PHP_EOL; | |
foreach ($rowData as $identifier => $row) { | |
echo $divider . PHP_EOL; | |
echo sprintf( | |
'|%s|%s|%s|', | |
str_pad(' ' . $identifier . ' ', $colWidths[0], ' ', STR_PAD_RIGHT), | |
str_pad(' ' . $row['parent_id'] . ' ', $colWidths[1], ' ', STR_PAD_LEFT), | |
str_pad(' ' . $row['product_id'] . ' ', $colWidths[1], ' ', STR_PAD_LEFT) | |
) . PHP_EOL; | |
} | |
} | |
echo $divider . PHP_EOL; | |
echo PHP_EOL . PHP_EOL; | |
echo "PARENT PRODUCT IDS" . PHP_EOL; | |
$parentProductIds = $magentoProductSyncRepository->getParentProductIds($store); | |
echo implode(',', $parentProductIds) . PHP_EOL; | |
echo PHP_EOL . PHP_EOL; | |
// -- deleteProductCollection | |
echo "deleteProductCollection" . PHP_EOL; | |
echo "--------------------" . PHP_EOL . PHP_EOL; | |
$maxEntityId = $maxSyncIds['delete']; | |
if ($maxEntityId) { | |
$klevuSyncRepository->clearKlevuCollection(); | |
$lastEntityId = 0; | |
$i = 0; | |
while ($lastEntityId < $maxEntityId) { | |
echo "Iteration: " . $i . PHP_EOL; | |
echo "- Max Entity Id: " . $maxEntityId . PHP_EOL; | |
echo "- Last Entity Id: " . $lastEntityId . PHP_EOL; | |
$klevuProductIds = $klevuSyncRepository->getProductIds($store, [], $lastEntityId); | |
echo "- Klevu Product Ids (" . count($klevuProductIds) . "): " . implode(',', array_map('json_encode', $klevuProductIds)) . PHP_EOL; | |
if (!$klevuProductIds || ++$i >= \Klevu\Search\Model\Product\MagentoProductActions::MAX_ITERATIONS) { | |
echo PHP_EOL; | |
echo "* Exiting loop" . PHP_EOL; | |
break; | |
} | |
$lastEntityId = (int)max(array_column($klevuProductIds, \Klevu\Search\Model\Klevu\Klevu::FIELD_ENTITY_ID)); | |
$productIdsToFilter = array_map(static function (array $product) { | |
return $product['product_id']; | |
}, $klevuProductIds); | |
array_walk($klevuProductIds, function (&$v) { | |
unset($v['row_id']); | |
}); | |
echo "- Product Ids to Filter (" . count($productIdsToFilter) . "): " . implode(',', $productIdsToFilter) . PHP_EOL; | |
$magentoProductIdsCollection = $magentoProductSyncRepository->getProductIdsCollection( | |
$store, | |
MagentoProductSyncRepositoryInterface::NOT_VISIBLE_INCLUDED | |
); | |
echo "- Magento Product Ids Collection (" . $magentoProductIdsCollection->count() . "): " . implode(',', $magentoProductIdsCollection->getColumnValues('entity_id')) . PHP_EOL; | |
$magentoProductIds = $magentoProductSyncRepository->getBatchDataForCollection( | |
$magentoProductIdsCollection, | |
$store, | |
$productIdsToFilter, | |
null | |
); | |
echo "- Magento Product Ids (" . count($magentoProductIds) . "): " . implode(',', $magentoProductIds) . PHP_EOL; | |
$magentoProductIds = formatMagentoProductIds($magentoProductIds, false, $magentoProductSyncRepository); | |
echo "- Magento Product Ids - after format (" . count($magentoProductIds) . "): " . json_encode($magentoProductIds) . PHP_EOL; | |
$productIdsDiff = diffMultiDimensionalArrays($klevuProductIds, $magentoProductIds); | |
echo "- Product Ids Diff (" . count($productIdsDiff) . "): " . json_encode($productIdsDiff) . PHP_EOL; | |
$formattedProductIdsToDelete = formatProductIdsToDelete($productIdsDiff, $store, $parentProductIds); | |
echo "- Formatted Product Ids to Delete (" . count($formattedProductIdsToDelete) . "): " . json_encode($formattedProductIdsToDelete) . PHP_EOL; | |
echo PHP_EOL . "-----" . PHP_EOL; | |
} | |
} else { | |
echo "No max entity for delete operation" . PHP_EOL; | |
} | |
// -- addProductCollection | |
echo PHP_EOL . PHP_EOL; | |
echo "addProductCollection" . PHP_EOL; | |
echo "--------------------" . PHP_EOL . PHP_EOL; | |
$maxEntityId = $maxSyncIds['add']; | |
if ($maxEntityId) { | |
$klevuSyncRepository->clearKlevuCollection(); | |
$batchedProductIds = []; | |
$productCollection = $magentoProductSyncRepository->getProductIdsCollection($store); | |
$childProductCollection = $magentoProductSyncRepository->getChildProductIdsCollection($store); | |
$lastProductEntityId = 0; | |
$lastChildEntityId = 0; | |
$i = 0; | |
while ($lastProductEntityId < $maxEntityId || $lastChildEntityId < $maxEntityId) { | |
echo "Iteration: " . $i . PHP_EOL; | |
echo "- Max Entity Id : " . $maxEntityId . PHP_EOL; | |
echo "- Last Product Entity Id : " . $lastProductEntityId . PHP_EOL; | |
echo "- Last Child Entity Id : " . $lastChildEntityId . PHP_EOL; | |
$productIds = ($lastProductEntityId < $maxEntityId) ? | |
$magentoProductSyncRepository->getBatchDataForCollection($productCollection, $store, [], $lastProductEntityId) : | |
[]; | |
echo "- Product Ids (" . count($productIds) . "): " . implode(',', $productIds) . PHP_EOL; | |
$childProductIds = ($lastChildEntityId < $maxEntityId) ? | |
$magentoProductSyncRepository->getBatchDataForCollection($childProductCollection, $store, [], $lastChildEntityId) : | |
[]; | |
echo "- Child Product Ids (" . count($childProductIds) . "): " . implode(',', $childProductIds) . PHP_EOL; | |
if ((!$productIds && !$childProductIds) || ++$i >= \Klevu\Search\Model\Product\MagentoProductActions::MAX_ITERATIONS) { | |
echo PHP_EOL; | |
echo "* Exiting loop" . PHP_EOL; | |
break; | |
} | |
$lastProductEntityId = $productIds ? (int)max($productIds) : $maxEntityId + 1; | |
$lastChildEntityId = $childProductIds ? (int)max($childProductIds) : $maxEntityId + 1; | |
$magentoProductIdsToFilter = array_merge($productIds, $childProductIds); | |
echo "- Magento Product Ids To Filter (" . count($magentoProductIdsToFilter) . "): " . implode(',', $magentoProductIdsToFilter) . PHP_EOL; | |
$magentoProductIds = array_merge( | |
formatMagentoProductIds($productIds, false, $magentoProductSyncRepository), | |
formatMagentoProductIds($childProductIds, true, $magentoProductSyncRepository) | |
); | |
echo "- Magento Product Ids (" . count($magentoProductIds) . "): " . json_encode($magentoProductIds) . PHP_EOL; | |
$klevuProductIds = $klevuSyncRepository->getProductIds($store, $magentoProductIdsToFilter); | |
echo "- Klevu Product Ids (" . count($klevuProductIds) . "): " . json_encode($klevuProductIds) . PHP_EOL; | |
array_walk($klevuProductIds, function (&$v) { | |
unset($v['row_id']); | |
}); | |
$productIdsDiff = diffMultiDimensionalArrays($magentoProductIds, $klevuProductIds); | |
echo "- Product Ids Diff (" . count($productIdsDiff) . "): " . json_encode($productIdsDiff) . PHP_EOL; | |
$formattedProductIdsToAdd = formatProductIdsToAdd($productIdsDiff, $store); | |
echo "- Formatted Product Ids to Add (" . count($formattedProductIdsToAdd) . "): " . json_encode($formattedProductIdsToAdd) . PHP_EOL; | |
echo PHP_EOL . "-----" . PHP_EOL; | |
} | |
} else { | |
echo "No max entity for add operation" . PHP_EOL; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment