PageRenderTime 38ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/www/application/modules/filter/filter.php

https://github.com/kelios/imshop
PHP | 394 lines | 277 code | 75 blank | 42 comment | 38 complexity | 0a3e06cfa4790458186a59482494f89a MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * Image CMS
  4. *
  5. * Filter Module
  6. */
  7. class Filter extends MY_Controller {
  8. public $items_per_page = 1;
  9. public $default_tpl = 'search';
  10. public function __construct()
  11. {
  12. parent::__construct();
  13. //$this->output->enable_profiler(TRUE);
  14. }
  15. public function index()
  16. {
  17. return;
  18. }
  19. public function no_pages_found()
  20. {
  21. $this->load->module('core');
  22. $this->core->error('По Вашему запросу, страниц не найдено.');
  23. exit;
  24. }
  25. // Фильтр страниц
  26. public function pages()
  27. {
  28. $this->load->module('core')->set_meta_tags('Поиск');
  29. // Удалим из строки запроса /filter/pages
  30. $segments = array_slice($this->uri->segment_array(), 2);
  31. // Парсим строку запроса сгенерированную http_build_query обратно в массив.
  32. $search_data = $this->parse_url($segments);
  33. // Получаем ID страниц, которые подходят критериям поиска,
  34. $ids = $this->search_items($search_data);
  35. // если ничего не найдено, выводим соответствующее сообщение.
  36. if (!$ids)
  37. $this->no_pages_found(); //exit
  38. // Получаем данные страниц
  39. $query = $this->_filter_pages($ids, $search_data);
  40. // Сделаем пагинацию
  41. $this->load->library('Pagination');
  42. $config['base_url'] = site_url('filter/pages/'.http_build_query($search_data,'','/'));
  43. $config['total_rows'] = $this->_filter_pages($ids, $search_data, TRUE);
  44. $config['per_page'] = $this->items_per_page;
  45. $config['uri_segment'] = $this->uri->total_segments();
  46. $config['first_link'] = lang('first_link');
  47. $config['last_link'] = lang('last_link');
  48. $config['cur_tag_open'] = '<span class="active">';
  49. $config['cur_tag_close'] = '</span>';
  50. $this->pagination->num_links = 5;
  51. $this->pagination->initialize($config);
  52. $pagination = $this->pagination->create_links();
  53. if ($query->num_rows() > 0)
  54. {
  55. $tpl = $this->default_tpl;
  56. $pages = $query->result_array();
  57. // Продублируем здесь хук core_return_category_pages,
  58. // чтобы подключить к найденным страницам поля cfcm.
  59. ($hook = get_hook('core_return_category_pages')) ? eval($hook) : NULL;
  60. // Если поиск производится по одной категории,
  61. // то используем ее шаблон.
  62. if (isset($search_data['category']) AND count((array)$search_data['category']) == 1)
  63. {
  64. $category = $this->lib_category->get_category($search_data['category']);
  65. if ($category['tpl'] == '')
  66. $tpl = 'category';
  67. else
  68. $tpl = $category['tpl'];
  69. }
  70. $data =array(
  71. 'pages' => $pages,
  72. 'pagination' => $pagination,
  73. 'category' => $category,
  74. );
  75. if ($tpl == 'search') $data['items'] = $data['pages'];
  76. $this->template->add_array($data);
  77. $this->template->show($tpl);
  78. }
  79. else
  80. {
  81. $this->no_pages_found();
  82. }
  83. }
  84. public function _filter_pages($ids, $search_data, $count = FALSE)
  85. {
  86. // Вытягиваем только опубликованные страницы
  87. $where = array(
  88. 'post_status' => 'publish',
  89. 'publish_date <=' => time(),
  90. 'lang' => $this->config->item('cur_lang'),
  91. );
  92. $this->db->where($where);
  93. $this->db->where_in('id', $ids);
  94. // Если в запросе есть переменная 'category'
  95. // ищем страницы только из указанных категорий.
  96. if (isset($search_data['category']) AND $search_data['category'] != '')
  97. $this->db->where_in('category', $search_data['category']);
  98. if ($count == FALSE)
  99. {
  100. $this->db->select('*');
  101. $this->db->select('CONCAT_WS("", content.cat_url, content.url) as full_url', FALSE);
  102. return $this->db->get('content', $this->items_per_page, (int) $this->uri->segment($this->uri->total_segments()) );
  103. }
  104. else
  105. {
  106. $this->db->from('content');
  107. return $this->db->count_all_results();
  108. }
  109. }
  110. // Создание и вывод формы по ID cfmcm группы.
  111. public function group($group_id = 0)
  112. {
  113. if (!($form = $this->create_filter_form($group_id)))
  114. {
  115. $this->core->error('В группе нет полей.');
  116. exit;
  117. }
  118. $this->load->helper('form');
  119. if ($form->isValid())
  120. {
  121. $data = $form->getData();
  122. $uri_query = http_build_query($data, '', '/');
  123. redirect('filter/pages/'.$uri_query);
  124. }
  125. // перезаполним форму данными $_POST
  126. if ($_POST)
  127. $form->setAttributes($_POST);
  128. $form_html = form_open('filter/group/'.(int)$group_id);
  129. $form_html .= $form->render();
  130. $form_html .= form_csrf();
  131. $form_html .= form_submit('submit', 'Поиск');
  132. $form_html .= form_close();
  133. $this->template->add_array(array(
  134. 'content' => $form_html,
  135. )
  136. );
  137. $this->template->show();
  138. }
  139. // Создание формы с полей группы модуля cfcm.
  140. // $group_id - ID cfcm группы или список нужных полей через запятую.
  141. public function create_filter_form($group_id, $by_fields = FALSE)
  142. {
  143. $this->load->module('forms');
  144. $group = $this->db->get_where('content_field_groups', array('id' => $group_id))->row();
  145. if ($by_fields == FALSE)
  146. {
  147. $this->db->where('group', $group_id);
  148. }
  149. else
  150. {
  151. $exp_fields = explode(",", $group_id);
  152. if (count($exp_fields) > 0)
  153. $this->db->where_in('field_name', $exp_fields);
  154. else
  155. return FALSE;
  156. }
  157. $this->db->where('in_search', '1');
  158. $this->db->order_by('weight', 'ASC');
  159. $query = $this->db->get('content_fields');
  160. if ($query->num_rows() > 0)
  161. {
  162. $form_fields = array();
  163. $fields = $query->result_array();
  164. foreach ($fields as $field)
  165. {
  166. $f_data = unserialize($field['data']);
  167. if ($f_data == FALSE)
  168. $f_data = array();
  169. $form_fields[$field['field_name']] = array(
  170. 'type' => $field['type'],
  171. 'label' => $field['label'],
  172. );
  173. $form_fields[$field['field_name']] = array_merge($form_fields[$field['field_name']], $f_data);
  174. }
  175. $form = $this->forms->add_fields($form_fields);
  176. //TODO: set form attrs from session data
  177. return $form;
  178. }
  179. else
  180. {
  181. // В группе нет полей;
  182. return FALSE;
  183. }
  184. }
  185. // Поиск ID страниц или категорий в таблице `content_fields_data`
  186. // $fields - Массив field_name => value
  187. // $type - Возможные значения: page, category
  188. public function search_items($fields = array(), $type = 'page')
  189. {
  190. $search_fields = array();
  191. $select = array();
  192. $from = array();
  193. $where = array();
  194. $strict = array();
  195. $ids = array();
  196. if (!$fields)
  197. return FALSE;
  198. // Оставим поля, которые имеют префикс field_
  199. foreach ($fields as $key => $val)
  200. {
  201. if ($val != '' AND substr($key, 0, 6) == 'field_')
  202. {
  203. $search_fields[] = $key;
  204. }
  205. }
  206. if (count($search_fields) == 0)
  207. return FALSE;
  208. // В поиске будут участвовать, только поля, которые присутствуют в БД.
  209. $this->db->select('field_name, type');
  210. $this->db->where_in('field_name', (array) $search_fields);
  211. $this->db->where_in('in_search', '1');
  212. $query = $this->db->get('content_fields');
  213. if ($query->num_rows() == 0)
  214. return FALSE;
  215. else
  216. $query = $query->result_array();
  217. $n = 0;
  218. foreach ($query as $key => $field)
  219. {
  220. $name = $field['field_name'];
  221. $select[] = "t_$name.item_id as $name"."_item_id";
  222. $from[] = "`content_fields_data` t_$name";
  223. if ($query[$n+1]['field_name'])
  224. {
  225. $strict[] = "t_$name.item_id = t_".$query[$n+1]['field_name'].".item_id";
  226. $strict[] = "t_$name.item_type = '".$type."'";
  227. }
  228. if (in_array($field['type'], array('select','checkgroup','radiogroup')))
  229. {
  230. $where[] = "(t_$name.field_name='$name' AND t_$name.data IN (".$this->implode($fields[$name])."))";
  231. }
  232. elseif(in_array($field['type'], array('text','textarea')))
  233. {
  234. $where[] = "(t_$name.field_name='$name' AND t_$name.data LIKE '%".$this->db->escape_str($fields[$name])."%')";
  235. }
  236. elseif(in_array($field['type'], array('checkbox')))
  237. {
  238. $where[] = "(t_$name.field_name='$name' AND t_$name.data = '".$this->db->escape_str($field_name[$name])."')";
  239. }
  240. $n++;
  241. }
  242. // Если есть условия для поиска,
  243. // составим запрос.
  244. if (count($where) > 0)
  245. {
  246. $sql = "SELECT \n".implode(",",$select)."\n";
  247. $sql .= "FROM \n".implode(",", $from)."\n";
  248. $sql .= "WHERE \n".implode("\nAND\n", $where)."\n";
  249. if (count($strict) > 0)
  250. $sql .= "AND \n".implode(" \nAND\n ", $strict)."\n";
  251. $query = $this->db->query($sql);
  252. if ($query->num_rows() > 0)
  253. {
  254. foreach ($query->result_array() as $key => $val)
  255. {
  256. $ids = array_merge($ids, array_values($val));
  257. }
  258. $ids = array_values(array_unique($ids));
  259. }
  260. return $ids;
  261. }
  262. else
  263. {
  264. return FALSE;
  265. }
  266. }
  267. // Парсим сегменты http_build_query
  268. // обратно в массив.
  269. public function parse_url($request)
  270. {
  271. $result = array();
  272. if (is_array($request) AND count($request) > 0)
  273. {
  274. foreach ($request as $key => $val)
  275. {
  276. $vals = explode('=', $val);
  277. $segment_key = preg_replace('/\[.*?\]/', '', $vals[0]);
  278. $segment_val = $vals[1];
  279. if (isset($result[$segment_key]))
  280. {
  281. $result[$segment_key] = (array) $result[$segment_key];
  282. $result[$segment_key][] = urldecode($segment_val);
  283. }
  284. else
  285. {
  286. $result[$segment_key] = $segment_val;
  287. }
  288. }
  289. return $result;
  290. }
  291. return FALSE;
  292. }
  293. public function implode($array = array())
  294. {
  295. $array = array_values((array)$array);
  296. for ($i=0; $i<count($array); $i++)
  297. {
  298. $array[$i] = '"'.$this->db->escape_str($array[$i]).'"';
  299. }
  300. return implode(', ', (array) $array);
  301. }
  302. /**
  303. * Display template file
  304. */
  305. private function display_tpl($file = '')
  306. {
  307. $file = realpath(dirname(__FILE__)).'/templates/public/'.$file.'.tpl';
  308. $this->template->display('file:'.$file);
  309. }
  310. /**
  311. * Fetch template file
  312. */
  313. private function fetch_tpl($file = '')
  314. {
  315. $file = realpath(dirname(__FILE__)).'/templates/public/'.$file.'.tpl';
  316. return $this->template->fetch('file:'.$file);
  317. }
  318. }
  319. /* End of file filter.php */