Wie komme ich an die Article SEO URL aus einem Plugin?

Hallo,

ich schreibe gerade ein Plugin, dass im REST API für die Artikel auch die SEO URL ausgibt.

Wie komme ich über die Artikel ID an die entsprechende SEO URL in einem Plugin?

Ich kann natürlich ganz knallhart in der Datenbank nachschauen, aber da gibt es doch sicher eine 
elegantere Möglichkeit, oder?

Danke und viele Grüsse

Jens

Du kannst dir den Router aus dem DI holen. Da assemblst du dir die URL via Array mit [‘sViewport’ => ‘detail’, ‘sArticle’ => $id];
Als zweiten Argument braucht der ein RoutingContext. Am Routing Context gibs Static Methoden zum erstellen

1 Like

@Shyim schrieb:

Du kannst dir den Router aus dem DI holen. Da assemblst du dir die URL via Array mit [‚sViewport‘ => ‚detail‘, ‚sArticle‘ => $id];
Als zweiten Argument braucht der ein RoutingContext. Am Routing Context gibs Static Methoden zum erstellen

 

Danke für den Hint, aber leider bin ich anscheinend zu sehr Dummy für die Antwort. :slight_smile:
Ich versuche seit 2 Stunden mithilfe der Shopware Buchs (Kapitel 16.2.2), Google und Fulltextsuche im Shopware Sourcecode Deine Antwort zu entschlüsseln, aber schaffe es nicht.
 
Ich bin jetzt soweit, dass ich folgenden Code in meine Rest API Erweiterung eingebaut habe:

 

   public function getOne($id, array $options = [])
    {
        $result = parent::getOne($id,$options);


        //get seo url
        $query = [
            'module' => 'frontend',
            'sViewport' => 'detail',
            'sArticle' => $id,
        ];

        $my_seourl = Shopware()->Router()->assemble($query);
        $result['my_seourl'] = $my_seourl;

        return $result;


    }

Ich bekomme über das API allerdings immer eine technische URL geliefert und keine SEO URL:
http://192.168.33.10/sw_pp/detail/index/sArticle/1468

Wenn ich module=frontend herausnehme, erhalte ich eine api Url.

Was kann ich machen? Muss ich einen bestimmten Context einstellen? Dazu finde ich allerdings nirgendwo irgendwelche Infos.

Danke und viele Grüsse,

Jens

Prinzipiell sieht das gut aus bei dir. Ich habe statt ‘sViewport’ ‘controller’ genutzt. Aber das müsste egal sein. Ich glaube bei dir fehlt einfach nur der Shop Context. Ich habe das letztens so gemacht:  

use Shopware\Components\Routing\Context;
use Shopware\Components\Routing\Router;

$shop = $this->modelManager->getRepository(\Shopware\Models\Shop\Shop::class)->getById($product['subshopID']);
// oder ein anderer Shop
// $this->modelManager->getRepository(\Shopware\Models\Shop\Shop::class)->getActiveDefault();
$shopContext = Context::createFromShop($shop, Shopware()->Container()->get('config'));
$routerParams = [
  'module' => 'frontend',
  'controller' => 'detail',
  'sArticle' => $product['articleID']
];

// wenn es sich um eine Variante handeln solln
//$routerParams['number'] = $product['articleordernumber'];

$url = $this->router->assemble($routerParams, $shopContext);

 

 

1 Like

@arnebecker: Vielen Dank, allerdings komme ich über Deinen Code nicht an den Shop Context.

Ich starte aus der Datei “engine\Shopware\Components\Api\Resource\Article.php” aus der Klasse “Article” in der Funktion “getOne”.

Da habe ich keine Ahnung, wie ich an $shop oder den Shopcontext kommen soll. Hätte nicht gedacht, dass es so wahnsinnig kompliziert ist, 
aus einer API Erweiterung auf die SEO Url zu gelangen.

Wenn ich Deinen Code einsetze, erhalte ich eine Fehlermeldung:
"Fatal error: Uncaught Error: Call to a member function getRepository() on null in custom/plugins/SwagExtendArticleResource/Components/Api/Resource/Article.php on line 59"
 

Irgendjemand eine Ahnung?

Hast du dir denn den modelManager über den Container geholt? Das fehlt oben in dem Beispiel ja. Müsste sowas sein:

$modelManager = $this->container->get('models');

Geht aber natürlich nur, wenn du den Container dort auch verfügbar gemacht hast. 

1 Like

OK, nochmal danke an alle, die mir geantwortet haben.

Ich habe es jetzt mit folgendem Code geschafft:

 

   public function getOne($id, array $options = [])
    {

        $result = parent::getOne($id,$options);

        //Context
        $modelManager = $this->getManager();
        $shop = $modelManager->getRepository(\Shopware\Models\Shop\Shop::class)->getById(1);
        $shopContext = Context::createFromShop($shop, Shopware()->Container()->get('config'));


        //get seo url
        $query = [
            'module' => 'frontend',
            'controller' => 'detail',
            'sArticle' => $id,
        ];

        $my_seourl = Shopware()->Router()->assemble($query, $shopContext);
        $result['my_seourl'] = $my_seourl;

        return $result;

    }

 

Wichtig ist tatsächlich der Context. Ich habe hier den Shop auf den Hauptshop mit der shopid = 1 hart eincodiert.

Vielleicht nützt diese Lösung ja jemandem.

Viele Grüsse

Jens

Hallo!

Ich weiß, dass der Beitrag schon ziemlich alt ist. Ich habe jedoch den Code in dieser Art in einem Projekt untergebracht und es hat auch alles funktioniert. Seit dem Update auf 5.7.x generiert dies leider einen Fehler:
Error message: Method „Shopware::Router“ not found failure

Hier scheint sich etwas geändert zu haben, leider konnte ich dazu jedoch im Changelog keinerlei Information finden.
Hat vielleicht jemand eine Idee, wie ich das behoben bekomme?

Danke!

Hallo @StefanSchulte

probiere mal Shopware()->Container()->get('router') statt Shopware()->Router()

Am besten wäre es natürlich den Service direkt in deine Klasse zu injecten :slight_smile:

Viele Grüße aus Schöppingen
Michael Telgmann

Hi!

Danke für die schnelle Antwort! Ich habs allerdings jetzt über Shopware()->Front()->Router() gelöst bekommen. Ich weiß nur nicht, ob das in einer Extension von der API total daneben ist…
Ist dein Weg besser?

kommt aufs gleiche hinaus :wink: