primo commit
This commit is contained in:
109
components/com_search/controller.php
Normal file
109
components/com_search/controller.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_search
|
||||
*
|
||||
* @copyright (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
/**
|
||||
* Search Component Controller
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class SearchController extends JControllerLegacy
|
||||
{
|
||||
/**
|
||||
* Method to display a view.
|
||||
*
|
||||
* @param bool $cachable If true, the view output will be cached
|
||||
* @param bool $urlparams An array of safe URL parameters and their variable types, for valid values see {@link JFilterInput::clean()}.
|
||||
*
|
||||
* @return JControllerLegacy This object to support chaining.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public function display($cachable = false, $urlparams = false)
|
||||
{
|
||||
// Force it to be the search view
|
||||
$this->input->set('view', 'search');
|
||||
|
||||
return parent::display($cachable, $urlparams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function search()
|
||||
{
|
||||
// Slashes cause errors, <> get stripped anyway later on. # causes problems.
|
||||
$badchars = array('#', '>', '<', '\\');
|
||||
$searchword = trim(str_replace($badchars, '', $this->input->post->getString('searchword')));
|
||||
|
||||
// If searchword enclosed in double quotes, strip quotes and do exact match
|
||||
if (substr($searchword, 0, 1) === '"' && substr($searchword, -1) === '"')
|
||||
{
|
||||
$post['searchword'] = substr($searchword, 1, -1);
|
||||
$this->input->set('searchphrase', 'exact');
|
||||
}
|
||||
else
|
||||
{
|
||||
$post['searchword'] = $searchword;
|
||||
}
|
||||
|
||||
$post['ordering'] = $this->input->post->getWord('ordering');
|
||||
$post['searchphrase'] = $this->input->post->getWord('searchphrase', 'all');
|
||||
$post['limit'] = $this->input->post->getUInt('limit');
|
||||
|
||||
if ($post['limit'] === null)
|
||||
{
|
||||
unset($post['limit']);
|
||||
}
|
||||
|
||||
$areas = $this->input->post->get('areas', null, 'array');
|
||||
|
||||
if ($areas)
|
||||
{
|
||||
foreach ($areas as $area)
|
||||
{
|
||||
$post['areas'][] = JFilterInput::getInstance()->clean($area, 'cmd');
|
||||
}
|
||||
}
|
||||
|
||||
// The Itemid from the request, we will use this if it's a search page or if there is no search page available
|
||||
$post['Itemid'] = $this->input->getInt('Itemid');
|
||||
|
||||
// Set Itemid id for links from menu
|
||||
$app = JFactory::getApplication();
|
||||
$menu = $app->getMenu();
|
||||
$item = $menu->getItem($post['Itemid']);
|
||||
|
||||
// The requested Item is not a search page so we need to find one
|
||||
if ($item && ($item->component !== 'com_search' || $item->query['view'] !== 'search'))
|
||||
{
|
||||
// Get item based on component, not link. link is not reliable.
|
||||
$item = $menu->getItems('component', 'com_search', true);
|
||||
|
||||
// If we found a search page, use that.
|
||||
if (!empty($item))
|
||||
{
|
||||
$post['Itemid'] = $item->id;
|
||||
}
|
||||
}
|
||||
|
||||
unset($post['task'], $post['submit']);
|
||||
|
||||
$uri = JUri::getInstance();
|
||||
$uri->setQuery($post);
|
||||
$uri->setVar('option', 'com_search');
|
||||
|
||||
$this->setRedirect(JRoute::_('index.php' . $uri->toString(array('query', 'fragment')), false));
|
||||
}
|
||||
}
|
||||
247
components/com_search/models/search.php
Normal file
247
components/com_search/models/search.php
Normal file
@ -0,0 +1,247 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_search
|
||||
*
|
||||
* @copyright (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
/**
|
||||
* Search Component Search Model
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class SearchModelSearch extends JModelLegacy
|
||||
{
|
||||
/**
|
||||
* Search data array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_data = null;
|
||||
|
||||
/**
|
||||
* Search total
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_total = null;
|
||||
|
||||
/**
|
||||
* Search areas
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_areas = null;
|
||||
|
||||
/**
|
||||
* Pagination object
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $_pagination = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// Get configuration
|
||||
$app = JFactory::getApplication();
|
||||
$config = JFactory::getConfig();
|
||||
|
||||
// Get the pagination request variables
|
||||
$this->setState('limit', $app->getUserStateFromRequest('com_search.limit', 'limit', $config->get('list_limit'), 'uint'));
|
||||
$this->setState('limitstart', $app->input->get('limitstart', 0, 'uint'));
|
||||
|
||||
// Get parameters.
|
||||
$params = $app->getParams();
|
||||
|
||||
if ($params->get('searchphrase') == 1)
|
||||
{
|
||||
$searchphrase = 'any';
|
||||
}
|
||||
elseif ($params->get('searchphrase') == 2)
|
||||
{
|
||||
$searchphrase = 'exact';
|
||||
}
|
||||
else
|
||||
{
|
||||
$searchphrase = 'all';
|
||||
}
|
||||
|
||||
// Set the search parameters
|
||||
$keyword = urldecode($app->input->getString('searchword'));
|
||||
$match = $app->input->get('searchphrase', $searchphrase, 'word');
|
||||
$ordering = $app->input->get('ordering', $params->get('ordering', 'newest'), 'word');
|
||||
$this->setSearch($keyword, $match, $ordering);
|
||||
|
||||
// Set the search areas
|
||||
$areas = $app->input->get('areas', null, 'array');
|
||||
$this->setAreas($areas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to set the search parameters
|
||||
*
|
||||
* @param string $keyword string search string
|
||||
* @param string $match matching option, exact|any|all
|
||||
* @param string $ordering option, newest|oldest|popular|alpha|category
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSearch($keyword, $match = 'all', $ordering = 'newest')
|
||||
{
|
||||
if (isset($keyword))
|
||||
{
|
||||
$this->setState('origkeyword', $keyword);
|
||||
|
||||
if ($match !== 'exact')
|
||||
{
|
||||
$keyword = preg_replace('#\xE3\x80\x80#', ' ', $keyword);
|
||||
}
|
||||
|
||||
$this->setState('keyword', $keyword);
|
||||
}
|
||||
|
||||
if (isset($match))
|
||||
{
|
||||
$this->setState('match', $match);
|
||||
}
|
||||
|
||||
if (isset($ordering))
|
||||
{
|
||||
$this->setState('ordering', $ordering);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get weblink item data for the category
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
// Lets load the content if it doesn't already exist
|
||||
if (empty($this->_data))
|
||||
{
|
||||
$areas = $this->getAreas();
|
||||
|
||||
JPluginHelper::importPlugin('search');
|
||||
$dispatcher = JEventDispatcher::getInstance();
|
||||
$results = $dispatcher->trigger('onContentSearch', array(
|
||||
$this->getState('keyword'),
|
||||
$this->getState('match'),
|
||||
$this->getState('ordering'),
|
||||
$areas['active'])
|
||||
);
|
||||
|
||||
$rows = array();
|
||||
|
||||
foreach ($results as $result)
|
||||
{
|
||||
$rows = array_merge((array) $rows, (array) $result);
|
||||
}
|
||||
|
||||
$this->_total = count($rows);
|
||||
|
||||
if ($this->getState('limit') > 0)
|
||||
{
|
||||
$this->_data = array_splice($rows, $this->getState('limitstart'), $this->getState('limit'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_data = $rows;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the total number of weblink items for the category
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTotal()
|
||||
{
|
||||
return $this->_total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to set the search areas
|
||||
*
|
||||
* @param array $active areas
|
||||
* @param array $search areas
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setAreas($active = array(), $search = array())
|
||||
{
|
||||
$this->_areas['active'] = $active;
|
||||
$this->_areas['search'] = $search;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a pagination object of the weblink items for the category
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getPagination()
|
||||
{
|
||||
// Lets load the content if it doesn't already exist
|
||||
if (empty($this->_pagination))
|
||||
{
|
||||
$this->_pagination = new JPagination($this->getTotal(), $this->getState('limitstart'), $this->getState('limit'));
|
||||
}
|
||||
|
||||
return $this->_pagination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the search areas
|
||||
*
|
||||
* @return integer
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public function getAreas()
|
||||
{
|
||||
// Load the Category data
|
||||
if (empty($this->_areas['search']))
|
||||
{
|
||||
$areas = array();
|
||||
|
||||
JPluginHelper::importPlugin('search');
|
||||
$dispatcher = JEventDispatcher::getInstance();
|
||||
$searchareas = $dispatcher->trigger('onContentSearchAreas');
|
||||
|
||||
foreach ($searchareas as $area)
|
||||
{
|
||||
if (is_array($area))
|
||||
{
|
||||
$areas = array_merge($areas, $area);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_areas['search'] = $areas;
|
||||
}
|
||||
|
||||
return $this->_areas;
|
||||
}
|
||||
}
|
||||
107
components/com_search/router.php
Normal file
107
components/com_search/router.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_search
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
/**
|
||||
* Routing class from com_search
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
class SearchRouter extends JComponentRouterBase
|
||||
{
|
||||
/**
|
||||
* Build the route for the com_search component
|
||||
*
|
||||
* @param array &$query An array of URL arguments
|
||||
*
|
||||
* @return array The URL arguments to use to assemble the subsequent URL.
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
public function build(&$query)
|
||||
{
|
||||
$segments = array();
|
||||
|
||||
if (isset($query['view']))
|
||||
{
|
||||
unset($query['view']);
|
||||
}
|
||||
|
||||
return $segments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the segments of a URL.
|
||||
*
|
||||
* @param array &$segments The segments of the URL to parse.
|
||||
*
|
||||
* @return array The URL attributes to be used by the application.
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
public function parse(&$segments)
|
||||
{
|
||||
$vars = array();
|
||||
|
||||
// Fix up search for URL
|
||||
$total = count($segments);
|
||||
|
||||
for ($i = 0; $i < $total; $i++)
|
||||
{
|
||||
// Urldecode twice because it is encoded twice
|
||||
$segments[$i] = urldecode(urldecode(stripcslashes($segments[$i])));
|
||||
}
|
||||
|
||||
$searchword = array_shift($segments);
|
||||
$vars['searchword'] = $searchword;
|
||||
$vars['view'] = 'search';
|
||||
|
||||
return $vars;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* searchBuildRoute
|
||||
*
|
||||
* These functions are proxies for the new router interface
|
||||
* for old SEF extensions.
|
||||
*
|
||||
* @param array &$query An array of URL arguments
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @deprecated 4.0 Use Class based routers instead
|
||||
*/
|
||||
function searchBuildRoute(&$query)
|
||||
{
|
||||
$router = new SearchRouter;
|
||||
|
||||
return $router->build($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* searchParseRoute
|
||||
*
|
||||
* These functions are proxies for the new router interface
|
||||
* for old SEF extensions.
|
||||
*
|
||||
* @param array $segments The segments of the URL to parse.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @deprecated 4.0 Use Class based routers instead
|
||||
*/
|
||||
function searchParseRoute($segments)
|
||||
{
|
||||
$router = new SearchRouter;
|
||||
|
||||
return $router->parse($segments);
|
||||
}
|
||||
14
components/com_search/search.php
Normal file
14
components/com_search/search.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_search
|
||||
*
|
||||
* @copyright (C) 2005 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
$controller = JControllerLegacy::getInstance('Search');
|
||||
$controller->execute(JFactory::getApplication()->input->get('task'));
|
||||
$controller->redirect();
|
||||
29
components/com_search/views/search/tmpl/default.php
Normal file
29
components/com_search/views/search/tmpl/default.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_search
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
?>
|
||||
<div class="search<?php echo $this->pageclass_sfx; ?>">
|
||||
<?php if ($this->params->get('show_page_heading')) : ?>
|
||||
<h1 class="page-title">
|
||||
<?php if ($this->escape($this->params->get('page_heading'))) : ?>
|
||||
<?php echo $this->escape($this->params->get('page_heading')); ?>
|
||||
<?php else : ?>
|
||||
<?php echo $this->escape($this->params->get('page_title')); ?>
|
||||
<?php endif; ?>
|
||||
</h1>
|
||||
<?php endif; ?>
|
||||
<?php echo $this->loadTemplate('form'); ?>
|
||||
<?php if ($this->error == null && count($this->results) > 0) : ?>
|
||||
<?php echo $this->loadTemplate('results'); ?>
|
||||
<?php else : ?>
|
||||
<?php echo $this->loadTemplate('error'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
103
components/com_search/views/search/tmpl/default.xml
Normal file
103
components/com_search/views/search/tmpl/default.xml
Normal file
@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_SEARCH_SEARCH_VIEW_DEFAULT_TITLE" option="COM_SEARCH_SEARCH_VIEW_DEFAULT_OPTION">
|
||||
<help
|
||||
key = "JHELP_MENUS_MENU_ITEM_SEARCH_RESULTS"
|
||||
/>
|
||||
<message>
|
||||
<![CDATA[COM_SEARCH_SEARCH_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
|
||||
<!-- Add fields to the request variables for the layout. -->
|
||||
<fields name="request">
|
||||
<fieldset name="request" label="COM_SEARCH_FIELDSET_OPTIONAL_LABEL">
|
||||
|
||||
<field
|
||||
name="searchword"
|
||||
type="text"
|
||||
label="COM_SEARCH_FIELD_LABEL"
|
||||
description="COM_SEARCH_FIELD_DESC"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
<!-- Add fields to the parameters object for the layout. -->
|
||||
<fields name="params">
|
||||
|
||||
<!-- Basic options. -->
|
||||
<fieldset name="basic" label="COM_MENUS_BASIC_FIELDSET_LABEL">
|
||||
|
||||
<field
|
||||
name="search_phrases"
|
||||
type="list"
|
||||
label="COM_SEARCH_FIELD_SEARCH_PHRASES_LABEL"
|
||||
description="COM_SEARCH_FIELD_SEARCH_PHRASES_DESC"
|
||||
useglobal="true"
|
||||
class="chzn-color"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="search_areas"
|
||||
type="list"
|
||||
label="COM_SEARCH_FIELD_SEARCH_AREAS_LABEL"
|
||||
description="COM_SEARCH_FIELD_SEARCH_AREAS_DESC"
|
||||
useglobal="true"
|
||||
class="chzn-color"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_date"
|
||||
type="list"
|
||||
label="COM_SEARCH_CONFIG_FIELD_CREATED_DATE_LABEL"
|
||||
description="COM_SEARCH_CONFIG_FIELD_CREATED_DATE_DESC"
|
||||
useglobal="true"
|
||||
class="chzn-color"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="spacer1"
|
||||
type="spacer"
|
||||
label="COM_SEARCH_SAVED_SEARCH_OPTIONS"
|
||||
class="text"
|
||||
/>
|
||||
|
||||
<!-- Add fields to define saved search. -->
|
||||
|
||||
<field
|
||||
name="searchphrase"
|
||||
type="list"
|
||||
label="COM_SEARCH_FOR_LABEL"
|
||||
description="COM_SEARCH_FOR_DESC"
|
||||
default="0"
|
||||
>
|
||||
<option value="0">COM_SEARCH_ALL_WORDS</option>
|
||||
<option value="1">COM_SEARCH_ANY_WORDS</option>
|
||||
<option value="2">COM_SEARCH_EXACT_PHRASE</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="ordering"
|
||||
type="list"
|
||||
label="COM_SEARCH_ORDERING_LABEL"
|
||||
description="COM_SEARCH_ORDERING_DESC"
|
||||
default="newest"
|
||||
>
|
||||
<option value="newest">COM_SEARCH_NEWEST_FIRST</option>
|
||||
<option value="oldest">COM_SEARCH_OLDEST_FIRST</option>
|
||||
<option value="popular">COM_SEARCH_MOST_POPULAR</option>
|
||||
<option value="alpha">COM_SEARCH_ALPHABETICAL</option>
|
||||
<option value="category">JCATEGORY</option>
|
||||
</field>
|
||||
|
||||
</fieldset>
|
||||
</fields>
|
||||
</metadata>
|
||||
17
components/com_search/views/search/tmpl/default_error.php
Normal file
17
components/com_search/views/search/tmpl/default_error.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_search
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
?>
|
||||
<?php if ($this->error) : ?>
|
||||
<div class="error">
|
||||
<?php echo $this->escape($this->error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
83
components/com_search/views/search/tmpl/default_form.php
Normal file
83
components/com_search/views/search/tmpl/default_form.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_search
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
JHtml::_('bootstrap.tooltip');
|
||||
|
||||
$lang = JFactory::getLanguage();
|
||||
$upper_limit = $lang->getUpperLimitSearchWord();
|
||||
|
||||
?>
|
||||
<form id="searchForm" action="<?php echo JRoute::_('index.php?option=com_search'); ?>" method="post">
|
||||
<div class="btn-toolbar">
|
||||
<div class="btn-group pull-left">
|
||||
<label for="search-searchword" class="element-invisible">
|
||||
<?php echo JText::_('COM_SEARCH_SEARCH_KEYWORD'); ?>
|
||||
</label>
|
||||
<input type="text" name="searchword" title="<?php echo JText::_('COM_SEARCH_SEARCH_KEYWORD'); ?>" placeholder="<?php echo JText::_('COM_SEARCH_SEARCH_KEYWORD'); ?>" id="search-searchword" size="30" maxlength="<?php echo $upper_limit; ?>" value="<?php echo $this->escape($this->origkeyword); ?>" class="inputbox" />
|
||||
</div>
|
||||
<div class="btn-group pull-left">
|
||||
<button name="Search" onclick="this.form.submit()" class="btn hasTooltip" title="<?php echo JHtml::_('tooltipText', 'COM_SEARCH_SEARCH');?>">
|
||||
<span class="icon-search"></span>
|
||||
<?php echo JText::_('JSEARCH_FILTER_SUBMIT'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<input type="hidden" name="task" value="search" />
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="searchintro<?php echo $this->params->get('pageclass_sfx', ''); ?>">
|
||||
<?php if (!empty($this->searchword)) : ?>
|
||||
<p>
|
||||
<?php echo JText::plural('COM_SEARCH_SEARCH_KEYWORD_N_RESULTS', '<span class="badge badge-info">' . $this->total . '</span>'); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ($this->params->get('search_phrases', 1)) : ?>
|
||||
<fieldset class="phrases">
|
||||
<legend>
|
||||
<?php echo JText::_('COM_SEARCH_FOR'); ?>
|
||||
</legend>
|
||||
<div class="phrases-box">
|
||||
<?php echo $this->lists['searchphrase']; ?>
|
||||
</div>
|
||||
<div class="ordering-box">
|
||||
<label for="ordering" class="ordering">
|
||||
<?php echo JText::_('COM_SEARCH_ORDERING'); ?>
|
||||
</label>
|
||||
<?php echo $this->lists['ordering']; ?>
|
||||
</div>
|
||||
</fieldset>
|
||||
<?php endif; ?>
|
||||
<?php if ($this->params->get('search_areas', 1)) : ?>
|
||||
<fieldset class="only">
|
||||
<legend>
|
||||
<?php echo JText::_('COM_SEARCH_SEARCH_ONLY'); ?>
|
||||
</legend>
|
||||
<?php foreach ($this->searchareas['search'] as $val => $txt) : ?>
|
||||
<?php $checked = is_array($this->searchareas['active']) && in_array($val, $this->searchareas['active']) ? 'checked="checked"' : ''; ?>
|
||||
<label for="area-<?php echo $val; ?>" class="checkbox">
|
||||
<input type="checkbox" name="areas[]" value="<?php echo $val; ?>" id="area-<?php echo $val; ?>" <?php echo $checked; ?> />
|
||||
<?php echo JText::_($txt); ?>
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</fieldset>
|
||||
<?php endif; ?>
|
||||
<?php if ($this->total > 0) : ?>
|
||||
<div class="form-limit">
|
||||
<label for="limit">
|
||||
<?php echo JText::_('JGLOBAL_DISPLAY_NUM'); ?>
|
||||
</label>
|
||||
<?php echo $this->pagination->getLimitBox(); ?>
|
||||
</div>
|
||||
<p class="counter">
|
||||
<?php echo $this->pagination->getPagesCounter(); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
48
components/com_search/views/search/tmpl/default_results.php
Normal file
48
components/com_search/views/search/tmpl/default_results.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_search
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
?>
|
||||
<dl class="search-results<?php echo $this->pageclass_sfx; ?>">
|
||||
<?php foreach ($this->results as $result) : ?>
|
||||
<dt class="result-title">
|
||||
<?php echo $this->pagination->limitstart + $result->count . '. '; ?>
|
||||
<?php if ($result->href) : ?>
|
||||
<a href="<?php echo JRoute::_($result->href); ?>"<?php if ($result->browsernav == 1) : ?> target="_blank"<?php endif; ?>>
|
||||
<?php // $result->title should not be escaped in this case, as it may ?>
|
||||
<?php // contain span HTML tags wrapping the searched terms, if present ?>
|
||||
<?php // in the title. ?>
|
||||
<?php echo $result->title; ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<?php // see above comment: do not escape $result->title ?>
|
||||
<?php echo $result->title; ?>
|
||||
<?php endif; ?>
|
||||
</dt>
|
||||
<?php if ($result->section) : ?>
|
||||
<dd class="result-category">
|
||||
<span class="small<?php echo $this->pageclass_sfx; ?>">
|
||||
(<?php echo $this->escape($result->section); ?>)
|
||||
</span>
|
||||
</dd>
|
||||
<?php endif; ?>
|
||||
<dd class="result-text">
|
||||
<?php echo $result->text; ?>
|
||||
</dd>
|
||||
<?php if ($this->params->get('show_date')) : ?>
|
||||
<dd class="result-created<?php echo $this->pageclass_sfx; ?>">
|
||||
<?php echo JText::sprintf('JGLOBAL_CREATED_DATE_ON', $result->created); ?>
|
||||
</dd>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</dl>
|
||||
<div class="pagination">
|
||||
<?php echo $this->pagination->getPagesLinks(); ?>
|
||||
</div>
|
||||
314
components/com_search/views/search/view.html.php
Normal file
314
components/com_search/views/search/view.html.php
Normal file
@ -0,0 +1,314 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_search
|
||||
*
|
||||
* @copyright (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\String\StringHelper;
|
||||
|
||||
/**
|
||||
* HTML View class for the search component
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
class SearchViewSearch extends JViewLegacy
|
||||
{
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return mixed A string if successful, otherwise an Error object.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
JLoader::register('SearchHelper', JPATH_COMPONENT_ADMINISTRATOR . '/helpers/search.php');
|
||||
|
||||
$app = JFactory::getApplication();
|
||||
$uri = JUri::getInstance();
|
||||
$error = null;
|
||||
$results = null;
|
||||
$total = 0;
|
||||
|
||||
// Get some data from the model
|
||||
$areas = $this->get('areas');
|
||||
$state = $this->get('state');
|
||||
$searchWord = $state->get('keyword');
|
||||
$params = $app->getParams();
|
||||
|
||||
if (!$app->getMenu()->getActive())
|
||||
{
|
||||
$params->set('page_title', JText::_('COM_SEARCH_SEARCH'));
|
||||
}
|
||||
|
||||
$title = $params->get('page_title');
|
||||
|
||||
if ($app->get('sitename_pagetitles', 0) == 1)
|
||||
{
|
||||
$title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title);
|
||||
}
|
||||
elseif ($app->get('sitename_pagetitles', 0) == 2)
|
||||
{
|
||||
$title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename'));
|
||||
}
|
||||
|
||||
$this->document->setTitle($title);
|
||||
|
||||
if ($params->get('menu-meta_description'))
|
||||
{
|
||||
$this->document->setDescription($params->get('menu-meta_description'));
|
||||
}
|
||||
|
||||
if ($params->get('menu-meta_keywords'))
|
||||
{
|
||||
$this->document->setMetadata('keywords', $params->get('menu-meta_keywords'));
|
||||
}
|
||||
|
||||
if ($params->get('robots'))
|
||||
{
|
||||
$this->document->setMetadata('robots', $params->get('robots'));
|
||||
}
|
||||
|
||||
// Built select lists
|
||||
$orders = array();
|
||||
$orders[] = JHtml::_('select.option', 'newest', JText::_('COM_SEARCH_NEWEST_FIRST'));
|
||||
$orders[] = JHtml::_('select.option', 'oldest', JText::_('COM_SEARCH_OLDEST_FIRST'));
|
||||
$orders[] = JHtml::_('select.option', 'popular', JText::_('COM_SEARCH_MOST_POPULAR'));
|
||||
$orders[] = JHtml::_('select.option', 'alpha', JText::_('COM_SEARCH_ALPHABETICAL'));
|
||||
$orders[] = JHtml::_('select.option', 'category', JText::_('JCATEGORY'));
|
||||
|
||||
$lists = array();
|
||||
$lists['ordering'] = JHtml::_('select.genericlist', $orders, 'ordering', 'class="inputbox"', 'value', 'text', $state->get('ordering'));
|
||||
|
||||
$searchphrases = array();
|
||||
$searchphrases[] = JHtml::_('select.option', 'all', JText::_('COM_SEARCH_ALL_WORDS'));
|
||||
$searchphrases[] = JHtml::_('select.option', 'any', JText::_('COM_SEARCH_ANY_WORDS'));
|
||||
$searchphrases[] = JHtml::_('select.option', 'exact', JText::_('COM_SEARCH_EXACT_PHRASE'));
|
||||
$lists['searchphrase'] = JHtml::_('select.radiolist', $searchphrases, 'searchphrase', '', 'value', 'text', $state->get('match'));
|
||||
|
||||
// Log the search
|
||||
\Joomla\CMS\Helper\SearchHelper::logSearch($searchWord, 'com_search');
|
||||
|
||||
// Limit search-word
|
||||
$lang = JFactory::getLanguage();
|
||||
$upper_limit = $lang->getUpperLimitSearchWord();
|
||||
$lower_limit = $lang->getLowerLimitSearchWord();
|
||||
|
||||
if (SearchHelper::limitSearchWord($searchWord))
|
||||
{
|
||||
$error = JText::sprintf('COM_SEARCH_ERROR_SEARCH_MESSAGE', $lower_limit, $upper_limit);
|
||||
}
|
||||
|
||||
// Sanitise search-word
|
||||
if (SearchHelper::santiseSearchWord($searchWord, $state->get('match')))
|
||||
{
|
||||
$error = JText::_('COM_SEARCH_ERROR_IGNOREKEYWORD');
|
||||
}
|
||||
|
||||
if (!$searchWord && !empty($this->input) && count($this->input->post))
|
||||
{
|
||||
// $error = JText::_('COM_SEARCH_ERROR_ENTERKEYWORD');
|
||||
}
|
||||
|
||||
// Put the filtered results back into the model
|
||||
// for next release, the checks should be done in the model perhaps...
|
||||
$state->set('keyword', $searchWord);
|
||||
|
||||
if ($error === null)
|
||||
{
|
||||
$results = $this->get('data');
|
||||
$total = $this->get('total');
|
||||
$pagination = $this->get('pagination');
|
||||
|
||||
// Flag indicates to not add limitstart=0 to URL
|
||||
$pagination->hideEmptyLimitstart = true;
|
||||
|
||||
if ($state->get('match') === 'exact')
|
||||
{
|
||||
$searchWords = array($searchWord);
|
||||
$needle = $searchWord;
|
||||
}
|
||||
else
|
||||
{
|
||||
$searchWordA = preg_replace('#\xE3\x80\x80#', ' ', $searchWord);
|
||||
$searchWords = preg_split("/\s+/u", $searchWordA);
|
||||
$needle = $searchWords[0];
|
||||
}
|
||||
|
||||
JLoader::register('ContentHelperRoute', JPATH_SITE . '/components/com_content/helpers/route.php');
|
||||
|
||||
// Make sure there are no slashes in the needle
|
||||
$needle = str_replace('/', '\/', $needle);
|
||||
|
||||
for ($i = 0, $count = count($results); $i < $count; ++$i)
|
||||
{
|
||||
$rowTitle = &$results[$i]->title;
|
||||
$rowTitleHighLighted = $this->highLight($rowTitle, $needle, $searchWords);
|
||||
$rowText = &$results[$i]->text;
|
||||
$rowTextHighLighted = $this->highLight($rowText, $needle, $searchWords);
|
||||
|
||||
$result = &$results[$i];
|
||||
$created = '';
|
||||
|
||||
if ($result->created)
|
||||
{
|
||||
$created = JHtml::_('date', $result->created, JText::_('DATE_FORMAT_LC3'));
|
||||
}
|
||||
|
||||
$result->title = $rowTitleHighLighted;
|
||||
$result->text = JHtml::_('content.prepare', $rowTextHighLighted, '', 'com_search.search');
|
||||
$result->created = $created;
|
||||
$result->count = $i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for layout override
|
||||
$active = JFactory::getApplication()->getMenu()->getActive();
|
||||
|
||||
if (isset($active->query['layout']))
|
||||
{
|
||||
$this->setLayout($active->query['layout']);
|
||||
}
|
||||
|
||||
// Escape strings for HTML output
|
||||
$this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx', ''));
|
||||
$this->pagination = &$pagination;
|
||||
$this->results = &$results;
|
||||
$this->lists = &$lists;
|
||||
$this->params = &$params;
|
||||
$this->ordering = $state->get('ordering');
|
||||
$this->searchword = $searchWord;
|
||||
$this->origkeyword = $state->get('origkeyword');
|
||||
$this->searchphrase = $state->get('match');
|
||||
$this->searchareas = $areas;
|
||||
$this->total = $total;
|
||||
$this->error = $error;
|
||||
$this->action = $uri;
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to control the highlighting of keywords
|
||||
*
|
||||
* @param string $string text to be searched
|
||||
* @param string $needle text to search for
|
||||
* @param string $searchWords words to be searched
|
||||
*
|
||||
* @return mixed A string.
|
||||
*
|
||||
* @since 3.8.4
|
||||
*/
|
||||
public function highLight($string, $needle, $searchWords)
|
||||
{
|
||||
$hl1 = '<span class="highlight">';
|
||||
$hl2 = '</span>';
|
||||
$mbString = extension_loaded('mbstring');
|
||||
$highlighterLen = strlen($hl1 . $hl2);
|
||||
|
||||
// Doing HTML entity decoding here, just in case we get any HTML entities here.
|
||||
$quoteStyle = version_compare(PHP_VERSION, '5.4', '>=') ? ENT_NOQUOTES | ENT_HTML401 : ENT_NOQUOTES;
|
||||
$row = html_entity_decode($string, $quoteStyle, 'UTF-8');
|
||||
$row = SearchHelper::prepareSearchContent($row, $needle);
|
||||
$searchWords = array_values(array_unique($searchWords));
|
||||
$lowerCaseRow = $mbString ? mb_strtolower($row) : StringHelper::strtolower($row);
|
||||
|
||||
$transliteratedLowerCaseRow = SearchHelper::remove_accents($lowerCaseRow);
|
||||
|
||||
$posCollector = array();
|
||||
|
||||
foreach ($searchWords as $highlightWord)
|
||||
{
|
||||
$found = false;
|
||||
|
||||
if ($mbString)
|
||||
{
|
||||
$lowerCaseHighlightWord = mb_strtolower($highlightWord);
|
||||
|
||||
if (($pos = mb_strpos($lowerCaseRow, $lowerCaseHighlightWord)) !== false)
|
||||
{
|
||||
$found = true;
|
||||
}
|
||||
elseif (($pos = mb_strpos($transliteratedLowerCaseRow, $lowerCaseHighlightWord)) !== false)
|
||||
{
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$lowerCaseHighlightWord = StringHelper::strtolower($highlightWord);
|
||||
|
||||
if (($pos = StringHelper::strpos($lowerCaseRow, $lowerCaseHighlightWord)) !== false)
|
||||
{
|
||||
$found = true;
|
||||
}
|
||||
elseif (($pos = StringHelper::strpos($transliteratedLowerCaseRow, $lowerCaseHighlightWord)) !== false)
|
||||
{
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($found === true)
|
||||
{
|
||||
// Iconv transliterates '€' to 'EUR'
|
||||
// TODO: add other expanding translations?
|
||||
$eur_compensation = $pos > 0 ? substr_count($row, "\xE2\x82\xAC", 0, $pos) * 2 : 0;
|
||||
$pos -= $eur_compensation;
|
||||
|
||||
// Collect pos and search-word
|
||||
$posCollector[$pos] = $highlightWord;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($posCollector))
|
||||
{
|
||||
// Sort by pos. Easier to handle overlapping highlighter-spans
|
||||
ksort($posCollector);
|
||||
$cnt = 0;
|
||||
$lastHighlighterEnd = -1;
|
||||
|
||||
foreach ($posCollector as $pos => $highlightWord)
|
||||
{
|
||||
$pos += $cnt * $highlighterLen;
|
||||
|
||||
/*
|
||||
* Avoid overlapping/corrupted highlighter-spans
|
||||
* TODO $chkOverlap could be used to highlight remaining part
|
||||
* of search-word outside last highlighter-span.
|
||||
* At the moment no additional highlighter is set.
|
||||
*/
|
||||
$chkOverlap = $pos - $lastHighlighterEnd;
|
||||
|
||||
if ($chkOverlap >= 0)
|
||||
{
|
||||
// Set highlighter around search-word
|
||||
if ($mbString)
|
||||
{
|
||||
$highlightWordLen = mb_strlen($highlightWord);
|
||||
$row = mb_substr($row, 0, $pos) . $hl1 . mb_substr($row, $pos, $highlightWordLen)
|
||||
. $hl2 . mb_substr($row, $pos + $highlightWordLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
$highlightWordLen = StringHelper::strlen($highlightWord);
|
||||
$row = StringHelper::substr($row, 0, $pos)
|
||||
. $hl1 . StringHelper::substr($row, $pos, StringHelper::strlen($highlightWord))
|
||||
. $hl2 . StringHelper::substr($row, $pos + StringHelper::strlen($highlightWord));
|
||||
}
|
||||
|
||||
$cnt++;
|
||||
$lastHighlighterEnd = $pos + $highlightWordLen + $highlighterLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
52
components/com_search/views/search/view.opensearch.php
Normal file
52
components/com_search/views/search/view.opensearch.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_search
|
||||
*
|
||||
* @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
/**
|
||||
* OpenSearch View class for the Search component
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
class SearchViewSearch extends JViewLegacy
|
||||
{
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl name of the template
|
||||
*
|
||||
* @throws Exception
|
||||
* @return mixed A string if successful, otherwise an Error object.
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$doc = JFactory::getDocument();
|
||||
$app = JFactory::getApplication();
|
||||
|
||||
$params = JComponentHelper::getParams('com_search');
|
||||
$doc->setShortName($params->get('opensearch_name', $app->get('sitename')));
|
||||
$doc->setDescription($params->get('opensearch_description', $app->get('MetaDesc')));
|
||||
|
||||
// Add the URL for the search
|
||||
$searchUri = JUri::base() . 'index.php?option=com_search&searchword={searchTerms}';
|
||||
|
||||
// Find the menu item for the search
|
||||
$menu = $app->getMenu();
|
||||
$items = $menu->getItems('link', 'index.php?option=com_search&view=search');
|
||||
|
||||
if (isset($items[0]))
|
||||
{
|
||||
$searchUri .= '&Itemid=' . $items[0]->id;
|
||||
}
|
||||
|
||||
$htmlSearch = new JOpenSearchUrl;
|
||||
$htmlSearch->template = JRoute::_($searchUri);
|
||||
$doc->addUrl($htmlSearch);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user