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