Поставщик данных пользовательского интерфейса Magento 2 не загружает данные

#magento2

#magento2

Вопрос:

Во-первых, я не хардкорный программист в Magento 2, поэтому, скорее всего, я что-то упускаю. Я искал в Интернете, но, похоже, я не могу найти решение. Надеюсь, кто-нибудь сможет мне здесь помочь.

Ситуация: я создал пользовательский модуль, и у меня есть пользовательский контроллер, который должен извлекать данные из пользовательской таблицы. Для этого я создал пользовательский поставщик данных пользовательского интерфейса, который должен извлекать данные. Когда я обращаюсь к контроллеру, параметры в URL-адресе предоставляют внутренний идентификатор. Когда я восстанавливаю этот идентификатор и создаю простой поиск, я не получаю никаких значений в своей таблице. В этом случае идентификатор равен 59. Когда я жестко кодирую идентификатор в поиске, я получаю результаты в своей таблице.

Я тестировал с некоторыми отладочными выводами print_r запроса и извлеченных элементов, и в обоих случаях данные присутствуют перед возвратом данных в функции getData(). Итак, на данный момент я действительно не понимаю, почему это работает, когда я жестко кодирую значение 59, но это не так, когда я восстанавливаю его с помощью getParam.

Я ожидаю, что, возможно, каким-то образом я неправильно использую коллекцию. Если я добавлю тот же фильтр в parent:: тогда я получаю сообщение об ошибке, и кажется, что он использует коллекцию продуктов Magento. Раздел, в котором это происходит неправильно,:

     $items = $this->purchaseOrderItemCollection
        ->addFieldToFilter('purchase_order_id', array('eq' => $id))
        //->addFieldToFilter('purchase_order_id', array('eq' => 59))
        ->getData()
    ;
  

Если я прокомментирую addFieldToFilter с помощью идентификатора $ id и раскомментирую строку с помощью жесткого кода 59, это сработает. Я также попытался здесь установить значение $id через реестр, потому что, возможно, я думал, что Magento не запоминает данные где-то еще, но это не решило проблему.

Под моим контроллером.

 <?php
namespace DssSolutionsManagementUiDataProviderPurchaseOrderItem;

use DssSolutionsManagementApiPurchaseOrderSalesOrderItemRepositoryInterface;
use DssSolutionsManagementModelPurchaseOrderSalesOrderItemDataProvider;
use DssSolutionsManagementModelResourceModelPurchaseOrderItem;
use DssSolutionsManagementModelResourceModelPurchaseOrderSalesOrderItem;
use DssSolutionsManagementModelResourceModelPurchaseOrdersLines;
use MagentoCatalogModelResourceModelProductCollectionFactory;
use MagentoFrameworkAppObjectManager;
use MagentoStoreModelStore;
use MagentoUiDataProviderModifierModifierInterface;
use MagentoUiDataProviderModifierPoolInterface;

/**
* Class ProductDataProvider
*
* @api
* @since 100.0.2
*/
class ReceiveOrderedProductDataProvider extends MagentoUiDataProviderAbstractDataProvider
{
  /**
 * Product collection
 *
 * @var DssSolutionsManagementModelResourceModelPurchaseOrderItemCollection
 */
protected $collection;

/**
 * @var MagentoUiDataProviderAddFieldToCollectionInterface[]
 */
protected $addFieldStrategies;

/**
 * @var MagentoUiDataProviderAddFilterToCollectionInterface[]
 */
protected $addFilterStrategies;

/**
 * @var PoolInterface
 */
private $modifiersPool;

/**
 * @var MagentoFrameworkAppRequestHttp
 */
protected $request;

/**
 * @var PurchaseOrderItemCollection
 */
protected $purchaseOrderItemCollection;

/**
 * @var MagentoFrameworkRegistry
 */
protected $_registry;

/**
 * @param string $name
 * @param string $primaryFieldName
 * @param string $requestFieldName
 * @param CollectionFactory $collectionFactory
 * @param MagentoUiDataProviderAddFieldToCollectionInterface[] $addFieldStrategies
 * @param MagentoUiDataProviderAddFilterToCollectionInterface[] $addFilterStrategies
 * @param array $meta
 * @param array $data
 * @param PoolInterface|null $modifiersPool
 */
public function __construct(
    $name,
    $primaryFieldName,
    $requestFieldName,
    CollectionFactory $collectionFactory,
    MagentoFrameworkAppRequestHttp $request,
    MagentoFrameworkRegistry $registry,
    DssSolutionsManagementModelResourceModelPurchaseOrderItemCollection $purchaseOrderItemCollection,
    array $addFieldStrategies = [],
    array $addFilterStrategies = [],
    array $meta = [],
    array $data = [],
    PoolInterface $modifiersPool = null
) {
    parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
    $this->request = $request;
    $this->_registry = $registry;
    $this->purchaseOrderItemCollection = $purchaseOrderItemCollection;
    $this->collection = $collectionFactory->create();
    $this->addFieldStrategies = $addFieldStrategies;
    $this->addFilterStrategies = $addFilterStrategies;
    $this->modifiersPool = $modifiersPool ?: ObjectManager::getInstance()->get(PoolInterface::class);
}

/**
 * Get data
 *
 * @return array
 */
public function getData()
{
    if (!$this->getCollection()->isLoaded()) {
        $this->getCollection()->load();
    }

    $this->_registry->register('current_purchase_order', $this->request->getParam('purchase_id', null));
    $id = $this->_registry->registry('current_purchase_order');

    $items = $this->purchaseOrderItemCollection
        ->addFieldToFilter('purchase_order_id', array('eq' => $id))
        //->addFieldToFilter('purchase_order_id', array('eq' => 59))
        ->getData()
    ;

    $collectionCounter = 1;
    foreach ($items as $k => $product){
        $items[$k]['qty_receivable'] = ($product['qty_orderred'] - $product['qty_received']);
        $collectionCounter  ;
    }

    $data = [
        'totalRecords' => $collectionCounter,
        'items' => array_values($items),
    ];

    /** @var ModifierInterface $modifier */
    foreach ($this->modifiersPool->getModifiersInstances() as $modifier) {
        $data = $modifier->modifyData($data);
    }

    return $data;
}

/**
 * Add field to select
 *
 * @param string|array $field
 * @param string|null $alias
 * @return void
 */
public function addField($field, $alias = null)
{
    if (isset($this->addFieldStrategies[$field])) {
        $this->addFieldStrategies[$field]->addField($this->getCollection(), $field, $alias);
    } else {
        parent::addField($field, $alias);
    }
}

/**
 * @inheritdoc
 */
public function addFilter(MagentoFrameworkApiFilter $filter)
{
    if (isset($this->addFilterStrategies[$filter->getField()])) {
        $this->addFilterStrategies[$filter->getField()]
            ->addFilter(
                $this->getCollection(),
                $filter->getField(),
                [$filter->getConditionType() => $filter->getValue()]
            );
    } else {
        parent::addFilter($filter);
    }
}

/**
 * @inheritdoc
 * @since 103.0.0
 */
public function getMeta()
{
    $meta = parent::getMeta();

    /** @var ModifierInterface $modifier */
    foreach ($this->modifiersPool->getModifiersInstances() as $modifier) {
        $meta = $modifier->modifyMeta($meta);
    }

    return $meta;
}
  

}

Ответ №1:

После долгих исследований я обнаружил, что пользовательский интерфейс dataProvider подвергается изменениям и что параметры URL не всегда отправляются, и это связано с тем, что сетка пользовательского интерфейса использует ajax и маршрут mui / index / render.

Поэтому, чтобы заставить это работать, источник данных должен был быть настроен так, чтобы он включал элемент, который суммирует параметры url. Это делается с помощью следующего кода в моем примере.

 <item name="filter_url_params" xsi:type="array">
    <item name="purchase_order_id" xsi:type="string">*</item>
</item>
  

Затем добавьте следующий код в dataProvider:

 /** * @return void */protected function prepareUpdateUrl()
{
    if (!isset($this->data['config']['filter_url_params'])) {
        return;
    }
    foreach ($this->data['config']['filter_url_params'] as $paramName => $paramValue) {
        if ('*' == $paramValue) {
            $paramValue = $this->request->getParam($paramName);
        }
        if ($paramValue) {
            $this->data['config']['update_url'] = sprintf(
                '%s%s/%s/',
                $this->data['config']['update_url'],
                $paramName,
                $paramValue
            );
            $this->addFilter($this->filterBuilder->setField($paramName)->setValue($paramValue)->setConditionType('eq')->create());
        }
    }
}
  

При этом фильтрация работает, и не забудьте также добавить поле в качестве поля в xml, иначе Magento не сможет фильтровать.

Для заинтересованных правильный код поставщика данных теперь:

 <?php
namespace DssSolutionsManagementUiDataProviderPurchaseOrderItem;

use MagentoUiDataProviderAbstractDataProvider;
use MagentoUiDataProviderModifierPoolInterface;
use MagentoFrameworkApiFilterBuilder;
use DssSolutionsManagementModelResourceModelPurchaseOrderItemCollection;

/**
* Class PurchaseOrderItem
* @package DssSolutionsManagementUiDataProviderPurchaseOrsderItem
*/
class ReceiveOrderedProductDataProvider extends AbstractDataProvider
{
/**
 * @var PoolInterface
 */
protected $pool;

/**
 * @var MagentoFrameworkRegistry
 */
protected $_coreRegistry;

/**
 * @var MagentoFrameworkAppRequestHttp
 */
protected $request;

/**
 * @var FilterBuilder
 */
protected $filterBuilder;

/**
 * Warehouse constructor.
 * @param string $name
 * @param string $primaryFieldName
 * @param string $requestFieldName
 * @param PoolInterface $pool
 * @param array $meta
 * @param array $data
 */
public function __construct(
    $name,
    $primaryFieldName,
    $requestFieldName,
    PoolInterface $pool,
    Collection $collection,
    MagentoFrameworkRegistry $registry,
    MagentoFrameworkAppRequestHttp $request,
    FilterBuilder $filterBuilder,
    array $meta = [],
    array $data = []

) {
    parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
    $this->pool = $pool;
    $this->collection = $collection;
    $this->_coreRegistry = $registry;
    $this->request = $request;
    $this->filterBuilder = $filterBuilder;
    $this->prepareUpdateUrl();
}

/**
 * {@inheritdoc}
 */
public function getData()
{

    $this->collection->addFieldToSelect('purchase_order_item_id');
    $this->collection->addFieldToSelect('purchase_order_id');
    $this->collection->addFieldToSelect('product_sku');
    $this->collection->addFieldToSelect('qty_orderred');
    $this->collection->addFieldToSelect('qty_received');
    $this->collection->addFieldToSelect('qty_returned');

    $items = $this->collection->getData();
    foreach ($items as $k => $product){
        $items[$k]['qty_receivable'] = ($product['qty_orderred'] - $product['qty_received']);
    }

    $data = [
        'totalRecords' => $this->collection->count(),
        'items' => array_values($items),
    ];

    return $data;
}

/** * @return void */protected function prepareUpdateUrl()
{
    if (!isset($this->data['config']['filter_url_params'])) {
        return;
    }
    foreach ($this->data['config']['filter_url_params'] as $paramName => $paramValue) {
        if ('*' == $paramValue) {
            $paramValue = $this->request->getParam($paramName);
        }
        if ($paramValue) {
            $this->data['config']['update_url'] = sprintf(
                '%s%s/%s/',
                $this->data['config']['update_url'],
                $paramName,
                $paramValue
            );
            $this->addFilter($this->filterBuilder->setField($paramName)->setValue($paramValue)->setConditionType('eq')->create());
        }
    }
}

/**
 * {@inheritdoc}
 */
public function getMeta()
{
    $meta = parent::getMeta();

    /** @var ModifierInterface $modifier */
    foreach ($this->pool->getModifiersInstances() as $modifier) {
        $meta = $modifier->modifyMeta($meta);
    }

    return $meta;
}

}