PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/com_flexicontent_v2.x/admin/controllers/search.php

http://flexicontent.googlecode.com/
PHP | 285 lines | 182 code | 34 blank | 69 comment | 38 complexity | a98ab907614080ffdc57af913b7b9969 MD5 | raw file
Possible License(s): MIT, GPL-2.0, Apache-2.0
  1. <?php
  2. /**
  3. * @version 1.5 stable $Id: search.php 1767 2013-09-18 17:46:46Z ggppdk $
  4. * @package Joomla
  5. * @subpackage FLEXIcontent
  6. * @copyright (C) 2009 Emmanuel Danan - www.vistamedia.fr
  7. * @license GNU/GPL v2
  8. *
  9. * FLEXIcontent is a derivative work of the excellent QuickFAQ component
  10. * @copyright (C) 2008 Christoph Lukes
  11. * see www.schlu.net for more information
  12. *
  13. * FLEXIcontent is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. */
  18. defined( '_JEXEC' ) or die( 'Restricted access' );
  19. jimport('joomla.application.component.controller');
  20. /**
  21. * FLEXIcontent Component Search Controller
  22. *
  23. * @package Joomla
  24. * @subpackage FLEXIcontent
  25. * @since 1.0
  26. */
  27. class FlexicontentControllerSearch extends FlexicontentController
  28. {
  29. /**
  30. * Constructor
  31. *
  32. * @since 1.0
  33. */
  34. function __construct() {
  35. parent::__construct();
  36. }
  37. /**
  38. * count the rows
  39. *
  40. * @access public
  41. * @return void
  42. * @since 1.0
  43. */
  44. function countrows()
  45. {
  46. $start_microtime = microtime(true);
  47. // Check for request forgeries
  48. //JRequest::checkToken() or jexit( 'Invalid Token' );
  49. //$params = JComponentHelper::getParams( 'com_flexicontent' );
  50. @ob_end_clean();
  51. $indexer = JRequest::getVar('indexer','advanced');
  52. $rebuildmode = JRequest::getVar('rebuildmode','');
  53. $session = JFactory::getSession();
  54. // Retrieve fields, that are assigned as (advanced/basic) searchable/filterable
  55. if ($rebuildmode=='quick' && $indexer=='advanced') {
  56. $nse_fields = FlexicontentFields::getSearchFields('id', $indexer, null, null, $_load_params=false, 0, $search_type='non-search');
  57. $nsp_fields = FlexicontentFields::getSearchFields('id', $indexer, null, null, $_load_params=false, 0, $search_type='dirty-nosupport');
  58. $session->set($indexer.'_nse_fields', $nse_fields, 'flexicontent');
  59. $session->set($indexer.'_nsp_fields', $nsp_fields, 'flexicontent');
  60. $fields = FlexicontentFields::getSearchFields('id', $indexer, null, null, $_load_params=true, 0, $search_type='dirty-search');
  61. } else {
  62. $fields = FlexicontentFields::getSearchFields('id', $indexer, null, null, $_load_params=true, 0, $search_type='all-search');
  63. }
  64. // Get the field ids of the searchable fields
  65. $fieldids = array_keys($fields);
  66. // Get ids of searchable and ids of item having values for these fields
  67. $itemsmodel = $this->getModel('items'); // Get items model to call needed methods
  68. $itemids = $itemsmodel->getFieldsItems($fieldids); // Get the items ids that have value for any of the searchable fields
  69. // Set item ids into session to avoid recalculation ...
  70. $session->set($indexer.'_items_to_index', $itemids, 'flexicontent');
  71. // Set field information into session to avoid recalculation ...
  72. $session->set($indexer.'_fields', $fields, 'flexicontent');
  73. echo 'success'; //echo count($fieldids)*count($itemids).'|';
  74. // WARNING: json_encode will output object if given an array with gaps in the indexing
  75. //echo '|'.json_encode($itemids);
  76. //echo '|'.json_encode($fieldids);
  77. echo '|'.count($itemids);
  78. echo '|'.count($fieldids);
  79. $elapsed_microseconds = round(1000000 * 10 * (microtime(true) - $start_microtime)) / 10;
  80. $session->set($indexer.'_total_runtime', $elapsed_microseconds ,'flexicontent');
  81. exit;
  82. }
  83. function index()
  84. {
  85. $start_microtime = microtime(true);
  86. $session = JFactory::getSession();
  87. $db = JFactory::getDBO();
  88. @ob_end_clean();
  89. $indexer = JRequest::getVar('indexer','advanced');
  90. $rebuildmode = JRequest::getVar('rebuildmode','');
  91. $items_per_call = JRequest::getVar('items_per_call', 20); // Number of item to index per HTTP request
  92. $itemcnt = JRequest::getVar('itemcnt', 0); // Counter of items indexed so far, this is given via HTTP request
  93. $itemsmodel = $this->getModel('items'); // Get items model to call needed methods
  94. // TAKE CARE: this code depends on countrows() to set session variables
  95. // Retrieve fields, that are assigned as (advanced/basic) searchable/filterable
  96. if ($rebuildmode=='quick' && $indexer=='advanced') {
  97. $nse_fields = $session->get($indexer.'_nse_fields', array(),'flexicontent');
  98. $nsp_fields = $session->get($indexer.'_nsp_fields', array(),'flexicontent');
  99. $fields = $session->get($indexer.'_fields', array(),'flexicontent');
  100. //echo 'fail|'; print_r(array_keys($fields)); exit;
  101. // Get the field ids of the fields removed from searching
  102. $del_fieldids = array_unique( array_merge(array_keys($nse_fields), array_keys($nsp_fields), array_keys($fields)) ) ;
  103. } else {
  104. $fields = $session->get($indexer.'_fields', array(),'flexicontent');
  105. //echo 'fail|'; print_r(array_keys($fields)); exit;
  106. }
  107. // Get the field ids of the searchable fields
  108. $fieldids = array_keys($fields);
  109. // Get items ids that have value for any of the searchable fields, but use session to avoid recalculation
  110. $itemids = $session->get($indexer.'_items_to_index', array(),'flexicontent');
  111. // For advanced search index Remove old search values from the DB
  112. if ($itemcnt==0) {
  113. if ($indexer=='advanced') {
  114. if ($rebuildmode!='quick') {
  115. $clear_query = "TRUNCATE TABLE #__flexicontent_advsearch_index";
  116. } else if (count($del_fieldids)) {
  117. $del_fieldids_list = implode( ',' , $del_fieldids);
  118. $clear_query = "DELETE FROM #__flexicontent_advsearch_index "
  119. ." WHERE field_id IN (". $del_fieldids_list. ")";
  120. }
  121. } else { // INDEX: basic
  122. if ( !count($fields) ) {
  123. // (all items) Clear basic index records no fields marked as text searchable
  124. $clear_query = "UPDATE #__flexicontent_items_ext SET search_index = '' ";
  125. }
  126. }
  127. if ( !empty($clear_query) ) {
  128. $db->setQuery($clear_query);
  129. $db->query();
  130. }
  131. }
  132. $items_per_query = 50;
  133. $items_per_query = $items_per_query > $items_per_call ? $items_per_call : $items_per_query;
  134. $cnt = $itemcnt;
  135. while($cnt < $itemcnt+$items_per_call)
  136. {
  137. $query_itemids = array_slice($itemids, $cnt, $items_per_query);
  138. $cnt += $items_per_query;
  139. // Item is not needed, later and only if field uses item replacements then it will be loaded
  140. $item = null;
  141. if ($indexer == 'basic') {
  142. $searchindex = array();
  143. // Add all query itemids to searchindex array so that it will be cleared even if zero fields are indexed
  144. foreach ($query_itemids as $query_itemid) $searchindex[$query_itemid] = array();
  145. } else {
  146. // This will hold the SQL inserting new advanced search records for multiple item/values
  147. $ai_query_vals = array();
  148. }
  149. // For current item: Loop though all searchable fields according to their type
  150. foreach($fieldids as $fieldid)
  151. {
  152. // Clone field to avoid problems
  153. $field = clone($fields[$fieldid]);
  154. // Indicate multiple items per query
  155. $field->item_id = 0;
  156. $field->query_itemids = $query_itemids;
  157. // Indicate that the indexing fuction should retrieve the values
  158. $values = null;
  159. // Add values to advanced search index
  160. $fieldname = $field->iscore ? 'core' : $field->field_type;
  161. if ($indexer == 'advanced') {
  162. FLEXIUtilities::call_FC_Field_Func($fieldname, 'onIndexAdvSearch', array( &$field, &$values, &$item ));
  163. //print_r($field->ai_query_vals);
  164. if ( isset($field->ai_query_vals) ) {
  165. foreach ($field->ai_query_vals as $query_val) $ai_query_vals[] = $query_val;
  166. } //else echo "Not set for : ". $field->name;
  167. } else if ($indexer == 'basic') {
  168. FLEXIUtilities::call_FC_Field_Func($fieldname, 'onIndexSearch', array( &$field, &$values, &$item ));
  169. foreach ($query_itemids as $query_itemid)
  170. if ( @$field->search[$query_itemid] ) $searchindex[$query_itemid][] = /*$field->name.': '.*/$field->search[$query_itemid];
  171. }
  172. }
  173. // Create query that will update/insert data into the DB
  174. unset($query); // make sure it is not set above
  175. if ($indexer == 'basic') {
  176. if (count($searchindex)) { // check for zero search index records
  177. $query = "UPDATE #__flexicontent_items_ext SET search_index = CASE item_id ";
  178. foreach ($searchindex as $query_itemid => $search_text)
  179. {
  180. // Add new search value into the DB
  181. $query .= " WHEN $query_itemid THEN ".$db->Quote( implode(' | ', $search_text) );
  182. }
  183. $query .= " END ";
  184. $query .= " WHERE item_id IN (". implode(',', array_keys($searchindex)) .")";
  185. }
  186. } else {
  187. if ( count($ai_query_vals) ) { // check for zero search index records
  188. $query = "INSERT INTO #__flexicontent_advsearch_index "
  189. ." (field_id,item_id,extraid,search_index,value_id) VALUES "
  190. .implode(",", $ai_query_vals);
  191. }
  192. }
  193. if ( !empty($query) ) {
  194. $db->setQuery($query);
  195. $db->query();
  196. if ($db->getErrorNum()) {
  197. echo $db->getErrorMsg();
  198. }
  199. }
  200. }
  201. // Check if items have finished, otherwise continue with -next- group of item ids
  202. if ($cnt >= count($itemids))
  203. {
  204. // Reset dirty SEARCH properties of published fields to be: normal ON/OFF
  205. $set_clause = ' SET' .($indexer=='basic' ?
  206. ' issearch = CASE issearch WHEN 2 THEN 1 WHEN -1 THEN 0 ELSE issearch END' :
  207. ' isadvsearch = CASE isadvsearch WHEN 2 THEN 1 WHEN -1 THEN 0 ELSE isadvsearch END,'.
  208. ' isadvfilter = CASE isadvfilter WHEN 2 THEN 1 WHEN -1 THEN 0 ELSE isadvfilter END');
  209. $query = 'UPDATE #__flexicontent_fields'. $set_clause ." WHERE published=1";
  210. $db->setQuery($query);
  211. $db->query();
  212. // Force SEARCH properties of unpublished fields to be: normal OFF
  213. if ($indexer=='basic') {
  214. $query = 'UPDATE #__flexicontent_fields SET issearch = 0 WHERE published=0';
  215. $db->setQuery($query);
  216. $db->query();
  217. } else {
  218. $query = 'UPDATE #__flexicontent_fields SET isadvsearch = 0, isadvfilter = 0 WHERE published=0';
  219. $db->setQuery($query);
  220. $db->query();
  221. }
  222. }
  223. if ( !count($fieldids) ) {
  224. echo 'fail|Index was only cleaned-up, since no field(s) were marked as: '.'<br> -- ' .
  225. ($indexer=='basic' ? 'Text Searchable (CONTENT LISTS)' : 'Text Searchable OR filterable (SEARCH VIEW)');
  226. exit;
  227. }
  228. if ( !count($itemids) ) {
  229. echo 'fail|Index was only cleaned-up, since no items were found to have value for fields marked as: '.'<br> -- ' .
  230. ($indexer=='basic' ? 'Text Searchable (CONTENT LISTS)' : 'Text Searchable OR filterable (SEARCH VIEW)');
  231. exit;
  232. }
  233. $elapsed_microseconds = round(1000000 * 10 * (microtime(true) - $start_microtime)) / 10;
  234. if ( $session->has($indexer.'_total_runtime', 'flexicontent')) {
  235. $_total_runtime = $session->get($indexer.'_total_runtime', 0,'flexicontent');
  236. } else {
  237. $_total_runtime = 0;
  238. }
  239. $_total_runtime += $elapsed_microseconds;
  240. $session->set($indexer.'_total_runtime', $_total_runtime ,'flexicontent');
  241. echo sprintf( ' [%.2f secs] ', $_total_runtime/1000000);
  242. exit;
  243. }
  244. function purge()
  245. {
  246. $model = $this->getModel('search');
  247. $model->purge();
  248. $msg = JText::_('FLEXI_ITEMS_PURGED');
  249. $this->setRedirect('index.php?option=com_flexicontent&view=search', $msg);
  250. }
  251. }