php8
[web.mtrack] / MTrackWeb / Search.php
1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
3
4 die("fixme");
5
6 include '../inc/common.php';
7
8 $q = $_GET['q'];
9
10 if (preg_match('/^#([a-zA-Z0-9]+)$/', $q, $M)) {
11   /* ticket */
12   header("Location: {$ABSWEB}ticket.php/$M[1]");
13   exit;
14 }
15 if (preg_match('/^r([a-zA-Z]*\d+)$/', $q, $M)) {
16   /* changeset */
17   $url = mtrack_changeset_url($M[1]);
18   header("Location: $url");
19   exit;
20 }
21 if (preg_match('/^\[([a-zA-Z]*\d+)\]$/', $q, $M)) {
22   /* changeset */
23   $url = mtrack_changeset_url($M[1]);
24   header("Location: $url");
25   exit;
26 }
27 if (preg_match('/^\{(\d+)\}$/', $q, $M)) {
28   /* report */
29   header("Location: {$ABSWEB}report.php/$M[1]");
30   exit;
31 }
32 mtrack_head("Search results for \"$q\"");
33
34 ?>
35 <h1>Search results</h1>
36
37 <form action="<?php echo $ABSWEB; ?>search.php">
38   <input type="text" name="q"
39     size="50"
40     value="<?php echo htmlentities($q, ENT_QUOTES, 'utf-8'); ?>">
41   <button type="submit">Search</button>
42   Read more about <a href="<?php echo $ABSWEB ; ?>help.php/Searching">Searching</a>.
43   <button id='togglesummary' type='button'>Show Fields</button>
44 <script>
45 $(document).ready(function () {
46   $('#togglesummary').click(function () {
47     $('#fieldsummary').toggle();
48   });
49 });
50 </script>
51 <div id='fieldsummary' style='display:none'>
52   <p>The following fields are available for targeted searching:</p>
53   <table>
54     <tr>
55       <th>Item</th>
56       <th>Field</th>
57       <th>Description</th>
58     </tr>
59     <tr>
60       <td>Ticket</td>
61       <td>summary</td>
62       <td>The one-line ticket summary</td>
63     </tr>
64     <tr>
65       <td>Ticket</td>
66       <td>description</td>
67       <td>The ticket description</td>
68     </tr>
69     <tr>
70       <td>Ticket</td>
71       <td>changelog</td>
72       <td>The changelog field</td>
73     </tr>
74     <tr>
75       <td>Ticket</td>
76       <td>keyword</td>
77       <td>The keyword field</td>
78     </tr>
79     <tr>
80       <td>Ticket</td>
81       <td>date</td>
82       <td>The last-changed date</td>
83     </tr>
84     <tr>
85       <td>Ticket</td>
86       <td>who</td>
87       <td>who last changed the ticket</td>
88     </tr>
89     <tr>
90       <td>Ticket</td>
91       <td>creator</td>
92       <td>who opened the ticket</td>
93     </tr>
94     <tr>
95       <td>Ticket</td>
96       <td>created</td>
97       <td>The date that the ticket was created</td>
98     </tr>
99     <tr>
100       <td>Ticket</td>
101       <td>owner</td>
102       <td>who is responsible for the ticket</td>
103     </tr>
104     <tr>
105       <td>Comment</td>
106       <td>description</td>
107       <td>The comment text</td>
108     </tr>
109     <tr>
110       <td>Comment</td>
111       <td>date</td>
112       <td>Date the comment was made</td>
113     </tr>
114     <tr>
115       <td>Comment</td>
116       <td>who</td>
117       <td>who made that comment</td>
118     </tr>
119     <tr>
120       <td>Wiki</td>
121       <td>wiki</td>
122       <td>The content from the wiki page</td>
123     </tr>
124     <tr>
125       <td>Wiki</td>
126       <td>who</td>
127       <td>Who last changed that wiki page</td>
128     </tr>
129     <tr>
130       <td>Wiki</td>
131       <td>date</td>
132       <td>Date the wiki page was last changed</td>
133     </tr>
134 <?php
135 $CF = MTrackTicket_CustomFields::getInstance();
136 foreach ($CF->fields as $f) {
137   echo "<tr><td>Ticket</td><td>$f->name</td><td>",
138     htmlentities($f->label, ENT_QUOTES, 'utf-8'),
139     "</td></tr>\n";
140 }
141 ?>
142   </table>
143
144 </div>
145 </form>
146
147 <?php
148
149 if (strlen($q)) {
150   $start = microtime(true);
151   $hits = MTrackSearchDB::search($q);
152   $end = microtime(true);
153   $elapsed = sprintf("%.2f seconds", $end - $start);
154 } else {
155   $hits = array();
156   $elapsed = '';
157 }
158 ?>
159
160
161 <p>Searching for <i>
162
163 <?php
164 echo htmlentities($q, ENT_QUOTES, 'utf-8'), "</i>:</p><br>\n";
165
166 $hits_by_object = array();
167 $objects = array();
168 /* aggregate results by canonical object; since
169  * we index comments separately from the top level
170  * item, we need to adjust for that here */
171 foreach ($hits as $hit) {
172   /* get canonical object */
173   list($item, $id) = explode(':', $hit->objectid, 3);
174
175   $object = "$item:$id";
176   if (isset($hits_by_object[$object])) {
177     if ($hit->score > $hits_by_object[$object]) {
178       $hits_by_object[$object] = $hit->score;
179       $objects[$object] = $hit;
180     }
181   } else {
182     $hits_by_object[$object] = $hit->score;
183     $objects[$object] = $hit;
184   }
185 }
186 arsort($hits_by_object);
187 ?>
188 <table class='searchresults'>
189 <?php
190
191
192
193 $denied = 0;
194 foreach ($hits_by_object as $object => $score) {
195   list($item, $id) = explode(':', $object, 2);
196   $obj = $objects[$object];
197   $score = (int)($score * 100);
198
199   $html = "<tr><td valign='right'>$score%</td><td>";
200
201   switch ($item) {
202     case 'ticket':
203       $tkt = MTrackIssue::loadByNSIdent($id);
204       if ($tkt === null) {
205         $tkt = MTrackIssue::loadById($id);
206       }
207       $aclid = "ticket:" . $tkt->tid;
208       $html .= mtrack_ticket($tkt);
209       if ($tkt->nsident) {
210         $url = "{$ABSWEB}ticket.php/$tkt->nsident";
211       } else {
212         $url = "{$ABSWEB}ticket.php/$id";
213       }
214       $html .= " <a href='$url'>";
215       $html .= htmlentities($tkt->summary, ENT_QUOTES, 'utf-8');
216       $html .= "</a>";
217       $html .= $obj->getExcerpt($tkt->description);
218
219       break;
220     case 'wiki':
221       $wiki = new MTrack_Wiki_Item($id);
222       $aclid = "wiki:$id";
223       $url = "{$ABSWEB}wiki.php/$id";
224       $html .= "<a href='$url'>".
225         htmlentities($id, ENT_QUOTES, 'utf-8').
226         "</a>";
227       $html .= $obj->getExcerpt($wiki->content);
228       break;
229     default:
230       $aclid = $object;
231       $html .= $object;
232   }
233
234   if (!MTrackACL::hasAnyRights($aclid, 'read')) {
235     $denied++;
236     continue;
237   }
238
239   $html .= "</td></tr>\n";
240   echo $html;
241 }
242 echo "</table>\n";
243
244 if (!count($hits_by_object)) {
245   echo "<em>No matches</em>";
246 } else {
247   echo "<em>" . count($hits_by_object) . " results in $elapsed</em>\n";
248 }
249 if ($denied) {
250   echo "<br>Denied access to $denied items<br>\n";
251 }
252
253 mtrack_foot();