Web Store Product Filters

Hi!

I wonder, what is the best way to create web store product list filters?

I do have a product list using CListView (it is not customized, but simply CListView widget).

I need to filter this product list by category, brand, gender and some other properties (about 6 properties).

SiteController/ProductsAction is action which displays product list. Now it has only one variable $brands:

actionProducts($brands=null) and if $brands != null I am adding it to CDbCondition.

But I wonder, what is the best way to create a long filter?

Where to store all those filter values? If these are GET variables, how properly create URL?

You can use in your product model something like this




    public static function getFilterResults($filters = array())

    {

        $joinArr = array();

        $criteria = new CDbCriteria;


        if ($filters) {

            if (isset($filters['category'])) {

//example for MANY2MANY relation

                $joinArr[] = "INNER JOIN `" . self::item2CategoryTableName() . "` as `i2c` ON (`t`.`item_id` = `i2c`.`r_item_id`)";

                $criteria->addInCondition('i2c.r_category_id', $filters['category']);

            }

//example for BELONGS TO relation

            if (isset($filters['brand'])) {

                $criteria->addInCondition('t.brand_id', $filters['brand']);

            }

            if (isset($filters['filter'])) {

                $joinArr[] = "INNER JOIN `" . self::item2FilterTableName() . "` as `i2f` ON (`t`.`item_id` = `i2f`.`item_id`)";

                $criteria->addInCondition('i2f.value_id', $filters['filter']);

            }

//example for price

            if (isset($filters['priceRange'])) {

                $criteria->addBetweenCondition('t.price', $filters['priceRange']['0'], $filters['priceRange']['1']);

            }

            if (isset($filters['search'])) {

                if (count($filters['search']) > 0)

                    $criteria->compare("`t`.`item_id`", $filters['search']);

                else

                    $criteria->compare("`t`.`item_id`", -1);

            }

        }

        $criteria->join = implode(" ", $joinArr);

        return self::getDataProvider($criteria, 12);

    }


  public static function getDataProvider($criteria2, $pageSize, $defaultOrder = 't.viewed_cnt DESC')

    {

        $criteria = new CDbCriteria;

        $criteria->group = "t.item_id";

        $criteria->addCondition("t.amount != " . self::AVAILABLE_SOLD);

        $sort = new CSort();

        $sort->sortVar = 'sort';

        $sort->defaultOrder = $defaultOrder;

        $sort->attributes = array(

            'price' => array(

                'label' => "Price",

                'asc' => 't.price ASC',

                'desc' => 't.price DESC',

            ),

            'newest' => array(

                'label' => "Newest",

                'asc' => 't.create_datetime ASC',

                'desc' => 't.create_datetime DESC',

            ),

        );

        if ($criteria2 instanceof CDbCriteria) {

            $criteria2->mergeWith($criteria);

        }

        $dataProvider = new CActiveDataProvider("Item", array(

                    'pagination' => array(

                        'pageSize' => $pageSize,

                    ),

                    'sort' => $sort,

                    'criteria' => $criteria2,

                        )

        );

        return $dataProvider;

    }



And send values ids for filtering to this method as array;

It can be session, $_GET, etc.

Example site with this filters - 300watches2 dot chdev dot com dot ua (site is not finished)