Na poczatek struktura bazy danych:
produkt
id name price ...
products_categories
product_id category_id
categories
id name ...
attributes
id name
attribute_sets
id attribute_id product_id value
categories_attributes
category_id attribute_id
Mam formularz z multiselektami, ktory przekazuje do funkcji z repozytorium parametry, w tym id wartosci cechy produktu.
Probuje przy uzyciu query buildera wykonac zapytanie, ktore by mi zwrocilo pasujace rekordy - liste produktow z wartosciami cech zaznaczonych w formularzu. Jednak mam problem, bo gdy uzyje orWhere panuje istny chaos - zwracane sa niepoprawne wyniki, jesli zas uzyje andWhere pojawiaja sie poprawne wyniki, ale brane sa pod uwage tylko przekazane parametry z ostatniego checkboxa w ostatnim multiselekcie.
Zaznaczam w formularzu przykladowo (cecha | wartosc cechy):
pierwszy multiselect: kolor (pobierane jest id cechy) | bialy (pobierana jest wartosc cechy jako string)
drugi multiselect: typ (pobierane jest id cechy) | prawe (pobierana jest wartosc cechy jako string)
class ProductsRepository extends \Doctrine\ORM\EntityRepository { public function search($searchParam) { http://www.php.net/extract($searchParam); $qb = $this->createQueryBuilder('p') ->leftJoin('p.brands', 'b') ->addSelect('b') ->leftJoin('p.categories', 'c') ->addSelect('c') ->leftJoin('p.attributeSets', 't') // wartosci cech produktow ->addSelect('t'); if(!http://www.php.net/empty($brandId)) $qb->andWhere('b.id = :brands')->setParameter('brands', $brandId); if(!http://www.php.net/empty($catId)) $qb->andWhere('c.id = :categories')->setParameter('categories', $catId); if(!http://www.php.net/empty($attributeSetsVal)){ http://www.php.net/print_r($attributeSetsVal); // zwracane jest: Array ( [6] => Array ( [0] => bialy ) [7] => Array ( [0] => prawe ) ) 6 i 7 to id cechy produktu foreach($attributeSetsVal as $attribute){ $qb->andWhere('t.value = :attributeSets')->setParameter('attributeSets', $attribute); // problem jest z tym fragmentem, zwracane sa poprawne wyniki, ale tylko dla zaznaczonego ostatniego checkboxa z multiselekta } } }
Przecież ten zapis w pętli nadpisze ci bindowaną wartość parametru na ostatni element tablicy... Musiałbyś mieć unikalne nazwy parametrów. Z resztą zrzuć sobie zapytanie poprzez $qb->getQuery()->getSQL() i zobaczysz, że będziesz miał kilka takich samych where.
Odstawiając temat Doctrine'a na chwilę, rozwiązanie samo w sobie: http://stackoverflow.com/questions/927724/what-is-a-sql-statement-to-select-an-item-that-has-several-attributes-in-an-item - przeniesienie tego do ORM-a nie będzie wielce skomplikowane.
PS. Zastanów się od razu czy nie skorzystać z narzędzi typu Apache SOLR, które zdecydowanie lepiej radzą sobie z wyszukiwaniem.
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)