to slash or not to slash...

wie können wir in eine plugin testen ob eine url existiert in shopware?

ich sollte eine shopware plugin schreiben was prüft ob die request url doch mit oder ohne slash existiert, und wenn ja, 301 weiterleiten…

 $request-\>getRequestUri() ?

@waldicom schrieb:

$request->getRequestUri() ?

jou, damit bekommen wir die url von request.
aber ich möchte testen ob eine url in shopware existiert.

sagen wir mal der request hat folgende url:
/some/cat/some-article/

diese verursacht in shopware eine exception, bzw 404 (weil artikel detail seiten nicht in slash enden) und landet in
Shopware_Controllers_Frontend_Error

in Shopware_Controllers_Frontend_Error::preDispatch::before möchte ich dann testen ob /some/cat/some-article (ohne slash) existiert, und wenn ja, weiterleiten.

(und das selbe für wenn request url ohne slash ist, ob es mit slash existiert. zbs. kategorie listing)

 

Eine Möglichkeit wäre direkt in der Datenbank nachschauen, in der Tabelle s_core_rewrite_urls, im Feld path. In der Tabelle stehe alle SEO URLs, die Shopware generiert.   

Hallo,

ohne das ausprobiert zu haben…

Hier ist der Routing-Vorgang beschrieben: The Shopware SEO engine

Es gibt einen (bzw. mehrere) Matcher, die testen, ob es eine URL gibt. Du müsstest dir also bloß die entsprechenden Services aus dem Container holen und mit dem Matcher testen.

Ich habe gesehen, dass der Router selbst auch eine match-Methode hat - vielleicht kannst du dir auch einfach den Router-Service aus dem Container ziehen und dort testen (dann musst du evtl. nicht wissen, welchen Matcher-Service du brauchst).

Grüße,
Sven

 

1 „Gefällt mir“

@hec schrieb:

Ich habe gesehen, dass der Router selbst auch eine match-Methode hat - vielleicht kannst du dir auch einfach den Router-Service aus dem Container ziehen und dort testen (dann musst du evtl. nicht wissen, welchen Matcher-Service du brauchst).

danke für denn tip!

für url „/this/path/does/not/exist“ bekommen ich diese antwort:

array(5) {
  ["module"]=>
  string(8) "frontend"
  ["controller"]=>
  string(4) "this"
  ["action"]=>
  string(4) "path"
  ["does"]=>
  string(3) "not"
  ["exist"]=>
  string(0) ""
}

also prüft Shopware()->Router()->match($url) methode anscheinend nicht ob ein url existiert, sondern generiert einfach ne array für egal welche url. (wir sind noch auf sw5.1.x, ich frage mich ob sw5.2.x das gleiche antwortet)

jetzt müsste ich wohl testen ob die module/controller/action von diese array existiert…

oder wenn ich mit echten daten teste:

/bodenbelaege/parkett/landhausdiele
array(4) {
  ["module"]=>
  string(8) "frontend"
  ["controller"]=>
  string(12) "bodenbelaege"
  ["action"]=>
  string(7) "parkett"
  ["landhausdiele"]=>
  string(0) ""
}

/bodenbelaege/parkett/landhausdiele/
array(5) {
  ["module"]=>
  string(8) "frontend"
  ["controller"]=>
  string(3) "cat"
  ["action"]=>
  string(5) "index"
  ["sCategory"]=>
  string(3) "101"
  ["rewriteUrl"]=>
  bool(true)
}

könnte ich vielleicht einfach testen wenn $match[„controller“] ist gleich wie die erste pfad node in url, existiert diese url nicht…

 

diese scheint zu funktionieren…

public function install ()
{
	$this->subscribeEvent(
		'Shopware_Controllers_Frontend_Error::preDispatch::before',
		'checkUrlSlash'
	);
	return true;
}

public function checkUrlSlash (Enlight_Hook_HookArgs $args)
{
	$sub = $args->getSubject();
	$url = $sub->Request()->getRequestUri();

	if (preg_match("/\/$/", $url)) {
		$url = rtrim($url, "/");
	} else {
		$url .= "/";
	}

	if(preg_match("/^\/([^\/]+)/", $url, $match) == 1) {
		$firstPathNode = $match[1];
		$routeThing = Shopware()->Router()->match($url);
		if ($routeThing["controller"] != $firstPathNode) {
			return $sub->redirect($url, ['code' => 301]);
		}
	}
}

 

Auf mich wirkt das so, als ob du um ein Fehlverhalten des Shopware-Cores drumherum-programmiert hast :wink:

Ich verstehe die Dokumentation so, dass

Shopware()->Router()->match($url)

false zurückliefern müsste, wenn es für die URL keine Route gibt.

[@Daniel Nögel](http://forum.shopware.com/profile/4010/Daniel Nögel „Daniel Nögel“)‍ Kannst du (als Autor von https://developers.shopware.com/blog/2015/08/11/the-shopware-seo-engine/#routing ) vielleicht was dazu sagen?

Danke und Grüße,
Sven

Hi,

ja, „match“ liefert ein Array mit module/controller/action und weiteren Params zurück, wenn die Route existiert verarbeitet werden kann - und ansonsten „false“. Allerdings ist der DefaultMatcher sehr tolerant, da geht es nicht um „die Route ist aufrufbar und valide“, sondern um „die Route entspricht dem erwarteten Format“. Für dieses Szenario also vermutlich nicht ganz passend. 

Ich denke, ich würde an eurer Stelle einfach einen Query auf die s_core_rewrite_urls machen - da muss es für den aktuellen Shop ja einen „path“ geben, der mit/ohne Slash dem aktuellen Pfad entspricht:

Das wäre einen Versuch wert, denke ich. Alternativ könnte man auch direkt mit dem Event- und dem RewriteMatcher arbeiten und dort die „match“ Methode nutzen.

Grundsätzlich ist vll. die Frage, ob das ein permanentes Problem im Shop ist - oder „nur“ eine Anforderung / ein seltener Sonderfall? Wenn die URLs korrekt indexiert sind, sollte es ja keine falschen Aufrufe geben (außer händische). Wenn ihr wiederum bestimmte Routen habt, die immer wieder von Hand falsch eingegeben werden, könnte man auch überlegen, dafür einen Controller anzulegen - das ist etwas weniger elegant, aber bei Controllern greift der DefaultMatcher und ist weniger picky hinsichtlich slash / kein Slash. 

Daniel

1 „Gefällt mir“

super, noch mehr hart-kodierte sql abfragen…

@Daniel Nögel schrieb:

Grundsätzlich ist vll. die Frage, ob das ein permanentes Problem im Shop ist

Unsere problem ist das Shopware hat manche URLs mit slash am ende, und manche nicht. Und unsere SEO mensch hat gemeint es gibt mehrere 404 in seine statistik, weil der request eine slash (oder nicht) am ende der URL hatte. (Konnte aber nicht sagen von wo diese requests kommen)

Ich denke das beste wäre wenn Shopware einfach keine URLs mit slash am ende hätte, dann könnten wir einfach mit apache alle URLs mit slash am ende weiterleiten.

Was ist die use-case in Shopware für URLs die mit slash enden?

@wontfix schrieb:

super, noch mehr hart-kodierte sql abfragen…

 

wenn du das System erweitern möchtest, musst du bisweilen SQL-Abfragen schreiben. Auch das Aufrufen des Matchers löst verschiedene SQL-Queries aus, die liegen nur im Service versteckt. Da kann ein expliziter, optimierter Query für deinen Fall sehr viel sinnvoller sein. Sowas wie „hartkodierte SQL-Abfrage“ ist ja technisch erstmal kein Argument, wenn es erforderlich ist. 

Daniel

 

@wontfix schrieb:

Ich denke das beste wäre wenn Shopware einfach keine URLs mit slash am ende hätte, dann könnten wir einfach mit apache alle URLs mit slash am ende weiterleiten.

Was ist die use-case in Shopware für URLs die mit slash enden?

Typischerweise enden die URLs der Kategorien-Seiten auf einen Slash.

Das kannst du aber in den Grundeinstellungen einstellen, vgl. auch
SEO Weiterleitung ohne Slash auf mit Slash - Administration - Shopware Community Forum
http://community.shopware.com/SEO-Router-Einstellungen\_detail\_912.html

Grüße,
Sven

1 „Gefällt mir“

@hec schrieb:

@wontfix schrieb:

Ich denke das beste wäre wenn Shopware einfach keine URLs mit slash am ende hätte, dann könnten wir einfach mit apache alle URLs mit slash am ende weiterleiten.

Was ist die use-case in Shopware für URLs die mit slash enden?

Typischerweise enden die URLs der Kategorien-Seiten auf einen Slash.

Das kannst du aber in den Grundeinstellungen einstellen, vgl. auch
https://forum.shopware.com/discussion/28017/seo-weiterleitung-ohne-slash-auf-mit-slash
http://community.shopware.com/SEO-Router-Einstellungen_detail_912.html

WOW! und ich kriege hier eine auftrag ne plugin zu schreiben wenn es einfach ne backend/datenbank einstellung ist…

@Daniel Nögel schrieb:

[…] Alternativ könnte man auch direkt mit dem Event- und dem RewriteMatcher arbeiten und dort die „match“ Methode nutzen.

Grundsätzlich ist vll. die Frage, ob das ein permanentes Problem im Shop ist - oder „nur“ eine Anforderung / ein seltener Sonderfall? Wenn die URLs korrekt indexiert sind, sollte es ja keine falschen Aufrufe geben (außer händische).  […]

Danke für deine sehr ausführliche Beschreibung.

Ob es ein permanentes Problem ist, kann ich nicht beurteilen - gefühlt kommt die Frage nach Slashes am Ende von Kategorie-URLs öfters hier im Forum. Und das Ticket dazu (Shopware Issuetracker) hat immerhin schon 13 Votes.

Ich mag auch keine eigenen SQL Queries, wenn der Core bereits Klassen zur Verfügung stellt, die diese abdecken (und meine Query wäre ja letzten Endes auch ähnlich zu der, die aktuell bereits im RewriteMatcher steht) - ich fühle mich dann bei Updates deutlich wohler.

Am elegansten fände ich es wohl, den RewriteMatcher zu nutzen oder zu dekorieren. Aktuell ist er kein Service aus dem DIC -  @Daniel Nögel‍ spricht aus deiner Sicht etwas dagegen, ihn als solchen aufzunehmen? Wenn nein, könnte ich einen PR vorbereiten.

Grüße,
Sven
 

@wontfix schrieb:

WOW! und ich kriege hier eine auftrag ne plugin zu schreiben wenn es einfach ne backend/datenbank einstellung ist…

Du wolltest doch ein Plugin schreiben und hast eine Frage im Programmier-Bereich aufgemacht. Wenn du fragst, wie du ein Auto bauen kannst, erkläre ich dir das - und erkläre dir nicht, dass es auch Busse gibt :). Die Eingangsfrage war ja, wie du rausfinden kannst, ob es ähnliche Route mit / ohne Slash gibt - und nicht, wie man von Slash auf Nicht-Slash umstellt?

@hec schrieb:

Am elegansten fände ich es wohl, den RewriteMatcher zu nutzen oder zu dekorieren. Aktuell ist er kein Service aus dem DIC -  @Daniel Nögel‍ spricht aus deiner Sicht etwas dagegen, ihn als solchen aufzunehmen? Wenn nein, könnte ich einen PR vorbereiten.

Fände ich sehr cool, bin ich auch schon drüber gestolpert! 

@Daniel Nögel schrieb:

@wontfix schrieb:

WOW! und ich kriege hier eine auftrag ne plugin zu schreiben wenn es einfach ne backend/datenbank einstellung ist…

Du wolltest doch ein Plugin schreiben und hast eine Frage im Programmier-Bereich aufgemacht. Wenn du fragst, wie du ein Auto bauen kannst, erkläre ich dir das - und erkläre dir nicht, dass es auch Busse gibt :). Die Eingangsfrage war ja, wie du rausfinden kannst, ob es ähnliche Route mit / ohne Slash gibt - und nicht, wie man von Slash auf Nicht-Slash umstellt?

 

jou, das weiterleiten in shopware habe ich schon vorher herausgefunden, daher die frage für nur zum testen ob eine url in shopware existiert…

aber die original frage war weil ich dachte das shopware hat manche seine urls hardkodiert mit slash am ende, und nun stellte sich heraus das in backend (was ich persönlich nicht benutze) kann man mindestens die seo urls anpassen, und unsere (oder default) ist/war kategorien und hersteller seiten mit slash am ende.

und wenn diese jetzt die einzigen sind wo shopware urls mit slash am ende hat (wir ignorieren mal /backend/), kann ich das ursprungs problem mit einfache apache regel lösen:

RewriteCond %{REQUEST_URI} !^/backend/
RewriteRule ^(.+)/$ /$1 [L,R=301]

daher, die hoffentlich letzte frage zu diesen thema:
gibts in shopware frontend urls die mit slash enden?

ps. ach so und das „wow“ kommentar war nicht für euch gezielt (hab ja auch nicht von euch diesen auftrag), sondern für unsere marketing/seo leute. sorry for the noise!

@Daniel Nögel schrieb:

@hec schrieb:

Am elegansten fände ich es wohl, den RewriteMatcher zu nutzen oder zu dekorieren. Aktuell ist er kein Service aus dem DIC -  @Daniel Nögel‍ spricht aus deiner Sicht etwas dagegen, ihn als solchen aufzunehmen? Wenn nein, könnte ich einen PR vorbereiten.

Fände ich sehr cool, bin ich auch schon drüber gestolpert! 

Pull Request siehe ProductListingPriceIndexer causes n+1 db requests · Issue #691 · shopware/shopware · GitHub