freenetis-github/application/controllers/search.php @ c4e49814
8baed187 | Michal Kliment | <?php defined('SYSPATH') or die('No direct script access.');
|
|
/*
|
|||
* This file is part of open source system FreenetIS
|
|||
* and it is released under GPLv3 licence.
|
|||
*
|
|||
* More info about licence can be found:
|
|||
* http://www.gnu.org/licenses/gpl-3.0.html
|
|||
*
|
|||
* More info about project can be found:
|
|||
* http://www.freenetis.org/
|
|||
*
|
|||
*/
|
|||
/**
|
|||
* Controller handles search throught whole system.
|
|||
*
|
|||
* @author Michal Kliment
|
|||
*/
|
|||
class Search_Controller extends Controller
|
|||
{
|
|||
/**
|
|||
* Array with results of search
|
|||
*
|
|||
* @var array
|
|||
*/
|
|||
private $results = array();
|
|||
/**
|
|||
* Only redirects to method simple
|
|||
*
|
|||
* @author Michal Kliment
|
|||
*/
|
|||
public function index()
|
|||
{
|
|||
url::redirect('search/simple/' . $this->input->get('keyword'));
|
|||
}
|
|||
/**
|
|||
* Base method, makes search.
|
|||
* Search result is placed to property $results
|
|||
*
|
|||
c1bdc1c4 | Michal Kliment | * @author Ondrej Fibich, Michal Kliment
|
|
8baed187 | Michal Kliment | * @param string $keyword
|
|
c1bdc1c4 | Michal Kliment | * @param integer $limit Limit of results
|
|
8baed187 | Michal Kliment | */
|
|
c1bdc1c4 | Michal Kliment | private function search($keyword = NULL, $limit = NULL)
|
|
8baed187 | Michal Kliment | {
|
|
c1bdc1c4 | Michal Kliment | // trim and remove unrequired cars from keyword
|
|
$keyword = trim($keyword);
|
|||
$mkeyword = preg_replace("/[\[\]!\"#$%&'()*+,\/:;<=>?@\^`{|}~-]/", ' ', $keyword);
|
|||
// separate keywords
|
|||
$keywords = explode(' ', preg_replace("/\s+/", ' ', $mkeyword));
|
|||
8baed187 | Michal Kliment | ||
c1bdc1c4 | Michal Kliment | // variations - if keyword contains many words (> 3) then only create
|
|
// variations that contains all words of keyword but only sorted in many
|
|||
// ways. If keyword do not contain many words then make all variations.
|
|||
// If keyword contains more then 5 words then disable variations at all.
|
|||
$variation_keys = array();
|
|||
8baed187 | Michal Kliment | ||
c1bdc1c4 | Michal Kliment | if (count($keywords) <= 3) // all
|
|
{
|
|||
for ($i = count($keywords); $i > 0; $i--)
|
|||
{
|
|||
$variation_keys = arr::merge($variation_keys, arr::variation($keywords, $i));
|
|||
}
|
|||
}
|
|||
else if (count($keywords) > 5) // only keyword
|
|||
{
|
|||
$variation_keys = array($mkeyword);
|
|||
}
|
|||
else // only mixed keyword
|
|||
{
|
|||
$variation_keys = arr::variation($keywords, count($keywords));
|
|||
}
|
|||
8baed187 | Michal Kliment | ||
c1bdc1c4 | Michal Kliment | // search model
|
|
8baed187 | Michal Kliment | $search_model = new Search_Model();
|
|
c1bdc1c4 | Michal Kliment | // search variables
|
|
$search_rules = Search_Model::get_rules_sorted_by_weight();
|
|||
8baed187 | Michal Kliment | $sums = array();
|
|
$counts = array();
|
|||
$total_counts = array();
|
|||
$values = array();
|
|||
c1bdc1c4 | Michal Kliment | ||
// no rules => empty result
|
|||
if (!count($search_rules))
|
|||
{
|
|||
$this->results = array();
|
|||
return;
|
|||
}
|
|||
// each rule should get oportunity to be searched (reserved limits)
|
|||
$result_limit = !empty($limit) ? ceil($limit / count($search_rules)) : NULL;
|
|||
8baed187 | Michal Kliment | // foreach all search rules
|
|
c1bdc1c4 | Michal Kliment | foreach ($search_rules as $rule)
|
|
8baed187 | Michal Kliment | {
|
|
c1bdc1c4 | Michal Kliment | // networks is disabled
|
|
if (!Settings::get('networks_enabled') && (
|
|||
$rule['model'] == 'device' ||
|
|||
$rule['model'] == 'subnet' ||
|
|||
$rule['model'] == 'link'
|
|||
))
|
|||
{
|
|||
continue;
|
|||
}
|
|||
// search only in keyword by default
|
|||
$searched_keys = array($keyword);
|
|||
// variation enabled?
|
|||
if (isset($rule['variation_enabled']) && $rule['variation_enabled'])
|
|||
{
|
|||
$searched_keys = $variation_keys;
|
|||
}
|
|||
8baed187 | Michal Kliment | // foreach variations
|
|
c1bdc1c4 | Michal Kliment | foreach ($searched_keys as $key)
|
|
8baed187 | Michal Kliment | {
|
|
if (isset($total_counts[$rule['model']]))
|
|||
c1bdc1c4 | Michal Kliment | {
|
|
8baed187 | Michal Kliment | $total_counts[$rule['model']]++;
|
|
c1bdc1c4 | Michal Kliment | }
|
|
8baed187 | Michal Kliment | else
|
|
c1bdc1c4 | Michal Kliment | {
|
|
8baed187 | Michal Kliment | $total_counts[$rule['model']] = 1;
|
|
c1bdc1c4 | Michal Kliment | }
|
|
8baed187 | Michal Kliment | ||
ecfe4a41 | Michal Kliment | $method_result_limit = ceil($result_limit * $rule['limit_weight']);
|
|
$result = $search_model->{$rule['method']}($key, $method_result_limit);
|
|||
8baed187 | Michal Kliment | ||
foreach ($result as $row)
|
|||
{
|
|||
c1bdc1c4 | Michal Kliment | $titled_value = url::title($row->value, ' ');
|
|
$percent = 0;
|
|||
8baed187 | Michal Kliment | // test how much are texts similar
|
|
c1bdc1c4 | Michal Kliment | similar_text($titled_value, url::title($key, ' '), $percent);
|
|
// rating and informations about this result was not registered yet
|
|||
8baed187 | Michal Kliment | if (!isset($sums[$rule['model']][$row->id]))
|
|
{
|
|||
$sums[$rule['model']][$row->id] = 0;
|
|||
$counts[$rule['model']][$row->id] = 0;
|
|||
$values[$rule['model']][$row->id] = $row;
|
|||
}
|
|||
c1bdc1c4 | Michal Kliment | ||
// weight to percentage
|
|||
$weight = $rule['weight'];
|
|||
// special treatment if value is same as keyword
|
|||
if (!isset($rule['ignore_special_threatment']) ||
|
|||
!$rule['ignore_special_threatment'])
|
|||
{
|
|||
// keyword match with special threatment for
|
|||
// login (we do want to mess tha members)
|
|||
if (strtolower(trim($keyword)) == strtolower(trim($row->value)) &&
|
|||
$rule['method'] != 'user_login')
|
|||
{
|
|||
$weight = 3.5;
|
|||
}
|
|||
// modified keyword match
|
|||
if (strtolower(trim($mkeyword)) == strtolower(trim($row->value)))
|
|||
{
|
|||
$weight = 2.5;
|
|||
}
|
|||
// special treatment if titled value is same as titled modified keyword
|
|||
else if (url::title($mkeyword) == $titled_value)
|
|||
{
|
|||
$weight = 2;
|
|||
}
|
|||
}
|
|||
// special threatment for number results weight if they are equal
|
|||
if ($rule['method'] == 'member_id' &&
|
|||
intval($keyword) == intval($row->value))
|
|||
{
|
|||
// member ID is equal => increase weight of this result
|
|||
$weight = 6;
|
|||
}
|
|||
else if ($rule['method'] == 'member_variable_symbol' &&
|
|||
intval($keyword) == intval($row->value))
|
|||
{
|
|||
// variable key equals to key?
|
|||
$weight = 6;
|
|||
}
|
|||
// add rating about the current result
|
|||
$sums[$rule['model']][$row->id] += $percent * $weight;
|
|||
8baed187 | Michal Kliment | $counts[$rule['model']][$row->id]++;
|
|
}
|
|||
}
|
|||
}
|
|||
$result_sums = array();
|
|||
ecfe4a41 | Michal Kliment | $this->results = array();
|
|
8baed187 | Michal Kliment | ||
// transforms to 1-dimensional array
|
|||
foreach ($sums as $model => $model_sums)
|
|||
{
|
|||
foreach ($model_sums as $id => $sum)
|
|||
{
|
|||
$result_sums[] = $sum;
|
|||
$this->results[] = $values[$model][$id];
|
|||
}
|
|||
}
|
|||
c1bdc1c4 | Michal Kliment | ||
8baed187 | Michal Kliment | // sorts results
|
|
array_multisort($result_sums, SORT_DESC, $this->results, SORT_DESC);
|
|||
}
|
|||
/**
|
|||
* Simple searching, uses method search
|
|||
*
|
|||
* @author Michal Kliment
|
|||
* @param string $keyword
|
|||
* @param integer $limit_results
|
|||
* @param integer $page_word
|
|||
* @param integer $page
|
|||
*/
|
|||
c1bdc1c4 | Michal Kliment | public function simple($keyword = NULL, $limit_results = 20,
|
|
$page_word = 'page', $page = 1)
|
|||
8baed187 | Michal Kliment | {
|
|
// bad parameter
|
|||
if (!$keyword)
|
|||
c1bdc1c4 | Michal Kliment | {
|
|
8baed187 | Michal Kliment | Controller::warning(PARAMETER);
|
|
c1bdc1c4 | Michal Kliment | }
|
|
8baed187 | Michal Kliment | ||
// searching
|
|||
$this->search($keyword);
|
|||
$pagination = new Pagination(array
|
|||
(
|
|||
'base_url' => Config::get('lang') . '/search/simple/'
|
|||
. $keyword . '/' . $limit_results,
|
|||
'uri_segment' => 'page',
|
|||
'total_items' => count($this->results),
|
|||
'items_per_page' => $limit_results
|
|||
));
|
|||
$from = ($page - 1) * $limit_results;
|
|||
$to = $page * $limit_results;
|
|||
if ($to >= count($this->results))
|
|||
c1bdc1c4 | Michal Kliment | {
|
|
8baed187 | Michal Kliment | $to = count($this->results) - 1;
|
|
c1bdc1c4 | Michal Kliment | }
|
|
8baed187 | Michal Kliment | ||
$view = new View('main');
|
|||
$view->keyword = $keyword;
|
|||
$view->title = $keyword . ' - ' . __('Searching');
|
|||
$view->content = new View('search/simple');
|
|||
$view->content->keyword = $keyword;
|
|||
$view->content->total_items = count($this->results);
|
|||
$view->content->pagination = $pagination;
|
|||
$view->content->results = $this->results;
|
|||
$view->content->from = $from;
|
|||
$view->content->to = $to;
|
|||
$view->render(TRUE);
|
|||
}
|
|||
/**
|
|||
* Ajax searching (for whisper)
|
|||
*
|
|||
* @author Michal Kliment
|
|||
c1bdc1c4 | Michal Kliment | * @param integer $count do not change contans unless you know what it will cause!!
|
|
8baed187 | Michal Kliment | */
|
|
c1bdc1c4 | Michal Kliment | public function ajax($count = 150)
|
|
8baed187 | Michal Kliment | {
|
|
c1bdc1c4 | Michal Kliment | $keyword = $this->input->get('q');
|
|
$this->search($keyword, $count);
|
|||
8baed187 | Michal Kliment | ||
c1bdc1c4 | Michal Kliment | $view = new View('search/ajax');
|
|
$view->total_items = count($this->results);
|
|||
$view->results = $this->results;
|
|||
$view->keyword = $keyword;
|
|||
$view->render(TRUE);
|
|||
8baed187 | Michal Kliment | }
|
|
}
|