changes to make code compatible with php 5.3
[racktables-contribs] / LinkManagement / plugins / linkmgmt.php
... / ...
CommitLineData
1<?php
2/*
3 * Link Management for RT >= 0.20.9
4 *
5 * Features:
6 * - create links between ports
7 * - create backend links between ports
8 * - visually display links / chains
9 * e.g.
10 * (Object)>[port] -- front --> [port]<(Object) == back == > (Object)>[port] -- front --> [port]<(Object)
11 * - Link object backend ports by name (e.g. handy for patch panels)
12 * - change/create CableID (needs jquery.jeditable.mini.js)
13 * - change/create Port Reservation Comment (needs jquery.jeditable.mini.js)
14 * - multiple backend links for supported port types (e.g. AC-in, DC)
15 * - GraphViz Maps (Objects, Ports and Links) (needs GraphViz_Image 1.3.0)
16 * - object,port or link highligthing (just click on it)
17 * - context menu to link and unlink ports
18 *
19 * Usage:
20 * 1. select "Link Management" tab
21 * 2. you should see link chains of all linked ports
22 * 3. to display all ports hit "Show All Ports" in the left upper corner
23 * 4. to link all ports with the same name of two different objects use "Link Object Ports by Name"
24 * a. select the other object you want to backend link to
25 * b. "show back ports" gives you the list of possible backend links
26 * !! Important port names have to be the same on both objects !!
27 * e.g. (Current Object):Portname -?-> Portname:(Selected Object)
28 * c. select all backend link to create (Ctrl + a for all)
29 * d. Enter backend CableID for all selected links
30 * e. "Link back" create the backend links
31 * 5. If you have an backend link within the same Object the link isn't shown until
32 * "Expand Backend Links on same Object" is hit
33 * 6. "Object Map" displays Graphviz Map of current object
34 * 7. To get a Graphviz Map of a single port click the port name on the left
35 *
36 *
37 * Requirements:
38 * PHP 5 (http://php.net/)
39 * GraphViz_Image 1.3.0 or newer (http://pear.php.net/package/Image_GraphViz)
40 * GraphViz (http://www.graphviz.org/)
41 *
42 * INSTALL:
43 *
44 * 1. create LinkBackend Table in your RackTables database
45 *
46 * Multilink table
47
48CREATE TABLE `LinkBackend` (
49 `porta` int(10) unsigned NOT NULL DEFAULT '0',
50 `portb` int(10) unsigned NOT NULL DEFAULT '0',
51 `cable` char(64) DEFAULT NULL,
52 PRIMARY KEY (`porta`,`portb`),
53 KEY `LinkBackend_FK_a` (`porta`),
54 KEY `LinkBackend_FK_b` (`portb`),
55 CONSTRAINT `LinkBackend_FK_a` FOREIGN KEY (`porta`) REFERENCES `Port` (`id`) ON DELETE CASCADE,
56 CONSTRAINT `LinkBackend_FK_b` FOREIGN KEY (`portb`) REFERENCES `Port` (`id`) ON DELETE CASCADE
57) ENGINE=InnoDB DEFAULT CHARSET=utf8 collate=utf8_unicode_ci;
58
59 * 2. copy jquery.jeditable.mini.js to js/ directory (http://www.appelsiini.net/download/jquery.jeditable.mini.js)
60 * 3. copy linkmgmt.php to plugins directory
61 *
62 * Ready to go!
63 *
64 *
65 * UPDATE TABLE:
66 *
67 * Update from non-multilink table
68 * ALTER TABLE
69
70ALTER TABLE LinkBackend ADD KEY `LinkBackend_FK_b` (`portb`);
71ALTER TABLE LinkBackend DROP INDEX porta;
72ALTER TABLE LinkBackend DROP INDEX portb;
73
74 * UPDATE to RT 0.20.7
75
76ALTER TABLE LinkBackend CONVERT to CHARACTER SET utf8 COLLATE utf8_unicode_ci;
77
78 *
79 *
80 * TESTED on FreeBSD 9.0, nginx/1.0.11, php 5.3.9
81 * GraphViz_Image 1.3.0
82 *
83 * (c)2012-2015 Maik Ehinger <m.ehinger@ltur.de>
84 */
85
86/**
87 * The newest version of this plugin can be found at:
88 *
89 * https://github.com/github138/myRT-contribs/tree/develop-0.20.9
90 *
91 */
92
93/*************************
94 * TODO
95 *
96 * - code cleanups
97 * - bug fixing
98 *
99 * - fix loopdectect for multiport
100 * MAX_LOOP_COUNT
101 * loop highlight gv map
102 *
103 * - fix column alignment with multilinks
104 *
105 * - put selected object/port top left of graph
106 * - multlink count for Graphviz maps empty or full dot
107 *
108 * - csv list
109 *
110 */
111
112/* DEBUG */
113//error_reporting(E_ALL);
114
115$tab['object']['linkmgmt'] = 'Link Management';
116$tabhandler['object']['linkmgmt'] = 'linkmgmt_tabhandler';
117//$trigger['object']['linkmgmt'] = 'linkmgmt_tabtrigger';
118
119$ophandler['object']['linkmgmt']['update'] = 'linkmgmt_opupdate';
120$ophandler['object']['linkmgmt']['unlinkPort'] = 'linkmgmt_opunlinkPort';
121$ophandler['object']['linkmgmt']['PortLinkDialog'] = 'linkmgmt_opPortLinkDialog';
122$ophandler['object']['linkmgmt']['Help'] = 'linkmgmt_opHelp';
123
124$ophandler['object']['linkmgmt']['map'] = 'linkmgmt_opmap';
125$ajaxhandler['lm_mapinfo'] = 'linkmgmt_ajax_mapinfo';
126
127/* ------------------------------------------------- */
128
129define('LM_MULTILINK',TRUE);
130
131/* -------------------------------------------------- */
132
133$lm_multilink_port_types = array(
134 16, /* AC-in */
135 //1322, /* AC-out */
136 1399, /* DC */
137 );
138
139/* -------------------------------------------------- */
140
141$lm_cache = array(
142 'allowcomment' => TRUE, /* RackCode ${op_set_reserve_comment} */
143 'allowlink' => TRUE, /* RackCode ${op_set_link} */
144 'rackinfo' => array(),
145 );
146
147/* -------------------------------------------------- */
148
149//function linkmgmt_tabtrigger() {
150// return 'std';
151//} /* linkmgmt_tabtrigger */
152
153/* -------------------------------------------------- */
154
155function linkmgmt_opHelp() {
156?>
157 <table cellspacing=10><tr><th>Help</th><tr>
158 <tr><td width=150></td><td width=150 style="font-weight:bold;color:<?php echo portlist::CURRENT_OBJECT_BGCOLOR; ?>">Current Object</td></tr>
159 <tr><td></td><td bgcolor=<?php echo portlist::CURRENT_PORT_BGCOLOR; ?>>[current port]</td></tr>
160 <tr><td>front link</td><td>[port]<(Object)</td><td>back link</td></tr>
161 <tr><td>back link</td><td>(Object)>[port]</td><td>front link</td></tr>
162 <tr><td></td><td><pre>----></pre></td><td>Front link</td></tr>
163 <tr><td></td><td><pre>====></pre></td><td>Backend link</td></tr>
164 <tr><td></td><td>Link Symbol</td><td>Create new link</td></tr>
165 <tr><td></td><td>Cut Symbol</td><td>Delete link</td></tr>
166
167 </table>
168
169<?php
170 exit;
171} /* opHelp */
172
173/* -------------------------------------------------- */
174
175function linkmgmt_ajax_mapinfo() {
176
177 $object_id = NULL;
178 $port_id = NULL;
179 $remote_id = NULL;
180 $linktype = NULL;
181
182 if(isset($_REQUEST['object_id']))
183 $object_id = $_REQUEST['object_id'];
184
185 if(isset($_REQUEST['port_id']))
186 $port_id = $_REQUEST['port_id'];
187
188 if(isset($_REQUEST['remote_id']))
189 $remote_id = $_REQUEST['remote_id'];
190
191 if(isset($_REQUEST['linktype']))
192 $linktype = $_REQUEST['linktype'];
193
194 $debug = NULL;
195 if(isset($_REQUEST['debug']))
196 $debug['value'] = $_REQUEST['debug'];
197
198 $info = array();
199
200 echo "<table style=\"font-size:12;\"><tr>";
201
202 if($port_id != NULL)
203 {
204 $port = new linkmgmt_RTport($port_id);
205
206 echo "<td>";
207 $port->printtable('both');
208 echo "</td>";
209
210 if($debug)
211 $debug['port'] = &$port;
212
213 if($remote_id != NULL)
214 {
215
216 $remote_port = new linkmgmt_RTport($remote_id);
217
218 echo "<td><table align=\"center\">";
219
220 // TODO cableid
221 echo "<tr><td><pre>".($linktype == 'back' ? ' ===> ' : ' ---> ')."</pre></td></tr>";
222
223 $port->printunlinktr($linktype, $remote_port);
224
225 echo "</table></td>";
226
227
228 echo "<td>";
229 $remote_port->printtable('both');
230 echo "</td>";
231
232 if($debug)
233 $debug['remote_port'] = &$remote_port;
234
235 }
236 else
237 $port->printunlinktr();
238
239
240 }
241 echo "</tr><tr>";
242
243 echo "<td>";
244 $object = linkmgmt_RTport::printobjecttable($object_id);
245 echo "</td>";
246
247 if($debug)
248 $debug['object'] = &$object;
249
250 if($remote_id != NULL)
251 {
252
253 echo "<td></td>"; /* link */
254 echo "<td>";
255 $remote_object = linkmgmt_RTport::printobjecttable($remote_port->port['object_id']);
256 echo "</td>";
257
258 if($debug)
259 $debug['remote_object'] = &$remote_object;
260 }
261
262 echo "</tr></table>";
263
264 if($debug)
265 {
266 echo "<pre>--- Debug ---";
267 var_dump($debug);
268 echo "</pre>";
269 }
270
271 exit;
272}
273
274/* -------------------------------------- */
275function lm_renderObjectCell ($cell)
276{
277 echo "<table class='slbcell vscell'><tr><td rowspan=2 width='5%'>";
278 printImageHREF ('OBJECT');
279 echo '</td><td>';
280 echo mkA ('<strong>' . niftyString ($cell['dname']) . '</strong>', 'object', $cell['id']);
281 echo '</td></tr><tr><td>';
282 echo count ($cell['etags']) ? ("<small>" . serializeTags ($cell['etags']) . "</small>") : '&nbsp;';
283 echo "</td></tr></table>";
284}
285/* -------------------------------------- */
286
287class linkmgmt_RTport {
288
289 private $port_id = NULL;
290
291 public $port = false;
292
293 function __construct($port_id) {
294
295 $this->port = getPortInfo($port_id);
296
297 if($this->port === false)
298 return;
299
300 /* successfully get port info */
301 $this->port_id = $port_id;
302
303 } /* __construct */
304
305 function isvalid() {
306 return ($port_id !== NULL);
307 }
308
309 function getlinks($type = 'front') {
310 } /* getlinks */
311
312 function printtable($linktype = 'front') {
313
314 if($this->port_id == NULL)
315 return;
316
317 echo "<table>";
318
319 $urlparams = array(
320 'module' => 'redirect',
321 'page' => 'object',
322 'tab' => 'linkmgmt',
323 'op' => 'map',
324 'object_id' => $this->port['object_id'],
325 'port_id' => $this->port_id,
326 'usemap' => 1,
327 );
328
329 echo '<tr><td><a title="don\'t highlight port" href="?'.http_build_query($urlparams).'">-phl</a></td>';
330
331 $urlparams['hl'] = 'p';
332 echo '<td><a title="highlight port" href="?'.http_build_query($urlparams).'">+phl</a></td></tr>';
333
334 $this->_printinforow($this->port,
335 array(
336 'id' => 'Port ID',
337 'name' => 'Port Name',
338 'oif_name' => 'Port Type',
339 'l2address' => 'MAC',
340 'reservation_comment' => 'comment',
341 )
342 ); /* printinforow */
343
344 $this->printlinktr($linktype);
345
346 echo "</table>";
347 } /* printtable */
348
349 function printlinktr($linktype = 'front') {
350 if($this->port_id === NULL)
351 return;
352
353 $urlparams = array(
354 'tab' => 'linkmgmt',
355 'page' => 'object',
356 'op'=>'PortLinkDialog',
357 'port'=>$this->port_id,
358 'object_id'=>$this->port['object_id'],
359 'linktype' => $linktype,
360 );
361
362 echo "<tr><td align=\"center\"><a href='".
363 makeHrefProcess($urlparams).
364 "'>";
365 printImageHREF ('plug', 'Link this port');
366 echo "</a></td></tr>";
367 } /* link */
368
369 function printunlinktr($linktype = 'front', $remote_port = NULL) {
370 if($this->port_id === NULL)
371 return;
372
373 $urlparams = array(
374 'tab' => 'linkmgmt',
375 'op'=>'unlinkPort',
376 'port_id'=>$this->port_id,
377 'object_id'=>$this->port['object_id'],
378 'linktype' => $linktype,
379 );
380
381 $confirmmsg = "unlink port ".$this->port['name'];
382
383 if($remote_port !== NULL)
384 {
385 $urlparams['remote_id'] = $remote_port->port['id'];
386 $confirmmsg .= ' -> '.$remote_port->port['name'];
387 }
388
389 $confirmmsg .= " ($linktype)"; // TODO cableid
390
391 echo "<tr><td align=\"center\"><a href='".makeHrefProcess($urlparams).
392 "' onclick=\"return confirm('$confirmmsg');\">";
393 printImageHREF ('cut', 'Unlink this port');
394 echo "</a></td></tr>";
395
396 } /* unlink */
397
398 /* TODO move to object class */
399 static function printobjecttable($object_id = NULL) {
400
401 if($object_id === NULL)
402 return;
403
404 $object = spotEntity ('object', $object_id);
405
406 if($object === false)
407 return;
408
409 if($object['rack_id'])
410 {
411 $rack = spotEntity('rack', $object['rack_id']);
412
413 $object['row_name'] = $rack['row_name'];
414 $object['rack_name'] = $rack['name'];
415 }
416
417 echo "<table><tr><td>";
418 lm_renderObjectCell($object);
419 echo "</td></tr><tr><td><table>";
420
421 self::_printinforow($object,
422 array(
423 'id' => 'ID',
424 'dname' => 'Name',
425 'label' => 'Label',
426 'rack_name' => 'Rack',
427 'row_name' => 'Row',
428 )
429
430 ); /* printinforow */
431
432 $urlparams = array(
433 'module' => 'redirect',
434 'page' => 'object',
435 'tab' => 'linkmgmt',
436 'op' => 'map',
437 'object_id' => $object_id,
438 'usemap' => 1,
439 );
440
441 echo '<tr><td><a title="don\'t highlight object" href="?'.http_build_query($urlparams).'">-ohl</a></td>';
442
443 $urlparams['hl'] = 'o';
444 echo '<td><a title="highlight object" href="?'.http_build_query($urlparams).'">+ohl</a></td></tr>';
445
446 echo "</table></td></tr></table>";
447
448 return $object;
449
450 } /* printobjecttable */
451
452 static function _printinforow(&$data, $config) {
453
454 foreach($config as $key => $name)
455 {
456 if(isset($data[$key]))
457 {
458 $value = $data[$key];
459 if(!empty($value))
460 echo "<tr><td align=\"right\" nowrap=\"nowrap\" style=\"font-size:10;\">$name:</td><td nowrap=\"nowrap\">$value</td></tr>";
461 }
462 }
463
464 } /* _printinforow */
465} /* class RTport */
466
467/* -------------------------------------------------- */
468
469function linkmgmt_opmap() {
470
471 /* display require errors "white screen of death" */
472 $errorlevel = error_reporting();
473 error_reporting(E_ALL);
474
475 require_once 'Image/GraphViz.php';
476
477/*
478 *
479 */
480class lm_Image_GraphViz extends Image_GraphViz {
481
482 /* extend renderDotFile with additional output file
483 */
484 function renderDotFile($dotfile, $outputfile, $format = 'svg',
485 $command = null, $outputfile2 = null, $format2 = null)
486 {
487 if (!file_exists($dotfile)) {
488 if ($this->_returnFalseOnError) {
489 return false;
490 }
491 $error = PEAR::raiseError('Could not find dot file');
492 return $error;
493 }
494
495 $oldmtime = file_exists($outputfile) ? filemtime($outputfile) : 0;
496
497 switch ($command) {
498 case 'dot':
499 case 'neato':
500 break;
501 default:
502 $command = $this->graph['directed'] ? 'dot' : 'neato';
503 }
504 $command_orig = $command;
505
506 $command = $this->binPath.(($command == 'dot') ? $this->dotCommand
507 : $this->neatoCommand);
508
509 $command .= ' -T'.escapeshellarg($format)
510 .' -o'.escapeshellarg($outputfile)
511 .($format2 !== null && $outputfile2 !== null ? ' -T'.escapeshellarg($format2).' -o'.escapeshellarg($outputfile2) : '')
512 .' '.escapeshellarg($dotfile)
513 .' 2>&1';
514
515 exec($command, $msg, $return_val);
516
517 clearstatcache();
518 if (file_exists($outputfile) && filemtime($outputfile) > $oldmtime
519 && $return_val == 0) {
520 return true;
521 } elseif ($this->_returnFalseOnError) {
522 return false;
523 }
524 $error = PEAR::raiseError($command_orig.' command failed: '
525 .implode("\n", $msg));
526 return $error;
527 }
528 // renderDotFile
529
530
531 /*
532 */
533 function fetch($format = 'svg', $command = null, $format2 = null, &$data2 = null)
534 {
535
536 $file = $this->saveParsedGraph();
537 if (!$file || PEAR::isError($file)) {
538 return $file;
539 }
540
541 $outputfile = $file . '.' . $format;
542
543 if($format2 != null && $data2 !== null)
544 $outputfile2 = $file . '.' . $format2;
545 else
546 $outputfile2 = null;
547
548 $rendered = $this->renderDotFile($file, $outputfile, $format,
549 $command, $outputfile2, $format2);
550 if ($rendered !== true) {
551 return $rendered;
552 }
553
554 @unlink($file);
555
556 if($format2 !== null && $data2 !== null) {
557 $fp = fopen($outputfile2, 'rb');
558
559 if ($fp) {
560 $data = fread($fp, filesize($outputfile2));
561 fclose($fp);
562 @unlink($outputfile2);
563
564 $data2 = $data;
565 } else {
566 return $error;
567 }
568 }
569
570
571 $fp = fopen($outputfile, 'rb');
572
573 if (!$fp) {
574 if ($this->_returnFalseOnError) {
575 return false;
576 }
577 $error = PEAR::raiseError('Could not read rendered file');
578 return $error;
579 }
580
581 $data = fread($fp, filesize($outputfile));
582 fclose($fp);
583 @unlink($outputfile);
584
585 return $data;
586 }
587 // fetch
588
589
590
591} /* class lm_Image_GraphViz */
592
593 error_reporting($errorlevel);
594
595 $object_id = NULL;
596 $port_id = NULL;
597 $remote_id = NULL;
598 $allports = false;
599 $usemap = false;
600 $command = NULL;
601
602 /* highlight object */
603 $hl = NULL;
604 if(isset($_REQUEST['hl']))
605 {
606 $hl = $_REQUEST['hl'];
607 unset($_REQUEST['hl_object_id']);
608 unset($_REQUEST['hl_port_id']);
609
610 if($hl == 'o')
611 {
612 unset($_GET['port_id']);
613 unset($_GET['remote_id']);
614 }
615
616 }
617
618 if(!$hl && isset($_REQUEST['hl_object_id']))
619 {
620 $hl = 'o';
621 $object_id = $_REQUEST['hl_object_id'];
622 $_REQUEST['object_id'] = $object_id;
623 unset($_REQUEST['hl_object_id']);
624 unset($_REQUEST['hl_port_id']);
625 unset($_REQUEST['port_id']);
626 }
627
628 if(isset($_REQUEST['object_id']))
629 $object_id = $_REQUEST['object_id'];
630
631 if(isset($_REQUEST['type']))
632 {
633 $type = $_REQUEST['type'];
634 }
635 else
636 $type = 'gif';
637
638 /* highlight port */
639 if(!$hl && isset($_REQUEST['hl_port_id']))
640 {
641 $hl = 'p';
642 $port_id = $_REQUEST['hl_port_id'];
643 $_REQUEST['port_id'] = $port_id;
644 unset($_REQUEST['hl_port_id']);
645 }
646
647 if(isset($_REQUEST['allports']))
648 {
649 $allports = $_REQUEST['allports'];
650 }
651
652 if(isset($_REQUEST['port_id']))
653 {
654 $port_id = $_REQUEST['port_id'];
655 }
656
657 if(isset($_REQUEST['usemap']))
658 $usemap = $_REQUEST['usemap'];
659
660 if($hl == 'p' && $port_id === NULL)
661 {
662 unset($_GET['hl']);
663 unset($_GET['port_id']);
664 unset($_GET['remote_id']);
665 }
666
667 if($hl == 'o')
668 unset($_GET['remote_id']);
669
670 if(isset($_REQUEST['remote_id']))
671 $remote_id = $_REQUEST['remote_id'];
672
673 /* show all objects */
674 if(isset($_REQUEST['all']))
675 {
676 $object_id = NULL;
677 $port_id = NULL;
678 $hl = NULL;
679 unset($_GET['hl']);
680 }
681
682 if(isset($_REQUEST['cmd']))
683 $command = $_REQUEST['cmd'];
684
685 if(isset($_REQUEST['debug']))
686 $debug = $_REQUEST['debug'];
687 else
688 $debug = False;
689
690 if($debug) echo "-- DEBUG --<br>";
691
692 $gvmap = new linkmgmt_gvmap($object_id, $port_id, $allports, $hl, $remote_id);
693
694 if($debug) echo "-- after gvmap --<br>";
695
696 switch($type) {
697 case 'gif':
698 case 'png':
699 case 'bmp':
700 case 'jpeg':
701 case 'tif':
702 case 'wbmp':
703 $ctype = "image/$type";
704 break;
705 case 'jpg':
706 $ctype = "image/jpeg";
707 break;
708 case 'svg':
709 $ctype = 'image/svg+xml';
710 break;
711 case 'pdf':
712 $ctype = 'application/pdf';
713 break;
714 case 'cmapx':
715 $ctype = 'text/plain';
716 break;
717
718 }
719
720 if($usemap)
721 {
722
723 if($debug) echo "-- usemap --<br>";
724
725 /* add context menu to Ports, Objects, Links, ...
726 */
727
728 echo "<script>
729 function initcontextmenu() {
730 var maps = document.getElementsByTagName('map');
731 for(var i=0;i<maps.length;i++) {
732 var areas = maps[i].childNodes;
733
734 for(j=0;j<areas.length;j++) {
735 if(areas[j].nodeType == 1)
736 {
737 // console.log(areas[j].id);
738 // attr = document.createAttribute('onmouseover','ahh');
739 // areas[j].setAttribute(attr);
740 // areas[j].onmouseover = 'menu(this);';
741
742 areas[j].addEventListener('contextmenu',menu,false);
743 // areas[j].oncontextmenu = 'menu(this, event);';
744 // console.log(areas[j].oncontextmenu);
745 }
746 }
747
748 }
749
750 };
751
752 function menu(event) {
753
754 // console.log('Menu');
755
756 if(!event)
757 event = window.event;
758
759 var parent = event.target;
760
761 // console.log('--' + parent);
762
763 var ids = parent.id.split('-');
764
765 if(ids[0] == 'graph1')
766 return false;
767
768 var object_id = ids[0];
769
770 var url ='?module=ajax&ac=lm_mapinfo&object_id=' + object_id;
771
772 // links ='<li><a href=' + object_id + '>Object</a></li>';
773
774 if(ids[1] != '')
775 {
776 var port_id = ids[1];
777 url += '&port_id=' + port_id;
778 // links += '<li><a href=' + port_id + '>Port</a></li>';
779
780 if(ids[2] != '')
781 {
782 var remote_id = ids[2];
783
784 if(ids[3] != '')
785 {
786 var linktype = ids[3];
787 url += '&remote_id=' + remote_id + '&linktype=' + linktype;
788 // links += '<li><a href=' + port_id + '_' + remote_id + '_' + linktype + '>Unlink</a></li>';
789 }
790 }
791
792 }
793
794
795 var xmlHttp = new XMLHttpRequest();
796 xmlHttp.open('GET', url, false);
797 xmlHttp.send(null);
798
799 var infodiv = document.getElementById('info');
800 infodiv.innerHTML = xmlHttp.responseText;
801
802 // linkdiv = document.getElementById('link');
803 // linkdiv.innerHTML = links;
804
805 var menudiv = document.getElementById('menu');
806 menudiv.style.position = 'absolute';
807 menudiv.style.top = (event.clientY + document.body.scrollTop) + 'px';
808 menudiv.style.left = (event.clientX + document.body.scrollLeft) + 'px';
809 menudiv.style.display = '';
810
811 return false;
812 };
813
814 function mousedown(event) {
815 // console.log('mouse down');
816
817 if(!event)
818 event = window.event;
819
820 if(event.button != 2)
821 return true;
822
823 var menudiv = document.getElementById('menu');
824
825 menudiv.style.display = 'none';
826
827 return false;
828 };
829
830 </script>";
831
832 echo "<body oncontextmenu=\"return false\" onmousedown=\"mousedown(event);\" onload=\"initcontextmenu();\">";
833
834 echo "<div id=\"menu\" style=\"display:none; background-color:#ffff90\">
835 <div id=\"info\"></div>
836 <ul id=\"link\" style=\"list-style-type:none\"></ul>
837 </div>";
838
839 if($debug)
840 $gvmap->setFalseOnError(False);
841
842 $data2 = '';
843 $data = $gvmap->fetch($type, $command, 'cmapx', $data2);
844
845 if($data === false)
846 echo "ERROR Fetching image data!<br>";
847
848 if(PEAR::isError($data))
849 echo $data->getMessage();
850
851 //echo $gvmap->fetch('cmapx', $command);
852 echo $data2;
853
854 if($debug) echo "-- after map gvmap --<br>";
855
856 echo "<img src=\"data:$ctype;base64,".
857 base64_encode($data).
858 "\" usemap=#map$object_id />";
859
860 if($debug)
861 {
862 echo "<pre>";
863 echo $gvmap->export();
864 echo "</pre>";
865
866 echo "<pre>".$gvmap->parse()."</pre>";
867 }
868 }
869 else
870 {
871 $gvmap->image($type);
872 }
873
874 exit;
875
876} /* linkmgmt_opmap */
877
878/* ------------------------------------- */
879class linkmgmt_gvmap {
880
881 private $object_id = NULL;
882 private $port_id = NULL;
883 private $remote_id = NULL;
884
885 private $gv = NULL;
886
887 private $ports = array();
888
889 private $allports = false;
890 private $back = NULL;
891
892 private $alpha = 'ff';
893
894 private $errorlevel = NULL;
895
896 function __construct($object_id = NULL, $port_id = NULL, $allports = false, $hl = NULL, $remote_id = NULL) {
897 $this->allports = $allports;
898
899 $this->object_id = $object_id;
900 $this->port_id = $port_id;
901 $this->remote_id = $remote_id;
902
903 $hllabel = "";
904
905 /* suppress strict standards warnings for Image_GraphViz and PHP 5.4.0
906 * output would corrupt image data
907 */
908 $this->errorlevel = error_reporting();
909 error_reporting($this->errorlevel & ~E_STRICT);
910
911 $graphattr = array(
912 'rankdir' => 'RL',
913 // 'ranksep' => '0',
914 'nodesep' => '0',
915 // 'overlay' => false,
916 );
917
918 unset($_GET['module']);
919
920 $_GET['all'] = 1;
921
922 $graphattr['URL'] = $this->_makeHrefProcess($_GET);
923
924 unset($_GET['all']);
925
926 //$this->gv = new Image_GraphViz(true, $graphattr, "map".$object_id);
927 $this->gv = new lm_Image_GraphViz(true, $graphattr, "map".$object_id);
928
929 if($object_id === NULL)
930 {
931 /* all objects ! */
932 unset($_GET['all']);
933 $_GET['hl'] = 'o';
934
935 $this->gv->addAttributes(array(
936 'label' => 'Showing all objects'.$hllabel,
937 'labelloc' => 't',
938 )
939 );
940
941 $objects = listCells('object');
942
943 foreach($objects as $obj)
944 $this->_add($this->gv, $obj['id'], NULL);
945
946 return;
947 }
948 else
949 {
950 $object = spotEntity ('object', $object_id);
951
952 $this->gv->addAttributes(array(
953 'label' => "Graph for ${object['dname']}$hllabel",
954 'labelloc' => 't',
955 )
956 );
957
958 $this->_add($this->gv, $object_id, $port_id);
959
960 $children = getEntityRelatives ('children', 'object', $object_id); //'entity_id'
961
962 foreach($children as $child)
963 $this->_add($this->gv, $child['entity_id'], NULL);
964 }
965
966 switch($hl)
967 {
968 case 'p':
969 case 'port':
970 $hllabel = " (Port highlight)";
971 $this->alpha = '30';
972 $this->_add($this->gv, $object_id, NULL);
973 break;
974 case 'o':
975 case 'object':
976 $hllabel = " (Object highlight)";
977 $this->alpha = '30';
978 /* all objects */
979 $objects = listCells('object');
980
981 foreach($objects as $obj)
982 $this->_add($this->gv, $obj['id'], NULL);
983
984 break;
985
986 }
987
988 /* add hl label */
989 $this->gv->addAttributes(array(
990 'label' => $this->gv->graph['attributes']['label'].$hllabel,
991 ));
992
993 // portlist::var_dump_html($this->gv);
994
995 // $this->gv->saveParsedGraph('/tmp/graph.txt');
996 // error_reporting( E_ALL ^ E_NOTICE);
997 } /* __construct */
998
999 function __destruct() {
1000 error_reporting($this->errorlevel);
1001 }
1002
1003 function setFalseOnError($newvalue)
1004 {
1005 $this->gv->_returnFalseOnError = $newvalue;
1006 }
1007
1008 function _makeHrefProcess($array)
1009 {
1010 return str_replace('&','&amp;',makeHrefProcess($array));
1011 }
1012
1013 // !!!recursiv !!!
1014 function _add($gv, $object_id, $port_id = NULL) {
1015 global $lm_multilink_port_types;
1016
1017 if($port_id !== NULL) {
1018 if(isset($this->ports[$port_id])) {
1019 return;
1020 }
1021 }
1022
1023 if($this->back != 'front' || $port_id === NULL || $this->allports)
1024 $front = $this->_getObjectPortsAndLinks($object_id, 'front', $port_id, $this->allports);
1025 else
1026 $front = array();
1027
1028 if($this->back != 'back' || $port_id === NULL || $this->allports)
1029 $backend = $this->_getObjectPortsAndLinks($object_id, 'back', $port_id, $this->allports);
1030 else
1031 $backend = array();
1032
1033 $ports = array_merge($front,$backend);
1034
1035 /* used only for Graphviz ...
1036 * !! numeric ids cause Image_Graphviz problems on nested clusters !!
1037 */
1038 $cluster_id = "c$object_id";
1039
1040 if(empty($ports))
1041 {
1042 /* needed because of gv_image empty cluster bug (invalid foreach argument) */
1043 $gv->addNode('dummy', array(
1044 // 'label' =>'No Ports found/connected',
1045 'label' =>'',
1046 'fontsize' => 0,
1047 'size' => 0,
1048 'width' => 0,
1049 'height' => 0,
1050 'shape' => 'point',
1051 'style' => 'invis',
1052 ), $cluster_id);
1053
1054 /* show objects without ports */
1055 if($object_id === NULL)
1056 return;
1057 }
1058
1059 if($object_id !== NULL) {
1060 if(
1061 !isset($gv->graph['clusters'][$cluster_id]) &&
1062 !isset($gv->graph['subgraphs'][$cluster_id])
1063 ) {
1064
1065 $object = spotEntity ('object', $object_id);
1066 // $object['attr'] = getAttrValues($object_id);
1067
1068 $clusterattr = array();
1069
1070 $this->_getcolor('cluster', 'default', $this->alpha, $clusterattr, 'color');
1071 $this->_getcolor('cluster', 'default', $this->alpha, $clusterattr, 'fontcolor');
1072
1073 if($this->object_id == $object_id)
1074 {
1075 $clusterattr['rank'] = 'source';
1076
1077 $this->_getcolor('cluster', 'current', $this->alpha, $clusterattr, 'color');
1078 $this->_getcolor('cluster', 'current', $this->alpha, $clusterattr, 'fontcolor');
1079 }
1080
1081 $clustertitle = "${object['dname']}";
1082 $clusterattr['tooltip'] = $clustertitle;
1083
1084 unset($_GET['module']); // makeHrefProcess adds this
1085 unset($_GET['port_id']);
1086 unset($_GET['remote_id']);
1087 $_GET['object_id'] = $object_id;
1088 //$_GET['hl'] = 'o';
1089
1090 $clusterattr['URL'] = $this->_makeHrefProcess($_GET);
1091
1092 //has_problems
1093 if($object['has_problems'] != 'no')
1094 {
1095 $clusterattr['style'] = 'filled';
1096 $this->_getcolor('cluster', 'problem', $this->alpha, $clusterattr, 'fillcolor');
1097 }
1098
1099 if(!empty($object['container_name']))
1100 $clustertitle .= "<BR/>${object['container_name']}";
1101
1102 if($object['rack_id'])
1103 {
1104 $rack = spotEntity('rack', $object['rack_id']);
1105
1106 if(!empty($rack['row_name']) || !empty($rack['name']))
1107 $clustertitle .= "<BR/>${rack['row_name']} / ${rack['name']}";
1108 }
1109
1110 $embedin = $object['container_id'];
1111 if(empty($embedin))
1112 $embedin = 'default';
1113 else
1114 {
1115 $embedin = "c$embedin"; /* see cluster_id */
1116
1117 /* add container / cluster if not already exists */
1118 $this->_add($gv, $object['container_id'], NULL);
1119 }
1120
1121 $clusterattr['id'] = "$object_id----"; /* used for js context menu */
1122
1123 $gv->addCluster($cluster_id, $clustertitle, $clusterattr, $embedin);
1124
1125 } /* isset cluster_id */
1126 } /* object_id !== NULL */
1127
1128 foreach($ports as $key => $port) {
1129
1130 $this->back = $port['linktype'];
1131
1132 if(!isset($this->ports[$port['id']])) {
1133
1134
1135 $nodelabel = htmlspecialchars("${port['name']}");
1136
1137 if($port['iif_id'] != '1' )
1138 $nodelabel .= "<BR/><FONT POINT-SIZE=\"8\">${port['iif_name']}</FONT>";
1139
1140 $nodelabel .= "<BR/><FONT POINT-SIZE=\"8\">${port['oif_name']}</FONT>";
1141
1142 $nodeattr = array(
1143 'label' => $nodelabel,
1144 );
1145
1146 $this->_getcolor('port', 'default',$this->alpha, $nodeattr, 'fontcolor');
1147 $this->_getcolor('oif_id', $port['oif_id'],$this->alpha, $nodeattr, 'color');
1148
1149 if($this->port_id == $port['id']) {
1150 $nodeattr['style'] = 'filled';
1151 $nodeattr['fillcolor'] = $this->_getcolor('port', 'current', $this->alpha);
1152 }
1153
1154 if($this->remote_id == $port['id']) {
1155 $nodeattr['style'] = 'filled';
1156 $nodeattr['fillcolor'] = $this->_getcolor('port', 'remote', $this->alpha);
1157 }
1158
1159 $nodeattr['tooltip'] = htmlspecialchars("${port['name']}");
1160
1161 unset($_GET['module']);
1162 unset($_GET['remote_id']);
1163 $_GET['object_id'] = $port['object_id'];
1164 $_GET['port_id'] = $port['id'];
1165 $_GET['hl'] = 'p';
1166
1167 $nodeattr['URL'] = $this->_makeHrefProcess($_GET);
1168 $nodeattr['id'] = "${port['object_id']}-${port['id']}--"; /* for js context menu */
1169
1170 $gv->addNode($port['id'],
1171 $nodeattr,
1172 "c${port['object_id']}"); /* see cluster_id */
1173
1174 $this->ports[$port['id']] = true;
1175
1176 } /* isset port */
1177
1178 if(!empty($port['remote_id'])) {
1179
1180 if($this->object_id !== NULL)
1181 $this->_add($gv, $port['remote_object_id'], $port['remote_id']);
1182
1183 if(
1184 !isset($gv->graph['edgesFrom'][$port['id']][$port['remote_id']]) &&
1185 !isset($gv->graph['edgesFrom'][$port['remote_id']][$port['id']])
1186 ) {
1187
1188 $linktype = $port['linktype'];
1189
1190 $edgetooltip = $port['object_name'].':'.$port['name'].
1191 ' - '.$port['cableid'].' -> '.
1192 $port['remote_name'].':'.$port['remote_object_name'];
1193
1194 $edgeattr = array(
1195 'fontsize' => 8,
1196 'label' => htmlspecialchars($port['cableid']),
1197 'tooltip' => $edgetooltip,
1198 'sametail' => $linktype,
1199 'samehead' => $linktype,
1200 );
1201
1202 $this->_getcolor('edge', 'default', $this->alpha, $edgeattr, 'color');
1203 $this->_getcolor('edge', 'default', $this->alpha, $edgeattr, 'fontcolor');
1204
1205 if($linktype == 'back' )
1206 {
1207 $edgeattr['style'] = 'dashed';
1208 $edgeattr['arrowhead'] = 'none';
1209 $edgeattr['arrowtail'] = 'none';
1210
1211 /* multilink ports */
1212 if(in_array($port['oif_id'], $lm_multilink_port_types))
1213 {
1214 $edgeattr['dir'] = 'both';
1215 $edgeattr['arrowtail'] = 'dot';
1216 }
1217
1218 if(in_array($port['remote_oif_id'], $lm_multilink_port_types))
1219 {
1220 $edgeattr['dir'] = 'both';
1221 $edgeattr['arrowhead'] = 'dot';
1222 }
1223 }
1224
1225 if(
1226 ($port['id'] == $this->port_id && $port['remote_id'] == $this->remote_id) ||
1227 ($port['id'] == $this->remote_id && $port['remote_id'] == $this->port_id)
1228 )
1229 {
1230 $this->_getcolor('edge', 'highlight', 'ff', $edgeattr, 'color');
1231 $edgeattr['penwidth'] = 2; /* bold */
1232 }
1233
1234 unset($_GET['module']);
1235 $_GET['object_id'] = $port['object_id'];
1236 $_GET['port_id'] = $port['id'];
1237 $_GET['remote_id'] = $port['remote_id'];
1238
1239 $edgeattr['URL'] = $this->_makeHrefProcess($_GET);
1240
1241 $edgeattr['id'] = $port['object_id']."-".$port['id']."-".$port['remote_id']."-".$linktype; /* for js context menu */
1242
1243 $gv->addEdge(array($port['id'] => $port['remote_id']),
1244 $edgeattr,
1245 array(
1246 $port['id'] => $linktype,
1247 $port['remote_id'] => $linktype,
1248 )
1249 );
1250 }
1251 }
1252
1253 }
1254
1255 // portlist::var_dump_html($port);
1256 }
1257
1258 function fetch($type = 'png', $command = NULL, $format2 = NULL, &$data2 = NULL) {
1259
1260 $tmpdata = $data2;
1261 $ret = $this->gv->fetch($type, $command, $format2, $tmpdata);
1262 if($data2 !== NULL)
1263 $data2 = $tmpdata;
1264 return $ret;
1265 }
1266
1267 function image($type = 'png', $command = NULL) {
1268 $this->gv->image($type, $command);
1269 }
1270
1271 function parse() {
1272 return $this->gv->parse();
1273 }
1274
1275 /* should be compatible with getObjectPortsAndLinks from RT database.php */
1276 function _getObjectPortsAndLinks($object_id, $linktype = 'front', $port_id = NULL, $allports = false) {
1277
1278 if($linktype == 'front')
1279 $linktable = 'Link';
1280 else
1281 $linktable = 'LinkBackend';
1282
1283 $qparams = array();
1284
1285 $query = "SELECT
1286 '$linktype' as linktype,
1287 Port.*,
1288 Port.type AS oif_id,
1289 PortInnerInterface.iif_name as iif_name,
1290 POI.oif_name as oif_name,
1291 Object.id as object_id, Object.name as object_name,
1292 IFNULL(LinkTable_a.cable,LinkTable_b.cable) as cableid,
1293 remoteObject.id as remote_object_id, remoteObject.name as remote_object_name,
1294 remotePort.id as remote_id, remotePort.name as remote_name,
1295 remotePort.type AS remote_oif_id,
1296 remotePortInnerInterface.iif_name as remote_iif_name,
1297 remotePOI.oif_name as remote_oif_name
1298 FROM Port";
1299
1300 // JOIN
1301 $join = " LEFT JOIN PortInnerInterface on PortInnerInterface.id = Port.iif_id
1302 LEFT JOIN PortOuterInterface AS POI on POI.id = Port.type
1303 LEFT JOIN $linktable as LinkTable_a on Port.id = LinkTable_a.porta
1304 LEFT JOIN $linktable as LinkTable_b on Port.id = LinkTable_b.portb
1305 LEFT JOIN Object on Object.id = Port.object_id
1306 LEFT JOIN Port as remotePort on remotePort.id = IFNULL(LinkTable_a.portb, LinkTable_b.porta)
1307 LEFT JOIN Object as remoteObject on remoteObject.id = remotePort.object_id
1308 LEFT JOIN PortInnerInterface as remotePortInnerInterface on remotePortInnerInterface.id = remotePort.iif_id
1309 LEFT JOIN PortOuterInterface as remotePOI on remotePOI.id = remotePort.type
1310 ";
1311
1312 // WHERE
1313 if($port_id === NULL)
1314 {
1315 $where = " WHERE Object.id = ?";
1316 $qparams[] = $object_id;
1317
1318 if(!$allports) {
1319 $where .= " AND remotePort.id is not NULL";
1320
1321 if($linktype != 'front') {
1322 $join .= "
1323 LEFT JOIN Link as FrontLink_a on Port.id = FrontLink_a.porta
1324 LEFT JOIN Link as FrontLink_b on Port.id = FrontLink_b.portb
1325 LEFT JOIN Link as FrontRemoteLink_a on remotePort.id = FrontRemoteLink_a.porta
1326 LEFT JOIN Link as FrontRemoteLink_b on remotePort.id = FrontRemoteLink_b.portb
1327 ";
1328 $where .= " AND ( (FrontLink_a.porta is not NULL or FrontLink_b.portb is not NULL )
1329 OR (FrontRemoteLink_a.porta is not NULL or FrontRemoteLink_b.portb is not NULL) )";
1330 }
1331 }
1332 }
1333 else
1334 {
1335 // $where = " WHERE Port.id = ? and remotePort.id is not NULL";
1336 $where = " WHERE Port.id = ?";
1337 $qparams[] = $port_id;
1338 }
1339
1340 // ORDER
1341 $order = " ORDER by oif_name, Port.Name";
1342
1343 $query .= $join.$where.$order;
1344
1345 //echo "$port_id: $query<br><br>";
1346
1347 $result = usePreparedSelectBlade ($query, $qparams);
1348
1349 $row = $result->fetchAll(PDO::FETCH_ASSOC);
1350
1351 $result->closeCursor();
1352
1353 return $row;
1354 }
1355
1356 function _getcolor($type = 'object', $key = 'default', $alpha = 'ff', &$array = NULL , $arraykey = 'color') {
1357
1358 $object = array(
1359 'current' => '#ff0000',
1360 );
1361 $port = array(
1362 'current' => '#ffff90',
1363 'remote' => '#ffffD0',
1364 );
1365
1366 $cluster = array(
1367 'current' => '#ff0000',
1368 'problem' => '#ff3030',
1369 );
1370
1371 $edge = array (
1372 'highlight' => '#ff0000',
1373 );
1374
1375 $oif_id = array(
1376 '16' => '#800000', /* AC-in */
1377 '1322' => '#ff4500', /* AC-out */
1378 '24' => '#000080', /* 1000base-t */
1379 );
1380
1381 $defaultcolor = '#000000'; /* black */
1382 $default = true;
1383
1384 if(isset(${$type}[$key]))
1385 {
1386 $default = false;
1387 $color = ${$type}[$key];
1388 }
1389 else
1390 $color = $defaultcolor;
1391
1392
1393 if($alpha != 'ff' || $default == false)
1394 {
1395 $color .= $alpha;
1396
1397 if($array !== NULL)
1398 $array[$arraykey] = $color;
1399 else
1400 return $color;
1401 }
1402 else
1403 return $defaultcolor;
1404
1405 } /* _getcolor */
1406
1407 function dump() {
1408 var_dump($this->gv);
1409 }
1410
1411 function export() {
1412 var_export($this->gv);
1413 }
1414
1415} /* class gvmap */
1416
1417/* -------------------------------------------------- */
1418
1419function linkmgmt_opupdate() {
1420
1421 if(!isset($_POST['id']))
1422 exit;
1423
1424 $ids = explode('_',$_POST['id'],3);
1425 $retval = strip_tags($_POST['value']);
1426
1427 if(isset($ids[1])) {
1428 if(permitted(NULL, NULL, 'set_link'))
1429 if(isset($ids[2]) && $ids[2] == 'back')
1430 linkmgmt_commitUpdatePortLink($ids[0], $ids[1], $retval, TRUE);
1431 else
1432 linkmgmt_commitUpdatePortLink($ids[0], $ids[1], $retval);
1433 else
1434 $retval = "Permission denied!";
1435 } else {
1436 if(permitted(NULL, NULL, 'set_reserve_comment'))
1437 commitUpdatePortComment($ids[0], $retval);
1438 else
1439 $retval = "Permission denied!";
1440 }
1441
1442 /* return what jeditable should display after edit */
1443 echo $retval;
1444
1445 exit;
1446} /* opupdate */
1447
1448/* -------------------------------------------------- */
1449
1450/* similar to commitUpatePortLink in database.php with backend support */
1451function linkmgmt_commitUpdatePortLink($port_id1, $port_id2, $cable = NULL, $backend = FALSE) {
1452
1453 /* TODO check permissions */
1454
1455 if($backend)
1456 $table = 'LinkBackend';
1457 else
1458 $table = 'Link';
1459
1460 return usePreparedExecuteBlade
1461 (
1462 "UPDATE $table SET cable=\"".(mb_strlen ($cable) ? $cable : NULL).
1463 "\" WHERE ( porta = ? and portb = ?) or (portb = ? and porta = ?)",
1464 array (
1465 $port_id1, $port_id2,
1466 $port_id1, $port_id2)
1467 );
1468
1469} /* linkmgmt_commitUpdatePortLink */
1470
1471/* -------------------------------------------------- */
1472
1473function linkmgmt_opunlinkPort() {
1474 $port_id = $_REQUEST['port_id'];
1475 $linktype = $_REQUEST['linktype'];
1476
1477 portlist::var_dump_html($_REQUEST);
1478
1479 /* check permissions */
1480 if(!permitted(NULL, NULL, 'set_link')) {
1481 exit;
1482 }
1483
1484 if($linktype == 'back')
1485 {
1486 $table = 'LinkBackend';
1487 $remote_id = $_REQUEST['remote_id'];
1488
1489 $retval = usePreparedExecuteBlade
1490 (
1491 "DELETE FROM $table WHERE ( porta = ? and portb = ?) or (portb = ? and porta = ?)",
1492 array (
1493 $port_id, $remote_id,
1494 $port_id, $remote_id)
1495 );
1496 }
1497 else
1498 {
1499 $table = 'Link';
1500
1501 $retval = usePreparedDeleteBlade ($table, array('porta' => $port_id, 'portb' => $port_id), 'OR');
1502 }
1503
1504 if($retval == 0)
1505 echo " Link not found";
1506 else
1507 echo " $retval Links deleted";
1508
1509
1510 unset($_GET['module']);
1511 unset($_GET['op']);
1512
1513 header('Location: ?'.http_build_query($_GET));
1514 //header('Location: ?page='.$_REQUEST['page'].'&tab='.$_REQUEST['tab'].'&object_id='.$_REQUEST['object_id']);
1515 exit;
1516} /* opunlinkPort */
1517
1518/* -------------------------------------------------- */
1519
1520function linkmgmt_oplinkPort() {
1521
1522 $linktype = $_REQUEST['linktype'];
1523 $cable = $_REQUEST['cable'];
1524
1525 /* check permissions */
1526 if(!permitted(NULL, NULL, 'set_link')) {
1527 echo("Permission denied!");
1528 return;
1529 }
1530
1531 if(!isset($_REQUEST['link_list'])) {
1532 //portlist::var_dump_html($_REQUEST);
1533 $porta = $_REQUEST['port'];
1534
1535 foreach($_REQUEST['remote_ports'] as $portb)
1536 {
1537 $link_list[] = "${porta}_${portb}";
1538
1539 /* with no LM_MULTILINK process first value only */
1540 if(!LM_MULTILINK)
1541 break;
1542 }
1543 } else
1544 $link_list = $_REQUEST['link_list'];
1545
1546 foreach($link_list as $link){
1547
1548 $ids = preg_split('/[^0-9]/',$link);
1549 $porta = $ids[0];;
1550 $portb = $ids[1];
1551
1552 $ret = linkmgmt_linkPorts($porta, $portb, $linktype, $cable);
1553
1554 //error_log("$ret - $porta - $portb");
1555 $port_info = getPortInfo ($porta);
1556 $remote_port_info = getPortInfo ($portb);
1557 showSuccess(
1558 sprintf
1559 (
1560 'Port %s %s successfully linked with port %s %s',
1561 formatPortLink ($port_info['id'], $port_info['name'], NULL, NULL),
1562 $linktype,
1563 formatPort ($remote_port_info),
1564 $linktype
1565 )
1566 );
1567 }
1568
1569 addJS (<<<END
1570window.opener.location.reload(true);
1571window.close();
1572END
1573 , TRUE);
1574
1575 return;
1576} /* oplinkPort */
1577
1578/* -------------------------------------------------- */
1579
1580/*
1581 * same as in database.php extendend with linktype
1582 */
1583function linkmgmt_linkPorts ($porta, $portb, $linktype, $cable = NULL)
1584{
1585 if ($porta == $portb)
1586 throw new InvalidArgException ('porta/portb', $porta, "Ports can't be the same");
1587
1588 if($linktype == 'back')
1589 {
1590 $table = 'LinkBackend';
1591 $multilink = LM_MULTILINK;
1592 }
1593 else
1594 {
1595 $table = 'Link';
1596 $multilink = false;
1597 }
1598
1599 global $dbxlink;
1600 $dbxlink->exec ('LOCK TABLES '.$table.' WRITE');
1601
1602 if(!$multilink)
1603 {
1604 $result = usePreparedSelectBlade
1605 (
1606 'SELECT COUNT(*) FROM '.$table.' WHERE porta IN (?,?) OR portb IN (?,?)',
1607 array ($porta, $portb, $porta, $portb)
1608 );
1609
1610 if ($result->fetchColumn () != 0)
1611 {
1612 $dbxlink->exec ('UNLOCK TABLES');
1613 return "$linktype Port ${porta} or ${portb} is already linked";
1614 }
1615 $result->closeCursor ();
1616 }
1617
1618 if ($porta > $portb)
1619 {
1620 $tmp = $porta;
1621 $porta = $portb;
1622 $portb = $tmp;
1623 }
1624 $ret = FALSE !== usePreparedInsertBlade
1625 (
1626 $table,
1627 array
1628 (
1629 'porta' => $porta,
1630 'portb' => $portb,
1631 'cable' => mb_strlen ($cable) ? $cable : ''
1632 )
1633 );
1634 $dbxlink->exec ('UNLOCK TABLES');
1635 $ret = $ret and FALSE !== usePreparedExecuteBlade
1636 (
1637 'UPDATE Port SET reservation_comment=NULL WHERE id IN(?, ?)',
1638 array ($porta, $portb)
1639 );
1640 return $ret ? '' : 'query failed';
1641}
1642
1643/* -------------------------------------------------- */
1644
1645/*
1646 * similar to renderPopupHTML in popup.php
1647 */
1648function linkmgmt_opPortLinkDialog() {
1649// portlist::var_dump_html($_REQUEST);
1650header ('Content-Type: text/html; charset=UTF-8');
1651?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1652<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" style="height: 100%;">
1653<?php
1654
1655 $text = '<div style="background-color: #f0f0f0; border: 1px solid #3c78b5; padding: 10px; text-align: center;
1656 margin: 5px;">';
1657
1658 if(permitted(NULL,NULL,"set_link"))
1659 if (isset ($_REQUEST['do_link'])) {
1660 $text .= getOutputOf ('linkmgmt_oplinkPort');
1661 }
1662 else
1663 if(isset($_REQUEST['byname']))
1664 $text .= getOutputOf ('linkmgmt_renderPopupPortSelectorbyName');
1665 else
1666 $text .= getOutputOf ('linkmgmt_renderPopupPortSelector');
1667 else
1668 $text .= "Permission denied!";
1669
1670 $text .= '</div>';
1671
1672 echo '<head><title>RackTables pop-up</title>';
1673 printPageHeaders();
1674 echo '</head>';
1675 echo '<body style="height: 100%;">' . $text . '</body>';
1676?>
1677</html>
1678<?php
1679 exit;
1680} /* opPortLinkDialog */
1681
1682/* -------------------------------------------------- */
1683
1684/*
1685 * like findSparePorts in popup.php extended with linktype
1686 *
1687 * multilink
1688 *
1689 */
1690function linkmgmt_findSparePorts($port_info, $filter, $linktype, $multilink = false, $objectsonly = false, $byname = false, $portcompat = true, $src_object_id = NULL) {
1691
1692
1693 /*
1694 $linktable ports that will be returned if not linked in this table
1695 $linkinfotable display link for info only show backend links if you want front link a port
1696
1697 front: select ports no front connection and port compat, filter, ...
1698
1699 back:
1700
1701 */
1702
1703 if($linktype == 'back')
1704 {
1705 $linktable = 'LinkBackend';
1706 $linkinfotable = 'Link';
1707 }
1708 else
1709 {
1710 $linktable = 'Link';
1711 $linkinfotable = 'LinkBackend';
1712 }
1713
1714 $qparams = array();
1715 $whereparams = array();
1716
1717 // all ports with no link
1718 /* port:object -> linked port:object */
1719 $query = 'SELECT';
1720 $join = "";
1721 $where = " WHERE";
1722 $group = "";
1723 $order = " ORDER BY";
1724
1725 if($objectsonly)
1726 {
1727 $query .= " remotePort.object_id, CONCAT(IFNULL(remoteObject.name, CONCAT('[',remoteObjectDictionary.dict_value,']')), ' (', count(remotePort.id), ')') as name";
1728 $group .= " GROUP by remoteObject.id";
1729 }
1730 else
1731 if($byname)
1732 {
1733 if($linktype == 'back')
1734 $arrow = '=?=>';
1735 else
1736 $arrow = '-?->';
1737
1738 $query .= ' CONCAT(localPort.id, "_", remotePort.id),
1739 CONCAT(IFNULL(localObject.name, CONCAT("[",localObjectDictionary.dict_value,"]")), " : ", localPort.Name, " '.$arrow.'", remotePort.name, " : ", IFNULL(remoteObject.name,CONCAT("[",remoteObjectDictionary.dict_value,"]")))';
1740 }
1741 else
1742 {
1743
1744 if($linktype == 'front')
1745 $arrow = '==';
1746 else
1747 $arrow = '--';
1748
1749 $query .= " remotePort.id, CONCAT(IFNULL(remoteObject.name, CONCAT('[',remoteObjectDictionary.dict_value,']')), ' : ', remotePort.name,
1750 IFNULL(CONCAT(' $arrow ', IFNULL(IFNULL(infolnk_a.cable,infolnk_b.cable),''), ' $arrow> ', InfoPort.name, ' : ', IFNULL(InfoObject.name,CONCAT('[',InfoObjectDictionary.dict_value,']'))),'') ) as Text";
1751 }
1752
1753 $query .= " FROM Port as remotePort";
1754 $join .= " LEFT JOIN Object as remoteObject on remotePort.object_id = remoteObject.id";
1755 $order .= " remoteObject.name";
1756
1757 /* object type name */
1758 $join .= " LEFT JOIN Dictionary as remoteObjectDictionary on (remoteObjectDictionary.chapter_id = 1 AND remoteObject.objtype_id = remoteObjectDictionary.dict_key)";
1759
1760 if($byname)
1761 {
1762 /* by name */
1763 $join .= " JOIN Port as localPort on remotePort.name = localPort.name";
1764 $where .= " remotePort.object_id <> ? AND localPort.object_id = ?";
1765 $whereparams[] = $src_object_id;
1766 $whereparams[] = $src_object_id;
1767
1768 /* own port not linked */
1769 $join .= " LEFT JOIN $linktable as localLink_a on localPort.id = localLink_a.porta";
1770 $where .= " AND localLink_a.porta is NULL";
1771 $join .= " LEFT JOIN $linktable as localLink_b on localPort.id = localLink_b.portb";
1772 $where .= " AND localLink_b.portb is NULL";
1773 $join .= " LEFT JOIN Object as localObject on localObject.id = localPort.object_id";
1774
1775 /* object type name */
1776 $join .= " LEFT JOIN Dictionary as localObjectDictionary on (localObject.objtype_id = localObjectDictionary.dict_key AND localObjectDictionary.chapter_id = 1)";
1777 }
1778 else
1779 {
1780 /* exclude current port */
1781 $where .= " remotePort.id <> ?";
1782 $whereparams[] = $port_info['id'];
1783 $order .= " ,remotePort.name";
1784
1785 /* add info to remoteport */
1786 $join .= " LEFT JOIN $linkinfotable as infolnk_a on remotePort.id = infolnk_a.porta";
1787 $join .= " LEFT JOIN $linkinfotable as infolnk_b on remotePort.id = infolnk_b.portb";
1788 $join .= " LEFT JOIN Port as InfoPort on InfoPort.id = IFNULL(infolnk_a.portb, infolnk_b.porta)";
1789 $join .= " LEFT JOIN Object as InfoObject on InfoObject.id = InfoPort.object_id";
1790
1791 /* object type name */
1792 $join .= " LEFT JOIN Dictionary as InfoObjectDictionary on (InfoObject.objtype_id = InfoObjectDictionary.dict_key AND InfoObjectDictionary.chapter_id = 1)";
1793 }
1794
1795 /* only ports which are not linked already */
1796 $join .= " LEFT JOIN $linktable as lnk_a on remotePort.id = lnk_a.porta";
1797 $where .= " AND lnk_a.porta is NULL";
1798 $join .= " LEFT JOIN $linktable as lnk_b on remotePort.id = lnk_b.portb";
1799 $where .= " AND lnk_b.portb is NULL";
1800
1801 if($portcompat)
1802 {
1803 /* port compat */
1804 $join .= ' INNER JOIN PortInnerInterface pii ON remotePort.iif_id = pii.id
1805 INNER JOIN PortOuterInterface poi ON remotePort.type = poi.id';
1806 // porttype filter (non-strict match)
1807 $join .= ' INNER JOIN (
1808 SELECT Port.id FROM Port
1809 INNER JOIN
1810 (
1811 SELECT DISTINCT pic2.iif_id
1812 FROM PortInterfaceCompat pic2
1813 INNER JOIN PortCompat pc ON pc.type2 = pic2.oif_id';
1814
1815 if ($port_info['iif_id'] != 1)
1816 {
1817 $join .= " INNER JOIN PortInterfaceCompat pic ON pic.oif_id = pc.type1 WHERE pic.iif_id = ?";
1818 $qparams[] = $port_info['iif_id'];
1819 }
1820 else
1821 {
1822 $join .= " WHERE pc.type1 = ?";
1823 $qparams[] = $port_info['oif_id'];
1824 }
1825 $join .= " AND pic2.iif_id <> 1
1826 ) AS sub1 USING (iif_id)
1827 UNION
1828 SELECT Port.id
1829 FROM Port
1830 INNER JOIN PortCompat ON type1 = type
1831 WHERE iif_id = 1 and type2 = ?
1832 ) AS sub2 ON sub2.id = remotePort.id";
1833 $qparams[] = $port_info['oif_id'];
1834 }
1835
1836
1837 $qparams = array_merge($qparams, $whereparams);
1838
1839 // rack filter
1840 if (! empty ($filter['racks']))
1841 {
1842 $where .= ' AND remotePort.object_id IN (SELECT DISTINCT object_id FROM RackSpace WHERE rack_id IN (' .
1843 questionMarks (count ($filter['racks'])) . ')) ';
1844 $qparams = array_merge ($qparams, $filter['racks']);
1845 }
1846
1847 // object_id filter
1848 if (! empty ($filter['object_id']))
1849 {
1850 $where .= ' AND remoteObject.id = ?';
1851 $qparams[] = $filter['object_id'];
1852 }
1853 else
1854 // objectname filter
1855 if (! empty ($filter['objects']))
1856 {
1857 $where .= ' AND remoteObject.name like ? ';
1858 $qparams[] = '%' . $filter['objects'] . '%';
1859 }
1860
1861 // portname filter
1862 if (! empty ($filter['ports']))
1863 {
1864 $where .= ' AND remotePort.name LIKE ? ';
1865 $qparams[] = '%' . $filter['ports'] . '%';
1866 }
1867
1868 $query .= $join.$where.$group.$order;
1869
1870 $result = usePreparedSelectBlade ($query, $qparams);
1871
1872 $row = $result->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_COLUMN);
1873
1874 $result->closeCursor();
1875
1876 /* [id] => displaystring */
1877 return $row;
1878
1879} /* findSparePorts */
1880
1881/* -------------------------------------------------- */
1882
1883/*
1884 * like renderPopupPortSelector in popup.php extenden with linktype
1885 */
1886function linkmgmt_renderPopupPortSelector()
1887{
1888 global $lm_multilink_port_types;
1889
1890 assertUIntArg ('port');
1891 $port_id = $_REQUEST['port'];
1892
1893 $showlinktypeswitch = false;
1894
1895 if(isset($_GET['linktype']))
1896 $linktype = $_GET['linktype'];
1897 else
1898 $linktype = 'front';
1899
1900 if($linktype == 'both')
1901 {
1902
1903 /*
1904 * use POST front/back_view to set linktype
1905 * and show linktype switch button
1906 */
1907
1908 $showlinktypeswitch = true;
1909
1910 if(isset($_POST['front_view']))
1911 $linktype = 'front';
1912 else
1913 if(isset($_POST['back_view']))
1914 $linktype = 'back';
1915 else
1916 $linktype = 'front';
1917 }
1918
1919// portlist::var_dump_html($_POST);
1920
1921 $portcompat = true;
1922
1923 if($linktype == 'back')
1924 {
1925 if(isset($_POST['portcompat']))
1926 $portcompat = $_POST['portcompat'];
1927 }
1928
1929 $object_id = $_REQUEST['object_id'];
1930 $port_info = getPortInfo ($port_id);
1931
1932 $multilink = LM_MULTILINK && $linktype == 'back' && in_array($port_info['oif_id'], $lm_multilink_port_types);
1933
1934 if(isset ($_REQUEST['in_rack']))
1935 $in_rack = $_REQUEST['in_rack'] != 'off';
1936 else
1937 $in_rack = true;
1938
1939// portlist::var_dump_html($port_info);
1940// portlist::var_dump_html($_GET);
1941// portlist::var_dump_html($_POST);
1942
1943 // fill port filter structure
1944 $filter = array
1945 (
1946 'racks' => array(),
1947 'objects' => '',
1948 'object_id' => '',
1949 'ports' => '',
1950 );
1951
1952 $remote_object = NULL;
1953 if(isset($_REQUEST['remote_object']))
1954 {
1955 $remote_object = $_REQUEST['remote_object'];
1956
1957 if($remote_object != 'NULL')
1958 $filter['object_id'] = $remote_object;
1959 }
1960
1961 if (isset ($_REQUEST['filter-obj']))
1962 $filter['objects'] = $_REQUEST['filter-obj'];
1963 if (isset ($_REQUEST['filter-port']))
1964 $filter['ports'] = $_REQUEST['filter-port'];
1965 if ($in_rack)
1966 {
1967 $object = spotEntity ('object', $port_info['object_id']);
1968 if ($object['rack_id'])
1969 $filter['racks'] = getProximateRacks ($object['rack_id'], getConfigVar ('PROXIMITY_RANGE'));
1970 }
1971
1972 $objectlist = array('NULL' => '- Show All -');
1973 $objectlist = $objectlist + linkmgmt_findSparePorts($port_info, $filter, $linktype, $multilink, true, false, $portcompat);
1974
1975 $spare_ports = linkmgmt_findSparePorts ($port_info, $filter, $linktype, $multilink, false, false, $portcompat);
1976
1977 $maxsize = getConfigVar('MAXSELSIZE');
1978 $objectcount = count($objectlist);
1979
1980 if($linktype == 'back')
1981 $notlinktype = 'front';
1982 else
1983 $notlinktype = 'back';
1984
1985 // display search form
1986 echo 'Link '.$linktype.' of ' . formatPort ($port_info) . ' to...';
1987 echo '<form method=POST>';
1988 startPortlet ($linktype.' Port list filter');
1989 // echo '<input type=hidden name="module" value="popup">';
1990 // echo '<input type=hidden name="helper" value="portlist">';
1991
1992 echo '<input type=hidden name="port" value="' . $port_id . '">';
1993 echo '<table><tr><td valign="top"><table><tr><td>';
1994
1995 echo '<table align="center"><tr>';
1996
1997// echo '<td nowrap="nowrap"><input type="hidden" name="linktype" value="front" /><input type="checkbox" name="linktype" value="back"'.($linktype == 'back' ? ' checked="checked"' : '' ).'>link backend</input></td></tr><tr>';
1998 echo '<td class="tdleft"><label>Object name:<br><input type=text size=8 name="filter-obj" value="' . htmlspecialchars ($filter['objects'], ENT_QUOTES) . '"></label></td>';
1999 echo '<td class="tdleft"><label>Port name:<br><input type=text size=6 name="filter-port" value="' . htmlspecialchars ($filter['ports'], ENT_QUOTES) . '"></label></td>';
2000 echo '<td class="tdleft" valign="bottom"><input type="hidden" name="in_rack" value="off" /><label><input type=checkbox value="1" name="in_rack"'.($in_rack ? ' checked="checked"' : '').' onchange="this.form.submit();">Nearest racks</label></td>';
2001 echo '</tr></table>';
2002
2003 echo '</td></tr><tr><td>';
2004 echo 'Object name (count ports)<br>';
2005 echo getSelect ($objectlist, array ('name' => 'remote_object',
2006 'size' => ($objectcount <= $maxsize ? $objectcount : $maxsize)),
2007 $remote_object, FALSE);
2008
2009 echo '</td></tr></table></td>';
2010 echo '<td valign="top"><table><tr><td><input type=submit value="update objects / ports"></td></tr>';
2011
2012 if($showlinktypeswitch)
2013 echo '<tr height=150px><td><input type=submit value="Switch to '.$notlinktype.' view" name="'.$notlinktype.'_view"></tr></td>';
2014
2015 if($linktype == 'back')
2016 {
2017 echo '<input type="hidden" name="portcompat" value="0">';
2018 echo '<tr height=150px><td><input type=checkbox onchange="this.form.submit();" name="portcompat"'.( $portcompat ? 'checked="checked" ' : '' ).'value="1">Port Compatibility</input></tr></td>';
2019 echo '<input type="hidden" name="back_view">';
2020 }
2021
2022 echo '</table></td>';
2023
2024 finishPortlet();
2025 echo '</td><td>';
2026
2027 // display results
2028 startPortlet ('Compatible spare '.$linktype.' ports');
2029 echo "spare $linktype Object:Port -- $notlinktype cableID --> $notlinktype Port:Object<br>";
2030
2031 if($multilink)
2032 echo "Multilink<br>";
2033
2034 if (empty ($spare_ports))
2035 echo '(nothing found)';
2036 else
2037 {
2038 $linkcount = count($spare_ports);
2039
2040 $options = array(
2041 'name' => 'remote_ports[]',
2042 'size' => getConfigVar ('MAXSELSIZE'),
2043 'size' => ($linkcount <= $maxsize ? $linkcount : $maxsize),
2044 );
2045
2046 if($multilink)
2047 $options['multiple'] = 'multiple';
2048
2049 echo getSelect ($spare_ports, $options, NULL, FALSE);
2050
2051 echo "<p>$linktype Cable ID: <input type=text id=cable name=cable>";
2052 echo "<p><input type='submit' value='Link $linktype' name='do_link'>";
2053 }
2054 finishPortlet();
2055 echo '</td></tr></table>';
2056 echo '</form>';
2057
2058} /* linkmgmt_renderPopUpPortSelector */
2059
2060/* -------------------------------------------------- */
2061
2062/*
2063 * similar to renderPopupPortSelector but let you select the destination object
2064 * and displays possible backend links with ports of the same name
2065 */
2066function linkmgmt_renderPopupPortSelectorbyName()
2067{
2068 $linktype = $_REQUEST['linktype'];
2069 $object_id = $_REQUEST['object_id'];
2070
2071 $object = spotEntity ('object', $object_id);
2072
2073 $objectlist = linkmgmt_findSparePorts(NULL, NULL, $linktype, false, true, TRUE, false, $object_id);
2074
2075 $objectname = $object['dname'];
2076
2077 /* remove self from list */
2078 unset($objectlist[$object_id]);
2079
2080 if(isset($_REQUEST['remote_object']))
2081 $remote_object = $_REQUEST['remote_object'];
2082 else
2083 {
2084 /* choose first object from list */
2085 $keys = array_keys($objectlist);
2086
2087 if(isset($keys[0]))
2088 $remote_object = $keys[0];
2089 else
2090 $remote_object = NULL;
2091 }
2092
2093 if($remote_object)
2094 {
2095 $filter['object_id'] = $remote_object;
2096 $link_list = linkmgmt_findSparePorts(NULL, $filter, $linktype, false, false, TRUE, false, $object_id);
2097 }
2098 else
2099 $link_list = linkmgmt_findSparePorts(NULL, NULL, $linktype, false, false, TRUE, false, $object_id);
2100
2101 // display search form
2102 echo 'Link '.$linktype.' of ' . formatPortLink($object_id, $objectname, NULL, NULL) . ' Ports by Name to...';
2103 echo '<form method=POST>';
2104
2105 echo '<table align="center"><tr><td>';
2106 startPortlet ('Object list');
2107
2108 $maxsize = getConfigVar('MAXSELSIZE');
2109 $objectcount = count($objectlist);
2110
2111 echo 'Object name (count ports)<br>';
2112 echo getSelect ($objectlist, array ('name' => 'remote_object',
2113 'size' => ($objectcount <= $maxsize ? $objectcount : $maxsize)),
2114 $remote_object, FALSE);
2115 echo '</td><td><input type=submit value="show '.$linktype.' ports>"></td>';
2116 finishPortlet();
2117
2118 echo '<td>';
2119 // display results
2120 startPortlet ('Possible Backend Link List');
2121 echo "Select links to create:<br>";
2122 if (empty ($link_list))
2123 echo '(nothing found)';
2124 else
2125 {
2126 $linkcount = count($link_list);
2127
2128 $options = array(
2129 'name' => 'link_list[]',
2130 'size' => ($linkcount <= $maxsize ? $linkcount : $maxsize),
2131 'multiple' => 'multiple',
2132 );
2133
2134 echo getSelect ($link_list,$options, NULL, FALSE);
2135
2136 echo "<p>$linktype Cable ID: <input type=text id=cable name=cable>";
2137 echo "<p><input type='submit' value='Link $linktype' name='do_link'>";
2138 }
2139 finishPortlet();
2140 echo '</td></tr></table>';
2141 echo '</form>';
2142
2143} /* linkmgmt_renderPopUpPortSelectorByName */
2144
2145/* ------------------------------------------------ */
2146
2147function linkmgmt_tabhandler($object_id) {
2148 global $lm_cache;
2149
2150 $target = makeHrefProcess(portlist::urlparams('op','update'));
2151
2152 addJS('js/jquery.jeditable.mini.js');
2153
2154 /* TODO if (permitted (NULL, 'ports', 'set_reserve_comment')) */
2155 /* TODO Link / unlink permissions */
2156
2157 $lm_cache['allowcomment'] = permitted(NULL, NULL, 'set_reserve_comment'); /* RackCode {$op_set_reserve_comment} */
2158 $lm_cache['allowlink'] = permitted(NULL, NULL, 'set_link'); /* RackCode {$op_set_link} */
2159
2160 //portlist::var_dump_html($lm_cache);
2161
2162 /* init jeditable fields/tags */
2163 if($lm_cache['allowcomment'])
2164 addJS('$(document).ready(function() { $(".editcmt").editable("'.$target.'",{placeholder : "add comment"}); });' , TRUE);
2165
2166 if($lm_cache['allowlink'])
2167 addJS('$(document).ready(function() { $(".editcable").editable("'.$target.'",{placeholder : "edit cableID"}); });' , TRUE);
2168
2169 /* linkmgmt for current object */
2170 linkmgmt_renderObjectLinks($object_id);
2171
2172 /* linkmgmt for every child */
2173 //$parents = getEntityRelatives ('parents', 'object', $object_id);
2174 $children = getEntityRelatives ('children', 'object', $object_id); //'entity_id'
2175
2176 //portlist::var_dump_html($children);
2177
2178 foreach($children as $child) {
2179 echo '<h1>Links for Child: '.$child['name'].'</h1>';
2180 linkmgmt_renderObjectLinks($child['entity_id']);
2181 }
2182
2183 return;
2184
2185} /* tabhandler */
2186
2187/* -------------------------------------------------- */
2188function linkmgmt_renderObjectLinks($object_id) {
2189
2190 $object = spotEntity ('object', $object_id);
2191 $object['attr'] = getAttrValues($object_id);
2192
2193 /* get ports */
2194 /* calls getObjectPortsAndLinks */
2195 amplifyCell ($object);
2196
2197 //$ports = getObjectPortsAndLinks($object_id);
2198 $ports = $object['ports'];
2199
2200 /* reindex array so key starts at 0 */
2201 $ports = array_values($ports);
2202
2203 /* URL param handling */
2204 if(isset($_GET['allports'])) {
2205 $allports = $_GET['allports'];
2206 } else
2207 $allports = FALSE;
2208
2209 if(isset($_GET['allback'])) {
2210 $allback = $_GET['allback'];
2211 } else
2212 $allback = FALSE;
2213
2214 echo '<table><tr>';
2215
2216 if($allports) {
2217
2218 echo '<td width=200><a href="'.makeHref(portlist::urlparams('allports','0','0'))
2219 .'">Hide Ports without link</a></td>';
2220 } else
2221 echo '<td width=200><a href="'.makeHref(portlist::urlparams('allports','1','0'))
2222 .'">Show All Ports</a></td>';
2223
2224 echo '<td width=200><span onclick=window.open("'.makeHrefProcess(portlist::urlparamsarray(
2225 array('op' => 'PortLinkDialog','linktype' => 'back','byname' => '1'))).'","name","height=700,width=800,scrollbars=yes");><a>Link Object Ports by Name</a></span></td>';
2226
2227 if($allback) {
2228
2229 echo '<td width=200><a href="'.makeHref(portlist::urlparams('allback','0','0'))
2230 .'">Collapse Backend Links on same Object</a></td>';
2231 } else
2232 echo '<td width=200><a href="'.makeHref(portlist::urlparams('allback','1','0'))
2233 .'">Expand Backend Links on same Object</a></td>';
2234
2235 /* Graphviz map */
2236 echo '<td width=100><span onclick=window.open("'.makeHrefProcess(portlist::urlparamsarray(
2237 array('op' => 'map','usemap' => 1))).'","name","height=800,width=800,scrollbars=yes");><a>Object Map</a></span></td>';
2238
2239 /* Help */
2240 echo '<td width=200><span onclick=window.open("'.makeHrefProcess(portlist::urlparamsarray(
2241 array('op' => 'Help'))).'","name","height=400,width=500");><a>Help</a></span></td>';
2242
2243 if(isset($_REQUEST['hl_port_id']))
2244 $hl_port_id = $_REQUEST['hl_port_id'];
2245 else
2246 $hl_port_id = NULL;
2247
2248 echo '</tr></table>';
2249
2250
2251 echo '<br><br><table id=renderobjectlinks0>';
2252
2253 /* switch display order depending on backend links */
2254 $first = portlist::hasbackend($object_id);
2255
2256 $rowcount = 0;
2257 foreach($ports as $key => $port) {
2258
2259 $plist = new portlist($port, $object_id, $allports, $allback);
2260
2261 //echo "<td><img src=\"index.php?module=redirect&page=object&tab=linkmgmt&op=map&object_id=$object_id&port_id=${port['id']}&allports=$allports\" ></td>";
2262
2263 if($plist->printportlistrow($first, $hl_port_id, ($rowcount % 2 ? portlist::ALTERNATE_ROW_BGCOLOR : "#ffffff")) )
2264 $rowcount++;
2265
2266 }
2267
2268 echo "</table>";
2269
2270} /* renderObjectLinks */
2271
2272/* -------------------------------------------------- */
2273
2274/*
2275 * Portlist class
2276 * gets all linked ports to spezified port
2277 * and prints this list as table row
2278 *
2279 */
2280class portlist {
2281
2282 public $list = array();
2283
2284 private $object_id;
2285 private $port_id;
2286 private $port;
2287
2288 private $first_id;
2289 private $front_count;
2290
2291 private $last_id;
2292 private $back_count;
2293
2294 private $count = 0;
2295
2296 private $allback = FALSE;
2297
2298 private $multilink = LM_MULTILINK;
2299
2300 const B2B_LINK_BGCOLOR = '#d8d8d8';
2301 const CURRENT_PORT_BGCOLOR = '#ffff99';
2302 const CURRENT_OBJECT_BGCOLOR = '#ff0000';
2303 const HL_PORT_BGCOLOR = '#00ff00';
2304 const ALTERNATE_ROW_BGCOLOR = '#f0f0f0';
2305
2306 /* Possible LOOP detected after count links print only */
2307 const MAX_LOOP_COUNT = 13;
2308
2309 private $loopcount;
2310
2311 private $gv = NULL;
2312
2313 function __construct($port, $object_id, $allports = FALSE, $allback = FALSE) {
2314
2315 $this->object_id = $object_id;
2316
2317 $this->port = $port;
2318
2319 $port_id = $port['id'];
2320
2321 $this->port_id = $port_id;
2322
2323 $this->first_id = $port_id;
2324 $this->last_id = $port_id;
2325
2326 $this->allback = $allback;
2327
2328 $this->_getportlists($port_id);
2329
2330 if(!$allports)
2331 if($this->count == 0 || ( ($this->count == 1) && (!empty($this->list[$port_id]['back'])) ) ) {
2332 $this->list = array();
2333 $this->first_id = NULL;
2334 }
2335
2336 // $this->var_dump_html($this->list);
2337
2338 } /* __construct */
2339
2340
2341 /*
2342 * get front and back portlist
2343 */
2344 function _getportlists($port_id) {
2345
2346 /* Front Port */
2347 $this->count = 0;
2348 $this->_getportlist($this->_getportdata($port_id),FALSE, TRUE);
2349 $this->front_count = $this->count;
2350
2351 /* Back Port */
2352 $this->count = 0;
2353 $this->_getportlist($this->_getportdata($port_id), TRUE, FALSE);
2354 $this->back_count = $this->count;
2355
2356 $this->count = $this->front_count + $this->back_count;
2357 }
2358
2359 /*
2360 * gets front or back port of src_port
2361 * and adds it to the list
2362 */
2363 /* !!! recursive */
2364 function _getportlist(&$src_port, $back = FALSE, $first = TRUE) {
2365
2366 $src_port_id = $src_port['id'];
2367
2368 if($back)
2369 $linktype = 'back';
2370 else
2371 $linktype = 'front';
2372
2373 if(!empty($src_port[$linktype])) {
2374
2375 /* multilink */
2376 foreach($src_port[$linktype] as &$src_link) {
2377 $dst_port_id = $src_link['id'];
2378
2379 if(!$this->_loopdetect($src_port,$dst_port_id,$src_link,$linktype)) {
2380 //error_log("no loop $linktype>".$dst_port_id);
2381 $this->count++;
2382 $this->_getportlist($this->_getportdata($dst_port_id), !$back, $first);
2383 }
2384 }
2385
2386 } else {
2387 if($first) {
2388 $this->first_id = $src_port_id;
2389 // $this->front_count = $this->count; /* doesn't work on loops */
2390 } else {
2391 $this->last_id = $src_port_id;
2392 // $this->back_count = $this->count; /* doesn't work on loops */
2393 }
2394
2395 }
2396
2397 } /* _getportlist */
2398
2399 /*
2400 * as name suggested
2401 */
2402 function _loopdetect(&$src_port, $dst_port_id, &$src_link, $linktype) {
2403
2404 /* TODO multilink*/
2405 if(array_key_exists($dst_port_id, $this->list)) {
2406
2407 // $dst_port = $this->list[$dst_port_id];
2408
2409 //echo "LOOP :".$src_port['id']."-->".$dst_port_id;
2410
2411 /* print loop at least once */
2412 if($dst_port_id == $this->port_id)
2413 {
2414 $src_link['loop'] = $dst_port_id;
2415 return TRUE;
2416 }
2417
2418 }
2419
2420 return FALSE;
2421
2422 } /* _loopdetect */
2423
2424 /*
2425 * get all data for one port
2426 * name, object, front link, back link
2427 */
2428 function &_getportdata($port_id) {
2429 /* sql bitwise xor: porta ^ portb */
2430 //select cable, ((porta ^ portb) ^ 4556) as port from Link where (4556 in (porta, portb));
2431
2432 //error_log("_getportdata $port_id");
2433
2434 /* TODO single sql ? */
2435
2436 $result = usePreparedSelectBlade
2437 (
2438 'SELECT Port.id, Port.name, Port.label, Port.type, Port.l2address, Port.object_id, Port.reservation_comment,
2439 Object.name as "obj_name"
2440 from Port
2441 join Object on Object.id = Port.object_id
2442 where Port.id = ?',
2443 array($port_id)
2444 );
2445 $datarow = $result->fetchAll(PDO::FETCH_ASSOC);
2446
2447 $result->closeCursor();
2448 unset($result);
2449
2450 $result = usePreparedSelectBlade
2451 (
2452 'SELECT Port.id, Link.cable, Port.name, Port.label, Port.type, Port.l2address, Port.object_id,
2453 CONCAT(Link.porta,"_",Link.portb) as link_id from Link
2454 join Port
2455 where (? = Link.porta or ? = Link.portb) and ((Link.porta ^ Link.portb) ^ ? ) = Port.id',
2456 array($port_id, $port_id, $port_id)
2457 );
2458 $frontrow = $result->fetchAll(PDO::FETCH_ASSOC);
2459
2460 $result->closeCursor();
2461 unset($result);
2462
2463 $result = usePreparedSelectBlade
2464 (
2465 'SELECT Port.id, LinkBackend.cable, Port.name, Port.label, Port.type, Port.l2address, Port.object_id,
2466 CONCAT(LinkBackend.porta,"_",LinkBackend.portb,"_back") as link_id from LinkBackend
2467 join Port
2468 where (? = LinkBackend.porta or ? = LinkBackend.portb) and ((LinkBackend.porta ^ LinkBackend.portb) ^ ? ) = Port.id',
2469 array($port_id, $port_id, $port_id)
2470 );
2471 $backrow = $result->fetchAll(PDO::FETCH_ASSOC);
2472
2473 $result->closeCursor();
2474 unset($result);
2475
2476 $retval = $datarow[0];
2477
2478 if(!empty($frontrow))
2479 $retval['front']= $frontrow;
2480 else
2481 $retval['front'] = array();
2482
2483 if(!empty($backrow))
2484 $retval['back'] = $backrow;
2485 else
2486 $retval['back'] = array();
2487
2488 // $this->var_dump_html($retval);
2489
2490 /* return reference */
2491 return ($this->list[$port_id] = &$retval);
2492
2493 } /* _getportdata */
2494
2495 /*
2496 */
2497 function printport(&$port, $multilink = false) {
2498
2499 /* set bgcolor for current port */
2500 if($port['id'] == $this->port_id) {
2501 $bgcolor = 'bgcolor='.self::CURRENT_PORT_BGCOLOR;
2502 $idtag = ' id='.$port['id'];
2503 } else {
2504 $bgcolor = '';
2505 $idtag = '';
2506 }
2507
2508 $mac = trim(preg_replace('/(..)/','$1:',$port['l2address']),':');
2509
2510 $title = "Label: ${port['label']}\nMAC: $mac\nTypeID: ${port['type']}\nPortID: ${port['id']}";
2511
2512 echo '<td'.$idtag.' align=center '.$bgcolor.' title="'.$title.'"><pre>[<a href="'
2513 .makeHref(array('page'=>'object', 'tab' => 'linkmgmt', 'object_id' => $port['object_id'], 'hl_port_id' => $port['id']))
2514 .'#'.$port['id']
2515 .'">'.$port['name'].'</a>]</pre>'.($multilink ? $this->_getlinkportsymbol($port['id'], 'back') : '' ).'</td>';
2516
2517 } /* printport */
2518
2519 /*
2520 */
2521 function printcomment(&$port) {
2522
2523 if(!empty($port['reservation_comment'])) {
2524 $prefix = '<b>Reserved: </b>';
2525 } else
2526 $prefix = '';
2527
2528 echo '<td>'.$prefix.'<i><a class="editcmt" id='.$port['id'].'>'.$port['reservation_comment'].'</a></i></td>';
2529
2530 } /* printComment */
2531
2532
2533 /*
2534 */
2535 function printobject($object_id, $object_name) {
2536 if($object_id == $this->object_id) {
2537 $color='color: '.self::CURRENT_OBJECT_BGCOLOR;
2538 } else {
2539 $color='';
2540 }
2541
2542 echo '<td><table align=center cellpadding=5 cellspacing=0 border=1><tr><td align=center><a style="font-weight:bold;'
2543 .$color.'" href="'.makeHref(array('page'=>'object', 'tab' => 'linkmgmt', 'object_id' => $object_id))
2544 .'"><pre>'.$object_name.'</pre></a><pre>'.$this->_getRackInfo($object_id, 'font-size:80%')
2545 .'</pre></td></tr></table></td>';
2546
2547 } /* printobject */
2548
2549 /*
2550 */
2551 function printlink($src_port_id, &$dst_link, $linktype) {
2552
2553 if($linktype == 'back')
2554 $arrow = '====>';
2555 else
2556 $arrow = '---->';
2557
2558 /* link */
2559 echo '<td align=center>';
2560
2561 echo '<pre><a class="editcable" id='.$dst_link['link_id'].'>'.$dst_link['cable']
2562 ."</a></pre><pre>$arrow</pre>"
2563 .$this->_printUnLinkPort($src_port_id, $dst_link, $linktype);
2564
2565 echo '</td>';
2566 } /* printlink */
2567
2568 /*
2569 * print cableID dst_port:dst_object
2570 */
2571 function _printportlink($src_port_id, $dst_port_id, &$dst_link, $back = FALSE) {
2572
2573 global $lm_multilink_port_types;
2574
2575 $multilink = LM_MULTILINK;
2576
2577 if(!isset($this->list[$dst_port_id]))
2578 {
2579 /* get port not in list */
2580 // echo "<td>AHHH $src_port_id $dst_port_id --> $back</td>";
2581 // echo "<td>load".$this->var_dump_html($dst_link)." tree</td>";
2582// echo "<td>".$dst_link['cable']." ".$dst_link['name']."</td><td>not displayed</td>";
2583
2584 if($back)
2585 echo "<td>></td>";
2586
2587 // TODO check if multilink is needed here
2588 $this->printport($dst_link, $multilink && in_array($dst_link['type'], $lm_multilink_port_types));
2589 echo "<td>...</td>";
2590
2591 return TRUE;
2592
2593 // $this->_getportlist($this->list[$src_port_id], $back, !$back);
2594 }
2595
2596 $dst_port = $this->list[$dst_port_id];
2597 $object_id = $dst_port['object_id'];
2598 $obj_name = $dst_port['obj_name'];
2599
2600 if($obj_name == NULL)
2601 {
2602 $tmpobj = spotEntity('object', $dst_port['object_id']);
2603 $dst_port['obj_name'] = $tmpobj['dname'];
2604 $obj_name = $tmpobj['dname'];
2605 }
2606
2607 $loop = FALSE;
2608 $edgeport = ($dst_link == NULL) || empty($dst_port['front']) || empty($dst_port['back']);
2609
2610 if($back) {
2611 $linktype = 'back';
2612 } else {
2613 $linktype = 'front';
2614 }
2615
2616 $sameobject = FALSE;
2617
2618 if(isset($dst_link['loop']))
2619 $loop = TRUE;
2620
2621 if($dst_link != NULL) {
2622
2623 $src_object_id = $this->list[$src_port_id]['object_id'];
2624
2625 if(!$this->allback && $object_id == $src_object_id && $back) {
2626 $sameobject = TRUE;
2627 } else {
2628 $this->printlink($src_port_id, $dst_link, $linktype);
2629 }
2630
2631 } else {
2632 $this->_printlinkportsymbol($dst_port_id, $linktype);
2633 $edgeport = true;
2634
2635 if(!$back)
2636 $this->printcomment($dst_port);
2637 }
2638
2639 if($back) {
2640 if(!$sameobject)
2641 $this->printobject($object_id,$obj_name);
2642
2643 echo "<td>></td>";
2644
2645 /* align ports nicely */
2646 if($dst_port['id'] == $this->port_id)
2647 echo '</td></tr></table id=printportlink1></td><td><table align=left><tr>';
2648 }
2649
2650 /* print [portname] */
2651 // TODO check multilink symbols front/back edgeports
2652 $this->printport($dst_port, $multilink && in_array($dst_port['type'], $lm_multilink_port_types));
2653
2654 if($loop)
2655 echo '<td bgcolor=#ff9966>LOOP</td>';
2656
2657 if(!$back) {
2658
2659 /* align ports nicely */
2660 if($dst_port['id'] == $this->port_id)
2661 echo '</td></tr></table id=printportlink2></td><td><table align=left><tr>';
2662
2663 echo "<td><</td>";
2664 $this->printobject($object_id,$obj_name);
2665
2666 if(empty($dst_port['back']))
2667 $this->_printlinkportsymbol($dst_port_id, 'back');
2668 } else
2669 if(empty($dst_port['front'])) {
2670 $this->printcomment($dst_port);
2671 $this->_printlinkportsymbol($dst_port_id, 'front');
2672 }
2673
2674 if($loop) {
2675 if(isset($dst_link['loopmaxcount']))
2676 $reason = " (MAX LOOP COUNT reached)";
2677 else
2678 $reason = '';
2679
2680 showWarning("Possible Loop on Port ($linktype) ".$dst_port['name'].$reason);
2681 return FALSE;
2682 }
2683
2684 return TRUE;
2685
2686 } /* _printportlink */
2687
2688 /*
2689 * print <tr>..</tr>
2690 */
2691 function printportlistrow($first = TRUE, $hl_port_id = NULL, $rowbgcolor = '#ffffff') {
2692
2693 $this->loopcount = 0;
2694
2695 if($this->first_id == NULL)
2696 return false;
2697
2698 if($first)
2699 $id = $this->first_id;
2700 else
2701 $id = $this->last_id;
2702
2703 if($hl_port_id == $this->port_id)
2704 $hlbgcolor = "bgcolor=".self::HL_PORT_BGCOLOR;
2705 else
2706 $hlbgcolor = "bgcolor=$rowbgcolor";
2707
2708 $link = NULL;
2709
2710 $port = $this->list[$id];
2711
2712 $urlparams = array(
2713 'module' => 'redirect',
2714 'page' => 'object',
2715 'tab' => 'linkmgmt',
2716 'op' => 'map',
2717 'usemap' => 1,
2718 'object_id' => $port['object_id'],
2719 );
2720
2721 if($hl_port_id !== NULL)
2722 $urlparams['hl_port_id'] = $hl_port_id;
2723 else
2724 $urlparams['port_id'] = $id;
2725
2726 $title = "linkcount: ".$this->count." (".$this->front_count."/".$this->back_count.")\nTypeID: ${port['type']}\nPortID: $id";
2727
2728 $onclick = 'onclick=window.open("'.makeHrefProcess(portlist::urlparamsarray(
2729 $urlparams)).'","Map","height=500,width=800,scrollbars=yes");';
2730
2731 /* Current Port */
2732 echo '<tr '.$hlbgcolor.'><td nowrap="nowrap" bgcolor='.self::CURRENT_PORT_BGCOLOR.' title="'.$title.
2733 '"><a '.$onclick.'>'.
2734 $this->port['name'].': </a></td>';
2735
2736 echo "<td><table id=printportlistrow1 align=right><tr><td>";
2737
2738 $back = empty($this->list[$id]['back']);
2739
2740 $this->_printportlink(NULL, $id, $link, $back);
2741
2742 $this->_printportlist($id, !$back);
2743 echo "</td></tr></table id=printportlistrow2></td></tr>";
2744
2745 /* horizontal line */
2746 echo '<tr><td height=1 colspan=3 bgcolor=#e0e0e0></td></tr>';
2747
2748 return true;
2749
2750 } /* printportlist */
2751
2752 /*
2753 * print <td>
2754 * prints all ports in a list starting with start_port_id
2755 */
2756 /* !!! recursive */
2757 function _printportlist($src_port_id, $back = FALSE) {
2758
2759 if($back)
2760 $linktype = 'back';
2761 else
2762 $linktype = 'front';
2763
2764 if(!empty($this->list[$src_port_id][$linktype])) {
2765
2766 $linkcount = count($this->list[$src_port_id][$linktype]);
2767
2768 if($linkcount > 1)
2769 echo "<td bgcolor=#f00000></td><td><table id=_printportlist1>";
2770
2771 $lastkey = $linkcount - 1;
2772
2773 foreach($this->list[$src_port_id][$linktype] as $key => &$link) {
2774
2775 if($linkcount > 1) {
2776 echo "<tr style=\"background-color:".( $key % 2 ? self::ALTERNATE_ROW_BGCOLOR : "#ffffff" )."\"><td><table id=_printportlist2><tr>";
2777 }
2778
2779 $dst_port_id = $link['id'];
2780
2781 $this->loopcount++;
2782
2783 if($this->loopcount > self::MAX_LOOP_COUNT) {
2784 // $src_port_name = $this->list[$src_port_id]['name'];
2785 // $dst_port_name = $this->list[$dst_port_id]['name'];
2786
2787 $link['loop'] = $dst_port_id;
2788 $link['loopmaxcount'] = $dst_port_id;
2789
2790 /* loop warning is handeld in _printportlink() */
2791 //showWarning("MAX LOOP COUNT reached $src_port_name -> $dst_port_name".self::MAX_LOOP_COUNT);
2792 //return; /* return after _printportlink */
2793 }
2794
2795 if(!$this->_printportlink($src_port_id, $dst_port_id, $link, $back))
2796 {
2797 return;
2798 }
2799
2800 $this->_printportlist($dst_port_id,!$back);
2801
2802 if($linkcount > 1) {
2803 echo "</tr></table></td></tr>"
2804 .( $key != $lastkey ? "<tr><td height=1 colspan=100% bgcolor=#c0c0c0><td></tr>" : "");
2805 }
2806 }
2807
2808 if($linkcount > 1)
2809 echo "</table></td>";
2810 }
2811 } /* _printportlist */
2812
2813 /*
2814 * returns linked Row / Rack Info for object_id
2815 *
2816 */
2817 function _getRackInfo($object_id, $style = '') {
2818 global $lm_cache;
2819
2820 $rackinfocache = $lm_cache['rackinfo'];
2821
2822 /* if not in cache get it */
2823 if(!array_key_exists($object_id,$rackinfocache)) {
2824
2825 $object = spotEntity('object', $object_id);
2826 $rack_id = $object['rack_id'];
2827
2828 if($rack_id)
2829 $rackinfocache[$object_id] = spotEntity('rack', $object['rack_id']);
2830 }
2831
2832
2833 $rack = &$rackinfocache[$object_id];
2834
2835 if(empty($rack))
2836 return '<span style="'.$style.'">Unmounted</span>';
2837 else
2838 return '<a style="'.$style.'" href='.makeHref(array('page'=>'row', 'row_id'=>$rack['row_id'])).'>'.$rack['row_name']
2839 .'</a>/<a style="'.$style.'" href='.makeHref(array('page'=>'rack', 'rack_id'=>$rack['id'])).'>'
2840 .$rack['name'].'</a>';
2841
2842 } /* _getRackInfo */
2843
2844 /*
2845 * return link symbol
2846 */
2847 function _getlinkportsymbol($port_id, $linktype) {
2848 $retval = '<span onclick=window.open("'.makeHrefProcess(portlist::urlparamsarray(
2849 array('op' => 'PortLinkDialog','port' => $port_id,'linktype' => $linktype ))).'","name","height=800,width=800");'
2850 .'>';
2851
2852 $img = getImageHREF ('plug', $linktype.' Link this port');
2853
2854 if($linktype == 'back')
2855 $img = str_replace('<img',
2856 '<img style="transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg);-moz-transform:rotate(180deg);-webkit-transform:rotate(180deg);"',
2857 $img);
2858
2859 $retval .= $img;
2860 $retval .= "</span>";
2861 return $retval;
2862
2863 } /* _getlinkportsymbol */
2864
2865 /*
2866 * print link symbol
2867 *
2868 */
2869 function _printlinkportsymbol($port_id, $linktype = 'front') {
2870 global $lm_cache;
2871
2872 if(!$lm_cache['allowlink'])
2873 return;
2874
2875 echo "<td align=center>";
2876
2877 echo $this->_getlinkportsymbol($port_id, $linktype);
2878
2879 echo "</td>";
2880
2881 } /* _printlinkportsymbol */
2882
2883 /*
2884 * return link cut symbol
2885 *
2886 * TODO $opspec_list
2887 */
2888 function _printUnLinkPort($src_port_id, &$dst_link, $linktype) {
2889 global $lm_cache;
2890
2891 if(!$lm_cache['allowlink'])
2892 return '';
2893
2894 $src_port = $this->list[$src_port_id];
2895
2896 $dst_port = $this->list[$dst_link['id']];
2897
2898 /* use RT unlink for front link, linkmgmt unlink for back links */
2899 if($linktype == 'back')
2900 $tab = 'linkmgmt';
2901 else
2902 $tab = 'ports';
2903
2904 return '<a href='.
2905 makeHrefProcess(array(
2906 'op'=>'unlinkPort',
2907 'port_id'=>$src_port_id,
2908 'remote_id' => $dst_port['id'],
2909 'object_id'=>$this->object_id,
2910 'tab' => $tab,
2911 'linktype' => $linktype)).
2912 ' onclick="return confirm(\'unlink ports '.$src_port['name']. ' -> '.$dst_port['name']
2913 .' ('.$linktype.') with cable ID: '.$dst_link['cable'].'?\');">'.
2914 getImageHREF ('cut', $linktype.' Unlink this port').'</a>';
2915
2916 } /* _printUnLinkPort */
2917
2918
2919 /*
2920 *
2921 */
2922 static function urlparams($name, $value, $defaultvalue = NULL) {
2923
2924 $urlparams = $_GET;
2925
2926 if($value == $defaultvalue) {
2927
2928 /* remove param */
2929 unset($urlparams[$name]);
2930
2931 } else {
2932
2933 $urlparams[$name] = $value;
2934
2935 }
2936
2937 return $urlparams;
2938
2939 } /* urlparams */
2940
2941 /*
2942 * $params = array('name' => 'value', ...)
2943 */
2944 static function urlparamsarray($params) {
2945
2946 $urlparams = $_GET;
2947
2948 foreach($params as $name => $value) {
2949
2950 if($value == NULL) {
2951
2952 /* remove param */
2953 unset($urlparams[$name]);
2954
2955 } else {
2956
2957 $urlparams[$name] = $value;
2958
2959 }
2960 }
2961
2962 return $urlparams;
2963
2964 } /* urlparamsarray */
2965
2966 /* */
2967 static function hasbackend($object_id) {
2968 /* sql bitwise xor: porta ^ portb */
2969 //select cable, ((porta ^ portb) ^ 4556) as port from Link where (4556 in (porta, portb));
2970
2971 $result = usePreparedSelectBlade
2972 (
2973 'SELECT count(*) from Port
2974 join LinkBackend as LinkBackend_a on LinkBackend_a.porta = id
2975 join LinkBackend as LinkBackend_b on LinkBackend_b.portb = id
2976 where object_id = ?',
2977 array($object_id)
2978 );
2979 $retval = $result->fetchColumn();
2980
2981 $result->closeCursor();
2982
2983 return $retval != 0;
2984
2985 } /* hasbackend */
2986
2987 /* for debugging only */
2988 function var_dump_html(&$var) {
2989 echo "<pre>------------------Start Var Dump -------------------------\n";
2990 var_dump($var);
2991 echo "\n---------------------END Var Dump ------------------------</pre>";
2992 }
2993
2994} /* portlist */
2995
2996/* -------------------------------------------------- */
2997
2998?>