API Route zu erstellen sehr schwer, trotz Docu

Mein Versuch eine API Route in die Service Klasse des Plugin hinzufügen schlug fehl. Nach mehreren Stunden kann ich den Fehler nicht mal verstehen.

Ich habe den Shopware Beispiel aus der on-line docu streng befolgt und bekam trotzdem 500 Error, genau in der constructor’s signature der Service Klasse AddDataToPage.php.

Too few arguments to function September\Service\AddDataToPage::__construct()


Zusätzlich, mein IDE bringt mir folgede Warnung die ich nicht verstehe:
The typehint should be \September\Core\Content\Example\SalesChannel\AbstractProductCountRoute to allow decoration.

Die Anderung des Type Hints von ProductCountRoute auf AbstractProductCountRoute allein ändert nichts (daselbe 500 bleibt)

Hier die Abstract Klasse:

<?php declare(strict_types=1);

namespace September\Core\Content\Example\SalesChannel;

use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\SalesChannel\SalesChannelContext;

abstract class AbstractProductCountRoute
{
    abstract public function getDecorated(): AbstractProductCountRoute;

    abstract public function load(Criteria $criteria, SalesChannelContext $context): ProductCountRouteResponse;
}

Hier die Route Klasse die das Abstract extendet:

<?php declare(strict_types=1);

namespace September\Core\Content\Example\SalesChannel;

use OpenApi\Annotations as OA;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Plugin\Exception\DecorationPatternException;
use Shopware\Core\Framework\Routing\Annotation\Entity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\Routing\Annotation\Route;

/**
 * @Route(defaults={"_routeScope"={"store-api"}})
 */
class ProductCountRoute extends AbstractProductCountRoute
{
    protected EntityRepositoryInterface $exampleRepository;

    public function __construct(EntityRepositoryInterface $exampleRepository)
    {
        $this->exampleRepository = $exampleRepository;
    }

    public function getDecorated(): AbstractProductCountRoute
    {
        throw new DecorationPatternException(self::class);
    }

    /**
     * @Entity("swag_example")
     * @Route("/store-api/example", name="store-api.example.search", methods={"GET", "POST"})
     */
    public function load(Criteria $criteria, SalesChannelContext $context): ProductCountRouteResponse
    {
        return new ExampleRouteResponse($this->exampleRepository->search($criteria, $context->getContext()));
    }
}
1 „Gefällt mir“

AddDataToPage.php in service.xml nochmal überprüfen, ob alles richtig gemacht wurde.

Ist OK:

   <services>
        <service id="September\Service\AddDataToPage" >
            <argument type="service" id="September\Core\Content\Example\SalesChannel\ProductCountRoute"/>
            <tag name="kernel.event_subscriber" />
        </service>
    </services>

Sieht ok aus. Hast du auch den Cache geleert?

Ja. Das tue ich über admin Settings.

Noch eine Frage: die abstract Klasse wird im Constructor mit EntityRepositoryInterface initalisiert. Das steht in der Docu. Aber mein IDE zeigt EntityRepositoryInterface als deprecated. Kann es zum Problem werden? Wie machen es andere Developer?

1 „Gefällt mir“

Versuch auch Mal den Cache Ordner zu leeren.

EntityRepositoryInterface ist deprecated und wahrscheinlich mit Shopware 6.5 entfernt, siehe auch das Interface selbst an. Bis dahin sollte es keine Probleme geben.

Danke für Deine Zeit.
Cache leeren und .xml checken sind standards, die habe gemacht bevor ich Forum Message geschrieben habe.

Die Doku Seite von Shopware ist 6 Tage alt (s. Footer dort) und trotzdem empfehlen sie in den Beispielen deprecated usage von EntityRepositoryInterface
OK das ist aber ein anderes Thema.
Habe keine Ahnung wie komme ich weiter.

1 „Gefällt mir“

Autoload in der composer.json mit dem Namespace und Ordnerpfad sind richtig?

Ich weiß es nicht wie ich es prüfen kann. Der ganze Shop funktioniert (ohne Plugin) einwandfrei.
Hier der relevante Eintrag:

  "autoload": {
    "psr-4": {
      "September\\": "src/"
    }

Hallo, ich hatte das mal gemacht, aber api nicht store-api und ich hab implements AbstractController gemacht, nicht eine eigene abstrakte Klasse.

Ich will jetzt nicht den ganzen Code kopieren, aber im Grunde so:

/**
 * @Route(defaults={"_routeScope"={"api"}})
 */

class MyController extends AbstractController {

 /*
  * @Route ("/api/my-api-extension", name="api.my.extension", methods={"POST"}) 
  */
    public function my_api_extension (Request $request, Context $context) : JsonResponse {

      return new JsonResponse();
   }
}

In config/routes.xml:

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

In config/services.xml:

<service id="MyPlugin\Controller\MyController" public="true">
  <call method="setContainer">
    <argument type="service" id="service_container"/>
  </call>
</service>

Wegen EntityRepositoryInterface soll man jetzt EntityRepository verwenden. Also ich denke einfach im Constructor + protected Variable ändern, dann müsste es gehen.

1 „Gefällt mir“

Vielen Dank für Dein Feedback. Auch mit EntityRepository von DataAbstractionLayer habe ich auch probiert, leider ohne Erfolg.

Ich wollte möglichst treu den Beispiel aus der Docu folgen, weil als Anfänger soll ich nicht zu viel experimentieren. Daher habe ich Dein Code nicht übernommen. Die Dokumentation enttäuscht aber.

Manchmal hilft es, einen Neustart zu machen und von neuem anzufangen. Ich würde dir empfehlen die Dokumentation von neu zu beginnen und dabei auch die von Shopware empfohlenen Konventionen einzuhalten, z. B. Plugin Präfix (könnte bei dir z. B. Iteam sein).

Ansonsten versuch doch manuell den Cache Ordner zu leeren.

du musst das EntityRepositoryInterface als Argument in der service.xml angeben, das besagt auch deine Fehlermeldung

„too few arguments, 1 expected“

allerdings ist auch das nicht zwingend notwendig, da der Controller Zugriff auf $this->container haben sollte. Das Container Objekt lässt dich wiederrum auf verschiedenste Daten zugreifen, bspw. Repos über die DAL abzurufen.

1 „Gefällt mir“

Wertvoller Hinweis, danke. Zwar habe ich schon den plugin auf dem Server gelöscht, werde aber aus backup reaktivieren.

1 „Gefällt mir“

Hallo @iteam , haben Sie eine Lösung gefunden? Ich habe hier ein ähnliches Problem mit Beispielen aus der offiziellen Shopware 6 Dokumentation:

„Too few arguments to function March\Core\Content\Example\SalesChannel\ProductCountRoute::__construct(), 0 passed in /chroot/home/…/…/html/vendor/shopware/core/Framework/DependencyInjection/CompilerPass/EntityCompilerPass.php on line 50 and exactly 1 expected“

Lösung nicht gefunden, sorry. Wir haben dann nicht weiter gemacht.

Kann vielleicht jemand vom Shopware-Team helfen?

Ich habe mehrmals versucht, es zu implementieren, habe schon zwei Wochen lang gegoogelt und kann es immer noch nicht mit dieser Dokumentation zum Funktionieren bringen:

Ich kann nicht weitermachen, weil dieser Fehler auftritt:
„Too few arguments to function CustomFilter\Core\Content\Example\SalesChannel\ProductCountRoute::__construct(), 0 passed in /chroot/home/domain.de/html/vendor/shopware/core/Framework/DependencyInjection/CompilerPass/EntityCompilerPass.php on line 50 and exactly 1 expected“

Dieses Tutorial funktioniert gut (ich habe es bis zum Caching fertiggestellt), aber es hat eine etwas andere Struktur und ich konnte es nicht mit einem früheren Tutorial verbinden:

Wie können wir das lösen?

Deine __construct hat kein Argument. Du musst ein Argument mit übergeben, wie in dem verlinkten Beispiel der Fall; natürlich auf deine Werte angepasst:

public function __construct(AbstractExampleRoute $route)
    {
        $this->route = $route;
    }
1 „Gefällt mir“

Danke @Max_Shop , hier ist, was ich für der Klasse habe:

class ProductCountRoute extends AbstractProductCountRoute
{
    protected EntityRepository $productRepository;

    public function __construct(EntityRepository $productRepository)
    {
        $this->productRepository = $productRepository;
    }

und ich route ihn so, aber er kommt nicht an:

<service id="CustomFilter\Service\AddDataToPage" >
    <argument type="service" id="CustomFilter\Core\Content\Example\SalesChannel\ProductCountRoute"/>
    <tag name="kernel.event_subscriber" />
</service>

<service id="CustomFilter\Core\Content\Example\SalesChannel\ProductCountRoute">
    <argument type="service" id="product.repository"/>
    <tag name="shopware.entity.definition" entity="swag_get_active_product_count" />
</service>

Wieso taggst du die Route denn als shopware.entity.definition?
Nimm das mal raus.

1 „Gefällt mir“