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