Your IP : 216.73.216.43


Current Path : /home/cbequiperp/www/plugins/search/flexisearch/
Upload File :
Current File : /home/cbequiperp/www/plugins/search/flexisearch/flexisearch.php

<?php
/**
 * @version 1.0 $Id: flexisearch.php 1353 2012-06-23 20:47:30Z ggppdk $
 * @package Joomla
 * @subpackage FLEXIcontent
 * @copyright (C) 2009 Emmanuel Danan - www.vistamedia.fr
 * @license GNU/GPL v2
 * 
 * FLEXIcontent is a derivative work of the excellent QuickFAQ component
 * @copyright (C) 2008 Christoph Lukes
 * see www.schlu.net for more information
 *
 * FLEXIcontent is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );

jimport('cms.plugin.plugin');

require_once(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_flexicontent'.DS.'defineconstants.php');

FLEXI_J40GE
	? require_once (JPATH_SITE.DS.'components'.DS.'com_content'.DS.'src'.DS.'Helper'.DS.'RouteHelper.php')
	: require_once (JPATH_SITE.DS.'components'.DS.'com_content'.DS.'helpers'.DS.'route.php');
require_once(JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'helpers'.DS.'route.php');
if (!FLEXI_J40GE) require_once(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_search'.DS.'helpers'.DS.'search.php');

require_once(JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'classes'.DS.'flexicontent.fields.php');
require_once(JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'classes'.DS.'flexicontent.helper.php');

/**
 * Content Search plugin
 *
 * @package		FLEXIcontent.Plugin
 * @subpackage	Search.flexisearch
 * @since		1.6
 */
class plgSearchFlexisearch extends JPlugin
{
	var $autoloadLanguage = false;

	/**
	 * Constructor
	 *
	 * @access      public
	 * @param       object  $subject The object to observe
	 * @param       array   $config  An array that holds the plugin configuration
	 * @since       1.5
	 */
	public function __construct(& $subject, $config)
	{
		parent::__construct($subject, $config);

		static $language_loaded = null;
		if (!$this->autoloadLanguage && $language_loaded === null) $language_loaded = JPlugin::loadLanguage('plg_search_flexisearch', JPATH_ADMINISTRATOR);
	}
	
	
	function _getAreas()
	{
		$areas = array();
		if ($this->params->get('search_title',	1)) {$areas['FlexisearchTitle'] = JText::_('FLEXI_STDSEARCH_TITLE');}
		if ($this->params->get('search_desc',		1)) {$areas['FlexisearchDesc'] = JText::_('FLEXI_STDSEARCH_DESC');}
		if ($this->params->get('search_fields',	1)) {$areas['FlexisearchFields'] = JText::_('FLEXI_STDSEARCH_FIELDS');}
		if ($this->params->get('search_meta',		1)) {$areas['FlexisearchMeta'] = JText::_('FLEXI_STDSEARCH_META');}
		if ($this->params->get('search_tags',		1)) {$areas['FlexisearchTags'] = JText::_('FLEXI_STDSEARCH_TAGS');}
		
		// Goto last element of array and add to it 2 line breaks, this layout hack is not appropriate e.g. the areas maybe inside a list ...
		//end($areas);
		//$areas[key($areas)]=current($areas).'<br><br>';
		
		return $areas;
	}
	
	
	function _getContentTypes()
	{
		// Get allowed search types
		$typeIds = $this->params->get('search_types',	'');
		$typesarray = array();
		preg_match_all('/\b\d+\b/', $typeIds, $typesarray);
		
		$wheres=array();
		foreach ($typesarray[0] as $key=>$typeID)
		{
			$wheres[]='t.id = '.$typeID;
		}
		$whereTypes =  $wheres ? '(' . implode(') OR (', $wheres) . ')' : '';
		
		$db		= JFactory::getDbo();
		$query	= $db->getQuery(true);
		$query->clear();
		$query->select('t.id, t.name ');
		$query->from('#__flexicontent_types AS t ');
		$query->where('t.published = 1'.($whereTypes ? ' AND ('.$whereTypes.')' : ''));
		$query->order('t.id ASC');

		$db->setQuery($query);
		$list = $db->loadObjectList();

		$ContentType = array();
		if (isset($list)){
			foreach($list as $item){
				$ContentType['FlexisearchType'.$item->id]=$item->name.'<br>'; // add a line break too
			}
		}
		
		// Goto last element of array and add to it one more line breaks, this layout hack is not appropriate e.g. the areas maybe inside a list ...
		//end($ContentType);
		//$ContentType[key($ContentType)]=current($ContentType).'<br>';
		
		return $ContentType;
	
	}
	
	/*
	 * @return array of search areas
	 */
	function onContentSearchAreas()
	{
		static $areas = array();
		
		$areas = $this->params->get('search_select_types',	1) ? $this->_getAreas() + $this->_getContentTypes() :  $this->_getAreas();
		return $areas;
	}
	
	// Also add J1.5 function signature
	/*function onSearchAreas()
	{
		return $this->onContentSearchAreas();
	}*/
	

	/**
	 * Content Search method
	 * The sql must return the following fields that are used in a common display
	 * routine: href, title, section, created, text, browsernav
	 * @param string Target search string
	 * @param string mathcing option, exact|any|all
	 * @param string ordering option, newest|oldest|popular|alpha|category
	 * @param mixed An array if restricted to areas, null if search all
	 */
	function onContentSearch( $text, $phrase='', $ordering='', $areas=null )
	{
		$db		= JFactory::getDbo();
		$app	= JFactory::getApplication();
		$user	= JFactory::getUser();
		
		// Get language
		$cntLang = substr(JFactory::getLanguage()->getTag(), 0,2);  // Current Content language (Can be natively switched in J2.5)
		$urlLang  = JFactory::getApplication()->input->getWord('lang', '' );                 // Language from URL (Can be switched via Joomfish in J1.5)
		$lang = (FLEXI_J16GE || empty($urlLang)) ? $cntLang : $urlLang;
		
	  // COMPONENT PARAMETERS
		$cparams 	= $app->isClient('site')  ?  $app->getParams('com_flexicontent')  : JComponentHelper::getParams('com_flexicontent');
		if (!defined('FLEXI_SECTION'))
			define('FLEXI_SECTION', $cparams->get('flexi_section'));		// define section
		$show_noauth = $cparams->get('show_noauth', 0);		// items the user cannot see ...

		$searchText = $text;
		
		$AllAreas = array_keys( $this->_getAreas() );
		$AllTypes = array_keys( $this->_getContentTypes() );
		
		if (is_array($areas)) {
			// search in selected areas
			$searchAreas = array_intersect( $areas, $AllAreas );
			$searchTypes = array_intersect( $areas, $AllTypes );
			
			if (!$searchAreas && !$searchTypes)  return array();
			
			if (!$searchAreas) {$searchAreas = $AllAreas;}
			if (!$searchTypes) {$searchTypes = $AllTypes;}
		} else {
			// search in all avaliable areas if no selected ones
			$searchAreas = $AllAreas;
			$searchTypes = $AllTypes;
		}
		
		foreach ($searchTypes as $id=>$tipe){
			$searchTypes[$id]=preg_replace('/\D/','',$tipe);
		}
		
		$types= implode(', ',$searchTypes);

		$filter_lang	= $this->params->def('filter_lang',	1);
		$limit				= $this->params->def('search_limit', 50);

		// NULL and CURRENT dates,
		// NOTE: the current date needs to use built-in MYSQL function, otherwise filter caching can not work because the CURRENT DATETIME is continuously different !!!
		//$now = JFactory::getDate()->toSql();
		$_nowDate = 'UTC_TIMESTAMP()'; //$db->Quote($now);
		$nullDate = $db->getNullDate();
		
		$text = trim($text);
		if ($text == '') {
			return array();
		}
		
		$wheres = array();
		switch ($phrase) {
			case 'exact':
				$text = $db->escape($text, true);
				$text = $db->Quote('%'.$text.'%', false);
				$wheres2	= array();
				if (in_array('FlexisearchTitle', $searchAreas))		{$wheres2[]	= 'i.title LIKE '.$text;}
				if (in_array('FlexisearchDesc', $searchAreas))		{$wheres2[]	= 'i.introtext LIKE '.$text;	$wheres2[]	= 'i.fulltext LIKE '.$text;}
				if (in_array('FlexisearchMeta', $searchAreas))		{$wheres2[]	= 'i.metakey LIKE '.$text;		$wheres2[]	= 'i.metadesc LIKE '.$text;}
				if (in_array('FlexisearchFields', $searchAreas))	{$wheres2[]	= "f.field_type IN ('text','textselect') AND f.issearch=1 AND fir.value LIKE ".$text;}
				if (in_array('FlexisearchTags', $searchAreas))		{$wheres2[]	= 't.name LIKE '.$text;}
				if (count($wheres2)) $where		= '(' . implode(') OR (', $wheres2) . ')';
				break;
			case 'all':
			case 'any':
			default:
				$words = explode(' ', $text);
				$wheres = array();
				foreach ($words as $word) {
					$word = $db->escape($word, true);
					$word = $db->Quote('%'.$word.'%', false);
					$wheres2	= array();
					if (in_array('FlexisearchTitle', $searchAreas))		{$wheres2[]	= 'i.title LIKE '.$word;}
					if (in_array('FlexisearchDesc', $searchAreas))		{$wheres2[]	= 'i.introtext LIKE '.$word;	$wheres2[]	= 'i.fulltext LIKE '.$word;}
					if (in_array('FlexisearchMeta', $searchAreas))		{$wheres2[]	= 'i.metakey LIKE '.$word;		$wheres2[]	= 'i.metadesc LIKE '.$word;}
					if (in_array('FlexisearchFields', $searchAreas))	{$wheres2[]	= "f.field_type IN ('text','textselect') AND f.issearch=1 AND fir.value LIKE ".$word;}
					if (in_array('FlexisearchTags', $searchAreas))		{$wheres2[]	= 't.name LIKE '.$word;}
					if (count($wheres2)) $wheres[]	= '(' . implode(') OR (', $wheres2) . ')';
				}
				if (count($wheres)) {
					$where = '(' . implode(($phrase == 'all' ? ') AND (' : ') OR ('), $wheres) . ')';
				}
				break;
		}
		
		if (!@$where) {return array();}
		
		//if ( empty($where) ) $where = '1';
		
		switch ($ordering)
		{
				//case 'relevance': $order = ' ORDER BY score DESC, i.title ASC'; break;
				case 'oldest':   $order = 'i.created ASC'; break;
				case 'popular':  $order = 'i.hits DESC'; break;
				case 'alpha':    $order = 'i.title ASC'; break;
				case 'category': $order = 'c.title ASC, i.title ASC'; break;
				case 'newest':   $order = 'i.created DESC'; break;
				default:         $order = 'i.created DESC'; break;
		}
		
		
		
		// ****************************************************************************************
		// Create JOIN clause and WHERE clause part for filtering by current (viewing) access level
		// ****************************************************************************************
		$joinaccess	= '';
		$andaccess	= '';
		$select_access = '';
		
		// Extra access columns for main category and content type (item access will be added as 'access')
		$select_access .= ',  c.access as category_access, ty.access as type_access';
		
		if ( !$show_noauth ) {   // User not allowed to LIST unauthorized items
			$aid_arr = JAccess::getAuthorisedViewLevels($user->id);
			$aid_list = implode(",", $aid_arr);
			$andaccess .= ' AND ty.access IN (0,'.$aid_list.')';
			$andaccess .= ' AND  c.access IN (0,'.$aid_list.')';
			$andaccess .= ' AND  i.access IN (0,'.$aid_list.')';
			$select_access .= ', 1 AS has_access';
		}
		else {
			// Access Flags for: content type, main category, item
			$aid_arr = JAccess::getAuthorisedViewLevels($user->id);
			$aid_list = implode(",", $aid_arr);
			$select_access .= ', '
				.' CASE WHEN '
				.'  ty.access IN ('.$aid_list.') AND '
				.'   c.access IN ('.$aid_list.') AND '
				.'   i.access IN ('.$aid_list.') '
				.' THEN 1 ELSE 0 END AS has_access';
		}
		
		
		
		// **********************************************************************************************************************************************************
		// Create WHERE clause part for filtering by current active language, and current selected contend types ( !! although this is possible via a filter too ...)
		// **********************************************************************************************************************************************************
		
		$andlang = '';
		if (	$app->isClient('site') &&
					( FLEXI_FISH || (FLEXI_J16GE && $app->getLanguageFilter()) ) &&
					$filter_lang  // Language filtering enabled
		) {
			$andlang .= ' AND ( i.language LIKE ' . $db->Quote( $lang .'%' ) . ' OR i.language="*" ) ';
			$andlang .= ' AND ( c.language LIKE ' . $db->Quote( $lang .'%' ) . ' OR c.language="*" ) ';
		}
		
		// search articles
		$results = array();
		if ( $limit > 0)
		{
			$query	= $db->getQuery(true);
			$query->clear();
			$query->select(''
				.' i.id as id,'
				.' i.title AS title,'
				.' i.language AS language,'
				.' i.metakey AS metakey,'
				.' i.metadesc AS metadesc,'
				.' i.modified AS created,'     // TODO ADD a PARAMETER FOR CONTROLING the use of modified by or created by date as "created"
				.' c.title AS maincat_title, c.alias AS maincat_alias,'  // Main category data
				.' t.name AS tagname,'
				.' fir.value as field,'
				.' i.access, ie.type_id,'
				.' CONCAT(i.introtext, i.fulltext) AS text,'
				.' CONCAT_WS( " / ", '. $db->Quote( JText::_( 'FLEXICONTENT' ) ) .', c.title, i.title ) AS section,'
				.' CASE WHEN CHAR_LENGTH(i.alias) THEN CONCAT_WS(\':\', i.id, i.alias) ELSE i.id END AS slug,'
				.' CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(\':\', c.id, c.alias) ELSE c.id END AS catslug,'
				.' "2" AS browsernav'
				. $select_access
				);
			$query->from('#__content AS i '
				.' JOIN #__categories AS c ON i.catid = c.id'
				.' JOIN #__flexicontent_items_ext AS ie ON i.id = ie.item_id'
				.' JOIN #__flexicontent_types AS ty ON ie.type_id = ty.id'
				// searching into text-like fields
				.' LEFT JOIN #__flexicontent_fields_item_relations AS fir ON i.id = fir.item_id'
				.' LEFT JOIN #__flexicontent_fields AS f ON fir.field_id = f.id'
				// searching into 'tags' field
				.' LEFT JOIN #__flexicontent_tags_item_relations AS tir ON i.id = tir.itemid'
				.' LEFT JOIN #__flexicontent_tags AS t ON tir.tid = t.id	'
				. $joinaccess
				);
			$query->where(' ('. $where .') ' 
				.' AND ie.type_id IN('.$types.') '
				.' AND i.state IN (1, -5) AND c.published = 1 '
				.' AND (i.publish_up IS NULL OR i.publish_up = '.$db->Quote($nullDate).' OR i.publish_up <= ' . $_nowDate . ') '
				.' AND (i.publish_down IS NULL OR i.publish_down = '.$db->Quote($nullDate).' OR i.publish_down >= ' . $_nowDate . ') '
				. $andaccess // Filter by user access
				. $andlang   // Filter by current language
				); 
			$query->group('i.id');
			$query->order($order);
			//echo "<pre style='white-space:normal!important;'>".$query."</pre>";
			
			$list = $db->setQuery($query, 0, $limit)->loadObjectList();

			if ($list)
			{
				$item_cats = FlexicontentFields::_getCategories($list);
				$typeData = flexicontent_db::getTypeData();
				
				foreach($list as $key => $item)
				{
					// echo $item->title." ".$item->tagname."<br/>"; // Before checking for noHTML
					$item->categories = isset($item_cats[$item->id])  ?  $item_cats[$item->id] : array();  // in case of item categories missing
					
					// If joomla article view is allowed allowed and then search view may optional create Joomla article links
					if( $typeData[$item->type_id]->params->get('allow_jview', 0) == 1 && $typeData[$item->type_id]->params->get('search_jlinks', 1) )
					{
						$item->href = JRoute::_(ContentHelperRoute::getArticleRoute($item->slug, $item->catslug, $item->language));
					}
					else
					{
						$item->href = JRoute::_(FlexicontentHelperRoute::getItemRoute($item->slug, $item->catslug, 0, $item));
					}
					
					if (searchHelper::checkNoHTML($item, $searchText, array('title', 'metadesc', 'metakey', 'tagname', 'field', 'text' ))) {
						$results[$item->id] = $item;
					}
				}
			}
		}

		return $results;
	}
	
	
	// Also add J1.5 function signature
	/*function onSearch( $text, $phrase='', $ordering='', $areas=null )
	{
		return $this->onContentSearch( $text, $phrase, $ordering, $areas );
	}*/
}