call NotifyPersons() using the admin account instead for the client's acocunt
[plewww.git] / planetlab / sites / join_request.php
1 <?php
2 // $Id$
3 //
4 // page for administration of pending site registration requests
5 //
6
7 // Require login
8 require_once 'plc_login.php';
9
10 // Get session and API handles
11 require_once 'plc_session.php';
12 require_once 'plc_api.php'; 
13 global $plc, $api, $adm;
14
15 // Print header
16 require_once 'plc_drupal.php';
17 include 'plc_header.php';
18
19 // Common functions
20 require_once 'plc_functions.php';
21 require_once 'details.php';
22 require_once 'nifty.php';
23 require_once 'table.php';
24 require_once 'nifty.php';
25
26 include 'site_form.php';
27
28 ////////////////////////////////////////
29 function render_all_join_requests($api) {
30   global $PENDING_CONSORTIUM_ID;
31   $filter = array("peer_id" => NULL, "ext_consortium_id" => $PENDING_CONSORTIUM_ID);
32   $columns=array('site_id','name','enabled','date_created');
33   $sites = $api->GetSites( $filter, $columns);
34   if (empty($sites)) {
35     print("<p> No open join requests </p>");
36     return;
37   }
38   $headers = array();
39   $headers['id']='int';
40   $headers['Site Name']='string';
41   # trying the sortEnglishDateTime stuff - not too lucky so far
42   # http://www.frequency-decoder.com/demo/table-sort-revisited/custom-sort-functions/
43   $headers['submitted']='sortEnglishDateTime';
44   $headers['enabled']='string';
45   
46   $nifty=new PlekitNifty ('pending','sites-pending','medium');
47   $nifty->start();
48   $table=new PlekitTable ('pending',$headers,2,
49                           array('pagesize_area'=>FALSE,'pagesize'=>10000));
50   $table->start();
51   foreach($sites as $site) {
52     $site_id=$site['site_id'];
53     $link = $site['enabled'] ? l_site($site_id) : l_site_review_pending($site_id);
54     $table->row_start();
55     $table->cell(href($link,$site['site_id']));
56     $table->cell(href($link,$site['name']));
57     $table->cell(date("dS F Y",$site['date_created']) . " at " . date("G:i",$site['date_created']));
58     $table->cell( $site['enabled'] ? plc_warning_html('yes') : 'no');
59     $table->row_end();
60   }
61   $table->end();
62   $nifty->end();
63 }
64
65 function render_join_request_review($api, $site_id) {
66   $sites = $api->GetSites( array(intval($site_id)) );
67   if (empty($sites)) {
68       print("<p class='plc-warning'> Invalid request with site_id=$site_id</p> ");
69       return;
70   }
71   $site = $sites[0];
72   if ($site['enabled'] && $site['ext_consortium_id'] === $PENDING_CONSORTIUM_ID) {
73     print("<p class='plc-warning'> This site is already enabled </p>");
74     return;
75   }
76   $addresses = $api->GetAddresses ($site['address_ids']);
77   if (empty ($addresses)) {
78     drupal_set_message("Site $site_id has no address - never mind");
79     $address=array('line1'=>'');
80     $address_id=0;
81   } else {
82     $address = $addresses[0];
83     $address_id=$address['address_id'];
84   }
85 # just in case there is no person attached yet
86   if (empty ($site['person_ids'])) {
87     $persons=array();
88   } else {
89     $person_ids = $site['person_ids'];
90     $persons = $api->GetPersons( $person_ids, array( "person_id", "role_ids", "first_name", "last_name", "title", "email" , "phone") );
91   }
92   $tech = Null;
93   $pi = Null;
94   foreach($persons as $person) {
95     if ( in_array('20',  $person['role_ids']) ) {
96       $pi = $person;
97     }
98     if ( in_array('40',  $person['role_ids']) ) {
99       $tech = $person;
100     }
101   }
102   $pi_id = $pi['person_id'];
103   $tech_id = $tech['person_id'];
104
105   print <<< EOF
106 <p> Please review the join request below.</p>
107     <p> <b> Warning:</b> the PI email address that was provided in this form will <b> not be checked</b> automatically. We expect that as part of the handshake with the site, the support team has had an opportunity to use this address so it can be considered safe. Please check it manually if this is not the case.</p>
108 <form name="join_request" method="post" action="/db/sites/join_request.php">
109 <input type="hidden" name="pi_id" value="$pi_id">
110 <input type="hidden" name="address_id" value="$address_id">
111 <input type="hidden" name="tech_id" value="$tech_id">
112 <input type="hidden" name="site_id" value="$site_id">
113 EOF;
114
115   // don't render the tech part if that was the same as the pi
116   $site_form = build_site_form(FALSE);
117   $input = array ('site' => $site, 'address'=> $address, 'pi' => $pi, 'tech' => $tech);
118   
119   $nifty=new PlekitNifty ('pending','site-pending','medium');
120
121   $nifty->start();
122   $details = new PlekitDetails(TRUE);
123   $details->start();
124
125   // display the buttons 
126   $buttons_row =<<<EOF
127     <table width="100%" border=0 cellspacing="0" cellpadding="5"> <tr> 
128     <td align=center><input type="submit" name="submitted" value="Delete"></td>
129     <td align=center><input type="submit" name="submitted" value="Update"></td>
130     <td align=center><input type="submit" name="submitted" value="Approve"></td>
131     </tr> </table>
132 EOF;
133
134   $details->tr($buttons_row,'center');
135   // render the form - not supposed to be empty
136   form_render_details ($details,$site_form, $input, TRUE);
137
138   // display the buttons again
139   $details->tr($buttons_row,'center');
140
141   $details->end();
142   $nifty->end();
143
144 }
145
146 function notify_enabled_pi ($api, $pi_id, $pi, $site_id, $site) {
147   // notify the PI
148   $template= <<<EOF
149 You have filed a site registration with the %s platform.
150
151 This registration has been approved, and your account was enabled
152 You were granted a PI role, meaning that you will be responsible 
153 for managing personal accounts and slices for your site
154
155 You can now enter the system at
156 https://%s:%d/
157 with %s as a login, 
158 and the password that you provided at registration-time
159
160 You can directly access your site information at
161 https://%s:%d/db/sites/index.php?id=%d
162
163 Please start with adding nodes for this site with
164 https://%s:%d/db/nodes/node_add.php
165
166 Our support team will be glad to answer any question that you might have
167 They are reachable at mailto:%s
168 EOF;
169  
170  $body=sprintf($template,
171                PLC_NAME,
172                PLC_WWW_HOST,PLC_WWW_SSL_PORT,
173                $pi['email'],
174                PLC_WWW_HOST,PLC_WWW_SSL_PORT,$site_id,
175                PLC_WWW_HOST,PLC_WWW_SSL_PORT,
176                PLC_MAIL_SUPPORT_ADDRESS);
177    
178  $subject="Site registration for " . $site['name'] . " has been approved by " . PLC_NAME;
179  $adm->NotifyPersons(array($pi_id),$subject,$body);
180 }
181
182
183 // find person roles
184 $_person= $plc->person;
185 $_roles= $_person['role_ids'];
186
187 // only admins are allowed to view this page
188 if( !in_array( '10', $_roles ) ) {
189
190     print("<p> not allowed to view this page </p>");
191 }
192 else if ($_GET['review'])
193 {
194
195     //print review page
196     drupal_set_title('Join Request - Review');
197     render_join_request_review($api, $_GET['site_id']);
198         
199 }
200 else if ($_POST['submitted'] )
201 {
202
203   // parse the form
204   $site_form = build_site_form(FALSE);
205   $input = parse_form ($site_form, $_REQUEST, $input);
206   // xxx should not happen ?
207   $empty_form = $input['is_empty'];
208   $error = "";
209   $messages= array();
210   if ( $empty_form ) {
211     $error .= '<div class-"plc-warning">Internal error - empty form !?!</div>';
212   }
213   if (empty ($error)) {
214     $site=$input['site'];
215     $address=$input['address'];
216     $pi=$input['pi'];
217     $tech=$input['tech'];
218
219     // Look for missing/blank entries
220     $error .= form_check_required ($site_form, $input);
221   }
222
223   if (empty($error)) {
224     // get objects id from the request
225     $site_id = intval(trim($_POST['site_id']));
226     $address_id = intval(trim($_POST['address_id']));
227     $pi_id = intval(trim($_POST['pi_id']));
228     $tech_id = intval(trim($_POST['tech_id']));
229
230     switch ($_POST['submitted']) {
231     case 'Delete': {
232       $api->DeleteSite ($site_id);
233       $api_error=$api->error();
234       if (!empty($api_error)) {
235         $error .= $api->error();
236       } else {
237         $messages [] = "Site " . $site['name'] . " deleted";
238       }
239       break;
240     }
241     case 'Update': {
242       $api->begin();
243       $api->UpdateSite($site_id,$site);
244       if ($address_id) $api->UpdateAddress($address_id,$address);
245       else if(!empty($address)) $api->AddSiteAddress($site_id,$address);
246       $api->UpdatePerson($pi_id,$pi);
247       if ($tech_id != $pi_id) $api->UpdatePerson($tech_id,$tech);
248       $api->commit();
249       $api_error=$api->error();
250       if (!empty($api_error)) {
251         $error .= $api->error();
252       } else {
253         $messages [] = "Join request updated for site " . $site['name'] ;
254       }
255       
256       break;
257     }
258     case 'Approve': {
259       // Thierry - august 22 2007
260       // keep it simple - the admin who approves is now supposed to check 
261       // the PI's email address, which makes the whole thing *a lot* simpler
262       // enable the site, enable the PI, and VerifyPerson the thec if different from the PI
263       $site['enabled'] = True;
264       global $APPROVED_CONSORTIUM_ID;
265       $site['ext_consortium_id'] = $APPROVED_CONSORTIUM_ID;
266       $api->UpdateSite ($site_id,$site);
267       $api_error=$api->error();
268       if (!empty($api_error)) {
269         $error .= $api->error();
270         $messages [] = "Could not enable site";
271       } else {
272         $messages[] = l_site_t ($site_id,"Site '" . $site['name'] . "' enabled");
273       }
274       
275       if (empty ($error) && $address_id) {
276         // Update Address
277         $api->UpdateAddress($address_id,$address);
278         $api_error=$api->error();
279         if ( ! empty($api_error)) {
280           $error .= $api->error();
281           $messages [] = "Could not update address";
282         }
283         
284         foreach ( array("Billing","Shipping") as $address_type) {
285           $api->AddAddressTypeToAddress($address_type,$address_id);
286           $api_error=$api->error();
287           if ( ! empty($api_error)) {
288             $error .= $api->error();
289             $messages [] = "Could not add address type " . $address_type;
290           }
291         }
292           
293         // Update pi, and enable him
294         $api->UpdatePerson ($pi_id,$pi);
295         if ( $pi ['enabled' ] ) {
296           $messages [] = "PI already enabled";
297         } else {
298           $api->UpdatePerson ($pi_id,array("enabled"=>True));
299           $api_error=$api->error();
300           if (empty($api_error)) {
301             $messages[] = "Enabled PI as " . $pi['email'] ;
302             notify_enabled_pi ($api, $pi_id,$pi,$site_id, $site);
303             $messages[] = "Notified PI by email";
304           } else {
305             $error .= $api->error();
306             $messages [] = "Could not update PI";
307           }
308         }
309
310         if ($pi_id != $tech_id) {
311           // Update tech, and VerifyPerson him if needed
312           $api->UpdatePerson ($tech_id,$tech);
313           if ( $tech [ 'enabled' ] ) {
314             $messages [] = "Tech already enabled";
315           } else {
316             $api->VerifyPerson($tech_id);
317             $api_error=$api->error();
318             if (empty($api_error)) {
319               $messages[] = "Created account registration for Tech as " . $tech['email'];
320             } else {
321               $error .= $api->error();
322               $messages [] = "Could not verify Tech";
323             }
324           }
325         }
326       }
327
328       break;
329     }
330     default: {
331       $error .= '<div class-"plc-warning">Internal error - unexpected request</div>';
332       break;
333     }
334
335     } // end switch
336   }
337
338   // Show messages
339   if (!empty($messages)) {
340     print '<div class="messages status"><ul>';
341     foreach ($messages as $line) {
342       print "<li> $line";
343     }
344     print "</ul></div>";
345   }
346         
347   // Show errors if any
348   if (!empty($error)) {
349     print '<div class="messages error">' . $error . '</div>';
350     drupal_set_title('Join Request - Review');
351     render_join_request_review($api, $_POST['site_id']);    
352   } else {
353     drupal_set_title('All currently pending join requests');
354     render_all_join_requests($api);
355   }
356
357  }
358  else // list all pending requests
359 {
360
361     drupal_set_title('All currently pending join requests');
362     render_all_join_requests($api);
363 }
364
365 // Print footer
366 include 'plc_footer.php';
367
368 ?>