Skip to content

Commit

Permalink
Merge pull request #51 from FlashpointBV/feature/product-website-stra…
Browse files Browse the repository at this point in the history
…tegy

Feature/product website strategy
  • Loading branch information
mrdevries authored Feb 22, 2022
2 parents 2da02be + cb5a782 commit 38152e9
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 3 deletions.
18 changes: 17 additions & 1 deletion Api/ImportConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,22 @@ class ImportConfig
const CATEGORY_STRATEGY_ADD = 'add'; // Only add and update category links
const CATEGORY_STRATEGY_SET = 'set'; // Add and update category links; and also remove existing category links not named in the import

/**
* How to deal with the imported websites?
* - add: link products to websites named in the import
* - set: like add, and delete links too
*
* Important!
* The 'set' option compares existing product-to-website links with the ones mentioned in the import.
* Existing links that are not named in the import are removed.
*
* @var string
*/
public $websiteStrategy = self::WEBSITE_STRATEGY_ADD;

const WEBSITE_STRATEGY_ADD = 'add'; // Only add and update website links
const WEBSITE_STRATEGY_SET = 'set'; // Add and update website links; and also remove existing website links not named in the import

/**
* How to handle varchar and text fields with value ""?
*
Expand Down Expand Up @@ -219,4 +235,4 @@ class ImportConfig
const M2EPRO_NO = "no";
const M2EPRO_YES = "yes";

}
}
7 changes: 6 additions & 1 deletion Api/ProductImportWebApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class ProductImportWebApi implements ProductImportWebApiInterface
const OPTION_AUTO_CREATE_CATEGORIES = 'auto-create-categories';
const OPTION_CATEGORY_URL_TYPE = "category-url-type";
const OPTION_CATEGORY_STRATEGY = "category-strategy";
const OPTION_WEBSITE_STRATEGY = "website-strategy";
const OPTION_PATH_SEPARATOR = 'path-separator';
const OPTION_IMAGE_STRATEGY = 'image';
const OPTION_IMAGE_SOURCE_DIR = 'image-source-dir';
Expand Down Expand Up @@ -100,6 +101,10 @@ protected function buildConfig(array $parameters)
$config->categoryStrategy = $parameters[self::OPTION_CATEGORY_STRATEGY];
}

if (isset($parameters[self::OPTION_WEBSITE_STRATEGY])) {
$config->websiteStrategy = $parameters[self::OPTION_WEBSITE_STRATEGY];
}

if (isset($parameters[self::OPTION_EMPTY_TEXT])) {
$config->emptyTextValueStrategy = $parameters[self::OPTION_EMPTY_TEXT];
}
Expand Down Expand Up @@ -150,4 +155,4 @@ protected function buildConfig(array $parameters)

return $config;
}
}
}
11 changes: 10 additions & 1 deletion Console/Command/ProductImportCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ProductImportCommand extends Command
const OPTION_IMAGE_CACHING = "image-caching";
const OPTION_AUTO_CREATE_CATEGORIES = 'auto-create-categories';
const OPTION_CATEGORY_STRATEGY = "category-strategy";
const OPTION_WEBSITE_STRATEGY = "website-strategy";
const OPTION_PATH_SEPARATOR = 'path-separator';
const OPTION_CATEGORY_URL_TYPE = 'category-url-type';
const OPTION_IMAGE_STRATEGY = "image";
Expand Down Expand Up @@ -102,6 +103,13 @@ protected function configure()
'category strategy: How to handle product-category links that are not in the import (set: delete these links)',
ImportConfig::CATEGORY_STRATEGY_ADD
),
new InputOption(
self::OPTION_WEBSITE_STRATEGY,
null,
InputOption::VALUE_OPTIONAL,
'website strategy: How to handle product-website links that are not in the import (set: delete these links)',
ImportConfig::WEBSITE_STRATEGY_ADD
),
new InputOption(
self::OPTION_EMPTY_TEXT,
null,
Expand Down Expand Up @@ -216,6 +224,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$config->categoryNamePathSeparator = $input->getOption(self::OPTION_PATH_SEPARATOR);
$config->categoryUrlType = $input->getOption(self::OPTION_CATEGORY_URL_TYPE);
$config->categoryStrategy = $input->getOption(self::OPTION_CATEGORY_STRATEGY);
$config->websiteStrategy = $input->getOption(self::OPTION_WEBSITE_STRATEGY);
$config->productTypeChange = $input->getOption(self::OPTION_PRODUCT_TYPE_CHANGE);
$config->imageStrategy = $input->getOption(self::OPTION_IMAGE_STRATEGY);
$config->existingImageStrategy = $input->getOption(self::OPTION_IMAGE_CACHING);
Expand Down Expand Up @@ -273,4 +282,4 @@ protected function guessImageSourceDir(string $fileName, string $imageSourceDirO

return $dirName;
}
}
}
3 changes: 3 additions & 0 deletions Model/Resource/ProductStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,9 @@ protected function saveProducts(array $validProducts, ImportConfig $config)
$this->productEntityStorage->removeOldCategoryIds($validProducts);
}
$this->productEntityStorage->insertCategoryIds($validProducts);
if ($config->websiteStrategy === ImportConfig::WEBSITE_STRATEGY_SET) {
$this->productEntityStorage->removeOldWebsiteIds($validProducts);
}
$this->productEntityStorage->insertWebsiteIds($validProducts);
$this->stockItemStorage->storeStockItems($validProducts);
$this->linkedProductStorage->updateLinkedProducts($validProducts);
Expand Down
49 changes: 49 additions & 0 deletions Model/Resource/Storage/ProductEntityStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,55 @@ public function removeOldCategoryIds(array $products)
}
}

/**
* @param Product[] $products
*/
public function removeOldWebsiteIds(array $products)
{
if (empty($products)) { return; }

$productIds = array_column($products, 'id');

// load existing links
$rows = $this->db->fetchAllAssoc("
SELECT `website_id`, `product_id`
FROM `" . $this->metaData->productWebsiteTable . "`
WHERE `product_id` IN (" . implode(',', $productIds) . ")
");

// collect existing links
$toBeRemoved = [];
foreach ($rows as $row) {
$toBeRemoved[$row['product_id']][$row['website_id']] = true;
}

// remove links from this set that are present in the import
foreach ($products as $product) {
$websiteIds = $product->getWebsiteIds();
if ($websiteIds === null) {
// websites are not used in the import; skip
unset($toBeRemoved[$product->id]);
} else {
foreach ($websiteIds as $websiteId) {
unset($toBeRemoved[$product->id][$websiteId]);
}
}
}

// delete links one by one (there won't be many)
foreach ($toBeRemoved as $productId => $websiteIds) {
foreach ($websiteIds as $websiteId => $true) {
$this->db->execute("
DELETE FROM `" . $this->metaData->productWebsiteTable . "`
WHERE `product_id` = ? AND `website_id` = ?
", [
$productId,
$websiteId
]);
}
}
}

/**
* @param Product[] $products
*/
Expand Down

0 comments on commit 38152e9

Please sign in to comment.