Fehlerbeschreibung

Schon in früheren Versionen mind. 1.1.3 und aktuell einschließlich Version 1.1.9 tritt bei VirtueMart nach wie vor ein Fehler auf, sobald man über die Produkt-Page-Navigation (vorheriges / nächstes Produkt) oberhalb der Produktdetailanzeige klickt. Der Fehler äußert sich in drei Symptomen:

  1. Auffällig ist besonders, dass im Shopmenü die vorher gewählte, nun aktuelle Kategorie plözlich nicht mehr als aktiv angezeigt wird - abhängig von Menütyp (muss also bei reinen JavaScriptMenüs nicht auftreten - ich nutze eine Art Mod-Mainmenü für die Kategorien).
  2. Wenn man z.B. einer Kategorie eine eigenen oder von der Standard flypage abweichende Flypage zugewiesen hat, wird diese plötzlich nicht mehr verwendet, das Design wechselt unerwartet und unerwünscht zur Standard-Flypage.
  3. Arbeitet man mit Child-Artikeln wird bei Auswahl eines Childartikels auf der Produktdetailseite plötzlich ebenfalls nicht mehr die korrekte Flypage zu Anzeige verwendet.

Fraglich ist, warum die Entwickler diesen Fehler seit vielen Versionen nicht korrigieren.



Fehlerursache

Für alle drei oben beschriebenen Fehler gibt es ein und den gleichen Grund oder Bug, der sich entsprechend auswirkt. Bei allen Links die wie oben beschrieben aufgerufen werden, fehlt in der URL der GET-Parameter für die catergory_id. Wurde schlicht und ergeifend vergessen.

Im ersten Fall (Pagenavigation) wird diese mit den beiden Links ohne Kategorie-ID aufgerufen. Folglich passiert folgendes. VM fehlt die Infos zur Katerorie beim Aufbau der aufgerufenen Seite und kann folglich die der Kategorie in der Konfiguration zugewiesene Flypage nicht ermitteln und verwendet dann ersatzweise die Standard-Flypage.

Für den zweiten Fall, erhält auch das Menü nicht die Information welche Kategorie aktuell ist und kann das current-Menüelement nicht aktivieren/kennzeichnen.

Bei der aufgebauten Detailseite kann die Childartikel-Selektionsliste ebenfalls nicht korrekt aufgebaut werden, weshalb bei einer hier getätigten Auswahl dann ebenfalls oben beschriebenes Fehlerverhalten mit der Ersatz-Flypage auftritt.

Fehlerbehebung

Diese ist eigentlich reicht einfach, wenn weiss was die Ursache ist und welches Script zu beackern ist. Leider betrittt dieser Bug ein Core-Script. Es ist also damit zu rechnen, dass hier vorgenommene Korrekturen mit nächsten Upgrades von VM wieder überschrieben werden.

Also konkret: Der Bugfix betrifft das Script html/shop.product_details.php. Ca. Zeile 171 werden die neighbor-Links zusammengebaut und hierbei vergessen dem Link folgende Sequenz beizufügen: '&category_id='.$category_id.. Das machen wir einfach mal an den beiden notw. Stellen:

html/shop.product_details.php
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
if( !empty($next_product) ) {
 $url_parameters = 'page=shop.product_details&product_id='.$next_product['product_id'].'&flypage='.$ps_product->get_flypage($next_product['product_id']).'&category_id='.$category_id.'&pop='.$pop;
 if( $manufacturer_id ) {
 $url_parameters .= "&manufacturer_id=" . $manufacturer_id;
 }
 if( $keyword != '') {
 $url_parameters .= "&keyword=".urlencode($keyword);
 }
 if( $pop == 1 ) {
 $next_product_url = $sess->url( $_SERVER['PHP_SELF'].'?'.$url_parameters );
 } else {
 $next_product_url = str_replace("index2","index",$sess->url( $url_parameters ));
 }
}
if( !empty($previous_product) ) {
 $url_parameters = 'page=shop.product_details&product_id='.$previous_product['product_id'].'&flypage='.$ps_product->get_flypage($previous_product['product_id']).'&category_id='.$category_id.'&pop='.$pop;
 if( $manufacturer_id ) {
 $url_parameters .= "&manufacturer_id=" . $manufacturer_id;
 }
 if( $keyword != '') {
 $url_parameters .= "&keyword=".urlencode($keyword);
 }
 if( $pop == 1 ) {
 $previous_product_url = $sess->url( $_SERVER['PHP_SELF'].'?'.$url_parameters );
 } else {
 $previous_product_url = str_replace("index2","index",$sess->url( $url_parameters ));
 }
}
 

Prinzipiell wäre dieser Fehler übrigens nicht schlimm, weil wenn im Script die Kategorie-ID nicht bekannt ist, diese hier vorab neu ermittelt würde und damit eigentlich zur Verfügung stehen müsste. Gleiches trifft zu für die Flypage. Auch diese wird wenn nicht als Parameter übergeben im gleichen Script neu ermittelt.

Ein Tücke besteht noch,

die einem das Leben beim Testen schwer macht: Wenn eine Flypage nicht bekannt ist, wird diese für das Produkt neu ermittelt. Dabei wird die Method get_flypage() aus der ps.product.php verwendet. Diese schaut immer zuerst nach, ob in der Session schon mal eine Flypage für dieses Produkt abgelegt wurde und holt die Flypage nur, wenn das nicht so ist. Haben Sie hier also aus vorangegegangenen Tests schon eine gespeichert, werden sich ihre Kategorie-Flypage-Änderungen beharlich nicht auswirken ... das könnte einen verzweifeln lassen. Man müßte also zunächst die Session säubern. Man könnte das einfach bewirken, in dem man in die Methode get_flypage() als erste Zeile folgendes temporär einfügt:

ps.product.php
1176
1177
unset($_SESSION['product_sess'][$product_id]['flypage']);
 

Danach hat man dann also sofort sein gewünschte Ergebnis (Später nicht vergessen wieder zu löschen!).

Weiterhin wäre folgende Diskussion zu führen: Ziemlich auswändig (script- und datenbanktechnisch) wird hier die Flypage ermittelt. Wozu jedoch? Denn innerhalb einer Kategorie ist die Flypage jedem Produkt gleich zugewiesen, weil eine Flypage im Produkt ja nicht gepflegt werden kann, sondern immer nur in der Kategorie-Verwaltung. Wenn also die Flypage fürs aktuelle Produkt bekannt ist, und diese per GET-Parameter im PageNavigationslink übergeben wird, kann diese eigentlich ungeprüft für die Nachbar-Produkte verwendet werden. Ein Neuholen ist also nach meiner Einschätzung überflüssig - oder?
Es besteht einer kleiner Nachteil: Wenn die Funktion get_flypage() nicht aufgerufen wird, wird für dieses Produkt auch die Flypage nicht in die Session geschrieben. Aber das passiert ganz sicher an anderer Stelle ;-)

Davon mal ausgehend kann also der Link-Zusammenbau für die Nachbar-Produkte vereinfacht werden:

shop.product_detail.php
1
2
$url_parameters = 'page=shop.product_details&product_id='.$next_product['product_id'].'&flypage='.$flypage.'&category_id='.$category_id.'&pop='.$pop;
$url_parameters = 'page=shop.product_details&product_id='.$previous_product['product_id'].'&flypage='.$flypage.'&category_id='.$category_id.'&pop='.$pop;

.