Bonne façon d'implémenter getExtensionAttributes ()

11

Je me demandais quelle était la bonne façon de mettre en œuvre un modèle EAV extensible.

Je vois que dans Magento\Catalog\Model\Product, la méthode getExtensionAttributes()est implémentée comme ceci:

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

Mais dans d'autres, comme les modèles client ou catégorie, c'est juste

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

ce qui peut conduire à un résultat NULL , si la clé extension_attributes n'a pas été définie auparavant.

Pragmatiquement, je préférerais le premier. De cette façon, je peux toujours être sûr d'obtenir une instance de Magento\Framework\Api\ExtensionAttributesInterface, même si le modèle vient d'être instancié.

Mais pourquoi n'est-il pas utilisé dans d'autres modules? Est-ce contre la nouvelle séparation des modèles de données que nous voyons dans le module client? Si oui, comment sommes-nous censés initialiser les attributs d'extension?

Fabian Schmengler
la source

Réponses:

1

Magento mis à jour le AbstractExtensibleObject :: _ méthode getExtensionAttributes pour générer un objet vide si elle n'a pas d' extension des attributs https://github.com/magento/magento2/commit/375132a81b95fafa4a03a17b72dbacdc90afa745#diff-56d044692f579051647a8284ff39cc0eR165 il ne reviendra pas nulle. Ils doivent cependant mettre à jour l'annotation de l'API, par exemple dans vendor / magento / module-customer / Model / Data / Customer.php

 /**
 * {@inheritdoc}
 *
 * @return \Magento\Customer\Api\Data\CustomerExtensionInterface|null
 */
public function getExtensionAttributes()
{
    return $this->_getExtensionAttributes();
}
Ryan Sun
la source
2

Je peux partiellement répondre à ma propre question car j'ai découvert que la façon dont la méthode est implémentée Magento\Catalog\Model\Productest définitivement fausse et peut conduire à des bugs désagréables:

S'il n'y a pas extension_attributesencore de données, c'est-à-dire _getExtensionAttributes()renvoie null, la méthode renvoie une instance vide de l'interface des attributs d'extension.

C'est bon pour remplir le contrat explicite et empêche les erreurs "Appel à une fonction membre sur null" mais cela retourne toujours une nouvelle instance vide, qui ne remplit pas le contrat implicite, à savoir que j'obtiens un conteneur d'attributs d'extension pour cette instance spécifique .

Cela signifie:

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

les sorties:

NULL

Une meilleure mise en œuvre ressemblerait à ceci:

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

Mais pourquoi n'est-il pas utilisé dans d'autres modules? Est-ce contre la nouvelle séparation des modèles de données que nous voyons dans le module client? Si oui, comment sommes-nous censés initialiser les attributs d'extension?

A cela, je n'ai toujours pas de réponse

Fabian Schmengler
la source
Problème
Fabian Schmengler
Avez-vous déjà obtenu une réponse à cette question - ou comment y faire face au mieux? Je reçois actuellement ce problème lors de l'extension d'un objet de commande.
ol'bob dole
@ ol'bobdole, je recevais NULL $order->getExtensionAttributes() et a été résolu après avoir obtenu l' ordre comme suit: $order = $this->orderRepositoryInterface->get($order->getId());. L'interface du référentiel de commandes est Magento\Sales\Api\OrderRepositoryInterface. Je ne sais pas si votre problème était le même
Sarjan Gautam
0

Le code est utilisé de différentes manières dans différentes extensions. La fonctionnalité est utilisée pour lier n'importe quel attribut dans cette interface. Pour une meilleure compréhension de ceci, référez-vous à ce lien: http://oyenetwork.com/articles/magento2-devliery-date-module-creation-from-scratch/


la source
Cet article ne répond pas à ma question. Je sais comment ajouter des attributs d'extension à des entités existantes, je posais des questions spécifiquement sur la mise getExtensionAttributes()en œuvre d' entités personnalisées
Fabian Schmengler