Правильный способ реализации getExtensionAttributes ()

11

Мне было интересно, как правильно реализовать расширяемую модель EAV.

Я вижу Magento\Catalog\Model\Product, что метод getExtensionAttributes()реализован так:

public function getExtensionAttributes()
{
    $extensionAttributes = $this->_getExtensionAttributes();
    if (!$extensionAttributes) {
        return $this->extensionAttributesFactory->create('Magento\Catalog\Api\Data\ProductInterface');
    }
    return $extensionAttributes;
}

Но в других, как модели клиентов или категории, это просто

public function getExtensionAttributes()
{
    return $this->_getExtensionAttributes();
}

что может привести к NULL- результату, если ключ extension_attributes не был установлен ранее.

Прагматично, я бы предпочел первый. Таким образом, я всегда могу получить экземпляр Magento\Framework\Api\ExtensionAttributesInterface, даже если модель только что была создана.

Но почему тогда он не используется в других модулях? Это против нового разделения моделей данных, которое мы видим в модуле клиента? Если так, как мы должны инициализировать атрибуты расширения?

Фабиан Шменглер
источник

Ответы:

1

Magento обновил AbstractExtensibleObject :: _ метод getExtensionAttributes сгенерировать пустой объект , если он не имеет расширения не атрибуты https://github.com/magento/magento2/commit/375132a81b95fafa4a03a17b72dbacdc90afa745#diff-56d044692f579051647a8284ff39cc0eR165 поэтому он никогда не вернется нуля. Им по-прежнему необходимо обновить аннотацию API, например, в vendor / magento / module-customer / Model / Data / Customer.php

 /**
 * {@inheritdoc}
 *
 * @return \Magento\Customer\Api\Data\CustomerExtensionInterface|null
 */
public function getExtensionAttributes()
{
    return $this->_getExtensionAttributes();
}
Райан Сан
источник
2

Я могу частично ответить на свой собственный вопрос, так как обнаружил, что способ реализации метода Magento\Catalog\Model\Productопределенно неверен и может привести к неприятным ошибкам:

Если extension_attributesданных еще нет, т. _getExtensionAttributes()Е. Возвращает ноль, метод возвращает пустой экземпляр интерфейса атрибутов расширения.

Это хорошо для выполнения явного контракта и предотвращения ошибок «Вызов функции-члена при нулевом значении», но он всегда возвращает новый пустой экземпляр, который не выполняет неявный контракт, а именно, что я получаю контейнер атрибутов расширения для этого конкретного экземпляра .

Это означает:

$product->getExtensionAttributes()->setStockItem($stockItem);
var_dump($product->getExtensionAttributes()->getStockItem());

выходы:

NULL

Лучшая реализация будет выглядеть так:

public function getExtensionAttributes()
{
    $extensionAttributes = $this->_getExtensionAttributes();
    if (!$extensionAttributes) {
        $extensionAttributes = $this->extensionAttributesFactory->create('Magento\Catalog\Api\Data\ProductInterface');
        $this->_setExtensionAttributes($extensionAttributes);
    }
    return $extensionAttributes;
}

Но почему тогда он не используется в других модулях? Это против нового разделения моделей данных, которое мы видим в модуле клиента? Если так, как мы должны инициализировать атрибуты расширения?

На это у меня до сих пор нет ответа

Фабиан Шменглер
источник
Выпуск Github: github.com/magento/magento2/issues/5979
Фабиан Шменглер,
Вы когда-нибудь получали ответ на этот вопрос - или как лучше с этим бороться? В настоящее время я получаю эту проблему при расширении объекта заказа.
Олбоб Доул
@ ol'bobdole, я получаю NULL для $order->getExtensionAttributes() и был решен после получения заказа , как показано ниже: $order = $this->orderRepositoryInterface->get($order->getId());. Интерфейс заказа репозитория есть Magento\Sales\Api\OrderRepositoryInterface. Не уверен, что ваша проблема была такой же
Сарджан Гаутам
0

Код по-разному используется в различных расширениях. Функциональность используется для привязки любого атрибута в этом интерфейсе. Чтобы лучше понять это, перейдите по этой ссылке: http://oyenetwork.com/articles/magento2-devliery-date-module-creation-from-scratch/


источник
Эта статья не отвечает на мой вопрос. Я знаю, как добавить атрибуты расширения к существующим объектам, я специально спрашивал о реализации getExtensionAttributes()в пользовательских объектах
Фабиан Шменглер,