Magento 2 Object Manager – How to Create a ProductRepository

magento2object-managersave

I want to save/update the product in phtml file and I need to create productRepository using object manager.
I don't want any controller to be called. Is there any possibility to save product in phtml file without calling controller or helper class?

Best Answer

No. Noooo. Not the right approach.

You haven't given much information about exactly what problem you are trying to solve, but you should never be loading or saving any model directly in a template.

The correct process depends on the circumstances, but you should be running your product logic in a context where you can take advantage of Dependency Injection (DI)--a block, a controller, an observer, but preferably a model. In that class, you would use DI to get an instance of \Magento\Catalog\Api\ProductRepositoryInterface (ProductRepository), and then you could use that to create/load your product and then to save it.

Using ObjectManager to directly create and save a Product object, in a template, is breaking just about every rule and code standard in the book. I cannot overstate this: What you are asking to do is very bad practice. Don't do it.

  1. Don't use ObjectManager. The only place it should be used is in a Factory class.
  2. Don't use business logic in a template. Templates are for displaying content only; they should never contain any code that changes the state of the system. Some logic can be contained in a template's Block class, but that block also should not change any system state. Changes (like creating a product) belong in a Model.
  3. Use dependency injection and inject the objects you need in your class constructors. It makes it clear what your dependencies are, and allows you/others to change them as well via DI.
  4. ORM objects (anything stored/loaded in the database, like Products) are non-injectable. You need to inject its Factory (literally append Factory to the class name you're getting), and use that to create your object instance.
  5. Use the service layer. That means use DI to get interfaces corresponding to objects, not the objects themselves.

Ignoring these standards can give you code that works (like the other answer), but it's code that will probably break in future versions, it's code that won't be findable (it's not where standards say it should be), it's code that isn't maintainable (does things wrong), and you're making a mess of your site in the process.

Taken all together: Here is how to inject, create, and save a product correctly in the context of dependency injection and M2 code standards.

<?php
/**
 * MyClass Class
 */
class MyClass
{
    /**
     * @var \Magento\Catalog\Api\Data\ProductInterfaceFactory
     */
    private $productFactory;
    /**
     * @var \Magento\Catalog\Api\ProductRepositoryInterface
     */
    private $productRepository;

    /**
     * MyClass constructor
     *
     * @param \Magento\Catalog\Api\Data\ProductInterfaceFactory $productFactory
     * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
     */
    public function __construct(
        \Magento\Catalog\Api\Data\ProductInterfaceFactory $productFactory,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
    ) {
        $this->productFactory = $productFactory;
        $this->productRepository = $productRepository;
    }

    /**
     * Create my new simple product.
     *
     * @return void
     */
    public function createProduct()
    {
        $product = $this->productFactory->create();
        $product->setSku('MyNewProduct');
        // Set other product data here
        $this->productRepository->save($product);
    }
}

There are a lot of complex concepts at play here, but it's worth the time to learn and understand them and do things right. You'll be able to work with M2 much more effectively when you do.

Related Topic