Skip to content

Instantly share code, notes, and snippets.

@klevu
Last active June 10, 2022 10:56
Show Gist options
  • Save klevu/e8fb14a2efa90dbc5288af5a20df4f50 to your computer and use it in GitHub Desktop.
Save klevu/e8fb14a2efa90dbc5288af5a20df4f50 to your computer and use it in GitHub Desktop.
bin/klevu-sync-debug
#!/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