r1131 + welcome the first revision of main help page
[racktables] / inc / interface.php
1 <?
2 /*
3 *
4 * This file contains frontend functions for RackTables.
5 *
6 */
7
8 // Main menu.
9 function renderIndex ()
10 {
11 global $root;
12 ?>
13 <table border=0 cellpadding=0 cellspacing=0 width='100%'>
14 <tr>
15 <td>
16 <div style='text-align: center; margin: 10px; '>
17 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
18 <tr>
19 <td>
20 <h1><a href='<? echo $root; ?>?page=rackspace'>Rackspace<br>
21 <? printImageHREF ('rackspace'); ?></a></h1>
22 </td>
23 <td>
24 <h1><a href='<? echo $root; ?>?page=objects'>Objects<br>
25 <? printImageHREF ('objects'); ?></a></h1>
26 </td>
27 <td>
28 <h1><a href='<? echo $root; ?>?page=ipv4space'>IPv4 space<br>
29 <? printImageHREF ('ipv4space'); ?></a></h1>
30 </td>
31 </tr>
32 </table>
33 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
34 <tr>
35 <td>
36 <h1><a href='<? echo $root; ?>?page=config'>Configuration<br>
37 <? printImageHREF ('config'); ?></a></h1>
38 </td>
39 <td>
40 <h1><a href='<? echo $root; ?>?page=reports'>Reports<br>
41 <? printImageHREF ('reports'); ?></a></h1>
42 </td>
43 <td>
44 <h1><a href='<? echo $root; ?>?page=help'>Help<br>
45 <? printImageHREF ('help'); ?></a></h1>
46 </td>
47 </tr>
48 </table>
49 </div>
50 </td>
51 </tr>
52 </table>
53 <?
54 }
55
56 function renderRackspace ()
57 {
58 ?>
59 <table border=0 cellpadding=10 cellpadding=1>
60 <?
61 // generate thumb gallery
62 $rackrowList = getRackRowInfo();
63 global $rtwidth, $root, $nextorder;
64 $rackwidth = $rtwidth[0] + $rtwidth[1] + $rtwidth[2];
65 $order = 'odd';
66 foreach ($rackrowList as $rackrow)
67 {
68 echo "<tr class=row_${order}><th><a href='${root}?page=row&row_id=${rackrow['dict_key']}'>${rackrow['dict_value']}</a></th>";
69 $rackList = getRacksForRow ($rackrow['dict_key']);
70 echo "<td><table border=0 cellspacing=5><tr>";
71 foreach ($rackList as $dummy => $rack)
72 {
73 echo "<td align=center><a href='${root}?page=rack&rack_id=${rack['id']}'>";
74 echo "<img border=0 width=${rackwidth} height=";
75 echo 3 + 3 + $rack['height'] * 2;
76 echo " title='${rack['height']} units'";
77 echo "src='render_rack_thumb.php?rack_id=${rack['id']}'>";
78 echo "<br>${rack['name']}</a></td>";
79 }
80 echo "</tr></table></tr>\n";
81 $order = $nextorder[$order];
82 }
83 echo "</table>\n";
84 }
85
86 function renderRow ($row_id)
87 {
88 if ($row_id == 0)
89 {
90 showError ('Invalid row_id in renderRow()');
91 return;
92 }
93 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
94 {
95 showError ('getRackRowInfo() failed in renderRow()');
96 return;
97 }
98 // Main layout starts.
99 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
100
101 // Left portlet with row information.
102 echo "<tr><td class=pcleft>";
103 startPortlet ('Row information');
104 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
105 echo "<tr><th width='50%' class=tdright>Row name:</th><td class=tdleft>${rowInfo['dict_value']}</td></tr>\n";
106 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
107 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
108 echo "</table><br>\n";
109 finishPortlet();
110
111 echo "</td><td class=pcright>";
112
113 global $rtwidth, $root, $nextorder;
114 $rackwidth = $rtwidth[0] + $rtwidth[1] + $rtwidth[2];
115 $rackList = getRacksForRow ($row_id);
116 $order = 'odd';
117 startPortlet ('Racks');
118 echo "<table border=0 cellspacing=5 align='center'><tr>";
119 foreach ($rackList as $dummy => $rack)
120 {
121 echo "<td align=center class=row_${order}><a href='${root}?page=rack&rack_id=${rack['id']}'>";
122 echo "<img border=0 width=" . $rackwidth * ROW_SCALE . " height=";
123 echo (3 + 3 + $rack['height'] * 2) * ROW_SCALE;
124 echo " title='${rack['height']} units'";
125 echo "src='render_rack_thumb.php?rack_id=${rack['id']}'>";
126 echo "<br>${rack['name']}</a></td>";
127 $order = $nextorder[$order];
128 }
129 echo "</tr></table>\n";
130 finishPortlet();
131
132 echo "</td></tr></table>";
133 }
134
135 function showError ($info = '')
136 {
137 global $root;
138 echo '<div class=msg_error>An error has occured. ';
139 if (empty ($info))
140 echo 'No additional information is available.';
141 else
142 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
143 echo "Go back or try starting from <a href='${root}'>index page</a>.<br></div>\n";
144 }
145
146 // This function renders rack as HTML table.
147 function renderRack ($rack_id = 0, $hl_obj_id = 0)
148 {
149 if ($rack_id == 0)
150 {
151 showError ('Invalid rack_id in renderRack()');
152 return;
153 }
154 if (($rackData = getRackData ($rack_id)) == NULL)
155 {
156 showError ('getRackData() failed in renderRack()');
157 return;
158 }
159 global $root, $pageno, $tabno;
160 markAllSpans ($rackData);
161 if ($hl_obj_id > 0)
162 highlightObject ($rackData, $hl_obj_id);
163 markupObjectProblems ($rackData);
164 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
165 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
166 echo "<center>\n<h2><a href='${root}?page=row&row_id=${rackData['row_id']}'>${rackData['row_name']}</a> :";
167 // FIXME: use 'bypass'?
168 if ($prev_id != NULL)
169 echo " <a href='${root}?page=rack&rack_id=${prev_id}'>&lt; &lt; &lt;</a>";
170 echo " <a href='${root}?page=rack&rack_id=${rackData['id']}'>${rackData['name']}</a>";
171 if ($next_id != NULL)
172 echo " <a href='${root}?page=rack&rack_id=${next_id}'>&gt; &gt; &gt;</a>";
173 echo "</h2>\n";
174 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
175 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
176 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
177 for ($i = $rackData['height']; $i > 0; $i--)
178 {
179 echo "<tr><th>$i</th>";
180 for ($locidx = 0; $locidx < 3; $locidx++)
181 {
182 if (isset ($rackData[$i][$locidx]['skipped']))
183 continue;
184 $state = $rackData[$i][$locidx]['state'];
185 echo "<td class=state_${state}";
186 if (isset ($rackData[$i][$locidx]['hl']))
187 echo $rackData[$i][$locidx]['hl'];
188 if (isset ($rackData[$i][$locidx]['colspan']))
189 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
190 if (isset ($rackData[$i][$locidx]['rowspan']))
191 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
192 echo ">";
193 switch ($state)
194 {
195 case 'T':
196 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
197 if (!empty ($objectData['asset_no']))
198 $prefix = "<div title='${objectData['asset_no']}";
199 else
200 $prefix = "<div title='no asset tag";
201 // Don't tell about label, if it matches common name.
202 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
203 $suffix = ", visible label is \"${objectData['label']}\"'>";
204 else
205 $suffix = "'>";
206 echo $prefix . $suffix;
207 echo "<a href='${root}?page=object&object_id=${objectData['id']}'>${objectData['dname']}</a></div>";
208 break;
209 case 'A':
210 echo '<div title="This rackspace does not exist">&nbsp;</div>';
211 break;
212 case 'F':
213 echo '<div title="Free rackspace">&nbsp;</div>';
214 break;
215 case 'U':
216 echo '<div title="Problematic rackspace, you CAN\'T mount here">&nbsp;</div>';
217 break;
218 default:
219 echo '<div title="No data">&nbsp;</div>';
220 break;
221 }
222 echo '</td>';
223 }
224 echo "</tr>\n";
225 }
226 echo "</table></center>\n";
227 }
228
229 function renderNewObjectForm ()
230 {
231 global $pageno, $tabno;
232
233 // Look for current submit.
234 if (isset ($_REQUEST['got_data']))
235 {
236 $log = array();
237 assertUIntArg ('object_type_id');
238 assertStringArg ('object_name', TRUE);
239 assertStringArg ('object_label', TRUE);
240 assertStringArg ('object_barcode', TRUE);
241 assertStringArg ('object_asset_no', TRUE);
242 $type_id = $_REQUEST['object_type_id'];
243 $name = $_REQUEST['object_name'];
244 $label = $_REQUEST['object_label'];
245 $asset_no = $_REQUEST['object_asset_no'];
246 $barcode = $_REQUEST['object_barcode'];
247
248 if (commitAddObject ($name, $label, $barcode, $type_id, $asset_no) === TRUE)
249 $log[] = array ('code' => 'success', 'message' => "Added new object '${name}'");
250 else
251 $log[] = array ('code' => 'error', 'message' => 'commitAddObject() failed in renderNewObjectForm()');
252 printLog ($log);
253 }
254
255 // Render a form for the next.
256 startPortlet ('Object attributes');
257 echo '<form>';
258 echo "<input type=hidden name=page value=${pageno}>";
259 echo "<input type=hidden name=tab value=${tabno}>";
260 echo '<table border=0 align=center>';
261 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
262 printSelect (getObjectTypeList(), 'object_type_id');
263 echo "</td></tr>\n";
264 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name></td></tr>\n";
265 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label></td></tr>\n";
266 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no></td></tr>\n";
267 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode></td></tr>\n";
268 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
269 echo '</form></table>';
270 finishPortlet();
271 }
272
273 function renderNewRackForm ($row_id)
274 {
275 global $pageno, $tabno;
276
277 // Look for current submit.
278 if (isset ($_REQUEST['got_data']))
279 {
280 $log = array();
281 assertStringArg ('rack_name');
282 assertUIntArg ('rack_height');
283 assertStringArg ('rack_comment', TRUE);
284 $name = $_REQUEST['rack_name'];
285 $height = $_REQUEST['rack_height'];
286 $comment = $_REQUEST['rack_comment'];
287
288 if (commitAddRack ($name, $height, $row_id, $comment) === TRUE)
289 $log[] = array ('code' => 'success', 'message' => "Added new rack '${name}'");
290 else
291 $log[] = array ('code' => 'error', 'message' => 'commitAddRack() failed in renderNewRackForm()');
292 printLog ($log);
293 }
294
295 // Render a form for the next.
296 startPortlet ('Rack attributes');
297 echo '<form>';
298 echo "<input type=hidden name=page value=${pageno}>";
299 echo "<input type=hidden name=tab value=${tabno}>";
300 echo "<input type=hidden name=row_id value=${row_id}>";
301 echo '<table border=0 align=center>';
302 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name></td></tr>\n";
303 echo "<tr><th class=tdright>Height in units (required):</th><td class=tdleft><input type=text name=rack_height></td></tr>\n";
304 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment></td></tr>\n";
305 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
306 echo '</form></table>';
307 finishPortlet();
308 }
309
310 function renderEditObjectForm ($object_id)
311 {
312 showMessageOrError();
313 // Handle submit.
314 if (isset ($_REQUEST['got_data']))
315 {
316 $log = array();
317 // object_id is already verified by page handler
318 assertUIntArg ('object_type_id');
319 assertStringArg ('object_name', TRUE);
320 assertStringArg ('object_label', TRUE);
321 assertStringArg ('object_barcode', TRUE);
322 assertStringArg ('object_asset_no', TRUE);
323 $type_id = $_REQUEST['object_type_id'];
324 if (isset ($_REQUEST['object_has_problems']) and $_REQUEST['object_has_problems'] == 'on')
325 $has_problems = 'yes';
326 else
327 $has_problems = 'no';
328 $name = $_REQUEST['object_name'];
329 $label = $_REQUEST['object_label'];
330 $barcode = $_REQUEST['object_barcode'];
331 $asset_no = $_REQUEST['object_asset_no'];
332 $comment = $_REQUEST['object_comment'];
333
334 if (commitUpdateObject ($object_id, $name, $label, $barcode, $type_id, $has_problems, $asset_no, $comment) === TRUE)
335 $log[] = array ('code' => 'success', 'message' => "Updated object '${name}'");
336 else
337 $log[] = array ('code' => 'error', 'message' => 'commitUpdateObject() failed in renderEditObjectForm()');
338 printLog ($log);
339 }
340
341 global $pageno, $tabno;
342 $object = getObjectInfo ($object_id);
343 if ($object == NULL)
344 {
345 showError ('getObjectInfo() failed in renderEditObjectForm()');
346 return;
347 }
348
349 // Render a form for the next submit;
350 echo '<table border=0 width=100%><tr>';
351
352 echo '<td class=pcleft>';
353 startPortlet ('Static attributes');
354 echo '<form>';
355 echo "<input type=hidden name=page value=${pageno}>";
356 echo "<input type=hidden name=tab value=${tabno}>";
357 echo "<input type=hidden name=object_id value=${object_id}>";
358 echo '<table border=0 align=center>';
359 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
360 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
361 echo "</td></tr>\n";
362 // Common attributes.
363 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
364 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
365 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no value='${object['asset_no']}'></td></tr>\n";
366 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
367 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
368 if ($object['has_problems'] == 'yes')
369 echo ' checked';
370 echo "></td></tr>\n";
371 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
372 echo "<tr><th class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
373 echo '</form></table><br>';
374 finishPortlet();
375 echo '</td>';
376
377 // Optional attributes.
378 echo '<td class=pcright>';
379 startPortlet ('Optional attributes');
380 $values = getAttrValues ($object_id);
381 global $root;
382 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
383 echo "<tr><th>&nbsp;</th><th>Attribute</th><th>Value</th><th>&nbsp;</th></tr>\n";
384 foreach ($values as $record)
385 {
386 echo "<form method=post action='${root}process.php'>";
387 echo "<input type=hidden name=page value=${pageno}>";
388 echo "<input type=hidden name=tab value=${tabno}>";
389 echo "<input type=hidden name=op value=upd>";
390 echo "<input type=hidden name=object_id value=${object_id}>";
391 echo "<input type=hidden name=attr_id value=${record['id']}>";
392 echo "<tr><td><a href=${root}process.php?page=${pageno}&tab=${tabno}&op=del&object_id=${object_id}&attr_id=${record['id']}>";
393 printImageHREF ('delete', 'Delete value');
394 echo "</a></td>";
395 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
396 switch ($record['type'])
397 {
398 case 'uint':
399 case 'float':
400 case 'string':
401 echo "<input type=text name=value value='${record['value']}'>";
402 break;
403 case 'dict':
404 $chapter = readChapter ($record['chapter_name']);
405 $chapter[] = array ('dict_key' => 0, 'dict_value' => '-- NOT SET --');
406 printSelect ($chapter, 'value', $record['key']);
407 break;
408 }
409 echo "</td>";
410 echo "<td><input type=submit value='OK'></td></tr>\n";
411 echo "</form>";
412 }
413 echo "</table>\n";
414 finishPortlet();
415 echo '</td>';
416
417 echo '</tr><tr>';
418
419 echo '<td colspan=2>';
420 startPortlet ('history');
421 renderHistory ($pageno, $object_id);
422 finishPortlet();
423 echo '</td>';
424
425 echo '</tr></table>';
426 }
427
428 // This is a clone of renderEditObjectForm().
429 function renderEditRackForm ($rack_id)
430 {
431 // Handle submit.
432 if (isset ($_REQUEST['got_data']))
433 {
434 $log = array();
435 assertUIntArg ('rack_row_id');
436 assertUIntArg ('rack_height');
437 assertStringArg ('rack_name');
438 assertStringArg ('rack_comment', TRUE);
439 $row_id = $_REQUEST['rack_row_id'];
440 $height = $_REQUEST['rack_height'];
441 $name = $_REQUEST['rack_name'];
442 $comment = $_REQUEST['rack_comment'];
443
444 if (commitUpdateRack ($rack_id, $name, $height, $row_id, $comment) === TRUE)
445 $log[] = array ('code' => 'success', 'message' => "Updated rack '${name}'");
446 else
447 $log[] = array ('code' => 'error', 'message' => 'commitUpdateRack() failed in renderEditRackForm()');
448 printLog ($log);
449 }
450
451 global $pageno, $tabno;
452 $rack = getRackData ($rack_id);
453 if ($rack == NULL)
454 {
455 showError ('getRackData() failed in renderEditRackForm()');
456 return;
457 }
458
459 // Render a form for the next.
460 startPortlet ('Rack attributes');
461 echo '<form>';
462 echo "<input type=hidden name=page value=${pageno}>";
463 echo "<input type=hidden name=tab value=${tabno}>";
464 echo "<input type=hidden name=rack_id value=${rack_id}>";
465 echo '<table border=0 align=center>';
466 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
467 printSelect (getRackRowInfo(), 'rack_row_id', $rack['row_id']);
468 echo "</td></tr>\n";
469 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
470 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
471 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
472 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
473 echo '</form></table><br>';
474 finishPortlet();
475
476 startPortlet ('History');
477 renderHistory ($pageno, $rack_id);
478 finishPortlet();
479 }
480
481 // This is a helper for creators and editors.
482 function printSelect ($rowList, $select_name, $selected_id = 1)
483 {
484 echo "<select name=${select_name}>";
485 foreach ($rowList as $dummy => $data)
486 {
487 echo "<option value=${data['dict_key']}";
488 if ($data['dict_key'] == $selected_id)
489 echo ' selected';
490 echo ">${data['dict_value']}</option>";
491 }
492 echo "</select>";
493 }
494
495 // This is a universal editor of rack design/waste.
496 function renderGridForm ($rack_id = 0, $filter, $header, $submit, $help, $state1, $state2)
497 {
498 if ($rack_id == 0)
499 {
500 showError ('Invalid rack_id in renderGridFrom()');
501 return;
502 }
503 if (($rackData = getRackData ($rack_id)) == NULL)
504 {
505 showError ('getRackData() failed in renderGridFrom()');
506 return;
507 }
508
509 global $root, $pageno, $tabno;
510 $filter($rackData);
511 markupObjectProblems ($rackData);
512
513 // Process form submit.
514 if (isset ($_REQUEST['do_update']))
515 {
516 $log[] = processGridForm ($rackData, $state1, $state2);
517 printLog($log);
518 }
519
520 // Render the result whatever it is.
521 // Main layout.
522 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
523 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
524
525 // Left column with information portlet.
526 echo "<tr><td class=pcleft height='1%' width='50%'>";
527 startPortlet ('Rack information');
528 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
529 echo "<tr><th width='50%' class=tdright>Rack name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
530 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
531 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
532 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
533 echo "</table>\n";
534 finishPortlet();
535
536 echo "</td>\n";
537 echo "<td class=pcright rowspan=2>";
538
539 // Grid form.
540 startPortlet ($header);
541 echo "<center>\n";
542 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
543 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
544 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
545 echo "<form action='${root}?'>\n";
546 echo "<input type=hidden name=page value=${pageno}>\n";
547 echo "<input type=hidden name=tab value=${tabno}>\n";
548 echo "<input type=hidden name=rack_id value=${rack_id}>\n";
549 markupAtomGrid ($rackData, $state2);
550 renderAtomGrid ($rackData);
551 echo "</table></center>\n";
552 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
553 finishPortlet();
554 echo "</td></tr>\n";
555
556 // Help portlet.
557 echo '<tr><td class=pcleft>';
558 startPortlet ('Help');
559 echo "<p align=justify style='margin-left: 30px; margin-right: 30px;'>$help</p>";
560 finishPortlet();
561 echo "</td></td></table>\n";
562 }
563
564 function renderRackDesign ($rack_id)
565 {
566 $help =
567 "Rack design defines the physical layout of a rack cabinet. " .
568 "Most common reason to use this tab is absence of back rails, although " .
569 "any other design can be defined. " .
570 "In this tab you can change atoms' state between 'free' and 'absent'.<br>" .
571 "A selected checkbox means atom presence.";
572 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', $help, 'A', 'F');
573 }
574
575 function renderRackProblems ($rack_id = 0)
576 {
577 $help =
578 "Rack problems prevent free rackspace from being used for mounting. Such rackspace is considered " .
579 "unusable. After the problem is gone, the atom can become free again. " .
580 "In this tab you can change atoms' state from free to unusable and back.<br>" .
581 "A selected checkbox means a problem.";
582 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', $help, 'F', 'U');
583 }
584
585 function startPortlet ($title = '')
586 {
587 echo "<div class=portlet><h2>${title}</h2>";
588 }
589
590 function finishPortlet ()
591 {
592 echo "</div>\n";
593 }
594
595 function printRefsOfType ($refs, $type, $eq)
596 {
597 global $root;
598 $gotone=0;
599 foreach ($refs as $ref)
600 {
601 if ($eq($ref['type'], $type))
602 {
603 if ($gotone) echo ', ';
604 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>${ref['object_name']}</a>";
605 $gotone=1;
606 }
607 }
608 }
609
610 function renderRackObject ($object_id = 0)
611 {
612 global $root;
613 if ($object_id <= 0)
614 {
615 showError ('Invalid object_id in renderRackObject()');
616 return;
617 }
618 $info = getObjectInfo ($object_id);
619 if ($info == NULL)
620 {
621 showError ('getObjectInfo() failed in renderRackObject()');
622 return;
623 }
624 // Main layout starts.
625 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
626 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
627 // left column with uknown number of portlets
628 echo "<tr><td class=pcleft>";
629 startPortlet ('Object information');
630 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
631 if (!empty ($info['name']))
632 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
633 else
634 switch ($info['objtype_id'])
635 {
636 case TYPE_SERVER:
637 case TYPE_SWITCH:
638 case TYPE_ROUTER:
639 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
640 }
641 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft>${info['objtype_name']}</td></tr>\n";
642 if (!empty ($info['asset_no']))
643 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
644 else
645 switch ($info['objtype_id'])
646 {
647 case TYPE_SERVER:
648 case TYPE_SWITCH:
649 case TYPE_ROUTER:
650 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
651 }
652 if (!empty ($info['label']))
653 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
654 if (!empty ($info['barcode']))
655 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
656 if ($info['has_problems'] == 'yes')
657 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
658 foreach (getAttrValues ($object_id) as $record)
659 if (!empty ($record['value']))
660 echo "<tr><th width='50%' class=opt_attr_th>${record['name']}:</th><td class=tdleft>${record['value']}</td></tr>\n";
661 echo "</table><br>\n";
662 finishPortlet();
663
664 if (!empty ($info['comment']))
665 {
666 startPortlet ('Comment');
667 echo '<div class=commentblock>' . $info['comment'] . '</div>';
668 finishPortlet ();
669 }
670
671 $ports = getObjectPortsAndLinks ($object_id);
672 if (count ($ports))
673 {
674 startPortlet ('Ports and links');
675 usort($ports, 'sortByName');
676 if ($ports)
677 {
678 $hl_port_id = 0;
679 if (isset ($_REQUEST['hl_port_id']))
680 {
681 assertUIntArg ('hl_port_id');
682 $hl_port_id = $_REQUEST['hl_port_id'];
683 }
684 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
685 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
686 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
687 foreach ($ports as $port)
688 {
689 echo '<tr';
690 if ($hl_port_id == $port['id'])
691 echo ' class=port_highlight';
692 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
693 echo "<td>${port['l2address']}</td>";
694 if ($port['remote_object_id'])
695 {
696 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
697 echo "<td>${port['remote_name']}</td>";
698 }
699 elseif (!empty ($port['reservation_comment']))
700 {
701 echo "<td><b>Reserved;</b></td>";
702 echo "<td>${port['reservation_comment']}</td>";
703 }
704 else
705 echo '<td>&nbsp;</td><td>&nbsp;</td>';
706 echo "</tr>\n";
707 }
708 echo "</table><br>\n";
709 }
710 finishPortlet();
711 }
712 $addresses = getObjectAddresses ($object_id);
713 usort($addresses, 'sortAddresses');
714 if (count ($addresses))
715 {
716 startPortlet ('Network addresses');
717 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
718 echo "<tr><th>Interface name</th><th>IP Address</th><th>Description</th><th>Misc</th></tr>\n";
719 foreach ($addresses as $addr)
720 {
721 if (strlen($addr['address_name'])>40)
722 $address_name = substr($addr['address_name'],0,38).'...';
723 else
724 $address_name = $addr['address_name'];
725
726 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
727 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
728 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
729 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
730
731 if ($addr['address_reserved']=='yes')
732 $class='trwarning';
733 elseif ($addr['type']!='virtual' && $regnum>0)
734 $class='trwarning';
735 elseif ($addr['type']=='regular' && $sharednum>0)
736 $class='trwarning';
737 else
738 $class='';
739
740 echo "<tr class='$class'><td>${addr['name']}</td><td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td class='description'>$address_name</td><td>\n";
741
742 if ($addr['address_reserved']=='yes')
743 echo "<b>Reserved;</b> ";
744
745 if ($addr['type'] == 'virtual')
746 {
747 echo "<b>V</b>";
748 if ($notvirtnum > 0)
749 {
750 echo " Owners: ";
751 printRefsOfType($addr['references'], 'virtual', 'neq');
752 }
753 }
754 elseif ($addr['type'] == 'shared')
755 {
756 echo "<b>S</b>";
757 if ($sharednum > 0)
758 {
759 echo " Peers: ";
760 printRefsOfType($addr['references'], 'shared', 'eq');
761 echo ";";
762 }
763 if ($virtnum > 0)
764 {
765 echo " Virtuals: ";
766 printRefsOfType($addr['references'], 'virtual', 'eq');
767 echo ";";
768 }
769 if ($regnum > 0)
770 {
771 echo " Collisions: ";
772 printRefsOfType($addr['references'], 'regular', 'eq');
773 }
774
775 }
776 else
777 {
778 if ($virtnum > 0)
779 {
780 echo " Virtuals: ";
781 printRefsOfType($addr['references'], 'virtual', 'eq');
782 echo ";";
783 }
784 if ($notvirtnum > 0)
785 {
786 echo " Collisions: ";
787 printRefsOfType($addr['references'], 'virtual', 'neq');
788 }
789 }
790
791 echo "</td></tr>\n";
792 }
793 echo "</table><br>\n";
794 finishPortlet();
795 }
796
797 $forwards = getObjectForwards ($object_id);
798 if (count($forwards['in']) or count($forwards['out']))
799 {
800 startPortlet('Port Forwarding');
801
802 if (count($forwards['out']))
803 {
804
805 echo "<h3>Forwarding out:</h3>";
806
807 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
808 echo "<tr><th>Source</th><th>Target</th><th>Target Objects</th><th>Description</th></tr>\n";
809
810 foreach ($forwards['out'] as $pf)
811 {
812 $class='trwarning';
813 $name='';
814 foreach ($addresses as $addr)
815 if ($addr['ip'] == $pf['localip'])
816 {
817 $class='';
818 $name=$addr['name'];
819 break;
820 }
821
822 echo "<tr class='$class'>";
823
824 echo "<td>${pf['proto']}/$name:<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
825
826 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
827
828 $address=getIPAddress($pf['remoteip']);
829
830 echo "<td class='description'>";
831 foreach($address['bonds'] as $bond)
832 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
833
834 echo "</td><td class='description'>${pf['description']}</td>";
835
836 echo "</tr>";
837 }
838 echo "</table><br><br>";
839 }
840 if (count($forwards['in']))
841 {
842 echo "<h3>Forwarded from:</h3>";
843
844 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
845 echo "<tr><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
846
847 foreach ($forwards['in'] as $pf)
848 {
849 echo "<tr>";
850 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
851
852 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
853
854 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
855 echo "<td class='description'>${pf['description']}</td></tr>";
856 }
857
858 echo "</table><br><br>";
859 }
860 finishPortlet();
861 }
862
863 echo "</td>\n";
864
865 // After left column we have (surprise!) right column with rackspace portled only.
866 echo "<td class=pcright>";
867 // rackspace portlet
868 startPortlet ('Rackspace allocation');
869 // FIXME: now we call getRackData() twice
870 $racks = getResidentRacksData ($object_id);
871 foreach ($racks as $rackData)
872 renderRack ($rackData['id'], $object_id);
873 echo '<br>';
874 finishPortlet();
875 echo "</td></tr>";
876 echo "</table>\n";
877 }
878
879 function renderRackMultiSelect ($sname, $racks, $selected)
880 {
881 echo "<select name=${sname} multiple size=" . MAXSELSIZE . " onchange='getElementById(\"racks\").submit()'>\n";
882 foreach ($racks as $rack)
883 {
884 echo "<option value=${rack['id']}";
885 if (!(array_search ($rack['id'], $selected) === FALSE))
886 echo ' selected';
887 echo">${rack['name']}</option>\n";
888 }
889 echo "</select>\n";
890 }
891
892 function showMessageOrError ()
893 {
894 if (isset($_REQUEST['message']))
895 echo "<div class=msg_success>${_REQUEST['message']}</div>";
896 if (isset($_REQUEST['error']))
897 echo "<div class=msg_error>${_REQUEST['error']}</div>";
898 }
899
900 // This function renders a form for port edition.
901 function renderPortsForObject ($object_id = 0)
902 {
903 global $root, $pageno, $tabno;
904 if ($object_id <= 0)
905 {
906 showError ('Invalid object_id in renderPortsForObject()');
907 return;
908 }
909 showMessageOrError();
910 startPortlet ('Ports and interfaces');
911 $ports = getObjectPortsAndLinks ($object_id);
912 usort($ports, 'sortByName');
913 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
914 echo "<tr><th>&nbsp;</th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
915 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th>&nbsp;</th></tr>\n";
916 foreach ($ports as $port)
917 {
918 echo "<form action='${root}process.php'>";
919 echo "<input type=hidden name=op value=editPort>";
920 echo "<input type=hidden name=page value='${pageno}'>\n";
921 echo "<input type=hidden name=tab value='${tabno}'>\n";
922 echo "<input type=hidden name=port_id value='${port['id']}'>";
923 echo "<input type=hidden name=object_id value='$object_id'>\n";
924 echo "<tr><td><a href='${root}process.php?op=delPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=${port['name']}'>";
925 printImageHREF ('delete', 'Unlink and Delete this port');
926 echo "</a></td>\n";
927 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
928 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
929 echo "<td>${port['type']}</td>\n";
930 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
931 if ($port['remote_object_id'])
932 {
933 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
934 echo "<td>${port['remote_name']}</td>";
935 echo "<td><a href='${root}process.php?op=unlinkPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=";
936 echo urlencode ($port['name']);
937 echo "&remote_port_name=${port['remote_name']}&remote_object_name=${port['remote_object_name']}'>";
938 printImageHREF ('unlink', 'Unlink this port');
939 echo "</a></td>";
940 }
941 elseif (!empty ($port['reservation_comment']))
942 {
943 echo "<td><b>Reserved;</b></td>";
944 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
945 echo "<td><a href='${root}process.php?op=useup&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=${object_id}'>";
946 printImageHREF ('useup', 'Use up this port');
947 echo "</a></td>";
948 }
949 else
950 {
951 echo "<td>&nbsp;</td><td>&nbsp;</td>";
952 echo "<td>";
953 echo "<a href='javascript:;' onclick='window.open(\"${root}link_helper.php?port=${port['id']}&type=${port['type_id']}&object_id=$object_id&port_name=";
954 echo urlencode ($port['name']);
955 echo "\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
956 printImageHREF ('link', 'Link this port');
957 echo "</a> <input type=text name=reservation_comment>";
958 echo "</td>\n";
959 }
960 echo "<td><input type='submit' value='OK'></td>";
961 echo "</form></tr>\n";
962 }
963 echo "<form action='${root}process.php'><tr>";
964 echo "<td colspan=2><input type=text size=10 name=port_name tabindex=100></td>\n";
965 echo "<td><input type=text size=24 name=port_label tabindex=101></td>";
966 echo "<input type=hidden name=op value=addPort>\n";
967 echo "<input type=hidden name=object_id value='${object_id}'>\n";
968 echo "<input type=hidden name=page value='${pageno}'>\n";
969 echo "<input type=hidden name=tab value='${tabno}'>\n";
970 echo "<td><select name='port_type_id' tabindex=102>\n";
971 $types = getPortTypes();
972 global $default_port_type;
973 foreach ($types as $typeid => $typename)
974 {
975 echo "<option value='${typeid}'";
976 if ($typeid == $default_port_type)
977 echo " selected";
978 echo ">${typename}</option>\n";
979 }
980 echo "</select></td>";
981 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
982 echo "<td colspan=4><input type='submit' value='Add a new port' tabindex=104></td></tr></form>";
983 echo "</table><br>\n";
984 finishPortlet();
985
986 startPortlet ('Add/update multiple ports');
987 echo "<form action=${root}process.php method=post>";
988 echo "<input type=hidden name=page value='${pageno}'>\n";
989 echo "<input type=hidden name=tab value='${tabno}'>\n";
990 echo "<input type=hidden name=object_id value='${object_id}'>\n";
991 echo "<input type=hidden name=op value=addMultiPorts>";
992 echo 'Format: <select name=format>';
993 echo '<option value=c2900 disabled>Cisco 2900 series: sh int eth</option>';
994 echo '<option value=c3600eth disabled>Cisco 3600 ethernet: sh arp | inc -</option>';
995 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
996 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
997 echo '<option value=fiedge disabled>Foundry FastIron Edge: sh int br</option>';
998 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
999 echo "</select>";
1000 echo 'Default port type: ';
1001 echo "<select name=port_type>\n";
1002 foreach ($types as $typeid => $typename)
1003 {
1004 echo "<option value='${typeid}'";
1005 if ($typeid == $default_port_type)
1006 echo " selected";
1007 echo ">${typename}</option>\n";
1008 }
1009 echo "</select>";
1010 echo "<input type=submit value='Parse output'><br>\n";
1011 echo "<textarea name=input cols=100 rows=50></textarea><br>\n";
1012 echo '</form>';
1013 finishPortlet();
1014 }
1015
1016 function renderNetworkForObject ($object_id=0)
1017 {
1018 global $root, $pageno, $tabno;
1019 if ($object_id <= 0)
1020 {
1021 showError ('Invalid object_id in renderNetworkForObject()');
1022 return;
1023 }
1024 showMessageOrError();
1025 startPortlet ('Network Addresses');
1026 $addresses = getObjectAddresses ($object_id);
1027 usort($addresses, 'sortAddresses');
1028 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1029 echo "<tr><th>&nbsp;</th><th>Interface name</th><th>IP Address</th><th>Description</th><th>Type</th><th>Misc</th><th>&nbsp</th></tr>\n";
1030 foreach ($addresses as $addr)
1031 {
1032 if (strlen($addr['address_name'])>40)
1033 $address_name = substr($addr['address_name'],0,38).'...';
1034 else
1035 $address_name = $addr['address_name'];
1036
1037 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
1038 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
1039 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
1040 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
1041
1042 if ($addr['address_reserved']=='yes')
1043 $class='trwarning';
1044 elseif ($addr['type']!='virtual' && $regnum>0)
1045 $class='trwarning';
1046 elseif ($addr['type']=='regular' && $sharednum>0)
1047 $class='trwarning';
1048 else
1049 $class='';
1050
1051 echo "<form action='process.php'>";
1052 echo "<input type=hidden name=page value='${pageno}'>\n";
1053 echo "<input type=hidden name=tab value='${tabno}'>\n";
1054 echo "<input type=hidden name=op value=editAddressFromObject>";
1055 echo "<input type=hidden name=object_id value='$object_id'>";
1056 echo "<input type=hidden name=ip value='${addr['ip']}'>";
1057 echo "<tr class='$class'><td><a href='process.php?op=delAddrFObj&page=${pageno}&tab=${tabno}&ip=${addr['ip']}&object_id=$object_id'>";
1058 printImageHREF ('delete', 'Delete this IPv4 address');
1059 echo "</a></td>";
1060 echo "<td><input type='text' name='bond_name' value='${addr['name']}' size=10></td>";
1061 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
1062 echo "<td class='description'>$address_name</td>\n";
1063 echo "<td><select name='bond_type'>";
1064 foreach (array('regular'=>'Regular', 'virtual'=>'Virtual', 'shared'=>'Shared') as $n => $v)
1065 {
1066 echo "<option value='$n'";
1067 if ($addr['type'] == $n)
1068 echo " selected";
1069 echo ">$v</option>";
1070 }
1071 echo "</td><td>";
1072 if ($addr['address_reserved']=='yes')
1073 echo "<b>Reserved</b>; ";
1074
1075 if ($addr['type'] == 'virtual')
1076 {
1077 if ($notvirtnum > 0)
1078 {
1079 echo " Owners: ";
1080 printRefsOfType($addr['references'], 'virtual', 'neq');
1081 }
1082 }
1083 elseif ($addr['type'] == 'shared')
1084 {
1085 if ($sharednum > 0)
1086 {
1087 echo " Peers: ";
1088 printRefsOfType($addr['references'], 'shared', 'eq');
1089 echo ";";
1090 }
1091 if ($virtnum > 0)
1092 {
1093 echo " Virtuals: ";
1094 printRefsOfType($addr['references'], 'virtual', 'eq');
1095 echo ";";
1096 }
1097 if ($regnum > 0)
1098 {
1099 echo " Collisions: ";
1100 printRefsOfType($addr['references'], 'regular', 'eq');
1101 }
1102
1103 }
1104 else
1105 {
1106 if ($virtnum > 0)
1107 {
1108 echo " Virtuals: ";
1109 printRefsOfType($addr['references'], 'virtual', 'eq');
1110 echo ";";
1111 }
1112 if ($notvirtnum > 0)
1113 {
1114 echo " Collisions: ";
1115 printRefsOfType($addr['references'], 'virtual', 'neq');
1116 }
1117 }
1118
1119 echo "</td><td><input type=submit value='OK'></td></form></tr>\n";
1120 }
1121
1122
1123 echo "<form action='${root}process.php'><tr><td colspan=2><input type='text' size='10' name='name' tabindex=100></td>\n";
1124 echo "<input type=hidden name=page value='${pageno}'>\n";
1125 echo "<input type=hidden name=tab value='${tabno}'>\n";
1126 echo "<input type=hidden name=op value=addAddrFObj>\n";
1127 echo "<input type=hidden name=object_id value='$object_id'>\n";
1128
1129 echo "<td><input type=text name='ip' tabindex=101>\n";
1130 echo "</td><td><select name='type' tabindex=102>";
1131 echo "<option value='regular'>Regular</option>";
1132 echo "<option value='virtual'>Virtual</option>";
1133 echo "<option value='shared'>Shared</option>";
1134 echo "</select>";
1135 echo "</td><td colspan=3><input type='submit' value='Add a new interface' tabindex=103></td></tr></form>";
1136 echo "</table><br>\n";
1137 finishPortlet();
1138
1139 }
1140
1141 function printLog ($log)
1142 {
1143 foreach ($log as $record)
1144 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1145 }
1146
1147 /*
1148 The following conditions must be followed:
1149 1. We can mount onto free atoms only. This means: if any record for an atom
1150 already exists in RackSpace, it can't be used for mounting.
1151 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1152 and either delete them before unmounting or refuse to unmount the object.
1153 */
1154
1155 // We extensively use $_REQUEST in the function.
1156 function renderRackSpaceForObject ($object_id = 0)
1157 {
1158 if ($object_id <= 0)
1159 {
1160 showError ('Invalid object_id in renderRackSpaceForObject()');
1161 return;
1162 }
1163 $is_submit = isset ($_REQUEST['got_atoms']);
1164 $is_update = isset ($_REQUEST['rackmulti'][0]);
1165 $info = getObjectInfo ($object_id);
1166 if ($info == NULL)
1167 {
1168 showError ('getObjectInfo() failed in renderRackSpaceForObject()');
1169 return;
1170 }
1171 // Always process occupied racks plus racks chosen by user. First get racks with
1172 // already allocated rackspace...
1173 $workingRacksData = getResidentRacksData ($object_id);
1174 if ($workingRacksData === NULL)
1175 {
1176 print_r ($workingRacksData);
1177 showError ('getResidentRacksData() failed in renderRackSpaceForObject()');
1178 return;
1179 }
1180
1181 // ...and then add those chosen by user (if any).
1182 if ($is_update)
1183 foreach ($_REQUEST['rackmulti'] as $cand_id)
1184 {
1185 if (!isset ($workingRacksData[$cand_id]))
1186 {
1187 $rackData = getRackData ($cand_id);
1188 if ($rackData == NULL)
1189 {
1190 showError ('getRackData() failed in renderRackSpaceForObject()');
1191 return NULL;
1192 }
1193 $workingRacksData[$cand_id] = $rackData;
1194 }
1195 }
1196
1197 // Do it only once...
1198 foreach ($workingRacksData as &$rackData)
1199 applyObjectMountMask ($rackData, $object_id);
1200 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1201 unset ($rackData);
1202
1203 // Here we process form submit by trying to save all submitted info to database.
1204 if ($is_submit)
1205 {
1206 $oldMolecule = getMoleculeForObject ($object_id);
1207 $worldchanged = FALSE;
1208 $log = array();
1209 foreach ($workingRacksData as $rack_id => $rackData)
1210 {
1211 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1212 $log[] = $logrecord;
1213 if ($logrecord['code'] != 300)
1214 {
1215 $worldchanged = TRUE;
1216 // Reload our working copy after form processing.
1217 $rackData = getRackData ($rack_id);
1218 if ($rackData == NULL)
1219 $log[] = array ('code' => 500, 'message' => 'Working copy update failed in renderRackSpaceForObject()');
1220 applyObjectMountMask ($rackData, $object_id);
1221 $workingRacksData[$rack_id] = $rackData;
1222 }
1223 }
1224 if ($worldchanged)
1225 {
1226 // Log a record.
1227 $newMolecule = getMoleculeForObject ($object_id);
1228 $oc = count ($oldMolecule);
1229 $nc = count ($newMolecule);
1230 $omid = $oc ? createMolecule ($oldMolecule) : 'NULL';
1231 $nmid = $nc ? createMolecule ($newMolecule) : 'NULL';
1232 global $remote_username;
1233 $comment = empty ($_REQUEST['comment']) ? 'NULL' : "'${_REQUEST['comment']}'";
1234 $query =
1235 "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
1236 "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
1237 global $dbxlink;
1238 $result = $dbxlink->query ($query);
1239 if ($result == NULL)
1240 $log[] = array ('code' => 'error', 'message' => 'SQL query failed during history logging.');
1241 else
1242 $log[] = array ('code' => 'success', 'message' => 'History logged.');
1243 }
1244 printLog ($log);
1245 }
1246
1247 // This is the time for rendering.
1248 global $root, $pageno, $tabno;
1249 echo "<form id='racks' action='${root}'>";
1250 echo "<input type=hidden name=page value='${pageno}'>\n";
1251 echo "<input type=hidden name=tab value='${tabno}'>\n";
1252 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1253 // Main layout starts.
1254 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1255
1256 // Left portlet with rack list.
1257 echo "<td class=pcleft height='1%'>";
1258 startPortlet ('Racks');
1259 $allRacksData = getRacksForRow();
1260 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1261 echo "<br>";
1262 echo "<br>";
1263 finishPortlet();
1264 echo "</td>";
1265
1266 // Middle portlet with comment and submit.
1267 echo "<td class=pcleft>";
1268 startPortlet ('Comment');
1269 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1270 echo "<input type=submit value='Save' name=got_atoms>\n";
1271 echo "<br>";
1272 echo "<br>";
1273 finishPortlet();
1274 echo "</td>";
1275
1276 // Right portlet with rendered racks. If this form submit is not final, we have to
1277 // reflect the former state of the grid in current form.
1278 echo "<td class=pcright rowspan=2 height='1%'>";
1279 startPortlet ('Working copy');
1280 echo '<table border=0 cellspacing=10 align=center><tr>';
1281 foreach ($workingRacksData as $rack_id => $rackData)
1282 {
1283 // Order is important here: only original allocation is highlighted.
1284 highlightObject ($rackData, $object_id);
1285 markupAtomGrid ($rackData, 'T');
1286 // If we have a form processed, discard user input and show new database
1287 // contents.
1288 if (!$is_submit and $is_update)
1289 mergeGridFormToRack ($rackData);
1290 echo "<td valign=top>";
1291 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1292 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1293 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1294 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1295 renderAtomGrid ($rackData);
1296 echo "</table></center>\n";
1297 echo '</td>';
1298 }
1299 echo "</tr></table>";
1300 finishPortlet();
1301 echo "</td>\n";
1302
1303 echo "</form>\n";
1304 echo "</tr></table>\n";
1305 }
1306
1307 function renderMolecule ($mdata, $object_id)
1308 {
1309 // sort data out
1310 $rackpack = array();
1311 global $loclist;
1312 foreach ($mdata as $dummy => $rua)
1313 {
1314 $rack_id = $rua['rack_id'];
1315 $unit_no = $rua['unit_no'];
1316 $atom = $rua['atom'];
1317 if (!isset ($rackpack[$rack_id]))
1318 {
1319 $rackData = getRackData ($rack_id);
1320 for ($i = $rackData['height']; $i > 0; $i--)
1321 for ($locidx = 0; $locidx < 3; $locidx++)
1322 $rackData[$i][$locidx]['state'] = 'F';
1323 $rackpack[$rack_id] = $rackData;
1324 }
1325 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1326 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1327 }
1328 // now we have some racks to render
1329 foreach ($rackpack as $dummy => $rackData)
1330 {
1331 markAllSpans ($rackData);
1332 echo "<table class=molecule cellspacing=0>\n";
1333 echo "<caption>${rackData['name']}</caption>\n";
1334 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1335 for ($i = $rackData['height']; $i > 0; $i--)
1336 {
1337 echo "<tr><th>$i</th>";
1338 for ($locidx = 0; $locidx < 3; $locidx++)
1339 {
1340 $state = $rackData[$i][$locidx]['state'];
1341 echo "<td class=state_${state}>&nbsp;</td>\n";
1342 }
1343 echo "</tr>\n";
1344 }
1345 echo "</table>\n";
1346 }
1347 }
1348
1349 function renderUnmountedObjectsPortlet ()
1350 {
1351 startPortlet ('Unmounted objects');
1352 $objs = getUnmountedObjects();
1353 if ($objs === NULL)
1354 {
1355 showError ('getUnmountedObjects() failed in renderUnmountedObjectsPortlet()');
1356 return;
1357 }
1358 global $root, $nextorder;
1359 $order = 'odd';
1360 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1361 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th></tr>';
1362 foreach ($objs as $obj)
1363 {
1364 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1365 echo "<td>${obj['label']}</td>";
1366 echo "<td>${obj['asset_no']}</td></tr>";
1367 $order = $nextorder[$order];
1368 }
1369 echo "</table><br>\n";
1370 finishPortlet();
1371 }
1372
1373 function renderProblematicObjectsPortlet ()
1374 {
1375 startPortlet ('Problematic objects');
1376 $objs = getProblematicObjects();
1377 if ($objs === NULL)
1378 {
1379 showError ('getProblematicObjects() failed in renderProblematicObjectsPortlet()');
1380 return;
1381 }
1382 global $root, $nextorder;
1383 $order = 'odd';
1384 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1385 echo '<tr><th>Type</th><th>Common name</th></tr>';
1386 foreach ($objs as $obj)
1387 {
1388 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1389 echo "<td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></tr>";
1390 $order = $nextorder[$order];
1391 }
1392 echo "</table><br>\n";
1393 finishPortlet();
1394 }
1395
1396 function renderObjectGroupSummary ()
1397 {
1398 global $root;
1399 $summary = getObjectGroupInfo();
1400 if ($summary === NULL)
1401 {
1402 showError ('getObjectGroupInfo() failed in renderObjectGroupSummary()');
1403 return;
1404 }
1405 echo "<table border=0 class=objectview>\n";
1406 echo "<tr><td class=pcleft width='25%'>";
1407
1408 startPortlet ('Summary');
1409 foreach ($summary as $gi)
1410 {
1411 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1412 }
1413 finishPortlet();
1414
1415 echo '</td><td class=pcright>';
1416 renderUnmountedObjectsPortlet();
1417 echo '</td><td class=pcright>';
1418 renderProblematicObjectsPortlet();
1419 echo "</td></tr></table>\n";
1420 }
1421
1422 function renderObjectGroup ($group_id = 0)
1423 {
1424 global $root;
1425 $summary = getObjectGroupInfo();
1426 if ($summary == NULL)
1427 {
1428 showError ('getObjectGroupInfo() failed in renderObjectGroup()');
1429 return;
1430 }
1431 $objects = getObjectList ($group_id);
1432 if ($objects === NULL)
1433 {
1434 showError ('getObjectList() failed in renderObjectGroup()');
1435 return;
1436 }
1437 echo "<table border=0 class=objectview>\n";
1438 echo "<tr><td class=pcleft width='25%'>";
1439
1440 startPortlet ('All objects');
1441 foreach ($summary as $gi)
1442 {
1443 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1444 }
1445 finishPortlet();
1446
1447 echo '</td><td class=pcright>';
1448
1449 startPortlet ('Object group');
1450 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1451 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Rack</th></tr>';
1452 $order = 'odd';
1453 global $nextorder;
1454 foreach ($objects as $obj)
1455 {
1456 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1457 echo "<td>${obj['label']}</td>";
1458 echo "<td>${obj['asset_no']}</td>";
1459 if ($obj['rack_id'])
1460 echo "<td><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
1461 else
1462 echo '<td>Unmounted</td>';
1463 echo '</tr>';
1464 $order = $nextorder[$order];
1465 }
1466 echo '</table>';
1467 finishPortlet();
1468
1469 echo "</td></tr></table>";
1470 }
1471
1472 function renderEmptyPortsSelect ($port_id, $type_id)
1473 {
1474 $ports = getEmptyPortsOfType($type_id);
1475 usort($ports, 'sortEmptyPorts');
1476 foreach ($ports as $port)
1477 {
1478 if ($port_id == $port['Port_id'])
1479 continue;
1480 echo "<option value='${port['Port_id']}' onclick='getElementById(\"remote_port_name\").value=\"${port['Port_name']}\"; getElementById(\"remote_object_name\").value=\"${port['Object_name']}\";'>${port['Object_name']} ${port['Port_name']}</option>\n";
1481 }
1482 }
1483
1484 function renderObjectAddressesAndNames ()
1485 {
1486 $addresses = getObjectAddressesAndNames();
1487 usort($addresses, 'sortObjectAddressesAndNames');
1488 foreach ($addresses as $address)
1489 {
1490 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1491 }
1492 }
1493
1494 // History viewer for history-enabled simple dictionaries.
1495 function renderHistory ($object_type, $object_id)
1496 {
1497 switch ($object_type)
1498 {
1499 case 'row':
1500 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1501 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1502 $extra = 4;
1503 break;
1504 case 'rack':
1505 $query =
1506 "select ctime, user_name, rh.name, rh.deleted, d.dict_value as name, rh.height, rh.comment " .
1507 "from RackHistory as rh left join Dictionary as d on rh.row_id = d.dict_key " .
1508 "natural join Chapter " .
1509 "where chapter_name = 'RackRow' and rh.id = ${object_id} order by ctime";
1510 $header = '<tr><th>change time</th><th>author</th><th>rack name</th><th>is deleted?</th><th>rack row name</th><th>rack height</th><th>rack comment</th></tr>';
1511 $extra = 6;
1512 break;
1513 case 'object':
1514 $query =
1515 "select ctime, user_name, name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1516 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key natural join Chapter " .
1517 "where chapter_name = 'RackObjectType' and id=${object_id} order by ctime";
1518 $header = '<tr><th>change time</th><th>author</th><th>common name</th><th>visible label</th><th>barcode</th><th>asset no</th><th>is deleted?</th><th>has problems?</th><th>object type</th><th>comment</th></tr>';
1519 $extra = 9;
1520 break;
1521 default:
1522 showError ("Uknown object type '${object_type}' in renderHistory()");
1523 return;
1524 }
1525 global $dbxlink;
1526 $result = $dbxlink->query ($query);
1527 if ($result == NULL)
1528 {
1529 showError ('SQL query failed in renderHistory()');
1530 return;
1531 }
1532 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1533 $order = 'odd';
1534 global $nextorder;
1535 echo $header;
1536 while ($row = $result->fetch (PDO::FETCH_NUM))
1537 {
1538 echo "<tr class=row_${order}><td>${row[0]}</td>";
1539 for ($i = 1; $i <= $extra; $i++)
1540 echo "<td>" . $row[$i] . "</td>";
1541 echo "</tr>\n";
1542 $order = $nextorder[$order];
1543 }
1544 echo "</table><br>\n";
1545 }
1546
1547 function renderRackspaceHistory ()
1548 {
1549 global $root, $nextorder, $pageno, $tabno;
1550 $order = 'odd';
1551 $history = getRackspaceHistory();
1552 // Show the last operation by default.
1553 if (isset ($_REQUEST['op_id']))
1554 $op_id = $_REQUEST['op_id'];
1555 elseif (isset ($history[0]['mo_id']))
1556 $op_id = $history[0]['mo_id'];
1557 else $op_id = NULL;
1558
1559 $omid = NULL;
1560 $nmid = NULL;
1561 $object_id = 1;
1562 if ($op_id)
1563 list ($omid, $nmid) = getOperationMolecules ($op_id);
1564
1565 // Main layout starts.
1566 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1567
1568 // Left top portlet with old allocation.
1569 echo "<tr><td class=pcleft>";
1570 startPortlet ('Old allocation');
1571 if ($omid)
1572 {
1573 $oldMolecule = getMolecule ($omid);
1574 renderMolecule ($oldMolecule, $object_id);
1575 }
1576 else
1577 echo "nothing";
1578 finishPortlet();
1579
1580 echo '</td><td class=pcright>';
1581
1582 // Right top portlet with new allocation
1583 startPortlet ('New allocation');
1584 if ($nmid)
1585 {
1586 $newMolecule = getMolecule ($nmid);
1587 renderMolecule ($newMolecule, $object_id);
1588 }
1589 else
1590 echo "nothing";
1591 finishPortlet();
1592
1593 echo '</td></tr><tr><td colspan=2>';
1594
1595 // Bottom portlet with list
1596
1597 startPortlet ('Rackspace allocation history');
1598 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1599 echo "<tr><th>timestamp</th><th>author</th><th>rack object ID</th><th>rack object type</th><th>rack object name</th><th>comment</th></tr>\n";
1600 foreach ($history as $row)
1601 {
1602 if ($row['mo_id'] == $op_id)
1603 $class = 'hl';
1604 else
1605 $class = "row_${order}";
1606 echo "<tr class=${class}><td><a href='${root}?page=${pageno}&tab=${tabno}&op_id=${row['mo_id']}'>${row['ctime']}</a></td>";
1607 echo "<td>${row['user_name']}</td>";
1608 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1609 echo "</tr>\n";
1610 $order = $nextorder[$order];
1611 }
1612 echo "</table>\n";
1613 finishPortlet();
1614
1615 echo '</td></tr></table>';
1616
1617 }
1618
1619 function renderAddressspace ()
1620 {
1621 global $root;
1622 echo "<table class='widetable' border=0 cellpadding=10 cellspacing=0 align='center'>\n";
1623 $addrspaceList = getAddressspaceList();
1624 echo "<tr><th>Address range</th><th>Name</th><th>Total/used addresses</th></tr>";
1625 foreach ($addrspaceList as $iprange)
1626 {
1627 echo "<tr><td><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td><td>${iprange['name']}</td><td>";
1628 echo ($iprange['ip_bin'] | $iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin'])+1;
1629 $range = getIPRange($iprange['id']);
1630 echo "/";
1631 echo count($range['addrlist']);
1632 echo "</td></tr>";
1633 }
1634 echo "</table>\n";
1635 }
1636
1637 function renderAddNewRange ()
1638 {
1639 global $root, $pageno, $tabno;
1640 showMessageOrError();
1641 echo "<table class='widetable' border=0 cellpadding=10 cellpadding=0 align='center'>\n";
1642 $addrspaceList = getAddressspaceList();
1643 echo "<tr><th>&nbsp;</th><th>Address range</th><th>Name</th><th>Total/used addresses</th></tr>";
1644 foreach ($addrspaceList as $iprange)
1645 {
1646 $range = getIPRange($iprange['id']);
1647 $usedips = 0;
1648 foreach ($range['addrlist'] as $addr)
1649 if (count($addr['references'])>0 || $addr['reserved']=='yes')
1650 $usedips++;
1651 echo "<tr>";
1652 if ($usedips == 0)
1653 {
1654 echo "<td><a href='process.php?op=delRange&page=${pageno}&tab=${tabno}&id=${iprange['id']}'>";
1655 printImageHREF ('delete', 'Delete this IP range');
1656 echo "</a></td>\n";
1657 }
1658 else
1659 echo "<td>&nbsp</td>";
1660 echo "<td><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td><td>${iprange['name']}</td><td>";
1661 echo ($iprange['ip_bin'] | $iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin'])+1;
1662 echo "/";
1663 echo $usedips;
1664 echo "</td></tr>";
1665 }
1666 echo "<form action='process.php'>";
1667 echo "<input type=hidden name=op value=addRange>";
1668 echo "<input type=hidden name=page value='${pageno}'>\n";
1669 echo "<input type=hidden name=tab value='${tabno}'>\n";
1670 echo "<tr><td colspan=4 class='tdcenter'><input type=text name=ip size=10>/<input type=text name=mask size=10>&nbsp;<input type=text name='name' size='20'>&nbsp;<input type=submit value='Add a new range'></td></tr>";
1671 echo "</form></table>\n";
1672 }
1673
1674 function renderIPRange ()
1675 {
1676 global $root;
1677 $maxperpage=256;
1678 $id = $_REQUEST['id'];
1679 if (isset($_REQUEST['pg']))
1680 $page = $_REQUEST['pg'];
1681 else
1682 $page=0;
1683
1684 $paging=0;
1685
1686 $range = getIPRange($id);
1687 echo "<center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></center>\n";
1688
1689
1690 $startip = $range['ip_bin'] & $range['mask_bin'];
1691 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
1692 $realstartip = $startip;
1693 $realendip = $endip;
1694 $numpages = 0;
1695 if($endip - $startip > $maxperpage)
1696 {
1697 $paging=1;
1698 $numpages = ($endip - $startip)/$maxperpage;
1699 $startip = $startip + $page * $maxperpage;
1700 $endip = $startip + $maxperpage-1;
1701 }
1702 echo "<center>";
1703 for ($i=0; $i<$numpages; $i++)
1704 {
1705 if ($i == $page)
1706 echo "<b>$i</b> ";
1707 else
1708 echo "<a href='${root}?page=iprange&id=$id&pg=$i'>$i</a> ";
1709 }
1710 echo "</center>";
1711
1712 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n";
1713 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
1714
1715
1716 for($ip = $startip; $ip<=$endip; $ip++)
1717 {
1718 if ( (isset($range['addrlist'][$ip])) && ($range['addrlist'][$ip]['ip_bin'] == $ip) )
1719 {
1720 $numshared = countRefsOfType($range['addrlist'][$ip]['references'], 'shared', 'eq');
1721 $numreg = countRefsOfType($range['addrlist'][$ip]['references'], 'regular', 'eq');
1722 $numvirt = countRefsOfType($range['addrlist'][$ip]['references'], 'virtual', 'eq');
1723
1724 $addr = $range['addrlist'][$ip];
1725 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1726 echo "<tr class='trwarning'>";
1727 elseif ( $addr['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1728 echo "<tr class='trwarning'>";
1729 elseif ( $addr['reserved'] == 'yes')
1730 echo "<tr class='trbusy'>";
1731 elseif ( $numshared > 0 || $numreg > 0)
1732 echo "<tr class='trbusy'>";
1733 else
1734 echo "<tr>";
1735
1736 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td>${addr['name']}</td><td>";
1737 if ( $addr['reserved'] == 'yes')
1738 echo "<b>Reserved;</b> ";
1739 foreach ($range['addrlist'][$ip]['references'] as $ref)
1740 {
1741 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>${ref['object_name']}[${ref['name']}]</a>; ";
1742 }
1743 echo "</td></tr>\n";
1744 }
1745 else
1746 {
1747 echo "<tr><td><a href='${root}?page=ipaddress&ip=".long2ip($ip)."'>".long2ip($ip)."</a></td><td>&nbsp;</td><td>&nbsp;</td></tr>\n";
1748 }
1749 }
1750
1751 echo "</table>";
1752
1753 }
1754
1755 function renderIPRangeProperties ()
1756 {
1757 global $pageno, $tabno;
1758 $id = $_REQUEST['id'];
1759 showMessageOrError();
1760 $range = getIPRange($id);
1761 echo "<center><h1>${range['ip']}/${range['mask']}</h1></center>\n";
1762 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
1763 echo "<form action='process.php'><input type=hidden name=op value=editRange>";
1764 echo "<input type=hidden name=page value='${pageno}'>\n";
1765 echo "<input type=hidden name=tab value='${tabno}'>\n";
1766 echo "<input type=hidden name=id value='${id}'>";
1767 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${range['name']}'></tr><tr><td colspan=2 class='tdcenter'><input type=submit value='Update range'></td></form></tr>";
1768 echo "</table>\n";
1769
1770 }
1771
1772 function renderIPAddress ()
1773 {
1774 global $root;
1775 $ip = $_REQUEST['ip'];
1776 $address = getIPAddress($ip);
1777 echo "<center><h1>$ip</h1>";
1778 if ($address['exists'] == 1)
1779 echo "<h2>${address['name']}</h2>";
1780 echo "</center>\n";
1781
1782 // echo "<table width='100%' cesspadding=5 cellspacing=0 border=0 align='center'>";
1783 // echo "<tr valign='top'><td>";
1784
1785 startPortlet ('Address assignment');
1786 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1787 echo "<tr><th>Object name</th><th>Interface name</th><th>Interface type</th></tr>\n";
1788
1789 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
1790 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
1791 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
1792
1793
1794 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1795 $class='trwarning';
1796 elseif ( $address['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1797 $class='trwarning';
1798 else
1799 $class='';
1800
1801
1802
1803 if ($address['reserved'] == 'yes')
1804 echo "<tr class='$class'><td colspan='3'><b>RESERVED</b></td></tr>";
1805 foreach ($address['bonds'] as $bond)
1806 {
1807 echo "<tr class='$class'><td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td><td>${bond['name']}</td><td><b>";
1808 switch ($bond['type'])
1809 {
1810 case 'virtual':
1811 echo "Virtual";
1812 break;
1813 case 'shared':
1814 echo "Shared";
1815 break;
1816 case 'regular':
1817 echo "Regular";
1818 break;
1819 }
1820 echo "</b></td></tr>\n";
1821 }
1822 echo "</table><br><br>";
1823 finishPortlet();
1824
1825 // echo "</td><td>";
1826 // echo "</td></tr></table>";
1827 }
1828
1829 function renderIPAddressProperties ()
1830 {
1831 global $pageno, $tabno;
1832 $ip = $_REQUEST['ip'];
1833 showMessageOrError();
1834 $address = getIPAddress($ip);
1835 echo "<center><h1>$ip</h1></center>\n";
1836 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
1837 echo "<form action='process.php'><input type=hidden name=op value=editAddress>";
1838 echo "<input type=hidden name=page value='${pageno}'>\n";
1839 echo "<input type=hidden name=tab value='${tabno}'>\n";
1840 echo "<input type=hidden name=ip value='${ip}'>";
1841 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='".($address['exists']==1?$address['name']:'')."'></tr>";
1842 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ".($address['exists']==1?(($address['reserved']=='yes')?'checked':''):'')."></tr>";
1843 echo "<tr><td colspan=2 class='tdcenter'><input type=submit value='Update address'></td></form></tr>";
1844 echo "</table>\n";
1845
1846 }
1847
1848 function renderIPAddressAssignment ()
1849 {
1850 global $pageno, $tabno, $root;
1851 $ip = $_REQUEST['ip'];
1852 $address = getIPAddress($ip);
1853
1854 showMessageOrError();
1855 echo "<center><h1>$ip</h1></center>\n";
1856
1857
1858 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1859 echo "<tr><th>&nbsp;</th><th>Object name</th><th>Interface name</th><th>Interface type</th><th>&nbsp;</th></tr>\n";
1860
1861 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
1862 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
1863 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
1864
1865
1866 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1867 $class='trwarning';
1868 elseif ( $address['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1869 $class='trwarning';
1870 else
1871 $class='';
1872
1873
1874
1875 if ($address['reserved'] == 'yes')
1876 echo "<tr class='$class'><td colspan='5'><b>RESERVED</b></td></tr>";
1877 foreach ($address['bonds'] as $bond)
1878 {
1879 echo "<tr class='$class'><form action='process.php'>";
1880 echo "<input type=hidden name=op value='editBondForAddress'>";
1881 echo "<input type=hidden name=page value='${pageno}'>";
1882 echo "<input type=hidden name=tab value='${tabno}'>";
1883 echo "<input type=hidden name=ip value='$ip'>";
1884 echo "<input type=hidden name=object_id value='${bond['object_id']}'>";
1885 echo "<td><a href='process.php?op=delIpAssignment&page=${pageno}&tab=${tabno}&ip=$ip&object_id=${bond['object_id']}'>";
1886 printImageHREF ('delete', 'Unallocate address');
1887 echo "</a></td>";
1888 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td>";
1889 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td>";
1890 echo "<td><select name='bond_type'>";
1891 switch ($bond['type'])
1892 {
1893 case 'virtual':
1894 echo "<option value='regular'>Regular</option>";
1895 echo "<option value='virtual' selected>Virtual</option>";
1896 echo "<option value='shared'>Shared</option>";
1897 break;
1898 case 'shared':
1899 echo "<option value='regular'>Regular</option>";
1900 echo "<option value='virtual'>Virtual</option>";
1901 echo "<option value='shared' selected>Shared</option>";
1902 break;
1903 case 'regular':
1904 echo "<option value='regular' selected>Regular</option>";
1905 echo "<option value='virtual'>Virtual</option>";
1906 echo "<option value='shared'>Shared</option>";
1907 break;
1908 }
1909 echo "</select></td><td><input type='submit' value='OK'></td></form></tr>\n";
1910 }
1911 echo "<form action='process.php'><input type='hidden' name='op' value='bindObjectToIp'>";
1912 echo "<input type=hidden name=page value='${pageno}'>\n";
1913 echo "<input type=hidden name=tab value='${tabno}'>\n";
1914 echo "<input type='hidden' name='ip' value='$ip'>";
1915 echo "<td colspan=2><select name='object_id'>";
1916
1917 foreach (array(1, 4, 7, 8, 12, 14) as $type)
1918 {
1919 //get all Balck Boxes, Servers, Routers, Switches, UPS, Modems
1920 $objects = getObjectList($type);
1921 foreach ($objects as $object)
1922 echo "<option value='${object['id']}'>${object['dname']}</option>";
1923 }
1924
1925 echo "</select></td><td><input type='text' name='bond_name' value='' size=10></td>";
1926 echo "<td><select name='bond_type'><option value='regular'>Regular</option><option value='virtual'>Virtual</option><option value='shared'>Shared</option></select></td>";
1927 echo "<td><input type='submit' value='Assign address'></td></form></tr>";
1928 echo "</table><br><br>";
1929
1930 }
1931
1932 function renderIPAddressPortForwarding ($object_id=0)
1933 {
1934 global $pageno, $tabno, $root;
1935
1936 $info = getObjectInfo ($object_id);
1937 $forwards = getObjectForwards ($object_id);
1938 $addresses = getObjectAddresses ($object_id);
1939 showMessageOrError();
1940 echo "<center><h1>Port Forwardings</h1></center>\n";
1941 echo "<center><h3>Forwarding out:</h3></center>";
1942
1943 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1944 echo "<tr><th></th><th>Source</th><th>Target</th><th>Target Objects</th><th>Description</th></tr>\n";
1945
1946 foreach ($forwards['out'] as $pf)
1947 {
1948 $class='trwarning';
1949 $name='';
1950 foreach ($addresses as $addr)
1951 if ($addr['ip'] == $pf['localip'])
1952 {
1953 $class='';
1954 $name = $addr['name'];
1955 break;
1956 }
1957
1958 echo "<tr class='$class'>";
1959 echo "<td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto_bin']}&object_id=$object_id&page=${pageno}&tab=${tabno}'><img src='${root}/pix/delete_s.gif' title='Delete port forwarding' border=0 width=16 height=16></a></td>";
1960 echo "<td>${pf['proto']}/$name:<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
1961 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1962
1963 $address=getIPAddress($pf['remoteip']);
1964
1965 echo "<td class='description'>";
1966 foreach($address['bonds'] as $bond)
1967 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
1968 echo "</td><form action='process.php'><input type='hidden' name='op' value='updPortForwarding'><input type=hidden name=page value='${pageno}'><input type=hidden name=tab value='${tabno}'><input type='hidden' name='object_id' value='$object_id'><input type='hidden' name='localip' value='${pf['localip']}'><input type='hidden' name='localport' value='${pf['localport']}'><input type='hidden' name='remoteip' value='${pf['remoteip']}'><input type='hidden' name='remoteport' value='${pf['remoteport']}'><input type='hidden' name='proto' value='${pf['proto_bin']}'><td class='description'><input type='text' name='description' value='${pf['description']}'> <input type='submit' value='OK'></td></form>";
1969 echo "</tr>";
1970 }
1971 echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
1972 echo "<input type='hidden' name='object_id' value='$object_id'>";
1973 echo "<input type=hidden name=page value='${pageno}'>\n";
1974 echo "<input type=hidden name=tab value='${tabno}'>\n";
1975 echo "<tr align='center'><td colspan=2><select name='proto'><option value='1'>TCP</option><option value='2'>UDP</option></select><select name='localip'>";
1976
1977 foreach ($addresses as $addr)
1978 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ? '' : "${addr['name']}:") . "${addr['ip']}</option>";
1979
1980 echo "</select>:<input type='text' name='localport' size='4'></td><td><input type='text' name='remoteip' id='remoteip' size='10'>";
1981 echo "<a href='javascript:;' onclick='window.open(\"${root}/find_object_ip_helper.php\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'><img src='${root}/pix/find.png' title='Find object' border=0 height=16 width=16></a>";
1982 echo ":<input type='text' name='remoteport' size='4'></td><td></td><td colspan=1><input type='text' name='description' size='20'> <input type='submit' value='Create Forwarding'></td></tr>";
1983 echo "</form>";
1984
1985 echo "</table><br><br>";
1986
1987
1988 echo "<center><h3>Forwarded from:</h3></center>";
1989 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1990 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
1991
1992 foreach ($forwards['in'] as $pf)
1993 {
1994 echo "<tr>";
1995
1996 echo "<td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto_bin']}&object_id=${pf['object_id']}&page=${pageno}&tab=${tabno}'><img src='${root}/pix/delete_s.gif' title='Delete port forwarding' border=0 width=16 height=16></a></td>";
1997 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
1998 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
1999 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2000 echo "<td class='description'>${pf['description']}</td></tr>";
2001 }
2002
2003 // echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2004 // echo "<input type='hidden' name='object_id' value='$object_id'>";
2005 // echo "<input type=hidden name=page value='${pageno}'>\n";
2006 // echo "<input type=hidden name=tab value='${tabno}'>\n";
2007 // echo "<tr align='center'><td colspan=2><select name='proto'><option value='1'>TCP</option><option value='2'>UDP</option><input type='text' name='localip' size='10'>:<input type='text' name='localport' size='4'></td><td><select name='localip'>";
2008 // foreach ($addresses as $addr)
2009 // echo "<option value='${addr['ip']}'>${addr['ip']}</option>";
2010 //
2011 // echo "</select>:<input type='text' name='remoteport' size='4'></td><td><input type='text' name='description' size='20'></td><td><input type='submit' value='Create Forwarding'></td></tr>";
2012 // echo "</form>";
2013 echo "</table><br><br>";
2014
2015
2016 }
2017
2018
2019 function renderAddMultipleObjectsForm ()
2020 {
2021 global $pageno, $tabno, $nextorder;
2022
2023 $type_id = array();
2024 $name = array();
2025 $asset_no = array();
2026 $keepvalues = FALSE;
2027 // Look for current submit.
2028 if (isset ($_REQUEST['got_data']))
2029 {
2030 $keepvalues = TRUE;
2031 $log = array();
2032 for ($i=0; $i < MASSCOUNT; $i++)
2033 {
2034 if (!isset ($_REQUEST["${i}_object_type_id"]))
2035 {
2036 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i + 1);
2037 break;
2038 }
2039 assertUIntArg ("${i}_object_type_id", TRUE);
2040 assertStringArg ("${i}_object_name", TRUE);
2041 assertStringArg ("${i}_object_label", TRUE);
2042 assertStringArg ("${i}_object_asset_no", TRUE);
2043 assertStringArg ("${i}_object_barcode", TRUE);
2044 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2045 // Save user input for possible rendering.
2046 $name[$i] = $_REQUEST["${i}_object_name"];
2047 $label[$i] = $_REQUEST["${i}_object_label"];
2048 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2049 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2050
2051 // It's better to skip silently than printing a notice.
2052 if ($type_id[$i] == 0)
2053 continue;
2054 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i]) === TRUE)
2055 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2056 else
2057 $log[] = array ('code' => 'error', 'message' => 'commitAddObject() failed in renderAddMultipleObjectsForm()');
2058 }
2059 printLog ($log);
2060 }
2061
2062 // Render a form for the next.
2063 $typelist = getObjectTypeList();
2064 $typelist[0]['dict_key'] = 0;
2065 $typelist[0]['dict_value'] = 'SKIP';
2066 $order = 'odd';
2067 startPortlet ('Add multiple objects');
2068 echo '<form>';
2069 echo "<input type=hidden name=page value=${pageno}>";
2070 echo "<input type=hidden name=tab value=${tabno}>";
2071 echo '<table border=0 align=center>';
2072 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>\n";
2073 // If a user forgot to select object type on input (it is 'SKIP'), we keep his
2074 // previous input in the form.
2075 $order = 'odd';
2076 for ($i = 0; $i < MASSCOUNT; $i++)
2077 {
2078 echo '<tr class=row_{order}>';
2079 echo '<td>';
2080 printSelect ($typelist, "${i}_object_type_id", 0);
2081 echo '</td>';
2082 echo "<td><input type=text size=30 name=${i}_object_name";
2083 if ($keepvalues and $type_id[$i] == 0)
2084 echo " value='${name[$i]}'";
2085 echo "></td>";
2086 echo "<td><input type=text size=30 name=${i}_object_label";
2087 if ($keepvalues and $type_id[$i] == 0)
2088 echo " value='${label[$i]}'";
2089 echo "></td>";
2090 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2091 if ($keepvalues and $type_id[$i] == 0)
2092 echo " value='${asset_no[$i]}'";
2093 echo "></td>";
2094 echo "<td><input type=text size=10 name=${i}_object_barcode";
2095 if ($keepvalues and $type_id[$i] == 0)
2096 echo " value='${barcode[$i]}'";
2097 echo "></td>";
2098 echo "</tr>\n";
2099 $order = $nextorder[$order];
2100 }
2101 echo "<tr><td class=submit colspan=5><input type=submit name=got_data value='Create'></td></tr>\n";
2102 echo "</form></table>\n";
2103 finishPortlet();
2104 }
2105
2106 function printGreeting ()
2107 {
2108 global $remote_username, $accounts;
2109 $account = $accounts[$remote_username];
2110 echo "Hello, ${account['user_realname']}. This is RackTables " . VERSION;
2111 }
2112
2113 function renderSearchResults ()
2114 {
2115 global $remote_username, $root;
2116 $terms = trim ($_REQUEST['q']);
2117 if (empty ($terms))
2118 {
2119 showError ('Search string cannot be empty.');
2120 return;
2121 }
2122 if (!authorized ($remote_username, 'object', 'default'))
2123 {
2124 showError ('You are not authorized for viewing information about objects.');
2125 return;
2126 }
2127 // If we search for L2 address, we can either find one or find none.
2128 if
2129 (
2130 preg_match ('/^[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?$/i', $terms) or
2131 preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms) or
2132 preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms)
2133 )
2134 // Search for L2 address.
2135 {
2136 $result = searchByl2address ($terms);
2137 if ($result !== NULL)
2138 {
2139 echo "<script language='Javascript'>document.location='${root}?page=object";
2140 echo "&hl_port_id=${result['port_id']}";
2141 echo "&object_id=${result['object_id']}';//</script>";
2142 }
2143 else
2144 echo "L2 address '${terms}' not found!";
2145 }
2146 elseif (preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms))
2147 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2148 {
2149 $terms = substr ($terms, 4);
2150 $result = searchByl2address ($terms);
2151 if ($result !== NULL)
2152 {
2153 echo "<script language='Javascript'>document.location='${root}?page=object";
2154 echo "&hl_port_id=${result['port_id']}";
2155 echo "&object_id=${result['object_id']}';//</script>";
2156 }
2157 else
2158 echo "L2 address '${terms}' not found!";
2159 }
2160 elseif (preg_match ('/^[0-9][0-9]?[0-9]?\.[0-9]?[0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9]?[0-9]?[0-9]?$/i', $terms))
2161 // Search for IP address.
2162 {
2163 $result = getRangeByIp ($terms);
2164 if ($result !== NULL)
2165 {
2166 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2167 echo "&ip=${terms}";
2168 echo "';//</script>";
2169 }
2170 else
2171 echo "IP address '${terms}' not found!";
2172 return;
2173 }
2174 else
2175 // Search for objects.
2176 {
2177 $objects = getSearchResults ($terms);
2178 if (count ($objects) == 1)
2179 {
2180 $obj = current ($objects);
2181 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${obj['id']}';//</script>";
2182 }
2183 elseif (count ($objects) > 1)
2184 {
2185 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2186 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2187 $order = 'odd';
2188 global $nextorder;
2189 foreach ($objects as $obj)
2190 {
2191 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2192 echo "<td>${obj['label']}</td>";
2193 echo "<td>${obj['asset_no']}</td>";
2194 echo "<td>${obj['barcode']}</td></tr>";
2195 $order = $nextorder[$order];
2196 }
2197 echo '</table>';
2198 }
2199 else
2200 echo "Object '${terms}' not found!";
2201 }
2202 }
2203
2204 // This function prints a table of checkboxes to aid the user in toggling mount atoms
2205 // from one state to another. The first argument is rack data as
2206 // produced by getRackData(), the second is the value used for the 'unckecked' state
2207 // and the third is the value used for 'checked' state.
2208 // Usage contexts:
2209 // for mounting an object: printAtomGrid ($data, 'F', 'T')
2210 // for changing rack design: printAtomGrid ($data, 'A', 'F')
2211 // for adding rack problem: printAtomGrid ($data, 'F', 'U')
2212 // for adding object problem: printAtomGrid ($data, 'T', 'W')
2213
2214 function renderAtomGrid ($data)
2215 {
2216 $rack_id = $data['id'];
2217 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2218 {
2219 echo "<tr><th>${unit_no}</th>";
2220 for ($locidx = 0; $locidx < 3; $locidx++)
2221 {
2222 $state = $data[$unit_no][$locidx]['state'];
2223 echo "<td class=state_${state}";
2224 if (isset ($data[$unit_no][$locidx]['hl']))
2225 echo $data[$unit_no][$locidx]['hl'];
2226 echo ">";
2227 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2228 echo '<input type=checkbox disabled>';
2229 else
2230 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2231 echo '</td>';
2232 }
2233 echo "</tr>\n";
2234 }
2235 }
2236
2237 function renderPermissions ()
2238 {
2239 startPortlet ('User permissions');
2240 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2241 echo "<tr><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>";
2242 global $perms, $nextorder;
2243 $order = 'odd';
2244 foreach ($perms as $username => $pages)
2245 foreach ($pages as $page => $tabs)
2246 foreach ($tabs as $tab => $access)
2247 {
2248 echo "<tr class=row_${order}><td class=tdleft>$username</td><td>$page</td><td>$tab</td><td>$access</td></tr>\n";
2249 $order = $nextorder[$order];
2250 }
2251 echo "</table>\n";
2252 finishPortlet();
2253 }
2254
2255 function renderAccounts ()
2256 {
2257 global $nextorder, $accounts;
2258 startPortlet ('User accounts');
2259 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2260 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2261 $order = 'odd';
2262 foreach ($accounts as $user)
2263 {
2264 echo "<tr class=row_${order}><td class=tdleft>${user['user_name']}</td><td class=tdleft>${user['user_realname']}</td></li>";
2265 $order = $nextorder[$order];
2266 }
2267 echo '</table>';
2268 finishPortlet();
2269 }
2270
2271 function renderAccountsEditForm ()
2272 {
2273 global $root, $pageno, $tabno, $accounts;
2274 startPortlet ('User accounts');
2275 showMessageOrError();
2276 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2277 echo "<tr><th>op</th><th>Username</th><th>Real name</th><th>Password</th><th>&nbsp;</th></tr>\n";
2278 foreach ($accounts as $account)
2279 {
2280 echo "<form action='${root}process.php'>";
2281 echo "<input type=hidden name=op value=updateAccount>";
2282 echo "<input type=hidden name=page value='${pageno}'>\n";
2283 echo "<input type=hidden name=tab value='${tabno}'>\n";
2284 echo "<input type=hidden name=id value='${account['user_id']}'><tr>";
2285 echo "<td>";
2286 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2287 {
2288 echo "<a href='${root}process.php?op=disableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2289 printImageHREF ('blockuser', 'disable account');
2290 echo "</a>\n";
2291 }
2292 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2293 {
2294 echo "<a href='${root}process.php?op=enableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2295 printImageHREF ('unblockuser', 'enable account');
2296 echo "</a>\n";
2297 }
2298 // Otherwise skip icon.
2299 echo "</td>";
2300 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2301 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2302 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td>";
2303 echo "<td><input type='submit' value='OK'></td>";
2304 echo "</form></tr>\n";
2305 }
2306 echo "<form action='${root}process.php' method=post><tr>";
2307 echo "<input type=hidden name=op value=createAccount>\n";
2308 echo "<input type=hidden name=page value='${pageno}'>\n";
2309 echo "<input type=hidden name=tab value='${tabno}'>\n";
2310 echo "<td colspan=2><input type=text size=16 name=username tabindex=100></td>\n";
2311 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2312 echo "<td><input type=password size=64 name=password tabindex=102></td>";
2313 echo "<td colspan=4><input type=submit value='Create account' tabindex=103></td></tr></form>";
2314 echo "</table><br>\n";
2315 finishPortlet();
2316 }
2317
2318 function printChildrenAsOptions ($root, $depth = 0)
2319 {
2320 echo "<option value=${root['title']}>";
2321 if ($depth == 0)
2322 echo '* ';
2323 for ($i = 0; $i < $depth; $i++)
2324 echo '-- ';
2325 echo $root['title'];
2326 echo "</option>\n";
2327 foreach ($root['kids'] as $kid)
2328 printChildrenAsOptions ($kid, $depth + 1);
2329 }
2330
2331 // 1. Find all parentless pages.
2332 // 2. For each of them recursively find all children.
2333 // 3. Output the tree with recursion tree display.
2334 function printPagesTree ()
2335 {
2336 global $page;
2337 echo '<pre>';
2338 foreach ($page as $ctitle => $cpage)
2339 if (!isset ($cpage['parent']))
2340 {
2341 $croot['title'] = $ctitle;
2342 $croot['kids'] = getAllChildPages ($ctitle);
2343 printChildrenAsOptions ($croot);
2344 }
2345 echo '</pre>';
2346 }
2347
2348 function renderPermissionsEditForm ()
2349 {
2350 global $root, $pageno, $tabno, $perms, $accounts;
2351 startPortlet ('User permissions');
2352 showMessageOrError();
2353 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
2354 echo "<tr><th>&nbsp;</th><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>\n";
2355 foreach ($perms as $username => $pages)
2356 foreach ($pages as $access_page => $tabs)
2357 foreach ($tabs as $access_tab => $access)
2358 {
2359 echo "<td>";
2360 if ($username != '%')
2361 $userid = $accounts[$username]['user_id'];
2362 else
2363 $userid = 0;
2364 echo "<a href='${root}process.php?op=revoke&page=${pageno}&tab=${tabno}&access_userid=${userid}&access_page=${access_page}&access_tab=${access_tab}'>";
2365 printImageHREF ('revoke', 'Revoke permission');
2366 echo "</a></td>";
2367 echo "<td>${username}</td>";
2368 echo "<td>${access_page}</td>";
2369 echo "<td>${access_tab}</td>";
2370 echo "<td>${access}</td>";
2371 echo "</tr>\n";
2372 }
2373 echo "<form action='${root}process.php' method=post><tr>";
2374 echo "<input type=hidden name=op value=grant>\n";
2375 echo "<input type=hidden name=page value='${pageno}'>\n";
2376 echo "<input type=hidden name=tab value='${tabno}'>\n";
2377 // FIXME: border=0 doesn't work here for unknown reason
2378 echo "<td>";
2379 printImageInput ('grant', 103);
2380 echo "</td>";
2381 echo "<td><select name=access_userid>";
2382 echo "<option value=0>ANY</option>";
2383 foreach ($accounts as $account)
2384 echo "<option value=${account['user_id']}>${account['user_name']}</option>";
2385 echo "</select></td>\n";
2386 echo "<td><select name=access_page>";
2387 echo "<option value='%'>ANY</option>";
2388 printPagesTree();
2389 echo "</select></td>";
2390 echo "<td><input type=text size=16 name=access_tab tabindex=102 value=default></td>";
2391 echo "<td><input type=radio name=access_value value=no checked>no <input type=radio name=access_value value=yes>yes</td>";
2392 echo "</tr></form>";
2393 echo "</table><br>\n";
2394 finishPortlet();
2395 }
2396
2397 function renderReadonlyParameters ()
2398 {
2399 global $color, $default_port_type;
2400 startPortlet ('config.php');
2401 echo '<table border=0 align=center>';
2402 echo "<tr><th class=tdright>version:</th><td class=tdleft>" . VERSION . "</td></tr>\n";
2403 echo "<tr><th class=tdright>password hash:</th><td class=tdleft>" . PASSWORD_HASH . "</td></tr>\n";
2404 echo "<tr><th class=tdright>default port type:</th><td class=tdleft>${default_port_type}</td></tr>\n";
2405 foreach ($color as $class => $value)
2406 echo "<tr><th class=tdright bgcolor='#${value}'>color for class ${class}</th><td class=tdleft>${value}</td></tr>\n";
2407 echo "</table>\n";
2408 finishPortlet();
2409 }
2410
2411 function renderPortMap ($editable = FALSE)
2412 {
2413 global $nextorder, $root, $pageno, $tabno;
2414 showMessageOrError();
2415 startPortlet ("Port compatibility map");
2416 $ptlist = getPortTypes();
2417 $pclist = getPortCompat();
2418 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
2419 if ($editable)
2420 {
2421 echo "<form method=post action='${root}process.php'>";
2422 echo "<input type=hidden name=page value='${pageno}'>";
2423 echo "<input type=hidden name=tab value='${tabno}'>";
2424 echo "<input type=hidden name=op value=save>";
2425 }
2426 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2427 echo "<tr><th class=vert_th>&nbsp;</th>";
2428 foreach ($ptlist as $name2)
2429 echo "<th>to ${name2}</th>";
2430 echo "</tr>";
2431 // Make a copy to have an independent array pointer.
2432 $ptlistY = $ptlist;
2433 $order = 'odd';
2434 foreach ($ptlistY as $type1 => $name1)
2435 {
2436 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
2437 foreach ($ptlist as $type2 => $name2)
2438 {
2439 echo '<td><input type=checkbox' . ($editable ? " name=atom_${type1}_${type2}" : ' disabled');
2440 echo ($pctable[$type1][$type2] ? ' checked' : '') . '></td>';
2441 }
2442 echo "</tr>\n";
2443 $order = $nextorder[$order];
2444 }
2445 echo '</table><br>';
2446 if ($editable)
2447 {
2448 echo "<input type=submit value='Save changes'>";
2449 echo "</form>";
2450 }
2451 finishPortlet();
2452 }
2453
2454 function renderConfigMainpage ()
2455 {
2456 global $pageno, $root;
2457 $children = getDirectChildPages ($pageno);
2458 echo '<ul>';
2459 foreach ($children as $cpageno => $child)
2460 {
2461 $ctitle = $child['title']($cpageno);
2462 echo "<li><a href='${root}?page=${cpageno}'>" . $ctitle['name'] . "</li>\n";
2463 }
2464 echo '';
2465 echo '</ul>';
2466 }
2467
2468 function renderRackPage ($rack_id)
2469 {
2470 if ($rack_id == 0)
2471 {
2472 showError ('Invalid rack_id in renderRack()');
2473 return;
2474 }
2475 if (($rackData = getRackData ($rack_id)) == NULL)
2476 {
2477 showError ('getRackData() failed in renderRack()');
2478 return;
2479 }
2480 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
2481
2482 // Left column with information.
2483 echo "<td class=pcleft>";
2484 startPortlet ('Rack information');
2485 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2486 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
2487 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
2488 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
2489 if (!empty ($rackData['comment']))
2490 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
2491 echo '</table>';
2492 finishPortlet();
2493 echo '</td>';
2494
2495 // Right column with rendered rack.
2496 echo '<td>';
2497 startPortlet ('Rack diagram');
2498 renderRack ($rack_id);
2499 finishPortlet();
2500 echo '</td>';
2501
2502 echo '</tr></table>';
2503 }
2504
2505 function renderDictionary ()
2506 {
2507 global $nextorder;
2508 $dict = getDict();
2509 echo "<table border=0><tr>";
2510 foreach ($dict as $chapter)
2511 {
2512 echo "<td class=pcleft>";
2513 startPortlet ($chapter['name'] . ' (' . count ($chapter['word']) . ')');
2514 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2515 $order = 'odd';
2516 foreach ($chapter['word'] as $value)
2517 {
2518 echo "<tr class=row_${order}><td class=tdleft>${value}</td></tr>";
2519 $order = $nextorder[$order];
2520 }
2521 echo "</table>";
2522 finishPortlet();
2523 echo "</td>";
2524 }
2525 echo "</tr></table>";
2526 }
2527
2528 function renderDictionaryEditor ()
2529 {
2530 global $root, $pageno, $tabno;
2531 showMessageOrError();
2532 $dict = getDict();
2533 echo "<table border=0><tr>";
2534 foreach ($dict as $chapter)
2535 {
2536 echo "<td class=pcleft>";
2537 startPortlet ($chapter['name'] . ' (' . count ($chapter['word']) . ')');
2538 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2539 foreach ($chapter['word'] as $key => $value)
2540 {
2541 echo "<form action='${root}process.php' method=post>";
2542 echo "<input type=hidden name=page value='${pageno}'>";
2543 echo "<input type=hidden name=tab value='${tabno}'>";
2544 echo "<input type=hidden name=op value='upd'>";
2545 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2546 echo "<input type=hidden name=dict_key value='${key}'>";
2547 echo '<tr>';
2548 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
2549 printImageHREF ('delete', 'Delete word');
2550 echo "</a></td>";
2551 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
2552 echo "<td><input type=submit value=OK></td>";
2553 echo '</tr></form>';
2554 }
2555 echo "<form action='${root}process.php' method=post>";
2556 echo "<input type=hidden name=page value='${pageno}'>";
2557 echo "<input type=hidden name=tab value='${tabno}'>";
2558 echo "<input type=hidden name=op value=add>";
2559 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2560 echo '<tr>';
2561 echo "<td>&nbsp;</td>";
2562 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
2563 echo "<td><input type=submit value=OK></td>";
2564 echo '</tr></form>';
2565 echo "</table>";
2566 finishPortlet();
2567 echo "</td>";
2568 }
2569 echo "</tr></table>";
2570 }
2571
2572 // We don't allow to rename/delete a sticky chapter and we don't allow
2573 // to delete a non-empty chapter.
2574 function renderChaptersEditor ()
2575 {
2576 global $root, $pageno, $tabno;
2577 showMessageOrError();
2578 $dict = getDict();
2579 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2580 echo '<tr><th>&nbsp;</th><th>Chapter name</th><th>Words</th><th>&nbsp;</th></tr>';
2581 foreach ($dict as $chapter)
2582 {
2583 $wordcount = count ($chapter['word']);
2584 $sticky = $chapter['sticky'];
2585 echo "<form action='${root}process.php' method=post>";
2586 echo "<input type=hidden name=page value='${pageno}'>";
2587 echo "<input type=hidden name=tab value='${tabno}'>";
2588 echo "<input type=hidden name=op value=upd>";
2589 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2590 echo '<tr>';
2591 echo '<td>';
2592 if ($sticky or $wordcount > 0)
2593 echo '&nbsp;';
2594 else
2595 {
2596 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
2597 printImageHREF ('delete', 'Remove chapter');
2598 echo "</a>";
2599 }
2600 echo '</td>';
2601 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ? ' disabled' : '') . "></td>";
2602 echo "<td class=tdleft>${wordcount}</td><td>";
2603 if ($sticky)
2604 echo '&nbsp;';
2605 else
2606 echo "<input type=submit value='OK'>";
2607 echo '</td></tr>';
2608 echo '</form>';
2609 }
2610 echo "<form action='${root}process.php' method=post>";
2611 echo "<input type=hidden name=page value='${pageno}'>";
2612 echo "<input type=hidden name=tab value='${tabno}'>";
2613 echo "<input type=hidden name=op value=add>";
2614 echo '<tr><td>';
2615 printImageInput ('add');
2616 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
2617 echo '</tr>';
2618 echo '</form>';
2619 echo "</table>\n";
2620 }
2621
2622 function renderAttributes ()
2623 {
2624 global $nextorder;
2625 $attrMap = getAttrMap();
2626 startPortlet ('Optional attributes');
2627 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2628 echo "<tr><th class=tdleft>Attribute name</th><th class=tdleft>Attribute type</th><th class=tdleft>Applies to</th></tr>";
2629 $order = 'odd';
2630 foreach ($attrMap as $attr)
2631 {
2632 echo "<tr class=row_${order}>";
2633 echo "<td class=tdleft>${attr['name']}</td>";
2634 echo "<td class=tdleft>${attr['type']}</td>";
2635 echo '<td class=tdleft>';
2636 if (count ($attr['application']) == 0)
2637 echo '&nbsp;';
2638 else
2639 foreach ($attr['application'] as $app)
2640 if ($attr['type'] == 'dict')
2641 echo "${app['objtype_name']} (values from '${app['chapter_name']}')<br>";
2642 else
2643 echo "${app['objtype_name']}<br>";
2644 echo '</td>';
2645 echo "</tr>\n";
2646 $order = $nextorder[$order];
2647 }
2648 echo "</table><br>\n";
2649 finishPortlet();
2650 }
2651
2652 function renderEditAttributesForm ()
2653 {
2654 global $root, $pageno, $tabno;
2655 $attrMap = getAttrMap();
2656 showMessageOrError();
2657 startPortlet ('Optional attributes');
2658 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2659 echo '<tr><th>&nbsp;</th><th>Name</th><th>Type</th><th>&nbsp;</th></tr>';
2660 foreach ($attrMap as $attr)
2661 {
2662 echo "<form action='${root}process.php' method=post>";
2663 echo "<input type=hidden name=page value='${pageno}'>";
2664 echo "<input type=hidden name=tab value='${tabno}'>";
2665 echo "<input type=hidden name=op value=upd>";
2666 echo "<input type=hidden name=attr_id value='${attr['id']}'>";
2667 echo '<tr>';
2668 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&attr_id=${attr['id']}'>";
2669 printImageHREF ('delete', 'Remove attribute');
2670 echo '</a></td>';
2671 echo "<td><input type=text name=attr_name value='${attr['name']}'></td>";
2672 echo "<td>${attr['type']}</td>";
2673 echo "<td><input type=submit value='OK'></td>";
2674 echo '</tr>';
2675 echo '</form>';
2676 }
2677 echo "<form action='${root}process.php' method=post>";
2678 echo "<input type=hidden name=page value='${pageno}'>";
2679 echo "<input type=hidden name=tab value='${tabno}'>";
2680 echo "<input type=hidden name=op value=add>";
2681 echo '<tr><td>';
2682 printImageInput ('add');
2683 echo "</td><td><input type=text name=attr_name></td>";
2684 echo '<td><select name=attr_type>';
2685 echo '<option value=uint>uint</option>';
2686 echo '<option value=float>float</option>';
2687 echo '<option value=string>string</option>';
2688 echo '<option value=dict>dict</option>';
2689 echo '</select></td>';
2690 echo '</tr>';
2691 echo '</form>';
2692 echo "</table>\n";
2693 finishPortlet();
2694 }
2695
2696 function renderEditAttrMapForm ()
2697 {
2698 global $root, $pageno, $tabno;
2699 $attrMap = getAttrMap();
2700 showMessageOrError();
2701 startPortlet ('Attribute map');
2702 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2703 echo '<tr><th>&nbsp;</th><th>Attribute name</th><th>Object type</th><th>Dictionary chapter</th></tr>';
2704 foreach ($attrMap as $attr)
2705 {
2706 if (count ($attr['application']) == 0)
2707 continue;
2708 foreach ($attr['application'] as $app)
2709 {
2710 echo '<tr>';
2711 echo '<td>';
2712 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&";
2713 echo "attr_id=${attr['id']}&objtype_id=${app['objtype_id']}'>";
2714 printImageHREF ('delete', 'Remove mapping');
2715 echo "</a>";
2716 echo '</td>';
2717 echo "<td>${attr['name']}</td>";
2718 echo "<td>${app['objtype_name']}</td>";
2719 echo "<td>";
2720 if ($attr['type'] == 'dict')
2721 echo "${app['chapter_name']}";
2722 else
2723 echo '&nbsp;';
2724 echo "</td></tr>\n";
2725 }
2726 }
2727 echo "<form action='${root}process.php' method=post>";
2728 echo "<input type=hidden name=page value='${pageno}'>";
2729 echo "<input type=hidden name=tab value='${tabno}'>";
2730 echo "<input type=hidden name=op value=add>";
2731 echo '<tr><td>';
2732 printImageInput ('add');
2733 echo "</td><td><select name=attr_id>";
2734 $shortType['uint'] = 'U';
2735 $shortType['float'] = 'F';
2736 $shortType['string'] = 'S';
2737 $shortType['dict'] = 'D';
2738 foreach ($attrMap as $attr)
2739 echo "<option value=${attr['id']}>[" . $shortType[$attr['type']] . "] ${attr['name']}</option>";
2740 echo "</select></td>";
2741 echo '<td>';
2742 printSelect (getObjectTypeList(), 'objtype_id');
2743 echo '</td>';
2744 $dict = getDict();
2745 echo '<td><select name=chapter_no>';
2746 foreach ($dict as $chapter)
2747 if (!$chapter['sticky'])
2748 echo "<option value='${chapter['no']}'>${chapter['name']}</option>";
2749 echo '</select></td>';
2750 echo '</tr>';
2751 echo '</form>';
2752 echo "</table>\n";
2753 finishPortlet();
2754 }
2755
2756 function printImageHREF ($tag, $title = '')
2757 {
2758 global $root, $image;
2759 if (!isset ($image[$tag]))
2760 $tag = 'error';
2761 $img = $image[$tag];
2762 echo
2763 "<img " .
2764 "src='${root}${img['path']}' " .
2765 "width=${img['width']} " .
2766 "height=${img['height']} " .
2767 "border=0 " .
2768 (empty ($title) ? '' : "title='${title}'") .
2769 ">";
2770 }
2771
2772 function printImageInput ($tag, $tabindex = 0)
2773 {
2774 global $root, $image;
2775 if (!isset ($image[$tag]))
2776 $tag = 'error';
2777 $img = $image[$tag];
2778 echo
2779 "<input type=image name=submit " .
2780 "src='${root}${img['path']}' " .
2781 "border=0 " .
2782 ($tabindex ? '' : "tabindex=${tabindex}") .
2783 ">";
2784 }
2785
2786 // This function returns URL for favourite icon.
2787 function getFaviconURL ()
2788 {
2789 global $root, $image;
2790 return $root . $image['favicon']['path'];
2791 }
2792
2793 function renderReportSummary ()
2794 {
2795 echo "Here be dragons :-P";
2796 }
2797
2798 function renderUIConfig ()
2799 {
2800 echo "Here be dragons :-P";
2801 }
2802
2803 // This function queries the backend about current VLAN configuration and
2804 // renders a form suitable for submit.
2805 function renderVLANMembership ($object_id = 0)
2806 {
2807 global $root, $pageno, $tabno, $remote_username;
2808 if ($object_id <= 0)
2809 {
2810 showError ('Invalid object_id in renderVLANMembership()');
2811 return;
2812 }
2813 showMessageOrError();
2814 $endpoints = findAllEndpoints ($object_id);
2815 if (count ($endpoints) == 0)
2816 echo 'Can\'t find any mean to reach current object. Please either set FQDN attribute or assign an IP address to the object.';
2817 elseif (count ($endpoints) > 1)
2818 echo 'More than one IP address is assigned to this object, please configure FQDN attribute.';
2819 else
2820 {
2821 // FIXME: find actual HW and SW data and pass to the gateway.
2822 $data = queryGateway
2823 (
2824 $tabno,
2825 array ($endpoints[0], 'hwtype', 'swtype', $remote_username),
2826 array ('listvlans', 'listports')
2827 );
2828 if ($data == NULL)
2829 {
2830 showError ('Failed to get any response from queryGateway() or the gateway returned');
2831 return;
2832 }
2833 if ($data[0] != 'OK!')
2834 {
2835 showError ("Gateway failure: ${data[0]}");
2836 return;
2837 }
2838 // Now we have VLAN list in $data[1] and port list in $data[2]. Let's sort this out.
2839 $vlanlist = array_unique (explode (',', substr ($data[1], strlen ('OK!'))));
2840 sort ($vlanlist);
2841 if (count ($vlanlist) == 0)
2842 {
2843 showError ("Gateway succeeded, but returned no VLAN records.");
2844 return;
2845 }
2846 $portlist = array();
2847 foreach (explode (',', substr ($data[2], strlen ('OK '))) as $pair)
2848 {
2849 list ($portname, $vlanid) = explode ('=', $pair);
2850 $portlist[$portname] = $vlanid;
2851 }
2852 if (count ($portlist) == 0)
2853 {
2854 showError ("Gateway succeeded, but returned no port records.");
2855 return;
2856 }
2857 // We don't sort the port list, as the gateway is believed to have done this already
2858 // (or at least the underlying switch software ought to).
2859 // Here the visual part of the work comes. Top row, then bottom.
2860 startPortlet ('Current configuration');
2861
2862 echo "<table class=widetable cellspacing=0 cellpadding='5' align=center><tr>";
2863 echo "<form action='${root}process.php' method=post>";
2864 echo "<input type=hidden name=page value='${pageno}'>";
2865 echo "<input type=hidden name=tab value='${tabno}'>";
2866 echo "<input type=hidden name=op value=submit>";
2867 echo "<input type=hidden name=object_id value=${object_id}>";
2868 echo "<input type=hidden name=portcount value=" . count ($portlist) . ">\n";
2869 $portno = 0;
2870 foreach ($portlist as $portname => $vlanid)
2871 {
2872 // Don't let big boxes break our fancy pages.
2873 if (($portno) % PORTS_PER_ROW == 0)
2874 {
2875 if ($portno > 0)
2876 echo "</tr>\n";
2877 echo "<tr><th>" . ($portno + 1) . "-" . ($portno + PORTS_PER_ROW) . "</th>";
2878 }
2879 echo "<td>${portname} ";
2880 if ($vlanid == 'trunk')
2881 echo '[trunk]';
2882 else
2883 {
2884 echo "<input type=hidden name=portname_${portno} value='${portname}'>";
2885 echo "<select name=vlanid_${portno}>";
2886 foreach ($vlanlist as $dummy => $v)
2887 {
2888 echo "<option value=${v}";
2889 if ($v == $vlanid)
2890 echo ' selected';
2891 echo ">${v}</option>";
2892 }
2893 echo "</select>";
2894 }
2895 $portno++;
2896 echo "</td>";
2897 }
2898 echo "</tr><tr><td colspan=" . (PORTS_PER_ROW + 1) . "><input type=submit value='Save changes'></form></td></tr></table>";
2899 finishPortlet();
2900 }
2901 }
2902
2903 function renderHelpContents ()
2904 {
2905 echo 'Hello there. All existing help snippets scattered across other tabs are going to be gathered here. Soon.';
2906 }
2907
2908 ?>