Templates im Plugin Theme werden falsch extended

Shopware Version 5.2.2

Ich habe eine Plugin erstellt gemäßt dem neuen Plugin System (https://developers.shopware.com/developers-guide/plugin-system/)

In diesem Plugin möchte ich nun ein Theme erstellen und das „Responsive“ Theme erweitern.

Die Verzeichnisstruktur ist demnach diese:

Hier der Inhalt der Theme.php:

Ich bekomme allerdings immer einen Fehler wenn ich nun ein Parent Template extende (custom/plugins/MyPlugin/Resources/Themes/Frontend/MyTheme/frontend/index/index.tpl):

{extends file='parent:frontend/index/index.tpl'}

illegal recursive call of „parent:frontend/index/index.tpl“

Anscheinend will er sich immer selber extenden und nicht das Template des Parent Themes

Nach langem debugging habe ich nun selber den Fehler gefunden.

Der “Resources” Ordner MUSS klein geschrieben werden -> ‘resources’.

Das liegt daran das der Ordner in der Funktion getPluginPath klein geschrieben ist:

engine/Shopware/Components/Theme/PathResolver.php

    public function getPluginPath(Plugin $plugin)
    {
        if ($plugin->isLegacyPlugin()) {
            return $this->pluginDirectories[$plugin->getSource()] . $plugin->getNamespace() . DIRECTORY_SEPARATOR . $plugin->getName();
        }

        return $this->rootDir . '/custom/plugins/' . $plugin->getName() . '/resources';
    }

Wenn der Ordner nun wie in meinem Fall groß geschrieben wird, kann er das Template nicht richtig zuordnen:

    protected function buildFilepath(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
    {
        $this->index++;
        $file = $source->name;
        $hit = false;

        foreach ($source->smarty->getTemplateDir() as $_directory) {
            $_filePath = realpath($_directory . $file);
            if ($this->fileExists($source, $_filePath)) {
                if ($hit) {
                    return $_filePath;
                }
                if ($_template->parent->source->filepath == $_filePath) {
                    $hit = true;
                }
            }
        }

        return parent::buildFilepath($source, $_template);
    }

\_template-\>parent-\>source-\>filepath == _filePath trifft da nie zu und er gibt den falschen Pfad zurück.

 

Nun die Frage, ist das so gewollt das “resources” immer klein geschrieben wird? In der Dokumentation ist es groß https://developers.shopware.com/developers-guide/plugin-system/#container-configuration

Funktioniert das config.xml noch, wenn Du resources klein schreibst?

Ich binde momentan nur eine .yml Datei ein, das funktioniert zumindest in der Entwicklungsumgebung obwohl der Pfad jetzt nicht mehr stimmt:

$loader->load($this->getPath().'/Resources/services.yml');

Ich kann mir aber vorstellen das er die .xml und andere Ressourcen jetzt nicht mehr findet. Da es sonst überall groß geschrieben wird, gehe ich mal davon aus dass das ein Bug ist und in der getPluginPath Funktion auch groß geschrieben werden sollte.

Also ich habe das mal bei einem Plugin ausprobiert. Wenn ich “resources” statt “Resources” verwende, wars das mit der Installationsroutine. Funktioniert nicht mehr…

__________________________________________________
Konnte ich Dir helfen? Dann freue ich mich über ein Danke :wink:

Dann scheint das tatsächlich ein Bug zu sein. Liest das hier jemand von Shopware oder soll ich das besser wo anders melden?

Ich denke auch dass das ‚/resources‘ da gar nicht hingehört und die Funktion zu dem Hauptordner des Plugins führen soll.

return $this->rootDir . '/custom/plugins/' . $plugin->getName() . '/resources';

 

Am besten ein Ticket im Bugtracker anlegen…

Weiß jemand ob dies gepatcht wurde?

Hallo,

ich hab dafür mal ein Ticket angelegt und einen PR gestellt. Sollte in der nächsten Patch Version behoben werden.

Viele Grüße aus Schöppingen

cool Michael Telgmann

In der 5.3 Branch wurde es gefixt SW-15736 - Fix theme path resolver for new plugins. · shopware/shopware@1227379 · GitHub

Ich habe es temporär selber so gelöst:

$container->addCompilerPass(new PathResolverCompilerPass());

// PathResolverCompilerPass.php
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;

class PathResolverCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition('theme_path_resolver')) {
            return;
        }

        $definition = $container->getDefinition('theme_path_resolver');
        $definition->setClass(PathResolver::class);
        $definition->addMethodCall('setRootDir', array($container->getParameter('kernel.root_dir')));
        $definition->addMethodCall('setPluginDirectories', array($container->getParameter('shopware.plugin_directories')));
    }
}

// PathResolver.php
use Shopware\Components\Theme\PathResolver AS ShopwarePathResolver;
use Shopware\Models\Plugin\Plugin;

class PathResolver extends ShopwarePathResolver
{
    /**
     * @var string
     */
    private $rootDir;

    /**
     * @var array
     */
    private $pluginDirectories;


    /**
     * @param string $rootDir
     */
    public function setRootDir($rootDir){
        $this->rootDir = $rootDir;
    }

    /**
     * @param array $pluginDirectories
     */
    public function setPluginDirectories(array $pluginDirectories){
        $this->pluginDirectories = $pluginDirectories;
    }

    /**
     * Helper function to build the path to the passed plugin.
     *
     * @param Plugin $plugin
     * @return string
     */
    public function getPluginPath(Plugin $plugin)
    {
        if ($plugin->isLegacyPlugin()) {
            return $this->pluginDirectories[$plugin->getSource()] . $plugin->getNamespace() . DIRECTORY_SEPARATOR . $plugin->getName();
        }

        return $this->rootDir . '/custom/plugins/' . $plugin->getName() . '/Resources';
    }
}