Ergebnis 1 bis 6 von 6

Thema: Symfony 4 - Controller-Implementierung für Contao

  1. #1
    Contao-Nutzer
    Registriert seit
    26.07.2016.
    Beiträge
    47

    Standard Symfony 4 - Controller-Implementierung für Contao

    Moin,

    ich bin derzeit dabei ein Symfony-Projekt mit einem Contao aufzusetzen und stoße leider immer wieder auf Probleme.
    Auch nach längerer Recherche finde ich keine wirklichen Antworten zu meinen Fragen.

    Kurz zum Projekt:
    In dem Projekt sollen einige statische Inhalte mit Contao angezeigt werden, aber ebenso sollen auch einige Aufgaben im Symfony Backend geschehen.
    Insbesondere sollen einige Auswertungen und die Datenhaltung (neben den Contao DB-Tabellen) mit Symfony umgesetzt.

    Ich mache das Projekt mit einem Partner, er arbeitet seit Jahren mit Contao, ich seit Jahren mit Symfony....man könnte meinen dass es ja dann ein Leichtes sein sollte
    Das Projekt an sich habe ich aufgesetzt und soweit läuft auch alles. Hierzu hatten wir neulich schon mal ein paar andere Fragen und wir haben tolle Hilfe in diesem Forum bekommen.
    Hoffentlich kann uns wieder jemand Rat geben.

    1. Backend-Controller:
    Ich habe hierzu ein schönes Beispiel gefunden, komme hier aber nicht zu dem was wir eigentlich erreichen wollen.
    Den Backend-Controller habe ich implementiert und auch ins Contao-Menü eingebaut. Hier der Code:
    PHP-Code:
    namespace App\Controller;

    use 
    Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use 
    Symfony\Component\Routing\Annotation\Route;
    use 
    Symfony\Component\HttpFoundation\Response;
    use 
    Twig\Environment as TwigEnvironment;

    /**
     * @Route("/contao/my-backend-route",
     *     name=BackendController::class,
     *     defaults={"_scope" = "backend"}
     * )
     */
    class BackendController extends AbstractController
    {
        private 
    $twig;

        public function 
    __construct(TwigEnvironment $twig)
        {
            
    $this->twig $twig;
        }

        public function 
    __invoke(): Response
        
    {
            return new 
    Response($this->twig->render(
                
    'my_backend_route.html.twig',
                []
            ));
        }

    In diesem BackendModul sollen Daten verwaltet / angelegt / editiert werden. Leider reicht hier der Catalog-Manager nicht mehr aus.
    Nun hatte ich mir das so vorgestellt, dass es eine Route für das Modul an sich gibt, und dazu noch weitere Routen für Useraktionen (oder vielleicht auch in einem anderen Controller).
    In diesem Beispiel ist jedoch ein Controller mit "invoke()"-Methode (ADR-Pattern), wodurch natürlich nur eine Aktion zur Verfügung habe.
    Wenn ich den Controller dann ohne "invoke" mit mehreren Methoden, die eigene Route-Annotations haben, umbaue, funktioniert es nicht
    und ich bekomme einen Fehler. Ich habe mir das in etwa so vorgestellt:

    PHP-Code:
    namespace App\Controller;

    use 
    Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use 
    Symfony\Component\Routing\Annotation\Route;
    use 
    Symfony\Component\HttpFoundation\Response;
    use 
    Twig\Environment as TwigEnvironment;

    /**
     * @Route("/contao/my-backend-route",
     *     name=BackendController::class,
     *     defaults={"_scope" = "backend"}
     * )
     */
    class BackendController extends AbstractController
    {
        
    /**
         * @Route("/", name="test_test")
         */
        
    public function test()
        {
            return 
    $this->render('my_backend_route.html.twig',[]);
        }

        
    /**
         * @Route("/irgendwas", name="test_test2")
         */
        
    public function test2()
        {
            
    // Do sth else
        
    }

    Leider bekomme ich dann folgende Fehlermeldung:
    "An exception has been thrown during the rendering of a template ("None of the chained routers were able to generate route: Route 'App\Controller\BackendController' not found")."

    Gibt es hier die Möglichkeit auch "herkömmliche" Symfony-Controller mit mehreren Routen zu verwenden und wenn ja wie?
    Habe irgendwo gelesen, dass das möglich ist...


    2. Frontend-Controller:

    Auch hier möchte ich, dass ich einen Controller habe, welcher mehrere Routes verarbeiten kann (kein invoke).
    Mein Controller sieht nun so aus:
    PHP-Code:
    namespace App\Controller;

    use 
    Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use 
    Symfony\Component\Routing\Annotation\Route;
    use 
    Symfony\Component\HttpFoundation\Response;
    use 
    Twig\Environment as TwigEnvironment;

    /**
     * @Route("/my-front-route",
     *     name=FrontendController::class,
     *     defaults={"_scope" = "frontend"}
     * )
     */
    class FrontendController extends AbstractController
    {
        private 
    $twig;

        public function 
    __construct(TwigEnvironment $twig)
        {
            
    $this->twig $twig;
        }

        public function 
    __invoke(): Response
        
    {
            
    $res $this->twig->render(
                
    'test.html.twig',
                []
            );

            return new 
    Response($res);
        }


    Leider weiss ich nicht genau, wie ich den Aufruf der Route in Contao einbinde. Ich habe es mit einem Template probiert, welches ich in einen Artikel eingebunden habe.
    In diesem Template führe ich lediglich ein "file_get_contents" mit der Route aus.
    Auf meinem lokalen Server bekomme ich folgende ErrorException: "Warning: file_get_contents(http://localhost:8000/my-front-route): failed to open stream: HTTP request failed!"
    Für jegliche andere URL (z.B. Google) funktioniert es. Die Route an sich funktioniert und ich sehe den Inhalt meines Templates, wenn ich die Route direkt im Browser aufrufe.
    Der Aufruf funktioniert nur anscheinend nicht aus Contao heraus. Wo liegt das Problem, CORS oder irgendetwas anderes Contao-spezifisches?

  2. #2
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.237
    Partner-ID
    10107

    Standard

    Zitat Zitat von buddy274 Beitrag anzeigen
    Leider bekomme ich dann folgende Fehlermeldung:
    "An exception has been thrown during the rendering of a template ("None of the chained routers were able to generate route: Route 'App\Controller\BackendController' not found")."
    Nachdem du jetzt das ADR pattern nicht mehr benutzt, gibt es auch diese Route nicht mehr. Du musst den richtigen Route Namen verwenden.

  3. #3
    Contao-Nutzer
    Registriert seit
    26.07.2016.
    Beiträge
    47

    Standard

    Hi Spooky,

    danke für deine Antwort. Leider verstehe ich nicht ganz was du meinst.
    In der Annotation des Controllers ist doch die Route definiert für diesen Controller (@Route("/contao/my-backend-route"....).

    Was meinst du genau mit dem richtigen Route Namen?
    Und hast du eventuelle auch ne Idee, warum ich meine Frontend-Route von überall aufrufen kann, nur nicht aus Contao?
    Geändert von buddy274 (05.11.2020 um 17:28 Uhr)

  4. #4
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.237
    Partner-ID
    10107

    Standard

    Zitat Zitat von buddy274 Beitrag anzeigen
    danke für deine Antwort. Leider verstehe ich nicht ganz was du meinst.
    In der Annotation des Controllers ist doch die Route definiert für diesen Controller (@Route("/contao/my-backend-route"....).
    Ja, das ist der Pfad der Route. Du hast insgesamt folgendes geschrieben:
    PHP-Code:
    /**
     * @Route("/contao/my-backend-route",
     *     name=BackendController::class,
     *     defaults={"_scope" = "backend"}
     * )
     */
    class BackendController extends AbstractController
    {
        
    /**
         * @Route("/", name="test_test")
         */
        
    public function test()
        {
            return 
    $this->render('my_backend_route.html.twig',[]);
        }

        
    /**
         * @Route("/irgendwas", name="test_test2")
         */
        
    public function test2()
        {
            
    // Do sth else
        
    }

    Du hast also einen Controller gemacht, dessen Route Prefix "/contao/my-backend-route" lautet. Du hast dem Controller auch einen Route Namen vergeben, nämlich "App\Controller\BackendController", der jedoch überflüssig ist, da der Controller selbst keine endgültige Route ist. Du hast weiters zwei Routes in diesem Controller definiert, einmal mit dem Pfad "/" (also insgesamt "/contao/my-backend-route/") und dem Namen "test_test" und einmal mit dem Pfad "/irgendwas" (also insgesamt "/contao/my-backend-route/irgendwas") und dem Namen "test_test2".

    Laut Fehlermeldung versuchst du nun die URL zu einer Route mit dem Namen "App\Controller\BackendController" zu generieren. Solch eine Route existiert aber nicht. Es existieren in deinem Controller nur Routes mit dem Namen "test_test" und "test_test2".

  5. #5
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.237
    Partner-ID
    10107

    Standard

    Zitat Zitat von buddy274 Beitrag anzeigen
    Und hast du eventuelle auch ne Idee, warum ich meine Frontend-Route von überall aufrufen kann, nur nicht aus Contao?
    Es ist besser, wenn du ein Problem nach dem anderen behandlest und nicht zwei verschiedenen Probleme in einem Thread mischst. Wenn erfordlich öffne einen separaten Thread zu diesem separaten Problem und beschreibe dein Vorhaben und das Problem dort genau.

  6. #6
    Contao-Nutzer
    Registriert seit
    26.07.2016.
    Beiträge
    47

    Standard

    Ok, ich werde noch einen separaten Thread dazu machen.

    Alles klar, nun verstehe ich auch die Fehlermeldung
    Ich hatte in dem Beispiel noch folgenden MenuListener gesehen und implementiert.
    Der hat dann letztendlich wohl auch den Fehler geworfen....

    PHP-Code:
    amespace App\EventListener;

    use 
    App\Controller\BackendController;
    use 
    Contao\CoreBundle\Event\MenuEvent;
    use 
    Symfony\Component\HttpFoundation\RequestStack;
    use 
    Symfony\Component\Routing\RouterInterface;
    use 
    Terminal42\ServiceAnnotationBundle\Annotation\ServiceTag;

    /**
     * @ServiceTag("kernel.event_listener", event="contao.backend_menu_build", priority=-255)
     */
    class BackendMenuListener
    {
        protected 
    $router;
        protected 
    $requestStack;

        public function 
    __construct(RouterInterface $routerRequestStack $requestStack)
        {
            
    $this->router $router;
            
    $this->requestStack $requestStack;
        }

        public function 
    __invoke(MenuEvent $event): void
        
    {
            
    $factory $event->getFactory();
            
    $tree $event->getTree();

            if (
    'mainMenu' !== $tree->getName()) {
                return;
            }

            
    $contentNode $tree->getChild('data');

            
    $node $factory
                
    ->createItem('my-module')
                ->
    setUri($this->router->generate(BackendController::class))
                ->
    setLabel('My Modules')
                ->
    setLinkAttribute('title''Title')
                ->
    setLinkAttribute('class''my-module')
                ->
    setCurrent($this->requestStack->getCurrentRequest()->get('_controller') === BackendController::class)
            ;

            
    $contentNode->addChild($node);
        }

    Nun habe ich hier die Route nochmal angepasst (setUri($this->router->generate('test_test))) und es geht
    Hab ich gar nicht mehr dran gedacht...nun ja, irgendwann sieht man auch nicht mehr so klar, wenn nichts funktionieren will.

    Du warst mir jetzt schon das zweite Mal eine große Hilfe, vielen Dank dafür!!!

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •