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