Skip to content

Use of CartItemFactory class is not following OOP #40129

@adarshkhatri

Description

@adarshkhatri

Summary

I'm trying to pass additional data into the cart mutation, but currently, CartItemFactory is instantiated directly using new CartItemFactory(). This approach prevents me from extending or customising its behaviour via subclassing or plugins.

Would it be possible to refactor this so that CartItemFactory is created via a constructor or factory method? That way, we could inject dependencies or override behaviour more flexibly.

        foreach ($cartItemsData as $cartItemData) {
            $cartItems[] = (new CartItemFactory())->create($cartItemData);
        }

https://github.com/magento/magento2/blob/10fdaddfd21f922d0c1b4f9f889dba8cfd4be8d6/app/code/Magento/QuoteGraphQl/Model/AddProductsToCart.php#L56C33-L56

Examples

<?php
/**
 * Copyright 2024 Adobe
 * All Rights Reserved.
 */
declare(strict_types=1);

namespace Magento\QuoteGraphQl\Model;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Quote\Api\ErrorInterface;
use Magento\Quote\Model\Cart\Data\AddProductsToCartOutput;
use Magento\Quote\Model\Cart\Data\CartItemFactory;
use Magento\GraphQl\Model\Query\ContextInterface;
use Magento\Quote\Model\Cart\AddProductsToCart as AddProductsToCartService;
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;
use Magento\QuoteGraphQl\Model\CartItem\PrecursorInterface;

class AddProductsToCart
{
    /**
     * @param GetCartForUser $getCartForUser
     * @param AddProductsToCartService $addProductsToCartService
     * @param ScopeConfigInterface $scopeConfig
     * @param PrecursorInterface $cartItemPrecursor
     * @param CartItemFactory $cartItemFactory
     */
    public function __construct(
        private readonly GetCartForUser $getCartForUser,
        private readonly AddProductsToCartService $addProductsToCartService,
        private readonly ScopeConfigInterface $scopeConfig,
        private readonly PrecursorInterface $cartItemPrecursor,
        private readonly CartItemFactory $cartItemFactory
    ) {
    }

    /**
     * Add products in cart
     *
     * @param ContextInterface $context
     * @param array|null $args
     * @return array
     * @throws GraphQlInputException
     */
    public function execute($context, ?array $args): array
    {
        $maskedCartId = $args['cartId'];
        $cartItemsData = $args['cartItems'];
        $storeId = (int)$context->getExtensionAttributes()->getStore()->getId();

        // Shopping Cart validation
        $this->getCartForUser->execute($maskedCartId, $context->getUserId(), $storeId);
        $cartItemsData = $this->cartItemPrecursor->process($cartItemsData, $context);
        $cartItems = [];
        foreach ($cartItemsData as $cartItemData) {
            $cartItems[] = $this->cartItemFactory->create($cartItemData);
        }

        /** @var AddProductsToCartOutput $addProductsToCartOutput */
        $addProductsToCartOutput = $this->addProductsToCartService->execute($maskedCartId, $cartItems);

        return [
            'cart' => [
                'model' => $addProductsToCartOutput->getCart(),
            ],
            'user_errors' => array_map(
                function (ErrorInterface $error) {
                    return [
                        'code' => $error->getCode(),
                        'message' => $error->getMessage(),
                        'path' => [$error->getCartItemPosition()],
                        'quantity' => $this->isStockItemMessageEnabled() ? $error->getQuantity() : null
                    ];
                },
                array_merge($addProductsToCartOutput->getErrors(), $this->cartItemPrecursor->getErrors())
            )
        ];
    }

    /**
     * Check inventory option available message
     *
     * @return bool
     */
    private function isStockItemMessageEnabled(): bool
    {
        return (int) $this->scopeConfig->getValue('cataloginventory/options/not_available_message') === 1;
    }
}

Additional Details

Please note the same thing is in here too:

https://github.com/magento/magento2/blob/1be120497a82ee21545fea629bc501ae3e26534e/app/code/Magento/WishlistGraphQl/Model/Resolver/Wishlist/AddToCart.php#L166C13-L167C72

Proposed solution

#40128

Release note

No response

Triage and priority

  • Severity: S0 - Affects critical data or functionality and leaves users without workaround.
  • Severity: S1 - Affects critical data or functionality and forces users to employ a workaround.
  • Severity: S2 - Affects non-critical data or functionality and forces users to employ a workaround.
  • Severity: S3 - Affects non-critical data or functionality and does not force users to employ a workaround.
  • Severity: S4 - Affects aesthetics, professional look and feel, “quality” or “usability”.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: CatalogComponent: QuoteGraphQlIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedPriority: P2A defect with this priority could have functionality issues which are not to expectations.Reported on 2.4.xIndicates original Magento version for the Issue report.Reproduced on 2.4.xThe issue has been reproduced on latest 2.4-develop branchTriage: Dev.ExperienceIssue related to Developer Experience and needs help with Triage to Confirm or Reject it

    Type

    No type

    Projects

    Status

    Ready for Development

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions