Is it possible to disable plugins defined in di.xml programatically?

In your di.xml you can do the following:

<type name="\Magento\Catalog\Model\Product">
    <plugin name="se_catalog_product_plugin_ample" disabled="true" />
</type>

Magento does it out of the box in Magento/Backend/etc/adminhtml/di.xml with the following :

<type name="Magento\Framework\App\Action\Action">
    <plugin name="storeCheck" disabled="true" />
</type>

Side note: you may have to make your module depends on the Example\Module ;)


It sounds like in this case you might have to make a preference on the plugin class, extend it with your class, then conditionally call the parent/original plugin method based on some system config you want to check.

I haven't tested this but seems like it might work unless preferences don't work as expected for the plugin/interceptor process.

preference in di.xml

<preference for="Example\Module\Model\Plugin\Catalog\Product" type="Your\Module\Model\ConditionalProductPlugin"/>

preference class

namespace Your\Module\Model;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;

class ConditionalProductPlugin extends \Example\Module\Model\Plugin\Catalog\Product
{
    protected $storeManager;
    protected $scopeConfig;

    public function __construct(
        $originalClassArg1,
        $originalClassArg2,
        StoreManagerInterface $storeManager,
        ScopeConfigInterface $scopeConfig
    ) {
        parent::__construct($originalClassArg1, $originalClassArg2);
        $this->storeManager = $storeManager;
        $this->scopeConfig = $scopeConfig;
    }

    /**
     * Check config for some flag to determine if original plugins should run
     */
    public function isDisabled()
    {
        $store = $this->storeManager->getStore()->getId();

        return $this->scopeConfig->isSetFlag(
            'some/config/path/disabled',
            ScopeInterface::SCOPE_STORE,
            $store
        );
    }

    /**
     * Example for before plugin
     */
    public function beforeSomething($subject, ...$args)
    {
        if ($this->isDisabled()) {
            return null;
        }

        // Allow the calling of the original before plugin
        return parent::beforeSomething($subject, ...$args);
    }

    /**
     * Example for around plugin
     */
    public function aroundSomething($subject, $proceed, ...$args)
    {
        if ($this->isDisabled()) {
            return $proceed(...$args);
        }

        // Allow the calling of the original around plugin
        return parent::aroundSomething($subject, $proceed, ...$args);
    }

    /**
     * Example for after plugin
     */
    public function afterSomething($subject, $result, ...$args)
    {
        if ($this->isDisabled()) {
            return $result;
        }

        // Allow the calling of the original after plugin
        return parent::afterSomething($subject, $result, ...$args);
    }
}