How can I load quote in magento 2 by quote id ?
3 Answers
you can inject in your class an instance of \Magento\Quote\Model\QuoteFactory
.
protected $quoteFactory;
public function __construct(
...
\Magento\Quote\Model\QuoteFactory $quoteFactory,
....
) {
....
$this->quoteFactory = $quoteFactory;
....
}
Then you can use:
$quote = $this->quoteFactory->create()->load($quoteId);
This should work for now,
but soon, the load
method is going to go away and you need to use a service contract.
So you can use \Magento\Quote\Api\CartRepositoryInterface
.
Same as above, inject an instance of this class in your class:
protected $quoteRepository;
public function __construct(
...
\Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
....
) {
....
$this->quoteRepository = $quoteRepository;
....
}
and use this:
$this->quoteRepository->get($quoteId);
If you want to see how the code looks like, the implementation for \Magento\Quote\Api\CartRepositoryInterface
is \Magento\Quote\Model\QuoteRepository
-
-
-
-
@Black. The second approach is still valid. The one with
CartRepositoryInterface
– Marius ♦Nov 10, 2020 at 9:35
First you need to inject a \Magento\Quote\Model\QuoteFactory
in your class constructor:
protected $_quoteFactory;
public function __construct(
...
\Magento\Quote\Model\QuoteFactory $quoteFactory
) {
$this->_quoteFactory = $quoteFactory;
parent::__construct(...);
}
Then in your class you can do:
$this->_quoteFactory->create()->loadByIdWithoutStore($quoteId);
On a side note you can also use the following methods to load a quote:
loadActive($quoteId)
where it loads corresponding active quote (whereis_active
= 1)loadByCustomerId($customerId)
where it load the active quote corresponding to the customer id.
NB: you can also use the object manager directly to do it but it is not recommended:
$this->_objectManager->create('Magento\Quote\Model\Quote')->loadByIdWithoutStore($quoteId);
-
1
\Magento\Quote\Model\Quote
is a non-injectable class. I mean you can inject it, but it's not the best idea to do so. If you inject this class in 2 other classes you will get it as a singleton in the DI container and if you callload
once in one of the classes, you will have it "loaded" in your other class also. Most probably you don't want that. Use factories instead.– Marius ♦May 12, 2016 at 14:18 -
@Marius here's what happens when you're working on M1 and M2 projects at the same time. You tend to mix up everything. Thanks for the enlight and +1 for your solution, definitely the right way to go with service contracts May 12, 2016 at 14:22
-
Instead of
$this->_objectManager->get('Magento\Quote\Model\QuoteFactory')->create()->loadByIdWithoutStore($quoteId);
you can use$this->_objectManager->create('Magento\Quote\Model\Quote')->loadByIdWithoutStore($quoteId);
For the same reason stated above. callingget
on the OM will result in a singleton.– Marius ♦May 12, 2016 at 14:23 -
1@Marius I find that
get
vscreate
is more obvious than the use of singletons of M1 but I still tend to misuse them May 12, 2016 at 14:25 -
I recommend the following method
use Psr\Log\LoggerInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Quote\Api\Data\CartInterface;
class MyClass
{
/**
* @var CartRepositoryInterface
*/
public $quoteRepository;
/**
* @var LoggerInterface
*/
public $logger;
public function __construct(
CartRepositoryInterface $quoteRepository,
LoggerInterface $logger
) {
$this->quoteRepository = $quoteRepository;
$this->logger = $logger;
}
/**
* Get Quote By Id
* @param int $quoteId
* @return CartInterface|null
*/
public function getQuoteById(int $quoteId): ?CartInterface
{
$quote = null;
try {
$quote = $this->quoteRepository->get($quoteId);
} catch (NoSuchEntityException $e) {
$this->logger->error(
'Quote does not exist'.,
[$e->getMessage()]
);
}
return $quote;
}
}