В довольно-таки популярном js-фреймворке kendo присутствует виджет grid. Из названия виджета понятно, что он представляет из себя таблицу. При проведении фильтрации, сортировки и т.п., грид отправляет набор фильтров, из которых потом формируется sql-запрос.
Вот пример отправляемых данных:
CODE ( htmlphp):
скопировать код в буфер обмена
filter[logic]:and filter[filters][0][logic]:or filter[filters][0][filters][0][field]:id_ad filter[filters][0][filters][0][operator]:contains filter[filters][0][filters][0][value]: filter[filters][0][filters][1][field]:id_user filter[filters][0][filters][1][operator]:contains filter[filters][0][filters][1][value]: filter[filters][1][field]:status_db filter[filters][1][operator]:eq filter[filters][1][value]:active filter[filters][2][field]:status_nodb filter[filters][2][operator]:eq filter[filters][2][value]:active
Фильтры соединены между собой логикой [logic] : or/and. Если [value] фильтра приходит пустым - фильтр необходимо игнорировать.
Операторы eq и contains обозначают = 'value' и like '%value%' соответственно.
Из примера выше видно, что фильтры могут быть вложены. Таким образом тут необходима рекурсия.
Вот запрос. который должен получиться исходя из текущих фильтров.
CODE ( SQL):
скопировать код в буфер обмена
SELECT * FROM mytable WHERE status_db='active' AND status_nodb = 'active' AND (id_ad LIKE '%1%' OR id_user LIKE '%1%')
Была написана костыльная версия фильтрации, она под спойлером.
Спойлер (Отобразить)
PHP:
скопировать код в буфер обмена
echo $filter = $this->parse_filter($post['filter']['filters'], $post['filter']['logic']); function parse_filter($filters, $logic) { if (isset($filters['filters'])) { $result = $this->parse_filter($filters['filters'],$filters['logic']); } else { $result = '('; foreach ($filters as $filter) { if(isset($filter['filters'])) { $res = $this->parse_filter($filter['filters'],$filter['logic']); if ($res == '()' || $res == '') { return ''; } else { if ($result != '' && $result != '(') { $result .= ' '.$logic.' '.$res; } else { $result .= $res; } } } else { if (!empty($filter['value'])) { if ($result != '' && $result != '(') { $result .= ' '.$logic.' '; } switch ($filter['operator']) { case 'contains': $result .= '(`'.$filter['field'].'` LIKE "%'.$filter['value'].'%")'; break; case 'eq': $result .= '(`'.$filter['field'].'` = "'.$filter['value'].'")'; break; case 'neq': $result .= '(`'.$filter['field'].'` <> "'.$filter['value'].'")'; break; case 'lt': case 'lte': case 'gt': case 'gte': case 'startswith': $result .= '(`'.$filter['field'].'` LIKE "'.$filter['value'].'%")'; case 'endswith': $result .= '(`'.$filter['field'].'` LIKE "%'.$filter['value'].'")'; default: break; } } } } $result .= ')'; } if ($result == '' || $result == '()') { return ''; } else { return $result; } }
Помогите, пожалуйста, написать нормальную функцию, которая могла бы обрабатывать присылаемые фильтры. Я думаю это будет полезно многим, кто использует подобную фильтрацию.
|