Page-Controller kann nicht gefunden werden, obwohl dieser existiert

Hey,

ich habe jetzt eine neue Seite mit dieser Anleitung (Add Custom Page | Shopware Documentation) erstellt und aufgerufen.

Nun bekomme ich beim Aufruf des Shops folgende Fehlermeldung:

Class HP2022\ProductDesigner\Storefront\Controller\ProductDesignerController does not exist in /var/www/html/custom/plugins/ProductDesigner/src/Storefront/Controller/ProductDesignerController.php (which is being imported from „/var/www/html/custom/plugins/ProductDesigner/src/Resources/config/routes.xml“). Make sure to use PHP 8+ or that annotations are installed and enabled.

Ich weiß nicht warum dieser Fehler kommt. Die Klasse ProductDesignerController exisitiert genau unter dieser Quelle (HP2022\ProductDesigner\Storefront\Controller\ProductDesignerController). Unerklärlicherweise kann diese aber nicht gefunden werden.

Dies ist die ProductDesignerController.php:

namespace HP2022\ProductDesigner\Storefront\Controller;
use ....

/**
 * @Route(defaults={"_routeScope"={"storefront"}})
 */
class ProductDesignerController extends StorefrontController{

    private ProductDesignerPageLoader $productDesignerPageLoader;

    public function __construct(ProductDesignerPageLoader $productDesignerPageLoader){
        $this->productDesignerPageLoader = $productDesignerPageLoader;
    }

    /**
     * @Route("/designer", name="frontend.hp2022.productDesigner", methods={"GET"})
     */
    public function showProductDesigner(Request $request, SalesChannelContext $context) : Response{

        $page = $this->productDesignerPageLoader->load($request, $context);

        return $this->renderStorefront("@HP2022/storefront/page/productDesigner/index.html.twig", [
            "example" => "Hello World"
        ]);
    }
}

dies die services.xml:

<services>
        <service id="HP2022\ProductDesigner\Storefront\Controller\ProductDesignerController" public="true">
            <call method="setContainer">
                <argument type="service" id="service_container"/>
            </call>
        </service>
        <service id="HP2022\ProductDesigner\Storefront\Page\ProductDesigner\ProductDesignerPageLoader" public="true">
            <argument type="service" id="Shopware\Storefront\Page\GenericPageLoader" />
            <argument type="service" id="event_dispatcher"/>
        </service>
    </services>

und dies die routes.xml

<import resource="../../Storefront/Controller/**/*Controller.php" type="annotation" />

Hat jemand eine Idee, woran es liegt und wie ich dies lösen kann?

1 „Gefällt mir“

Müsste das nicht so sein?

<import resource="../../Controller/*Controller.php" type="annotation" />
1 „Gefällt mir“

In deiner services.xml müsstest du noch deinem ProductDesignerController den Pageloader als Argument mitgeben. Ansonsten sehe ich keine Fehler.

Tritt der Fehler auch auf, wenn du PHP8 verwendest?

Welche Shopware Version verwendest du gerade?

Ansonsten würde ich noch folgende Möglichkeit probieren:

/**
 * @RouteScope(scopes={"storefront"})
 */
class ProductDesignerController extends StorefrontController

Eventuell so?

   /**
     * @Route("/designer", name="frontend.designer", methods={"GET"})
     */

Guten Morgen,

danke für eure Unterstützung.

Ich habe jetzt all eure Vorschläge ausprobiert. Es erscheint weiterhin der Fehler.

@R4M : Was ich so gelesen habe ist, dass der name der Route nur dazu da ist, dass diese Route auch eindeutig erkannt wird. Den import in der routes.xml habe ich so von der verlinkten Seite in der Doku.

@abdullah : Warum muss ich an den Pageloader den Controller übergeben? Ich nutze den Controller nicht im Pageloader. Da sich die Klassen im gleichen Namespace befinden , können sie sich ja auch gegenseitig sehen und somit auch aufrufen.

Ich nutze die PHP-Version 8.0 und Shopware Version 6.4.13.0.

1 „Gefällt mir“

@StefanB, mit PageLoader meine ich den ‚ProductDesignerPageLoader‘.

Dein Controller hat einen Constructor und erwartet als ersten Parameter einen ProductDesignerPageLoader. Diesen musst du auch in der services.xml angeben.

Auch wenn sie im gleichen package sind, muss man sie in der services.xml angeben. Bin ich der Meinung. Korrigiert mich, wenn ich falsch liege.

@abdullah : Aso okay. Danke.

Nur entsteht der Fehler nicht schon bevor die Klasse ProductDesignerPageLoader geladen wird?
Der Controller wird ja erst garnicht gefunden.

Nichts desto trotz habe ich es jetzt in die services.xml integriert. Weiterhin bekomme ich den gleichen Fehler.

@StefanB , im Code selbst sehe ich auf Anhieb keinen Fehler. Könntest du noch deine Imports zeigen?
Wird auch die richtige Route Annotation Class von Symfony geladen?

@abdullah : Mit Imports meinst du?

Wie kann ich dies prüfen?

Deine use Statements

Aso. Hier sind die use-Statements der 4 Scripte:

1. ProductDesignerController.php

use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use HP2022\ProductDesigner\Storefront\Page\ProductDesigner\ProductDesignerPageLoader;

2. ProductDesignerPage.php

use Shopware\Storefront\Page\Page;

3. ProductDesignerPageLoadedEvent.php

use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Page\PageLoadedEvent;
use Symfony\Component\HttpFoundation\Request;

4. ProductDesignerPageLoader.php

use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Page\GenericPageLoaderInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;

für mich sieht alles in Ordnung aus.

Vermute daher, dass das Problem an der Server-Kondiguration liegt.

Hast du versucht das Plugin einmal zu deinstallieren und erneut zu installieren?

Hast du mal nachgeguckt, ob die Annotations bei auch installiert sind?

Tritt das Problem auch unter PHP 7.4 auf?

Okay. Ich nutze auf docker das Image dockware:latest. Kenne mich bei der Severkonfiguration aber nicht aus.

Ja, bei PHP 7.4 tritt der Fehler auch auf und wenn ich das Plugin deinstalliere und neu installiere ebenso.

Hast du mal nachgeguckt, ob die Annotations bei auch installiert sind?

Wie mache ich das? Hast du da einen Link, bei dem ich das nachschauen kann?

Edit:
Ich habe gerade den cache gelöscht und dabei kam auf der Console folgender Fehler:

In AnnotationFileLoader.php line 56:
[ReflectionException (-1)]
Class HP2022\ProductDesigner\Storefront\Controller\ProductDesignerController does not exist

und hier ist der Exception Trace dazu:

Exception trace:
  at /var/www/html/vendor/symfony/routing/Loader/AnnotationFileLoader.php:56
 ReflectionClass->__construct() at /var/www/html/vendor/symfony/routing/Loader/AnnotationFileLoader.php:56
 Symfony\Component\Routing\Loader\AnnotationFileLoader->load() at /var/www/html/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php:38
 Symfony\Component\Routing\Loader\AnnotationDirectoryLoader->load() at /var/www/html/vendor/symfony/config/Loader/FileLoader.php:159
 Symfony\Component\Config\Loader\FileLoader->doImport() at /var/www/html/vendor/symfony/config/Loader/FileLoader.php:87
 Symfony\Component\Config\Loader\FileLoader->import() at /var/www/html/vendor/symfony/routing/Loader/XmlFileLoader.php:198
 Symfony\Component\Routing\Loader\XmlFileLoader->parseImport() at /var/www/html/vendor/symfony/routing/Loader/XmlFileLoader.php:85
 Symfony\Component\Routing\Loader\XmlFileLoader->parseNode() at /var/www/html/vendor/symfony/routing/Loader/XmlFileLoader.php:63
 Symfony\Component\Routing\Loader\XmlFileLoader->load() at /var/www/html/vendor/symfony/config/Loader/FileLoader.php:159
 Symfony\Component\Config\Loader\FileLoader->doImport() at /var/www/html/vendor/symfony/config/Loader/FileLoader.php:87
 Symfony\Component\Config\Loader\FileLoader->import() at /var/www/html/vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php:45
 Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator->import() at /var/www/html/vendor/shopware/core/Framework/Bundle.php:74
 Shopware\Core\Framework\Bundle->configureRoutes() at /var/www/html/vendor/shopware/core/Framework/Plugin.php:80
 Shopware\Core\Framework\Plugin->configureRoutes() at /var/www/html/vendor/shopware/core/Kernel.php:432
 Shopware\Core\Kernel->addBundleRoutes() at /var/www/html/vendor/shopware/core/Kernel.php:282
 Shopware\Core\Kernel->configureRoutes() at /var/www/html/vendor/symfony/framework-bundle/Kernel/MicroKernelTrait.php:222
 Shopware\Core\Kernel->loadRoutes() at /var/www/html/vendor/symfony/routing/Loader/ObjectLoader.php:62
 Symfony\Component\Routing\Loader\ObjectLoader->load() at /var/www/html/vendor/symfony/config/Loader/DelegatingLoader.php:40
 Symfony\Component\Config\Loader\DelegatingLoader->load() at /var/www/html/vendor/symfony/framework-bundle/Routing/DelegatingLoader.php:70
 Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader->load() at /var/www/html/vendor/symfony/framework-bundle/Routing/Router.php:68
 Symfony\Bundle\FrameworkBundle\Routing\Router->getRouteCollection() at /var/www/html/vendor/symfony/routing/Router.php:361
 Symfony\Component\Routing\Router->getMatcherDumperInstance() at /var/www/html/vendor/symfony/routing/Router.php:289
 Symfony\Component\Routing\Router->Symfony\Component\Routing\{closure}() at /var/www/html/vendor/symfony/config/ResourceCheckerConfigCacheFactory.php:39
 Symfony\Component\Config\ResourceCheckerConfigCacheFactory->cache() at /var/www/html/vendor/symfony/routing/Router.php:297
 Symfony\Component\Routing\Router->getMatcher() at /var/www/html/vendor/symfony/framework-bundle/Routing/Router.php:97
 Symfony\Bundle\FrameworkBundle\Routing\Router->warmUp() at /var/www/html/vendor/shopware/storefront/Framework/Routing/Router.php:55
 Shopware\Storefront\Framework\Routing\Router->warmUp() at /var/www/html/vendor/symfony/framework-bundle/CacheWarmer/RouterCacheWarmer.php:45
 Symfony\Bundle\FrameworkBundle\CacheWarmer\RouterCacheWarmer->warmUp() at /var/www/html/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php:99
 Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate->warmUp() at /var/www/html/vendor/symfony/framework-bundle/Command/CacheClearCommand.php:244
 Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand->warmup() at /var/www/html/vendor/symfony/framework-bundle/Command/CacheClearCommand.php:156
 Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand->execute() at /var/www/html/vendor/symfony/console/Command/Command.php:298
 Symfony\Component\Console\Command\Command->run() at /var/www/html/vendor/symfony/console/Application.php:1042
 Symfony\Component\Console\Application->doRunCommand() at /var/www/html/vendor/symfony/framework-bundle/Console/Application.php:96
 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /var/www/html/vendor/symfony/console/Application.php:299
 Symfony\Component\Console\Application->doRun() at /var/www/html/vendor/symfony/framework-bundle/Console/Application.php:82
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /var/www/html/vendor/symfony/console/Application.php:171
 Symfony\Component\Console\Application->run() at /var/www/html/bin/console:77

Ich habe jetzt noch herumgetestet, mir nochmal die Beispiele angeschaut und habe nun testweise einfach den Namenspace so abgeändert, wie der Ordnerpfad ist.

Also:
Namespace: ProductDesigner\Storefront\Controller
Ordnerpfad: ProductDesigner/src/Storefront/Controller

Dies funktioniert jetzt. Warum weiß ich aber nicht. Denn im Controller-Tutorial wird auch bevor der Pluginname kommt Swag hinzugefügt: namespace Swag\BasicExample\Storefront\Controller;

1 „Gefällt mir“

Das liegt am autoload innerhalb der composer.json.

Da steht z.B.:
„autoload“: {
„psr-4“: {
„Swag\BasicExample\“: „src/“
}
},
Das heißt, dass für den Ordner „src/Controller“ der namespace „Swag/BasicExample/Controller“ ist.

Viele Grüße

1 „Gefällt mir“

Aso okay. Danke.

Ich habe dies jetzt mal getestet und den Namespace von

„psr-4“: {
„ProductDesigner\\“: „src/“
}

in

„psr-4“: {
„HP2022\\ProductDesigner\\“: „src/“
}

geändert.

Wenn ich diesen Namespace in den Controllern wieder verwende, kommt die gleiche Fehlermeldung (dass der Controller nicht gefunden werden kann).

Ich habe denselben Error gehabt.
Hier geht es um Zusammenspiel von namespace, @Route und die routes.xml
Durch basteln in diesen drei Bereichen habe ich das Problem mit Mühe gefixed.

Aber es ist eine hässliche Sache, diese Annotations, die habe ich bisher nie gesehen.

Dass viele Entwickler:innen herumprobieren (müssen?) lese ich leider viel zu oft und stoße beim Coden gerade selbst wieder auf das gleiche Dilemma.

Die Annotations sind ja Symfony-Syntax (inzwischen mit #[Route Schreibweise, aber vom Prinzip her genau so wie früher), bloß nutzen die aktuellen Symfony-Tutorials Autowiring für manches, was in Shopware üblicherweise explizit gemacht wird (gemacht werden muss/soll zwecks Performance-Optimierung?)

Dokumentation und Tutorials sind zwar inzwischen besser geworden, aber die fehlerhaften und schlecht erklärten uralten Academy-Videos sind immer noch online, und die Fehlermeldungen im Symfony Profiler sind oft auch eher missverständlich als hilfreich.