Câu trả lời:
Bạn nên sử dụng Magento\Catalog\Model\ProductRepository
hoặc Magento\Catalog\Model\ResourceModel\Product\Collection
theo nhu cầu của bạn. Bạn có thể sử dụng cả hai phương pháp để lấy các phiên bản sản phẩm với tất cả dữ liệu.
/**
* @param \Magento\Catalog\Model\ProductRepository $productRepository
* @param \Magento\Framework\Api\SearchCriteriaInterface $criteria
* @param \Magento\Framework\Api\Search\FilterGroup $filterGroup
* @param \Magento\Framework\Api\FilterBuilder $filterBuilder
* @param \Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus
* @param \Magento\Catalog\Model\Product\Visibility $productVisibility
*/
public function __construct(
\Magento\Catalog\Model\ProductRepository $productRepository,
\Magento\Framework\Api\SearchCriteriaInterface $criteria,
\Magento\Framework\Api\Search\FilterGroup $filterGroup,
\Magento\Framework\Api\FilterBuilder $filterBuilder,
\Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus,
\Magento\Catalog\Model\Product\Visibility $productVisibility
) {
$this->productRepository = $productRepository;
$this->searchCriteria = $criteria;
$this->filterGroup = $filterGroup;
$this->filterBuilder = $filterBuilder;
$this->productStatus = $productStatus;
$this->productVisibility = $productVisibility;
$this->getProductData();
}
/**
* @return \Magento\Cms\Model\Block|null
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
protected function getProductData()
{
$this->filterGroup->setFilters([
$this->filterBuilder
->setField('status')
->setConditionType('in')
->setValue($this->productStatus->getVisibleStatusIds())
->create(),
$this->filterBuilder
->setField('visibility')
->setConditionType('in')
->setValue($this->productVisibility->getVisibleInSiteIds())
->create(),
]);
$this->searchCriteria->setFilterGroups([$this->filterGroup]);
$products = $this->productRepository->getList($this->searchCriteria);
$productItems = $products->getItems();
return $productItems;
}
Kết quả:
/**
* @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
* @param \Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus
* @param \Magento\Catalog\Model\Product\Visibility $productVisibility
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function __construct(
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus,
\Magento\Catalog\Model\Product\Visibility $productVisibility
) {
$this->productCollectionFactory = $productCollectionFactory;
$this->productStatus = $productStatus;
$this->productVisibility = $productVisibility;
}
/**
* @return \Magento\Framework\DataObject[]
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getProducts()
{
/** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */
$collection = $this->productCollectionFactory->create();
$collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
$collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
$collection->addAttributeToFilter('status', ['in' => $this->productStatus->getVisibleStatusIds()])
->addAttributeToFilter('visibility', ['in' => $this->productVisibility->getVisibleInSiteIds()]);
return $collection->getItems();
}
Kết quả:
Câu trả lời được đánh giá cao nhất đang hoạt động nhưng tôi muốn đề cập rằng ở đây bằng cách tiêm trực tiếp vào kho lưu trữ sản phẩm sẽ gây ra sự vi phạm nguyên tắc hợp đồng dịch vụ & đó là điều Magento muốn các nhà phát triển sửa. Bạn nên tiêm \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
thay vì đó là thực hiện \Magento\Catalog\Model\ProductRepository $productRepository
. Bằng cách đó bạn sẽ có một không gian cho khả năng nâng cấp trong tương lai. Điểm mấu chốt là sử dụng hợp đồng dịch vụ càng nhiều càng tốt.