php8
[web.mtrack] / MTrackWeb / Query.php
1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
3
4
5 die("custom query... todo...");
6
7 mtrack_head("Custom Query");
8
9 echo "<h1>Custom Query</h1>\n";
10
11 /* This logic matches up to equivalent logic in the macro_RunReport
12  * function in inc/report */
13
14 $params = array();
15
16 if (strlen($_SERVER['QUERY_STRING'])) {
17   $qs = $_SERVER['QUERY_STRING'];
18 } else {
19   $qs = mtrack_get_pathinfo();
20 }
21
22 list ($params, $mparams) = MTrack_Report::parseQuery($qs);
23
24 echo "<form action='{$ABSWEB}query.php' method='get' id='qform' onsubmit='return false;'>";
25 echo "<table id='qtable'></table></form>";
26
27 $params = json_encode($params);
28
29 $milestones = json_encode(array_values(MTrack_Milestone::enumMilestones(true)));
30 echo <<<HTML
31 <form id='customqryaddfilter'>
32 Add Filter: <select id='addfilt'>
33 <option value="">- Select to add a filter</option>
34 HTML;
35
36 $fields = array('cc', 'component', 'milestone', 'status', 'owner',
37   'type', 'summary', 'ticket', 'priority', 'keyword');
38
39 asort($fields);
40 $labels = array();
41
42 foreach ($fields as $field) {
43   echo "<option value='$field'>" . ucfirst($field) . "</option>\n";
44   $labels[$field] = ucfirst($field);
45 }
46 $C = MTrackTicket_CustomFields::getInstance();
47 $custom_fields = new stdclass;
48 foreach ($C->fields as $f) {
49   echo "<option value='$f->name'>" .
50     htmlentities($f->label, ENT_QUOTES, 'utf-8') . "</option>\n";
51   $labels[$f->name] = $f->label;
52   if ($f->type == 'select' || $f->type == 'multiselect') {
53     $d = $f->ticketData();
54     $custom_fields->{$f->name} = array_values($d['options']);
55   }
56 }
57 echo <<<HTML
58 </select>
59 <br>
60 <div id='colselector'>
61 <h3><a href='#'>Choose Columns (drag to re-order)</a></h3>
62 <div style="display:none">
63 <ul id='columns'>
64 HTML;
65
66 $labels = json_encode($labels);
67 $custom_fields = json_encode($custom_fields);
68 $c = new MTrackClassification;
69 $classifications = json_encode(array_values($c->enumerate()));
70 $c = new MTrackPriority;
71 $priorities = json_encode(array_values($c->enumerate()));
72 /* Allow selection of columns */
73 function add_col($name, $label) {
74   global $mparams;
75   $checked = in_array($name, $mparams['col']) ? ' checked="yes" ' : '';
76   $label = htmlentities($label, ENT_QUOTES, 'utf-8');
77   echo "<li class='ui-state-default'><input type='checkbox' name='col_$name' mtrackcol='$name' class='qrycol' $checked> ";
78   echo "<label for='col_$name'>$label</label></li> ";
79 }
80 $all_cols = array();
81
82 // Add in the selected columns in order first
83 foreach ($mparams['col'] as $col) {
84   $field = $C->fieldByName($col);
85   if ($field) {
86     $all_cols[$field->name] = $field->label;
87   } else {
88     $all_cols[$col] = ucfirst($col);
89   }
90 }
91 // Add in other possible fields
92 foreach ($fields as $field) {
93   $all_cols[$field] = ucfirst($field);
94 }
95 $possible_fields = array(
96   'severity', 'remaining'
97 );
98 foreach ($possible_fields as $name) {
99   $all_cols[$name] = ucfirst($name);
100 }
101 foreach ($C->fields as $f) {
102   $all_cols[$f->name] = $f->label;
103 }
104
105 foreach ($all_cols as $name => $label) {
106   add_col($name, $label);
107 }
108
109 echo <<<HTML
110 </ul>
111 </div>
112 </div>
113 </form>
114 <button id='updfilt'>Update</button><br>
115 <script language='javascript' type='text/javascript'>
116 var initq = $params;
117 var milestones = $milestones;
118 var classifications = $classifications;
119 var priorities = $priorities;
120 var next_field_id = 1;
121 var adding_field = false;
122 var custom_fields = $custom_fields;
123 var field_labels = $labels;
124
125 function mtrack_add_sel(sel, a, b)
126 {
127   sel.options[sel.options.length] = new Option(a, b);
128 }
129
130 // given a field name, operator and value, create a new entry in the form
131 function mtrack_add_field(name, op, value)
132 {
133   var qtable = document.getElementById('qtable');
134
135   // <tr><td>X</td><td>name</td><td>op select</td><td>value</td></tr>
136   var tr = document.createElement('tr');
137   var xcell = document.createElement('td');
138   var but = document.createElement('button');
139   but.innerHTML = "X";
140   xcell.appendChild(but);
141   xcell.onclick = function() {
142     qtable.removeChild(tr);
143     return false;
144   };
145   tr.appendChild(xcell);
146
147   var ncell = document.createElement('td');
148   ncell.innerHTML = field_labels[name];
149   ncell.align = "right";
150   var ntype = document.createElement('input');
151   ntype.type = 'hidden';
152   ntype.id = "optyp_" + next_field_id;
153   ntype.name = ntype.id;
154   ntype.value = name;
155   ncell.appendChild(ntype);
156   tr.appendChild(ncell);
157
158   var opcell = document.createElement('td');
159   // create the operator map
160   var sel = document.createElement('select');
161   sel.id = "opsel_" + next_field_id;
162   sel.name = sel.id;
163   mtrack_add_sel(sel, "is", "=");
164   mtrack_add_sel(sel, "is not", "!=");
165
166   if (name != 'milestone' && name != 'status' && name != 'type') {
167     mtrack_add_sel(sel, "contains", "~=");
168     mtrack_add_sel(sel, "does not contain", "!~=");
169     mtrack_add_sel(sel, "starts with", "^=");
170     mtrack_add_sel(sel, "does not start with", "!^=");
171     mtrack_add_sel(sel, "ends with", "\$=");
172     mtrack_add_sel(sel, "does not end with", "!\$=");
173   }
174   var i;
175   for (i = 0; i < sel.length; i++) {
176     if (sel.options[i].value == op) {
177       sel.selectedIndex = i;
178       break;
179     }
180   }
181
182   opcell.appendChild(sel);
183   tr.appendChild(opcell);
184
185   var vid = "opval_" + next_field_id;
186
187   var vcell = document.createElement('td');
188   var vele = null;
189
190   if (name == 'milestone') {
191     vele = document.createElement('select');
192     for (i in milestones) {
193       mtrack_add_sel(vele, milestones[i], milestones[i]);
194       if (milestones[i] == value) {
195         vele.selectedIndex = vele.length - 1;
196       }
197     }
198   } else if (name == 'status') {
199     vele = document.createElement('select');
200     mtrack_add_sel(vele, 'new', 'new');
201     mtrack_add_sel(vele, 'open', 'open');
202     mtrack_add_sel(vele, 'closed', 'closed');
203     mtrack_add_sel(vele, 'assigned', 'assigned');
204     switch (value) {
205       case 'new': vele.selectedIndex = 0; break;
206       case 'open': vele.selectedIndex = 1; break;
207       case 'closed': vele.selectedIndex = 2; break;
208       case 'assigned': vele.selectedIndex = 3; break;
209     }
210   } else if (name == 'type') {
211     vele = document.createElement('select');
212     for (i in classifications) {
213       mtrack_add_sel(vele, classifications[i], classifications[i]);
214       if (classifications[i] == value) {
215         vele.selectedIndex = vele.length - 1;
216       }
217     }
218   } else if (name == 'priority') {
219     vele = document.createElement('select');
220     for (i in priorities) {
221       mtrack_add_sel(vele, priorities[i], priorities[i]);
222       if (priorities[i] == value) {
223         vele.selectedIndex = vele.length - 1;
224       }
225     }
226   } else if (custom_fields[name]) {
227     vele = document.createElement('select');
228     var opts = custom_fields[name];
229     for (i in opts) {
230       mtrack_add_sel(vele, opts[i], opts[i]);
231       if (opts[i] == value) {
232         vele.selectedIndex = vele.length - 1;
233       }
234     }
235   }
236
237   if (vele == null) {
238     // default to a text entry field
239     vele = document.createElement('input');
240     vele.type = 'text';
241     vele.value = value;
242   }
243   vele.name = vid;
244   vele.id = vid;
245   vcell.appendChild(vele);
246   tr.appendChild(vcell);
247
248   qtable.appendChild(tr);
249   \$(vele).bind('keypress', function (e) {
250     switch (e.keyCode) {
251       case $.ui.keyCode.ENTER:
252       case $.ui.keyCode.BACKSPACE:
253         return false;
254     }
255   });
256
257   next_field_id++;
258 }
259
260 $(document).ready(function (){
261   $('#colselector').accordion({
262     collapsible: true,
263     active: false
264   });
265   $('#columns').sortable();
266
267   // decode the parameters and build out the form
268   var prop;
269   for (prop in initq) {
270     var d = initq[prop];
271     var op = d[0];
272     var values = d[1];
273     var val;
274     for (val in values) {
275       mtrack_add_field(prop, op, values[val]);
276     }
277   }
278
279   $('#addfilt').change(function () {
280     if (!adding_field) {
281       adding_field = true;
282       mtrack_add_field(this.options[this.selectedIndex].value, null, null);
283       this.selectedIndex = 0;
284       adding_field = false;
285     }
286   });
287
288   $('#updfilt').click(function (){
289     var filt = [];
290     // Iterate the form elements and build up the query string
291     var i;
292     var f = document.getElementById('qform');
293     for (i = 0; i < f.length; i++) {
294       var ele = f.elements[i];
295       if (ele.name.match(/^op(sel|val|typ)_/)) {
296         var fid = ele.name.substr(6);
297         var oper = document.getElementById('opsel_' + fid);
298         var val = document.getElementById('opval_' + fid);
299         var type = document.getElementById('optyp_' + fid);
300         filt[fid] = [type.value, oper.value, val.value];
301       }
302     }
303     var qs = "";
304     for (i in filt) {
305       f = filt[i];
306       if (qs.length) {
307         qs += "&";
308       }
309       qs += f[0] + f[1] + f[2];
310     }
311     // And the columns
312     var col = [];
313     $('input.qrycol:checked').each(function () {
314       col[col.length] = $(this).attr('mtrackcol');
315     });
316     qs = qs + "&col=" + col.join('|');
317     document.location.href = "{$ABSWEB}query.php?" + qs;
318     return false;
319   });
320 });
321 </script>
322 HTML;
323
324 if (strlen(trim($qs))) {
325   echo MTrack_Report::macro_TicketQuery($qs);
326 }
327
328 mtrack_foot();
329