PageRenderTime 57ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/html/AppCode/expressionengine/modules/search/mod.search.php

https://github.com/w3bg/www.hsifin.com
PHP | 1781 lines | 1104 code | 396 blank | 281 comment | 262 complexity | 4b3fc5c482769e6d1fcf78dbf6c874e0 MD5 | raw file
Possible License(s): AGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * ExpressionEngine - by EllisLab
  4. *
  5. * @package ExpressionEngine
  6. * @author ExpressionEngine Dev Team
  7. * @copyright Copyright (c) 2003 - 2010, EllisLab, Inc.
  8. * @license http://expressionengine.com/user_guide/license.html
  9. * @link http://expressionengine.com
  10. * @since Version 2.0
  11. * @filesource
  12. */
  13. // ------------------------------------------------------------------------
  14. /**
  15. * ExpressionEngine Search Module
  16. *
  17. * @package ExpressionEngine
  18. * @subpackage Modules
  19. * @category Modules
  20. * @author ExpressionEngine Dev Team
  21. * @link http://expressionengine.com
  22. */
  23. class Search {
  24. var $min_length = 3; // Minimum length of search keywords
  25. var $cache_expire = 2; // How many hours should we keep search caches?
  26. var $keywords = "";
  27. var $text_format = 'xhtml'; // Excerpt text formatting
  28. var $html_format = 'all'; // Excerpt html formatting
  29. var $auto_links = 'y'; // Excerpt auto-linking: y/n
  30. var $allow_img_url = 'n'; // Excerpt - allow images: y/n
  31. var $channel_array = array();
  32. var $cat_array = array();
  33. var $fields = array();
  34. var $num_rows = 0;
  35. function Search()
  36. {
  37. // Make a local reference to the ExpressionEngine super object
  38. $this->EE =& get_instance();
  39. }
  40. /** ----------------------------------------
  41. /** Perform Search
  42. /** ----------------------------------------*/
  43. function do_search()
  44. {
  45. /** ----------------------------------------
  46. /** Fetch the search language file
  47. /** ----------------------------------------*/
  48. $this->EE->lang->loadfile('search');
  49. /** ----------------------------------------
  50. /** Profile Exception
  51. /** ----------------------------------------*/
  52. // This is an exception to the normal search routine.
  53. // It permits us to search for all posts by a particular user's screen name
  54. // We look for the "mbr" $_GET variable. If it exsists it will
  55. // trigger our exception
  56. if ($this->EE->input->get_post('mbr'))
  57. {
  58. $_POST['RP'] = ($this->EE->input->get_post('result_path') != '') ? $this->EE->input->get_post('result_path') : 'search/results';
  59. $_POST['keywords'] = '';
  60. $_POST['exact_match'] = 'y';
  61. $_POST['exact_keyword'] = 'n';
  62. // $_POST['member_name'] = urldecode($this->EE->input->get_post('fetch_posts_by'));
  63. }
  64. // RP can be used in a query string,
  65. // so we need to clean it a bit
  66. $_POST['RP'] = str_replace(array('=', '&'), '', $_POST['RP']);
  67. /** ----------------------------------------
  68. /** Pulldown Addition - Any, All, Exact
  69. /** ----------------------------------------*/
  70. if (isset($_POST['where']) && $_POST['where'] == 'exact')
  71. {
  72. $_POST['exact_keyword'] = 'y';
  73. }
  74. /** ----------------------------------------
  75. /** Do we have a search results page?
  76. /** ----------------------------------------*/
  77. // The search results template is specified as a parameter in the search form tag.
  78. // If the parameter is missing we'll issue an error since we don't know where to
  79. // show the results
  80. if ( ! isset($_POST['RP']) OR $_POST['RP'] == '')
  81. {
  82. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('search_path_error')));
  83. }
  84. /** ----------------------------------------
  85. /** Is the current user allowed to search?
  86. /** ----------------------------------------*/
  87. if ($this->EE->session->userdata['can_search'] == 'n' AND $this->EE->session->userdata['group_id'] != 1)
  88. {
  89. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('search_not_allowed')));
  90. }
  91. /** ----------------------------------------
  92. /** Flood control
  93. /** ----------------------------------------*/
  94. if ($this->EE->session->userdata['search_flood_control'] > 0 AND $this->EE->session->userdata['group_id'] != 1)
  95. {
  96. $cutoff = time() - $this->EE->session->userdata['search_flood_control'];
  97. $sql = "SELECT search_id FROM exp_search WHERE site_id = '".$this->EE->db->escape_str($this->EE->config->item('site_id'))."' AND search_date > '{$cutoff}' AND ";
  98. if ($this->EE->session->userdata['member_id'] != 0)
  99. {
  100. $sql .= "(member_id='".$this->EE->db->escape_str($this->EE->session->userdata('member_id'))."' OR ip_address='".$this->EE->db->escape_str($this->EE->input->ip_address())."')";
  101. }
  102. else
  103. {
  104. $sql .= "ip_address='".$this->EE->db->escape_str($this->EE->input->ip_address())."'";
  105. }
  106. $query = $this->EE->db->query($sql);
  107. $text = str_replace("%x", $this->EE->session->userdata['search_flood_control'], $this->EE->lang->line('search_time_not_expired'));
  108. if ($query->num_rows() > 0)
  109. {
  110. return $this->EE->output->show_user_error('general', array($text));
  111. }
  112. }
  113. /** ----------------------------------------
  114. /** Did the user submit any keywords?
  115. /** ----------------------------------------*/
  116. // We only require a keyword if the member name field is blank
  117. if ( ! isset($_GET['mbr']) OR ! is_numeric($_GET['mbr']))
  118. {
  119. if ( ! isset($_POST['member_name']) OR $_POST['member_name'] == '')
  120. {
  121. if ( ! isset($_POST['keywords']) OR $_POST['keywords'] == "")
  122. {
  123. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('search_no_keywords')));
  124. }
  125. }
  126. }
  127. /** ----------------------------------------
  128. /** Strip extraneous junk from keywords
  129. /** ----------------------------------------*/
  130. if ($_POST['keywords'] != "")
  131. {
  132. // Load the search helper so we can filter the keywords
  133. $this->EE->load->helper('search');
  134. $this->keywords = sanitize_search_terms($_POST['keywords']);
  135. /** ----------------------------------------
  136. /** Is the search term long enough?
  137. /** ----------------------------------------*/
  138. if (strlen($this->keywords) < $this->min_length)
  139. {
  140. $text = $this->EE->lang->line('search_min_length');
  141. $text = str_replace("%x", $this->min_length, $text);
  142. return $this->EE->output->show_user_error('general', array($text));
  143. }
  144. // Load the text helper
  145. $this->EE->load->helper('text');
  146. $this->keywords = ($this->EE->config->item('auto_convert_high_ascii') == 'y') ? ascii_to_entities($this->keywords) : $this->keywords;
  147. /** ----------------------------------------
  148. /** Remove "ignored" words
  149. /** ----------------------------------------*/
  150. if (( ! isset($_POST['exact_keyword']) OR $_POST['exact_keyword'] != 'y') && @include_once(APPPATH.'config/stopwords'.EXT))
  151. {
  152. $parts = explode('"', $this->keywords);
  153. $this->keywords = '';
  154. foreach($parts as $num => $part)
  155. {
  156. // The odd breaks contain quoted strings.
  157. if ($num % 2 == 0)
  158. {
  159. foreach ($ignore as $badword)
  160. {
  161. $part = preg_replace("/\b".preg_quote($badword, '/')."\b/i","", $part);
  162. }
  163. }
  164. $this->keywords .= ($num != 0) ? '"'.$part : $part;
  165. }
  166. if (trim($this->keywords) == '')
  167. {
  168. return $this->EE->output->show_user_error('general', array($this->EE->lang->line('search_no_stopwords')));
  169. }
  170. }
  171. /** ----------------------------------------
  172. /** Log Search Terms
  173. /** ----------------------------------------*/
  174. $this->EE->functions->log_search_terms($this->keywords);
  175. }
  176. if (isset($_POST['member_name']) AND $_POST['member_name'] != "")
  177. {
  178. $_POST['member_name'] = $this->EE->security->xss_clean($_POST['member_name']);
  179. }
  180. /** ----------------------------------------
  181. /** Build and run query
  182. /** ----------------------------------------*/
  183. $original_keywords = $this->keywords;
  184. $mbr = ( ! isset($_GET['mbr'])) ? '' : $_GET['mbr'];
  185. $sql = $this->build_standard_query();
  186. /** ----------------------------------------
  187. /** No query results?
  188. /** ----------------------------------------*/
  189. if ($sql == FALSE)
  190. {
  191. if (isset($_POST['NRP']) AND $_POST['NRP'] != '')
  192. {
  193. $hash = $this->EE->functions->random('md5');
  194. $data = array(
  195. 'search_id' => $hash,
  196. 'search_date' => time(),
  197. 'member_id' => $this->EE->session->userdata('member_id'),
  198. 'keywords' => ($original_keywords != '') ? $original_keywords : $mbr,
  199. 'ip_address' => $this->EE->input->ip_address(),
  200. 'total_results' => 0,
  201. 'per_page' => 0,
  202. 'query' => '',
  203. 'custom_fields' => '',
  204. 'result_page' => '',
  205. 'site_id' => $this->EE->config->item('site_id')
  206. );
  207. $this->EE->db->query($this->EE->db->insert_string('exp_search', $data));
  208. return $this->EE->functions->redirect($this->EE->functions->create_url($this->EE->functions->extract_path("='".$_POST['NRP']."'")).'/'.$hash.'/');
  209. }
  210. else
  211. {
  212. return $this->EE->output->show_user_error('off', array($this->EE->lang->line('search_no_result')), $this->EE->lang->line('search_result_heading'));
  213. }
  214. }
  215. /** ----------------------------------------
  216. /** If we have a result, cache it
  217. /** ----------------------------------------*/
  218. $hash = $this->EE->functions->random('md5');
  219. $sql = str_replace("\\", "\\\\", $sql);
  220. // This fixes a bug that occurs when a different table prefix is used
  221. $sql = str_replace('exp_', 'MDBMPREFIX', $sql);
  222. $data = array(
  223. 'search_id' => $hash,
  224. 'search_date' => time(),
  225. 'member_id' => $this->EE->session->userdata('member_id'),
  226. 'keywords' => ($original_keywords != '') ? $original_keywords : $mbr,
  227. 'ip_address' => $this->EE->input->ip_address(),
  228. 'total_results' => $this->num_rows,
  229. 'per_page' => (isset($_POST['RES']) AND is_numeric($_POST['RES']) AND $_POST['RES'] < 999 ) ? $_POST['RES'] : 50,
  230. 'query' => addslashes(serialize($sql)),
  231. 'custom_fields' => addslashes(serialize($this->fields)),
  232. 'result_page' => $_POST['RP'],
  233. 'site_id' => $this->EE->config->item('site_id')
  234. );
  235. $this->EE->db->query($this->EE->db->insert_string('exp_search', $data));
  236. /** ----------------------------------------
  237. /** Redirect to search results page
  238. /** ----------------------------------------*/
  239. // Load the string helper
  240. $this->EE->load->helper('string');
  241. $path = $this->EE->functions->remove_double_slashes($this->EE->functions->create_url(trim_slashes($_POST['RP'])).'/'.$hash.'/');
  242. return $this->EE->functions->redirect($path);
  243. }
  244. /** ---------------------------------------
  245. /** Create the search query
  246. /** ---------------------------------------*/
  247. function build_standard_query()
  248. {
  249. $this->EE->load->model('addons_model');
  250. $channel_array = array();
  251. /** ---------------------------------------
  252. /** Fetch the channel_id numbers
  253. /** ---------------------------------------*/
  254. // If $_POST['channel_id'] exists we know the request is coming from the
  255. // advanced search form. We set those values to the $channel_id_array
  256. if (isset($_POST['channel_id']) AND is_array($_POST['channel_id']))
  257. {
  258. $channel_id_array = $_POST['channel_id'];
  259. }
  260. // Since both the simple and advanced search form have
  261. // $_POST['channel'], then we can safely find all of the
  262. // channels available for searching
  263. // By doing this for the advanced search form, we can discover
  264. // Which channels we are or are not supposed to search for, when
  265. // "Any Channel" is chosen
  266. $sql = "SELECT channel_id FROM exp_channels WHERE site_id = '".$this->EE->db->escape_str($this->EE->config->item('site_id'))."'";
  267. if (isset($_POST['channel']) AND $_POST['channel'] != '')
  268. {
  269. $sql .= $this->EE->functions->sql_andor_string($_POST['channel'], 'channel_name');
  270. }
  271. $query = $this->EE->db->query($sql);
  272. foreach ($query->result_array() as $row)
  273. {
  274. $channel_array[] = $row['channel_id'];
  275. }
  276. /** ------------------------------------------------------
  277. /** Find the Common Channel IDs for Advanced Search Form
  278. /** ------------------------------------------------------*/
  279. if (isset($channel_id_array) && $channel_id_array['0'] != 'null')
  280. {
  281. $channel_array = array_intersect($channel_id_array, $channel_array);
  282. }
  283. /** ----------------------------------------------
  284. /** Fetch the channel_id numbers (from Advanced search)
  285. /** ----------------------------------------------*/
  286. // We do this up-front since we use this same sub-query in two places
  287. $id_query = '';
  288. if (count($channel_array) > 0)
  289. {
  290. foreach ($channel_array as $val)
  291. {
  292. if ($val != 'null' AND $val != '')
  293. {
  294. $id_query .= " exp_channel_titles.channel_id = '".$this->EE->db->escape_str($val)."' OR";
  295. }
  296. }
  297. if ($id_query != '')
  298. {
  299. $id_query = substr($id_query, 0, -2);
  300. $id_query = ' AND ('.$id_query.') ';
  301. }
  302. }
  303. /** ----------------------------------------------
  304. /** Limit to a specific member? We do this now
  305. /** as there's a potential for this to bring the
  306. /** search to an end if it's not a valid member
  307. /** ----------------------------------------------*/
  308. $member_array = array();
  309. $member_ids = '';
  310. if (isset($_GET['mbr']) AND is_numeric($_GET['mbr']))
  311. {
  312. $query = $this->EE->db->query("SELECT member_id FROM exp_members WHERE member_id = '".$this->EE->db->escape_str($_GET['mbr'])."'");
  313. if ($query->num_rows() != 1)
  314. {
  315. return FALSE;
  316. }
  317. else
  318. {
  319. $member_array[] = $query->row('member_id');
  320. }
  321. }
  322. else
  323. {
  324. if ($this->EE->input->post('member_name') != '')
  325. {
  326. $sql = "SELECT member_id FROM exp_members WHERE screen_name ";
  327. if ($this->EE->input->post('exact_match') == 'y')
  328. {
  329. $sql .= " = '".$this->EE->db->escape_str($this->EE->input->post('member_name'))."' ";
  330. }
  331. else
  332. {
  333. $sql .= " LIKE '%".$this->EE->db->escape_like_str($this->EE->input->post('member_name'))."%' ";
  334. }
  335. $query = $this->EE->db->query($sql);
  336. if ($query->num_rows() == 0)
  337. {
  338. return FALSE;
  339. }
  340. else
  341. {
  342. foreach ($query->result_array() as $row)
  343. {
  344. $member_array[] = $row['member_id'];
  345. }
  346. }
  347. }
  348. }
  349. // and turn it into a string now so we only implode once
  350. if (count($member_array) > 0)
  351. {
  352. $member_ids = ' IN ('.implode(',', $member_array).') ';
  353. }
  354. unset($member_array);
  355. /** ---------------------------------------
  356. /** Fetch the searchable field names
  357. /** ---------------------------------------*/
  358. $fields = array();
  359. // no need to do this unless there are keywords to search
  360. if (trim($this->keywords) != '')
  361. {
  362. $xql = "SELECT DISTINCT(field_group) FROM exp_channels WHERE site_id = '".$this->EE->db->escape_str($this->EE->config->item('site_id'))."'";
  363. if ($id_query != '')
  364. {
  365. $xql .= $id_query.' ';
  366. $xql = str_replace('exp_channel_titles.', '', $xql);
  367. }
  368. $query = $this->EE->db->query($xql);
  369. if ($query->num_rows() > 0)
  370. {
  371. $fql = "SELECT field_id, field_name, field_search FROM exp_channel_fields WHERE (";
  372. foreach ($query->result_array() as $row)
  373. {
  374. $fql .= " group_id = '".$row['field_group']."' OR";
  375. }
  376. $fql = substr($fql, 0, -2).')';
  377. $query = $this->EE->db->query($fql);
  378. if ($query->num_rows() > 0)
  379. {
  380. foreach ($query->result_array() as $row)
  381. {
  382. if ($row['field_search'] == 'y')
  383. {
  384. $fields[] = $row['field_id'];
  385. }
  386. $this->fields[$row['field_name']] = array($row['field_id'], $row['field_search']);
  387. }
  388. }
  389. }
  390. }
  391. /** ---------------------------------------
  392. /** Build the main query
  393. /** ---------------------------------------*/
  394. $sql = "SELECT
  395. DISTINCT(exp_channel_titles.entry_id)
  396. FROM exp_channel_titles
  397. LEFT JOIN exp_channels ON exp_channel_titles.channel_id = exp_channels.channel_id
  398. LEFT JOIN exp_channel_data ON exp_channel_titles.entry_id = exp_channel_data.entry_id ";
  399. // is the comment module installed?
  400. if ($this->EE->addons_model->module_installed('comments'))
  401. {
  402. $sql .= "LEFT JOIN exp_comments ON exp_channel_titles.entry_id = exp_comments.entry_id";
  403. }
  404. $sql .= "
  405. LEFT JOIN exp_category_posts ON exp_channel_titles.entry_id = exp_category_posts.entry_id
  406. LEFT JOIN exp_categories ON exp_category_posts.cat_id = exp_categories.cat_id
  407. WHERE exp_channels.site_id = '".$this->EE->db->escape_str($this->EE->config->item('site_id'))."' ";
  408. /** ----------------------------------------------
  409. /** We only select entries that have not expired
  410. /** ----------------------------------------------*/
  411. if ( ! isset($_POST['show_future_entries']) OR $_POST['show_future_entries'] != 'yes')
  412. {
  413. $sql .= "\nAND exp_channel_titles.entry_date < ".$this->EE->localize->now." ";
  414. }
  415. if ( ! isset($_POST['show_expired']) OR $_POST['show_expired'] != 'yes')
  416. {
  417. $sql .= "\nAND (exp_channel_titles.expiration_date = 0 OR exp_channel_titles.expiration_date > ".$this->EE->localize->now.") ";
  418. }
  419. /** ----------------------------------------------
  420. /** Add status declaration to the query
  421. /** ----------------------------------------------*/
  422. $sql .= "\nAND exp_channel_titles.status != 'closed' ";
  423. if (($status = $this->EE->input->get_post('status')) !== FALSE)
  424. {
  425. $status = str_replace('Open', 'open', $status);
  426. $status = str_replace('Closed', 'closed', $status);
  427. $sql .= $this->EE->functions->sql_andor_string($status, 'exp_channel_titles.status');
  428. // add exclusion for closed unless it was explicitly used
  429. if (strncasecmp($status, 'not ', 4) == 0)
  430. {
  431. $status = trim(substr($status, 3));
  432. }
  433. $stati = explode('|', $status);
  434. if ( ! in_array('closed', $stati))
  435. {
  436. $sql .= "\nAND exp_channel_titles.status != 'closed' ";
  437. }
  438. }
  439. else
  440. {
  441. $sql .= "AND exp_channel_titles.status = 'open' ";
  442. }
  443. /** ----------------------------------------------
  444. /** Set Date filtering
  445. /** ----------------------------------------------*/
  446. if (isset($_POST['date']) AND $_POST['date'] != 0)
  447. {
  448. $cutoff = $this->EE->localize->now - (60*60*24*$_POST['date']);
  449. if (isset($_POST['date_order']) AND $_POST['date_order'] == 'older')
  450. {
  451. $sql .= "AND exp_channel_titles.entry_date < ".$cutoff." ";
  452. }
  453. else
  454. {
  455. $sql .= "AND exp_channel_titles.entry_date > ".$cutoff." ";
  456. }
  457. }
  458. /** ----------------------------------------------
  459. /** Add keyword to the query
  460. /** ----------------------------------------------*/
  461. if (trim($this->keywords) != '')
  462. {
  463. // So it begins
  464. $sql .= "\nAND (";
  465. /** -----------------------------------------
  466. /** Process our Keywords into Search Terms
  467. /** -----------------------------------------*/
  468. $this->keywords = stripslashes($this->keywords);
  469. $terms = array();
  470. $criteria = (isset($_POST['where']) && $_POST['where'] == 'all') ? 'AND' : 'OR';
  471. if (preg_match_all("/\-*\"(.*?)\"/", $this->keywords, $matches))
  472. {
  473. for($m=0; $m < count($matches['1']); $m++)
  474. {
  475. $terms[] = trim(str_replace('"','',$matches['0'][$m]));
  476. $this->keywords = str_replace($matches['0'][$m],'', $this->keywords);
  477. }
  478. }
  479. if (trim($this->keywords) != '')
  480. {
  481. $terms = array_merge($terms, preg_split("/\s+/", trim($this->keywords)));
  482. }
  483. $not_and = (count($terms) > 2) ? ') AND (' : 'AND';
  484. rsort($terms);
  485. $terms_like = $this->EE->db->escape_like_str($terms);
  486. $terms = $this->EE->db->escape_str($terms);
  487. /** ----------------------------------
  488. /** Search in Title Field
  489. /** ----------------------------------*/
  490. if (count($terms) == 1 && isset($_POST['where']) && $_POST['where'] == 'word') // Exact word match
  491. {
  492. $sql .= "((exp_channel_titles.title = '".$terms['0']."' OR exp_channel_titles.title LIKE '".$terms_like['0']." %' OR exp_channel_titles.title LIKE '% ".$terms_like['0']." %') ";
  493. // and close up the member clause
  494. if ($member_ids != '')
  495. {
  496. $sql .= " AND (exp_channel_titles.author_id {$member_ids})) \n";
  497. }
  498. else
  499. {
  500. $sql .= ") \n";
  501. }
  502. }
  503. elseif ( ! isset($_POST['exact_keyword'])) // Any terms, all terms
  504. {
  505. $mysql_function = (substr($terms['0'], 0,1) == '-') ? 'NOT LIKE' : 'LIKE';
  506. $search_term = (substr($terms['0'], 0,1) == '-') ? substr($terms_like['0'], 1) : $terms_like['0'];
  507. // We have three parentheses in the beginning in case
  508. // there are any NOT LIKE's being used and to allow for a member clause
  509. $sql .= "\n(((exp_channel_titles.title $mysql_function '%".$search_term."%' ";
  510. for ($i=1; $i < count($terms); $i++)
  511. {
  512. $mysql_criteria = ($mysql_function == 'NOT LIKE' OR substr($terms[$i], 0,1) == '-') ? $not_and : $criteria;
  513. $mysql_function = (substr($terms[$i], 0,1) == '-') ? 'NOT LIKE' : 'LIKE';
  514. $search_term = (substr($terms[$i], 0,1) == '-') ? substr($terms_like[$i], 1) : $terms_like[$i];
  515. $sql .= "$mysql_criteria exp_channel_titles.title $mysql_function '%".$search_term."%' ";
  516. }
  517. $sql .= ")) ";
  518. // and close up the member clause
  519. if ($member_ids != '')
  520. {
  521. $sql .= " AND (exp_channel_titles.author_id {$member_ids})) \n";
  522. }
  523. else
  524. {
  525. $sql .= ") \n";
  526. }
  527. }
  528. else // exact phrase match
  529. {
  530. $search_term = (count($terms) == 1) ? $terms_like[0] : $this->EE->db->escape_str($this->keywords);
  531. $sql .= "(exp_channel_titles.title LIKE '%".$search_term."%' ";
  532. // and close up the member clause
  533. if ($member_ids != '')
  534. {
  535. $sql .= " AND (exp_channel_titles.author_id {$member_ids})) \n";
  536. }
  537. else
  538. {
  539. $sql .= ") \n";
  540. }
  541. }
  542. /** ----------------------------------
  543. /** Search in Searchable Fields
  544. /** ----------------------------------*/
  545. if (isset($_POST['search_in']) AND ($_POST['search_in'] == 'entries' OR $_POST['search_in'] == 'everywhere'))
  546. {
  547. if (count($terms) > 1 && isset($_POST['where']) && $_POST['where'] == 'all' && ! isset($_POST['exact_keyword']) && count($fields) > 0)
  548. {
  549. $concat_fields = "CAST(CONCAT_WS(' ', exp_channel_data.field_id_".implode(', exp_channel_data.field_id_', $fields).') AS CHAR)';
  550. $mysql_function = (substr($terms['0'], 0,1) == '-') ? 'NOT LIKE' : 'LIKE';
  551. $search_term = (substr($terms['0'], 0,1) == '-') ? substr($terms['0'], 1) : $terms['0'];
  552. // Since Title is always required in a search we use OR
  553. // And then three parentheses just like above in case
  554. // there are any NOT LIKE's being used and to allow for a member clause
  555. $sql .= "\nOR ((($concat_fields $mysql_function '%".$search_term."%' ";
  556. for ($i=1; $i < count($terms); $i++)
  557. {
  558. $mysql_criteria = ($mysql_function == 'NOT LIKE' OR substr($terms[$i], 0,1) == '-') ? $not_and : $criteria;
  559. $mysql_function = (substr($terms[$i], 0,1) == '-') ? 'NOT LIKE' : 'LIKE';
  560. $search_term = (substr($terms[$i], 0,1) == '-') ? substr($terms_like[$i], 1) : $terms_like[$i];
  561. $sql .= "$mysql_criteria $concat_fields $mysql_function '%".$search_term."%' ";
  562. }
  563. $sql .= ")) ";
  564. // and close up the member clause
  565. if ($member_ids != '')
  566. {
  567. $sql .= " AND (exp_channel_titles.author_id {$member_ids})) \n";
  568. }
  569. else
  570. {
  571. $sql .= ") \n";
  572. }
  573. }
  574. else
  575. {
  576. foreach ($fields as $val)
  577. {
  578. if (count($terms) == 1 && isset($_POST['where']) && $_POST['where'] == 'word')
  579. {
  580. $sql .= "\nOR ((exp_channel_data.field_id_".$val." LIKE '".$terms_like['0']." %' OR exp_channel_data.field_id_".$val." LIKE '% ".$terms_like['0']." %' OR exp_channel_data.field_id_".$val." LIKE '% ".$terms_like['0']." %' OR exp_channel_data.field_id_".$val." = '".$terms['0']."') ";
  581. // and close up the member clause
  582. if ($member_ids != '')
  583. {
  584. $sql .= " AND (exp_channel_titles.author_id {$member_ids})) ";
  585. }
  586. else
  587. {
  588. $sql .= ") ";
  589. }
  590. }
  591. elseif ( ! isset($_POST['exact_keyword']))
  592. {
  593. $mysql_function = (substr($terms['0'], 0,1) == '-') ? 'NOT LIKE' : 'LIKE';
  594. $search_term = (substr($terms['0'], 0,1) == '-') ? substr($terms_like['0'], 1) : $terms_like['0'];
  595. // Since Title is always required in a search we use OR
  596. // And then three parentheses just like above in case
  597. // there are any NOT LIKE's being used and to allow for a member clause
  598. $sql .= "\nOR (((exp_channel_data.field_id_".$val." $mysql_function '%".$search_term."%' ";
  599. for ($i=1; $i < count($terms); $i++)
  600. {
  601. $mysql_criteria = ($mysql_function == 'NOT LIKE' OR substr($terms[$i], 0,1) == '-') ? $not_and : $criteria;
  602. $mysql_function = (substr($terms[$i], 0,1) == '-') ? 'NOT LIKE' : 'LIKE';
  603. $search_term = (substr($terms[$i], 0,1) == '-') ? substr($terms_like[$i], 1) : $terms_like[$i];
  604. $sql .= "$mysql_criteria exp_channel_data.field_id_".$val." $mysql_function '%".$search_term."%' ";
  605. }
  606. $sql .= ")) ";
  607. // and close up the member clause
  608. if ($member_ids != '')
  609. {
  610. $sql .= " AND (exp_channel_titles.author_id {$member_ids})) \n";
  611. }
  612. else
  613. {
  614. // close up the extra parenthesis
  615. $sql .= ") \n";
  616. }
  617. }
  618. else
  619. {
  620. $search_term = (count($terms) == 1) ? $terms_like[0] : $this->EE->db->escape_str($this->keywords);
  621. $sql .= "\nOR (exp_channel_data.field_id_".$val." LIKE '%".$search_term."%' ";
  622. // and close up the member clause
  623. if ($member_ids != '')
  624. {
  625. $sql .= " AND (exp_channel_titles.author_id {$member_ids})) \n";
  626. }
  627. else
  628. {
  629. // close up the extra parenthesis
  630. $sql .= ") \n";
  631. }
  632. }
  633. }
  634. }
  635. }
  636. /** ----------------------------------
  637. /** Search in Comments
  638. /** ----------------------------------*/
  639. if (isset($_POST['search_in']) AND $_POST['search_in'] == 'everywhere' AND $this->EE->addons_model->module_installed('comments'))
  640. {
  641. if (count($terms) == 1 && isset($_POST['where']) && $_POST['where'] == 'word')
  642. {
  643. $sql .= " OR (exp_comments.comment LIKE '% ".$terms_like['0']." %' ";
  644. // and close up the member clause
  645. if ($member_ids != '')
  646. {
  647. $sql .= " AND (exp_comments.author_id {$member_ids})) \n";
  648. }
  649. else
  650. {
  651. // close up the extra parenthesis
  652. $sql .= ") \n";
  653. }
  654. }
  655. elseif ( ! isset($_POST['exact_keyword']))
  656. {
  657. $mysql_function = (substr($terms['0'], 0,1) == '-') ? 'NOT LIKE' : 'LIKE';
  658. $search_term = (substr($terms['0'], 0,1) == '-') ? substr($terms_like['0'], 1) : $terms_like['0'];
  659. // We have three parentheses in the beginning in case
  660. // there are any NOT LIKE's being used and to allow a member clause
  661. $sql .= "\nOR (((exp_comments.comment $mysql_function '%".$search_term."%' ";
  662. for ($i=1; $i < count($terms); $i++)
  663. {
  664. $mysql_criteria = ($mysql_function == 'NOT LIKE' OR substr($terms[$i], 0,1) == '-') ? $not_and : $criteria;
  665. $mysql_function = (substr($terms[$i], 0,1) == '-') ? 'NOT LIKE' : 'LIKE';
  666. $search_term = (substr($terms[$i], 0,1) == '-') ? substr($terms_like[$i], 1) : $terms_like[$i];
  667. $sql .= "$mysql_criteria exp_comments.comment $mysql_function '%".$search_term."%' ";
  668. }
  669. $sql .= ")) ";
  670. // and close up the member clause
  671. if ($member_ids != '')
  672. {
  673. $sql .= " AND (exp_comments.author_id {$member_ids})) \n";
  674. }
  675. else
  676. {
  677. // close up the extra parenthesis
  678. $sql .= ") \n";
  679. }
  680. }
  681. else
  682. {
  683. $search_term = (count($terms) == 1) ? $terms_like[0] : $this->EE->db->escape_str($this->keywords);
  684. $sql .= " OR ((exp_comments.comment LIKE '%".$search_term."%') ";
  685. // and close up the member clause
  686. if ($member_ids != '')
  687. {
  688. $sql .= " AND (exp_comments.author_id {$member_ids})) \n";
  689. }
  690. else
  691. {
  692. // close up the extra parenthesis
  693. $sql .= ") \n";
  694. }
  695. }
  696. }
  697. // So it ends
  698. $sql .= ") \n";
  699. }
  700. else
  701. {
  702. // there are no keywords at all. Do we still need a member search?
  703. if ($member_ids != '')
  704. {
  705. $sql .= "AND (exp_channel_titles.author_id {$member_ids} ";
  706. // searching comments too?
  707. if (isset($_POST['search_in']) AND $_POST['search_in'] == 'everywhere' AND $this->EE->addons_model->module_installed('comments'))
  708. {
  709. $sql .= " OR exp_comments.author_id {$member_ids}";
  710. }
  711. $sql .= ")";
  712. }
  713. }
  714. //exit($sql);
  715. /** ----------------------------------------------
  716. /** Limit query to a specific channel
  717. /** ----------------------------------------------*/
  718. if (count($channel_array) > 0)
  719. {
  720. $sql .= $id_query;
  721. }
  722. /** ----------------------------------------------
  723. /** Limit query to a specific category
  724. /** ----------------------------------------------*/
  725. if (isset($_POST['cat_id']) AND is_array($_POST['cat_id']))
  726. {
  727. $temp = '';
  728. foreach ($_POST['cat_id'] as $val)
  729. {
  730. if ($val != 'all' AND $val != '')
  731. {
  732. $temp .= " exp_categories.cat_id = '".$this->EE->db->escape_str($val)."' OR";
  733. }
  734. }
  735. if ($temp != '')
  736. {
  737. $temp = substr($temp, 0, -2);
  738. $sql .= ' AND ('.$temp.') ';
  739. }
  740. }
  741. /** ----------------------------------------------
  742. /** Are there results?
  743. /** ----------------------------------------------*/
  744. $query = $this->EE->db->query($sql);
  745. if ($query->num_rows() == 0)
  746. {
  747. return FALSE;
  748. }
  749. $this->num_rows = $query->num_rows();
  750. /** ----------------------------------------------
  751. /** Set sort order
  752. /** ----------------------------------------------*/
  753. $order_by = ( ! isset($_POST['order_by'])) ? 'date' : $_POST['order_by'];
  754. $orderby = ( ! isset($_POST['orderby'])) ? $order_by : $_POST['orderby'];
  755. $end = '';
  756. switch ($orderby)
  757. {
  758. case 'most_comments' : $end .= " ORDER BY comment_total ";
  759. break;
  760. case 'recent_comment' : $end .= " ORDER BY recent_comment_date ";
  761. break;
  762. case 'title' : $end .= " ORDER BY title ";
  763. break;
  764. default : $end .= " ORDER BY entry_date ";
  765. break;
  766. }
  767. $order = ( ! isset($_POST['sort_order'])) ? 'desc' : $_POST['sort_order'];
  768. if ($order != 'asc' AND $order != 'desc')
  769. $order = 'desc';
  770. $end .= " ".$order;
  771. $sql = "SELECT DISTINCT(t.entry_id), t.entry_id, t.channel_id, t.forum_topic_id, t.author_id, t.ip_address, t.title, t.url_title, t.status, t.dst_enabled, t.view_count_one, t.view_count_two, t.view_count_three, t.view_count_four, t.allow_comments, t.comment_expiration_date, t.sticky, t.entry_date, t.year, t.month, t.day, t.entry_date, t.edit_date, t.expiration_date, t.recent_comment_date, t.comment_total, t.site_id as entry_site_id,
  772. w.channel_title, w.channel_name, w.search_results_url, w.search_excerpt, w.channel_url, w.comment_url, w.comment_moderate, w.channel_html_formatting, w.channel_allow_img_urls, w.channel_auto_link_urls, w.comment_system_enabled,
  773. m.username, m.email, m.url, m.screen_name, m.location, m.occupation, m.interests, m.aol_im, m.yahoo_im, m.msn_im, m.icq, m.signature, m.sig_img_filename, m.sig_img_width, m.sig_img_height, m.avatar_filename, m.avatar_width, m.avatar_height, m.photo_filename, m.photo_width, m.photo_height, m.group_id, m.member_id, m.bday_d, m.bday_m, m.bday_y, m.bio,
  774. md.*,
  775. wd.*
  776. FROM exp_channel_titles AS t
  777. LEFT JOIN exp_channels AS w ON t.channel_id = w.channel_id
  778. LEFT JOIN exp_channel_data AS wd ON t.entry_id = wd.entry_id
  779. LEFT JOIN exp_members AS m ON m.member_id = t.author_id
  780. LEFT JOIN exp_member_data AS md ON md.member_id = m.member_id
  781. WHERE t.entry_id IN (";
  782. foreach ($query->result_array() as $row)
  783. {
  784. $sql .= $row['entry_id'].',';
  785. }
  786. $sql = substr($sql, 0, -1).') '.$end;
  787. return $sql;
  788. }
  789. /** ----------------------------------------
  790. /** Total search results
  791. /** ----------------------------------------*/
  792. function total_results()
  793. {
  794. /** ----------------------------------------
  795. /** Check search ID number
  796. /** ----------------------------------------*/
  797. // If the QSTR variable is less than 32 characters long we
  798. // don't have a valid search ID number
  799. if (strlen($this->EE->uri->query_string) < 32)
  800. {
  801. return '';
  802. }
  803. /** ----------------------------------------
  804. /** Fetch ID number and page number
  805. /** ----------------------------------------*/
  806. $search_id = substr($this->EE->uri->query_string, 0, 32);
  807. /** ----------------------------------------
  808. /** Fetch the cached search query
  809. /** ----------------------------------------*/
  810. $query = $this->EE->db->query("SELECT total_results FROM exp_search WHERE search_id = '".$this->EE->db->escape_str($search_id)."'");
  811. if ($query->num_rows() == 1)
  812. {
  813. return $query->row('total_results') ;
  814. }
  815. else
  816. {
  817. return 0;
  818. }
  819. }
  820. /** ----------------------------------------
  821. /** Search keywords
  822. /** ----------------------------------------*/
  823. function keywords()
  824. {
  825. /** ----------------------------------------
  826. /** Check search ID number
  827. /** ----------------------------------------*/
  828. // If the QSTR variable is less than 32 characters long we
  829. // don't have a valid search ID number
  830. if (strlen($this->EE->uri->query_string) < 32)
  831. {
  832. return '';
  833. }
  834. /** ----------------------------------------
  835. /** Fetch ID number and page number
  836. /** ----------------------------------------*/
  837. $search_id = substr($this->EE->uri->query_string, 0, 32);
  838. /** ----------------------------------------
  839. /** Fetch the cached search query
  840. /** ----------------------------------------*/
  841. $query = $this->EE->db->query("SELECT keywords FROM exp_search WHERE search_id = '".$this->EE->db->escape_str($search_id)."'");
  842. if ($query->num_rows() == 1)
  843. {
  844. // Load the XML Helper
  845. $this->EE->load->helper('xml');
  846. return $this->EE->functions->encode_ee_tags(xml_convert($query->row('keywords')));
  847. }
  848. else
  849. {
  850. return '';
  851. }
  852. }
  853. /** ----------------------------------------
  854. /** Show search results
  855. /** ----------------------------------------*/
  856. function search_results()
  857. {
  858. // Fetch the search language file
  859. $this->EE->lang->loadfile('search');
  860. // Check search ID number
  861. // If the QSTR variable is less than 32 characters long we
  862. // don't have a valid search ID number
  863. if (strlen($this->EE->uri->query_string) < 32)
  864. {
  865. return $this->EE->output->show_user_error('off', array($this->EE->lang->line('search_no_result')), $this->EE->lang->line('search_result_heading'));
  866. }
  867. // Clear old search results
  868. $expire = time() - ($this->cache_expire * 3600);
  869. $this->EE->db->query("DELETE FROM exp_search WHERE site_id = '".$this->EE->db->escape_str($this->EE->config->item('site_id'))."' AND search_date < '$expire'");
  870. // Fetch ID number and page number
  871. $cur_page = 0;
  872. $qstring = $this->EE->uri->query_string;
  873. // Parse page number
  874. if (preg_match("#^P(\d+)|/P(\d+)#", $qstring, $match))
  875. {
  876. $cur_page = (isset($match[2])) ? $match[2] : $match[1];
  877. $search_id = trim_slashes(str_replace($match[0], '', $qstring));
  878. }
  879. else
  880. {
  881. $search_id = $qstring;
  882. }
  883. // If there is a slash in the search ID we'll kill everything after it.
  884. $search_id = trim($search_id);
  885. $search_id = preg_replace("#/.+#", "", $search_id);
  886. // Fetch the cached search query
  887. $query = $this->EE->db->get_where('search', array('search_id' => $search_id));
  888. if ($query->num_rows() == 0 OR $query->row('total_results') == 0)
  889. {
  890. return $this->EE->output->show_user_error('off', array($this->EE->lang->line('search_no_result')), $this->EE->lang->line('search_result_heading'));
  891. }
  892. $fields = ($query->row('custom_fields') == '') ? array() : unserialize(stripslashes($query->row('custom_fields') ));
  893. $sql = unserialize(stripslashes($query->row('query')));
  894. $sql = str_replace('MDBMPREFIX', 'exp_', $sql);
  895. $per_page = $query->row('per_page');
  896. $res_page = $query->row('result_page');
  897. // Run the search query
  898. $query = $this->EE->db->query(preg_replace("/SELECT(.*?)\s+FROM\s+/is", 'SELECT COUNT(*) AS count FROM ', $sql));
  899. if ($query->row('count') == 0)
  900. {
  901. return $this->EE->output->show_user_error('off', array($this->EE->lang->line('search_no_result')), $this->EE->lang->line('search_result_heading'));
  902. }
  903. // Calculate total number of pages
  904. $current_page = ($cur_page / $per_page) + 1;
  905. $total_pages = intval($query->row('count') / $per_page);
  906. if ($query->row('count') % $per_page)
  907. {
  908. $total_pages++;
  909. }
  910. $page_count = $this->EE->lang->line('page').' '.$current_page.' '.$this->EE->lang->line('of').' '.$total_pages;
  911. // Do we need pagination?
  912. // If so, we'll add the LIMIT clause to the SQL statement and run the query again
  913. $pager = '';
  914. if ($query->row('count') > $per_page)
  915. {
  916. $this->EE->load->library('pagination');
  917. $config = array(
  918. 'base_url' => $this->EE->functions->create_url($res_page.'/'.$search_id, 0, 0),
  919. 'prefix' => 'P',
  920. 'total_rows' => $query->row('count'),
  921. 'per_page' => $per_page,
  922. 'cur_page' => $cur_page,
  923. 'first_link' => $this->EE->lang->line('pag_first_link'),
  924. 'last_link' => $this->EE->lang->line('pag_last_link'),
  925. 'uri_segment' => 0 // Allows $config['cur_page'] to override
  926. );
  927. $this->EE->pagination->initialize($config);
  928. $pager = $this->EE->pagination->create_links();
  929. $sql .= " LIMIT ".$cur_page.", ".$per_page;
  930. }
  931. $query = $this->EE->db->query($sql);
  932. $output = '';
  933. if ( ! class_exists('Channel'))
  934. {
  935. require PATH_MOD.'channel/mod.channel'.EXT;
  936. }
  937. unset($this->EE->TMPL->var_single['auto_path']);
  938. unset($this->EE->TMPL->var_single['excerpt']);
  939. unset($this->EE->TMPL->var_single['id_auto_path']);
  940. unset($this->EE->TMPL->var_single['full_text']);
  941. unset($this->EE->TMPL->var_single['switch']);
  942. foreach($this->EE->TMPL->var_single as $key => $value)
  943. {
  944. if (substr($key, 0, strlen('member_path')) == 'member_path')
  945. {
  946. unset($this->EE->TMPL->var_single[$key]);
  947. }
  948. }
  949. $channel = new Channel;
  950. // This allows the channel {absolute_count} variable to work
  951. $channel->p_page = ($per_page * $current_page) - $per_page;
  952. $channel->fetch_custom_channel_fields();
  953. $channel->fetch_custom_member_fields();
  954. $channel->query = $this->EE->db->query($sql);
  955. if ($channel->query->num_rows() == 0)
  956. {
  957. return $this->EE->TMPL->no_results();
  958. }
  959. $this->EE->load->library('typography');
  960. $this->EE->typography->initialize();
  961. $this->EE->typography->convert_curly = FALSE;
  962. $this->EE->typography->encode_email = FALSE;
  963. $channel->fetch_categories();
  964. $channel->parse_channel_entries();
  965. $tagdata = $this->EE->TMPL->tagdata;
  966. // Does the tag contain "related entries" that we need to parse out?
  967. if (count($this->EE->TMPL->related_data) > 0 AND count($channel->related_entries) > 0)
  968. {
  969. $channel->parse_related_entries();
  970. }
  971. if (count($this->EE->TMPL->reverse_related_data) > 0 AND count($channel->reverse_related_entries) > 0)
  972. {
  973. $channel->parse_reverse_related_entries();
  974. }
  975. $output = $channel->return_data;
  976. $this->EE->TMPL->tagdata = $tagdata;
  977. // Fetch member path variable
  978. // We do it here in case it's used in multiple places.
  979. $m_paths = array();
  980. if (preg_match_all("/".LD."member_path(\s*=.*?)".RD."/s", $this->EE->TMPL->tagdata, $matches))
  981. {
  982. for ($j = 0; $j < count($matches['0']); $j++)
  983. {
  984. $m_paths[] = array($matches['0'][$j], $this->EE->functions->extract_path($matches['1'][$j]));
  985. }
  986. }
  987. // Fetch switch param
  988. $switch1 = '';
  989. $switch2 = '';
  990. if ($switch = $this->EE->TMPL->fetch_param('switch'))
  991. {
  992. if (strpos($switch, '|') !== FALSE)
  993. {
  994. $x = explode("|", $switch);
  995. $switch1 = $x['0'];
  996. $switch2 = $x['1'];
  997. }
  998. else
  999. {
  1000. $switch1 = $switch;
  1001. }
  1002. }
  1003. /** -----------------------------
  1004. /** Result Loop - Legacy!
  1005. /** -----------------------------*/
  1006. $i = 0;
  1007. foreach ($query->result_array() as $row)
  1008. {
  1009. if (isset($row['field_id_'.$row['search_excerpt']]) AND $row['field_id_'.$row['search_excerpt']])
  1010. {
  1011. $format = ( ! isset($row['field_ft_'.$row['search_excerpt']])) ? 'xhtml' : $row['field_ft_'.$row['search_excerpt']];
  1012. $full_text = $this->EE->typography->parse_type(strip_tags($row['field_id_'.$row['search_excerpt']]),
  1013. array(
  1014. 'text_format' => $format,
  1015. 'html_format' => 'safe',
  1016. 'auto_links' => 'y',
  1017. 'allow_img_url' => 'n'
  1018. ));
  1019. $excerpt = trim(strip_tags($full_text));
  1020. if (strpos($excerpt, "\r") !== FALSE OR strpos($excerpt, "\n") !== FALSE)
  1021. {
  1022. $excerpt = str_replace(array("\r\n", "\r", "\n"), " ", $excerpt);
  1023. }
  1024. $excerpt = $this->EE->functions->word_limiter($excerpt, 50);
  1025. }
  1026. else
  1027. {
  1028. $excerpt = '';
  1029. $full_text = '';
  1030. }
  1031. // Parse permalink path
  1032. $url = ($row['search_results_url'] != '') ? $row['search_results_url'] : $row['channel_url'];
  1033. $path = $this->EE->functions->remove_double_slashes($this->EE->functions->prep_query_string($url).'/'.$row['url_title']);
  1034. $idpath = $this->EE->functions->remove_double_slashes($this->EE->functions->prep_query_string($url).'/'.$row['entry_id']);
  1035. $switch = ($i++ % 2) ? $switch1 : $switch2;
  1036. $output = preg_replace("/".LD.'switch'.RD."/", $switch, $output, count(explode(LD.'switch'.RD, $this->EE->TMPL->tagdata)) - 1);
  1037. $output = preg_replace("/".LD.'auto_path'.RD."/", $path, $output, count(explode(LD.'auto_path'.RD, $this->EE->TMPL->tagdata)) - 1);
  1038. $output = preg_replace("/".LD.'id_auto_path'.RD."/", $idpath, $output, count(explode(LD.'id_auto_path'.RD, $this->EE->TMPL->tagdata)) - 1);
  1039. $output = preg_replace("/".LD.'excerpt'.RD."/", preg_quote($excerpt), $output, count(explode(LD.'excerpt'.RD, $this->EE->TMPL->tagdata)) - 1);
  1040. $output = preg_replace("/".LD.'full_text'.RD."/", preg_quote($full_text), $output, count(explode(LD.'full_text'.RD, $this->EE->TMPL->tagdata)) - 1);
  1041. // Parse member_path
  1042. if (count($m_paths) > 0)
  1043. {
  1044. foreach ($m_paths as $val)
  1045. {
  1046. $output = preg_replace("/".preg_quote($val['0'], '/')."/", $this->EE->functions->create_url($val['1'].'/'.$row['member_id']), $output, 1);
  1047. }
  1048. }
  1049. }
  1050. $this->EE->TMPL->tagdata = $output;
  1051. /** ----------------------------------------
  1052. /** Parse variables
  1053. /** ----------------------------------------*/
  1054. $swap = array(
  1055. 'lang:total_search_results' => $this->EE->lang->line('search_total_results'),
  1056. 'lang:search_engine' => $this->EE->lang->line('search_engine'),
  1057. 'lang:search_results' => $this->EE->lang->line('search_results'),
  1058. 'lang:search' => $this->EE->lang->line('search'),
  1059. 'lang:title' => $this->EE->lang->line('search_title'),
  1060. 'lang:channel' => $this->EE->lang->line('search_channel'),
  1061. 'lang:excerpt' => $this->EE->lang->line('search_excerpt'),
  1062. 'lang:author' => $this->EE->lang->line('search_author'),
  1063. 'lang:date' => $this->EE->lang->line('search_date'),
  1064. 'lang:total_comments' => $this->EE->lang->line('search_total_comments'),
  1065. 'lang:recent_comments' => $this->EE->lang->line('search_recent_comment_date'),
  1066. 'lang:keywords' => $this->EE->lang->line('search_keywords')
  1067. );
  1068. $this->EE->TMPL->template = $this->EE->functions->var_swap($this->EE->TMPL->template, $swap);
  1069. /** ----------------------------------------
  1070. /** Add Pagination
  1071. /** ----------------------------------------*/
  1072. if ($pager == '')
  1073. {
  1074. $this->EE->TMPL->template = preg_replace("#".LD."if paginate".RD.".*?".LD."/if".RD."#s", '', $this->EE->TMPL->template);
  1075. }
  1076. else
  1077. {
  1078. $this->EE->TMPL->template = preg_replace("#".LD."if paginate".RD."(.*?)".LD."/if".RD."#s", "\\1", $this->EE->TMPL->template);
  1079. }
  1080. $this->EE->TMPL->template = str_replace(LD.'paginate'.RD, $pager, $this->EE->TMPL->template);
  1081. $this->EE->TMPL->template = str_replace(LD.'page_count'.RD, $page_count, $this->EE->TMPL->template);
  1082. return stripslashes($this->EE->TMPL->tagdata);
  1083. }
  1084. /** ----------------------------------------
  1085. /** Simple Search Form
  1086. /** ----------------------------------------*/
  1087. function simple_form()
  1088. {
  1089. /** ----------------------------------------
  1090. /** Create form
  1091. /** ----------------------------------------*/
  1092. $result_page = ( ! $this->EE->TMPL->fetch_param('result_page')) ? 'search/results' : $this->EE->TMPL->fetch_param('result_page');
  1093. $data['hidden_fields'] = array(
  1094. 'ACT' => $this->EE->functions->fetch_action_id('Search', 'do_search'),
  1095. 'XID' => '',
  1096. 'RP' => $result_page,
  1097. 'NRP' => ($this->EE->TMPL->fetch_param('no_result_page')) ? $this->EE->TMPL->fetch_param('no_result_page') : '',
  1098. 'RES' => $this->EE->TMPL->fetch_param('results'),
  1099. 'status' => $this->EE->TMPL->fetch_param('status'),
  1100. 'channel' => $this->EE->TMPL->fetch_param('channel'),
  1101. 'search_in' => $this->EE->TMPL->fetch_param('search_in'),
  1102. 'where' => ( ! $this->EE->TMPL->fetch_param('where')) ? 'all' : $this->EE->TMPL->fetch_param('where')
  1103. );
  1104. if ($this->EE->TMPL->fetch_param('show_expired') !== FALSE)
  1105. {
  1106. $data['hidden_fields']['show_expired'] = $this->EE->TMPL->fetch_param('show_expired');
  1107. }
  1108. if ($this->EE->TMPL->fetch_param('show_future_entries') !== FALSE)
  1109. {
  1110. $data['hidden_fields']['show_future_entries'] = $this->EE->TMPL->fetch_param('show_future_entries');
  1111. }
  1112. if ($this->EE->TMPL->fetch_param('name') !== FALSE &&
  1113. preg_match("#^[a-zA-Z0-9_\-]+$#i", $this->EE->TMPL->fetch_param('name')))
  1114. {
  1115. $data['name'] = $this->EE->TMPL->fetch_param('name');
  1116. }
  1117. if ($this->EE->TMPL->fetch_param('id') !== FALSE &&
  1118. preg_match("#^[a-zA-Z0-9_\-]+$#i", $this->EE->TMPL->fetch_param('id')))
  1119. {
  1120. $data['id'] = $this->EE->TMPL->fetch_param('id');
  1121. $this->EE->TMPL->log_item('Simple Search Form: The \'id\' parameter has been deprecated. Please use form_id');
  1122. }
  1123. else
  1124. {
  1125. $data['id'] = $this->EE->TMPL->form_id;
  1126. }
  1127. $data['class'] = $this->EE->TMPL->form_class;
  1128. $res = $this->EE->functions->form_declaration($data);
  1129. $res .= stripslashes($this->EE->TMPL->tagdata);
  1130. $res .= "</form>";
  1131. return $res;
  1132. }
  1133. /** ----------------------------------------
  1134. /** Advanced Search Form
  1135. /** ----------------------------------------*/
  1136. function advanced_form()
  1137. {
  1138. $this->EE->lang->loadfile('search');
  1139. $this->EE->load->library('api');
  1140. $this->EE->api->instantiate('channel_categories');
  1141. /** ----------------------------------------
  1142. /** Fetch channels and categories
  1143. /** ----------------------------------------*/
  1144. // First we need to grab the name/ID number of all channels and categories
  1145. $sql = "SELECT channel_title, channel_id, cat_group FROM exp_channels WHERE ";
  1146. $sql .= "site_id = '".$this->EE->db->escape_str($this->EE->config->item('site_id'))."' ";
  1147. if ($channel = $this->EE->TMPL->fetch_param('channel'))
  1148. {
  1149. $xql = "SELECT channel_id FROM exp_channels WHERE site_id = '".$this->EE->db->escape_str($this->EE->config->item('site_id'))."' ";
  1150. $xql .= $this->EE->functions->sql_andor_string($channel, 'channel_name');
  1151. $query = $this->EE->db->query($xql);
  1152. if ($query->num_rows() > 0)
  1153. {
  1154. if ($query->num_rows() == 1)
  1155. {
  1156. $sql .= "AND channel_id = '".$query->row('channel_id') ."' ";
  1157. }
  1158. else
  1159. {
  1160. $sql .= "AND (";
  1161. foreach ($query->result_array() as $row)
  1162. {
  1163. $sql .= "channel_id = '".$row['channel_id']."' OR ";
  1164. }
  1165. $sql = substr($sql, 0, - 3);
  1166. $sql .= ") ";
  1167. }
  1168. }
  1169. }
  1170. $sql .= " ORDER BY channel_title";
  1171. $query = $this->EE->db->query($sql);
  1172. foreach ($query->result_array() as $row)
  1173. {
  1174. $this->channel_array[$row['channel_id']] = array($row['channel_title'], $row['cat_group']);
  1175. }
  1176. $nested = ($this->EE->TMPL->fetch_param('cat_style') !== FALSE && $this->EE->TMPL->fetch_param('cat_style') == 'nested') ? 'y' : 'n';
  1177. /** ----------------------------------------
  1178. /** Build select list
  1179. /** ----------------------------------------*/
  1180. $channel_names = "<option value=\"null\" selected=\"selected\">".$this->EE->lang->line('search_any_channel')."</option>\n";
  1181. // Load the form helper
  1182. $this->EE->load->helper('form');
  1183. foreach ($this->channel_array as $key => $val)
  1184. {
  1185. $channel_names .= "<option value=\"".$key."\">".form_prep($val['0'])."</option>\n";
  1186. }
  1187. $tagdata = $this->EE->TMPL->tagdata;
  1188. /** ----------------------------------------
  1189. /** Parse variables
  1190. /** ----------------------------------------*/
  1191. $swap = array(
  1192. 'lang:search_engine' => $this->EE->lang->line('search_engine'),
  1193. 'lang:search' => $this->EE->lang->line('search'),
  1194. 'lang:search_by_keyword' => $this->EE->lang->line('search_by_keyword'),
  1195. 'lang:search_in_titles' => $this->EE->lang->line('search_in_titles'),
  1196. 'lang:search_in_entries' => $this->EE->lang->line('search_entries'),
  1197. 'lang:search_everywhere' => $this->EE->lang->line('search_everywhere'),
  1198. 'lang:search_by_member_name' => $this->EE->lang->line('search_by_member_name'),
  1199. 'lang:exact_name_match' => $this->EE->lang->line('search_exact_name_match'),
  1200. 'lang:exact_phrase_match' => $this->EE->lang->line('search_exact_phrase_match'),
  1201. 'lang:also_search_comments' => $this->EE->lang->line('search_also_search_comments'),
  1202. 'lang:any_date' => $this-

Large files files are truncated, but you can click here to view the full file