Plugin: Uncaught SmartyException: directory not allowed by security setting

>> Wieso wird der Views Ordner im neuen Plugin System eigtl nicht automatisch registiert?

Ich habe zb Plugins, die ich nur in manchen Subshops (per Plugin Konfiguration) aktiveren möchte. Da spare ich mir ganz gerne den overhead und lade die Template Ordner dort nicht. Zudem gibt es weiterhin definitiv Konstellationen, bei denen du separiert das Template Verzeichnis laden möchtest oder eben nicht. Ich finde, dass es weiterhin in der Hand des Entwicklers liegen sollte, wann und ob ein Template erweitert wird - man muss dabei halt nur ein wenig aufpassen und sich an die Richtlinien halten.

Viele Grüße

Hallo,

es gibt glaub genug Anwendungsfälle, wo man entweder einen View-Ordner oder einen anderen laden muss, ein automatisches registrieren wäre also fatal und würde gar keinen Sinn machen und wird Shopware hoffentlich auch nie implementieren, da es eher ein Rückschritt wäre. Solange man sich an die Regeln hält, klappt doch auch alles.

Beste Grüße

Sebastian

Jo, wie “leicht” es mit an den “Regeln halten” ist, haben wir ja im S-Thread gesehen. Wenn ich mich nicht täusche, waren da einige Plugins mit dem Kürzel “SWAG” ganz vorne mit dabei.  Wink Lustig wird es dann, wenn solche Hinweise aus der unwartbaren Spaghetti-Code-Ecke kommen.  Sticking-out-tongue
Dank Patrick hat sich der Nebel schon erheblich gelichtet. Warum jetzt aber der Smarty-Cache erst zum Problem wird (bei mir) wenn der HTTP-Cache aktiviert ist, werde ich bestimmt nach mehrmaligem Lesen obiger Abhandlung verstehen. Oder einfach sagen: egal

Danke Patrick für die ausführliche Erklärung.

@sschreier‍: Okay. Macht bei den Views wohl Sinn. Wobei das gleiche ja für LESS und JS Erweiterungen auch gelten könnte. Die will man dann ja evtl. auch nicht haben, wenn man das Plugin für einen Subshop deaktiviert. Die werden auch, wenn sie in einem gewissen Verzeichnis liegen, automatisch registiert. Vielleicht wäre aber ein optionaler Schalter im InstallContext eine Möglichkeit. Somit könnte man sich ne Menge Boilerplate Code ersparen. Eine Autoregistierung für Models würde ich jedoch sehr sinnvoll finden. Könnte man ja optional im InstallContext deaktivieren oder hier auch wieder optional aktivieren. Wäre ja vermutlich ein Breaking Change.

Danke an [@Patrick Stahl](http://forum.shopware.com/profile/1869/Patrick Stahl “Patrick Stahl”)‍ für die ausführliche Erläuterug, das hat viel Licht ins Dunkle gebracht!

Ich frage mich jetzt allerdings was

Registriert eure Plugin eigene Views Ordner so früh wie möglich, also nicht erst nach bestimmten Bedingungen, und nutzt keine Events, die ja auch irgendwo direkt eine Bedingung beinhaltet, wie eben bspw. die Unterscheidung des Moduls.

nun genau bedeutet. Für mich ist der fett gedruckte Teil leider nicht ganz eindeutig:

  1. Templates nicht in einem Event für ein Modul hinzufügen
  2. oder gar nicht in einem Event hinzufügen.

Ersterer Fall wäre ja eben z.B. “Enlight_Controller_Action_PostDispatch”. Letzteren Fall wüßte ich momentan nicht umzusetzen, wie macht man denn die Views außerhalb von Events bekannt? Hier fehlt mir wohl das Wissen :frowning:

Anders ausgedrückt: Was ist denn grundsätzlich die früheste und damit sicherste Möglichkeit den Views-Ordner zu registrieren? Falls nicht “Enlight_Controller_Action_PostDispatch” wäre ein Code-Schnipsel natürlich toll… :wink:

LG und Besten Dank,
devnullroot

P.S.: Ich frage auch deshalb nochmal explizit nach, weil ich die Frage gerne als beantwortet markieren möchte

 

Moin @devnullroot‍.

damit meinte ich in lediglich, dass keine Events zur Template Registrierung benutzt werden sollten, die eine Bedingung enthalten.
Enlight_Controller_Action_PostDispatchSecure_Frontend

Hier ist bspw. das _Frontend ja schon eine Bedingung, wie oben in meinem Beispiel erläutert.

Du könntest bspw. das folgende Event nutzen:
Theme_Inheritance_Template_Directories_Collected
sowie der dazugehörige Beispiel-Code:
 

public function onCollectTemplateDir(\Enlight_Event_EventArgs $args)
{
    $dirs = $args->getReturn();
    $dirs[] = $this->pluginDir . '/Views';

    $args->setReturn($dirs);
}

Gruß,
Patrick  Shopware
 

2 Likes

Moin Patrick,

ich habe ein ähnliches Problem wie devnullroot, mein Plugin passt die Artikelbox im Listing an, ist der Cache geleert, funktioniert alles super, bei aktualisieren der Seite wird das Template aber scheinbar nicht mehr geladen. Ist der HTTP-Cache deaktiviert funktioniert alles einwandfrei. Das Problem tritt bei mehreren Kunden mit Shopware 5.3.4 auf.

Ich habe nun wie von Dir [@Patrick Stahl](http://forum.shopware.com/profile/1869/Patrick Stahl „Patrick Stahl“)‍ vorgeschlagen zuerst versucht das Template Verzeichnis direkt im  Enlight_Controller_Action_PostDispatch  Event (ohne jegliche Bedingungen) zu registrieren und es anschließend auch mit dem Event  Theme_Inheritance_Template_Directories_Collected  versucht. Aber das Problem bleibt das gleiche.

Ich habe natürlich nach dem Hinzufügen der genannten Events jeweils das Plugin neuinstalliert und den Cache komplett geleert. Aber immer das gleiche Verhalten der erste Seitenaufruf nach Cache leeren passt, der zweite und alle folgenden nicht mehr.

Wo könnte das Problem noch liegen?

Gruß

Daniel

Moin Daniel / @mowlwurf‍,

da kann ich mir spontan auch keinen Reim draus bilden.
Das müsste ich mir dann schon im Detail anschauen.

Ist dies zu 100% mit deinem Plugin nachstellbar?
Dann lass mir doch einfach ein .zip per PM zukommen, dann schaue ich mal, ob ich da etwas finde.
Bitte natürlich auch alle benötigten Informationen hinzufügen, also bspw. sowas wie “benötigte Plugin Konfigurationen” oder sowas, um das Verhalten nachzustellen.

Gruß,
Patrick  Shopware

Moin @mowlwurf‍,

hat sich bei dem Problem was ergeben? Ist es die gleiche/ähnliche Problematik, eine „erweiterete“ Version, oder etwas völlig anderes?

 

Cheers,
devnullroot

Moin @devnullroot‍,

komme momentan zeitlich leider nicht dazu mir das Verhalten von @mowlwurf‍ anzuschauen.
Habe mir dafür jedoch einen Reminder angelegt, sodass ich mir dies definitiv nochmal anschauen werde.

Gruß,
Patrick  Shopware

1 Like

Du könntest bspw. das folgende Event nutzen:

Theme_Inheritance_Template_Directories_Collected
sowie der dazugehörige Beispiel-Code:
 

public function onCollectTemplateDir(\Enlight_Event_EventArgs $args)
{
$dirs = $args->getReturn();
$dirs = $this->pluginDir . ‘/Views’;

$args->setReturn($dirs);
}

Hallo [@Patrick Stahl](http://forum.shopware.com/profile/1869/Patrick Stahl “Patrick Stahl”)‍,

kann man zu diesem Zeitpunkt auch schon ein Smarty-Plugin einbinden? Falls ja, wie müsste das aussehen?

Moin,

ich hatte das Problem bei Infinite Scrolling im Listing bei erweiterung der \frontend\listing\product-box\box-basic.tpl. Alle Lösungen die hier vorgeschlagen wurden haben in meinen Fall nicht funktioniert. Der Hinweis das es sich um Widget -Controller handelt brachte mich aber zur Lösung. Es funktioniert aber nur als PreDispatch! ‚Enlight_Controller_Action_PreDispatch_Widgets_Listing‘.

public static function getSubscribedEvents()
{
    return [
        'Enlight_Controller_Dispatcher_ControllerPath_Widgets_XXXXXXX' => 'registerController',
        'Enlight_Controller_Action_PostDispatchSecure_Frontend_Listing' => 'onPostDispatchFrontendListing',
        'Enlight_Controller_Action_PreDispatch_Widgets_Listing' => 'onDispatchWidgetListing',
    ];
}

public function registerController(\Enlight_Event_EventArgs $args)
{
    $this->container->get('template')->addTemplateDir($this->getPath() . '/Resources/Views/');
    return $this->getPath() . '/Controllers/Widgets/XXXXXXX.php';
}

public function onPreDispatchWidgetListing($args)
{
    $subject = $args->get('subject');
    $view = $subject->View();
    $view->addTemplateDir($this->getPath() . '/Resources/Views/');
}

public function onPostDispatchFrontendListing($args)
{
    $subject = $args->get('subject');
    $view = $subject->View();
    $view->addTemplateDir($this->getPath() . '/Resources/Views/');
}

Gruß,
Debianer

Moin @debianer‍,

das liegt daran, dass in der Action in dem Widgets-Controller das Template direkt geladen wird.

Entsprechend hast du im PostDispatch, also  nach  Ausführung der originalen Action, keine Möglichkeit mehr in das Template einzugreifen.
Hat aber nichts mit dem eigentlichen Fehler dieses Threads zu tun. Smile

Gruß,
Patrick  Shopware

Hallo [@Patrick Stahl](http://forum.shopware.com/profile/1869/Patrick Stahl „Patrick Stahl“)‍

könntest du bitte noch was zu meiner Frage obendrüber sagen? Kann man im Event Theme_Inheritance_Template_Directories_Collected auch schon ein Smarty Plugin laden? Wenn ja, wie?

Dankeschön

 

Moin @puhas‍,

das kann ich dir gerade nicht ganz genau sagen, müsstest du einfach mal ausprobieren.
Das kannst du ja erstmal Quick & Dirty direkt in engine/Shopware/Components/Theme/Inheritance.php#193 hiermit versuchen:

Shopware()->Template()->registerPlugin(...);

Sollte das funktionieren, kannst du ja den sauberen Weg über einen Subscriber und den DI-Container wählen.

Gruß,
Patrick  Shopware

1 Like

Guten Morgen [@Patrick Stahl](http://forum.shopware.com/profile/1869/Patrick Stahl „Patrick Stahl“)‍,

kommst du evtl. diese Woche zum Problem von @mowlwurf‍?
Wäre super.

Grüße
Ottscho

Das kannst du ja erstmal Quick & Dirty direkt in engine/Shopware/Components/Theme/Inheritance.php#193 hiermit versuchen:

Shopware()->Template()->registerPlugin(…);

 

Danke Patrick, mit

Shopware()->Template()->addPluginsDir( __DIR__. '/SmartyPlugins/');

funktioniert es schon mal.

Habe zu kompliziert gedacht Gasp

So, dank [@Patrick Stahl](http://forum.shopware.com/profile/1869/Patrick Stahl “Patrick Stahl”)‍ ist mein Problem nun auch geklärt,

hatte mit einer alten Plugin Template Struktur und der folgenden Funktion zu tun.

$view->extendsTemplate('frontend/plugins/mein_plugin/listing.tpl');

Diese ist deprecated und hat im Listing in Verbindung mit aktiviertem HTTP-Cache zu dem von mir beschriebenen fehlerhaften Verhalten geführt.

Insofern man, wie ich in dem Fall nur bestehende Templates bearbeitet, sollte man die Templates in der Frontend Theme Struktur anlegen und auf das extendsTemplate verzichten, da diese dann automatisch geladen werden. Also “frontend/listing/listing.tpl” beispielsweise.

Will man explizit ein neues/komplett eigenes Template verwenden sollte man die Funktion loadTemplate verwenden, darf in der, ich nenne sie mal custom.tpl dann nicht vergessen das entsprechende Template zu extenden, da sonst vom Rest der Seite nichts mehr geladen wird.

Ich hoffe ich habe das verständlich wiedergegeben. Dadurch tritt jedenfalls das mysteriöse Verhalten mit dem HTTP-Cache nicht mehr auf. Und nochmals riesen Dank an [@Patrick Stahl](http://forum.shopware.com/profile/1869/Patrick Stahl “Patrick Stahl”)‍ für seinen Einsatz.

Gruß

Daniel

1 Like

[@Patrick Stahl](http://forum.shopware.com/profile/1869/Patrick Stahl “Patrick Stahl”)‍

Ich verwende in meinem Plugin folgenden Code um im Backend ein Icon hinzuzufügen.

public static function getSubscribedEvents()
    {
        return [
            'Enlight_Controller_Action_PostDispatch_Backend_Index' => 'addBackendTemplateDir',
        ];
    }


/**
     * @param \Enlight_Event_EventArgs $args
     */
    public function addBackendTemplateDir(\Enlight_Event_EventArgs $args) {
        try {
            /** @var \Enlight_Controller_Action $controller */
            $controller = $args->getSubject();
            $view = $controller->View();

            if ($view->hasTemplate()) {
                $view->extendsTemplate(
                    $this->getPath() . '/Resources/Views/backend/index/index.tpl'
                );
            }
        } catch (\Exception $e) {
        }
    }

Nun wurde mir folgender Fehler in 5.4.1 gemeldet: 

MeinPlugin/Resources/Views/backend/index/index.tpl' not allowed by security setting

Ich kann diesen Fehler aktuell nicht in einer SW 5.4.1 Installation nicht reproduzieren. Was kann hier der Fehler sein - für mich sieht die index.tpl Registrierung im Backend richtig aus. Hättest Du oder jemand anderes einen Tipp?

Hallo @elbsurfer‍,

dir fehlt schlichtweg das Hinzufügen deines Template-Ordners, also so:
$this->addTemplateDir($this->getPath() . ‚/Resources/Views/‘);

Ich würde dir aber auch empfehlen deinen „views“ Ordner klein zu schreiben, aus Konsistenz-Gründen. :slight_smile:

Gruß,
Patrick  Shopware