Hallo zusammen,
ich bin seit ein paar Wochen dabei, alle meine Contao 4 Erweiterungen in 5er Bundles umzuschreiben. Bei den meisten hat das zum Glück recht gut funktioniert, nun hänge ich aber schon seit Tagen an einem eigentlich simplen Problem: Eine Ajax-Ausgabe von Produkten auf einem Merkzettel, die im Local Storage gespeichert sind.
Dazu habe ich einen NotepadController als Content Element angelegt, der das Template ausgibt. Beim Aufruf der Seite sollen nun per Ajax die vom Besucher ausgewählten Produkte geladen werden. Die Abfrage erfolgt auf die URL /_ajax/notepad, die ich in einem NotepadAjax Controller als Route definiert habe. Dabei werden die Produkt-IDs und das aktuelle Token mit übergeben.
Mein Problem ist aktuell, dass ich dabei das Contao Framework nicht korrekt initialisiert bekomme.
Hier erst mal mein Code:
Code:
# config/services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
App\ContaoProductsBundle\:
resource: ../src/
exclude: ../src/{Cron,DependencyInjection,Model,Session}
App\ContaoProductsBundle\Controller\NotepadAjax:
public: true
arguments:
- '@contao.framework'
- '@database_connection'
- '@contao.csrf.token_manager'
- '%contao.csrf_token_name%'
tags:
- controller.service_arguments
PHP-Code:
# src/Controller/NotepadAjax.php
namespace App\ContaoProductsBundle\Controller;
use App\ContaoProductsBundle\Model\ProductsModel;
use App\ContaoProductsBundle\Controller\ContentElement\NotepadController;
use Contao\CoreBundle\Csrf\ContaoCsrfTokenManager;
use Contao\CoreBundle\Framework\ContaoFramework;
use Contao\FilesModel;
use Contao\Input;
use Contao\StringUtil;
use Contao\System;
use Doctrine\DBAL\Connection;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Csrf\CsrfToken;
class NotepadAjax extends AbstractController
{
public function __construct(
private readonly ContaoFramework $framework,
private readonly Connection $connection,
private readonly ContaoCsrfTokenManager $tokenManager,
private readonly string $csrfTokenName,
) {
}
#[Route('/_ajax/notepad', name: 'app_contao_products_ajax_notepad', defaults: ['_token_check' => true])]
public function notepadajax(Request $request): Response
{
if (!isset($_POST['token']))
{
return new Response('');
}
// Token prüfen
$isTokenValid = $this->tokenManager->isTokenValid(new CsrfToken($this->csrfTokenName, $_POST['token']));
if (!$isTokenValid || $_SERVER['REQUEST_METHOD'] != 'POST' || !$request->isXmlHttpRequest())
{
return new Response('');
}
...
Erst hatte ich versucht, weitere Daten aus dem NotepadController zu holen:
PHP-Code:
$notepad = new NotepadController();
$return = $notepad->getNotepadData();
return new Response($return);
Hierbei kommt aber die Fehlermeldung:
The Symfony container is not available, did you initialize the Contao framework?
Bei Verwendung eines Models, kommt folgende Fehlermeldung:
There is no class for table "tl_files" registered in $GLOBALS['TL_MODELS']
Bei Verwendung von $rootDir = System::getContainer()->getParameter('kernel.project_dir'); gibt das System
Call to a member function getParameter() on null aus.
Versuche ich das Framework mit $this->framework->initialize(); zu initialisieren, kommt:
The "security.csrf.token_manager" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.
Einfach Datenbankabfragen per $objData = $this->connection->executeQuery("SELECT * FROM..."); funktionieren hingegen.
Wo liegt mein Fehler oder gibt es eine andere Möglichkeit, das umzusetzen? Vielleicht auch gleich direkt im NotepadController, von dem ich eh noch weitere Daten benötige.
Ich bin für jeden Tipp dankbar!
Gruß Tim