How to register custom models of third party plugins in Shopware before your own Plugin

Shopware is extendable and customizable, or at least that's the major idea behind the framework. Sometimes you will need to extend another plugin from your own plugin, in this article specifically the Models (Doctrine Entities) from another plugin. This by itself (unless the target entity doesn't allow to extend it, see Doctrine Inheritance) it's not theoretically a big deal.

For example, assuming that a model namely Person of the SwagThirdParty plugin exists, we want to extend this model in our own plugin. The new model that extends would look like:

<?php

namespace OurCodeWorldMyPlugin\Models;

use Doctrine\ORM\Mapping as ORM;
use Shopware\Components\Model\ModelEntity;
use Doctrine\Common\Collections\ArrayCollection;

// Model Of the Third Party Plugin
use Shopware\CustomModels\SwagThirdPartyPlugin\Person;

// Our new Model in our plugin that extends the model from another plugin
class Programmer extends Person
{
    // ... content of the class ... //
}

As you can see, the model requires the Person model to be executed, however in some cases during the installation of the plugin either by the command line or the plugin manager, you may found an exception that specifies that the Person model does not exists, although the SwagThirdPartyPlugin exists and is already installed.

Solution

The problem is that indeed, the model won't exist during the installation of your own plugin. This usually happens only with the installation/re-installation of the plugin with the command line (Shopware CLI Tools) as in this environment, your plugin will be installed without having a context of other installed third party plugins. To solve this issue, you will only need to register the Models of the plugin retrieving them manually during the install event of your Plugin. 

Open the PHP File of your plugin (the Bootstrap file), that in our case is OurCodeWorldMyPlugin.php (root folder) and add the new private method registerThirdPartyPluginModels to the class:

<?php

namespace OurCodeWorldMyPlugin;

use Shopware\Components\Plugin;
use Shopware\Components\Plugin\Context\ActivateContext;
use Shopware\Components\Plugin\Context\DeactivateContext;
use Shopware\Components\Plugin\Context\InstallContext;
use Shopware\Components\Plugin\Context\UninstallContext;
use Doctrine\ORM\Tools\SchemaTool;

// Use Models
use OurCodeWorldMyPlugin\Models\Programmer;

class OurCodeWorldMyPlugin extends Plugin
{
    /**
     * During the installation of our plugin, update the schema.
     *
     * @param InstallContext $context
     */
    public function install(InstallContext $context)
    {
        // Register models of the third party plugin before registering ours
        $this->registerThirdPartyPluginModels("SwagThirdPartyPlugin");

        // Now you shouldn't get an exception when you try to register your new models
        // during the rest of your code here ....
    }

    /**
     * Register Models of the third party plugin before proceding with the mapping.
     *
     * Note: this adds a reference to all the models of the plugin with the given name
     */
    private function registerThirdPartyPluginModels($thirdPartyPluginName)
    {
        try {
            // As our plugin modifies a model from an external plugin, we need to retrieve the plugin
            $plugin = Shopware()->Container()->get('shopware.plugin_manager')->getPluginBootstrap(
                Shopware()->Container()->get('shopware.plugin_manager')->getPluginByName($thirdPartyPluginName)
            );

            // Register Models of the SwagThirdPartyPlugin, which give us access to its models
            // during the generation of the schema for your new models.
            $plugin->registerCustomModels();
        } catch (\Exception $e) {}
    }
}

As you can see, the new method registers all the models of a plugin by its name. You need to run the method in the piece of code that imports the new model that requires the model of the third party plugin (in this case Programmer) or you will see the exception.

Happy coding !

This could interest you

Become a more social person