sortable tables now have options
[plewww.git] / planetlab / common / adminsearch.php
1 <?php
2
3   // $Id$
4
5 // Require login
6 require_once 'plc_login.php';
7
8 // Get session and API handles
9 require_once 'plc_session.php';
10 global $plc, $api;
11
12 // Print header
13 require_once 'plc_drupal.php';
14 // set default 
15 drupal_set_title('DB Search');
16 include 'plc_header.php'; 
17
18 // Common functions
19 require_once 'plc_functions.php';
20 require_once 'plc_objects.php';
21 require_once 'plc_peers.php';
22 require_once 'table.php';
23 require_once 'form.php';
24 require_once 'toggle.php';
25
26 ini_set("memory_limit","256M");
27
28 if ( ! plc_is_admin()) {
29   plc_warning ("DB Search is available to admins only");
30   return;
31  }
32
33 $pattern="";
34 if (isset($_GET['pattern'])) { $pattern=$_GET['pattern']; }
35 if (isset($_POST['pattern'])) { $pattern=$_POST['pattern']; }
36 $tokens=split(" ",$pattern);
37
38 ////////////////////
39 // from a single search form, extract all tokens entered 
40 // and then show all entities that match one of that tokens among
41 // persons - sites - slices - nodes
42 ////////////////////
43 function display_form ($pattern) {
44   if ($pattern) {
45     $title="Searching for $pattern";
46     $visible=false;
47   } else {
48     $title="Search for what";
49     $visible=true;
50   }
51   $toggle=new PlekitToggle("admin-search",$title,array('visible'=>$visible));
52   $toggle->start();
53   print <<< EOF
54 <p id='admin-search-message'>
55 This form searches for <span class="bold">any entry</span> in the database 
56 (among <span class="bold">persons</span>, <span class="bold">slices</span>, 
57 <span class="bold">sites</span> and <span class="bold">nodes</span>) 
58 matching a name fragment, or token. <br/>
59 You can specify a space-separated list of tokens, all entries matching 
60 <span class="bold">any token</span> would then get listed.
61 </p>
62 EOF;
63   print "<div id='admin-search-form'>";
64   $form=new PlekitForm ('/db/common/adminsearch.php',array());
65   $form->start();
66   print $form->label_html('pattern',"Enter space-separated tokens");
67   print $form->text_html('pattern',$pattern);
68   print $form->submit_html('submit','Submit');
69   $form->end();
70   print "</div>\n";
71   $toggle->end();
72 }
73
74 // just look for *token*
75 function token_pattern ($token) {
76   return "*" . $token . "*";
77 }
78
79 // $type is e.g. 'Persons' -- $field is e.g. 'email'
80 function generic_search ($type,$field,$tokens) {
81   global $api;
82   $results=array();
83   $methodname='Get'.$type;
84   if ( ! method_exists($api,$methodname)) {
85     plc_error("generic_search failed with methodname=$methodname");
86     return $results;
87   }
88   foreach ($tokens as $token) {
89     $filter=array($field=>token_pattern($token));
90     $results = 
91       array_merge ($results,$api->$methodname($filter));
92   }
93   return $results;
94 }
95
96 // $objects is e.g. a collection of persons
97 // then, e.g. on slice,  $key='site_id'  & $plural=false
98 // or,   e.g. on person, $key='site_ids'  & $plural=true
99 function generic_gather_related ($objects, $key, $plural) {
100   if ( empty ($objects)) 
101     return array();
102   // else, look for either 'site_id' or 'site_ids' in the first object
103   $sample=$objects[0];
104   if ( array_key_exists($key,$sample)) {
105     $result=array();
106     foreach ($objects as $object) {
107       if ($plural) {
108         $result = array_merge ($result, $object[$key]);
109       } else {
110         $result []= $object[$key];
111       }
112     }
113     return $result;
114   } else {
115     plc_debug("gather_related failed with $key",$sample);
116     return array();
117   }
118 }
119
120 ////////// 
121 // create link from an id, using the various global hashes
122 function plc_person_link ($person_id) {global $persons_hash; return l_person_obj($persons_hash[$person_id]);}
123 function plc_slice_link ($slice_id) {global $slices_hash; return l_slice_obj($slices_hash[$slice_id]);}
124 function plc_site_link ($site_id) {global $sites_hash; return l_site_obj($sites_hash[$site_id]);}
125 function plc_node_link ($node_id) {global $nodes_hash; return l_node_obj($nodes_hash[$node_id]);}
126
127 global $table_options;
128 $table_options = array('notes_area'=>false);
129
130 global $peers;
131 $peers = new Peers ($api);
132
133 function display_persons ($persons,$visible) {
134   if ( ! $persons) return;
135   
136   $toggle=new PlekitToggle('persons-area',"Persons",array('visible'=>$visible));
137   $toggle->start();
138
139   $headers=array('id'=>'int',
140                  'P'=>'string',
141                  'email'=>'string',
142                  'sites'=>'string',
143                  'slices'=>'string',
144                  'roles'=>'string');
145   global $table_options;
146   global $peers;
147   $table=new PlekitTable('persons',$headers,1,$table_options);
148   $table->start();
149   foreach ($persons as $person) {
150     $table->row_start();        
151     $table->cell($person['person_id']);
152     $peers->cell($table,$person['peer_id']);
153     $table->cell(l_person_obj($person));
154     $table->cell(plc_vertical_table(array_map("plc_site_link",$person['site_ids'])));
155     $table->cell(plc_vertical_table(array_map("plc_slice_link",$person['slice_ids'])));
156     $table->cell(plc_vertical_table($person['roles']));
157     $table->row_end();
158   }
159   $table->end();
160   $toggle->end();
161 }
162
163 function display_slices ($slices,$visible) {
164   if ( ! $slices) return;
165   
166   $toggle=new PlekitToggle('slices-area',"Slices",array('visible'=>$visible));
167   $toggle->start();
168
169   $headers=array('id'=>'int',
170                  'P'=>'string',
171                  'name'=>'string',
172                  'site'=>'string',
173                  'persons'=>'string',
174                  'N'=>'string');
175   global $table_options;
176   global $peers;
177   $table=new PlekitTable('slices',$headers,1,$table_options);
178   $table->start();
179   foreach ($slices as $slice) {
180     $table->row_start();        
181     $table->cell($slice['slice_id']);
182     $peers->cell($table,$slice['peer_id']);
183     $table->cell(l_slice_obj($slice));
184     global $sites_hash;
185     $site=$sites_hash[$slice['site_id']];
186     $table->cell(l_site_obj($site));
187     $table->cell(plc_vertical_table(array_map("plc_person_link",$slice['person_ids'])));
188     // this makes really long tables, use the slice link to see details
189     //$table->cell(plc_vertical_table(array_map("plc_node_link",$slice['node_ids'])));
190     $table->cell(count($slice['node_ids']));
191     $table->row_end();
192   }
193   $table->end();
194   $toggle->end();
195 }
196
197 function display_sites ($sites,$visible) {
198   if ( ! $sites) return;
199   
200   $toggle=new PlekitToggle('sites-area',"Sites",array('visible'=>$visible));
201   $toggle->start();
202
203   $headers=array('id'=>'int',
204                  'P'=>'string',
205                  'name'=>'string',
206                  'url'=>'string',
207                  'persons'=>'string',
208                  'slices'=>'string',
209                  'nodes'=>'string');
210   global $table_options;
211   global $peers;
212   $table=new PlekitTable('sites',$headers,1,$table_options);
213   $table->start();
214   foreach ($sites as $site) {
215     $table->row_start();        
216     $table->cell($site['site_id']);
217     $peers->cell($table,$site['peer_id']);
218     $table->cell(l_site_obj($site));
219     $table->cell(href($site['url'],$site['url']));
220     $table->cell(plc_vertical_table(array_map("plc_person_link",$site['person_ids'])));
221     $table->cell(plc_vertical_table(array_map("plc_slice_link",$site['slice_ids'])));
222     $table->cell(plc_vertical_table(array_map("plc_node_link",$site['node_ids'])));
223     $table->row_end();
224   }
225   $table->end();
226   $toggle->end();
227 }
228
229 function display_nodes ($nodes,$visible) {
230   if ( ! $nodes) return;
231   
232   $toggle=new PlekitToggle('nodes-area',"Nodes",array('visible'=>$visible));
233   $toggle->start();
234
235   $headers=array('id'=>'int',
236                  'P'=>'string',
237                  'hostname'=>'string',
238                  'site'=>'string',
239                  'slices'=>'string');
240   global $table_options;
241   global $peers;
242   $table=new PlekitTable('nodes',$headers,1,$table_options);
243   $table->start();
244   foreach ($nodes as $node) {
245     $table->row_start();        
246     $table->cell($node['node_id']);
247     $peers->cell($table,$node['peer_id']);
248     $table->cell(l_node_obj($node));
249     global $sites_hash;
250     $site=$sites_hash[$node['site_id']];
251     $table->cell(l_site_obj($site));
252     // same as above, too many entries, just list how many there are
253     //$table->cell(plc_vertical_table(array_map("plc_slice_link",$node['slice_ids'])));
254     $table->cell(count($node['slice_ids']));
255     $table->row_end();
256   }
257   $table->end();
258   $toggle->end();
259 }
260
261
262 ////////////////////////////////////////////////////////////
263 display_form($pattern);
264
265 if ($pattern) {
266
267   ////////// search database
268   // search persons on email
269   $persons = array();
270   $persons = array_merge ($persons, generic_search ('Persons','email',$tokens));
271
272   // search slices on name
273   $slices=array();
274   $slices = array_merge ($slices, generic_search ('Slices','name',$tokens));
275
276   // search sites on name and login_base
277   $sites=array();
278   $sites = array_merge ($sites, generic_search('Sites','name',$tokens));
279   $sites = array_merge ($sites, generic_search('Sites','login_base',$tokens));
280
281   // nodes on hostname
282   $nodes=array();
283   $nodes = array_merge ($nodes, generic_search('Nodes','hostname',$tokens));
284
285   print "Search results for <span class='tokens'> $pattern </span>\n";
286
287   // what kind of result have we gotten:
288   // if none : display message and exit
289   // if only one kind of objects : start toggle with visible=true
290   // otherwise start all toggles with visible=false
291   $areas=0;
292   if ($persons) $areas += 1;
293   if ($slices) $areas += 1;
294   if ($sites) $areas += 1;
295   if ($nodes) $areas += 1;
296
297   if ( $areas == 0) {
298     plc_warning ("No result found");
299     return;
300   } else if ($areas == 1) {
301     $visible=true;
302   } else {
303     $visible=false;
304   }
305   
306
307   ////////// collect all related objects 
308   $rel_person_ids = array();
309   $rel_person_ids = array_merge($rel_person_ids, generic_gather_related ($sites,'person_ids',true));
310   $rel_person_ids = array_merge($rel_person_ids, generic_gather_related ($slices,'person_ids',true));
311
312   $rel_slice_ids = array();
313   $rel_slice_ids = array_merge($rel_slice_ids, generic_gather_related ($persons,'slice_ids',true));
314   $rel_slice_ids = array_merge($rel_slice_ids, generic_gather_related ($sites,'slice_ids',true));
315   $rel_slice_ids = array_merge($rel_slice_ids, generic_gather_related ($nodes,'slice_ids',true));
316
317   $rel_site_ids = array();
318   $rel_site_ids = array_merge ( $rel_site_ids, generic_gather_related ($persons,'site_ids',true));
319   $rel_site_ids = array_merge ( $rel_site_ids, generic_gather_related ($slices,'site_id',false));
320   $rel_site_ids = array_merge ( $rel_site_ids, generic_gather_related ($nodes,'site_id',false));
321
322   $rel_node_ids = array();
323   $rel_node_ids = array_merge($rel_node_ids, generic_gather_related ($sites,'node_ids',true));
324   $rel_node_ids = array_merge($rel_node_ids, generic_gather_related ($slices,'node_ids',true));
325
326
327   ////////// fetch related and store in a global hash
328   $rel_persons = $api->GetPersons ($rel_person_ids);
329   global $persons_hash; $persons_hash=array();
330   foreach ($rel_persons as $person) $persons_hash[$person['person_id']]=$person;
331
332   $rel_slices = $api->GetSlices ($rel_slice_ids);
333   global $slices_hash; $slices_hash=array();
334   foreach ($rel_slices as $slice) $slices_hash[$slice['slice_id']]=$slice;
335
336   $rel_sites = $api->GetSites ($rel_site_ids);
337   global $sites_hash; $sites_hash=array();
338   foreach ($rel_sites as $site) $sites_hash[$site['site_id']]=$site;
339
340   $rel_nodes = $api->GetNodes ($rel_node_ids);
341   global $nodes_hash; $nodes_hash=array();
342   foreach ($rel_nodes as $node) $nodes_hash[$node['node_id']]=$node;
343
344   ////////// show results
345   display_persons ($persons,$visible);
346   display_slices ($slices,$visible);
347   display_sites($sites,$visible);
348   display_nodes($nodes,$visible);
349
350  }
351
352 // Print footer
353 include 'plc_footer.php';
354
355 ?>