L'objet chargé de déterminer si un index plat est disponible (classe Magento\Catalog\Model\Indexer\Product\Flat\State
) est une instance partagée immuable. Mais il est possible d'utiliser notre propre instance, en utilisant des types virtuels.
C'est mon di.xml
:
<virtualType name="disabledFlatStateProductCollectionFactory" type="Magento\Catalog\Model\ResourceModel\Product\CollectionFactory">
<arguments>
<argument name="instanceName" xsi:type="string">disabledFlatStateProductCollection</argument>
</arguments>
</virtualType>
<virtualType name="disabledFlatStateProductCollection" type="Magento\Catalog\Model\ResourceModel\Product\Collection">
<arguments>
<argument name="catalogProductFlatState" xsi:type="object">disabledFlatState</argument>
</arguments>
</virtualType>
<virtualType name="disabledFlatState" type="Magento\Catalog\Model\Indexer\Product\Flat\State">
<arguments>
<argument name="isAvailable" xsi:type="boolean">false</argument>
</arguments>
</virtualType>
Maintenant, j'ai un type d'usine de collection de produits virtuels, où ma propre instance "State" avec $isAvailable = false
est finalement utilisée:
disabledFlatStateProductCollectionFactory
|
+ disabledFlatStateProductCollection
|
+ disabledFlatState
Et pour les classes où j'ai besoin d'une fabrique de collection avec un index plat désactivé, je spécifie le type virtuel disabledFlatStateProductCollectionFactory
pour le paramètre constructeur correspondant:
<arguments>
<argument name="collectionFactory" xsi:type="object">disabledFlatStateProductCollectionFactory</argument>
</arguments>
Fabian Schmengler
la source
Lorsqu'une collection de produits est chargée, le fait qu'elle utilise EAV ou des tables plates est déterminé par ce résultat
\Magento\Catalog\Model\ResourceModel\Product\Collection::isEnabledFlat()
.Vous pouvez écrire un plugin
around
ouafter
, qui revientfalse
si vous êtes dans le contexte d'une certaine vue de magasin.Ou encore mieux, les valeurs de l'indicateur plat sont stockées (mises en cache) dans le membre
_flatEnabled
de la même classe.Vous pouvez écrire le même
around
ouafter
plugin pour la méthode\Magento\Catalog\Model\Indexer\Product\Flat\State::isAvailable()
.De cette façon, votre plugin n'est exécuté qu'une seule fois. Cela pourrait être utile si vous avez une logique lourde derrière elle ou si elle est utilisée dans d'autres endroits.
Cela semble plus élégant que de changer une valeur de configuration à la volée.
la source
\Magento\Catalog\Model\Indexer\Product\Flat\State::isAvailable()
?La manière la plus élégante serait d' utiliser le même code que le code qui active le mode plat lors de l'enregistrement de la configuration. Il se trouve sous
Magento/Catalog/Model/Indexer/Product/Flat/System/Config/Mode
:Je suis donc sûr que vous pourriez faire quelque chose comme ça:
Où
$this->_productFlatIndexerProcessor
est une instance de\Magento\Catalog\Model\Indexer\Product\Flat\Processor
.Alternative possible
Cependant, cette méthode n'enregistre pas la configuration, donc lorsque le système vérifie si le flat est activé via la configuration, il renvoie toujours true.
Une alternative possible (à tester) serait d' utiliser un plugin sur la
isFlatEnabled
méthode deMagento\Catalog\Model\Indexer\Product\Flat\State
(la méthode est en fait définie dans laMagento\Catalog\Model\Indexer\AbstractFlatState
classe).En fonction de ce que vous souhaitez réaliser, vous pouvez configurer un plugin After pour forcer cette méthode à retourner false dans certaines conditions.
la source
setScheduled(false)
l'indexeur ne fonctionne pas car il ne désactive que l'indexation planifiée et n'aura pas d'impact sur les collections. Mais quoi qu'il en soit, il enregistre également le mode, ce qui n'est certainement pas ce que je veux.