Получение простых продуктов из настраиваемых

11

Я пытаюсь следующий код, чтобы получить идентификаторы всех простых продуктов, которые являются потомками $collection, которые я знаю, как набор настраиваемых продуктов.

foreach($collection as $_product) {
    $_children = $_product->getTypeInstance()->getUsedProductIds($_product);
    print_r($_children);
}

Однако все массивы, которые я получаю, пусты. Я делаю что-то неправильно?

b_pcakes
источник
В вашей коллекции что-то есть?
Aedonis
Да, несколько продуктов
b_pcakes
1
Попробуйте использовать это, $_children = $_product->getTypeInstance()->getUsedProducts($_product);если вы что-то получаете.
Эдонис
На самом деле я уже пробовал это, а такжеgetUsedProductCollection
b_pcakes

Ответы:

23

Вы можете распечатать идентификаторы своих дочерних продуктов (из настраиваемых продуктов), внеся небольшое изменение в свой код следующим образом

foreach($collection as $_product) {
        $logger->info("Here are Parent Product Name".$_product->getName());
        $_children = $_product->getTypeInstance()->getUsedProducts($_product);
        foreach ($_children as $child){
            $logger->info("Here are your child Product Ids ".$child->getID());
        }
    }

После этого посмотрите на ваши файлы журналов, и вы получите IDS вашего ребенка.


источник
Для Magento 2.2.6 din не работал, вместо этого использовался: $ product-> getTypeId ()
Alejandro Torres
17

Ответы на этот вопрос неверны. Хотя их реализации могут работать, это неправильный способ справиться с этим. Правильный способ сделать это - использовать сервисные контракты Magentos и модели данных.

В этом случае Magento\ConfigurableProduct\Api\LinkManagementInterfaceвам нужен сервисный договор.

Небольшой пример кода, который я использую в консольной команде:

<?php

namespace Vendor\Module\Console;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\ConfigurableProduct\Api\LinkManagementInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\App\State;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Class UpdateChildProducts
 * @package Vendor\Module\Console
 */
class UpdateChildProducts extends Command
{
    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;

    /**
     * @var SearchCriteriaBuilder
     */
    protected $searchCriteriaBuilder;

    /**
     * @var LinkManagementInterface
     */
    protected $linkManagement;

    /**
     * @var State
     */
    protected $state;

    /**
     * UpdateChildProducts constructor.
     * @param State $state
     * @param LinkManagementInterface $linkManagement
     * @param ProductRepositoryInterface $productRepository
     * @param SearchCriteriaBuilder $searchCriteriaBuilder
     * @param string $name
     */
    public function __construct(
        State $state,
        LinkManagementInterface $linkManagement,
        ProductRepositoryInterface $productRepository,
        SearchCriteriaBuilder $searchCriteriaBuilder,
        $name = 'update_child_products'
    ) {
        $this->state = $state;
        $this->linkManagement = $linkManagement;
        $this->productRepository = $productRepository;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
        parent::__construct($name);
    }

    /**
     * Configure this command
     */
    protected function configure()
    {
        $this->setName('example:update_child_products');
        $this->setDescription('Iterate over all configurable products and show their children count.');
    }

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        // Set area code
        try {
            $this->state->setAreaCode('adminhtml');
        } catch (\Exception $e) {
            // Fail silently ...
        }

        $searchCriteria = $this->searchCriteriaBuilder
            ->addFilter('type_id', 'configurable')
            ->create();

        $configurableProducts = $this->productRepository->getList($searchCriteria);
        $output->writeln(sprintf('Found %d configurable products ...', $configurableProducts->getTotalCount()));

        foreach ($configurableProducts->getItems() as $configurableProduct) {
            $childProducts = $this->linkManagement->getChildren($configurableProduct->getSku());
            $output->writeln(
                sprintf('Found %d children for %s', count($childProducts), $configurableProduct->getSku())
            );
        }
    }
}

Magento 2 не очень соответствует его собственному коду, так как большая часть кода перенесена из Magento 1. Именно поэтому вы все еще видите остатки моделей, основанных на наследовании, и их методов (например getTypeInstance()). Если вы хотите создать код Magento 2, ориентированный на будущее, максимально используйте контракты на обслуживание и модели данных.

Гиль Беркерс
источник
это кажется ужасно медленным, если только я не делаю что-то не так ...
igrossiter
Необходимо исследовать, но linkManagement, кажется, не загружает все дочерние поля, такие как «special_price», так что это лучше для архитектуры, но в некоторых случаях кажется не очень полезным. $ _product-> getTypeInstance () -> getUsedProducts ($ _ продукта); работает правильно
Джузеппе Морелли
2

Вы можете просто вызвать метод ниже,

     foreach($collection as $_product) {
            $_configChild = $_product->getTypeInstance()->getUsedProductIds($_product);
            $getChildId = array();
            foreach ($_configChild as $child){
                $getChildId[] = $child;
            }
            echo "<pre>";print_r($getChildId);
        }

Выше $getChildIdотображаются все простые идентификатор продукта.

Ракеш Джесадия
источник
1

Другой способ добиться этого - использовать метод getChildrenIds.

$ children = $ cProductTypeInstance-> getChildrenIds ($ this-> currentProductObj-> getId ());

    // Get all the existing child and add it to associate Id too
    $existingChildrenIds = array();
    foreach ($children as $childIds) {
        foreach ($childIds as $child){
            $existingChildrenIds[] = $child;
        }
    }
Татенда Чума
источник
0

Чтобы получить реальные дочерние объекты продукта (а не только строки их идентификаторов), используйте это:

$childProducts = $product->getTypeInstance()->getUsedProducts($product);

Чтобы получить их идентификаторы или другие свойства, используйте приведенное выше с циклом:

foreach ($childProducts as $childProduct) {
    echo $childProduct->getId();
}
WackGet
источник