4 * This file contains frontend functions for RackTables.
8 // Interface function's special.
9 $nextorder['odd'] = 'even';
10 $nextorder['even'] = 'odd';
13 function renderIndex ()
17 <table border
=0 cellpadding
=0 cellspacing
=0 width
='100%'>
20 <div style
='text-align: center; margin: 10px; '>
21 <table width
='100%' cellspacing
=0 cellpadding
=30 class=mainmenu border
=0>
24 <h1
><a href
='<?php echo $root; ?>?page=rackspace'>Rackspace
<br
>
25 <?php
printImageHREF ('rackspace'); ?
></a
></h1
>
28 <h1
><a href
='<?php echo $root; ?>?page=objects'>Objects
<br
>
29 <?php
printImageHREF ('objects'); ?
></a
></h1
>
32 <h1
><a href
='<?php echo $root; ?>?page=ipv4space'>IPv4 space
<br
>
33 <?php
printImageHREF ('ipv4space'); ?
></a
></h1
>
37 <table width
='100%' cellspacing
=0 cellpadding
=30 class=mainmenu border
=0>
40 <h1
><a href
='<?php echo $root; ?>?page=config'>Configuration
<br
>
41 <?php
printImageHREF ('config'); ?
></a
></h1
>
44 <h1
><a href
='<?php echo $root; ?>?page=reports'>Reports
<br
>
45 <?php
printImageHREF ('reports'); ?
></a
></h1
>
48 <h1
><a href
='<?php echo $root; ?>?page=ipv4slb'>IPv4 SLB
<br
>
49 <?php
printImageHREF ('ipv4slb'); ?
></a
></h1
>
60 function renderRackspace ()
63 <table border
=0 cellpadding
=10 cellpadding
=1>
65 // generate thumb gallery
66 $rackrowList = getRackRowInfo();
67 global $root, $nextorder;
68 $rackwidth = getConfigVar ('rtwidth_0') +
getConfigVar ('rtwidth_1') +
getConfigVar ('rtwidth_2');
70 foreach ($rackrowList as $rackrow)
72 echo "<tr class=row_${order}><th><a href='${root}?page=row&row_id=${rackrow['dict_key']}'>${rackrow['dict_value']}</a></th>";
73 $rackList = getRacksForRow ($rackrow['dict_key']);
74 echo "<td><table border=0 cellspacing=5><tr>";
75 foreach ($rackList as $dummy => $rack)
77 echo "<td align=center><a href='${root}?page=rack&rack_id=${rack['id']}'>";
78 echo "<img border=0 width=${rackwidth} height=";
79 echo 3 +
3 +
$rack['height'] * 2;
80 echo " title='${rack['height']} units'";
81 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
82 echo "<br>${rack['name']}</a></td>";
84 echo "</tr></table></tr>\n";
85 $order = $nextorder[$order];
90 function renderRow ($row_id)
94 showError ('Invalid row_id', __FUNCTION__
);
97 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
99 showError ('getRackRowInfo() failed', __FUNCTION__
);
102 $rackList = getRacksForRow ($row_id);
103 // Main layout starts.
104 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
106 // Left portlet with row information.
107 echo "<tr><td class=pcleft>";
108 startPortlet ($rowInfo['dict_value']);
109 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
110 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
111 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
112 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
113 renderProgressBar (getRSUforRackRow ($rackList));
115 echo "</table><br>\n";
118 echo "</td><td class=pcright>";
120 global $root, $nextorder;
121 $rackwidth = getConfigVar ('rtwidth_0') +
getConfigVar ('rtwidth_1') +
getConfigVar ('rtwidth_2');
123 startPortlet ('Racks');
124 echo "<table border=0 cellspacing=5 align='center'><tr>";
125 foreach ($rackList as $dummy => $rack)
127 echo "<td align=center class=row_${order}><a href='${root}?page=rack&rack_id=${rack['id']}'>";
128 echo "<img border=0 width=" . $rackwidth * getConfigVar ('ROW_SCALE') . " height=";
129 echo (3 +
3 +
$rack['height'] * 2) * getConfigVar ('ROW_SCALE');
130 echo " title='${rack['height']} units'";
131 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
132 echo "<br>${rack['name']}</a></td>";
133 $order = $nextorder[$order];
135 echo "</tr></table>\n";
138 echo "</td></tr></table>";
141 function showError ($info = '', $funcname = 'N/A')
144 echo "<div class=msg_error>An error has occured in function [${funcname}]. ";
146 echo 'No additional information is available.';
148 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
149 echo "Go back or try starting from <a href='${root}'>index page</a>.<br></div>\n";
152 // This function renders rack as HTML table.
153 function renderRack ($rack_id = 0, $hl_obj_id = 0)
157 showError ('Invalid rack_id', __FUNCTION__
);
160 if (($rackData = getRackData ($rack_id)) == NULL)
162 showError ('getRackData() failed', __FUNCTION__
);
165 global $root, $pageno, $tabno;
166 markAllSpans ($rackData);
168 highlightObject ($rackData, $hl_obj_id);
169 markupObjectProblems ($rackData);
170 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
171 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
172 echo "<center>\n<h2><a href='${root}?page=row&row_id=${rackData['row_id']}'>${rackData['row_name']}</a> :";
173 // FIXME: use 'bypass'?
174 if ($prev_id != NULL)
175 echo " <a href='${root}?page=rack&rack_id=${prev_id}'>< < <</a>";
176 echo " <a href='${root}?page=rack&rack_id=${rackData['id']}'>${rackData['name']}</a>";
177 if ($next_id != NULL)
178 echo " <a href='${root}?page=rack&rack_id=${next_id}'>> > ></a>";
180 if ($rackData['left_is_front'] == 'yes')
181 $markup = array ('left' => 'Front', 'right' => 'Back');
183 $markup = array ('left' => 'Back', 'right' => 'Front');
184 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
185 echo "<tr><th width='10%'> </th><th width='20%'>${markup['left']}</th>";
186 echo "<th width='50%'>Interior</th><th width='20%'>${markup['right']}</th></tr>\n";
187 for ($i = $rackData['height']; $i > 0; $i--)
189 echo '<tr><th>' . ($rackData['bottom_is_unit1'] == 'yes' ?
$i : $rackData['height'] - $i +
1) . '</th>';
190 for ($locidx = 0; $locidx < 3; $locidx++
)
192 if (isset ($rackData[$i][$locidx]['skipped']))
194 $state = $rackData[$i][$locidx]['state'];
195 echo "<td class=state_${state}";
196 if (isset ($rackData[$i][$locidx]['hl']))
197 echo $rackData[$i][$locidx]['hl'];
198 if (isset ($rackData[$i][$locidx]['colspan']))
199 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
200 if (isset ($rackData[$i][$locidx]['rowspan']))
201 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
206 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
207 if (!empty ($objectData['asset_no']))
208 $prefix = "<div title='${objectData['asset_no']}";
210 $prefix = "<div title='no asset tag";
211 // Don't tell about label, if it matches common name.
212 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
213 $suffix = ", visible label is \"${objectData['label']}\"'>";
216 echo $prefix . $suffix;
217 echo "<a href='${root}?page=object&object_id=${objectData['id']}'>${objectData['dname']}</a></div>";
220 echo '<div title="This rackspace does not exist"> </div>';
223 echo '<div title="Free rackspace"> </div>';
226 echo '<div title="Problematic rackspace, you CAN\'T mount here"> </div>';
229 echo '<div title="No data"> </div>';
236 echo "</table></center>\n";
239 function renderNewObjectForm ()
241 global $pageno, $tabno;
243 // Look for current submit.
244 if (isset ($_REQUEST['got_data']))
247 assertUIntArg ('object_type_id', __FUNCTION__
);
248 assertStringArg ('object_name', __FUNCTION__
, TRUE);
249 assertStringArg ('object_label', __FUNCTION__
, TRUE);
250 assertStringArg ('object_barcode', __FUNCTION__
, TRUE);
251 assertStringArg ('object_asset_no', __FUNCTION__
, TRUE);
252 $type_id = $_REQUEST['object_type_id'];
253 $name = $_REQUEST['object_name'];
254 $label = $_REQUEST['object_label'];
255 $asset_no = $_REQUEST['object_asset_no'];
256 $barcode = $_REQUEST['object_barcode'];
258 if (commitAddObject ($name, $label, $barcode, $type_id, $asset_no) === TRUE)
259 $log[] = array ('code' => 'success', 'message' => "Added new object '${name}'");
261 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitAddObject() failed');
265 // Render a form for the next.
266 startPortlet ('Object attributes');
268 echo "<input type=hidden name=page value=${pageno}>";
269 echo "<input type=hidden name=tab value=${tabno}>";
270 echo '<table border=0 align=center>';
271 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
272 $typelist = getObjectTypeList();
273 $typelist[0] = 'select type...';
274 printSelect ($typelist, 'object_type_id', getConfigVar ('DEFAULT_OBJECT_TYPE'));
276 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name></td></tr>\n";
277 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label></td></tr>\n";
278 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no></td></tr>\n";
279 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode></td></tr>\n";
280 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
281 echo '</form></table>';
285 function renderNewRackForm ($row_id)
287 global $pageno, $tabno;
289 // Look for current submit.
290 if (isset ($_REQUEST['got_data']))
293 assertStringArg ('rack_name', __FUNCTION__
);
294 assertUIntArg ('rack_height', __FUNCTION__
);
295 assertStringArg ('rack_comment', __FUNCTION__
, TRUE);
296 $name = $_REQUEST['rack_name'];
297 $height = $_REQUEST['rack_height'];
298 $comment = $_REQUEST['rack_comment'];
300 if (commitAddRack ($name, $height, $row_id, $comment) === TRUE)
301 $log[] = array ('code' => 'success', 'message' => "Added new rack '${name}'");
303 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. 'commitAddRack() failed');
307 // Render a form for the next.
308 startPortlet ('Rack attributes');
310 echo "<input type=hidden name=page value=${pageno}>";
311 echo "<input type=hidden name=tab value=${tabno}>";
312 echo "<input type=hidden name=row_id value=${row_id}>";
313 echo '<table border=0 align=center>';
314 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
317 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td></tr>\n";
318 echo "<tr><th class=tdright>Height in units (required):</th><td class=tdleft><input type=text name=rack_height tabindex=2 value='${defh}'></td></tr>\n";
319 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
320 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
321 echo '</form></table>';
325 function renderEditObjectForm ($object_id)
327 showMessageOrError();
329 if (isset ($_REQUEST['got_data']))
332 // object_id is already verified by page handler
333 assertUIntArg ('object_type_id', __FUNCTION__
);
334 assertStringArg ('object_name', __FUNCTION__
, TRUE);
335 assertStringArg ('object_label', __FUNCTION__
, TRUE);
336 assertStringArg ('object_barcode', __FUNCTION__
, TRUE);
337 assertStringArg ('object_asset_no', __FUNCTION__
, TRUE);
338 $type_id = $_REQUEST['object_type_id'];
339 if (isset ($_REQUEST['object_has_problems']) and $_REQUEST['object_has_problems'] == 'on')
340 $has_problems = 'yes';
342 $has_problems = 'no';
343 $name = $_REQUEST['object_name'];
344 $label = $_REQUEST['object_label'];
345 $barcode = $_REQUEST['object_barcode'];
346 $asset_no = $_REQUEST['object_asset_no'];
347 $comment = $_REQUEST['object_comment'];
349 if (commitUpdateObject ($object_id, $name, $label, $barcode, $type_id, $has_problems, $asset_no, $comment) === TRUE)
350 $log[] = array ('code' => 'success', 'message' => "Updated object '${name}'");
352 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitUpdateObject() failed');
353 // Invalidate thumb cache of all racks objects could occupy.
354 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
355 resetThumbCache ($rack_id);
359 global $pageno, $tabno;
360 $object = getObjectInfo ($object_id);
363 showError ('getObjectInfo() failed', __FUNCTION__
);
367 // Render a form for the next submit;
368 echo '<table border=0 width=100%><tr>';
370 echo '<td class=pcleft>';
371 startPortlet ('Static attributes');
372 echo '<form method=post>';
373 echo "<input type=hidden name=page value=${pageno}>";
374 echo "<input type=hidden name=tab value=${tabno}>";
375 echo "<input type=hidden name=object_id value=${object_id}>";
376 echo '<table border=0 align=center>';
377 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
378 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
380 // Common attributes.
381 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
382 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
383 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";
384 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
385 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
386 if ($object['has_problems'] == 'yes')
388 echo "></td></tr>\n";
389 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
390 echo "<tr><th class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
391 echo '</form></table><br>';
395 // Optional attributes.
396 echo '<td class=pcright>';
397 startPortlet ('Optional attributes');
398 $values = getAttrValues ($object_id);
400 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
401 echo "<tr><th> </th><th>Attribute</th><th>Value</th><th> </th></tr>\n";
402 echo "<form method=post action='${root}process.php'>\n";
403 echo "<input type=hidden name=page value=${pageno}>\n";
404 echo "<input type=hidden name=tab value=${tabno}>\n";
405 echo "<input type=hidden name=op value=upd>\n";
406 echo "<input type=hidden name=object_id value=${object_id}>\n";
407 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
410 foreach ($values as $record)
412 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
414 if (!empty ($record['value']))
416 echo "<a href=${root}process.php?page=${pageno}&tab=${tabno}&op=del&object_id=${object_id}&attr_id=${record['id']}>";
417 printImageHREF ('delete', 'Delete value');
421 printImageHREF ('nodelete', 'Already empty');
423 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
424 switch ($record['type'])
429 echo "<input type=text name=${i}_value value='${record['value']}'>";
432 $chapter = readChapter ($record['chapter_name']);
433 $chapter[0] = '-- NOT SET --';
434 printSelect ($chapter, "${i}_value", $record['key']);
440 echo "<tr><td colspan=3><input type=submit value='Update'></td></tr>\n";
448 echo '<td colspan=2>';
449 startPortlet ('history');
450 renderHistory ($pageno, $object_id);
454 echo '</tr></table>';
457 // This is a clone of renderEditObjectForm().
458 function renderEditRackForm ($rack_id)
461 if (isset ($_REQUEST['got_data']))
464 assertUIntArg ('rack_row_id', __FUNCTION__
);
465 assertUIntArg ('rack_height', __FUNCTION__
);
466 assertStringArg ('rack_name', __FUNCTION__
);
467 assertStringArg ('rack_comment', __FUNCTION__
, TRUE);
468 $row_id = $_REQUEST['rack_row_id'];
469 $height = $_REQUEST['rack_height'];
470 $name = $_REQUEST['rack_name'];
471 $comment = $_REQUEST['rack_comment'];
473 if (commitUpdateRack ($rack_id, $name, $height, $row_id, $comment) === TRUE)
474 $log[] = array ('code' => 'success', 'message' => "Updated rack '${name}'");
476 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitUpdateRack() failed');
477 resetThumbCache ($rack_id);
481 global $pageno, $tabno;
482 $rack = getRackData ($rack_id);
485 showError ('getRackData() failed', __FUNCTION__
);
489 // Render a form for the next.
490 startPortlet ('Rack attributes');
492 echo "<input type=hidden name=page value=${pageno}>";
493 echo "<input type=hidden name=tab value=${tabno}>";
494 echo "<input type=hidden name=rack_id value=${rack_id}>";
495 echo '<table border=0 align=center>';
496 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
497 printSelect (readChapter ('RackRow'), 'rack_row_id', $rack['row_id']);
499 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
500 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
501 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
502 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
503 echo '</form></table><br>';
506 startPortlet ('History');
507 renderHistory ($pageno, $rack_id);
511 // This is a helper for creators and editors.
512 function printSelect ($rowList, $select_name, $selected_id = 1)
514 // First collect all data for OPTGROUPs, then ouput it and dump
515 // the rest of records as is.
518 foreach ($rowList as $dict_key => $dict_value)
520 if (strpos ($dict_value, '^') !== FALSE)
522 $tmp = explode ('^', $dict_value, 2);
523 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
526 $other[$dict_key] = $dict_value;
528 echo "<select name=${select_name}>";
529 if (!count ($optgroup))
531 foreach ($other as $dict_key => $dict_value)
533 echo "<option value=${dict_key}";
534 if ($dict_key == $selected_id)
536 echo ">${dict_value}</option>";
541 foreach ($optgroup as $groupname => $groupdata)
543 echo "<optgroup label='${groupname}'>";
544 foreach ($groupdata as $dict_key => $dict_value)
546 echo "<option value=${dict_key}";
547 if ($dict_key == $selected_id)
549 echo ">${dict_value}</option>";
551 echo "</optgroup>\n";
555 echo "<optgroup label='other'>\n";
556 foreach ($other as $dict_key => $dict_value)
558 echo "<option value=${dict_key}";
559 if ($dict_key == $selected_id)
561 echo ">${dict_value}</option>";
563 echo "</optgroup>\n";
569 // This is a universal editor of rack design/waste.
570 function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
574 showError ('Invalid rack_id', __FUNCTION__
);
577 if (($rackData = getRackData ($rack_id)) == NULL)
579 showError ('getRackData() failed', __FUNCTION__
);
583 global $root, $pageno, $tabno;
585 markupObjectProblems ($rackData);
587 // Process form submit.
588 if (isset ($_REQUEST['do_update']))
590 $log[] = processGridForm ($rackData, $state1, $state2);
594 // Render the result whatever it is.
596 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
597 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
599 // Left column with information portlet.
600 echo "<tr><td class=pcleft height='1%' width='50%'>";
601 startPortlet ('Rack information');
602 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
603 echo "<tr><th width='50%' class=tdright>Rack name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
604 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
605 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
606 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
611 echo "<td class=pcright>";
614 startPortlet ($header);
616 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
617 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
618 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
619 echo "<form method=post action='${root}?'>\n";
620 echo "<input type=hidden name=page value=${pageno}>\n";
621 echo "<input type=hidden name=tab value=${tabno}>\n";
622 echo "<input type=hidden name=rack_id value=${rack_id}>\n";
623 markupAtomGrid ($rackData, $state2);
624 renderAtomGrid ($rackData);
625 echo "</table></center>\n";
626 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
628 echo "</td></tr></table>\n";
631 function renderRackDesign ($rack_id)
633 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
636 function renderRackProblems ($rack_id = 0)
638 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
641 function startPortlet ($title = '')
643 echo "<div class=portlet><h2>${title}</h2>";
646 function finishPortlet ()
651 function printRefsOfType ($refs, $type, $eq)
655 foreach ($refs as $ref)
657 if ($eq($ref['type'], $type))
659 if ($gotone) echo ', ';
660 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
661 if (!empty ($ref['name']))
662 echo $ref['name'] . '@';
663 echo "${ref['object_name']}</a>";
669 function renderRackObject ($object_id = 0)
674 showError ('Invalid object_id', __FUNCTION__
);
677 $info = getObjectInfo ($object_id);
680 showError ('getObjectInfo() failed', __FUNCTION__
);
683 // Main layout starts.
684 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
685 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
686 // left column with uknown number of portlets
687 echo "<tr><td class=pcleft>";
688 startPortlet ('Object information');
689 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
690 if (!empty ($info['name']))
691 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
692 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
693 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
694 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft>${info['objtype_name']}</td></tr>\n";
695 if (!empty ($info['asset_no']))
696 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
697 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('REQUIRE_ASSET_TAG_FOR'))))
698 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
699 if (!empty ($info['label']))
700 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
701 if (!empty ($info['barcode']))
702 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
703 if ($info['has_problems'] == 'yes')
704 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
705 $attrs = getAttrValues ($object_id, TRUE);
706 foreach (getAttrValues ($object_id, TRUE) as $record)
707 if (!empty ($record['value']))
708 echo "<tr><th width='50%' class=opt_attr_th>${record['name']}:</th><td class=tdleft>${record['a_value']}</td></tr>\n";
710 echo "</table><br>\n";
713 if (!empty ($info['comment']))
715 startPortlet ('Comment');
716 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
720 $ports = getObjectPortsAndLinks ($object_id);
723 startPortlet ('Ports and links');
724 usort($ports, 'sortByName');
728 if (isset ($_REQUEST['hl_port_id']))
730 assertUIntArg ('hl_port_id', __FUNCTION__
);
731 $hl_port_id = $_REQUEST['hl_port_id'];
733 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
734 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
735 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
736 foreach ($ports as $port)
739 if ($hl_port_id == $port['id'])
740 echo ' class=port_highlight';
741 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
742 echo "<td>${port['l2address']}</td>";
743 if ($port['remote_object_id'])
745 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
746 echo "<td>${port['remote_name']}</td>";
748 elseif (!empty ($port['reservation_comment']))
750 echo "<td><b>Reserved;</b></td>";
751 echo "<td>${port['reservation_comment']}</td>";
754 echo '<td> </td><td> </td>';
757 echo "</table><br>\n";
761 $addresses = getObjectAddresses ($object_id);
762 usort($addresses, 'sortAddresses');
763 if (count ($addresses))
765 startPortlet ('IPv4 addresses');
766 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
767 echo "<tr><th>Interface name</th><th>IP Address</th><th>Description</th><th>Misc</th></tr>\n";
768 foreach ($addresses as $addr)
770 if (strlen($addr['address_name'])>40)
771 $address_name = substr($addr['address_name'],0,38).'...';
773 $address_name = $addr['address_name'];
775 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
776 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
777 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
778 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
780 if ($addr['address_reserved']=='yes')
782 elseif ($addr['type']!='virtual' && $regnum>0)
784 elseif ($addr['type']=='regular' && $sharednum>0)
789 echo "<tr class='$class'><td class=tdleft>${addr['name']}</td><td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td class='description'>$address_name</td><td class=tdleft>\n";
791 if ($addr['address_reserved']=='yes')
792 echo "<b>Reserved;</b> ";
794 if ($addr['type'] == 'virtual')
800 printRefsOfType($addr['references'], 'virtual', 'neq');
803 elseif ($addr['type'] == 'shared')
809 printRefsOfType($addr['references'], 'shared', 'eq');
815 printRefsOfType($addr['references'], 'virtual', 'eq');
820 echo " Collisions: ";
821 printRefsOfType($addr['references'], 'regular', 'eq');
830 printRefsOfType($addr['references'], 'virtual', 'eq');
835 echo " Collisions: ";
836 printRefsOfType($addr['references'], 'virtual', 'neq');
842 echo "</table><br>\n";
846 $forwards = getObjectForwards ($object_id);
847 if (count($forwards['in']) or count($forwards['out']))
849 startPortlet('NATv4');
851 if (count($forwards['out']))
854 echo "<h3>locally performed NAT</h3>";
856 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
857 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
859 foreach ($forwards['out'] as $pf)
863 foreach ($addresses as $addr)
864 if ($addr['ip'] == $pf['localip'])
871 echo "<tr class='$class'>";
873 echo "<td>${pf['proto']}</td><td class=tdleft>${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
875 echo "<td class=tdleft><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
877 $address=getIPAddress($pf['remoteip']);
879 echo "<td class='description'>";
880 if (count ($address['bonds']))
881 foreach($address['bonds'] as $bond)
882 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
883 elseif (!empty ($pf['remote_addr_name']))
884 echo '(' . $pf['remote_addr_name'] . ')';
886 echo "</td><td class='description'>${pf['description']}</td>";
890 echo "</table><br><br>";
892 if (count($forwards['in']))
894 echo "<h3>arriving NAT connections</h3>";
896 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
897 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
899 foreach ($forwards['in'] as $pf)
902 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
904 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
906 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
907 echo "<td class='description'>${pf['description']}</td></tr>";
910 echo "</table><br><br>";
915 $pools = getRSPoolsForObject ($object_id);
918 startPortlet ('Real server pools');
919 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
920 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
921 foreach ($pools as $vs_id => $info)
923 echo "<tr valign=top><td class=tdleft><a href='${root}?page=vservice&id=${vs_id}'>";
924 echo buildVServiceName ($info);
926 if (!empty ($info['name']))
927 echo " (${info['name']})";
928 echo "</td><td class=tdleft><a href='${root}?page=rspool&pool_id=${info['pool_id']}'>";
929 echo (empty ($info['pool_name']) ?
'ANONYMOUS' : $info['pool_name']);
930 echo '</a></td><td class=tdleft>' . $info['rscount'] . '</td>';
931 echo "<td class=tdleft><pre>${info['vsconfig']}</pre></td>";
932 echo "<td class=tdleft><pre>${info['rsconfig']}</pre></td>";
940 // After left column we have (surprise!) right column with rackspace portled only.
941 echo "<td class=pcright>";
943 startPortlet ('Rackspace allocation');
944 // FIXME: now we call getRackData() twice
945 $racks = getResidentRacksData ($object_id);
946 foreach ($racks as $rackData)
947 renderRack ($rackData['id'], $object_id);
954 function renderRackMultiSelect ($sname, $racks, $selected)
956 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementById(\"racks\").submit()'>\n";
957 foreach ($racks as $rack)
959 echo "<option value=${rack['id']}";
960 if (!(array_search ($rack['id'], $selected) === FALSE))
962 echo">${rack['row_name']}: ${rack['name']}</option>\n";
967 function showMessageOrError ()
969 if (isset($_REQUEST['message']))
970 echo "<div class=msg_success>${_REQUEST['message']}</div>";
971 if (isset($_REQUEST['error']))
972 echo "<div class=msg_error>${_REQUEST['error']}</div>";
975 // This function renders a form for port edition.
976 function renderPortsForObject ($object_id = 0)
978 global $root, $pageno, $tabno;
981 showError ('Invalid object_id', __FUNCTION__
);
984 showMessageOrError();
985 startPortlet ('Ports and interfaces');
986 $ports = getObjectPortsAndLinks ($object_id);
987 usort($ports, 'sortByName');
988 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
989 echo "<tr><th> </th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
990 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th> </th></tr>\n";
991 foreach ($ports as $port)
993 echo "<form action='${root}process.php'>";
994 echo "<input type=hidden name=op value=editPort>";
995 echo "<input type=hidden name=page value='${pageno}'>\n";
996 echo "<input type=hidden name=tab value='${tabno}'>\n";
997 echo "<input type=hidden name=port_id value='${port['id']}'>";
998 echo "<input type=hidden name=object_id value='$object_id'>\n";
999 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']}'>";
1000 printImageHREF ('delete', 'Unlink and Delete this port');
1002 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1003 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
1004 echo "<td>${port['type']}</td>\n";
1005 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1006 if ($port['remote_object_id'])
1008 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
1009 echo "<td>${port['remote_name']}</td>";
1010 echo "<td><a href='${root}process.php?op=unlinkPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=";
1011 echo urlencode ($port['name']);
1012 echo "&remote_port_name=${port['remote_name']}&remote_object_name=${port['remote_object_name']}'>";
1013 printImageHREF ('unlink', 'Unlink this port');
1016 elseif (!empty ($port['reservation_comment']))
1018 echo "<td><b>Reserved;</b></td>";
1019 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1020 echo "<td><a href='${root}process.php?op=useup&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=${object_id}'>";
1021 printImageHREF ('useup', 'Use up this port');
1026 echo "<td> </td><td> </td>";
1028 echo "<a href='javascript:;' onclick='window.open(\"${root}link_helper.php?port=${port['id']}&type=${port['type_id']}&object_id=$object_id&port_name=";
1029 echo urlencode ($port['name']);
1030 echo "\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
1031 printImageHREF ('link', 'Link this port');
1032 echo "</a> <input type=text name=reservation_comment>";
1035 echo "<td><input type='submit' value='OK'></td>";
1036 echo "</form></tr>\n";
1038 echo "<form action='${root}process.php'><tr>";
1039 echo "<td colspan=2><input type=text size=10 name=port_name tabindex=100></td>\n";
1040 echo "<td><input type=text size=24 name=port_label tabindex=101></td>";
1041 echo "<input type=hidden name=op value=addPort>\n";
1042 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1043 echo "<input type=hidden name=page value='${pageno}'>\n";
1044 echo "<input type=hidden name=tab value='${tabno}'>\n";
1045 echo "<td><select name='port_type_id' tabindex=102>\n";
1046 $types = getPortTypes();
1047 $default_port_type = getConfigVar ('default_port_type');
1048 foreach ($types as $typeid => $typename)
1050 echo "<option value='${typeid}'";
1051 if ($typeid == $default_port_type)
1053 echo ">${typename}</option>\n";
1055 echo "</select></td>";
1056 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
1057 echo "<td colspan=4><input type='submit' value='Add a new port' tabindex=104></td></tr></form>";
1058 echo "</table><br>\n";
1061 startPortlet ('Add/update multiple ports');
1062 echo "<form action=${root}process.php method=post>";
1063 echo "<input type=hidden name=page value='${pageno}'>\n";
1064 echo "<input type=hidden name=tab value='${tabno}'>\n";
1065 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1066 echo "<input type=hidden name=op value=addMultiPorts>";
1067 echo 'Format: <select name=format>';
1068 echo '<option value=c2900 disabled>Cisco 2900 series: sh int eth</option>';
1069 echo '<option value=c3600eth disabled>Cisco 3600 ethernet: sh arp | inc -</option>';
1070 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1071 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
1072 echo '<option value=fiedge disabled>Foundry FastIron Edge: sh int br</option>';
1073 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
1074 echo '<option value=ssv1>SSV:<interface name> <MAC address></option>';
1076 echo 'Default port type: ';
1077 echo "<select name=port_type>\n";
1078 foreach ($types as $typeid => $typename)
1080 echo "<option value='${typeid}'";
1081 if ($typeid == $default_port_type)
1083 echo ">${typename}</option>\n";
1086 echo "<input type=submit value='Parse output'><br>\n";
1087 echo "<textarea name=input cols=100 rows=50></textarea><br>\n";
1092 function renderNetworkForObject ($object_id=0)
1094 global $root, $pageno, $tabno;
1095 if ($object_id <= 0)
1097 showError ('Invalid object_id', __FUNCTION__
);
1100 showMessageOrError();
1101 startPortlet ('Network Addresses');
1102 $addresses = getObjectAddresses ($object_id);
1103 usort($addresses, 'sortAddresses');
1104 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1105 echo "<tr><th> </th><th>Interface name</th><th>IP Address</th><th>Description</th><th>Type</th><th>Misc</th><th> </th></tr>\n";
1106 foreach ($addresses as $addr)
1108 if (strlen($addr['address_name'])>40)
1109 $address_name = substr($addr['address_name'],0,38).'...';
1111 $address_name = $addr['address_name'];
1113 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
1114 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
1115 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
1116 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
1118 if ($addr['address_reserved']=='yes')
1120 elseif ($addr['type']!='virtual' && $regnum>0)
1122 elseif ($addr['type']=='regular' && $sharednum>0)
1127 echo "<form action='process.php'>";
1128 echo "<input type=hidden name=page value='${pageno}'>\n";
1129 echo "<input type=hidden name=tab value='${tabno}'>\n";
1130 echo "<input type=hidden name=op value=editAddressFromObject>";
1131 echo "<input type=hidden name=object_id value='$object_id'>";
1132 echo "<input type=hidden name=ip value='${addr['ip']}'>";
1133 echo "<tr class='$class'><td><a href='process.php?op=delAddrFObj&page=${pageno}&tab=${tabno}&ip=${addr['ip']}&object_id=$object_id'>";
1134 printImageHREF ('delete', 'Delete this IPv4 address');
1136 echo "<td><input type='text' name='bond_name' value='${addr['name']}' size=10></td>";
1137 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
1138 echo "<td class='description'>$address_name</td>\n";
1139 echo "<td><select name='bond_type'>";
1140 foreach (array('regular'=>'Regular', 'virtual'=>'Virtual', 'shared'=>'Shared') as $n => $v)
1142 echo "<option value='$n'";
1143 if ($addr['type'] == $n)
1145 echo ">$v</option>";
1148 if ($addr['address_reserved']=='yes')
1149 echo "<b>Reserved</b>; ";
1151 if ($addr['type'] == 'virtual')
1153 if ($notvirtnum > 0)
1156 printRefsOfType($addr['references'], 'virtual', 'neq');
1159 elseif ($addr['type'] == 'shared')
1164 printRefsOfType($addr['references'], 'shared', 'eq');
1170 printRefsOfType($addr['references'], 'virtual', 'eq');
1175 echo " Collisions: ";
1176 printRefsOfType($addr['references'], 'regular', 'eq');
1185 printRefsOfType($addr['references'], 'virtual', 'eq');
1188 if ($notvirtnum > 0)
1190 echo " Collisions: ";
1191 printRefsOfType($addr['references'], 'virtual', 'neq');
1195 echo "</td><td><input type=submit value='OK'></td></form></tr>\n";
1199 echo "<form action='${root}process.php'><tr><td colspan=2><input type='text' size='10' name='name' tabindex=100></td>\n";
1200 echo "<input type=hidden name=page value='${pageno}'>\n";
1201 echo "<input type=hidden name=tab value='${tabno}'>\n";
1202 echo "<input type=hidden name=op value=addAddrFObj>\n";
1203 echo "<input type=hidden name=object_id value='$object_id'>\n";
1205 echo "<td><input type=text name='ip' tabindex=101>\n";
1206 echo "</td><td><select name='type' tabindex=102>";
1207 echo "<option value='regular'>Regular</option>";
1208 echo "<option value='virtual'>Virtual</option>";
1209 echo "<option value='shared'>Shared</option>";
1211 echo "</td><td colspan=3><input type='submit' value='Add a new interface' tabindex=103></td></tr></form>";
1212 echo "</table><br>\n";
1217 function printLog ($log)
1219 foreach ($log as $record)
1220 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1224 The following conditions must be followed:
1225 1. We can mount onto free atoms only. This means: if any record for an atom
1226 already exists in RackSpace, it can't be used for mounting.
1227 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1228 and either delete them before unmounting or refuse to unmount the object.
1231 // We extensively use $_REQUEST in the function.
1232 function renderRackSpaceForObject ($object_id = 0)
1234 if ($object_id <= 0)
1236 showError ('Invalid object_id', __FUNCTION__
);
1239 $is_submit = isset ($_REQUEST['got_atoms']);
1240 $is_update = isset ($_REQUEST['rackmulti'][0]);
1241 $info = getObjectInfo ($object_id);
1244 showError ('getObjectInfo() failed', __FUNCTION__
);
1247 // Always process occupied racks plus racks chosen by user. First get racks with
1248 // already allocated rackspace...
1249 $workingRacksData = getResidentRacksData ($object_id);
1250 if ($workingRacksData === NULL)
1252 print_r ($workingRacksData);
1253 showError ('getResidentRacksData() failed', __FUNCTION__
);
1257 // ...and then add those chosen by user (if any).
1259 foreach ($_REQUEST['rackmulti'] as $cand_id)
1261 if (!isset ($workingRacksData[$cand_id]))
1263 $rackData = getRackData ($cand_id);
1264 if ($rackData == NULL)
1266 showError ('getRackData() failed', __FUNCTION__
);
1269 $workingRacksData[$cand_id] = $rackData;
1273 // Do it only once...
1274 foreach ($workingRacksData as &$rackData)
1275 applyObjectMountMask ($rackData, $object_id);
1276 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1279 // Here we process form submit by trying to save all submitted info to database.
1282 $oldMolecule = getMoleculeForObject ($object_id);
1283 $worldchanged = FALSE;
1285 foreach ($workingRacksData as $rack_id => $rackData)
1287 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1288 $log[] = $logrecord;
1289 if ($logrecord['code'] != 300)
1291 $worldchanged = TRUE;
1292 // Reload our working copy after form processing.
1293 $rackData = getRackData ($rack_id);
1294 if ($rackData == NULL)
1295 $log[] = array ('code' => 500, 'message' => 'Working copy update failed in ', __FUNCTION__
);
1296 applyObjectMountMask ($rackData, $object_id);
1297 $workingRacksData[$rack_id] = $rackData;
1303 $newMolecule = getMoleculeForObject ($object_id);
1304 $oc = count ($oldMolecule);
1305 $nc = count ($newMolecule);
1306 $omid = $oc ?
createMolecule ($oldMolecule) : 'NULL';
1307 $nmid = $nc ?
createMolecule ($newMolecule) : 'NULL';
1308 global $remote_username;
1309 $comment = empty ($_REQUEST['comment']) ?
'NULL' : "'${_REQUEST['comment']}'";
1311 "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
1312 "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
1314 $result = $dbxlink->query ($query);
1315 if ($result == NULL)
1316 $log[] = array ('code' => 'error', 'message' => 'SQL query failed during history logging.');
1318 $log[] = array ('code' => 'success', 'message' => 'History logged.');
1323 // This is the time for rendering.
1324 global $root, $pageno, $tabno;
1325 echo "<form id='racks' action='${root}'>";
1326 echo "<input type=hidden name=page value='${pageno}'>\n";
1327 echo "<input type=hidden name=tab value='${tabno}'>\n";
1328 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1329 // Main layout starts.
1330 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1332 // Left portlet with rack list.
1333 echo "<td class=pcleft height='1%'>";
1334 startPortlet ('Racks');
1335 $allRacksData = getRacksForRow();
1336 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1338 foreach (array_keys ($allRacksData) as $rack_id)
1340 $rackData = getRackData ($rack_id);
1341 if ($rackData == NULL)
1343 showError ('getRackData() failed', __FUNCTION__
);
1346 $workingRacksData[$rack_id] = $rackData;
1348 foreach ($workingRacksData as &$rackData)
1349 applyObjectMountMask ($rackData, $object_id);
1352 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1358 // Middle portlet with comment and submit.
1359 echo "<td class=pcleft>";
1360 startPortlet ('Comment');
1361 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1362 echo "<input type=submit value='Save' name=got_atoms>\n";
1368 // Right portlet with rendered racks. If this form submit is not final, we have to
1369 // reflect the former state of the grid in current form.
1370 echo "<td class=pcright rowspan=2 height='1%'>";
1371 startPortlet ('Working copy');
1372 echo '<table border=0 cellspacing=10 align=center><tr>';
1373 foreach ($workingRacksData as $rack_id => $rackData)
1375 // Order is important here: only original allocation is highlighted.
1376 highlightObject ($rackData, $object_id);
1377 markupAtomGrid ($rackData, 'T');
1378 // If we have a form processed, discard user input and show new database
1380 if (!$is_submit and $is_update)
1381 mergeGridFormToRack ($rackData);
1382 echo "<td valign=top>";
1383 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1384 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1385 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1386 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1387 renderAtomGrid ($rackData);
1388 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1389 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1390 echo "</table></center>\n";
1393 echo "</tr></table>";
1398 echo "</tr></table>\n";
1401 function renderMolecule ($mdata, $object_id)
1404 $rackpack = array();
1406 foreach ($mdata as $dummy => $rua)
1408 $rack_id = $rua['rack_id'];
1409 $unit_no = $rua['unit_no'];
1410 $atom = $rua['atom'];
1411 if (!isset ($rackpack[$rack_id]))
1413 $rackData = getRackData ($rack_id);
1414 for ($i = $rackData['height']; $i > 0; $i--)
1415 for ($locidx = 0; $locidx < 3; $locidx++
)
1416 $rackData[$i][$locidx]['state'] = 'F';
1417 $rackpack[$rack_id] = $rackData;
1419 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1420 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1422 // now we have some racks to render
1423 foreach ($rackpack as $dummy => $rackData)
1425 markAllSpans ($rackData);
1426 echo "<table class=molecule cellspacing=0>\n";
1427 echo "<caption>${rackData['name']}</caption>\n";
1428 echo "<tr><th width='10%'> </th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1429 for ($i = $rackData['height']; $i > 0; $i--)
1431 echo "<tr><th>$i</th>";
1432 for ($locidx = 0; $locidx < 3; $locidx++
)
1434 $state = $rackData[$i][$locidx]['state'];
1435 echo "<td class=state_${state}> </td>\n";
1443 function renderUnmountedObjectsPortlet ()
1445 startPortlet ('Unmounted objects');
1446 $objs = getUnmountedObjects();
1449 showError ('getUnmountedObjects() failed', __FUNCTION__
);
1452 global $root, $nextorder;
1454 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1455 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
1456 foreach ($objs as $obj)
1458 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1459 echo "<td>${obj['label']}</td>";
1460 echo "<td>${obj['asset_no']}</td>";
1461 echo "<td>${obj['barcode']}</td></tr>";
1462 $order = $nextorder[$order];
1464 echo "</table><br>\n";
1468 function renderProblematicObjectsPortlet ()
1470 startPortlet ('Problematic objects');
1471 $objs = getProblematicObjects();
1474 showError ('getProblematicObjects() failed', __FUNCTION__
);
1477 global $root, $nextorder;
1479 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1480 echo '<tr><th>Type</th><th>Common name</th></tr>';
1481 foreach ($objs as $obj)
1483 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1484 echo "<td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></tr>";
1485 $order = $nextorder[$order];
1487 echo "</table><br>\n";
1491 function renderObjectGroupSummary ()
1494 $tagfilter = isset ($_REQUEST['tagfilter']) ?
$_REQUEST['tagfilter'] : array();
1495 $tagfilter = complementByKids ($tagfilter);
1496 $summary = getObjectGroupInfo();
1497 if ($summary === NULL)
1499 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1502 echo "<table border=0 class=objectview>\n";
1503 echo "<tr><td class=pcleft width='25%'>";
1505 startPortlet ('Summary');
1506 foreach ($summary as $gi)
1507 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1510 echo '</td><td class=pcright>';
1511 renderUnmountedObjectsPortlet();
1512 echo '</td><td class=pcright>';
1513 renderProblematicObjectsPortlet();
1514 echo '</td><td class=pcright>';
1515 startPortlet ('Tag filter');
1516 renderTagFilterSelect ($tagfilter, 'object');
1518 echo "</td></tr></table>\n";
1521 function renderObjectSpace ()
1523 global $root, $taglist, $tagtree;
1524 echo "<table border=0 class=objectview>\n";
1525 echo "<tr><td class=pcleft width='50%'>";
1526 startPortlet ('View all by type');
1527 $groupInfo = getObjectGroupInfo();
1528 if ($groupInfo === NULL)
1530 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1533 if (count ($groupInfo) == 0)
1534 echo "No objects exist in DB";
1537 echo '<div align=left><ul>';
1538 foreach ($groupInfo as $gi)
1539 echo "<li><a href='${root}?page=objgroup&group_id=${gi['id']}'>${gi['name']}</a> (${gi['count']})</li>";
1544 echo '</td><td class=pcright>';
1546 startPortlet ('View all by tag');
1547 if (count ($taglist) == 0)
1548 echo "No tags exist in DB";
1550 renderTagCloud ('object');
1552 echo "</td></tr></table>\n";
1555 function renderObjectGroup ()
1557 global $root, $pageno, $tabno, $nextorder, $taglist, $tagtree;
1558 assertUIntArg ('group_id', __FUNCTION__
, TRUE);
1559 $group_id = $_REQUEST['group_id'];
1560 $tagfilter = isset ($_REQUEST['tagfilter']) ?
$_REQUEST['tagfilter'] : array();
1561 $tagfilter_str = getStringFromTrail (getExplicitTagsOnly (buildTrailFromIds ($tagfilter)));
1562 $tagfilter = complementByKids ($tagfilter);
1564 echo "<input type=hidden name=page value=${pageno}>\n";
1565 echo "<input type=hidden name=group_id value=${group_id}>\n";
1566 echo "<table border=0 class=objectview>\n";
1567 echo "<tr><td class=pcleft width='25%'>";
1568 startPortlet ('change type');
1569 $groupInfo = getObjectGroupInfo();
1570 if ($groupInfo === NULL)
1572 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1575 if (count ($groupInfo) == 0)
1576 echo "No objects exist in DB";
1579 echo '<div align=left><ul>';
1580 foreach ($groupInfo as $gi)
1582 echo "<li><a href='${root}?page=${pageno}&group_id=${gi['id']}&tagfilter[]=${tagfilter_str}'>";
1583 if ($gi['id'] == $group_id)
1585 echo "${gi['name']}</a>";
1586 if ($gi['id'] == $group_id)
1588 echo " (${gi['count']})";
1589 if ($gi['id'] == $group_id)
1597 echo '</td><td class=pcleft>';
1599 startPortlet ('Objects');
1600 $objects = getObjectList ($group_id, $tagfilter);
1601 if ($objects === NULL)
1603 showError ('getObjectList() failed', __FUNCTION__
);
1606 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1607 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
1609 foreach ($objects as $obj)
1611 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1612 echo "<td>${obj['label']}</td>";
1613 echo "<td>${obj['asset_no']}</td>";
1614 echo "<td>${obj['barcode']}</td>";
1615 if ($obj['rack_id'])
1616 echo "<td><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
1618 echo '<td>Unmounted</td>';
1620 $order = $nextorder[$order];
1625 echo "</td><td class=pcright width='25%'>";
1627 startPortlet ('change filter');
1628 renderTagFilterSelect ($tagfilter, 'object');
1629 echo "<input type=submit value='Apply'>\n";
1631 echo "</td></tr></table>\n";
1635 function renderObjectGroup_old ()
1638 assertUIntArg ('group_id', __FUNCTION__
);
1639 $group_id = $_REQUEST['group_id'];
1640 $summary = getObjectGroupInfo();
1641 if ($summary == NULL)
1643 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1646 $objects = getObjectList ($group_id);
1647 if ($objects === NULL)
1649 showError ('getObjectList() failed', __FUNCTION__
);
1652 echo "<table border=0 class=objectview>\n";
1653 echo "<tr><td class=pcleft width='25%'>";
1655 startPortlet ('All objects');
1656 foreach ($summary as $gi)
1658 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1662 echo '</td><td class=pcright>';
1664 startPortlet ('Object group');
1665 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1666 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
1669 foreach ($objects as $obj)
1671 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1672 echo "<td>${obj['label']}</td>";
1673 echo "<td>${obj['asset_no']}</td>";
1674 echo "<td>${obj['barcode']}</td>";
1675 if ($obj['rack_id'])
1676 echo "<td><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
1678 echo '<td>Unmounted</td>';
1680 $order = $nextorder[$order];
1685 echo "</td></tr></table>";
1688 function renderEmptyPortsSelect ($port_id, $type_id)
1690 $ports = getEmptyPortsOfType($type_id);
1691 usort($ports, 'sortEmptyPorts');
1692 foreach ($ports as $port)
1694 if ($port_id == $port['Port_id'])
1696 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";
1700 function renderObjectAddressesAndNames ()
1702 $addresses = getObjectAddressesAndNames();
1703 usort($addresses, 'sortObjectAddressesAndNames');
1704 foreach ($addresses as $address)
1706 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1710 // History viewer for history-enabled simple dictionaries.
1711 function renderHistory ($object_type, $object_id)
1713 switch ($object_type)
1716 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1717 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1722 "select ctime, user_name, rh.name, rh.deleted, d.dict_value as name, rh.height, rh.comment " .
1723 "from RackHistory as rh left join Dictionary as d on rh.row_id = d.dict_key " .
1724 "natural join Chapter " .
1725 "where chapter_name = 'RackRow' and rh.id = ${object_id} order by ctime";
1726 $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>';
1731 "select ctime, user_name, name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1732 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key natural join Chapter " .
1733 "where chapter_name = 'RackObjectType' and id=${object_id} order by ctime";
1734 $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>';
1738 showError ("Uknown object type '${object_type}'", __FUNCTION__
);
1742 $result = $dbxlink->query ($query);
1743 if ($result == NULL)
1745 showError ('SQL query failed', __FUNCTION__
);
1748 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1752 while ($row = $result->fetch (PDO
::FETCH_NUM
))
1754 echo "<tr class=row_${order}><td>${row[0]}</td>";
1755 for ($i = 1; $i <= $extra; $i++
)
1756 echo "<td>" . $row[$i] . "</td>";
1758 $order = $nextorder[$order];
1760 echo "</table><br>\n";
1763 function renderRackspaceHistory ()
1765 global $root, $nextorder, $pageno, $tabno;
1767 $history = getRackspaceHistory();
1768 // Show the last operation by default.
1769 if (isset ($_REQUEST['op_id']))
1770 $op_id = $_REQUEST['op_id'];
1771 elseif (isset ($history[0]['mo_id']))
1772 $op_id = $history[0]['mo_id'];
1779 list ($omid, $nmid) = getOperationMolecules ($op_id);
1781 // Main layout starts.
1782 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1784 // Left top portlet with old allocation.
1785 echo "<tr><td class=pcleft>";
1786 startPortlet ('Old allocation');
1789 $oldMolecule = getMolecule ($omid);
1790 renderMolecule ($oldMolecule, $object_id);
1796 echo '</td><td class=pcright>';
1798 // Right top portlet with new allocation
1799 startPortlet ('New allocation');
1802 $newMolecule = getMolecule ($nmid);
1803 renderMolecule ($newMolecule, $object_id);
1809 echo '</td></tr><tr><td colspan=2>';
1811 // Bottom portlet with list
1813 startPortlet ('Rackspace allocation history');
1814 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1815 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";
1816 foreach ($history as $row)
1818 if ($row['mo_id'] == $op_id)
1821 $class = "row_${order}";
1822 echo "<tr class=${class}><td><a href='${root}?page=${pageno}&tab=${tabno}&op_id=${row['mo_id']}'>${row['ctime']}</a></td>";
1823 echo "<td>${row['user_name']}</td>";
1824 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1826 $order = $nextorder[$order];
1831 echo '</td></tr></table>';
1835 function renderAddressspace ()
1837 global $root, $page;
1839 echo "<table border=0 class=objectview>\n";
1840 echo "<tr><td class=pcleft>";
1842 startPortlet ('Subnets');
1843 echo "<table class='widetable' border=0 cellpadding=10 cellspacing=0 align='center'>\n";
1844 $tagfilter = isset ($_REQUEST['tagfilter']) ?
$_REQUEST['tagfilter'] : array();
1845 $tagfilter = complementByKids ($tagfilter);
1846 $addrspaceList = getAddressspaceList ($tagfilter);
1847 echo "<tr><th>Subnet</th><th>Name</th><th>Utilization</th></tr>";
1848 foreach ($addrspaceList as $iprange)
1850 $range = getIPRange ($iprange['id']);
1851 $total = ($iprange['ip_bin'] |
$iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) +
1;
1852 $used = count ($range['addrlist']);
1853 echo "<tr><td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td>";
1854 echo "<td class=tdleft>${iprange['name']}</td><td class=tdleft>";
1855 renderProgressBar ($used/$total);
1856 echo " ${used}/${total}</td></tr>";
1860 echo '</td><td class=pcright>';
1861 renderTagFilterPortlet ($tagfilter, 'ipv4net');
1862 echo "</td></tr></table>\n";
1865 function renderIPv4SLB ()
1867 global $root, $page, $nextorder;
1869 startPortlet ('SLB configuration');
1870 echo "<table border=0 width='100%'><tr>";
1871 foreach (array ('vservices', 'rspools', 'rservers', 'lbs') as $pno)
1872 echo "<td><h3><a href='${root}?page=${pno}'>" . $page[$pno]['title'] . "</a></h3></td>";
1873 echo '</tr></table>';
1876 $summary = getSLBSummary();
1877 startPortlet ('SLB tactical overview');
1878 // A single id-keyed array isn't used here to preserve existing
1879 // order of LBs returned by getSLBSummary()
1882 foreach ($summary as $vipdata)
1883 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
1884 if (!in_array ($lb_object_id, $lblist))
1886 $oi = getObjectInfo ($lb_object_id);
1887 $lbdname[$lb_object_id] = $oi['dname'];
1888 $lblist[] = $lb_object_id;
1890 if (!count ($summary))
1891 echo 'none configured';
1895 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
1896 echo "<tr><th>VS ↓ LB →</th>";
1897 foreach ($lblist as $lb_object_id)
1898 echo "<th><a href='${root}?page=object&tab=default&object_id=${lb_object_id}'>" . $lbdname[$lb_object_id] . "</a></th>";
1900 foreach ($summary as $vsid => $vsdata)
1902 echo "<tr class=row_${order}><td class=tdleft><a href='$root?page=vservice&tab=default&id=${vsid}'>";
1903 echo buildVServiceName ($vsdata);
1905 if (!empty ($vsdata['name']))
1906 echo " (${vsdata['name']})";
1908 foreach ($lblist as $lb_object_id)
1910 echo '<td class=tdleft>';
1911 if (!isset ($vsdata['lblist'][$lb_object_id]))
1915 echo $vsdata['lblist'][$lb_object_id]['size'];
1916 echo " (<a href='${root}?page=rspool&pool_id=";
1917 echo $vsdata['lblist'][$lb_object_id]['id'] . "'>";
1918 echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
1923 $order = $nextorder[$order];
1930 function renderAddNewRange ()
1932 global $root, $pageno, $tabno;
1933 showMessageOrError();
1935 startPortlet ("Add New");
1936 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
1937 echo "<tr><th>Address range</th><th>Name</th><th>connected network</th><th>assign tags</th><th> </th></tr>\n";
1938 echo "<form name='add_new_range' action='process.php'>\n";
1939 echo "<input type=hidden name=op value=addRange>\n";
1940 echo "<input type=hidden name=page value='${pageno}'>\n";
1941 echo "<input type=hidden name=tab value='${tabno}'>\n";
1942 echo "<tr valign=top><td class='tdcenter'><input type=text name='range' size=18 class='live-validate' tabindex=1></td>\n";
1943 echo "<td class='tdcenter'><input type=text name='name' size='20' tabindex=2></td>\n";
1944 echo "<td class='tdcenter'><input type=checkbox name='is_bcast' tabindex=3 checked></td>\n";
1948 echo "<td class='tdcenter'><input type=submit value='Add a new range' tabindex=4></td>\n";
1949 echo "</td></tr>\n";
1950 echo "</form></table><br><br>\n";
1953 startPortlet ("Manage Existing");
1954 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
1955 $addrspaceList = getAddressspaceList();
1956 echo "<tr><th> </th><th>Address range</th><th>Name</th><th>Utilization</th></tr>";
1957 foreach ($addrspaceList as $iprange)
1959 $range = getIPRange($iprange['id']);
1960 $usedips = count ($range['addrlist']);
1961 $totalips = ($iprange['ip_bin'] |
$iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) +
1;
1965 echo "<a href='process.php?op=delRange&page=${pageno}&tab=${tabno}&id=${iprange['id']}'>";
1966 printImageHREF ('delete', 'Delete this IP range');
1970 printImageHREF ('nodelete', 'There are IP addresses allocated or reserved');
1971 echo "</td>\n<td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>";
1972 echo "${iprange['ip']}/${iprange['mask']}</a></td><td class=tdleft>${iprange['name']}";
1973 echo "</td><td class=tdleft>";
1974 renderProgressBar ($usedips / $totalips);
1975 echo " ${usedips}/${totalips}";
1982 function renderIPRange ($id)
1984 global $root, $pageno, $tabno;
1985 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
1986 if (isset($_REQUEST['pg']))
1987 $page = $_REQUEST['pg'];
1991 $range = getIPRange($id);
1992 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1993 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
1995 echo "<tr><td class=pcleft width='50%'>";
1996 startPortlet ('summary');
1997 $total = ($range['ip_bin'] |
$range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) +
1;
1998 $used = count ($range['addrlist']);
1999 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2000 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
2001 renderProgressBar ($used/$total);
2002 echo " ${used}/${total}</td></tr>\n";
2004 echo "</table><br>\n";
2008 echo "<td class=pcright>";
2009 startPortlet ('details');
2010 $startip = $range['ip_bin'] & $range['mask_bin'];
2011 $endip = $range['ip_bin'] |
$range['mask_bin_inv'];
2012 $realstartip = $startip;
2013 $realendip = $endip;
2015 if($endip - $startip > $maxperpage)
2017 $numpages = ($endip - $startip)/$maxperpage;
2018 $startip = $startip +
$page * $maxperpage;
2019 $endip = $startip +
$maxperpage-1;
2023 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
2024 for ($i=0; $i<$numpages; $i++
)
2029 echo "<a href='${root}?page=${pageno}&tab=${tabno}&id=$id&pg=$i'>$i</a> ";
2033 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n";
2034 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2037 for($ip = $startip; $ip<=$endip; $ip++
)
2039 if (isset ($range['addrlist'][$ip]))
2041 $numshared = countRefsOfType($range['addrlist'][$ip]['references'], 'shared', 'eq');
2042 $numreg = countRefsOfType($range['addrlist'][$ip]['references'], 'regular', 'eq');
2043 $numvirt = countRefsOfType($range['addrlist'][$ip]['references'], 'virtual', 'eq');
2044 $numlb = count ($range['addrlist'][$ip]['lbrefs']);
2045 $numrs = count ($range['addrlist'][$ip]['rsrefs']);
2047 $addr = $range['addrlist'][$ip];
2048 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2049 echo "<tr class='trerror'>";
2050 elseif ( $addr['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt+
$numlb+
$numrs > 0)
2051 echo "<tr class='trerror'>";
2052 elseif ( $addr['reserved'] == 'yes')
2053 echo "<tr class='trbusy'>";
2054 elseif ( $numshared > 0 ||
$numreg > 0 ||
$numlb > 0 ||
$numrs > 0)
2055 echo "<tr class='trbusy'>";
2059 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td>${addr['name']}</td><td>";
2062 if ( $addr['reserved'] == 'yes')
2064 echo "<b>Reserved</b> ";
2067 foreach ($range['addrlist'][$ip]['references'] as $ref)
2069 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
2070 echo $ref['name'] . (empty ($ref['name']) ?
'' : '@');
2071 echo "${ref['object_name']}</a>";
2079 foreach ($range['addrlist'][$ip]['lbrefs'] as $ref)
2083 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
2084 echo "${ref['object_name']}</a>:<a href='${root}?page=vservice&id=${ref['vs_id']}'>";
2085 echo "${ref['vport']}/${ref['proto']}</a>→";
2093 foreach ($range['addrlist'][$ip]['rsrefs'] as $ref)
2097 echo "${delim}→${ref['rsport']}@<a href='${root}?page=rspool&pool_id=${ref['rspool_id']}'>";
2098 echo "${ref['rspool_name']}</a>";
2101 echo "</td></tr>\n";
2105 echo "<tr><td><a href='${root}?page=ipaddress&ip=".long2ip($ip)."'>".long2ip($ip)."</a></td><td> </td><td> </td></tr>\n";
2111 echo "</td></tr></table>\n";
2114 function renderIPRangeProperties ($id)
2116 global $pageno, $tabno;
2117 showMessageOrError();
2118 $range = getIPRange($id);
2119 echo "<center><h1>${range['ip']}/${range['mask']}</h1></center>\n";
2120 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2121 echo "<form action='process.php'><input type=hidden name=op value=editRange>";
2122 echo "<input type=hidden name=page value='${pageno}'>\n";
2123 echo "<input type=hidden name=tab value='${tabno}'>\n";
2124 echo "<input type=hidden name=id value='${id}'>";
2125 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>";
2130 function renderIPAddress ()
2133 $ip = $_REQUEST['ip'];
2134 $address = getIPAddress($ip);
2135 echo "<center><h1>$ip</h1>";
2136 if ($address['exists'] == 1)
2137 echo "<h2>${address['name']}</h2>";
2140 // echo "<table width='100%' cesspadding=5 cellspacing=0 border=0 align='center'>";
2141 // echo "<tr valign='top'><td>";
2143 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
2144 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
2145 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
2147 if ($address['reserved'] == 'yes' or ($numshared +
$numreg +
$numvirt) > 0)
2149 startPortlet ('Allocation');
2150 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2151 echo "<tr><th>Object name</th><th>Interface name</th><th>Interface type</th></tr>\n";
2152 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2154 elseif ( $address['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt > 0)
2159 if ($address['reserved'] == 'yes')
2160 echo "<tr class='$class'><td colspan='3'><b>RESERVED</b></td></tr>";
2161 foreach ($address['bonds'] as $bond)
2163 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>";
2164 switch ($bond['type'])
2176 echo "</b></td></tr>\n";
2178 echo "</table><br><br>";
2182 if (count ($address['vslist']))
2184 startPortlet ('Virtual services (' . count ($address['vslist']) . ')');
2185 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2186 echo "<tr><th>VS</th><th>name</th></tr>\n";
2187 foreach ($address['vslist'] as $vsinfo)
2189 echo "<tr><td class=tdleft><a href='${root}?page=vservice&id=${vsinfo['id']}'>";
2190 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
2191 echo $vsinfo['name'] . "</td></tr>\n";
2193 echo "</table><br><br>";
2197 if (count ($address['rslist']))
2199 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2200 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2201 echo "<tr><th> </th><th>port</th><th>RS pool</th></tr>\n";
2202 foreach ($address['rslist'] as $rsinfo)
2205 if ($rsinfo['inservice'] == 'yes')
2206 printImageHREF ('inservice', 'in service');
2208 printImageHREF ('notinservice', 'NOT in service');
2209 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='${root}?page=rspool&pool_id=${rsinfo['pool_id']}'>";
2210 echo $rsinfo['poolname'] . "</a></td></tr>\n";
2212 echo "</table><br><br>";
2217 // echo "</td><td>";
2218 // echo "</td></tr></table>";
2221 function renderIPAddressProperties ()
2223 global $pageno, $tabno;
2224 $ip = $_REQUEST['ip'];
2225 showMessageOrError();
2226 $address = getIPAddress($ip);
2227 echo "<center><h1>$ip</h1></center>\n";
2228 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2229 echo "<form action='process.php'><input type=hidden name=op value=editAddress>";
2230 echo "<input type=hidden name=page value='${pageno}'>\n";
2231 echo "<input type=hidden name=tab value='${tabno}'>\n";
2232 echo "<input type=hidden name=ip value='${ip}'>";
2233 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='".($address['exists']==1?
$address['name']:'')."'></tr>";
2234 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ".($address['exists']==1?
(($address['reserved']=='yes')?
'checked':''):'')."></tr>";
2235 echo "<tr><td colspan=2 class='tdcenter'><input type=submit value='Update address'></td></form></tr>";
2240 function renderIPAddressAssignment ()
2242 global $pageno, $tabno, $root;
2243 $ip = $_REQUEST['ip'];
2244 $address = getIPAddress($ip);
2246 showMessageOrError();
2247 echo "<center><h1>$ip</h1></center>\n";
2250 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2251 echo "<tr><th> </th><th>Object name</th><th>Interface name</th><th>Interface type</th><th> </th></tr>\n";
2253 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
2254 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
2255 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
2258 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2260 elseif ( $address['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt > 0)
2267 if ($address['reserved'] == 'yes')
2268 echo "<tr class='$class'><td colspan='5'><b>RESERVED</b></td></tr>";
2269 foreach ($address['bonds'] as $bond)
2271 echo "<tr class='$class'><form action='process.php'>";
2272 echo "<input type=hidden name=op value='editBondForAddress'>";
2273 echo "<input type=hidden name=page value='${pageno}'>";
2274 echo "<input type=hidden name=tab value='${tabno}'>";
2275 echo "<input type=hidden name=ip value='$ip'>";
2276 echo "<input type=hidden name=object_id value='${bond['object_id']}'>";
2277 echo "<td><a href='process.php?op=delIpAssignment&page=${pageno}&tab=${tabno}&ip=$ip&object_id=${bond['object_id']}'>";
2278 printImageHREF ('delete', 'Unallocate address');
2280 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td>";
2281 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td>";
2282 echo "<td><select name='bond_type'>";
2283 switch ($bond['type'])
2286 echo "<option value='regular'>Regular</option>";
2287 echo "<option value='virtual' selected>Virtual</option>";
2288 echo "<option value='shared'>Shared</option>";
2291 echo "<option value='regular'>Regular</option>";
2292 echo "<option value='virtual'>Virtual</option>";
2293 echo "<option value='shared' selected>Shared</option>";
2296 echo "<option value='regular' selected>Regular</option>";
2297 echo "<option value='virtual'>Virtual</option>";
2298 echo "<option value='shared'>Shared</option>";
2301 echo "</select></td><td><input type='submit' value='OK'></td></form></tr>\n";
2303 echo "<form action='process.php'><input type='hidden' name='op' value='bindObjectToIp'>";
2304 echo "<input type=hidden name=page value='${pageno}'>\n";
2305 echo "<input type=hidden name=tab value='${tabno}'>\n";
2306 echo "<input type='hidden' name='ip' value='$ip'>";
2307 echo "<td colspan=2><select name='object_id'>";
2309 foreach (explode (',', getConfigVar ('IPV4_PERFORMERS')) as $type)
2310 foreach (getObjectList ($type) as $object)
2311 echo "<option value='${object['id']}'>${object['dname']}</option>";
2313 echo "</select></td><td><input type='text' name='bond_name' value='' size=10></td>";
2314 echo "<td><select name='bond_type'><option value='regular'>Regular</option><option value='virtual'>Virtual</option><option value='shared'>Shared</option></select></td>";
2315 echo "<td><input type='submit' value='Assign address'></td></form></tr>";
2316 echo "</table><br><br>";
2320 function renderIPAddressPortForwarding ($object_id=0)
2322 global $pageno, $tabno, $root;
2324 $info = getObjectInfo ($object_id);
2325 $forwards = getObjectForwards ($object_id);
2326 $addresses = getObjectAddresses ($object_id);
2327 showMessageOrError();
2328 echo "<center><h2>locally performed NAT</h2></center>";
2330 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2331 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th></tr>\n";
2333 foreach ($forwards['out'] as $pf)
2337 foreach ($addresses as $addr)
2338 if ($addr['ip'] == $pf['localip'])
2341 $name = $addr['name'];
2345 echo "<tr class='$class'>";
2346 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}'>";
2347 printImageHREF ('delete', 'Delete NAT rule');
2349 echo "<td>${pf['proto']}/${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
2350 if (!empty ($pf['local_addr_name']))
2351 echo ' (' . $pf['local_addr_name'] . ')';
2353 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2355 $address=getIPAddress($pf['remoteip']);
2357 echo "<td class='description'>";
2358 if (count ($address['bonds']))
2359 foreach($address['bonds'] as $bond)
2360 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
2361 elseif (!empty ($pf['remote_addr_name']))
2362 echo '(' . $pf['remote_addr_name'] . ')';
2363 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>";
2366 echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2367 echo "<input type='hidden' name='object_id' value='$object_id'>";
2368 echo "<input type=hidden name=page value='${pageno}'>\n";
2369 echo "<input type=hidden name=tab value='${tabno}'>\n";
2370 echo "<tr align='center'><td colspan=2>";
2371 printSelect (readChapter ('Protocols'), 'proto');
2372 echo "<select name='localip' tabindex=1>";
2374 foreach ($addresses as $addr)
2375 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ?
'' : "${addr['name']}: ") .
2376 "${addr['ip']}" . (empty ($addr['address_name']) ?
'' : " (${addr['address_name']})") . "</option>";
2378 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2379 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
2380 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\");'>";
2381 printImageHREF ('find', 'Find object');
2383 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2384 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5> <input type='submit' value='Create Forwarding' tabindex=6></td></tr>";
2387 echo "</table><br><br>";
2390 echo "<center><h2>arriving NAT connections</h2></center>";
2391 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2392 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2394 foreach ($forwards['in'] as $pf)
2398 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}'>";
2399 printImageHREF ('delete', 'Delete NAT rule');
2401 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2402 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2403 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2404 echo "<td class='description'>${pf['description']}</td></tr>";
2407 // echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2408 // echo "<input type='hidden' name='object_id' value='$object_id'>";
2409 // echo "<input type=hidden name=page value='${pageno}'>\n";
2410 // echo "<input type=hidden name=tab value='${tabno}'>\n";
2411 // 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'>";
2412 // foreach ($addresses as $addr)
2413 // echo "<option value='${addr['ip']}'>${addr['ip']}</option>";
2415 // 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>";
2417 echo "</table><br><br>";
2423 function renderAddMultipleObjectsForm ()
2425 global $root, $pageno, $tabno, $nextorder;
2428 $global_type_id = 0;
2430 $asset_no = array();
2431 $keepvalues = FALSE;
2433 // Look for current submit.
2434 if (isset ($_REQUEST['got_fast_data']))
2437 $max = getConfigVar ('MASSCOUNT');
2438 for ($i = 0; $i < $max; $i++
)
2440 if (!isset ($_REQUEST["${i}_object_type_id"]))
2442 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i +
1);
2445 assertUIntArg ("${i}_object_type_id", __FUNCTION__
, TRUE);
2446 assertStringArg ("${i}_object_name", __FUNCTION__
, TRUE);
2447 assertStringArg ("${i}_object_label", __FUNCTION__
, TRUE);
2448 assertStringArg ("${i}_object_asset_no", __FUNCTION__
, TRUE);
2449 assertStringArg ("${i}_object_barcode", __FUNCTION__
, TRUE);
2450 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2451 // Save user input for possible rendering.
2452 $name[$i] = $_REQUEST["${i}_object_name"];
2453 $label[$i] = $_REQUEST["${i}_object_label"];
2454 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2455 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2457 // It's better to skip silently than printing a notice.
2458 if ($type_id[$i] == 0)
2460 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i]) === TRUE)
2461 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2463 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitAddObject() failed');
2466 elseif (isset ($_REQUEST['got_very_fast_data']))
2469 assertUIntArg ('global_type_id', __FUNCTION__
, TRUE);
2470 assertStringArg ('namelist', __FUNCTION__
, TRUE);
2471 $global_type_id = $_REQUEST['global_type_id'];
2472 if ($global_type_id == 0)
2474 if (!empty ($_REQUEST['namelist']))
2475 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2477 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2481 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2482 $names1 = explode ('\n', $_REQUEST['namelist']);
2484 foreach ($names1 as $line)
2486 $parts = explode ('\r', $line);
2488 if (empty ($parts[0]))
2491 $names2[] = rtrim ($parts[0]);
2493 foreach ($names2 as $cname)
2494 if (commitAddObject ($cname, '', '', $global_type_id, '') === TRUE)
2495 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2497 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2502 // Render a form for the next.
2503 $typelist = getObjectTypeList();
2504 $typelist[0] = 'select type...';
2506 startPortlet ('Fast way');
2507 echo "<form name=fastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
2508 echo '<table border=0 align=center>';
2509 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>\n";
2510 // If a user forgot to select object type on input, we keep his
2511 // previous input in the form.
2512 $max = getConfigVar ('MASSCOUNT');
2513 for ($i = 0; $i < $max; $i++
)
2516 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2517 printSelect ($typelist, "${i}_object_type_id", 0);
2519 echo "<td><input type=text size=30 name=${i}_object_name";
2520 if ($keepvalues and $type_id[$i] == 0)
2521 echo " value='${name[$i]}'";
2523 echo "<td><input type=text size=30 name=${i}_object_label";
2524 if ($keepvalues and $type_id[$i] == 0)
2525 echo " value='${label[$i]}'";
2527 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2528 if ($keepvalues and $type_id[$i] == 0)
2529 echo " value='${asset_no[$i]}'";
2531 echo "<td><input type=text size=10 name=${i}_object_barcode";
2532 if ($keepvalues and $type_id[$i] == 0)
2533 echo " value='${barcode[$i]}'";
2537 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Create'></td></tr>\n";
2538 echo "</form></table>\n";
2541 startPortlet ('Very fast way');
2542 echo "<form name=veryfastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
2543 echo 'For each line shown below create an object of type ';
2544 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2545 echo " <input type=submit name=got_very_fast_data value='Go!'><br>\n";
2546 echo "<textarea name=namelist cols=40 rows=25>\n";
2547 if ($keepvalues and $global_type_id == 0)
2548 echo $_REQUEST['namelist'];
2549 echo "</textarea></form>\n";
2553 function printGreeting ()
2555 global $remote_username, $accounts, $root;
2556 $account = $accounts[$remote_username];
2557 echo "Hello, ${account['user_realname']}. This is RackTables " . CODE_VERSION
. ". Click <a href='${root}?logout'>here</a> to logout.";
2560 function renderSearchResults ()
2562 global $remote_username, $root;
2563 $terms = trim ($_REQUEST['q']);
2566 showError ('Search string cannot be empty.', __FUNCTION__
);
2569 if (!authorized ($remote_username, 'object', 'default'))
2571 showError ('You are not authorized for viewing information about objects.', __FUNCTION__
);
2575 // If we search for L2 address, we can either find one or find none.
2578 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
2579 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
2580 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
2581 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2582 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)
2584 // Search for L2 address.
2586 $terms = substr ($terms, -12);
2587 $result = searchByl2address ($terms);
2588 if ($result !== NULL)
2592 $summary['port'][] = $result;
2595 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))
2596 // Search for IP address.
2598 $result = getRangeByIp ($terms);
2599 if ($result !== NULL)
2602 $lasthit = 'ipv4address1';
2603 $summary['ipv4address1'][] = $terms;
2607 // Search for objects, addresses, networks, virtual services and RS pools by their description.
2609 $tmp = getObjectSearchResults ($terms);
2612 $nhits +
= count ($tmp);
2613 $lasthit = 'object';
2614 $summary['object'] = $tmp;
2616 $tmp = getIPv4AddressSearchResult ($terms);
2619 $nhits +
= count ($tmp);
2620 $lasthit = 'ipv4address2';
2621 $summary['ipv4address2'] = $tmp;
2623 $tmp = getIPv4PrefixSearchResult ($terms);
2626 $nhits +
= count ($tmp);
2627 $lasthit = 'ipv4network';
2628 $summary['ipv4network'] = $tmp;
2632 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
2633 elseif ($nhits == 1)
2635 $record = current ($summary[$lasthit]);
2639 echo "<script language='Javascript'>document.location='${root}?page=object";
2640 echo "&hl_port_id=" . $record['port_id'];
2641 echo "&object_id=" . $record['object_id'] . "';//</script>";
2643 case 'ipv4address1':
2644 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2645 echo "&ip=${record}";
2646 echo "';//</script>";
2648 case 'ipv4address2':
2649 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2650 echo "&ip=${record}";
2651 echo "';//</script>";
2654 echo "<script language='Javascript'>document.location='${root}?page=iprange";
2655 echo "&id=${record['id']}";
2656 echo "';//</script>";
2659 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
2668 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
2669 foreach ($summary as $where => $what)
2673 startPortlet ('Objects');
2674 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2675 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2676 foreach ($what as $obj)
2678 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2679 echo "<td>${obj['label']}</td>";
2680 echo "<td>${obj['asset_no']}</td>";
2681 echo "<td>${obj['barcode']}</td></tr>";
2682 $order = $nextorder[$order];
2688 startPortlet ('IPv4 networks');
2689 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2690 echo '<tr><th>Network</th><th>Descritpion</th></tr>';
2691 foreach ($what as $net)
2693 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=iprange&id=${net['id']}'>${net['ip']}";
2694 echo '/' . $net['mask'] . '</a></td>';
2695 echo "<td class=tdleft>${net['name']}</td></tr>";
2696 $order = $nextorder[$order];
2701 case 'ipv4address2':
2702 startPortlet ('IPv4 addresses');
2703 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2704 echo '<tr><th>Address</th><th>Descritpion</th></tr>';
2705 foreach ($what as $addr)
2707 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipaddress&id=${addr['ip']}'>";
2708 echo "${addr['ip']}</a></td>";
2709 echo "<td class=tdleft>${addr['name']}</td></tr>";
2710 $order = $nextorder[$order];
2719 // This function prints a table of checkboxes to aid the user in toggling mount atoms
2720 // from one state to another. The first argument is rack data as
2721 // produced by getRackData(), the second is the value used for the 'unckecked' state
2722 // and the third is the value used for 'checked' state.
2724 // for mounting an object: printAtomGrid ($data, 'F', 'T')
2725 // for changing rack design: printAtomGrid ($data, 'A', 'F')
2726 // for adding rack problem: printAtomGrid ($data, 'F', 'U')
2727 // for adding object problem: printAtomGrid ($data, 'T', 'W')
2729 function renderAtomGrid ($data)
2731 $rack_id = $data['id'];
2732 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2734 echo "<tr><th>${unit_no}</th>";
2735 for ($locidx = 0; $locidx < 3; $locidx++
)
2737 $state = $data[$unit_no][$locidx]['state'];
2738 echo "<td class=state_${state}";
2739 if (isset ($data[$unit_no][$locidx]['hl']))
2740 echo $data[$unit_no][$locidx]['hl'];
2742 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2743 echo '<input type=checkbox disabled>';
2745 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2752 function renderPermissions ()
2754 startPortlet ('User permissions');
2755 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2756 echo "<tr><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>";
2757 global $perms, $nextorder;
2759 foreach ($perms as $username => $pages)
2760 foreach ($pages as $page => $tabs)
2761 foreach ($tabs as $tab => $access)
2763 echo "<tr class=row_${order}><td class=tdleft>$username</td><td>$page</td><td>$tab</td><td>$access</td></tr>\n";
2764 $order = $nextorder[$order];
2770 function renderAccounts ()
2772 global $nextorder, $accounts;
2773 startPortlet ('User accounts');
2774 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2775 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2777 foreach ($accounts as $user)
2779 echo "<tr class=row_${order}><td class=tdleft><div title='\$userid_${user['user_id']}'>";
2780 echo "${user['user_name']}</div></td>";
2781 echo "<td class=tdleft>${user['user_realname']}</td></li>";
2782 $order = $nextorder[$order];
2788 function renderAccountsEditForm ()
2790 global $root, $pageno, $tabno, $accounts;
2791 startPortlet ('User accounts');
2792 showMessageOrError();
2793 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2794 echo "<tr><th>op</th><th>Username</th><th>Real name</th><th>Password</th><th> </th></tr>\n";
2795 foreach ($accounts as $account)
2797 echo "<form action='${root}process.php'>";
2798 echo "<input type=hidden name=op value=updateAccount>";
2799 echo "<input type=hidden name=page value='${pageno}'>\n";
2800 echo "<input type=hidden name=tab value='${tabno}'>\n";
2801 echo "<input type=hidden name=id value='${account['user_id']}'><tr>";
2803 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2805 echo "<a href='${root}process.php?op=disableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2806 printImageHREF ('blockuser', 'disable account');
2809 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2811 echo "<a href='${root}process.php?op=enableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2812 printImageHREF ('unblockuser', 'enable account');
2815 // Otherwise skip icon.
2817 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2818 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2819 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td>";
2820 echo "<td><input type='submit' value='OK'></td>";
2821 echo "</form></tr>\n";
2823 echo "<form action='${root}process.php' method=post><tr>";
2824 echo "<input type=hidden name=op value=createAccount>\n";
2825 echo "<input type=hidden name=page value='${pageno}'>\n";
2826 echo "<input type=hidden name=tab value='${tabno}'>\n";
2827 echo "<td colspan=2><input type=text size=16 name=username tabindex=100></td>\n";
2828 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2829 echo "<td><input type=password size=64 name=password tabindex=102></td>";
2830 echo "<td colspan=4><input type=submit value='Create account' tabindex=103></td></tr></form>";
2831 echo "</table><br>\n";
2835 function printChildrenAsOptions ($root, $depth = 0)
2837 echo "<option value=${root['title']}>";
2840 for ($i = 0; $i < $depth; $i++
)
2842 echo $root['title'];
2844 foreach ($root['kids'] as $kid)
2845 printChildrenAsOptions ($kid, $depth +
1);
2848 // 1. Find all parentless pages.
2849 // 2. For each of them recursively find all children.
2850 // 3. Output the tree with recursion tree display.
2851 function printPagesTree ()
2855 foreach ($page as $ctitle => $cpage)
2856 if (!isset ($cpage['parent']))
2858 $croot['title'] = $ctitle;
2859 $croot['kids'] = getAllChildPages ($ctitle);
2860 printChildrenAsOptions ($croot);
2865 function renderPermissionsEditForm ()
2867 global $root, $pageno, $tabno, $perms, $accounts;
2868 startPortlet ('User permissions');
2869 showMessageOrError();
2870 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
2871 echo "<tr><th> </th><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>\n";
2872 foreach ($perms as $username => $pages)
2873 foreach ($pages as $access_page => $tabs)
2874 foreach ($tabs as $access_tab => $access)
2877 if ($username != '%')
2878 $userid = $accounts[$username]['user_id'];
2881 echo "<a href='${root}process.php?op=revoke&page=${pageno}&tab=${tabno}&access_userid=${userid}&access_page=${access_page}&access_tab=${access_tab}'>";
2882 printImageHREF ('revoke', 'Revoke permission');
2884 echo "<td>${username}</td>";
2885 echo "<td>${access_page}</td>";
2886 echo "<td>${access_tab}</td>";
2887 echo "<td>${access}</td>";
2890 echo "<form action='${root}process.php' method=post><tr>";
2891 echo "<input type=hidden name=op value=grant>\n";
2892 echo "<input type=hidden name=page value='${pageno}'>\n";
2893 echo "<input type=hidden name=tab value='${tabno}'>\n";
2894 // FIXME: border=0 doesn't work here for unknown reason
2896 printImageHREF ('grant', '', TRUE, 103);
2898 echo "<td><select name=access_userid>";
2899 echo "<option value=0>ANY</option>";
2900 foreach ($accounts as $account)
2901 echo "<option value=${account['user_id']}>${account['user_name']}</option>";
2902 echo "</select></td>\n";
2903 echo "<td><select name=access_page>";
2904 echo "<option value='%'>ANY</option>";
2906 echo "</select></td>";
2907 echo "<td><input type=text size=16 name=access_tab tabindex=102 value=default></td>";
2908 echo "<td><input type=radio name=access_value value=no checked>no <input type=radio name=access_value value=yes>yes</td>";
2909 echo "</tr></form>";
2910 echo "</table><br>\n";
2914 function renderPortMapViewer ()
2916 renderPortMap (FALSE);
2919 function renderPortMapEditor ()
2921 renderPortMap (TRUE);
2924 function renderPortMap ($editable = FALSE)
2926 global $nextorder, $root, $pageno, $tabno;
2927 showMessageOrError();
2928 startPortlet ("Port compatibility map");
2929 $ptlist = getPortTypes();
2930 $pclist = getPortCompat();
2931 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
2934 echo "<form method=post action='${root}process.php'>";
2935 echo "<input type=hidden name=page value='${pageno}'>";
2936 echo "<input type=hidden name=tab value='${tabno}'>";
2937 echo "<input type=hidden name=op value=save>";
2939 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2940 echo "<tr><th class=vert_th> </th>";
2941 foreach ($ptlist as $name2)
2942 echo "<th>to ${name2}</th>";
2944 // Make a copy to have an independent array pointer.
2947 foreach ($ptlistY as $type1 => $name1)
2949 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
2950 foreach ($ptlist as $type2 => $name2)
2952 echo '<td><input type=checkbox' . ($editable ?
" name=atom_${type1}_${type2}" : ' disabled');
2953 echo ($pctable[$type1][$type2] ?
' checked' : '') . '></td>';
2956 $order = $nextorder[$order];
2958 echo '</table><br>';
2961 echo "<input type=submit value='Save changes'>";
2967 function renderConfigMainpage ()
2969 global $pageno, $root;
2970 $children = getDirectChildPages ($pageno);
2972 // FIXME: assume all config kids to have static titles at the moment,
2973 // but use some proper abstract function later.
2974 foreach ($children as $cpageno => $child)
2975 echo "<li><a href='${root}?page=${cpageno}'>" . $child['title'] . "</li>\n";
2980 function renderRackPage ($rack_id)
2984 showError ('Invalid rack_id', __FUNCTION__
);
2987 if (($rackData = getRackData ($rack_id)) == NULL)
2989 showError ('getRackData() failed', __FUNCTION__
);
2992 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
2994 // Left column with information.
2995 echo "<td class=pcleft>";
2996 startPortlet ('Rack information');
2997 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2998 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
2999 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
3000 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
3001 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
3002 renderProgressBar (getRSUforRack ($rackData));
3003 echo "</td></tr>\n";
3004 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
3005 echo getObjectCount ($rackData);
3006 echo "</td></tr>\n";
3008 if (!empty ($rackData['comment']))
3009 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
3014 // Right column with rendered rack.
3016 startPortlet ('Rack diagram');
3017 renderRack ($rack_id);
3021 echo '</tr></table>';
3024 function renderDictionary ()
3027 $dict = getDict (TRUE);
3028 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3029 foreach ($dict as $chapter_no => $chapter)
3032 echo "<tr><th>Chapter</th><th>refs</th><th>Word</th></tr>\n";
3033 $wc = count ($chapter['word']);
3034 echo "<tr class=row_${order}><td class=tdleft" . ($wc ?
" rowspan = ${wc}" : '');
3035 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
3037 echo "<td colspan=2>none</td>";
3041 foreach ($chapter['word'] as $key => $value)
3044 echo "<tr class=row_${order}>";
3046 $chap_start = FALSE;
3047 echo '<td>' . ($chapter['refcnt'][$key] ?
$chapter['refcnt'][$key] : ' ') . '</td>';
3048 echo "<td><div title='key=${key}'>${value}</div></td></tr>\n";
3049 $order = $nextorder[$order];
3053 echo "</table>\n<br>";
3056 function renderDictionaryEditor ()
3058 global $root, $pageno, $tabno, $nextorder;
3060 showMessageOrError();
3061 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3062 foreach ($dict as $chapter_no => $chapter)
3065 echo "<tr><th>Chapter</th><th> </th><th>Word</th><th> </th></tr>\n";
3066 $wc = count ($chapter['word']);
3067 // One extra span for the new record per each chapter block.
3068 echo "<tr class=row_${order}><td class=tdleft" . ($wc ?
' rowspan = ' . ($wc +
1) : '');
3069 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
3070 echo "<form action='${root}process.php' method=post>";
3071 echo "<input type=hidden name=page value='${pageno}'>";
3072 echo "<input type=hidden name=tab value='${tabno}'>";
3073 echo "<input type=hidden name=op value=add>";
3074 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3075 echo "<td> </td>";
3076 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
3077 echo "<td><input type=submit value='Add new'></td>";
3078 echo '</tr></form>';
3079 $order = $nextorder[$order];
3080 foreach ($chapter['word'] as $key => $value)
3082 echo "<form action='${root}process.php' method=post>";
3083 echo "<input type=hidden name=page value='${pageno}'>";
3084 echo "<input type=hidden name=tab value='${tabno}'>";
3085 echo "<input type=hidden name=op value='upd'>";
3086 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3087 echo "<input type=hidden name=dict_key value='${key}'>";
3088 echo "<tr class=row_${order}><td>";
3089 // Prevent deleting words currently used somewhere.
3090 if ($chapter['refcnt'][$key])
3091 printImageHREF ('nodelete', 'referenced ' . $chapter['refcnt'][$key] . ' time(s)');
3094 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
3095 printImageHREF ('delete', 'Delete word');
3099 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
3100 echo "<td><input type=submit value=OK></td>";
3101 echo "</tr></form>\n";
3102 $order = $nextorder[$order];
3103 } // foreach ($chapter['word']
3108 // We don't allow to rename/delete a sticky chapter and we don't allow
3109 // to delete a non-empty chapter.
3110 function renderChaptersEditor ()
3112 global $root, $pageno, $tabno;
3113 showMessageOrError();
3115 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3116 echo '<tr><th> </th><th>Chapter name</th><th>Words</th><th> </th></tr>';
3117 foreach ($dict as $chapter)
3119 $wordcount = count ($chapter['word']);
3120 $sticky = $chapter['sticky'];
3121 echo "<form action='${root}process.php' method=post>";
3122 echo "<input type=hidden name=page value='${pageno}'>";
3123 echo "<input type=hidden name=tab value='${tabno}'>";
3124 echo "<input type=hidden name=op value=upd>";
3125 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3129 printImageHREF ('nodelete', 'system chapter');
3130 elseif ($wordcount > 0)
3131 printImageHREF ('nodelete', 'contains ' . $wordcount . ' word(s)');
3134 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
3135 printImageHREF ('delete', 'Remove chapter');
3139 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ?
' disabled' : '') . "></td>";
3140 echo "<td class=tdleft>${wordcount}</td><td>";
3144 echo "<input type=submit value='OK'>";
3148 echo "<form action='${root}process.php' method=post>";
3149 echo "<input type=hidden name=page value='${pageno}'>";
3150 echo "<input type=hidden name=tab value='${tabno}'>";
3151 echo "<input type=hidden name=op value=add>";
3153 printImageHREF ('add', '', TRUE);
3154 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
3160 function renderAttributes ()
3163 $attrMap = getAttrMap();
3164 startPortlet ('Optional attributes');
3165 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3166 echo "<tr><th class=tdleft>Attribute name</th><th class=tdleft>Attribute type</th><th class=tdleft>Applies to</th></tr>";
3168 foreach ($attrMap as $attr)
3170 echo "<tr class=row_${order}>";
3171 echo "<td class=tdleft>${attr['name']}</td>";
3172 echo "<td class=tdleft>${attr['type']}</td>";
3173 echo '<td class=tdleft>';
3174 if (count ($attr['application']) == 0)
3177 foreach ($attr['application'] as $app)
3178 if ($attr['type'] == 'dict')
3179 echo "${app['objtype_name']} (values from '${app['chapter_name']}')<br>";
3181 echo "${app['objtype_name']}<br>";
3184 $order = $nextorder[$order];
3186 echo "</table><br>\n";
3190 function renderEditAttributesForm ()
3192 global $root, $pageno, $tabno;
3193 $attrMap = getAttrMap();
3194 showMessageOrError();
3195 startPortlet ('Optional attributes');
3196 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3197 echo '<tr><th> </th><th>Name</th><th>Type</th><th> </th></tr>';
3198 foreach ($attrMap as $attr)
3200 echo "<form action='${root}process.php' method=post>";
3201 echo "<input type=hidden name=page value='${pageno}'>";
3202 echo "<input type=hidden name=tab value='${tabno}'>";
3203 echo "<input type=hidden name=op value=upd>";
3204 echo "<input type=hidden name=attr_id value='${attr['id']}'>";
3206 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&attr_id=${attr['id']}'>";
3207 printImageHREF ('delete', 'Remove attribute');
3209 echo "<td><input type=text name=attr_name value='${attr['name']}'></td>";
3210 echo "<td>${attr['type']}</td>";
3211 echo "<td><input type=submit value='OK'></td>";
3215 echo "<form action='${root}process.php' method=post>";
3216 echo "<input type=hidden name=page value='${pageno}'>";
3217 echo "<input type=hidden name=tab value='${tabno}'>";
3218 echo "<input type=hidden name=op value=add>";
3220 printImageHREF ('add', '', TRUE);
3221 echo "</td><td><input type=text name=attr_name></td>";
3222 echo '<td><select name=attr_type>';
3223 echo '<option value=uint>uint</option>';
3224 echo '<option value=float>float</option>';
3225 echo '<option value=string>string</option>';
3226 echo '<option value=dict>dict</option>';
3227 echo '</select></td>';
3234 function renderEditAttrMapForm ()
3236 global $root, $pageno, $tabno;
3237 $attrMap = getAttrMap();
3238 showMessageOrError();
3239 startPortlet ('Attribute map');
3240 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3241 echo '<tr><th> </th><th>Attribute name</th><th>Object type</th><th>Dictionary chapter</th></tr>';
3242 foreach ($attrMap as $attr)
3244 if (count ($attr['application']) == 0)
3246 foreach ($attr['application'] as $app)
3250 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&";
3251 echo "attr_id=${attr['id']}&objtype_id=${app['objtype_id']}'>";
3252 printImageHREF ('delete', 'Remove mapping');
3255 echo "<td>${attr['name']}</td>";