Magento2 Quote – How to Load a Quote Item via Its ID

magento2quotequoteitemservice-contract

Is there a way to load a quote_item directly using current Magento coding standards?

Right now I'm loading the cart and then finding the quote item like so:

$cart_id = $this->getRequest()->getParam('cart');
$item_id = $this->getRequest()->getParam('item');
/** $this->cartItemRepo = Magento\Quote\Api\CartItemRepositoryInterface **/
$items = $this->cartItemRepo->getList($cart_id);
$quote_item = null;
foreach($items as $item){
    if ( $item->getId() && $item->getId() === $item_id ){
        $quote_item = $item;
        break;
    }
}

The above works but I want to clean it up and simplify. I would also like to load using just the $item_id, with no $cart_id.

Best Answer

Ok, here's 2 different ways to do this.

Grab it from the collection.

/** @var \Magento\Quote\Model\ResourceModel\Quote\Item\Collection $collection */
$collection = $this->collectionFactory->create();
$collection->addFieldToFilter(
    \Magento\Quote\Api\Data\CartItemInterface::KEY_ITEM_ID,
    $itemId
);

$item = $collection->getFirstItem();

The other option is a class which caches items by cartId/itemId so that if you need to continuously repeat this function you won't make any unnecessary queries to the database for items within the same cart.

class MyCustomClass
{
    /**
     * @var \Magento\Quote\Api\CartItemRepositoryInterface
     */
    private $cartItemRepository;

    /**
     * @var \Magento\Quote\Api\Data\CartItemInterface[]
     */
    private $items = [];

    /**
     * MyCustomClass constructor.
     *
     * @param \Magento\Quote\Api\CartItemRepositoryInterface $cartItemRepository
     */
    public function __construct(
        \Magento\Quote\Api\CartItemRepositoryInterface $cartItemRepository
    ) {
        $this->cartItemRepository = $cartItemRepository;
    }

    /**
     * @param $cartId
     *
     * @return \Magento\Quote\Api\Data\CartItemInterface[]
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    private function getCartItems($cartId)
    {
        if (!isset($this->items[$cartId])) {
            $this->items[$cartId] = [];

            $items = $this->cartItemRepository->getList($cartId);

            /** @var \Magento\Quote\Api\Data\CartItemInterface $item */
            foreach ($items as $item) {
                $this->items[$cartId][$item->getItemId()] = $item;
            }
        }

        return $this->items;
    }

    /**
     * @param int $cartId
     * @param int $itemId
     *
     * @return null|\Magento\Quote\Api\Data\CartItemInterface
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getItemByCartId($cartId, $itemId)
    {
        $items = $this->getCartItems($cartId);

        return isset($items[$cartId][$itemId]) ? $items[$cartId][$itemId] : null;
    }
}