Finally, I took the time to write a command-line to implement this needs.
running php bin/magento mbs:websites:update '1,2,3,4,5' '1,2'
will update the product whose id are 1, 2 , 3, 4 and 5 to be assigned to the website ids 1 and 2 only regardless of their previous context.
Of course, this is subject to each ids do exist and it did work with this in mind for me.
<?php
namespace Mbs\ProductWebsiteUpdate\Command;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpdateWebsites extends Command
{
/**
* @var \Magento\Catalog\Model\Product\Action
*/
private $action;
/**
* @var CollectionFactory
*/
private $collectionFactory;
public function __construct(
\Magento\Catalog\Model\Product\Action $action,
CollectionFactory $collectionFactory,
string $name = null
) {
parent::__construct($name);
$this->action = $action;
$this->collectionFactory = $collectionFactory;
}
protected function configure()
{
$this->setName('mbs:websites:update');
$this->setDescription('Update a product websites');
$this->addArgument('product_ids', InputArgument::REQUIRED);
$this->addArgument('website_ids', InputArgument::REQUIRED);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$collection = $this->collectionFactory->create();
$collection->addIdFilter($this->getProductIds($input));
foreach ($collection as $product) {
$this->action->updateWebsites(
[$product->getId()],
$product->getWebsiteIds(),
'remove'
);
$this->action->updateWebsites(
[$product->getId()],
$this->getWebsiteIds($input),
'add'
);
}
$output->writeln('done');
}
private function getProductIds(InputInterface $input)
{
if (strpos($input->getArgument('product_ids'), ',')!==false) {
return explode(',', $input->getArgument('product_ids'));
}
return [$input->getArgument('product_ids')];
}
private function getWebsiteIds(InputInterface $input)
{
if (strpos($input->getArgument('website_ids'), ',')!==false) {
return explode(',', $input->getArgument('website_ids'));
}
return [$input->getArgument('website_ids')];
}