Hm, schade, dass niemand etwas dazu zu sagen weiß, aber wie sagt man so schön: Selbst ist der Mann (+Frau natürlich auch!)…
Also hier mal meine bisherige Lösung, die zwar sauber funzt aber irgendwie umständlich wirkt. Ich bin mir halt beim ersten Versuch ein Oxid-Modul zu schreiben überhaupt nicht sicher, welche Klassen man am besten erweitert. Es scheint da ja oft mehrere Möglichkeiten zu geben. Und ist es überhaupt korrekt, für ein Modul mehrere Dateien einbinden zu müssen, oder sollte man immer versuchen, alles in eine zu quetschen (wahrscheinlich oft gar nicht möglich, oder)?
[B]1.: alist => showmanu/manulist[/B]
<?php
class manulist extends manulist_parent
{
public function execmanufilter()
{
// store this into session
$aFilter = oxConfig::getParameter('manufilter');
$sActCat = oxConfig::getParameter('cnid');
$aSessionFilter = oxSession::getVar('session_manufilter');
$aSessionFilter[$sActCat] = $aFilter;
oxSession::setVar('session_manufilter', $aSessionFilter);
}
public function getManuCatlist() {
$ret = array();
$sActCat = oxConfig::getParameter('cnid');
$sLangAdd = oxLang::getInstance()->getLanguageTag();
$sViewName = 'oxmanufacturers';
if (!$sActCat) return $ret;
$oDb = oxDb::getDb(true);
$sSelect = "SELECT oxid,oxtitle,(SELECT COUNT(*) FROM oxarticles AS a,oxobject2category AS oc WHERE m.oxid=a.oxmanufacturerid AND a.oxactive=1 AND a.oxid=oc.oxobjectid AND oc.oxcatnid=".$oDb->quote($sActCat).") AS artcnt ";
$sSelect .= "FROM {$sViewName} AS m WHERE m.oxactive=1 AND m.oxtitle{$sLangAdd}!='' HAVING artcnt>0 ORDER BY m.oxtitle{$sLangAdd}";
$rs = $oDb->Execute($sSelect);
if ($rs != false && $rs->recordCount() > 0) {
while (!$rs->EOF) {
$ret[] = $rs->fields;
$rs->moveNext();
}
}
return $ret;
}
}
[B]2.: oxarticlelist => showmanu/manuarts[/B]
<?php
class manuarts extends manuarts_parent
{
protected function _getCategorySelect( $sFields, $sCatId, $aSessionFilter )
{
$sArticleTable = getViewName( 'oxarticles' );
$sO2CView = getViewName( 'oxobject2category' );
// ----------------------------------
// sorting
$sSorting = '';
if ( $this->_sCustomSorting ) {
$sSorting = " {$this->_sCustomSorting} , ";
}
// ----------------------------------
// attribute filtering ?
$sFilterSql = '';
if ( $aSessionFilter && isset( $aSessionFilter[$sCatId] ) ) {
$sFilterSql = $this->_getFilterSql($sCatId, $aSessionFilter[$sCatId]);
}
$oDb = oxDb::getDb();
// ----------------------------------
// manufacturer filtering ?
$aFilter = oxSession::getVar('session_manufilter');
if ($aFilter && $aFilter[$sCatId]) {
$sFilterSql .= " AND $sArticleTable.oxmanufacturerid=".$oDb->quote($aFilter[$sCatId]);
}
$sSelect = "SELECT $sFields FROM $sO2CView as oc left join $sArticleTable
ON $sArticleTable.oxid = oc.oxobjectid
WHERE ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxparentid = ''
and oc.oxcatnid = ".$oDb->quote($sCatId)." $sFilterSql GROUP BY oc.oxcatnid, oc.oxobjectid ORDER BY $sSorting oc.oxpos, oc.oxobjectid ";
return $sSelect;
}
}
[B]3.: oxcmp_utils => showmanu/manuview[/B]
<?php
class manuview extends manuview_parent
{
public function render() {
$aFilter = oxSession::getVar('session_manufilter');
$sActCat = oxConfig::getParameter('cnid');
$manufilter = '';
if ($aFilter && $aFilter[$sActCat])
$manufilter = $aFilter[$sActCat];
$this->_oParent->addTplParam(
'manufilter', $manufilter
);
parent::render();
}
}
[B]4.:[/B] So, und wenn man das alles hat, kann man folgendes ins Template ([B]z.b. /out/custom/tpl/list.tpl[/B]) basteln (ich habe es oberhalb [{if $oView->getAttributes() }]
[{if $oView->getListType()!='manufacturer' && $oView->getManuCatlist() && $pageNavigation->iArtCnt}]
<form method="post" action="[{ $oViewConf->getSelfActionLink() }]" name="_manulist" id="_manulist">
<div class="catfilter">
[{ $oViewConf->getHiddenSid() }]
[{ $oViewConf->getNavFormParams() }]
<input type="hidden" name="cl" value="[{ $oViewConf->getActiveClassName() }]">
<input type="hidden" name="tpl" value="[{$tpl}]">
<input type="hidden" name="fnc" value="execmanufilter">
<table cellpadding="0" cellspacing="0">
<tr>
<td>
<label>[{ oxmultilang ident="DETAILS_MANUFACTURER" }]</label>
</td>
<td><select name="manufilter" onchange="oxid.form.send('_manulist');">
<option value=""> [{ oxmultilang ident="INC_SEARCHLEFTITEM_ALLMANUFACTURERS" }] </option>
[{foreach from=$oView->getManuCatlist() item=oManu}]
<option value="[{$oManu.oxid}]"[{if $manufilter == $oManu.oxid}] selected[{/if}]>[{ $oManu.oxtitle }] ([{ $oManu.artcnt }])</option>
[{/foreach}]
</select></td>
</tr>
</table>
</div>
</form>
[{/if}]
[{if $oView->getAttributes() }]
...
[{/if}]
[B]Ergebnis:[/B]
Es wird auf allen Kategorie-Listen (nicht Suche und nicht Herstellerlisten) nun unterhalb des Kategorienamens eine Hersteller-selectbox angezeigt, die nur die Hersteller der betreffenden Kategorie beinhaltet, soweit Artikel mit denen verknüpft sind (mit korrekter Anzahl dahinter). Der Filter wird genauso wie die Attribute pro Kategorie in der Session gespeichert (wobei die Frage bleibt, ob das immer sinnvoll ist) und funzt auch sonst sehr ähnlich.
Ich weiß (noch) nicht, ob dies eine gute Lösung ist, aber ich halte das Ergebnis für eine Standard-Funktion, die ruhig fest im Shop eingebaut sein dürfte (optional nutzbar), von daher bin ich sehr gespannt auf jegliche Resonanz, am liebsten seitens von Entwicklern!
Achja, und nebenbei habe ich auch den Hersteller-Filter der Suche etwas optimiert, sodass dort nur die Hersteller angeboten werden, zu denen es auch wirklich Artikel gibt (analog zur Adminoption, auch ungenutzte Kategorien ausblenden zu können):
5.: oxmanufacturerlist => showmanu/manucats
<?php
class manucats extends manucats_parent
{
public function loadManufacturerList()
{
$sLangAdd = oxLang::getInstance()->getLanguageTag();
$oBaseObject = $this->getBaseObject();
$sFieldList = $oBaseObject->getSelectFields();
$sViewName = $oBaseObject->getViewName();
$this->getBaseObject()->setShowArticleCnt( $this->_blShowManufacturerArticleCnt );
$sWhere = '';
if ( !$this->isAdmin() ) {
$sWhere = $oBaseObject->getSqlActiveSnippet();
$sWhere = $sWhere?" where $sWhere and ":' where ';
$sWhere .= "{$sViewName}.oxtitle{$sLangAdd} != '' ";
$sWhere .= "AND {$sViewName}.oxid IN (SELECT oxmanufacturerid FROM oxarticles WHERE oxactive=1)";
}
$sSelect = "select {$sFieldList} from {$sViewName} {$sWhere} order by {$sViewName}.oxtitle{$sLangAdd}";
$this->selectString( $sSelect );
}
}
So sagt ehrlich: bin ich auf dem richtigen Weg, habe ich evtl. sogar zuviel verraten, könnte/sollte ich das als offizielles Modul anbieten oder ist es alles totaler Quatsch???
Grüße