Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Товары, категории, покупатели и заказы

Товары, категории, покупатели и заказы хранятся в десятках связанных таблиц ядра. Читать их запросами SQL не нужно: у каждого вида данных есть репозиторий — интерфейс с теми же методами get, getList и save, что и у репозитория отзывов. Эти интерфейсы не меняются при обновлении Magento.

Репозитории ядра

ДанныеИнтерфейс
ТоварыMagento\Catalog\Api\ProductRepositoryInterface
КатегорииMagento\Catalog\Api\CategoryRepositoryInterface
ПокупателиMagento\Customer\Api\CustomerRepositoryInterface
ЗаказыMagento\Sales\Api\OrderRepositoryInterface

Репозиторий просят в конструкторе своего класса. Модули, чьи интерфейсы вы используете, перечисляют в разделе sequence файла module.xml.

Товар по артикулу

Создайте в модуле класс, который будет собирать сведения о магазине:

// app/code/Acme/Hello/Model/ShopInfo.php
namespace Acme\Hello\Model;
 
use Magento\Catalog\Api\ProductRepositoryInterface;
 
class ShopInfo
{
    public function __construct(private ProductRepositoryInterface $productRepository) {}
 
    public function productName(string $sku): string
    {
        $product = $this->productRepository->get($sku);
 
        return (string) $product->getName();
    }
}

Метод get() ищет товар по артикулу (SKU), а getById() — по номеру. Если товара нет, оба бросают исключение NoSuchEntityException.

Использование

Вызовем класс из действия Status прошлых уроков:

// app/code/Acme/Hello/Controller/Index/Status.php
public function execute(): ResultInterface
{
    return $this->resultFactory->create(ResultFactory::TYPE_JSON)
        ->setData(['name' => $this->shopInfo->productName('24-MB01')]);
}

Добавьте ShopInfo в конструктор действия, очистите папку generated и откройте /hello/index/status. Если установлены демонстрационные данные, ответ будет {"name":"Joust Duffle Bag"}.

Список товаров

Условия поиска собирает SearchCriteriaBuilder — так же, как для отзывов:

// app/code/Acme/Hello/Model/ShopInfo.php
public function cheapProducts(): array
{
    $criteria = $this->criteriaBuilder
        ->addFilter('price', 50, 'lt')
        ->setPageSize(10)
        ->create();
 
    return $this->productRepository->getList($criteria)->getItems();
}

Метод возвращает до десяти товаров дешевле 50. У каждого доступны getSku(), getName(), getPrice(). Объект Magento\Framework\Api\SearchCriteriaBuilder добавляют в конструктор.

Изменение товара

// app/code/Acme/Hello/Model/ShopInfo.php
public function setPrice(string $sku, float $price): void
{
    $product = $this->productRepository->get($sku);
    $product->setPrice($price);
 
    $this->productRepository->save($product);
}

Товар сохраняется со всеми проверками ядра, а индексы и кеш обновляются сами.

Категория, покупатель, заказ

// app/code/Acme/Hello/Model/ShopInfo.php
public function summary(int $categoryId, string $email, int $orderId): array
{
    $category = $this->categoryRepository->get($categoryId);
    $customer = $this->customerRepository->get($email);
    $order = $this->orderRepository->get($orderId);
 
    return [
        'category' => $category->getName(),
        'customer' => $customer->getFirstname() . ' ' . $customer->getLastname(),
        'order' => $order->getIncrementId(),
        'total' => $order->getGrandTotal(),
    ];
}

Категорию и заказ находят по номеру, покупателя — по адресу почты или через getById(). Метод getIncrementId() возвращает номер заказа, который видит покупатель, а getGrandTotal() — итоговую сумму.

Заказы покупателя

// app/code/Acme/Hello/Model/ShopInfo.php
public function ordersOf(string $email): array
{
    $criteria = $this->criteriaBuilder
        ->addFilter('customer_email', $email)
        ->create();
 
    return $this->orderRepository->getList($criteria)->getItems();
}

Метод возвращает все заказы с указанным адресом почты.

Частая ошибка

Репозиторий вызывают в цикле: для ста отзывов сто раз выполняют $this->productRepository->getById(). Каждый вызов загружает товар целиком со всеми атрибутами, и страница открывается несколько секунд. Соберите номера и получите товары одним вызовом getList() с условием in по полю entity_id.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.