rework crawler; add atom link extraction
[phinde.git] / www / index.php
1 <?php
2 namespace phinde;
3 // web interface to search
4 require 'www-header.php';
5
6 if (!isset($_GET['q'])) {
7     $_GET['q'] = '';
8 }
9
10 $query = $_GET['q'];
11 $page = 0;
12 if (isset($_GET['page'])) {
13     if (!is_numeric($_GET['page'])) {
14         throw new Exception_Input('List page is not numeric');
15     }
16     //PEAR Pager begins at 1
17     $page = (int)$_GET['page'] - 1;
18 }
19 $perPage = 10;//$GLOBALS['phinde']['perPage'];
20 $site = null;
21 $siteParam = false;
22 $baseLink = '?q=' . urlencode($query);
23
24 if (preg_match('#site:([^ ]*)#', $query, $matches)) {
25     $site = $matches[1];
26     $cleanQuery = trim(str_replace('site:' . $site, '', $query));
27     $site = Helper::noSchema($site);
28 } else if (isset($_GET['site']) && trim(isset($_GET['site'])) != '') {
29     $site = trim($_GET['site']);
30     $siteParam = true;
31     $cleanQuery = $query;
32     $baseLink .= '&site=' . urlencode($site);
33 } else {
34     $cleanQuery = $query;
35 }
36
37 $filters = array();
38 if (isset($_GET['filter'])) {
39     $allowedFilter = array('domain', 'language', 'tags', 'term');
40     foreach ($_GET['filter'] as $type => $value) {
41         if (in_array($type, $allowedFilter)) {
42             $filters[$type] = filter_var($value, FILTER_SANITIZE_STRING);
43         }
44     }
45 }
46 $activeFilters = array();
47 foreach ($filters as $type => $value) {
48     $activeFilters[$type] = array(
49         'label' => $value,
50         'removeUrl' => buildLink($baseLink, $filters, $type, null),
51     );
52 }
53
54 function buildLink($baseLink, $filters, $addFilterType, $addFilterValue)
55 {
56     if ($addFilterValue === null) {
57         if (array_key_exists($addFilterType, $filters)) {
58             unset($filters[$addFilterType]);
59         }
60     } else {
61         $filters[$addFilterType] = $addFilterValue;
62     }
63
64     $params = http_build_query(array('filter' => $filters));
65     if (strlen($params)) {
66         return $baseLink . '&' . $params;
67     }
68     return $baseLink;
69 }
70
71 if (preg_match('#site:([^ ]*)#', $query, $matches)) {
72     $site = $matches[1];
73     $cleanQuery = trim(str_replace('site:' . $site, '', $query));
74     $site = Helper::noSchema($site);
75     $urlNoSite = buildLink('?q=' . urlencode($cleanQuery), $filters, null, null);
76 } else {
77     $cleanQuery = $query;
78     $urlNoSite = null;
79 }
80
81 $timeBegin = microtime(true);
82 $es = new Elasticsearch($GLOBALS['phinde']['elasticsearch']);
83 $res = $es->search($cleanQuery, $filters, $site, $page, $perPage);
84 $timeEnd = microtime(true);
85
86 $pager = new Html_Pager(
87     $res->hits->total, $perPage, $page + 1,
88     $baseLink
89 );
90
91 foreach ($res->hits->hits as &$hit) {
92     $doc = $hit->_source;
93     if (!isset($doc->title) || $doc->title == '') {
94         $doc->title = '(no title)';
95         $doc->htmlTitle = '(no title)';
96     }
97     if (isset($hit->highlight->title[0])) {
98         $doc->htmlTitle = $hit->highlight->title[0];
99     } else {
100         $doc->htmlTitle = htmlspecialchars($doc->title);
101     }
102     if (isset($hit->highlight->text[0])) {
103         $doc->htmlText = $hit->highlight->text[0];
104     } else {
105         $doc->htmlText = null;
106     }
107
108     $doc->extra = new \stdClass();
109     $doc->extra->cleanUrl = preg_replace('#^.*://#', '', $doc->url);
110     if (isset($doc->modate)) {
111         $doc->extra->day = substr($doc->modate, 0, 10);
112     }
113 }
114
115 foreach ($res->aggregations as $key => &$aggregation) {
116     foreach ($aggregation->buckets as &$bucket) {
117         $bucket->url = buildLink($baseLink, $filters, $key, $bucket->key);
118     }
119 }
120
121 if ($site !== null) {
122     $urlNoSite = buildLink('?q=' . urlencode($cleanQuery), $filters, null, null);
123 } else {
124     $urlNoSite = null;
125 }
126
127 render(
128     'search',
129     array(
130         'queryTime' => round($timeEnd - $timeBegin, 2) . 's',
131         'query' => $query,
132         'cleanQuery' => $cleanQuery,
133         'urlNoSite' => $urlNoSite,
134         'site' => $site,
135         'siteParam' => $siteParam,
136         'hitcount' => $res->hits->total,
137         'hits' => $res->hits->hits,
138         'aggregations' => $res->aggregations,
139         'activeFilters' => $activeFilters,
140         'pager' => $pager
141     )
142 );
143 ?>