Problembeschreibung / Zielsetzung

In diesem Beitrag geht es um die Einstellungen in VirtueMart 2.x wie viele Produkt pro Kategorieseite angezeigt werden sollen.
Eigentlich denkt man, das sollte kein Problem sein. Praktisch ist es jedoch etwas verwirrend, denn das was konfigurierbar scheint, wirkt sich nicht wie erhofft aus. Ich konnte mit diesem Wert machen was ich wollte, die Anzeig ließ sich nicht ändern. In meinem Template hatte ich auch die Auswahl "LimitBox" abgeschalten, so dass auch hierüber keine Modifikation möglich war, der Shop also zwangsläufig immer mit dem Standardwert arbeiten sollte.

 

Beschreibung des Verhaltens und einer einfachen Problemlösung

Das nachfolgend beschriebene Verhalten bezieht sich auf die VirtueMart-Versionen bis 2.0.22. Es kann gut sein, dass es in Folgeversionen korrigiert oder geändert sein könnte.



Wir finden in der Shop-Administration unter Konfiguration > Konfiguration > Register "Stilvorlagen" eine Option maximale Anzahl der Produkte im Frontend pro Ansichtseite. Diese ist eigentlich genau dafür gedacht den Standardwert für die Anzahl der pro Seite zu zeigenden Produkte zu definieren. Bei meinen Shop-Installationen zeigt dies jedoch keinerlei Wirkung. Deshalb habe ich weiter gesucht und probiert. Im Register Stilvorlagen finden wir eine Optionsparameter Seitenumbruch festlegen. Lt. Beschreibung muss man hier eine Liste der Werte eingeben, die in der Auswahlliste für die Anzahl der pro Seiten anzuzeigenden Produkte angeboten werden sollen. Das kann z.B. so aussehen: 10,25,50,100,200,500. Und siehe da, nun plötzlich tut sich etwas, was man schon mal als Teilerfolg verbuchen kann. (Anmerkung: wichtig ist natürlich, dass Sie in Ihrem Category-Template auch die Ausgabe der LimitBox erzeugen/zulassen; dazu unten mehr). Nun können wir bei einem Strg+R auf unserer Kategorie-Seite feststellen, dass der Standardwert schon mal auf 10 gesetzt wird, also den ersten Wert in unserer Liste. Wem dieses Verhalten genügt, der kann ja schon mal mit dieser Erkenntnis ausgestattet diese Wertereihe so aufbauen, dass diese mit seinem Wunsch-Standardwert beginnt.

In Versionen ab 2.0.24 wurde das Verhalten durch die VM-Entwickler umgebaut, was hier ebenfall kurz beschrieben sein soll weil das Verständnis hierzu nicht unwichtig ist. Zunächst muss man wissen, dass das Standard-Template zur Anzeige von Produkten und Kategorien auf einem relativ starren Layout baisert, d.h. man muss in der Shopkonfiguration festlegen wieviel Produkte oder Kategorien pro Zeile angezeigt werden sollen. Das widerspricht dem modernen Anspruch der floatenden Anzeige der Produkte abhängig von der Browserbreite und damit dem responsiven Layoutansatz. Vorgesehen sind in VM 1-5 Produkte/Artikel pro Zeile. Hierfür wurden entspr. Seitenumbruchfelder vorgesehen (Für Ansichten mit 1 Artikel pro Zeile, ..., Für 5 Artikel pro Zeile) in die man nach oben beschriebener Weise die Auswahllisten eintragen kann. Trägt man hier nichts ein, so greift die generiesche Listenerstellung und hierbei wird die Anzahl der Produkte/Artikel pro Zeile multipliziert mit den voreingestellten Seitenumbruchsauswahlwerten 5, 10, 20 und 50.

Ein weiteres abnormes Verhalten konnte ich bei mir feststellen: In den Limit-SelectBoxen wird immer der erste Wert als selected angezeigt, unabhängig davon mit welchem eingestellten Wert wirklich gelistet wurde oder welchen Wert der User ausgewählt hatte. Das Attribut selected wird in den SelectListen nicht gesetzt. Also auch diese Frage gilt es zu klären.

Bleibt die Frage:

 

Wie lässt sich der Standardwert frei lt. list_limit setzen?

Nun nehmen wir mal an, dass unser Wunsch-Standardwert nicht der erste Wert in der Liste sein soll, sondern z.B. einer der optimaleren mittleren Werte aus unserer oben eingepflegte Werteliste, z.B. 50. Wir würden also in unserer Option maximale Anzahl der Produkte im Frontend pro Ansichtseite den Wert 50 eintragen, aber eben feststellen, dass dies ohne Wirkung bleibt.

 

Bug in VM verhindert die ordnungsgemäße Funktion der LimitBox

Hier zunächst mal ein paar Wissenswerte Fakten, für die die diesbezüglich etwas tiefer in die Quelltextscripte eindringen wollen:

Es gibt ein VirtueMart-Core-Script administrator/components/com_virtuemart/helpers/vmmodel.php. Hier werden u.a. die Classe VmModel (extends JModel) mit ihrer relevanten Methode setPagination() und in der Classe VmPagination (extends JPagination s. libraries/joomla/html/pagination.php) die Methode getLimitBox() deklariert. In setPagination() wird in Abhängigkeit von den Shop-Limit-Standardwerten und den vom User ausgewählten Limit-Werten die Erzeugungseinstellungen für die Paginaiton und auch Limit-SelectBox ermittelt und gesetzt. (s. http://docs.virtuemart.net/api-vm2/df/db9/class_vm_pagination.html). Über diverse weitere Joomla-Library-Scripte landet man in der Methode options() im Script libraries/joomla/html/html/select.php welche die Optionselement einer Selectionsliste also auch unserer Limit-SelectBox erzeugt.


Grund für oben beschriebenes Fehlverhalten ist ein Bug im VM-Script vmmodel.php und mündet in der Methode options() in der libraries/joomla/html/html/select.php. Hier soll ja das selected-Attribut für die jeweils akt. Option gesetzt werden, so wie im letzten Parameter von
$html = JHTML::_('select.genericlist', $limits, '', 'class="inputbox" size="1" '.$js , 'value', 'text', $selected);
im Script vmmodel.php übergeben.

Erwartet wird in der Methode options() für $options['list.select'] entweder ein array oder ein string. Hier übergeben wird die URI als string für den Vergleich bezüglich des limit-Wertes. Nun der konkrete Fehler - in der Zeile 615 in select.php wird wie folgt verglichen:

elseif ((string) $key == (string) $options['list.select'])

In der vmmodel.php Zeile 713 erzeugen wir den URi-String mit

$selected= JRoute::_( $link.'&limit='. $selected) ;

Das Problem ist dass dieser String html-specialchar-encodet ist also "&" umgewandelt wird in &. Damit schläg o.g. Stringvergleich in der select.php zwangsläufig fehl.

Deshalb sollte in der vmmodel.php die Zeile 713 ändern zu:

$selected= htmlspecialchars_decode(JRoute::_( $link.'&limit='. $selected));

Damit hätten die Strings eine Chance gleich zu sein.