Your IP : 216.73.216.43


Current Path : /home/cbequiperp/www/administrator/components/com_flexicontent/controllers/
Upload File :
Current File : /home/cbequiperp/www/administrator/components/com_flexicontent/controllers/search.raw.php

<?php
/**
 * @package         FLEXIcontent
 * @version         3.3
 *
 * @author          Emmanuel Danan, Georgios Papadakis, Yannick Berges, others, see contributor page
 * @link            https://flexicontent.org
 * @copyright       Copyright © 2018, FLEXIcontent team, All Rights Reserved
 * @license         http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
 */

defined('_JEXEC') or die;

use Joomla\String\StringHelper;
use Joomla\Utilities\ArrayHelper;

JLoader::register('FlexicontentControllerBaseAdmin', JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_flexicontent' . DS . 'controllers' . DS . 'base' . DS . 'baseadmin.php');

// Manually import models in case used by frontend, then models will not be autoloaded correctly via getModel('name')
require_once JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_flexicontent' . DS . 'models' . DS . 'search.php';

/**
 * FLEXIcontent Search Controller (RAW)
 *
 * NOTE: -Only- if this controller is needed by frontend URLs, then create a derived controller in frontend 'controllers' folder
 *
 * @since 3.3
 */
class FlexicontentControllerSearch extends FlexicontentControllerBaseAdmin
{
	/**
	 * Constructor
	 *
	 * @param   array   $config    associative array of configuration settings.
	 *
	 * @since 3.3
	 */
	public function __construct($config = array())
	{
		parent::__construct($config);
	}



	/**
	 * Method called before updating indexes to discover and count the rows that will be indexed
	 *
	 * @access   public
	 * @return   void
	 * @since    1.0
	 */
	public function countrows()
	{
		@ob_end_clean();
		header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
		header("Cache-Control: no-cache");
		header("Pragma: no-cache");

		// Check for request forgeries
		JSession::checkToken('request') or jexit('fail | ' . JText::_('JINVALID_TOKEN'));

		if (!FlexicontentHelperPerm::getPerm()->CanIndex)
		{
			jexit('fail | ' . JText::_('FLEXI_ALERTNOTAUTH_TASK'));
		}

		// Test counting with limited memory
		// ini_set("memory_limit", "20M");

		$start_microtime = microtime(true);

		$has_zlib    = function_exists("zlib_encode"); // Version_compare(PHP_VERSION, '5.4.0', '>=');
		$indexer     = $this->input->getCmd('indexer', 'advanced');
		$rebuildmode = $this->input->getCmd('rebuildmode', '');

		$session = JFactory::getSession();
		$db      = JFactory::getDbo();
		$app     = JFactory::getApplication();
		$model = $this->getModel('search');

		// Check indexer type
		if ($indexer !== 'advanced' && $indexer !== 'basic')
		{
			jexit('fail | indexer: ' . $indexer . ' not supported');
		}

		// Clear previous log file
		$log_filename = 'items_search_indexer_' . \JFactory::getUser()->id . '.php';
		$log_filename_full = JPATH::clean(\JFactory::getConfig()->get('log_path') . DS . $log_filename);

		if (file_exists($log_filename_full))
		{
			@ unlink($log_filename_full);
		}

		/**
		 * Get ids of searchable fields and ids of items having values for these fields
		 */

		// Retrieve fields, that are assigned as (advanced/basic) searchable/filterable
		if ($rebuildmode === 'quick' && $indexer === 'advanced')
		{
			$nse_fields = FlexicontentFields::getSearchFields('id', $indexer, null, null, $_load_params = false, 0, $search_type = 'non-search');
			$nsp_fields = FlexicontentFields::getSearchFields('id', $indexer, null, null, $_load_params = false, 0, $search_type = 'dirty-nosupport');
			$fields     = FlexicontentFields::getSearchFields('id', $indexer, null, null, $_load_params = false, 0, $search_type = 'dirty-search');

			// Get the field ids of the fields removed from searching
			$del_field_ids = array_unique(array_merge(array_keys($nse_fields), array_keys($nsp_fields), array_keys($fields)));
		}
		else
		{
			// INDEX: basic or advanced fully rebuilt
			$fields = FlexicontentFields::getSearchFields('id', $indexer, null, null, $_load_params = false, 0, $search_type = 'all-search');
			$del_field_ids = null;
		}

		// Check is session table DATA column is not mediumtext (16MBs, it can be 64 KBs ('text') in some sites that were not properly upgraded)
		$tblname  = 'session';
		$dbprefix = $app->getCfg('dbprefix');
		$dbname   = $app->getCfg('db');
		$db->setQuery("SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '" . $dbname . "' AND TABLE_NAME = '" . $dbprefix . $tblname . "'");
		$jession_coltypes = $db->loadAssocList('COLUMN_NAME');
		$_dataColType = strtolower($jession_coltypes['data']['DATA_TYPE']);
		$_dataCol_wrongSize = ($_dataColType != 'mediumtext') && ($_dataColType != 'longtext');

		// If data type is "text" it is safe to assume that it can be converted to "mediumtext",
		// since "text" means that session table is not memory storage,
		// plus it is already stored externally aka operation will be quick ?
		/*
		if ($_dataCol_wrongSize && $_dataColType == 'text')
		{
			$db->setQuery("ALTER TABLE `#__session` MODIFY `data` MEDIUMTEXT");
			$db->execute();
			$_dataCol_wrongSize = false;
		}*/

		// Set field information into session to avoid recalculation ...
		$_sz_encoded = base64_encode($has_zlib ? zlib_encode(serialize($fields), -15) : serialize($fields));

		if (!$_dataCol_wrongSize || strlen($_sz_encoded) < 16000)
		{
			$session->set($indexer . '_fields', $_sz_encoded, 'flexicontent');
		}
		else
		{
			$session->set($indexer . '_fields', null, 'flexicontent');
		}

		// Set field IDs of fields that are advanced-index "filters"
		if ($indexer === 'advanced')
		{
			$filterables = FlexicontentFields::getSearchFields('id', $indexer, null, null, $_load_params = false, 0, $search_type = 'filter');
			$filterable_ids = array_flip(array_keys($filterables));
		}
		else
		{
			$filterable_ids = array();
		}

		$_sz_encoded = base64_encode($has_zlib ? zlib_encode(serialize($filterable_ids), -15) : serialize($filterable_ids));
		$session->set($indexer . '_filterable_ids',  $_sz_encoded,  'flexicontent');  // This is both <3.4.7 session safe and also small, so do not compress

		// Get the field ids of the searchable fields that will be re-indexed, These are all ones ('all-search') or just the new ones ('dirty-search')
		$field_ids = array_keys($fields);

		// For advanced search index remove old search values from the DB, also creating missing per field tables
		if ($indexer === 'advanced')
		{
			$model->purge($del_field_ids);
		}

		// For basic index, clear records if no fields marked as text searchable
		elseif (!count($fields))
		{
			$db->setQuery("UPDATE #__flexicontent_items_ext SET search_index = '' ");
			$db->execute();
		}


		// Get records model to call needed methods
		$records_model = $this->getModel('items');

		// Get ids of records to process
		$records_total = 0;
		$record_ids = $records_model->getFieldsItems(/*$field_ids*/ null,
			$records_total, 0, self::$record_limit
		);

		// Set record ids into session to avoid recalculation ...
		$_sz_encoded = base64_encode($has_zlib ? zlib_encode(serialize($record_ids), -15) : serialize($record_ids));
		$session->set($indexer . '_records_to_index', $_sz_encoded, 'flexicontent');

		echo 'success';
		echo '|' . $records_total;
		echo '|' . count($field_ids);

		$elapsed_microseconds = round(1000000 * 10 * (microtime(true) - $start_microtime)) / 10;
		$_total_runtime = $elapsed_microseconds;
		$_total_queries = 0;
		echo sprintf('|0| Server execution time: %.2f secs ', $_total_runtime / 1000000) . ' | Total DB updates: ' . $_total_queries;

		$session->set($indexer . '_total_runtime', $elapsed_microseconds, 'flexicontent');
		$session->set($indexer . '_total_queries', 0, 'flexicontent');
		$session->set($indexer . '_records_total', $records_total, 'flexicontent');
		$session->set($indexer . '_records_start', 0, 'flexicontent');
		$session->set($indexer . '_log_filename', $log_filename, 'flexicontent');
		jexit();
	}



	/**
	 * Method to update the Basic or Advanced search index
	 *
	 * @access public
	 * @return void
	 * @since 1.0
	 */
	public function index()
	{
		@ob_end_clean();
		header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
		header("Cache-Control: no-cache");
		header("Pragma: no-cache");

		// Check for request forgeries
		// JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN'));
		// Not need because this task need the user session data that are set by countrows that checked for forgeries

		if (!FlexicontentHelperPerm::getPerm()->CanIndex)
		{
			jexit('fail | ' . JText::_('FLEXI_ALERTNOTAUTH_TASK'));
		}

		// Test indexing with limited memory
		// ini_set("memory_limit", "20M");

		$start_microtime = microtime(true);

		$session = JFactory::getSession();
		$db      = JFactory::getDbo();
		$app     = JFactory::getApplication();

		$has_zlib      = function_exists("zlib_encode"); // Version_compare(PHP_VERSION, '5.4.0', '>=');
		$search_prefix = JComponentHelper::getParams('com_flexicontent')->get('add_search_prefix') ? 'vvv' : '';   // SEARCH WORD Prefix

		$indexer     = $this->input->getCmd('indexer', 'advanced');
		$rebuildmode = $this->input->getCmd('rebuildmode', '');

		$records_per_call = $this->input->getInt('records_per_call', 20);  // Number of item to index per HTTP request
		$records_cnt      = $this->input->getInt('records_cnt', 0);        // Counter of items indexed so far, this is given via HTTP request

		$log_filename = $session->get($indexer . '_log_filename', null, 'flexicontent');
		jimport('joomla.log.log');
		JLog::addLogger(
			array(
				'text_file' => $log_filename,  // Sets the target log file
				'text_entry_format' => '{DATETIME} {PRIORITY} {MESSAGE}'  // Sets the format of each line
			),
			JLog::ALL,  // Sets messages of all log levels to be sent to the file
			array('com_flexicontent.search.items_indexer')  // category of logged messages
		);

		// TAKE CARE: this code depends on countrows() to set session variables
		// Retrieve fields, that are assigned as (advanced/basic) searchable/filterable
		$fields = $session->get($indexer . '_fields', array(), 'flexicontent');

		// If missing from session then calculate them
		if (empty($fields))
		{
			// INDEX: quick advanced index rebuilt
			if ($rebuildmode == 'quick' && $indexer == 'advanced')
			{
				$fields = FlexicontentFields::getSearchFields('id', $indexer, null, null, $_load_params = false, 0, $search_type = 'dirty-search');
			}
			else
			{
				// INDEX: basic index or fully rebuilt advanced index
				$fields = FlexicontentFields::getSearchFields('id', $indexer, null, null, $_load_params = false, 0, $search_type = 'all-search');
			}
		}
		else
		{
			$fields = unserialize($has_zlib ? zlib_decode(base64_decode($fields)) : base64_decode($fields));
		}

		// echo 'fail|'; print_r(array_keys($fields)); exit;

		// Get the field ids of the searchable fields
		$field_ids = array_keys($fields);

		// Get fields that will have atomic search tables, (current for advanced index only)
		if ($indexer === 'advanced')
		{
			$filterable_ids = $session->get($indexer . '_filterable_ids', array(), 'flexicontent');
			$filterable_ids = unserialize($has_zlib ? zlib_decode(base64_decode($filterable_ids)) : base64_decode($filterable_ids));
		}
		else
		{
			$filterable_ids = array();
		}


		/**
		 * We will process items that have value for any of the searchable fields
		 */

		// Get record ids to process, but use session to avoid recalculation
		$record_ids = $session->get($indexer . '_records_to_index', array(), 'flexicontent');
		$record_ids = unserialize($has_zlib ? zlib_decode(base64_decode($record_ids)) : base64_decode($record_ids));

		// Get total and current limit-start
		$records_total = $session->get($indexer . '_records_total', 0, 'flexicontent');
		$records_start = $session->get($indexer . '_records_start', 0, 'flexicontent');

		$_fields = array();

		foreach ($fields as $field_id => $field)
		{
			// Clone field to avoid problems
			$_fields[$field_id] = clone $field;

			// Create field parameters if not already created
			if (empty($_fields[$field_id]->parameters))
			{
				$_fields[$field_id]->parameters = new JRegistry($_fields[$field_id]->attribs);
			}
		}

		$fields = $_fields;

		// Get query size limit
		$query = "SHOW VARIABLES LIKE 'max_allowed_packet'";
		$db->setQuery($query);
		$_dbvariable = $db->loadObject();
		$max_allowed_packet = flexicontent_upload::parseByteLimit(@ $_dbvariable->Value);
		$max_allowed_packet = $max_allowed_packet ? $max_allowed_packet : 256 * 1024;
		$query_lim          = (int) (3 * $max_allowed_packet / 4);

		// jexit('fail | ' . $query_lim);

		// Get script max
		$max_execution_time = ini_get("max_execution_time");

		// jexit('fail | ' . $max_execution_time);

		// Get records models
		$records_model = $this->getModel('items');
		$record_model  = null;

		$query_count         = 0;
		$max_items_per_query = 100;
		$max_items_per_query = $max_items_per_query > $records_per_call ? $records_per_call : $max_items_per_query;

		// Start item counter at given index position
		$cnt = $records_cnt;

		// Until all records of current sub-set finish or until maximum records per AJAX call are reached
		while ($cnt < $records_start + count($record_ids)  &&  $cnt < $records_cnt + $records_per_call)
		{
			// Get maximum items per SQL query
			$query_itemids = array_slice($record_ids, ($cnt - $records_start), $max_items_per_query);

			if (empty($query_itemids))
			{
				jexit('fail | current step has no items');
			}

			// Increment item counter, but detect passing past current sub-set limit
			$cnt += $max_items_per_query;

			if ($cnt > $records_start + self::$record_limit)
			{
				$cnt = $records_start + self::$record_limit;
			}

			// Item is not needed, later and only if field uses item replacements then it will be loaded
			$item = null;

			// Items language is needed to do (if needed) special per language handling
			$lang_query = $db->getQuery(true)
				->select('id, language')
				->from('#__content AS i')
				->where('id IN (' . implode(', ', $query_itemids) . ')')
				;
			$items_data = $db->setQuery($lang_query)->loadObjectList('id');

			if ($indexer === 'basic')
			{
				$supports_verify = array();

				foreach ($field_ids as $field_id)
				{
					$field = $fields[$field_id];

					if (!isset($supports_verify[$field->field_type]))
					{
						$supports_verify[$field->field_type] = FLEXIUtilities::call_FC_Field_Func($field->field_type, 'onVerifyValues', array( null, null ))
						 ? true
						 : false;
					}

					if ($supports_verify[$field->field_type])
					{
						// Load field values for the purpose of verifying them
						$f_values_query = $db->getQuery(true)
							->select('*')
							->from('#__flexicontent_fields_item_relations AS r')
							->where('item_id IN (' . implode(', ', $query_itemids) . ')')
							->where('field_id = ' . $field->id)
							;
						$field_value_rows[$field->id] = $db->setQuery($f_values_query)->loadObjectList();
					}
				}

				// Add all query itemids to searchindex array so that it will be cleared even if zero fields are indexed
				$searchindex = array();

				foreach ($query_itemids as $query_itemid)
				{
					$searchindex[$query_itemid] = array();
				}
			}
			else
			{
				// This will hold the SQL inserting new advanced search records for multiple item/values
				$ai_query_vals = array();
				$ai_query_vals_f = array();  // Current for advanced index only
			}

			// For current item: Loop though all searchable fields according to their type
			foreach ($field_ids as $field_id)
			{
				// Must SHALLOW clone because we will be setting some properties , e.g. 'ai_query_vals', that we do not
				$field = clone $fields[$field_id];

				// Indicate multiple items per query
				$field->item_id = 0;
				$field->query_itemids = $query_itemids;
				$field->items_data = $items_data;   // Includes item language, which may be used for special per language handling

				// Indicate that the indexing fuction should retrieve the values
				$values = null;

				// Add values to advanced search index
				$fieldname = $field->iscore ? 'core' : $field->field_type;

				if ($indexer === 'advanced')
				{
					FLEXIUtilities::call_FC_Field_Func($fieldname, 'onIndexAdvSearch', array( &$field, &$values, &$item ));

					// print_r($field->ai_query_vals);
					if (isset($field->ai_query_vals))
					{
						foreach ($field->ai_query_vals as $query_val)
						{
							$ai_query_vals[] = $query_val;
						}

						// Currently for advanced index only
						if (isset($filterable_ids[$field->id]))
						{
							foreach ($field->ai_query_vals as $query_val)
							{
								$ai_query_vals_f[$field->id][] = $query_val;
							}
						}
					}
					// else echo "Not set for : ". $field->name;
				}
				elseif ($indexer === 'basic')
				{
					// Create search index record for this set of items
					FLEXIUtilities::call_FC_Field_Func($fieldname, 'onIndexSearch', array( &$field, &$values, &$item ));

					foreach ($query_itemids as $query_itemid)
					{
						if (!empty($field->search[$query_itemid]))
						{
							$searchindex[$query_itemid][] = $field->search[$query_itemid];
						}
					}

					// Verify field values validity according to field configuraton
					if (!empty($supports_verify[$field->field_type]) && count($field_value_rows[$field->id]))
					{
						FLEXIUtilities::call_FC_Field_Func($fieldname, 'onVerifyValues', array( $field, $field_value_rows[$field_id] ));
					}
				}
			}

			// Create query that will update/insert data into the DB
			$queries = array();

			if ($indexer === 'basic')
			{
				// Check for zero search index records
				if (count($searchindex))
				{
					// Start new query
					$query_vals = '';
					$query_ids = array();

					foreach ($searchindex as $query_itemid => $search_text)
					{
						if (strlen($query_vals) > $query_lim)
						{
							$queries[] = "UPDATE #__flexicontent_items_ext SET search_index = CASE item_id "
								. $query_vals
								. " END "
								. " WHERE item_id IN (" . implode(',', $query_ids) . ")";

							// Start new query
							$query_vals = '';
							$query_ids = array();
						}

						$query_ids[] = $query_itemid;
						$_search_text = implode(' | ', $search_text);

						if ($search_prefix && $_search_text)
						{
							$_search_text = preg_replace('/(\b[^\s,\.]+\b)/u', $search_prefix . '$0', trim($_search_text));
						}

						$query_vals .= " WHEN $query_itemid THEN " . $db->Quote($_search_text);
					}

					if (count($query_ids))
					{
						$queries[] = "UPDATE #__flexicontent_items_ext SET search_index = CASE item_id "
							. $query_vals
							. " END "
							. " WHERE item_id IN (" . implode(',', $query_ids) . ")";
					}
				}
			}
			else
			{
				// Check for zero search index records
				if (count($ai_query_vals))
				{
					$query_vals = '';  // Start new query

					foreach ($ai_query_vals as &$query_value)
					{
						$query_vals .= ($query_vals ? ',' : '') . $query_value;

						if (strlen($query_vals) > $query_lim)
						{
							$queries[] = "INSERT INTO #__flexicontent_advsearch_index "
								. " (field_id,item_id,extraid,search_index,value_id) VALUES "
								. $query_vals;
							$query_vals = ''; // Start new query
						}
					}

					unset($query_value);

					if (strlen($query_vals))
					{
						$queries[] = "INSERT INTO #__flexicontent_advsearch_index "
							. " (field_id,item_id,extraid,search_index,value_id) VALUES "
							. $query_vals;
					}
				}

				// Per field Table
				foreach ($ai_query_vals_f as $_field_id => $_query_vals)
				{
					$query_vals = '';  // Start new query

					foreach ($_query_vals as &$query_value)
					{
						$query_vals .= ($query_vals ? ',' : '') . $query_value;

						if (strlen($query_vals) > $query_lim)
						{
							$queries[] = "INSERT INTO #__flexicontent_advsearch_index_field_" . $_field_id
								. " (field_id,item_id,extraid,search_index,value_id) VALUES "
								. $query_vals;
							$query_vals = ''; // Start new query
						}
					}

					if (strlen($query_vals))
					{
						$queries[] = "INSERT INTO #__flexicontent_advsearch_index_field_" . $_field_id
							. " (field_id,item_id,extraid,search_index,value_id) VALUES "
							. $query_vals;
						$query_vals = ''; // Start new query
					}
				}
			}

			foreach ($queries as $query)
			{
				try
				{
					$db->setQuery($query)->execute();
				}
				catch (RuntimeException $e)
				{
					jexit('fail | ' . $e->getMessage());
				}
			}

			$query_count += count($queries);

			$elapsed_microseconds = round(1000000 * 10 * (microtime(true) - $start_microtime)) / 10;
			$elapsed_seconds = $elapsed_microseconds / 1000000.0;

			if ($elapsed_seconds > $max_execution_time / 3 || $elapsed_seconds > 6)
			{
				break;
			}
		}

		// Check if items have finished, otherwise continue with -next- group of item ids
		if ($cnt >= $records_total)
		{
			// Reset dirty SEARCH properties of published fields to be: normal ON/OFF
			$set_clause = ' SET' . ($indexer == 'basic'
				?
				' issearch = CASE issearch WHEN 2 THEN 1   WHEN -1 THEN 0   ELSE issearch   END,' .
				' isfilter = CASE isfilter WHEN 2 THEN 1   WHEN -1 THEN 0   ELSE isfilter   END'
				:
				' isadvsearch = CASE isadvsearch WHEN 2 THEN 1   WHEN -1 THEN 0   ELSE isadvsearch   END,' .
				' isadvfilter = CASE isadvfilter WHEN 2 THEN 1   WHEN -1 THEN 0   ELSE isadvfilter   END');
			$query = 'UPDATE #__flexicontent_fields' . $set_clause . " WHERE published=1";
			$db->setQuery($query)->execute();

			/**
			 * *Force SEARCH properties of non-published fields to be: normal OFF
			 */
			if ($indexer === 'basic')
			{
				$query = 'UPDATE #__flexicontent_fields SET issearch = 0 WHERE published <> 1';
				$db->setQuery($query)->execute();

				// Do not clear (set to 0) the isfilter of unpublished fields ... since this uses no special index
				$query = 'UPDATE #__flexicontent_fields '
					. ' SET isfilter = CASE isfilter WHEN 2 THEN 1   WHEN -1 THEN 0   ELSE isfilter   END '
					. ' WHERE published <> 1 AND (isfilter = 2 OR isfilter = -1)';
				$db->setQuery($query)->execute();
			}
			else
			{
				$query = 'UPDATE #__flexicontent_fields SET isadvsearch = 0, isadvfilter = 0  WHERE published <> 1';
				$db->setQuery($query)->execute();
			}
		}

		// Get next sub-set of items
		elseif ($cnt >= $records_start + self::$record_limit)
		{
			$records_start = $records_start + self::$record_limit;

			// Get next set of records
			$record_ids = $records_model->getFieldsItems(/*$field_ids*/ null,
				$total, $records_start, self::$record_limit
			);

			// Set item ids into session to avoid recalculation ...
			$_sz_encoded = base64_encode($has_zlib ? zlib_encode(serialize($record_ids), -15) : serialize($record_ids));
			$session->set($indexer . '_records_to_index', $_sz_encoded, 'flexicontent');

			$session->set($indexer . '_records_start', $records_start, 'flexicontent');
		}

		// Terminate if no fields found to be indexable
		if (!count($field_ids))
		{
			/**
			 * *Force SEARCH properties of non-published fields to be: normal OFF
			 */
			if ($indexer === 'basic')
			{
				$query = 'UPDATE #__flexicontent_fields SET issearch = 0 WHERE published <> 1';
				$db->setQuery($query)->execute();

				// Do not clear (set to 0) the isfilter of unpublished fields ... since this uses no special index
				$query = 'UPDATE #__flexicontent_fields '
					. ' SET isfilter = CASE isfilter WHEN 2 THEN 1   WHEN -1 THEN 0   ELSE isfilter   END '
					. ' WHERE published <> 1 AND (isfilter = 2 OR isfilter = -1)';
				$db->setQuery($query)->execute();
			}
			else
			{
				$query = 'UPDATE #__flexicontent_fields SET isadvsearch = 0, isadvfilter = 0  WHERE published <> 1';
				$db->setQuery($query)->execute();
			}

			jexit(
				'fail | Index was only cleaned-up, <br/>since no <b>fields</b> were marked as: ' . '<br> -- ' .
				($indexer == 'basic'
					? 'Text Searchable (CONTENT LISTS)'
					: 'Text Searchable OR filterable (SEARCH VIEW)'
				)
			);
		}

		// Terminate if not processing any records
		if (!$records_total)
		{
			jexit(
				'fail | Index was only cleaned-up, <br/>since no <b>items</b> were found to have value for fields marked as: ' . '<br> -- ' .
				($indexer == 'basic'
					? 'Text Searchable (CONTENT LISTS)'
					: 'Text Searchable OR filterable (SEARCH VIEW)'
				)
			);
		}

		$elapsed_microseconds = round(1000000 * 10 * (microtime(true) - $start_microtime)) / 10;

		if ($session->has($indexer . '_total_runtime', 'flexicontent'))
		{
			$_total_runtime = $session->get($indexer . '_total_runtime', 0, 'flexicontent');
		}
		else
		{
			$_total_runtime = 0;
		}

		$_total_runtime += $elapsed_microseconds;
		$session->set($indexer . '_total_runtime', $_total_runtime, 'flexicontent');

		if ($session->has($indexer . '_total_queries', 'flexicontent'))
		{
			$_total_queries = $session->get($indexer . '_total_queries', 0, 'flexicontent');
		}
		else
		{
			$_total_queries = 0;
		}

		$_total_queries += $query_count;
		$session->set($indexer . '_total_queries', $_total_queries, 'flexicontent');

		jexit(sprintf('success | ' . $cnt . ' | Server execution time: %.2f secs ', $_total_runtime / 1000000) . ' | Total DB updates: ' . $_total_queries);
	}



	/**
	 * Method to purge the Advanced search index
	 *
	 * @access   public
	 * @return   void
	 * @since    1.0
	 */
	public function purge()
	{
		$model = $this->getModel('search');
		$model->purge();
		$msg = JText::_('FLEXI_ITEMS_PURGED');
		$this->setRedirect('index.php?option=com_flexicontent&view=search', $msg);
	}
}