Hallo Leute,
ich möchte gerne die Attribut-Filterung anpassen, um auch mehrere Selektionen innerhalb eines Attributs zuzulassen. Zum Beispiel sollen alle Objekte angezeigt werden, welche die Farbe grün oder rot besitzen und nicht eine Filterung nach grün und seperat eine nach rot.
Ich habe mir also diese Attributfilter soweit vorbereitet checkbox-inputs und möchte nun den FIlterprozess anpassen, finde aber den Einstiegspunkt nicht, an dem [I]$aSessionFilter[/I] gesetzt wird.
Wird eine Auswahl gesetzt wird per javascript [I]onchange=“oxid.form.send(’_filterlist’);”[/I] gerufen…aber wo wird dann was ausgeführt. Habe schon ewig den COde durchkämmt
Vielen Dank im voraus!
ich glaube ich habe einen ganz guten Einstiegspunkt gefunden: function executefilter() in der alist.php, zumindest wird hier die filtersession gesetzt. aber wo werden denn die post und get variablen verarbeitet?
POST-Variable ist der array attrfilter. Dieser wird immer weitergereicht:
alist.php: executefilter() schreibt ihn in oxSession ‘session_attrfilter’
alist.php: _loadArticles() liest ihn wieder aus und übergibt ihn an
oxarticlelist.php: loadCategoryArticles( $sActCat, $aSessionFilter ).
Dieses übergibt ihn an
oxarticlelist.php: _getCategorySelect( $sArticleFields, $sCatId, $aSessionFilter )
Dieses übergibt ihn an
oxarticlelist.php: _getFilterSql($sCatId, $aSessionFilter[$sCatId])
Dieses übergibt ihn an
oxarticlelist.php: _getFilterIdsSql( $sCatId, $aFilter )
und hier wird dann das SQL gebaut:
foreach ( $aFilter as $sAttrId => $sValue ) {
if ( $sValue ) {
if ( $sFilter ) {
$sFilter .= ' or ';
}
$sValue = $oDb->quote( $sValue );
$sAttrId = $oDb->quote( $sAttrId );
$sFilter .= "( oa.oxattrid = {$sAttrId} and oa.oxvalue{$sSuffix} = {$sValue} )";
$iCnt++;
}
}
So ungefähr müsste das funktionieren…
hallo leofonic,
danke für deine antwort. ich dachte auch erst, dass man hier schon das problem lösen könnte, aber man muss schon vorher ansetzen. deine beschreibung wäre dann wohl erst der 2. schritt.
ich versuche kurz das problem zu beschreiben:
in dem formular, welches den attributfilter auslöst wird für jede zeile der selectbox als “name” die attributnummer übergeben. als value dient dann der jeweilige wert des attributs, welcher daruafhin in der sessionvariable gespeichert wird. da die attributnummern gleich sind müsste der php-interpreter die values ja in ein array schreiben, auf das ich bequem zugreifen kann.
.. name="attrfilter[[{ $sAttrID }]]" value="[{ $oValue->id }]" onchange="oxid.form.send('_filterlist');" ..
das problem ist, das ich beim abholen der attributfilter in der function executefilter() (alist.php) nur einen attributwert bekommen, trotz mehrfacher auswahl. ich möchte aber eigentlich einen array bekommen. deshalb müsste ich an den punkt, an dem die post-variablen verarbeitet werden.
public function executefilter()
{
// store this into session
$aFilter = oxConfig::getParameter( 'attrfilter', 1 );
// hier liefert $aFilter immer nur einen wert als string
$sActCat = oxConfig::getParameter( 'cnid' );
$aSessionFilter = oxSession::getVar( 'session_attrfilter' );
$aSessionFilter[$sActCat] = $aFilter;
oxSession::setVar( 'session_attrfilter', $aSessionFilter );
}
eine möglichkeit wäre ja ein workaround mit fake-attribut-ids. hm…
Ja stimmt das ist ein Problem. Ich hab mal probiert einen Ansatz zu finden. Erstmal in der list.tpl statt den Selects Checkboxen. Den Array habe ich dabei um eine Dimension erweitert und den value dafür benutzt, damit alle Werte zurückkommen:
<table cellpadding="0" cellspacing="0">
[{foreach from=$oView->getAttributes() item=oFilterAttr key=sAttrID name=testAttr}]
<tr>
<td>
<label id="test_attrfilterTitle_[{$sAttrID}]_[{$smarty.foreach.testAttr.iteration}]">[{ $oFilterAttr->title }]:</label>
</td>
<td>
[{foreach from=$oFilterAttr->aValues item=oValue}]
<input type="checkbox" name="attrfilter[[{ $oValue->id }]][[{ $sAttrID }]]" value="[{ $oValue->id }]" [{ if $oValue->blSelected }]checked[{/if}]>[{ $oValue->value }]
[{/foreach}]
</td>
</tr>
[{/foreach}]
<tr><td><input type="submit"></td></tr>
</table>
Dann die Filterlogik angepasst in der oxarticlelist->_getFilterIdsSql. Es stellte sich heraus dass der Counter nur eindeutige Attribute zählen darf damit Ergebnisse zurückkommen.
Ab Zeile 828:
foreach ( $aFilter as $aAtrrfilter ) {
foreach ( $aAtrrfilter as $sAttrId => $sValue ) {
if ( $sValue ) {
if ( $sFilter ) {
$sFilter .= ' or ';
}
$sValue = $oDb->quote( $sValue );
$sAttrId = $oDb->quote( $sAttrId );
$sFilter .= "( oa.oxattrid = {$sAttrId} and oa.oxvalue{$sSuffix} = {$sValue} )";
$aCnt[$sAttrId] = 1;
}
}
}
$iCnt = count($aCnt);
Sieht schon gut aus, funktioniert aber noch nicht. Debuggen ergibt dass in oxcategory.php noch was geändert werden muss, getAttributes(), Zeile 713:
$oValue->blSelected = isset($aSessionFilter[$sActCat][$oValue->id][$sAttId]) && $aSessionFilter[$sActCat][$oValue->id][$sAttId] == $sAttValue;
So funktioniert das schon mal!
hallo leofonic,
das hat super geklappt. ich war schon dabei, die fehlenden werte anzuhängen und in den folgenden funktionen die parameter zu splitten aber einfach nen mehrdimensionalen array klappt natürlich besser. für die checkboxen klappt es ebenfalls, sie auf “onclick” zu lassen. desweiteren lade ich bei der darstellung der attributfilterfunktion die filteroptionen in ungefiltertem zustand. dabei vergleiche ich die neuen attribute mit den alten und setze alle checkboxen auf disabled, welche nicht mehr vorkommen. mit ein paar modifikationen im filterprozess und eine zusätzlichen sessionvariable als merker für zuletzt gesetzte filter kann ich das gewünschte filtersystem fast komplett abbilden. siehe zum beispiel die filterfunktion links: http://yalook.com/men/kategorien/schuhe-men/c.html
also vielen dank! das hat mir echt weitergeholfen. vielleicht kann ich mich bei gelegenheit revanchieren.
viele grüße
Super, freut mich dass es geklappt hat und danke fürs Feedback!