Как поставщик данных формы администратора страницы CMS получает свои данные?


Короче говоря, длинная история:
Класс поставщика данных формы администратора страницы CMS Magento\Cms\Model\Page\DataProvider, более конкретный метод getData всегда возвращает массив с одним элементом, который содержит данные для страницы, которую я редактирую, а ключом элемента является идентификатор страницы.
Как это происходит? Где применяется фильтр по идентификатору страницы?

Короткий рассказ длинный:
На первый взгляд, какой метод Magento\Cms\Model\Page\DataProvider::getData возврат не так очевиден.
В метод есть такая строка

$items = $this->collection->getItems(); 

И элемент коллекции var инициализируется в __construct с помощью

$this->collection = $pageCollectionFactory->create();`   

Где $pageCollectionFactory является экземпляром Magento\Cms\Model\ResourceModel\Page\CollectionFactory.

Итак, когда я впервые посмотрел, я подумал: "Какого черта он загружает полную коллекцию, если я редактирую только один элемент? Это не масштабируется".
При ближайшем рассмотрении я увидел, что коллекция возвращает один-единственный предмет. Тот, который я редактирую. Это хорошо, но как это работает?
Если я напечатаю запрос на сбор данных echo $this->collection->getSelect(), я возвращайся

SELECT `main_table`.* FROM `cms_page` AS `main_table` WHERE (`main_table`.`page_id` = '2')

Где 2 - идентификатор страницы, которую я редактирую.
Теперь любопытная часть (если это было недостаточно любопытно) Если я создам свою собственную сущность, следуя тем же рекомендациям для класса поставщика данных, она будет работать так же. Я получаю обратно один-единственный предмет.
Это заставляет меня думать, что фильтрация происходит где-то выше в дереве наследования, но я понятия не имею, где?

Примечание: Пожалуйста, не объясняйте, как заставить это работать в моем пользовательском модуле. Я знаю, как это сделать. Я просто нужно объяснение того, как/почему/где происходит волшебство.

Author: Community, 2017-05-09

1 answers

Проверьте следующую функцию


/**
 * {@inheritdoc}
 */
public function getDataSourceData()
{
    $dataSource = [];

    $id = $this->getContext()->getRequestParam($this->getContext()->getDataProvider()->getRequestFieldName(), null);
    $filter = $this->filterBuilder->setField($this->getContext()->getDataProvider()->getPrimaryFieldName())
        ->setValue($id)
        ->create();
    $this->getContext()->getDataProvider()
        ->addFilter($filter);

    $data = $this->getContext()->getDataProvider()->getData();

    if (isset($data[$id])) {
        $dataSource = [
            'data' => $data[$id]
        ];
    } elseif (isset($data['items'])) {
        foreach ($data['items'] as $item) {
            if ($item[$item['id_field_name']] == $id) {
                $dataSource = ['data' => ['general' => $item]];
            }
        }
    }
    return $dataSource;
}

Следующая строка - создать коллекцию как единый элемент


$this->getContext()->getDataProvider()
        ->addFilter($filter);

[Правка OP].
Трассировка такова:

  • \Magento\Фреймворк\Представление\Элемент\Компонент\Тип содержимого\Json::визуализация()
  • \Magento\Фреймворк\Представление\Элемент\Компонент\Контекст::getdatasourcedata()
  • \Magento\Пользовательский интерфейс\Компонент\Форма::getdatasourcedata()
 2
Author: Sohel Rana, 2017-05-09 07:20:41