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