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