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