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