4

I have created simple product using following code.almost its working fine, but I'm not able assign product to websites.

Actually I have created two websites. I want to assign product to particular website or both websites. here

$this->product->setWebsiteIds(1); $this->product->setWebsiteIds(array(1));

both lines not working.

In Magento\Catalog\Api\ProductRepositoryInterface there is no information websites (I mean there is no constants,setters,getters).

Anyone have idea?

namespace Kensium\Commands\Console;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command;
use Magento\Framework\App\State;
use Magento\Framework\App\ObjectManager\ConfigLoader;
/**
 * Command creates simple product by given data 
 */
class CreateSimpleProduct extends Command
{
 protected $_productRepository;
 protected $product;
 protected $registry;
 protected $state;
 protected $configLoader;
 protected $objectManager;
 const SIMPLE_PRODUCT_INFO = "simpleproductinfo";
 public function __construct(
 \Magento\Catalog\Api\ProductRepositoryInterface $_productRepository,
 \Magento\Catalog\Api\Data\ProductInterface $product,
 \Magento\Framework\Registry $registry, 
 State $state,
 ConfigLoader $loader,
 \Magento\Framework\ObjectManagerInterface $objectManager
 )
 {
 $this->_productRepository =$_productRepository;
 $this->product=$product;
 $this->registry = $registry; 
 $this->state = $state;
 $this->configLoader = $loader;
 $this->objectManager = $objectManager; 
 parent::__construct();
 }
 /**
 * {@inheritdoc}
 */
 protected function configure()
 {
 $this->setName('kensium:create_product')
 ->setDescription('creates simple product')->setDefinition([
 new InputArgument(self::SIMPLE_PRODUCT_INFO, InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Simple Product Info')
 ]);
 parent::configure();
 }
 /**
 * {@inheritdoc}
 */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
 if (!$input->getArgument(self::SIMPLE_PRODUCT_INFO))
 {
 throw new \InvalidArgumentException('Missing Argument ' . self::SIMPLE_PRODUCT_INFO);
 }
 $this->registry->register('isSecureArea', true);
 $this->state->setAreaCode('adminhtml');
 $this->objectManager->configure($this->configLoader->load('adminhtml'));
 $simples=$input->getArgument(self::SIMPLE_PRODUCT_INFO);
 foreach($simples as $simple)
 {
 $arr=explode(":",$simple);
 $data['name']=$arr[0];
 $data['sku']=$arr[1];
 $data['price']=$arr[2];
 $this->product->setName($data['name']);
 $this->product->setSku($data['sku']); 
 $this->product->setPrice($data['price']);
 $this->product->setTypeId("simple");
 $this->product->setAttributeSetId(4);
 $this->product->setWebsiteIds(1); // $this->product->setWebsiteIds(array(1)); 
 $this->_productRepository->save($this->product); 
 $output->writeln('<info>created simple product</info>');
 }
 }
}
MGento
1,51910 silver badges22 bronze badges
asked May 8, 2015 at 7:58
3
  • 1
    it should work with setWebsiteIds(array(1)). I have no idea why it doesn't work for you but you can try with $this->product->save() instead of $this->_productRepository->save($this->product). Commented May 8, 2015 at 8:13
  • working fine with $this->product->save() & setWebsiteIds(array(1)) Commented May 8, 2015 at 9:02
  • but no idea when to use productRepository.any way thanks Marius. Commented May 8, 2015 at 9:03

3 Answers 3

1

Based on the comments...

it should work with setWebsiteIds(array(1)). I have no idea why it doesn't work for you but you can try with $this->product->save() instead of $this->_productRepository->save($this->product)

answered May 8, 2015 at 9:13
3
  • It's work currently. But in future this code will be broken, because the product interface do not have setWebsiteIds method Commented Dec 14, 2015 at 7:57
  • @KAndy. It worked when I answered this question. Sometimes I cannot predict the future. This is one of the cases. Commented Dec 14, 2015 at 8:01
  • Using $this->product->save over the repository means that you cannot assign a configurable product to a website programmatically. Commented Mar 2, 2016 at 19:10
1

I encountered the same issue and found that adding the website after the product has been saved to be the solution.

I used instances of the Magento\Catalog\Api\Data\ProductWebsiteLinkInterface and Magento\Catalog\Api\ProductWebsiteLinkRepositoryInterface repository with code similar to the below:

...
$mageProduct = $this->productRepository->save($mageProduct, true);
// Instance of ProductWebsiteLinkInterface
$siteLink = $this->productWebsiteLink;
$siteLink->setSku($mageProduct->getSku());
$siteLink->setWebsiteId(1);
// Instance of ProductWebsiteLinkRepositoryInterface
$websiteLinkRepo = $this->productWebsiteLinkRepository;
$websiteLinkRepo->save($siteLink);
answered Mar 2, 2016 at 19:35
0

I experienced some confusing application behavior when trying to add simple and configurable products to specific websites/stores in Magento 2.2.

My preferred solution:

/**
 * This version sets one of the stores the product is assigned to 
 * as the "current store"
 * and assigns the product to other websites via setWebsiteIds[...].
 * Disadvantage: There is no store with all products inside.
 * The product is assigned to websites 2, 4 and 5 in this example: 
 */
$websiteIds = [2, 4, 5]; // this is obviously dynamically set by an external system
$this->storeManager->setCurrentStoreId($websiteIds[0]);
$newProduct = $this->productInterfaceFactory->create();
$newProduct->setWebsiteIds($websiteIds);
// ... add other attributes
$savedProduct = $this->productRepository->save($newProduct);

If changing default stores is not preferred, then it is also a possibility to use a hidden admin store:

/**
 * This version sets a hidden admin store as the "current store"
 * and assigns the product to other websites via setWebsiteIds[...].
 * Disadvantage: Every product is assigned to the hidden admin store.
 * Advantage: Every product can be asssigned to and unassigned from
 * any (other) store programmatically.
 * The product is assigned to websites 2, 4 and 5 in this example: 
 */
$this->storeManager->setCurrentStoreId(5);
$newProduct = $this->productInterfaceFactory->create();
$newProduct->setWebsiteIds([2,4]);
// ... add other attributes
$savedProduct = $this->productRepository->save($newProduct);

If a product is always needed in all stores, this solution might be fine:

/**
 * If the current store is set to 0, each product is assigned to every
 * website. I would not know how to unassign a specific store: Stores 
 * can NOT be unassigned via $newProduct->setWebsiteIds([]);.
 */
$this->storeManager->setCurrentStoreId(0);
$newProduct = $this->productInterfaceFactory->create();
$newProduct->setStoreId(1); // This does not seem to have any impact.
$newProduct->setWebsiteIds([2]); // This does not seem to have any impact.
// ... add other attributes
$savedProduct = $this->productRepository->save($newProduct);

Not setting the current store seems to result in a slightly random scenario:

/**
 * Here, the current store of the store manager is not set.
 * This version does work, but in addition to store id 2, each product
 * has a second store assigned in my case. 
 * That second store seems to be quite random.
 */
$newProduct = $this->productInterfaceFactory->create();
$newProduct->setWebsiteIds([2]);
// ... add other attributes
$savedProduct = $this->productRepository->save($newProduct);

As a result, I keep these findings:

  • It seems to be necessary to set the current store via the store manager before creating the product. Not setting it makes the results a bit random.
  • Setting the current store to 0 assigns every product to all stores, but makes it hard to unassign them.
  • If a product is created with the current store set, it can be assigned to a choice of websites.
  • It seems to be not necessary to save the product twice; the websites can be chosen during the initial product creation.

I think, my research session was a bit funny; other people might know how to find that kind of information easier by looking through documentation or investigating code - but I did both, and even asked my colleagues, and nobody seemed to know. Hope, it helps anyone.

answered May 29, 2018 at 4:23

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.