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