mail_expirations.php: add MAILEXPR_DAYS_BEHIND
[racktables-contribs] / LinkManagement / plugins / linkmgmt.php
CommitLineData
9276dc97 1<?php
3badc888 2// TODO linkchain cytoscape create libs?
3// linkchain all objects graph cytoscape takes ages
3badc888 4// highlight port cytoscape maps
9276dc97 5/*
bac6215e 6 * Link Management for RT >= 0.20.11
9276dc97 7 *
fdc74cf0 8 * Features:
9 * - create links between ports
10 * - create backend links between ports
11 * - visually display links / chains
12 * e.g.
13 * (Object)>[port] -- front --> [port]<(Object) == back == > (Object)>[port] -- front --> [port]<(Object)
14 * - Link object backend ports by name (e.g. handy for patch panels)
16ec374c 15 * - change/create CableID
16 * - change/create Port Reservation Comment
fdc74cf0 17 * - multiple backend links for supported port types (e.g. AC-in, DC)
18 * - GraphViz Maps (Objects, Ports and Links) (needs GraphViz_Image 1.3.0)
19 * - object,port or link highligthing (just click on it)
20 * - context menu to link and unlink ports
9276dc97 21 *
fdc74cf0 22 * Usage:
23 * 1. select "Link Management" tab
24 * 2. you should see link chains of all linked ports
25 * 3. to display all ports hit "Show All Ports" in the left upper corner
26 * 4. to link all ports with the same name of two different objects use "Link Object Ports by Name"
27 * a. select the other object you want to backend link to
28 * b. "show back ports" gives you the list of possible backend links
29 * !! Important port names have to be the same on both objects !!
30 * e.g. (Current Object):Portname -?-> Portname:(Selected Object)
31 * c. select all backend link to create (Ctrl + a for all)
32 * d. Enter backend CableID for all selected links
33 * e. "Link back" create the backend links
34 * 5. If you have an backend link within the same Object the link isn't shown until
35 * "Expand Backend Links on same Object" is hit
36 * 6. "Object Map" displays Graphviz Map of current object
37 * 7. To get a Graphviz Map of a single port click the port name on the left
9276dc97
ME
38 *
39 *
3badc888 40 * Changes:
41 * switch to new linkchain class
42 * - nicer looking graphviz maps
43 * - better multilink support
44 *
45 * add cytoscape.js maps
46 * - path higlighting
47 * - zooming
48 *
fdc74cf0 49 * Requirements:
50 * PHP 5 (http://php.net/)
51 * GraphViz_Image 1.3.0 or newer (http://pear.php.net/package/Image_GraphViz)
52 * GraphViz (http://www.graphviz.org/)
9276dc97 53 *
3badc888 54 * to user cytoscape js map the following is required:
383230c5 55 * create plugins/linkmgmt directory and place the following 7 files in it
3badc888 56 *
57 * Cytoscape.js (http://js.cytoscape.org/)
3badc888 58 * https://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape.min.js
59 * dagre.js
3badc888 60 * https://raw.githubusercontent.com/cpettitt/dagre/master/dist/dagre.min.js
61 * https://raw.githubusercontent.com/cytoscape/cytoscape.js-dagre/master/cytoscape-dagre.js
62 * qtip
3badc888 63 * https://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.1/jquery.qtip.min.css
64 *
3badc888 65 * https://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.1/jquery.qtip.min.js
66 * https://raw.githubusercontent.com/cytoscape/cytoscape.js-qtip/master/cytoscape-qtip.js
67 *
68 * jquery >= 1.10.0 (qtip requirement)
3badc888 69 * https://code.jquery.com/jquery-1.11.3.min.js
70 *
9276dc97
ME
71 * INSTALL:
72 *
fdc74cf0 73 * 1. create LinkBackend Table in your RackTables database
74 *
75 * Multilink table
9276dc97
ME
76
77CREATE TABLE `LinkBackend` (
78 `porta` int(10) unsigned NOT NULL DEFAULT '0',
79 `portb` int(10) unsigned NOT NULL DEFAULT '0',
80 `cable` char(64) DEFAULT NULL,
81 PRIMARY KEY (`porta`,`portb`),
cb15aecc 82 KEY `LinkBackend_FK_a` (`porta`),
fdc74cf0 83 KEY `LinkBackend_FK_b` (`portb`),
84 CONSTRAINT `LinkBackend_FK_a` FOREIGN KEY (`porta`) REFERENCES `Port` (`id`) ON DELETE CASCADE,
85 CONSTRAINT `LinkBackend_FK_b` FOREIGN KEY (`portb`) REFERENCES `Port` (`id`) ON DELETE CASCADE
1fb0f48b 86) ENGINE=InnoDB DEFAULT CHARSET=utf8 collate=utf8_unicode_ci;
9276dc97 87
16ec374c 88 * 2. copy linkmgmt.php to plugins directory
fdc74cf0 89 *
90 * Ready to go!
91 *
92 *
93 * UPDATE TABLE:
94 *
95 * Update from non-multilink table
96 * ALTER TABLE
97
98ALTER TABLE LinkBackend ADD KEY `LinkBackend_FK_b` (`portb`);
99ALTER TABLE LinkBackend DROP INDEX porta;
100ALTER TABLE LinkBackend DROP INDEX portb;
101
b695efd7 102 * UPDATE to RT 0.20.7
103
104ALTER TABLE LinkBackend CONVERT to CHARACTER SET utf8 COLLATE utf8_unicode_ci;
105
fdc74cf0 106 *
9276dc97
ME
107 *
108 * TESTED on FreeBSD 9.0, nginx/1.0.11, php 5.3.9
fdc74cf0 109 * GraphViz_Image 1.3.0
9276dc97 110 *
7780b52f 111 * (c)2012-2017 Maik Ehinger <github138@t-online.de>
9276dc97
ME
112 */
113
fdc74cf0 114/**
115 * The newest version of this plugin can be found at:
9276dc97 116 *
3badc888 117 * https://github.com/github138/myRT-contribs/tree/develop-0.20.x
9276dc97
ME
118 *
119 */
120
121/*************************
122 * TODO
123 *
124 * - code cleanups
125 * - bug fixing
126 *
fdc74cf0 127 * - put selected object/port top left of graph
128 * - multlink count for Graphviz maps empty or full dot
129 *
130 * - csv list
9276dc97
ME
131 *
132 */
133
fdc74cf0 134/* DEBUG */
135//error_reporting(E_ALL);
9276dc97
ME
136
137$tab['object']['linkmgmt'] = 'Link Management';
138$tabhandler['object']['linkmgmt'] = 'linkmgmt_tabhandler';
c53e1af9 139$trigger['object']['linkmgmt'] = 'trigger_ports';
9276dc97
ME
140
141$ophandler['object']['linkmgmt']['update'] = 'linkmgmt_opupdate';
142$ophandler['object']['linkmgmt']['unlinkPort'] = 'linkmgmt_opunlinkPort';
143$ophandler['object']['linkmgmt']['PortLinkDialog'] = 'linkmgmt_opPortLinkDialog';
144$ophandler['object']['linkmgmt']['Help'] = 'linkmgmt_opHelp';
145
fdc74cf0 146$ophandler['object']['linkmgmt']['map'] = 'linkmgmt_opmap';
147$ajaxhandler['lm_mapinfo'] = 'linkmgmt_ajax_mapinfo';
16ec374c 148$ajaxhandler['lm-upd-reservation-cable'] = 'linkmgmt_updateCableIdAJAX';
fdc74cf0 149
3badc888 150$ophandler['object']['linkmgmt']['cytoscapemap'] = 'linkmgmt_cytoscapemap';
151
fdc74cf0 152/* ------------------------------------------------- */
153
1e6c47e6 154define('LM_MULTILINK',TRUE);
fdc74cf0 155
156/* -------------------------------------------------- */
157
158$lm_multilink_port_types = array(
159 16, /* AC-in */
160 //1322, /* AC-out */
161 1399, /* DC */
162 );
9276dc97
ME
163
164/* -------------------------------------------------- */
165
166$lm_cache = array(
3254ec33 167 'allowcomment' => TRUE, /* RackCode {$op_set_reserve_comment} */
168 'allowlink' => TRUE, /* RackCode {$op_set_link} */
169 'allowbacklink' => TRUE, /* RackCode {$op_set_backlink} */
9276dc97
ME
170 'rackinfo' => array(),
171 );
172
173/* -------------------------------------------------- */
174
175//function linkmgmt_tabtrigger() {
176// return 'std';
177//} /* linkmgmt_tabtrigger */
178
3badc888 179/* -------------------linkchain stuff------------------------------- */
180class linkchain_cache
181{
182 public $cache = array();
9276dc97 183
3badc888 184 function getobject($object_id , &$rack = null)
185 {
186 if(!$object_id)
187 return null;
9276dc97 188
3badc888 189 if(!isset($this->cache['o'.$object_id]))
190 {
191 $object = spotEntity('object', $object_id);
192 $object['IPV4OBJ'] = considerConfiguredConstraint ($object, 'IPV4OBJ_LISTSRC');
9276dc97 193
3badc888 194 /* get more object info */
9276dc97 195
3badc888 196 if($object['IPV4OBJ'])
197 {
3badc888 198 $object['portip'] = array();
09712ceb 199 foreach(getObjectIPv4Allocations ($object_id) as $ipv4)
3badc888 200 {
201 $object['portip'][$ipv4['osif']] = $ipv4['addrinfo']['ip'];
202 }
203 }
9276dc97 204
3badc888 205 $this->cache['o'.$object_id] = $object;
206 }
207 else
208 $object = $this->cache['o'.$object_id];
fdc74cf0 209
3badc888 210 $rack = $this->getrack($object['rack_id']);
fdc74cf0 211
3badc888 212 return $object;
213 }
fdc74cf0 214
3badc888 215 function getrack($rack_id)
216 {
217 // rack
218 if($rack_id)
219 {
220 if(!isset($this->cache['r'.$rack_id]))
221 {
222 $rack = spotEntity('rack', $rack_id);
223 $this->cache['r'.$rack_id] = $rack;
224 }
225 else
226 $rack = $this->cache['r'.$rack_id];
227 }
228 else
229 $rack = null;
fdc74cf0 230
3badc888 231 return $rack;
fdc74cf0 232
3badc888 233 }
234}
fdc74cf0 235
3badc888 236$lc_cache = new linkchain_cache();
fdc74cf0 237
3badc888 238/* recursive class */
239class lm_linkchain implements Iterator {
fdc74cf0 240
3badc888 241 const B2B_LINK_BGCOLOR = '#d8d8d8';
242 const CURRENT_PORT_BGCOLOR = '#ffff99';
243 const CURRENT_OBJECT_BGCOLOR = '#ff0000';
244 const HL_PORT_BGCOLOR = '#A0FFA0';
245 const ALTERNATE_ROW_BGCOLOR = '#f0f0f0';
246
247 public $first = null;
248 public $last = null;
249 public $init = null;
250 public $linked = null;
251 public $linkcount = 0;
252
253 public $loop = false;
254 private $lastipobjport = null;
255
256 public $ports = array();
257
258 private $currentid = null;
259 private $back = null;
260 public $initback = null;
261
262 //public $cache = null;
263 private $object_id = null;
264
265 private $icount = 0;
266 public $exceed = false;
267
268 public $initalign = true;
269
270 public $portmulti = 0;
271 public $prevportmulti = 0;
272
273 private $initport = false;
274
275 private $lids = array(); // link ids porta portb linktype
276
277 public $pids = null; // port ids
278 public $oids = null; // object ids
279
280 /* $back = null follow front and back
281 * true follow back only
282 * false follow front only
283 * $prevport first port
284 */
285 function __construct($port_id, $back = null, $prevport = null, $reverse = false, &$pids = null, &$oids = null)
fdc74cf0 286 {
3badc888 287 global $lc_cache;
fdc74cf0 288
3badc888 289 $this->init = $port_id;
fdc74cf0 290
3badc888 291 $this->initback = $back;
fdc74cf0 292
3badc888 293 if($pids === null)
294 $this->pids = array();
295 else
296 $this->pids = &$pids;
297
298 if($oids === null)
299 $this->oids = array();
300 else
301 $this->oids = &$oids;
302
303 if($back !== null)
fdc74cf0 304 {
3badc888 305 $prevport_id = $prevport['id'];
306 $prevlinktype = $this->getlinktype(!$back);
307 //if($this->setlinkid($port_id, $prevport_id, $prevlinktype))
308 {
309 $this->last = $this->_getlinks($port_id, $back, null, $reverse);
310 }
311 //else
312 {
313 // $this->loop = true;
314 // echo "SUBCHAIN LID exists $port_id $prevlinktype $prevport_id<br>";
315 }
fdc74cf0 316
3badc888 317 // TODO set previous port ..use _set... function()
318 $this->ports[$port_id][$this->getlinktype(!$back)]['portcount'] = 1;
319 $this->ports[$port_id][$this->getlinktype(!$back)]['linked'] = 1;
320 $this->ports[$port_id][$this->getlinktype(!$back)]['remote_id'] = $prevport['id'];
321 $this->ports[$port_id][$this->getlinktype(!$back)]['remote_object_id'] = $prevport['object_id'];
322 $this->ports[$port_id][$this->getlinktype(!$back)]['remote_name'] = $prevport['name'];
323 $this->ports[$port_id][$this->getlinktype(!$back)]['remote_object_name'] = $prevport['object_name'];
324 $this->ports[$port_id][$this->getlinktype(!$back)]['cableid'] = $prevport['cableid'];
fdc74cf0 325
fdc74cf0 326
3badc888 327 $prevport = $this->_setportlink($prevport, $this->getlinktype(!$back));
328 $prevport[$this->getlinktype($back)]['portcount'] = null;
329 $prevport[$this->getlinktype($back)]['remote_id'] = null;
330 $prevport[$this->getlinktype($back)]['remote_object_id'] = null;
fdc74cf0 331
3badc888 332 $this->ports[$prevport_id] = $prevport;
333 $this->first = $prevport_id;
334 $this->linkcount++;
fdc74cf0 335
3badc888 336 // self::var_dump_html($this->ports[$port_id], "PORT");
337 // self::var_dump_html($prevport, "PREVPORT");
338 $this->object_id = $_GET['object_id'];
339 }
340 else
341 {
342 // Link
343 $this->last = $this->_getlinks($port_id, false);
fdc74cf0 344
3badc888 345 if(!$this->loop)
346 $this->first = $this->_getlinks($port_id, true, null, true);
fdc74cf0 347
3badc888 348 $this->object_id = $this->ports[$this->init]['object_id'];
349 }
fdc74cf0 350
3badc888 351 if(0)
352 if($this->loop)
353 {
354 $linktype = $this->getlinktype($back);
355 $prevlinktype = $this->getlinktype(!$back);
356
357 /* set first object */
358 $object_id = $this->ports[$port_id]['object_id'];
359 $object = $lc_cache->getobject($object_id);
fdc74cf0 360
3badc888 361 if($object['IPV4OBJ'])
362 $this->lastipobjport = $port_id;
363
364 $this->first = $this->lastipobjport;
fdc74cf0 365 }
fdc74cf0 366
3badc888 367 $this->linked = ($this->linkcount > 0);
368
369 if($reverse)
370 $this->reverse();
fdc74cf0 371
372 }
fdc74cf0 373
3badc888 374 function setlinkid($porta, $portb, $linktype)
375 {
376 if($porta > $portb)
377 $lid = "${portb}_${porta}";
378 else
379 $lid = "${porta}_${portb}";
fdc74cf0 380
3badc888 381 $lid .= $linktype;
fdc74cf0 382
3badc888 383 if(isset($this->lids[$lid]))
384 return false;
fdc74cf0 385
3badc888 386 $this->lids[$lid] = true;
fdc74cf0 387
3badc888 388 return true;
fdc74cf0 389 }
390
3badc888 391 function hasport_id($port_id)
fdc74cf0 392 {
3badc888 393 if(isset($this->pids[$port_id]))
394 return true;
395 else
396 return false;
fdc74cf0 397 }
398
3badc888 399 function hasobject_id($object_id)
400 {
401 if(isset($this->oids[$object_id]))
402 return true;
403 else
404 return false;
405 }
fdc74cf0 406
3badc888 407 function _setportprevlink($port, $linktype, $prevport)
408 {
409 $port[$linktype] = array(
410 'cableid' => $prevport[$linktype]['cableid'],
411 'linked' => $prevport[$linktype]['linked'],
c205dc54 412 'portcount' => null, // TODO prev port count
3badc888 413 'remote_id' => $prevport['id'],
414 'remote_name' => $prevport['name'],
415 'remote_object_id' => $prevport['object_id'],
416 'remote_object_name' => $prevport['object_name'],
417 );
fdc74cf0 418
3badc888 419 return $port;
420 }
fdc74cf0 421
3badc888 422 function _setportlink($port, $linktype)
423 {
424 $port[$linktype] = array(
425 'cableid' => $port['cableid'],
426 'linked' => $port['linked'],
427 'portcount' => $port['portcount'],
428 'remote_id' => $port['remote_id'],
429 'remote_name' => $port['remote_name'],
430 'remote_object_id' => $port['remote_object_id'],
431 'remote_object_name' => $port['remote_object_name'],
432 );
fdc74cf0 433
3badc888 434 unset($port['cableid']);
435 unset($port['linked']);
436 unset($port['portcount']);
437 unset($port['remote_id']);
438 unset($port['remote_name']);
439 unset($port['remote_object_id']);
440 unset($port['remote_object_name']);
fdc74cf0 441
3badc888 442 return $port;
443 }
fdc74cf0 444
3badc888 445 function _getportlink($port)
446 {
447 $linktype = $this->getlinktype($this->back);
448 return array_merge($port, $port[$linktype], array('linktype' => $linktype));
449 }
fdc74cf0 450
3badc888 451 function isback($linktable)
452 {
453 if($linktable == 'back')
454 return true;
455 else
456 return false;
457 }
fdc74cf0 458
3badc888 459 function getlinktype($back)
460 {
461 return ($back ? 'back' : 'front' );
462 }
fdc74cf0 463
3badc888 464 function reverse()
465 {
466 $tmp = $this->first;
467 $this->first = $this->last;
468 $this->last = $tmp;
fdc74cf0 469
fdc74cf0 470 }
471
fdc74cf0 472
3badc888 473 //recursive
474 function _getlinks($port_id, $back = false, $prevport_id = null, $reverse = false)
475 {
476 global $lc_cache;
477 $linktype = $this->getlinktype($back);
fdc74cf0 478
3badc888 479 if($port_id == $this->init)
480 $this->initport = true;
fdc74cf0 481
3badc888 482 $ports = lm_getPortInfo($port_id, $back);
fdc74cf0 483
3badc888 484 $portcount = count($ports);
fdc74cf0 485
3badc888 486 $port = $ports[0];
fdc74cf0 487
3badc888 488 // check for loops on multilinked ports
489 // set main port to looping one
490 if($portcount > 1)
491 foreach($ports as $mport)
492 {
493 if(isset($this->ports[$mport['remote_id']]))
494 {
495 $port = $mport;
496 break;
497 }
498 }
fdc74cf0 499
3badc888 500 $remote_id = $port['remote_id'];
fdc74cf0 501
3badc888 502 $port['portcount'] = $portcount;
fdc74cf0 503
3badc888 504 $object_id = $port['object_id'];
fdc74cf0 505
3badc888 506 $rack = null;
507 $object = $lc_cache->getobject($object_id, $rack);
fdc74cf0 508
3badc888 509 $this->oids[$object_id] = true;
fdc74cf0 510
3badc888 511 if($object['IPV4OBJ'])
512 $this->lastipobjport = $port_id;
fdc74cf0 513
3badc888 514 if($object)
515 if(isset($object['portip'][$port['name']]))
516 $port['portip'] = $object['portip'][$port['name']];
fdc74cf0 517
3badc888 518 $port = $this->_setportlink($port, $linktype);
fdc74cf0 519
3badc888 520 if($prevport_id)
fdc74cf0 521 {
3badc888 522 $prevlinktype = $this->getlinktype(!$back);
523 $port = $this->_setportprevlink($port, $prevlinktype, $this->ports[$prevport_id]);
fdc74cf0 524 }
525
3badc888 526 //if(!$back)
527 {
528 if($prevport_id)
529 {
530 /* mutlilink: multiple previous links */
531 $prevports = lm_getPortInfo($port_id, !$back);
fdc74cf0 532
3badc888 533 $prevportcount = count($prevports);
fdc74cf0 534
3badc888 535 if($prevportcount > 1)
536 {
537 if($this->initport)
538 $this->initalign = false;
fdc74cf0 539
3badc888 540 $port[$this->getlinktype(!$back)]['portcount'] = $prevportcount;
fdc74cf0 541
3badc888 542 $lcs = array();
543 foreach($prevports as $mport)
544 {
545 if($prevport_id != $mport['remote_id'])
546 {
547 if(isset($this->pids[$mport['remote_id']]))
548 continue;
fdc74cf0 549
3badc888 550 $mport['portcount'] = 1;
551 $lc = new lm_linkchain($mport['remote_id'], $back, $mport, !$reverse, $this->pids, $this->oids);
552 $lcs[$mport['remote_id']] = $lc;
553 $this->linkcount += $lc->linkcount;
554 }
555 }
fdc74cf0 556
3badc888 557 $port[$this->getlinktype(!$back)]['chains'] = $lcs;
558 }
559 }
560 }
fdc74cf0 561
3badc888 562 if($portcount > 1)
fdc74cf0 563 {
3badc888 564 /* mutlilink: multiple links */
565
566 $lcs = array();
567 foreach($ports as $mport)
568 {
569 if($remote_id != $mport['remote_id'])
570 {
571 if(isset($this->pids[$mport['remote_id']]))
572 continue;
573
574 $mport['portcount'] = 1;
575 $lc = new lm_linkchain($mport['remote_id'], !$back, $mport, $reverse, $this->pids, $this->oids);
576 $lcs[$mport['remote_id']] = $lc;
577 $this->linkcount += $lc->linkcount;
578 }
579 }
580
581 $port[$linktype]['chains'] = $lcs;
fdc74cf0 582
fdc74cf0 583 }
584
3badc888 585 if(isset($this->ports[$port_id]))
586 {
587 if(!isset($this->ports[$port_id][$linktype]))
588 {
589 $this->ports[$port_id][$linktype] = $port[$linktype];
590 }
591 }
592 else
593 $this->ports[$port_id] = $port;
fdc74cf0 594
3badc888 595 $this->pids[$port_id] = true;
fdc74cf0 596
3badc888 597 if($remote_id)
598 {
599 if($this->setlinkid($port_id, $remote_id, $linktype))
600 {
601 $this->linkcount++;
602 return $this->_getlinks($remote_id, !$back, $port_id, $reverse);
603 }
604 else
605 {
606 $prevlinktype = $this->getlinktype(!$back);
607 $this->loop = true;
608 if(isset($port[$prevlinktype]))
609 $this->ports[$port_id][$prevlinktype] = $port[$prevlinktype];
610
611 $this->first = $remote_id;
612 }
613 }
614
615 return $port_id;
616 }
617
618 // TODO
619 function getchaintext()
620 {
621 //$this::var_dump_html($this->ports);
622 $chain = "";
623 foreach($this as $id => $port)
624 {
625 $linktype = $port['linktype']; //$this->getlinktype();
626 if($linktype == 'front')
627 $arrow = ' --> ';
628 else
629 $arrow = ' => ';
630
631 $text = $port['object_name']." [".$port['name']."]";
632
633 if($id == $this->init)
634 $chain .= "*$text*";
635 else
636 $chain .= "$text";
637
638 $remote_id = $port['remote_id'];
639
640 if($remote_id)
641 $chain .= $arrow;
642
643 if($this->loop && $remote_id == $this->first)
644 {
645 $chain .= "LOOP!";
646 break;
647 }
648 }
649 return $chain;
650 }
651
652 function getchainlabeltrstart($rowbgcolor = '#ffffff')
653 {
654
655 $port_id = $this->init;
656
657 $initport = $this->ports[$port_id];
fdc74cf0 658
659 $urlparams = array(
3badc888 660 'module' => 'redirect',
661 'page' => 'object',
662 'tab' => 'linkmgmt',
663 'op' => 'map',
664 'usemap' => 1,
665 'object_id' => $initport['object_id'],
fdc74cf0 666 );
667
3badc888 668 $hl_port_id = NULL;
669 if($hl_port_id !== NULL)
670 $urlparams['hl_port_id'] = $hl_port_id;
671 else
672 $urlparams['port_id'] = $port_id;
fdc74cf0 673
3badc888 674 $title = "linkcount: ".$this->linkcount."\nTypeID: ${initport['oif_id']}\nPortID: $port_id";
fdc74cf0 675
3badc888 676 $onclick = 'onclick=window.open("'.makeHrefProcess(array_merge($_GET, $urlparams)).'","Map","height=500,width=800,scrollbars=yes");';
fdc74cf0 677
3badc888 678 if($hl_port_id == $port_id)
679 {
680 $hlbgcolor = "bgcolor=".self::HL_PORT_BGCOLOR;
681 }
682 else
683 $hlbgcolor = "bgcolor=$rowbgcolor";
fdc74cf0 684
3badc888 685 if($rowbgcolor == '#ffffff')
686 $troutlinecolor = 'grey';
687 else
688 $troutlinecolor = 'white';
fdc74cf0 689
3badc888 690 /* Current Port */
691 $chainlabel = '<tr '.$hlbgcolor.' style="outline: thin solid '.$troutlinecolor.';"><td nowrap="nowrap" bgcolor='.($this->loop ? '#ff9966' : self::CURRENT_PORT_BGCOLOR).' title="'.$title.
692 '"><a '.$onclick.'>'.
693 $initport['name'].': </a></td>';
fdc74cf0 694
3badc888 695 return $chainlabel;
696 }
697
698 function getchainrow($allback = false, $rowbgcolor = '#ffffff', $isprev = false)
699 {
700 $port_id = $this->init;
701
702 $initport = $this->ports[$port_id];
703 $portmulti = 0;
704 $prevportmulti = 0;
705
706 $chain = "";
707
708 $remote_id = null;
709 $portalign = false;
710 $portmultis = array();
711 $i=0;
712 foreach($this as $id => $port)
fdc74cf0 713 {
3badc888 714 if($this->loop && (($isprev && $id == $this->last) || ($this->initback === null && !$isprev && $id == $this->first)))
715 $chain .= '<td bgcolor=#ff9966>LOOP</td>';
716
717 $object_text = $this->getprintobject($port);
718 $port_text = $this->getprintport($port);
719
720 if($this->initback !== null && (($isprev && $id == $this->last) || (!$isprev && $id == $this->first)))
fdc74cf0 721 {
3badc888 722 $object_text = "";
723 $port_text = "";
fdc74cf0 724 }
fdc74cf0 725
3badc888 726 $linktype = $port['linktype'];
727 $prevlinktype = ($linktype == 'front' ? 'back' : 'front');
fdc74cf0 728
3badc888 729 if($port[$prevlinktype]['portcount'] > 1)
730 {
731 $prevportmulti++;
732 /* mutlilink: multiple previous links */
fdc74cf0 733
3badc888 734 $notrowbgcolor = ($rowbgcolor == lm_linkchain::ALTERNATE_ROW_BGCOLOR ? '#ffffff' : lm_linkchain::ALTERNATE_ROW_BGCOLOR );
735 if($this->prevportmulti % 2)
736 {
737 $oddbgcolor = $rowbgcolor;
738 $evenbgcolor = $notrowbgcolor;
739 }
740 else
741 {
742 $oddbgcolor = $notrowbgcolor;
743 $evenbgcolor = $rowbgcolor;
744 }
fdc74cf0 745
3badc888 746 $chain = "<td><table id=pmp frame=box><tr id=main><td><table id=pmmain align=right><tr>$chain</tr></table></td></tr><!-- main tr--><tr><td><table id=plcs align=right width=100%>"; // end table pmmain; end main tr
fdc74cf0 747
3badc888 748 $mi = 0;
749 foreach($port[$prevlinktype]['chains'] as $mlc)
750 {
751 $mbgcolor = ($mi % 2 ? $evenbgcolor : $oddbgcolor);
752 $chain .= "<tr bgcolor=$mbgcolor align=right><td><table id=plc><tr>".$mlc->getchainrow($allback,$mbgcolor, true)."</tr></table><!-- end plc --></td></tr>"; // close table plc
753 $mi++;
754 }
755 $chain .= "</table><!--plcs--></td></tr></table><!--pmp--></td><td bgcolor=#ff0000></td>"; // clode tables plcs; pmp
fdc74cf0 756
3badc888 757 }
83b49cf7 758
3badc888 759 if($port_text && !$this->loop && $id == $this->first)
760 {
761 $chain .= $this->_printlinkportsymbol($id, $prevlinktype);
83b49cf7 762
3badc888 763 if($prevlinktype == 'front')
764 $chain .= $this->printcomment($port);
765 }
83b49cf7 766
3badc888 767 // current port align
768 if($this->initback === null && $port_text && !$portmulti && !$prevportmulti && $this->initalign && $id == $port_id)
769 {
770 $portalign = true;
771 $port_text = "</tr></table><!--t1 current--></td><!--end 1st td--><td id=2nd width=100%><table id=t2><tr>$port_text"; // close table t1 current; clode 1st td
772 }
83b49cf7 773
3badc888 774 $object_id = $port['object_id'];
83b49cf7 775
3badc888 776 $prevobject_id = $port[$prevlinktype]['remote_object_id'];
777 $remote_object_id = $port['remote_object_id'];
83b49cf7 778
3badc888 779 if($linktype == 'front')
780 {
781 // $arrow = ' ---> ';
782 if($object_text)
783 {
784 if($prevobject_id != $object_id || $allback)
785 $chain .= $object_text."<td>></td>";
83b49cf7 786
3badc888 787 $chain .= $port_text;
788 }
83b49cf7 789
3badc888 790 }
791 else
792 {
793 // $arrow = ' ===> ';
794 if($object_text)
795 $chain .= $port_text."<td><</td>".$object_text;
796 }
83b49cf7 797
3badc888 798 if($port['portcount'] > 1)
799 {
800
801 /* mutlilink: multiple links */
83b49cf7 802
3badc888 803 $notrowbgcolor = ($rowbgcolor == lm_linkchain::ALTERNATE_ROW_BGCOLOR ? '#ffffff' : lm_linkchain::ALTERNATE_ROW_BGCOLOR );
804 if($this->portmulti % 2)
805 {
806 $oddbgcolor = $rowbgcolor;
807 $evenbgcolor = $notrowbgcolor;
808 }
809 else
810 {
811 $oddbgcolor = $notrowbgcolor;
812 $evenbgcolor = $rowbgcolor;
813 }
814
815 $chain .= "<td bgcolor=#ff0000></td><td><table id=mp frame=box>";
83b49cf7 816
3badc888 817 $multichain = "<tr><td><table id=mlcs width=100%>";
83b49cf7 818
3badc888 819 $mi = 0;
820 foreach($port['chains'] as $mlc)
821 {
83b49cf7 822
3badc888 823 $mbgcolor = ($mi % 2 ? $evenbgcolor : $oddbgcolor);
824 $multichain .= "<tr bgcolor=$mbgcolor><td><table id=t9><tr>".$mlc->getchainrow(false, $mbgcolor)."</tr></table></td></tr>";
825 $mi++;
826 }
83b49cf7 827
3badc888 828 $multichain .= "</table><!-- mlcs --></td></tr>"; // close table mlcs
83b49cf7 829
3badc888 830 $portmultis[] = $multichain;
831
832 // main
833 $chain .= "<tr id=mm><td><table id=pmm><tr>";
83b49cf7 834
3badc888 835 $portmulti++;
83b49cf7 836
3badc888 837 }
838
839 $remote_id = $port['remote_id'];
840
841 if($remote_id)
842 if($object_id != $remote_object_id || $allback || $linktype == 'front')
843 $chain .= $this->printlink($port, $linktype);
844 else
845 $chain .= "<td>></td>";
846
847 if($port_text && !($remote_id && $this->loop) && $id == $this->last)
848 {
849 $chain .= $this->_printlinkportsymbol($id, $linktype);
850
851 if($linktype == 'front')
852 $chain .= $this->printcomment($port);
853 }
854
855 $i++;
856 } // foreach port
857
858 if($this->loop && $remote_id)
859 {
860 $chain .= '<td bgcolor=#ff9966>LOOP</td>';
861 showWarning("Possible Loop on Port ($linktype) ".$initport['name']);
83b49cf7 862 }
83b49cf7 863
3badc888 864 if($this->exceed)
865 {
866 $chain .= '<td bgcolor=#ff9966>LINKCOUNT EXCEEDED</td>';
867 $linktype = $this->getlinktype($this->back);
868 showWarning("Possible Loop linkcount(".$this->linkcount.") exceeded on Port ($linktype) ".$initport['name']);
869 }
83b49cf7 870
3badc888 871 foreach(array_reverse($portmultis) as $multitr)
872 {
873 $chain .= "</tr><!-- tr mm --></table><!-- pmm --></td></tr>$multitr</table><!-- mp--></td>"; // close table pmm; mp
874 }
83b49cf7 875
3badc888 876 if($this->initback === null)
877 {
878 // TODO width..
879 $chain = "<td id=1st".(!$portalign ? " colspan=2" : " width=1%")."><table id=t1".(!$portalign ? "" : " align=right")."><tr>$chain";
880 $chain .= "</tr></table><!-- end t1/t2 --></td><!--1st/2nd td-->"; // close table t1/t2; close 1st/2nd td
881 }
882
883 $this->portmulti += $portmulti;
884 $this->prevportmulti += $prevportmulti;
885
886 return $chain;
887 }
888
889 /*
890 */
891 function getprintobject($port) {
892 global $lc_cache;
893
894 $object_id = $port['object_id'];
895
896 if($object_id == $this->object_id) {
897 $color='color: '.self::CURRENT_OBJECT_BGCOLOR;
898 } else {
899 $color='';
900 }
901
902 $style = "font-size: 80%;";
903
904 $rack = null;
905 $object = $lc_cache->getobject($object_id, $rack);
906
c91b2c53 907 $rackinfo = $this->_getprintrack($object_id, $rack, $style);
5ddfc8cc 908
909 if($object['container_id'])
910 {
911 $container_rack = null;
912 $container = $lc_cache->getobject($object['container_id'], $container_rack);
c91b2c53 913 $container_rackinfo = $this->_getprintrack($object['container_id'], $container_rack, $style);
5ddfc8cc 914
915 $txt = '<a style="font-weight:bold;'
916 .$color.'" href="'.makeHref(array('page'=>'object', 'tab' => 'linkmgmt', 'object_id' => $container['id']))
917 .'"><pre>'.$container['name'].'</pre></a><pre>'.$container_rackinfo
918 .'</pre>';
919
920 $txt = "<tr><td><label style=\"font-size: 60%;\">Container:</label>$txt<hr></td></tr>";
921 }
922 else
923 $txt = '';
924
925
926 return '<td><table frame=box align=center cellpadding=5 cellspacing=0>'.$txt.'<tr><td align=center><a style="font-weight:bold;'
927 .$color.'" href="'.makeHref(array('page'=>'object', 'tab' => 'linkmgmt', 'object_id' => $object_id))
928 .'"><pre>'.$object['name'].'</pre></a><pre>'.$rackinfo
929 .'</pre></td></tr></table></td>';
930
931 } /* getprintobject */
932
c91b2c53 933 function _getprintrack($object_id, $rack, $style)
5ddfc8cc 934 {
c91b2c53 935 $slot = null;
936 $attrData = getAttrValues ($object_id);
937 if (isset ($attrData['28'])) // slot number
938 {
939 $slot = $attrData['28']['value'];
940 if (preg_match ('/\d+/', $slot, $matches))
941 $slot = $matches[0];
942 }
943
944 if(!$slot)
945 $txt = 'Unmounted';
946 else
947 $txt = "Slot: $slot";
948
949
950 if($slot)
951 $rackinfo = '<span style="'.$style.'">Slot: '.$slot.'</span>';
952 else
953 $rackinfo = '';
954
955 if($rack)
3badc888 956 {
c91b2c53 957 if($slot)
958 $rackinfo .= "<br>";
959
960 $rackinfo .= '<a style="'.$style.'" href='.makeHref(array('page'=>'row', 'row_id'=>$rack['row_id'])).'>'.$rack['row_name']
3badc888 961 .'</a>/<a style="'.$style.'" href='.makeHref(array('page'=>'rack', 'rack_id'=>$rack['id'])).'>'
962 .$rack['name'].'</a>';
963 }
964
c91b2c53 965 if(!$rackinfo)
966 $rackinfo = '<span style="'.$style.'">Unmounted</span>';
967
5ddfc8cc 968 return $rackinfo;
969 }
3badc888 970
971 function getprintport($port, $multilink = false) {
972 global $lm_cache, $lm_multilink_port_types;
973
974 /* multilink port */
975 $multilink = in_array($port['oif_id'], $lm_multilink_port_types);
976
977 /* set bgcolor for current port */
978 if($this->initback === null && $port['id'] == $this->init) {
979 $bgcolor = 'bgcolor='.self::CURRENT_PORT_BGCOLOR;
980 $idtag = ' id='.$port['id'];
981 } else {
982 $bgcolor = 'bgcolor=#e0e0f8';
983 $idtag = '';
984 }
985
986 $mac = trim(preg_replace('/(..)/','$1:',$port['l2address']),':');
987
988 $title = "Label: ${port['label']}\nMAC: $mac\nTypeID: ${port['oif_id']}\nPortID: ${port['id']}";
989
990 if(isset($port['portip']))
991 $ip = "<br><p style=\"font-size: 80%\">".$port['portip']."</p>";
992 else
993 $ip = "";
994
995 return '<td><table><tr><td'.$idtag.' align=center '.$bgcolor.' title="'.$title.'"><pre>[<a href="'
996 .makeHref(array('page'=>'object', 'tab' => 'linkmgmt', 'object_id' => $port['object_id'], 'hl_port_id' => $port['id']))
997 .'#'.$port['id']
998 .'">'.$port['name'].'</a>]'.$ip.'</pre>'.($multilink && $lm_cache['allowbacklink'] ? $this->_getlinkportsymbol($port['id'], 'back') : '' ).'</td></tr></table></td>';
999
1000 } /* printport */
1001
1002 /*
1003 */
1004 function printlink($port, $linktype) {
1005
3badc888 1006 if($linktype == 'back')
3badc888 1007 $arrow = '====>';
3badc888 1008 else
1009 $arrow = '---->';
1010
1011 $port_id = $port['id'];
1012
1013 /* link */
1014 return '<td align=center>'
16ec374c 1015 .'<pre><span class="editable id1-'.$port_id.' id2-'.$port['remote_id'].' op-lm-upd-reservation-cable linktype-'.$linktype.'">'.$port['cableid']
1016 ."</span></pre><pre>$arrow</pre>"
3badc888 1017 .$this->_printUnLinkPort($port, $linktype)
1018 .'</td>';
1019 } /* printlink */
1020
1021 /*
1022 * return link symbol
1023 */
1024 function _getlinkportsymbol($port_id, $linktype) {
1025 $retval = '<span onclick=window.open("'.makeHrefProcess(array_merge($_GET,
1026 array('op' => 'PortLinkDialog','port' => $port_id,'linktype' => $linktype ))).'","name","height=800,width=800");'
1027 .'>';
1028
1029 $img = getImageHREF ('plug', $linktype.' Link this port');
1030
1031 if($linktype == 'back')
1032 $img = str_replace('<img',
1033 '<img style="transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg);-moz-transform:rotate(180deg);-webkit-transform:rotate(180deg);"',
1034 $img);
1035
1036 $retval .= $img;
1037 $retval .= "</span>";
1038 return $retval;
1039
1040 } /* _getlinkportsymbol */
1041
1042 /*
1043 * print link symbol
1044 *
1045 */
1046 function _printlinkportsymbol($port_id, $linktype = 'front') {
1047 global $lm_cache;
1048
1049 if($linktype == 'front' && !$lm_cache['allowlink'])
1050 return;
1051
1052 if($linktype != 'front' && !$lm_cache['allowbacklink'])
1053 return;
1054
1055 return "<td align=center>"
1056 .$this->_getlinkportsymbol($port_id, $linktype)
1057 ."</td>";
1058
1059 } /* _printlinkportsymbol */
1060
1061 /*
1062 */
1063 function printcomment($port) {
1064
1065 if(!empty($port['reservation_comment'])) {
1066 $prefix = '<b>Reserved: </b>';
1067 } else
1068 $prefix = '';
1069
16ec374c 1070 return '<td>'.$prefix.'</td><td><i><span class="editable op-upd-reservation-port id-'.$port['id'].'">'.$port['reservation_comment'].'</span</i></td>';
3badc888 1071
1072 } /* printComment */
1073
1074 /*
1075 * return link cut symbol
1076 *
1077 * TODO $opspec_list
1078 */
1079 function _printUnLinkPort($src_port, $linktype) {
1080 global $lm_cache;
1081
1082 if($linktype == 'front' && !$lm_cache['allowlink'])
1083 return;
1084
1085 if($linktype != 'front' && !$lm_cache['allowbacklink'])
1086 return;
1087
1088 $dst_port = $this->ports[$src_port['remote_id']];
1089
1090 return '<a href='.
1091 makeHrefProcess(array(
1092 'op'=>'unlinkPort',
1093 'port_id'=>$src_port['id'],
1094 'remote_id' => $dst_port['id'],
4e33157f 1095 'hl_port_id' => $this->init,
3badc888 1096 'object_id'=> $this->object_id, //$this->ports[$this->init]['object_id'],
1097 'tab' => 'linkmgmt',
1098 'linktype' => $linktype)).
1099 ' onclick="return confirm(\'unlink ports '.$src_port['name']. ' -> '.$dst_port['name']
1100 .' ('.$linktype.') with cable ID: '.$src_port['cableid'].'?\');">'.
1101 getImageHREF ('cut', $linktype.' Unlink this port').'</a>';
1102
1103 } /* _printUnLinkPort */
1104
3d9d3e22 1105 function printports()
1106 {
1107
1108 $back = isset($this->ports[$this->first]['back']['remote_id']);
d894f236 1109 //$this->getporttds($this->first, $back);
1110 foreach($this as $port_id => $port)
1111 {
1112 $class = 'hidden';
1113 if($port_id == $this->first || $port_id == $this->last)
1114 $class = '';
1115
1116 $this->getporttds($port, $class);
1117 }
3d9d3e22 1118 }
1119
d894f236 1120 function getporttds($port, $class = '')
569219fa 1121 {
d894f236 1122 $back = ($port['linktype'] == 'front' ? false : true );
569219fa 1123
c205dc54 1124 $prev_port = $port[( !$back ? 'back' : 'front')];
1125 if ($prev_port['portcount'] > 1)
1126 echo '<td style="color: red;" class="hidden">+'.($prev_port['portcount'] - 1).'</td>';
1127 else
1128 echo '<td class="hidden"></td>';
1129
569219fa
CR
1130 // see interface.php renderObjectPortRow()
1131 // highlight port name with yellow if it's name is not canonical
1132 $canon_pn = shortenPortName ($port['name'], $port['object_id']);
1133 $name_class = $canon_pn == $port['name'] ? '' : 'trwarning';
1134
1135 echo "<td class='tdleft $class'>" .
1136 formatPortLink ($port['object_id'], $port['object_name'], $port['id'], NULL) .
1137 "</td>";
1138
1139 $a_class = isEthernetPort ($port) ? 'port-menu' : '';
1140 echo "<td class='tdleft $class' NOWRAP><a name='port-${port['id']}' class='interactive-portname nolink $a_class'>${port['name']}</a></td>";
1141 echo "<td class='tdleft $class'>${port['label']}</td>";
1142 echo "<td class='tdleft $class'>" . formatPortIIFOIF ($port) . "</td><td class='tdleft $class'><tt>${port['l2address']}</tt></td>";
1143
1144 $remote_port = $port[( $back ? 'back' : 'front')];
1145 if ($remote_port['remote_id'])
1146 {
3d9d3e22 1147 if($port['id'] == $this->first)
1148 {
1149 echo "<td class='tdcenter nothidden'>";
1150
1151 if( $this->linkcount == 1 )
1152 if($back)
1153 echo "=${remote_port['cableid']}=>";
1154 else
1155 echo "-${remote_port['cableid']}->";
1156 else
1157 if( $this->linkcount > 1 )
1158 echo "*".$this->linkcount."*>";
1159 echo "</td>";
1160 }
1161
569219fa 1162 $editable = permitted ('object', 'ports', 'editPort') ? 'editable' : '';
c205dc54 1163
1164 if($remote_port['portcount'] > 1)
1165 echo '<td style="color: red;" class="hidden">'.($remote_port['portcount'] - 1).'+</td>';
1166 else
1167 echo '<td class="hidden"></td>';
1168
d894f236 1169 echo "<td class='tdcenter hidden'>";
569219fa
CR
1170 if($back)
1171 echo "=${remote_port['cableid']}=>";
1172 else
1173 echo "-${remote_port['cableid']}->";
1174
d894f236 1175 echo "</td>";
569219fa
CR
1176 }
1177 else
d894f236 1178 {
1179 if(!empty($port['reservation_comment']))
1180 echo implode ('', formatPortReservation ($port));
1181 }
569219fa 1182
569219fa
CR
1183 } // getporttds
1184
3badc888 1185 // TODO
1186 // html table
1187 function getchainhtml()
1188 {
1189 $remote_id = $this->first;
1190
1191 // if not Link use LinkBackend
1192 $back = $this->ports[$remote_id]['front']['remote_id'];
1193
1194 $chain = "<table>";
1195
1196 for(;$remote_id;)
1197 {
1198 $back = !$back;
1199 $linktype = $port['linktype'];
1200
1201 if($back)
1202 {
1203 // $linktable = 'LinkBackend';
1204 $arrow = ' => ';
1205 }
1206 else
1207 {
1208 // $linktable = 'Link';
1209 $arrow = ' --> ';
1210 }
1211
1212 $port = $this->ports[$remote_id][$linktype];
1213
1214 if($this->init == $remote_id)
1215 $chain .= "<tr><td><b>".$port['object_name']."</b></td><td><b> [".$port['name']."]</b></td>";
1216 else
1217 $chain .= "<tr><td>".$port['object_name']."</td><td> [".$port['name']."]</td>";
1218
1219 if($remote_id == $this->first || $remote_id == $this->last)
1220 $chain .= "<td><div name=\"port${remote_id}-status\"></div></td>";
1221 else
1222 $chain .= "<td></td>";
1223
1224 $remote_id = $port['remote_id'];
1225
1226 if($remote_id)
1227 $chain .= "<td>$arrow</td></tr>";
1228 else
1229 $chain .= "<td></td></tr>";
1230
1231 if($this->loop && $remote_id == $this->first)
1232 {
1233 $chain .= "LOOP!<br>";
1234 break;
1235 }
1236
1237 }
1238
1239 $chain .= "</table>";
1240
1241 return $chain;
1242 }
1243
1244 function getport($id)
1245 {
1246 return $this->ports[$id];
1247 }
1248
1249 /* Iterator */
1250 function rewind() {
1251 $this->currentid = $this->first;
1252
1253 $this->back = isset($this->ports[$this->currentid]['back']['remote_id']);
1254
1255 $this->icount = 0;
1256 }
1257
1258 function current() {
1259 return $this->_getportlink($this->ports[$this->currentid]);
1260 }
1261
1262 function key() {
1263 return $this->currentid;
1264 }
1265
1266 function next() {
1267 $port = $this->current();
1268 $remote_id = $port['remote_id'];
1269
1270 if($this->loop && $remote_id == $this->first)
1271 $this->currentid = false;
1272 else
1273 $this->currentid = $remote_id;
1274
1275 $this->back = !$this->back;
1276
1277 $this->icount++;
1278 }
1279
1280 function valid() {
1281
1282 /* linkcout exceeded */
1283 if($this->icount > $this->linkcount+1)
1284 {
1285 $this->exceed = true;
1286 return false;
1287 }
1288
1289 return $this->currentid;
1290 }
1291
1292 /* for debugging only */
1293 function var_dump_html(&$var, $msg = "") {
1294 echo "<pre>------------------Start Var Dump -------------$msg------------\n";
1295 var_dump($var);
1296 echo "\n---------------------END Var Dump -----------$msg-------------</pre>";
1297 }
1298} // lm_linkchain
1299
1300/*
1301 * from RT database.php fetchPortList()
1302 * with Link table selection
1303 * and multilink changes
1304 */
1305function lm_fetchPortList ($sql_where_clause, $query_params = array(), $linktable = 'Link')
1306{
1307 $query = <<<END
1308SELECT
1309 Port.id,
1310 Port.name,
1311 Port.object_id,
1312 Object.name AS object_name,
1313 Port.l2address,
1314 Port.label,
1315 Port.reservation_comment,
1316 Port.iif_id,
1317 Port.type AS oif_id,
1318 (SELECT PortInnerInterface.iif_name FROM PortInnerInterface WHERE PortInnerInterface.id = Port.iif_id) AS iif_name,
1319 (SELECT PortOuterInterface.oif_name FROM PortOuterInterface WHERE PortOuterInterface.id = Port.type) AS oif_name,
1320
1321 lk.cable AS cableid,
1322 IF(lk.porta = Port.id, pb.id, pa.id) AS remote_id,
1323 IF(lk.porta = Port.id, pb.name, pa.name) AS remote_name,
1324 IF(lk.porta = Port.id, pb.object_id, pa.object_id) AS remote_object_id,
1325 IF(lk.porta = Port.id, ob.name, oa.name) AS remote_object_name,
1326
1327 (SELECT COUNT(*) FROM PortLog WHERE PortLog.port_id = Port.id) AS log_count,
1328 PortLog.user,
1329 UNIX_TIMESTAMP(PortLog.date) as time
1330FROM
1331 Port
1332 INNER JOIN Object ON Port.object_id = Object.id
1333
1334 LEFT JOIN $linktable AS lk ON lk.porta = Port.id or lk.portb = Port.id
1335 LEFT JOIN Port AS pa ON pa.id = lk.porta
1336 LEFT JOIN Object AS oa ON pa.object_id = oa.id
1337 LEFT JOIN Port AS pb ON pb.id = lk.portb
1338 LEFT JOIN Object AS ob ON pb.object_id = ob.id
1339
1340 LEFT JOIN PortLog ON PortLog.id = (SELECT id FROM PortLog WHERE PortLog.port_id = Port.id ORDER BY date DESC LIMIT 1)
1341WHERE
1342 $sql_where_clause
1343END;
1344
1345 $result = usePreparedSelectBlade ($query, $query_params);
1346
1347 $ret = array();
1348 while ($row = $result->fetch (PDO::FETCH_ASSOC))
1349 {
1350 $row['l2address'] = l2addressFromDatabase ($row['l2address']);
1351 $row['linked'] = isset ($row['remote_id']) ? 1 : 0;
1352
1353 // last changed log
1354 $row['last_log'] = array();
1355 if ($row['log_count'])
1356 {
1357 $row['last_log']['user'] = $row['user'];
1358 $row['last_log']['time'] = $row['time'];
1359 }
1360 unset ($row['user']);
1361 unset ($row['time']);
1362
1363 $ret[] = $row;
1364 }
1365 return $ret;
1366} /* lm_fetchPortList */
1367
1368function lm_getPortInfo ($port_id, $back = false)
1369{
1370 $linktable = ($back ? 'LinkBackend' : 'Link');
1371 if($back)
1372 $result = lm_fetchPortList ('Port.id = ?', array ($port_id), $linktable);
1373 else
1374 $result = fetchPortList ('Port.id = ?', array ($port_id));
1375
1376 //return empty ($result) ? NULL : $result[0];
1377 return $result;
1378} /* lm_getPortInfo */
1379
1380/* -------------------------------------------------------------------------- */
1381/* -------------------------------------------------- */
1382
1383function linkmgmt_opHelp() {
1384?>
1385 <table cellspacing=10><tr><th>Help</th><tr>
48d66be9 1386 <tr><td width=150></td><td width=150 style="font-weight:bold;color:<?php echo lm_linkchain::CURRENT_OBJECT_BGCOLOR; ?>">Current Object</td></tr>
1387 <tr><td></td><td bgcolor=<?php echo lm_linkchain::CURRENT_PORT_BGCOLOR; ?>>[current port]</td></tr>
3badc888 1388 <tr><td>front link</td><td>[port]<(Object)</td><td>back link</td></tr>
1389 <tr><td>back link</td><td>(Object)>[port]</td><td>front link</td></tr>
1390 <tr><td></td><td><pre>----></pre></td><td>Front link</td></tr>
1391 <tr><td></td><td><pre>====></pre></td><td>Backend link</td></tr>
1392 <tr><td></td><td>Link Symbol</td><td>Create new link</td></tr>
1393 <tr><td></td><td>Cut Symbol</td><td>Delete link</td></tr>
1394
1395 </table>
1396
1397<?php
1398 exit;
1399} /* opHelp */
1400
1401/* -------------------------------------------------- */
1402
1403function linkmgmt_ajax_mapinfo() {
1404
1405 $object_id = NULL;
1406 $port_id = NULL;
1407 $remote_id = NULL;
1408 $linktype = NULL;
1409
1410 if(isset($_REQUEST['object_id']))
1411 $object_id = $_REQUEST['object_id'];
1412
1413 if(isset($_REQUEST['port_id']))
1414 $port_id = $_REQUEST['port_id'];
1415
1416 if(isset($_REQUEST['remote_id']))
1417 $remote_id = $_REQUEST['remote_id'];
1418
1419 if(isset($_REQUEST['linktype']))
1420 $linktype = $_REQUEST['linktype'];
1421
1422 $debug = NULL;
1423 if(isset($_REQUEST['debug']))
1424 $debug['value'] = $_REQUEST['debug'];
1425
1426 $info = array();
1427
1428 echo "<table style=\"font-size:12;\"><tr>";
1429
1430 if($port_id != NULL)
1431 {
1432 $port = new linkmgmt_RTport($port_id);
1433
1434 echo "<td>";
1435 $port->printtable('both');
1436 echo "</td>";
1437
1438 if($debug)
1439 $debug['port'] = &$port;
1440
1441 if($remote_id != NULL)
1442 {
1443
1444 $remote_port = new linkmgmt_RTport($remote_id);
1445
1446 echo "<td><table align=\"center\">";
1447
1448 // TODO cableid
1449 echo "<tr><td><pre>".($linktype == 'back' ? ' ===> ' : ' ---> ')."</pre></td></tr>";
1450
1451 $port->printunlinktr($linktype, $remote_port);
1452
1453 echo "</table></td>";
1454
1455
1456 echo "<td>";
1457 $remote_port->printtable('both');
1458 echo "</td>";
1459
1460 if($debug)
1461 $debug['remote_port'] = &$remote_port;
1462
1463 }
1464 else
1465 $port->printunlinktr();
1466
1467
1468 }
1469 echo "</tr><tr>";
1470
1471 echo "<td>";
1472 $object = linkmgmt_RTport::printobjecttable($object_id);
1473 echo "</td>";
1474
1475 if($debug)
1476 $debug['object'] = &$object;
1477
1478 if($remote_id != NULL)
1479 {
1480
1481 echo "<td></td>"; /* link */
1482 echo "<td>";
1483 $remote_object = linkmgmt_RTport::printobjecttable($remote_port->port['object_id']);
1484 echo "</td>";
1485
1486 if($debug)
1487 $debug['remote_object'] = &$remote_object;
1488 }
1489
1490 echo "</tr></table>";
1491
1492 if($debug)
1493 {
1494 echo "<pre>--- Debug ---";
1495 var_dump($debug);
1496 echo "</pre>";
1497 }
1498
1499 exit;
1500}
1501
1502/* -------------------------------------- */
1503function lm_renderObjectCell ($cell)
1504{
1505 echo "<table class='slbcell vscell'><tr><td rowspan=2 width='5%'>";
1506 printImageHREF ('OBJECT');
1507 echo '</td><td>';
1508 echo mkA ('<strong>' . niftyString ($cell['dname']) . '</strong>', 'object', $cell['id']);
1509 echo '</td></tr><tr><td>';
1510 echo count ($cell['etags']) ? ("<small>" . serializeTags ($cell['etags']) . "</small>") : '&nbsp;';
1511 echo "</td></tr></table>";
1512}
1513/* -------------------------------------- */
1514
1515// TODO replace..
1516class linkmgmt_RTport {
1517
1518 private $port_id = NULL;
1519
1520 public $port = false;
1521
1522 function __construct($port_id) {
1523
1524 $this->port = getPortInfo($port_id);
1525
1526 if($this->port === false)
1527 return;
1528
1529 /* successfully get port info */
1530 $this->port_id = $port_id;
1531
1532 } /* __construct */
1533
1534 function isvalid() {
1535 return ($port_id !== NULL);
1536 }
1537
1538 function getlinks($type = 'front') {
1539 } /* getlinks */
1540
1541 function printtable($linktype = 'front') {
1542
1543 if($this->port_id == NULL)
1544 return;
1545
1546 echo "<table>";
1547
1548 $urlparams = array(
1549 'module' => 'redirect',
1550 'page' => 'object',
1551 'tab' => 'linkmgmt',
1552 'op' => 'map',
1553 'object_id' => $this->port['object_id'],
1554 'port_id' => $this->port_id,
1555 'usemap' => 1,
1556 );
1557
1558 echo '<tr><td><a title="don\'t highlight port" href="?'.http_build_query($urlparams).'">-phl</a></td>';
1559
1560 $urlparams['hl'] = 'p';
1561 echo '<td><a title="highlight port" href="?'.http_build_query($urlparams).'">+phl</a></td></tr>';
1562
1563 $this->_printinforow($this->port,
1564 array(
1565 'id' => 'Port ID',
1566 'name' => 'Port Name',
1567 'oif_name' => 'Port Type',
1568 'l2address' => 'MAC',
1569 'reservation_comment' => 'comment',
1570 )
1571 ); /* printinforow */
1572
1573 $this->printlinktr($linktype);
1574
1575 echo "</table>";
1576 } /* printtable */
1577
1578 function printlinktr($linktype = 'front') {
1579 if($this->port_id === NULL)
1580 return;
1581
1582 $urlparams = array(
1583 'tab' => 'linkmgmt',
1584 'page' => 'object',
1585 'op'=>'PortLinkDialog',
1586 'port'=>$this->port_id,
1587 'object_id'=>$this->port['object_id'],
1588 'linktype' => $linktype,
1589 );
1590
1591 echo "<tr><td align=\"center\"><a href='".
1592 makeHrefProcess($urlparams).
1593 "'>";
1594 printImageHREF ('plug', 'Link this port');
1595 echo "</a></td></tr>";
1596 } /* link */
1597
1598 function printunlinktr($linktype = 'front', $remote_port = NULL) {
1599 if($this->port_id === NULL)
1600 return;
1601
1602 $urlparams = array(
1603 'tab' => 'linkmgmt',
1604 'op'=>'unlinkPort',
1605 'port_id'=>$this->port_id,
1606 'object_id'=>$this->port['object_id'],
1607 'linktype' => $linktype,
1608 );
1609
1610 $confirmmsg = "unlink port ".$this->port['name'];
1611
1612 if($remote_port !== NULL)
1613 {
1614 $urlparams['remote_id'] = $remote_port->port['id'];
1615 $confirmmsg .= ' -> '.$remote_port->port['name'];
1616 }
1617
1618 $confirmmsg .= " ($linktype)"; // TODO cableid
1619
1620 echo "<tr><td align=\"center\"><a href='".makeHrefProcess($urlparams).
1621 "' onclick=\"return confirm('$confirmmsg');\">";
1622 printImageHREF ('cut', 'Unlink this port');
1623 echo "</a></td></tr>";
1624
1625 } /* unlink */
1626
1627 /* TODO move to object class */
1628 static function printobjecttable($object_id = NULL) {
1629
1630 if($object_id === NULL)
1631 return;
1632
1633 $object = spotEntity ('object', $object_id);
1634
1635 if($object === false)
1636 return;
1637
1638 if($object['rack_id'])
1639 {
1640 $rack = spotEntity('rack', $object['rack_id']);
1641
1642 $object['row_name'] = $rack['row_name'];
1643 $object['rack_name'] = $rack['name'];
1644 }
1645
1646 echo "<table><tr><td>";
1647 lm_renderObjectCell($object);
1648 echo "</td></tr><tr><td><table>";
1649
1650 self::_printinforow($object,
1651 array(
1652 'id' => 'ID',
1653 'dname' => 'Name',
1654 'label' => 'Label',
1655 'rack_name' => 'Rack',
1656 'row_name' => 'Row',
1657 )
1658
1659 ); /* printinforow */
1660
1661 $urlparams = array(
1662 'module' => 'redirect',
1663 'page' => 'object',
1664 'tab' => 'linkmgmt',
1665 'op' => 'map',
1666 'object_id' => $object_id,
1667 'usemap' => 1,
1668 );
1669
1670 echo '<tr><td><a title="don\'t highlight object" href="?'.http_build_query($urlparams).'">-ohl</a></td>';
1671
1672 $urlparams['hl'] = 'o';
1673 echo '<td><a title="highlight object" href="?'.http_build_query($urlparams).'">+ohl</a></td></tr>';
1674
1675 echo "</table></td></tr></table>";
1676
1677 return $object;
1678
1679 } /* printobjecttable */
1680
1681 static function _printinforow(&$data, $config) {
1682
1683 foreach($config as $key => $name)
1684 {
1685 if(isset($data[$key]))
1686 {
1687 $value = $data[$key];
1688 if(!empty($value))
1689 echo "<tr><td align=\"right\" nowrap=\"nowrap\" style=\"font-size:10;\">$name:</td><td nowrap=\"nowrap\">$value</td></tr>";
1690 }
1691 }
1692
1693 } /* _printinforow */
1694} /* class RTport */
1695
1696/* -------------------------------------------------- */
1697
1698function linkmgmt_opmap() {
1699
1700 /* display require errors "white screen of death" */
1701 $errorlevel = error_reporting();
1702 error_reporting(E_ALL);
1703
1704 require_once 'Image/GraphViz.php';
1705
1706/*
1707 *
1708 */
1709class lm_Image_GraphViz extends Image_GraphViz {
1710
1711 /* extend renderDotFile with additional output file
1712 */
1713 function renderDotFile($dotfile, $outputfile, $format = 'svg',
1714 $command = null, $outputfile2 = null, $format2 = null)
1715 {
1716 if (!file_exists($dotfile)) {
1717 if ($this->_returnFalseOnError) {
1718 return false;
1719 }
1720 $error = PEAR::raiseError('Could not find dot file');
1721 return $error;
1722 }
1723
1724 $oldmtime = file_exists($outputfile) ? filemtime($outputfile) : 0;
1725
1726 switch ($command) {
1727 case 'dot':
1728 case 'neato':
1729 break;
1730 default:
1731 $command = $this->graph['directed'] ? 'dot' : 'neato';
1732 }
1733 $command_orig = $command;
1734
1735 $command = $this->binPath.(($command == 'dot') ? $this->dotCommand
1736 : $this->neatoCommand);
1737
1738 $command .= ' -T'.escapeshellarg($format)
1739 .' -o'.escapeshellarg($outputfile)
1740 .($format2 !== null && $outputfile2 !== null ? ' -T'.escapeshellarg($format2).' -o'.escapeshellarg($outputfile2) : '')
1741 .' '.escapeshellarg($dotfile)
1742 .' 2>&1';
1743
1744 exec($command, $msg, $return_val);
1745
1746 clearstatcache();
1747 if (file_exists($outputfile) && filemtime($outputfile) > $oldmtime
1748 && $return_val == 0) {
1749 return true;
1750 } elseif ($this->_returnFalseOnError) {
1751 return false;
1752 }
1753 $error = PEAR::raiseError($command_orig.' command failed: '
1754 .implode("\n", $msg));
1755 return $error;
1756 }
1757 // renderDotFile
1758
1759
1760 /*
1761 */
1762 function fetch($format = 'svg', $command = null, $format2 = null, &$data2 = null)
1763 {
1764
1765 $file = $this->saveParsedGraph();
1766 if (!$file || PEAR::isError($file)) {
1767 return $file;
1768 }
1769
1770 $outputfile = $file . '.' . $format;
1771
1772 if($format2 != null && $data2 !== null)
1773 $outputfile2 = $file . '.' . $format2;
1774 else
1775 $outputfile2 = null;
1776
1777 $rendered = $this->renderDotFile($file, $outputfile, $format,
1778 $command, $outputfile2, $format2);
1779 if ($rendered !== true) {
1780 return $rendered;
1781 }
1782
1783 @unlink($file);
1784
1785 if($format2 !== null && $data2 !== null) {
1786 $fp = fopen($outputfile2, 'rb');
1787
1788 if ($fp) {
1789 $data = fread($fp, filesize($outputfile2));
1790 fclose($fp);
1791 @unlink($outputfile2);
1792
1793 $data2 = $data;
1794 } else {
1795 return $error;
1796 }
1797 }
1798
1799
1800 $fp = fopen($outputfile, 'rb');
1801
1802 if (!$fp) {
1803 if ($this->_returnFalseOnError) {
1804 return false;
83b49cf7 1805 }
1806 $error = PEAR::raiseError('Could not read rendered file');
1807 return $error;
1808 }
1809
3badc888 1810 $data = fread($fp, filesize($outputfile));
1811 fclose($fp);
1812 @unlink($outputfile);
1813
1814 return $data;
1815 }
1816 // fetch
1817
1818
1819
1820} /* class lm_Image_GraphViz */
1821
1822 error_reporting($errorlevel);
1823
1824 $object_id = NULL;
1825 $port_id = NULL;
1826 $remote_id = NULL;
1827 $allports = false;
1828 $usemap = false;
1829 $command = NULL;
1830
1831 /* highlight object */
1832 $hl = NULL;
1833 if(isset($_REQUEST['hl']))
1834 {
1835 $hl = $_REQUEST['hl'];
1836 unset($_REQUEST['hl_object_id']);
1837 unset($_REQUEST['hl_port_id']);
1838
1839 if($hl == 'o')
1840 {
1841 unset($_GET['port_id']);
1842 unset($_GET['remote_id']);
1843 }
1844
1845 }
1846
1847 if(!$hl && isset($_REQUEST['hl_object_id']))
1848 {
1849 $hl = 'o';
1850 $object_id = $_REQUEST['hl_object_id'];
1851 $_REQUEST['object_id'] = $object_id;
1852 unset($_REQUEST['hl_object_id']);
1853 unset($_REQUEST['hl_port_id']);
1854 unset($_REQUEST['port_id']);
1855 }
1856
1857 if(isset($_REQUEST['object_id']))
1858 $object_id = $_REQUEST['object_id'];
1859
1860 if(isset($_REQUEST['type']))
1861 {
1862 $type = $_REQUEST['type'];
1863 }
1864 else
1865 $type = 'gif';
1866
1867 /* highlight port */
1868 if(!$hl && isset($_REQUEST['hl_port_id']))
1869 {
1870 $hl = 'p';
1871 $port_id = $_REQUEST['hl_port_id'];
1872 $_REQUEST['port_id'] = $port_id;
1873 unset($_REQUEST['hl_port_id']);
1874 }
1875
1876 if(isset($_REQUEST['allports']))
1877 {
1878 $allports = $_REQUEST['allports'];
1879 }
1880
1881 if(isset($_REQUEST['port_id']))
1882 {
1883 $port_id = $_REQUEST['port_id'];
1884 }
1885
1886 if(isset($_REQUEST['usemap']))
1887 $usemap = $_REQUEST['usemap'];
1888
1889 if($hl == 'p' && $port_id === NULL)
1890 {
1891 unset($_GET['hl']);
1892 unset($_GET['port_id']);
1893 unset($_GET['remote_id']);
1894 }
1895
1896 if($hl == 'o')
1897 unset($_GET['remote_id']);
1898
1899 if(isset($_REQUEST['remote_id']))
1900 $remote_id = $_REQUEST['remote_id'];
1901
1902 /* show all objects */
1903 if(isset($_REQUEST['all']))
1904 {
1905 $object_id = NULL;
1906 $port_id = NULL;
1907 $hl = NULL;
1908 unset($_GET['hl']);
1909 }
1910
1911 if(isset($_REQUEST['cmd']))
1912 $command = $_REQUEST['cmd'];
1913
1914 if(isset($_REQUEST['debug']))
1915 $debug = $_REQUEST['debug'];
1916 else
1917 $debug = False;
1918
1919 if($debug) echo "-- DEBUG --<br>";
1920
1921
1922 switch($type) {
1923 case 'gif':
1924 case 'png':
1925 case 'bmp':
1926 case 'jpeg':
1927 case 'tif':
1928 case 'wbmp':
1929 $ctype = "image/$type";
1930 break;
1931 case 'jpg':
1932 $ctype = "image/jpeg";
1933 break;
1934 case 'svg':
1935 $ctype = 'image/svg+xml';
1936 break;
1937 case 'pdf':
1938 $ctype = 'application/pdf';
1939 break;
1940 case 'cmapx':
1941 $ctype = 'text/plain';
1942 break;
1943 }
1944
1945 $start = microtime(true);
1946 $gvmap = new linkmgmt_gvmap($object_id, $port_id, $allports, $hl, $remote_id);
1947 $stop = microtime(true);
1948
1949 if($debug)
1950 echo "gvmap Time: ".( $stop - $start )."<br>";
1951
1952 if($debug) echo "-- after gvmap --<br>";
1953
1954 if($usemap)
1955 {
1956
1957 if($debug) echo "-- usemap --<br>";
1958
1959 /* add context menu to Ports, Objects, Links, ...
1960 */
1961
1962 echo "<script>
1963 function initcontextmenu() {
1964 var maps = document.getElementsByTagName('map');
1965 for(var i=0;i<maps.length;i++) {
1966 var areas = maps[i].childNodes;
1967
1968 for(j=0;j<areas.length;j++) {
1969 if(areas[j].nodeType == 1)
1970 {
1971 // console.log(areas[j].id);
1972 // attr = document.createAttribute('onmouseover','ahh');
1973 // areas[j].setAttribute(attr);
1974 // areas[j].onmouseover = 'menu(this);';
1975
1976 areas[j].addEventListener('contextmenu',menu,false);
1977 // areas[j].oncontextmenu = 'menu(this, event);';
1978 // console.log(areas[j].oncontextmenu);
1979 }
1980 }
1981
1982 }
1983
1984 };
1985
1986 function menu(event) {
1987
1988 // console.log('Menu');
1989
1990 if(!event)
1991 event = window.event;
1992
1993 var parent = event.target;
1994
1995 // console.log('--' + parent);
1996
1997 var ids = parent.id.split('-');
1998
1999 if(ids[0] == 'graph1')
2000 return false;
2001
2002 var object_id = ids[0];
2003
2004 var url ='?module=ajax&ac=lm_mapinfo&object_id=' + object_id;
2005
2006 // links ='<li><a href=' + object_id + '>Object</a></li>';
2007
2008 if(ids[1] != '')
2009 {
2010 var port_id = ids[1];
2011 url += '&port_id=' + port_id;
2012 // links += '<li><a href=' + port_id + '>Port</a></li>';
2013
2014 if(ids[2] != '')
2015 {
2016 var remote_id = ids[2];
2017
2018 if(ids[3] != '')
2019 {
2020 var linktype = ids[3];
2021 url += '&remote_id=' + remote_id + '&linktype=' + linktype;
2022 // links += '<li><a href=' + port_id + '_' + remote_id + '_' + linktype + '>Unlink</a></li>';
2023 }
2024 }
2025
2026 }
2027
2028
2029 var xmlHttp = new XMLHttpRequest();
2030 xmlHttp.open('GET', url, false);
2031 xmlHttp.send(null);
2032
2033 var infodiv = document.getElementById('info');
2034 infodiv.innerHTML = xmlHttp.responseText;
2035
2036 // linkdiv = document.getElementById('link');
2037 // linkdiv.innerHTML = links;
2038
2039 var menudiv = document.getElementById('menu');
2040 menudiv.style.position = 'absolute';
2041 menudiv.style.top = (event.clientY + document.body.scrollTop) + 'px';
2042 menudiv.style.left = (event.clientX + document.body.scrollLeft) + 'px';
2043 menudiv.style.display = '';
2044
2045 return false;
2046 };
2047
2048 function mousedown(event) {
2049 // console.log('mouse down');
2050
2051 if(!event)
2052 event = window.event;
2053
2054 if(event.button != 2)
2055 return true;
2056
2057 var menudiv = document.getElementById('menu');
2058
2059 menudiv.style.display = 'none';
2060
2061 return false;
2062 };
2063
2064 </script>";
2065
2066 echo "<body oncontextmenu=\"return false\" onmousedown=\"mousedown(event);\" onload=\"initcontextmenu();\">";
2067
2068 echo "<div id=\"menu\" style=\"display:none; background-color:#ffff90\">
2069 <div id=\"info\"></div>
2070 <ul id=\"link\" style=\"list-style-type:none\"></ul>
2071 </div>";
2072
2073 if($debug)
2074 $gvmap->setFalseOnError(False);
2075
2076 $data2 = '';
2077
2078 $start = microtime(true);
2079 $data = $gvmap->fetch($type, $command, 'cmapx', $data2);
2080 $stop = microtime(true);
2081
2082 if($debug)
2083 echo "DOT time: ".( $stop - $start )."<br>";
2084
2085 if($data === false)
2086 echo "ERROR Fetching image data!<br>";
2087
2088 if(PEAR::isError($data))
2089 echo $data->getMessage();
2090
2091 //echo $gvmap->fetch('cmapx', $command);
2092 echo $data2;
2093
2094 if($debug) echo "-- after map gvmap --<br>";
2095
2096 echo "<img src=\"data:$ctype;base64,".
2097 base64_encode($data).
2098 "\" usemap=#map$object_id />";
2099
2100 if($debug)
2101 {
2102 echo "<pre>";
2103 echo $gvmap->export();
2104 echo "</pre>";
2105
2106 echo "<pre>".$gvmap->parse()."</pre>";
2107 }
2108 }
2109 else
2110 {
2111 $gvmap->image($type);
2112 }
2113
2114 exit;
2115
2116} /* linkmgmt_opmap */
2117
2118class cytoscapedata
2119{
2120 public $objects = array();
2121
2122 public $pids = array();
2123
2124 public $parents = array();
2125 public $nodes = array();
2126
2127 public $edges = NULL;
2128
2129 public $debug = null;
2130
2131 function __construct()
2132 {
2133
2134 $this->edges['parents'] = array();
2135 $this->edges['nodes'] = array();
2136 }
2137
2138 function addnode($id, $values = NULL, &$arr = NULL)
2139 {
2140 $data = array( 'id' => $id );
2141
2142 if($values != NULL)
2143 $data = $data + $values;
2144
2145 $node['data'] = $data;
2146
2147 $this->objects[] = array('group' => 'nodes') + $node;
2148
2149 switch($values['type'])
2150 {
2151 case 'port':
2152 $this->nodes[$id] = array('group' => 'nodes') + $node;
2153 break;
2154 case 'object':
2155 case 'container':
2156 $this->parents[$id] = array('group' => 'nodes') + $node;
2157 break;
2158 }
2159
2160 if($arr !== NULL)
2161 $arr[] = array('group' => 'nodes') + $node;
2162 }
2163
2164 function addedge($id, $source, $target, $values = NULL, &$arr = NULL)
2165 {
2166 $data = array(
2167 'id' => $id,
2168 'source' => $source,
2169 'target' => $target
2170 );
2171
2172 if($values != NULL)
2173 $data = $data + $values;
2174
2175 $edge['data'] = $data;
2176
2177 //$this->elements['edges'][] = $edge;
2178
2179 if($arr !== NULL)
2180 {
2181 $arr[$id] = array('group' => 'edges') + $edge;
2182 }
2183 else
2184 $this->objects[] = array('group' => 'edges') + $edge;
2185
2186 //$this->edges[] = array('group' => 'edges') + $edge;
2187 }
2188
2189 function _addobjectnode($object_id, $type = 'object')
2190 {
2191 global $lc_cache;
2192
2193 if(!isset($this->parents["o$object_id"]))
2194 {
2195 $rack = null;
2196 $object = $lc_cache->getobject($object_id, $rack);
2197
2198 $clustertitle = "${object['dname']}";
2199
2200 //has_problems
2201 //if($object['has_problems'] != 'no')
2202
2203 $rack_text = "";
2204 if(!empty($rack['row_name']) || !empty($rack['name']))
2205 {
2206 $rack_text = "${rack['row_name']} / ${rack['name']}";
2207 }
2208
2209 $data = array('label' => $object['name'], 'text' => $rack_text, 'type' => $type, 'has_problems' => $object['has_problems']);
2210
2211 $container_id = $object['container_id'];
2212 if($container_id)
2213 {
2214 $data['parent'] = "o$container_id";
2215 $this->_addobjectnode($container_id, 'container');
2216 }
2217
2218 $this->addnode('o'.$object_id, $data);
2219 }
2220
2221 }
2222
2223 // cytoscape
2224 function addlinkchain($linkchain, $index) {
2225
2226 foreach($linkchain as $id => $port)
2227 {
2228
2229 if(!$linkchain->linked)
2230 continue;
2231
2232 $this->_addobjectnode($port['object_id']);
2233
2234 $text = (isset($port['portip']) ? $port['portip'] : "" );
2235 $nodedata = array('label' => $port['name'], 'parent' => 'o'.$port['object_id'], 'text' => $text, 'type' => 'port', 'index' => $index , 'loop' => ($linkchain->loop ? '1' : '0'));
2236
2237 //$this->addnode('l_'.$port['id'], array( 'label' => $port['name'], 'parent' => 'p'.$port['id'], 'text' => $text ));
2238
2239 if($port['portcount'] > 1)
2240 foreach($port['chains'] as $mlc)
2241 {
2242 $this->addlinkchain($mlc, 0); // TODO index
2243 }
2244
2245 $prevlinktype = ($port['linktype'] == 'front' ? 'back' : 'front');
2246 if($port[$prevlinktype]['portcount'] > 1)
2247 {
2248 foreach($port[$prevlinktype]['chains'] as $mlc)
2249 {
2250 $this->addlinkchain($mlc, 0, false); // TODO index
2251 }
2252 }
83b49cf7 2253
3badc888 2254 if($port['remote_id'])
2255 {
83b49cf7 2256
3badc888 2257 $this->_addobjectnode($port['remote_object_id']);
83b49cf7 2258
3badc888 2259 $linktype = $port['linktype'];
2260 $edgedata = array('label' => $port['cableid'], 'type' => $linktype, 'loop' => ($linkchain->loop ? '1' : '0'));
83b49cf7 2261
3badc888 2262 if($linkchain->loop && $port['remote_id'] == $linkchain->first)
2263 {
2264 $nodedata['loopedge'] = array('group' => 'edges', 'data' => array( 'id' => 'le'.$port['id']."_".$port['remote_id'], 'source' => 'p'.$port['id'], 'target' => 'p'.$port['remote_id']) + $edgedata);
2265 }
2266 else
2267 {
83b49cf7 2268
3badc888 2269 $this->addedge('e'.$port['id']."_".$port['remote_id'], 'p'.$port['id'], 'p'.$port['remote_id'], $edgedata);
2270 $this->addedge('e'.$port['id']."_".$port['remote_id'], 'p'.$port['id'], 'p'.$port['remote_id'], $edgedata, $this->edges['nodes']);
2271 $id1 = $port['object_id'];
2272 if($id1 > $port['remote_object_id'])
2273 {
2274 $id1 = $port['remote_object_id'];
2275 $id2 = $port['object_id'];
2276 }
2277 else
2278 $id2 = $port['remote_object_id'];
fdc74cf0 2279
3badc888 2280 $peid = "pe".$id1."_".$id2;
fdc74cf0 2281
3badc888 2282 if(isset($this->edges['parents'][$peid]))
2283 $this->edges['parents'][$peid]['data']['linkcount']++;
2284 else
2285 $this->addedge($peid, 'o'.$id1, 'o'.$id2, array('type' => $linktype, 'linkcount' => 1), $this->edges['parents']);
2286 }
2287 }
fdc74cf0 2288
3badc888 2289 $this->addnode('p'.$port['id'], $nodedata);
2290 }
2291
2292 if(0)
2293 if($linkchain->first != $linkchain->last )
fdc74cf0 2294 {
3badc888 2295 $first = $linkchain->first;
2296 $last = $linkchain->last;
2297 $this->addedge("l${first}_${last}",'p'.$first, 'p'.$last, array('type' => 'logical', 'label' => "logical"));
fdc74cf0 2298 }
2299
48d66be9 2300 //lm_linkchain::var_dump_html($this->parents);
fdc74cf0 2301 }
2302
3badc888 2303 function getlinkchains($object_id) {
fdc74cf0 2304
3badc888 2305 $this->objects = array();
2306 $this->parents = array();
2307 $this->nodes = array();
2308 $this->edges['parents'] = array();
2309 $this->edges['nodes'] = array();
fdc74cf0 2310
3badc888 2311 $this->_getlinkchains($object_id);
fdc74cf0 2312 }
fdc74cf0 2313
3badc888 2314 function getelements()
fdc74cf0 2315 {
3badc888 2316 //lm_linkchain::var_dump_html($this);
2317 return array('parents' => array_values($this->parents),
2318 'nodes' => array_values($this->nodes),
2319 'edges' => array(
2320 'parents' => array_values($this->edges['parents']),
2321 'nodes' => array_values($this->edges['nodes'])
2322 ),
2323 'debug' => $this->debug
2324 );
fdc74cf0 2325
fdc74cf0 2326 }
2327
3badc888 2328 function gettest()
fdc74cf0 2329 {
3badc888 2330 return array_merge(array_values($this->parents), array_values($this->edges['parents']));
2331 //return array_merge(array_values($this->parents), array_values($this->edges['parents']), array_values($this->nodes), array_values($this->edges['nodes']));
fdc74cf0 2332 }
2333
3badc888 2334 function _getlinkchains($object_id) {
fdc74cf0 2335
fdc74cf0 2336
3badc888 2337 // container
2338 // $object = spotEntity('object', $object_id);
2339 $object['ports'] = getObjectPortsAndLinks ($object_id);
fdc74cf0 2340
3badc888 2341 $i = 0;
2342 foreach($object['ports'] as $key => $port)
2343 {
fdc74cf0 2344
3badc888 2345 if(isset($this->pids[$port['id']]))
2346 continue;
2347
2348 $i++;
2349 $lc = new lm_linkchain($port['id']);
2350
2351 $this->pids += $lc->pids;
2352
2353 $this->addlinkchain($lc, $i);
2354
2355 }
2356
2357 $children = getEntityRelatives ('children', 'object', $object_id);
2358
2359 foreach($children as $child)
2360 $this->_getlinkchains($child['entity_id']);
2361 }
2362
2363 function allobjects()
fdc74cf0 2364 {
3badc888 2365
2366 $this->objects = array();
2367 $this->parents = array();
2368 $this->nodes = array();
2369 $this->edges['parents'] = array();
2370 $this->edges['nodes'] = array();
2371
2372 $objects = listCells('object');
2373
2374 $i = 0;
2375 foreach($objects as $object)
2376 {
2377 //echo $object['id']."<br>";
2378 $this->_getlinkchains($object['id']);
2379 $i++;
2380 if($i > 20 ) break;
2381 }
fdc74cf0 2382 }
3badc888 2383}
fdc74cf0 2384
3badc888 2385function linkmgmt_cytoscapemap() {
fdc74cf0 2386
fdc74cf0 2387
3badc888 2388 $object_id = $_GET['object_id'];
fdc74cf0 2389
3badc888 2390 if(isset($_GET['json']))
2391 {
2392 ob_start();
2393 $data = new cytoscapedata();
2394 $data->getlinkchains($object_id);
2395 //$data->allobjects(); // ugly graph;
2396 //echo json_encode($data->objects);
fdc74cf0 2397
3badc888 2398 if(ob_get_length())
2399 $data->debug = ob_get_contents();
fdc74cf0 2400
3badc888 2401 ob_end_clean();
2402
2403 echo json_encode($data->getelements());
fdc74cf0 2404
3badc888 2405 exit;
fdc74cf0 2406 }
2407
3badc888 2408 echo (<<<HTMLEND
2409<!DOCTYPE html>
2410<html>
2411<head>
2412<style>
2413body {
2414 font: 14px helvetica neue, helvetica, arial, sans-serif;
2415}
fdc74cf0 2416
3badc888 2417#cy {
2418 height: 100%;
2419 width: 100%;
2420 position: absolute;
2421 left: 0;
2422 top: 0;
2423}
2424</style>
2425<meta charset=utf-8 />
2426<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
2427<title>Compound nodes</title>
2428<!--<script src="js/jquery-1.4.4.min.js"></script>-->
2429
383230c5 2430<script src="?module=chrome&uri=linkmgmt/jquery-1.11.3.min.js"></script>
2431<script src="?module=chrome&uri=linkmgmt/cytoscape.min.js"></script>
2432<script src="?module=chrome&uri=linkmgmt/dagre.min.js"></script>
2433<script src="?module=chrome&uri=linkmgmt/cytoscape-dagre.js"></script>
2434<link rel="stylesheet" type="text/css" href="?module=chrome&uri=linkmgmt/jquery.qtip.min.css">
2435<script src="?module=chrome&uri=linkmgmt/jquery.qtip.min.js"></script>
2436<script src="?module=chrome&uri=linkmgmt/cytoscape-qtip.js"></script>
3badc888 2437
383230c5 2438<!--<script src="?module=chrome&uri=linkmgmt/cytoscape-css-renderer_mod.js"></script>-->
2439<!--<script src="?module=chrome&uri=linkmgmt/cytoscape.js-navigator.js_mod"></script>-->
3badc888 2440<script>
2441var cy = null;
2442var cy2 = null;
2443var layout = null;
2444var data = null;
2445
2446$(function(){ // on dom ready
2447 var cystyle = [
2448 {
2449 selector: 'node',
2450 css: {
2451 'content': 'data(id)',
2452 'text-wrap': 'wrap'
2453 },
2454 style: {
2455 'background-color': '#666',
2456 'label': 'data(label)',
2457 'width': 'label',
2458 'min-zoomed-font-size' : 8,
2459 'text-valign': 'center',
2460 'text-halign': 'center',
2461 'text-wrap': 'wrap',
2462 'shape': function(ele) {
2463 if(ele.data('type') != 'port')
2464 return 'rectangle';
2465 else
2466 return 'ellipse';
2467 },
fdc74cf0 2468
3badc888 2469 }
2470 },
2471 {
2472 selector: '\$node > node',
2473 css: {
2474 'padding-top': '10px',
2475 'padding-left': '10px',
2476 'padding-bottom': '10px',
2477 'padding-right': '10px',
2478 'text-valign': 'top',
2479 'text-halign': 'center',
2480 'background-color': '#bbb',
2481 'min-zoomed-font-size' : 6,
2482 }
2483 },
2484 {
2485 selector: 'edge',
2486 css: {
2487 'target-arrow-shape': 'triangle',
2488 'line-color': function(ele){
2489 if(ele.data('type') == 'front')
2490 return 'black';
2491 else
2492 return 'grey';
2493 },
2494 'line-style': function(ele){
2495 if(ele.data('type') == 'front')
2496 return 'solid';
2497 else
2498 return 'dashed';
2499 },
2500 'width': function(ele){
2501 var ret = 1;
2502 if(ele.data('type') == 'front')
2503 ret = 3;
2504 else
2505 ret = 5;
fdc74cf0 2506
3badc888 2507 if(1)
2508 if(ele.data('linkcount'))
2509 {
2510 ret = (ele.data('linkcount') * ret);
2511 }
fdc74cf0 2512
3badc888 2513 //console.log(ele.data('id') + ret);
2514 return ret;
2515 },
2516// 'curve-style': 'segments',
2517 'font-size': '8',
2518 'min-zoomed-font-size' : 8,
2519 'label': 'data(label)',
2520 'edge-text-rotation': 'autorotate',
2521 'source-arrow-shape': 'none',
2522 'target-arrow-shape': 'none'
2523 }
2524 },
2525 {
2526 selector: '.logical',
2527 css: {
2528 'line-color': '#0000ff',
2529 'width': 5,
2530 'curve-style': 'segments',
2531 'z-index': 0
2532 }
2533 },
2534 {
2535 selector: ':selected',
2536 css: {
2537 'background-color': 'black',
2538 'line-color': 'black',
2539 'target-arrow-color': 'black',
2540 'source-arrow-color': 'black'
2541 }
2542 },
2543 {
2544 selector: '.highlighted',
2545 css: {
2546 'line-color': '#ff0000',
2547 'background-color': '#ff0000'
2548 }
2549 },
2550 {
2551 selector: '.clhighlighted',
2552 css: {
2553 'line-color': '#00ff00',
2554 'background-color': '#00ff00'
2555 }
2556 }
2557 ];
fdc74cf0 2558
3badc888 2559var cylayout = { name: 'dagre', nodeSep: 3, ready: layoutready, stop: layoutstop };
fdc74cf0 2560
3badc888 2561function highlight(evt) {
fdc74cf0 2562
3badc888 2563 //cy = evt.cy;
fdc74cf0 2564
3badc888 2565 var hlclass = evt.data.hlclass;
2566 var ele = evt.cyTarget;
fdc74cf0 2567
3badc888 2568 if(!ele.data)
2569 return;
fdc74cf0 2570
3badc888 2571 if(ele.data('source'))
2572 ele = cy.$( '#' + ele.data('source'));
fdc74cf0 2573
3badc888 2574 var id = ele.data('id');
fdc74cf0 2575
3badc888 2576 if(ele.isParent())
2577 {
2578 // var childs = cy.$('#' + id).children()
2579 // childs.layout({name:'grid', cols: 2, condense: true});
2580 return;
2581 }
fdc74cf0 2582
fdc74cf0 2583
3badc888 2584// console.log('Event ' + hlclass + ' ' + id );
fdc74cf0 2585
3badc888 2586 // remove existing highlights
2587 cy.$('.' + hlclass).removeClass(hlclass);
fdc74cf0 2588
3badc888 2589 var hleles = ele.closedNeighborhood();
fdc74cf0 2590
3badc888 2591 var hlcount = hleles.length;
fdc74cf0 2592
3badc888 2593 // max 100
2594 for(i=0;i<100;i++)
2595 {
2596 hleles = hleles.closedNeighborhood();
fdc74cf0 2597
3badc888 2598 if(hlcount == hleles.length)
2599 break;
fdc74cf0 2600
3badc888 2601 hlcount = hleles.length;
fdc74cf0 2602
3badc888 2603 }
2604 //console.log('End Loop ' + i );
2605 hleles.addClass(hlclass);
fdc74cf0 2606
3badc888 2607// console.log('Event Type: ' + evt.originalEvent.type)
2608// console.log('Event Type: ' + evt.type)
fdc74cf0 2609
3badc888 2610 if(evt.type != 'click')
2611 return;
fdc74cf0 2612
3badc888 2613 var hleles2 = hleles.clone();
2614 hleles2 = hleles2.add(hleles.parents().clone());
fdc74cf0 2615
3badc888 2616 //var cy2 = evt.data.cy2;
fdc74cf0 2617
3badc888 2618 //var ret = evt.data.ret;
fdc74cf0 2619
3badc888 2620 //var j = ret.parents.concat(ret.nodes).concat(ret.edges.nodes);
fdc74cf0 2621
3badc888 2622 cy2.remove(cy2.elements());
2623 cy2.add(hleles2);
2624 //cy2.add(j);
2625 cy2.layout({name: 'dagre', rankDir: 'LR', ready: layoutready});
2626}
fdc74cf0 2627
3badc888 2628function cytoscapeswitch(evt)
2629{
2630 var b = evt.target;
fdc74cf0 2631
3badc888 2632 var j = null;
2633 if(b.value == "1")
2634 {
2635 j = data.parents.concat(data.edges.parents);
2636 b.value = "0";
2637 b.innerHTML = "Ports";
2638 }
2639 else
2640 {
2641 j = data.parents.concat(data.nodes).concat(data.edges.nodes);
2642 b.value = "1";
2643 b.innerHTML = "Objects";
2644 }
fdc74cf0 2645
3badc888 2646 //layout.stop();
2647 cy.remove(cy.elements());
fdc74cf0 2648
3badc888 2649 cy.add(j);
fdc74cf0 2650
3badc888 2651 cy.layout(cylayout);
2652 //layout.run();
2653}
fdc74cf0 2654
3badc888 2655$.ajax({
2656 type: "GET",
2657 url: "{$_SERVER['PHP_SELF']}",
2658 data: { module: 'redirect',
2659 page: 'object',
2660 tab: 'linkmgmt',
2661 object_id: $object_id,
2662 op: 'cytoscapemap',
2663 json: 'json'
2664 },
2665 dataTye: 'json',
2666 error: function(){ alert("Error loading"); },
2667 success: function(jdata) {
2668
2669 data = JSON.parse(jdata);
2670
2671 if(data.debug)
2672 $('#debug').html(data.debug);
2673
2674 //j = data.parents.concat(data.edges.parents);
2675 j = data.parents.concat(data.nodes).concat(data.edges.nodes);
2676
2677 if(j.length == 0)
2678 {
2679 alert("No Links to display. Closing Window");
2680 window.close();
2681 return;
2682 }
fdc74cf0 2683
3badc888 2684 cy2 = cytoscape({
2685 container: document.getElementById('cy2'),
2686 //renderer: { name: 'css' },
2687
2688 boxSelectionEnabled: false,
2689 autounselectify: true,
2690 style: cystyle,
2691 wheelSensitivity: 0.1,
2692 });
2693 cy2.style().selector('node').style('label', function(node) { return node.data('label') + '\\n' + node.data('text'); });
2694
2695 cystyle.push({
2696 selector: '.loopedge',
2697 css: {
2698 'curve-style': 'segments',
2699 }
2700 });
2701
2702 cy = cytoscape({
2703 container: document.getElementById('cy'),
2704
2705 boxSelectionEnabled: false,
2706 autounselectify: true,
2707 style: cystyle,
2708 wheelSensitivity: 0.1,
2709 elements: j,
2710 layout: cylayout,
2711 });
2712
2713 cy.on('mouseover', { hlclass: 'highlighted' }, highlight );
2714 cy.on('click', { hlclass: 'clhighlighted' }, highlight );
2715
2716 $('#switch').click(cytoscapeswitch);
2717
2718 /*
2719 TODO: node ranking
2720 */
2721
2722 if(0)
2723 cy.layout({
2724 name: 'dagre',
2725 /*
2726 nodeSep: 5,
2727 rankDir: 'TB',
2728 */
2729 //edgeSep: 10,
2730 /*
2731 edgeWeight: function(edge) {
2732 if(edge.data('type') == 'front')
2733 return 10;
2734 else
2735 return 1;
2736
2737 },
2738 */
2739 ready: layoutready,
2740 stop: layoutstop
2741 });
2742
2743 if(1)
2744 cy.$(':child').qtip({
2745
2746 content: function() {
2747
2748 return this.id() + '<br>'
2749 + 'Index: ' + this.data('index') + '<br>'
2750 + 'Name: ' + this.data('label') + '<br>'
2751 + 'Text: ' + this.data('text');
2752 },
2753 position: {
2754 my: 'top center',
2755 at: 'bottom center'
2756 },
2757 style: {
2758 classes: 'qtip-bootstrap',
2759 tip: {
2760 width: 16,
2761 height: 8
2762 },
2763 }
2764 }); // qtip
2765 } // success function
2766 });
2767
2768
2769}); // on dom ready
2770
2771function layoutready(evt) {
2772 var _cy = evt.cy;
fdc74cf0 2773
3badc888 2774 // highlight current object
2775 var object = _cy.$('#o$object_id');
2776 if(object.data('has_problems') == 'no')
2777 object.style('background-color','#ffcccc');
fdc74cf0 2778
3badc888 2779 // highlight object with problems
2780 _cy.$('node[type = "object"][has_problems != "no"]').style('background-color','#ff0000');
de3d42dc 2781
3badc888 2782 var e = _cy.$('node[loop = "1"]').style('background-color','#ff6666');
83b49cf7 2783
3badc888 2784// console.log(e[0].data('loop'));
de3d42dc 2785
3badc888 2786// cy.add({group: 'edges', data: {id:'l691_2991', source: 'p691', target: 'p2991', label: 'test'}, classes: 'logical'});
de3d42dc 2787
3badc888 2788}
fdc74cf0 2789
3badc888 2790function layoutstop(evt) {
2791 var _cy = evt.cy;
2792// cy.elements().locked = true;
2793// cy.add({group: 'nodes', data: {id:'l2493', parent:'p2943', label: 'test'}});
fdc74cf0 2794
fdc74cf0 2795
3badc888 2796 var les = _cy.$('[loopedge]');
fdc74cf0 2797
3badc888 2798 if(les)
fdc74cf0 2799 {
3badc888 2800 _cy.batch( function() {
2801 les.each(function(i, ele) {
2802 var le = ele.data('loopedge');
2803 var edge = _cy.add(le);
2804 edge.addClass('loopedge');
2805 //edge.style('line-color', '#ffffff'); // TypeError text-transform undefined
2806 });
2807 });
2808 _cy.$('edge[loop = "1"]').style('line-color','#ff6666');
fdc74cf0 2809 }
3badc888 2810}
2811</script>
2812</head>
2813<body>
2814<div id="cy" style="position: absolute; height: 80%; width: 100%; left: 0; top: 20%;"></div>
2815<div id="cy2" style="position: absolute; height: 20%; width: 100%; left: 0; top: 0%;"></div>
2816<div id="debug"></div>
2817<button type="button" id="switch" style="position: absolute;" value="1">Object</button>
2818</body>
2819</html>
2820HTMLEND
2821); // echo
fdc74cf0 2822 exit;
3badc888 2823}
fdc74cf0 2824
2825/* ------------------------------------- */
2826class linkmgmt_gvmap {
2827
2828 private $object_id = NULL;
2829 private $port_id = NULL;
2830 private $remote_id = NULL;
3badc888 2831 private $hl = NULL;
fdc74cf0 2832
2833 private $gv = NULL;
2834
2835 private $ports = array();
2836
2837 private $allports = false;
2838 private $back = NULL;
2839
adc1e20b 2840 private $alpha = 'ff';
fdc74cf0 2841
2842 private $errorlevel = NULL;
2843
3badc888 2844 public $data = NULL;
2845
2846 private $pids = array();
2847
2848 function addlinkchainsobject($object_id)
2849 {
2850
2851 $object['ports'] = getObjectPortsAndLinks ($object_id);
2852
2853 if(empty($object['ports']))
2854 {
2855
2856 $hl = false;
2857 $alpha = $this->alpha;
2858 if($this->hl == 'o' && $this->object_id == $object_id)
2859 {
2860 $hl = true;
2861 $this->alpha = 'ff';
2862 }
2863
2864 $this->_addCluster($object_id, $hl, empty($object['ports']));
2865
2866 $this->alpha = $alpha;
2867 return;
2868 }
2869
2870 $i = 0;
2871 foreach($object['ports'] as $key => $port)
2872 {
2873
2874 if(isset($this->pids[$port['id']]))
2875 continue;
2876
2877 $i++;
2878 $lc = new lm_linkchain($port['id']);
2879
2880 $this->pids += $lc->pids;
2881
2882 if($this->allports ||($lc->linkcount > 0))
2883 $this->addlinkchain($lc, $i);
2884 }
2885
2886 }
2887
fdc74cf0 2888 function __construct($object_id = NULL, $port_id = NULL, $allports = false, $hl = NULL, $remote_id = NULL) {
2889 $this->allports = $allports;
2890
4eeb9282 2891 $this->object_id = $object_id;
2892 $this->port_id = $port_id;
2893 $this->remote_id = $remote_id;
3badc888 2894 $this->hl = $hl;
fdc74cf0 2895
2896 $hllabel = "";
2897
2898 /* suppress strict standards warnings for Image_GraphViz and PHP 5.4.0
2899 * output would corrupt image data
2900 */
2901 $this->errorlevel = error_reporting();
857ba778 2902 error_reporting($this->errorlevel & ~E_STRICT);
fdc74cf0 2903
2904 $graphattr = array(
3badc888 2905 'rankdir' => 'LR',
fdc74cf0 2906 // 'ranksep' => '0',
2907 'nodesep' => '0',
2908 // 'overlay' => false,
2909 );
2910
2911 unset($_GET['module']);
2912
2913 $_GET['all'] = 1;
2914
2dbca6fb 2915 $graphattr['URL'] = $this->_makeHrefProcess($_GET);
fdc74cf0 2916
2917 unset($_GET['all']);
2918
3badc888 2919 switch($hl)
2920 {
2921 case 'o':
2922 case 'p':
2923 $this->alpha = '30';
2924 break;
2925 }
2926
83b49cf7 2927 //$this->gv = new Image_GraphViz(true, $graphattr, "map".$object_id);
2928 $this->gv = new lm_Image_GraphViz(true, $graphattr, "map".$object_id);
fdc74cf0 2929
3badc888 2930 /* --------------------------- */
fdc74cf0 2931 if($object_id === NULL)
2932 {
4eeb9282 2933 /* all objects ! */
fdc74cf0 2934 unset($_GET['all']);
2935 $_GET['hl'] = 'o';
2936
2937 $this->gv->addAttributes(array(
2938 'label' => 'Showing all objects'.$hllabel,
2939 'labelloc' => 't',
2940 )
2941 );
2942
2943 $objects = listCells('object');
2944
2945 foreach($objects as $obj)
3badc888 2946 //$this->addlinkchainsobject($obj['id']); // longer runtimes !!
2947 $this->_add($this->gv, $obj['id'], NULL); // for all still faster and nicer looking graph
4eeb9282 2948
2949 return;
fdc74cf0 2950 }
2951 else
2952 {
2953 $object = spotEntity ('object', $object_id);
2954
2955 $this->gv->addAttributes(array(
2956 'label' => "Graph for ${object['dname']}$hllabel",
2957 'labelloc' => 't',
2958 )
2959 );
2960
3badc888 2961 $this->addlinkchainsobject($object_id);
2962 //$this->_add($this->gv, $object_id, $port_id);
fdc74cf0 2963
2964 $children = getEntityRelatives ('children', 'object', $object_id); //'entity_id'
2965
2966 foreach($children as $child)
3badc888 2967 $this->addlinkchainsobject($child['entity_id']);
2968 // $this->_add($this->gv, $child['entity_id'], NULL);
fdc74cf0 2969 }
2970
4eeb9282 2971 /* add hl label */
2972 $this->gv->addAttributes(array(
2973 'label' => $this->gv->graph['attributes']['label'].$hllabel,
2974 ));
2975
48d66be9 2976 // lm_linkchain::var_dump_html($this->gv);
2977// lm_linkchain::var_dump_html($this->data);
3badc888 2978
2979// echo json_encode($this->data);
fdc74cf0 2980
83b49cf7 2981 // $this->gv->saveParsedGraph('/tmp/graph.txt');
fdc74cf0 2982 // error_reporting( E_ALL ^ E_NOTICE);
2983 } /* __construct */
2984
2985 function __destruct() {
2986 error_reporting($this->errorlevel);
2987 }
2988
3badc888 2989 function _addCluster($object_id, $hl = false, $adddummy = false)
2990 {
2991 global $lc_cache;
2992
2993 $cluster_id = "c".$object_id;
2994
2995 if(
2996 !isset($this->gv->graph['clusters'][$cluster_id]) &&
2997 !isset($this->gv->graph['subgraphs'][$cluster_id])
2998 || $hl
2999 ) {
3000 $rack = null;
3001 $object = $lc_cache->getobject($object_id, $rack);
3002
3003 // $object['attr'] = getAttrValues($object_id);
3004
3005 $clusterattr = array();
3006
3007 $this->_getcolor('cluster', 'default', $this->alpha, $clusterattr, 'color');
3008 $this->_getcolor('cluster', 'default', $this->alpha, $clusterattr, 'fontcolor');
3009
3010 if($this->object_id == $object_id)
3011 {
3012 $clusterattr['rank'] = 'source';
3013
3014 $this->_getcolor('cluster', 'current', $this->alpha, $clusterattr, 'color');
3015 $this->_getcolor('cluster', 'current', $this->alpha, $clusterattr, 'fontcolor');
3016 }
3017
3018 $clustertitle = htmlspecialchars($object['dname']);
3019 $clusterattr['tooltip'] = $clustertitle;
3020
3021 unset($_GET['module']); // makeHrefProcess adds this
3022 unset($_GET['port_id']);
3023 unset($_GET['remote_id']);
3024 $_GET['object_id'] = $object_id;
3025 //$_GET['hl'] = 'o';
3026
3027 $clusterattr['URL'] = $this->_makeHrefProcess($_GET);
3028
3029 //has_problems
3030 if($object['has_problems'] != 'no')
3031 {
3032 $clusterattr['style'] = 'filled';
3033 $this->_getcolor('cluster', 'problem', $this->alpha, $clusterattr, 'fillcolor');
3034 }
3035
3036 if(!empty($object['container_name']))
3037 $clustertitle .= "<BR/>(${object['container_name']})";
3038
3039 if(!empty($rack['row_name']) || !empty($rack['name']))
3040 $clustertitle .= "<BR/><FONT point-size=\"10\">{$rack['row_name']} / {$rack['name']}</FONT>";
3041
3042 $embedin = $object['container_id'];
3043 if(empty($embedin))
3044 $embedin = 'default';
3045 else
3046 {
3047 $embedin = "c$embedin"; /* see cluster_id */
3048
3049 // TODO
3050 /* add container / cluster if not already exists */
3051 $this->addlinkchainsobject($object['container_id']);
3052 }
3053
3054 $clusterattr['id'] = "$object_id----"; /* used for js context menu */
3055
3056 $this->gv->addCluster($cluster_id, $clustertitle, $clusterattr, $embedin);
3057
3058 /* needed because of gv_image empty cluster bug (invalid foreach argument) */
3059 if($adddummy)
3060 $this->gv->addNode("dummy$cluster_id", array(
3061 // 'label' =>'No Ports found/connected',
3062 'label' =>'',
3063 'fontsize' => 0,
3064 'size' => 0,
3065 'width' => 0,
3066 'height' => 0,
3067 'shape' => 'point',
3068 'style' => 'invis',
3069 ), $cluster_id);
3070
3071
3072 }
3073 } // _addCluster
3074
3075 function _addEdge($port, $linkchain, $loopedge = false)
3076 {
3077 global $lm_multilink_port_types;
3078 if(
3079 !isset($this->gv->graph['edgesFrom'][$port['id']][$port['remote_id']]) &&
3080 !isset($this->gv->graph['edgesFrom'][$port['remote_id']][$port['id']])
3081 || $loopedge
3082 ) {
3083 $remote_id = $port['remote_id'];
3084
3085 $linktype = $port['linktype'];
3086
3087 $edgetooltip = $port['object_name'].':'.$port['name'].
3088 ' - '.$port['cableid'].' -> '.
3089 $port['remote_name'].':'.$port['remote_object_name'];
3090
3091 $edgeattr = array(
3092 'fontsize' => 8,
3093 'label' => htmlspecialchars($port['cableid']),
3094 'tooltip' => $edgetooltip,
3095 'sametail' => $linktype,
3096 'samehead' => $linktype,
3097 'arrowhead' => 'none',
3098 'arrowtail' => 'none',
3099 );
3100
3101 $this->_getcolor('edge', ($linkchain->loop ? 'loop' : 'default'), $this->alpha, $edgeattr, 'color');
3102 $this->_getcolor('edge', 'default', $this->alpha, $edgeattr, 'fontcolor');
3103
3104 if($linktype == 'back' )
3105 {
3106 $edgeattr['style'] = 'dashed';
3107
3108 /* multilink ports */
3109 if(in_array($port['oif_id'], $lm_multilink_port_types))
3110 {
3111 $edgeattr['dir'] = 'both';
3112 $edgeattr['arrowtail'] = 'dot';
3113 }
3114
3115 if(in_array($linkchain->ports[$remote_id]['oif_id'], $lm_multilink_port_types))
3116 {
3117 $edgeattr['dir'] = 'both';
3118 $edgeattr['arrowhead'] = 'dot';
3119 }
3120 }
3121
3122 if(
3123 ($port['id'] == $this->port_id && $port['remote_id'] == $this->remote_id) ||
3124 ($port['id'] == $this->remote_id && $port['remote_id'] == $this->port_id)
3125 )
3126 {
3127 $this->_getcolor('edge', 'highlight', 'ff', $edgeattr, 'color');
3128 $edgeattr['penwidth'] = 2; /* bold */
3129 }
3130
3131 unset($_GET['module']);
3132 $_GET['object_id'] = $port['object_id'];
3133 $_GET['port_id'] = $port['id'];
3134 $_GET['remote_id'] = $port['remote_id'];
3135
3136 $edgeattr['URL'] = $this->_makeHrefProcess($_GET);
3137
3138 $edgeattr['id'] = $port['object_id']."-".$port['id']."-".$port['remote_id']."-".$linktype; /* for js context menu */
3139
3140 if($loopedge)
3141 {
3142 $edgeattr = array_merge($edgeattr, array(
3143 'sametail' => 'loop',
3144 'samehead' => 'loop',
3145 'dir' => 'both',
3146 'arrowhead' => 'invodot',
3147 'arrowtail' => 'invodot',
3148 ));
3149 }
3150
3151 $this->gv->addEdge(array($port['id'] => $port['remote_id']),
3152 $edgeattr,
3153 array(
3154 $port['id'] => $linktype,
3155 $port['remote_id'] => $linktype,
3156 )
3157 );
3158
3159 }
3160 } // _addEdge
3161
3162 function addlinkchain($linkchain, $index)
3163 {
3164 global $lm_multilink_port_types;
3165
3166 $hl = false;
3167 $alpha = $this->alpha;
3168 if(
3169 ($this->hl == 'p' && $linkchain->hasport_id($this->port_id))
3170 || ($this->hl == 'o' && $linkchain->hasobject_id($this->object_id))
3171 )
3172 {
3173 $hl = true;
3174 $this->alpha = 'ff';
3175 }
3176
3177 $remote_id = null;
3178 foreach($linkchain as $id => $port)
3179 {
3180 $this->_addCluster($port['object_id'], $hl);
3181
3182 $nodelabel = htmlspecialchars("${port['name']}");
3183 $text = $nodelabel;
3184
3185 if($port['iif_id'] != '1' )
3186 {
3187 $nodelabel .= "<BR/><FONT POINT-SIZE=\"8\">${port['iif_name']}</FONT>";
3188 $text .= "\n".$port['iif_name'];
3189 }
3190
3191 $nodelabel .= "<BR/><FONT POINT-SIZE=\"8\">${port['oif_name']}</FONT>";
3192 $text .= "\n".$port['oif_name'];
3193
3194 // add ip address
3195 if(isset($port['portip']))
3196 $nodelabel .= "<BR/><FONT POINT-SIZE=\"8\">".$port['portip']."</FONT>";
3197
3198 $nodeattr = array(
3199 'label' => $nodelabel,
3200 );
3201
3202 $this->_getcolor('port', ($linkchain->loop ? 'loop' : 'default'),$this->alpha, $nodeattr, 'fontcolor');
3203 $this->_getcolor('oif_id', $port['oif_id'],$this->alpha, $nodeattr, 'color');
3204
3205 if($this->port_id == $port['id']) {
3206 $nodeattr['style'] = 'filled';
3207 $nodeattr['fillcolor'] = $this->_getcolor('port', 'current', $this->alpha);
3208 }
3209
3210 if($this->remote_id == $port['id']) {
3211 $nodeattr['style'] = 'filled';
3212 $nodeattr['fillcolor'] = $this->_getcolor('port', 'remote', $this->alpha);
3213 }
3214
3215 $nodeattr['tooltip'] = htmlspecialchars("${port['name']}");
3216
3217 unset($_GET['module']);
3218 unset($_GET['remote_id']);
3219 $_GET['object_id'] = $port['object_id'];
3220 $_GET['port_id'] = $port['id'];
3221 $_GET['hl'] = 'p';
3222
3223 $nodeattr['URL'] = $this->_makeHrefProcess($_GET);
3224 $nodeattr['id'] = "${port['object_id']}-${port['id']}--"; /* for js context menu */
3225
3226 $this->gv->addNode($port['id'],
3227 $nodeattr,
3228 "c${port['object_id']}"); /* see cluster_id */
3229
3230 $remote_id = $port['remote_id'];
3231
3232 if($port['portcount'] > 1)
3233 foreach($port['chains'] as $mlc)
3234 {
3235 $this->addlinkchain($mlc, 0); // TODO index
3236 }
3237
3238 $prevlinktype = ($port['linktype'] == 'front' ? 'back' : 'front');
3239 if($port[$prevlinktype]['portcount'] > 1)
3240 {
3241 foreach($port[$prevlinktype]['chains'] as $mlc)
3242 {
3243 $this->addlinkchain($mlc, 0, false); // TODO index
3244 }
3245 }
3246
3247 if($remote_id)
3248 $this->_addEdge($port, $linkchain);
3249
3250 } //foreach
3251
3252 if($linkchain->loop && $remote_id)
3253 {
3254 // TODO separate loop link
3255 // add loop edge
3256 $this->_addEdge($port, $linkchain, true);
3257 }
3258
3259 // reset alpha to start value
3260 $this->alpha = $alpha;
3261 }
3262
de3d42dc 3263 function setFalseOnError($newvalue)
3264 {
3265 $this->gv->_returnFalseOnError = $newvalue;
3266 }
3267
2dbca6fb 3268 function _makeHrefProcess($array)
3269 {
3270 return str_replace('&','&amp;',makeHrefProcess($array));
3271 }
3272
fdc74cf0 3273 // !!!recursiv !!!
3274 function _add($gv, $object_id, $port_id = NULL) {
3275 global $lm_multilink_port_types;
3276
4eeb9282 3277 if($port_id !== NULL) {
3278 if(isset($this->ports[$port_id])) {
fdc74cf0 3279 return;
4eeb9282 3280 }
fdc74cf0 3281 }
3282
2d257b3a 3283 if($this->back != 'front' || $port_id === NULL || $this->allports)
3284 $front = $this->_getObjectPortsAndLinks($object_id, 'front', $port_id, $this->allports);
3285 else
3286 $front = array();
3287
3288 if($this->back != 'back' || $port_id === NULL || $this->allports)
3289 $backend = $this->_getObjectPortsAndLinks($object_id, 'back', $port_id, $this->allports);
3290 else
3291 $backend = array();
3292
3293 $ports = array_merge($front,$backend);
3294
630a86c8 3295 /* used only for Graphviz ...
3296 * !! numeric ids cause Image_Graphviz problems on nested clusters !!
3297 */
3298 $cluster_id = "c$object_id";
3299
2d257b3a 3300 if(empty($ports))
3301 {
3302 /* needed because of gv_image empty cluster bug (invalid foreach argument) */
da6d05d0 3303 $gv->addNode("dummy$cluster_id", array(
2d257b3a 3304 // 'label' =>'No Ports found/connected',
3305 'label' =>'',
3306 'fontsize' => 0,
3307 'size' => 0,
3308 'width' => 0,
3309 'height' => 0,
3310 'shape' => 'point',
3311 'style' => 'invis',
3312 ), $cluster_id);
3313
3314 /* show objects without ports */
3315 if($object_id === NULL)
3316 return;
3317 }
3318
3badc888 3319 $object = NULL;
2d257b3a 3320 if($object_id !== NULL) {
4eeb9282 3321 if(
3322 !isset($gv->graph['clusters'][$cluster_id]) &&
3323 !isset($gv->graph['subgraphs'][$cluster_id])
3324 ) {
fdc74cf0 3325
4eeb9282 3326 $object = spotEntity ('object', $object_id);
3badc888 3327
3badc888 3328 $object['portip'] = array();
09712ceb 3329 foreach(getObjectIPv4Allocations ($object_id) as $ipv4)
3badc888 3330 {
3331 $object['portip'][$ipv4['osif']] = $ipv4['addrinfo']['ip'];
3332 }
3333
4eeb9282 3334 // $object['attr'] = getAttrValues($object_id);
fdc74cf0 3335
4eeb9282 3336 $clusterattr = array();
fdc74cf0 3337
4eeb9282 3338 $this->_getcolor('cluster', 'default', $this->alpha, $clusterattr, 'color');
3339 $this->_getcolor('cluster', 'default', $this->alpha, $clusterattr, 'fontcolor');
fdc74cf0 3340
4eeb9282 3341 if($this->object_id == $object_id)
3342 {
3343 $clusterattr['rank'] = 'source';
fdc74cf0 3344
4eeb9282 3345 $this->_getcolor('cluster', 'current', $this->alpha, $clusterattr, 'color');
3346 $this->_getcolor('cluster', 'current', $this->alpha, $clusterattr, 'fontcolor');
3347 }
fdc74cf0 3348
4eeb9282 3349 $clustertitle = "${object['dname']}";
3badc888 3350 $text = "${object['dname']}";
4eeb9282 3351 $clusterattr['tooltip'] = $clustertitle;
fdc74cf0 3352
4eeb9282 3353 unset($_GET['module']); // makeHrefProcess adds this
3354 unset($_GET['port_id']);
3355 unset($_GET['remote_id']);
3356 $_GET['object_id'] = $object_id;
3357 //$_GET['hl'] = 'o';
fdc74cf0 3358
2dbca6fb 3359 $clusterattr['URL'] = $this->_makeHrefProcess($_GET);
fdc74cf0 3360
4eeb9282 3361 //has_problems
3362 if($object['has_problems'] != 'no')
3363 {
3364 $clusterattr['style'] = 'filled';
3365 $this->_getcolor('cluster', 'problem', $this->alpha, $clusterattr, 'fillcolor');
3366 }
fdc74cf0 3367
4eeb9282 3368 if(!empty($object['container_name']))
3badc888 3369 {
4eeb9282 3370 $clustertitle .= "<BR/>${object['container_name']}";
3badc888 3371 $text .= "\n${object['container_name']}";
3372 }
fdc74cf0 3373
4eeb9282 3374 if($object['rack_id'])
3375 {
3376 $rack = spotEntity('rack', $object['rack_id']);
fdc74cf0 3377
4eeb9282 3378 if(!empty($rack['row_name']) || !empty($rack['name']))
3badc888 3379 {
4eeb9282 3380 $clustertitle .= "<BR/>${rack['row_name']} / ${rack['name']}";
3badc888 3381 $text .= "\n${rack['row_name']} / ${rack['name']}";
3382 }
4eeb9282 3383 }
3384
3385 $embedin = $object['container_id'];
3386 if(empty($embedin))
3387 $embedin = 'default';
3388 else
3389 {
3390 $embedin = "c$embedin"; /* see cluster_id */
3391
3392 /* add container / cluster if not already exists */
3393 $this->_add($gv, $object['container_id'], NULL);
3394 }
fdc74cf0 3395
2d257b3a 3396 $clusterattr['id'] = "$object_id----"; /* used for js context menu */
fdc74cf0 3397
2d257b3a 3398 $gv->addCluster($cluster_id, $clustertitle, $clusterattr, $embedin);
fdc74cf0 3399
2d257b3a 3400 } /* isset cluster_id */
3401 } /* object_id !== NULL */
fca4e38a 3402
fdc74cf0 3403 foreach($ports as $key => $port) {
3404
3405 $this->back = $port['linktype'];
3406
4eeb9282 3407 if(!isset($this->ports[$port['id']])) {
fdc74cf0 3408
fdc74cf0 3409
c613fc73 3410 $nodelabel = htmlspecialchars("${port['name']}");
3badc888 3411 $text = $nodelabel;
fdc74cf0 3412
4eeb9282 3413 if($port['iif_id'] != '1' )
3badc888 3414 {
4eeb9282 3415 $nodelabel .= "<BR/><FONT POINT-SIZE=\"8\">${port['iif_name']}</FONT>";
3badc888 3416 $text .= "\n".$port['iif_name'];
3417 }
fdc74cf0 3418
4eeb9282 3419 $nodelabel .= "<BR/><FONT POINT-SIZE=\"8\">${port['oif_name']}</FONT>";
3badc888 3420 $text .= "\n".$port['oif_name'];
3421
3422 // add ip address
3423 if($object)
3424 if(isset($object['portip'][$port['name']]))
3425 {
3426 $nodelabel .= "<BR/><FONT POINT-SIZE=\"8\">".$object['portip'][$port['name']]."</FONT>";
3427 $text .= "\n".$object['portip'][$port['name']];
3428 }
fdc74cf0 3429
4eeb9282 3430 $nodeattr = array(
3431 'label' => $nodelabel,
3432 );
fdc74cf0 3433
4eeb9282 3434 $this->_getcolor('port', 'default',$this->alpha, $nodeattr, 'fontcolor');
3435 $this->_getcolor('oif_id', $port['oif_id'],$this->alpha, $nodeattr, 'color');
fdc74cf0 3436
4eeb9282 3437 if($this->port_id == $port['id']) {
3438 $nodeattr['style'] = 'filled';
3439 $nodeattr['fillcolor'] = $this->_getcolor('port', 'current', $this->alpha);
3440 }
fdc74cf0 3441
4eeb9282 3442 if($this->remote_id == $port['id']) {
3443 $nodeattr['style'] = 'filled';
3444 $nodeattr['fillcolor'] = $this->_getcolor('port', 'remote', $this->alpha);
3445 }
3446
c613fc73 3447 $nodeattr['tooltip'] = htmlspecialchars("${port['name']}");
4eeb9282 3448
3449 unset($_GET['module']);
3450 unset($_GET['remote_id']);
3451 $_GET['object_id'] = $port['object_id'];
3452 $_GET['port_id'] = $port['id'];
3453 $_GET['hl'] = 'p';
fdc74cf0 3454
2dbca6fb 3455 $nodeattr['URL'] = $this->_makeHrefProcess($_GET);
4eeb9282 3456 $nodeattr['id'] = "${port['object_id']}-${port['id']}--"; /* for js context menu */
fdc74cf0 3457
4eeb9282 3458 $gv->addNode($port['id'],
fdc74cf0 3459 $nodeattr,
3460 "c${port['object_id']}"); /* see cluster_id */
3461
4eeb9282 3462 $this->ports[$port['id']] = true;
2d257b3a 3463
4eeb9282 3464 } /* isset port */
fdc74cf0 3465
3466 if(!empty($port['remote_id'])) {
3467
bb000ce6 3468 if($this->object_id !== NULL)
3469 $this->_add($gv, $port['remote_object_id'], $port['remote_id']);
fdc74cf0 3470
3471 if(
3472 !isset($gv->graph['edgesFrom'][$port['id']][$port['remote_id']]) &&
3473 !isset($gv->graph['edgesFrom'][$port['remote_id']][$port['id']])
3474 ) {
3475
3476 $linktype = $port['linktype'];
3477
3478 $edgetooltip = $port['object_name'].':'.$port['name'].
3479 ' - '.$port['cableid'].' -> '.
3480 $port['remote_name'].':'.$port['remote_object_name'];
3481
3482 $edgeattr = array(
3483 'fontsize' => 8,
c613fc73 3484 'label' => htmlspecialchars($port['cableid']),
fdc74cf0 3485 'tooltip' => $edgetooltip,
3486 'sametail' => $linktype,
3487 'samehead' => $linktype,
3488 );
3489
3490 $this->_getcolor('edge', 'default', $this->alpha, $edgeattr, 'color');
3491 $this->_getcolor('edge', 'default', $this->alpha, $edgeattr, 'fontcolor');
3492
3493 if($linktype == 'back' )
3494 {
3495 $edgeattr['style'] = 'dashed';
3496 $edgeattr['arrowhead'] = 'none';
3497 $edgeattr['arrowtail'] = 'none';
3498
3499 /* multilink ports */
3500 if(in_array($port['oif_id'], $lm_multilink_port_types))
3501 {
3502 $edgeattr['dir'] = 'both';
3503 $edgeattr['arrowtail'] = 'dot';
3504 }
3505
3506 if(in_array($port['remote_oif_id'], $lm_multilink_port_types))
3507 {
3508 $edgeattr['dir'] = 'both';
3509 $edgeattr['arrowhead'] = 'dot';
3510 }
3511 }
3512
3513 if(
3514 ($port['id'] == $this->port_id && $port['remote_id'] == $this->remote_id) ||
3515 ($port['id'] == $this->remote_id && $port['remote_id'] == $this->port_id)
3516 )
3517 {
3518 $this->_getcolor('edge', 'highlight', 'ff', $edgeattr, 'color');
3519 $edgeattr['penwidth'] = 2; /* bold */
3520 }
3521
3522 unset($_GET['module']);
3523 $_GET['object_id'] = $port['object_id'];
3524 $_GET['port_id'] = $port['id'];
3525 $_GET['remote_id'] = $port['remote_id'];
3526
2dbca6fb 3527 $edgeattr['URL'] = $this->_makeHrefProcess($_GET);
fdc74cf0 3528
3529 $edgeattr['id'] = $port['object_id']."-".$port['id']."-".$port['remote_id']."-".$linktype; /* for js context menu */
3530
3531 $gv->addEdge(array($port['id'] => $port['remote_id']),
3532 $edgeattr,
3533 array(
3534 $port['id'] => $linktype,
3535 $port['remote_id'] => $linktype,
3536 )
3537 );
3badc888 3538
fdc74cf0 3539 }
3540 }
3541
3542 }
3543
48d66be9 3544 // lm_linkchain::var_dump_html($port);
fdc74cf0 3545 }
3546
83b49cf7 3547 function fetch($type = 'png', $command = NULL, $format2 = NULL, &$data2 = NULL) {
3548
3549 $tmpdata = $data2;
3550 $ret = $this->gv->fetch($type, $command, $format2, $tmpdata);
3551 if($data2 !== NULL)
3552 $data2 = $tmpdata;
fdc74cf0 3553 return $ret;
3554 }
3555
3556 function image($type = 'png', $command = NULL) {
3557 $this->gv->image($type, $command);
3558 }
3559
3560 function parse() {
3561 return $this->gv->parse();
3562 }
3563
3564 /* should be compatible with getObjectPortsAndLinks from RT database.php */
3565 function _getObjectPortsAndLinks($object_id, $linktype = 'front', $port_id = NULL, $allports = false) {
3566
3567 if($linktype == 'front')
3568 $linktable = 'Link';
3569 else
3570 $linktable = 'LinkBackend';
3571
3572 $qparams = array();
3573
3574 $query = "SELECT
3575 '$linktype' as linktype,
3576 Port.*,
3577 Port.type AS oif_id,
3578 PortInnerInterface.iif_name as iif_name,
262da468 3579 POI.oif_name as oif_name,
fdc74cf0 3580 Object.id as object_id, Object.name as object_name,
2a5cd259 3581 IFNULL(LinkTable_a.cable,LinkTable_b.cable) as cableid,
fdc74cf0 3582 remoteObject.id as remote_object_id, remoteObject.name as remote_object_name,
3583 remotePort.id as remote_id, remotePort.name as remote_name,
3584 remotePort.type AS remote_oif_id,
3585 remotePortInnerInterface.iif_name as remote_iif_name,
262da468 3586 remotePOI.oif_name as remote_oif_name
fdc74cf0 3587 FROM Port";
3588
3589 // JOIN
3590 $join = " LEFT JOIN PortInnerInterface on PortInnerInterface.id = Port.iif_id
262da468 3591 LEFT JOIN PortOuterInterface AS POI on POI.id = Port.type
2be16f85 3592 LEFT JOIN $linktable as LinkTable_a on Port.id = LinkTable_a.porta
2a5cd259 3593 LEFT JOIN $linktable as LinkTable_b on Port.id = LinkTable_b.portb
fdc74cf0 3594 LEFT JOIN Object on Object.id = Port.object_id
2a5cd259 3595 LEFT JOIN Port as remotePort on remotePort.id = IFNULL(LinkTable_a.portb, LinkTable_b.porta)
fdc74cf0 3596 LEFT JOIN Object as remoteObject on remoteObject.id = remotePort.object_id
3597 LEFT JOIN PortInnerInterface as remotePortInnerInterface on remotePortInnerInterface.id = remotePort.iif_id
262da468 3598 LEFT JOIN PortOuterInterface as remotePOI on remotePOI.id = remotePort.type
fdc74cf0 3599 ";
3600
3601 // WHERE
3602 if($port_id === NULL)
3603 {
3604 $where = " WHERE Object.id = ?";
3605 $qparams[] = $object_id;
3606
09749fb9 3607 if(!$allports) {
fdc74cf0 3608 $where .= " AND remotePort.id is not NULL";
09749fb9 3609
3610 if($linktype != 'front') {
2a5cd259 3611 $join .= "
3612 LEFT JOIN Link as FrontLink_a on Port.id = FrontLink_a.porta
3613 LEFT JOIN Link as FrontLink_b on Port.id = FrontLink_b.portb
3614 LEFT JOIN Link as FrontRemoteLink_a on remotePort.id = FrontRemoteLink_a.porta
3615 LEFT JOIN Link as FrontRemoteLink_b on remotePort.id = FrontRemoteLink_b.portb
09749fb9 3616 ";
2a5cd259 3617 $where .= " AND ( (FrontLink_a.porta is not NULL or FrontLink_b.portb is not NULL )
3618 OR (FrontRemoteLink_a.porta is not NULL or FrontRemoteLink_b.portb is not NULL) )";
09749fb9 3619 }
3620 }
fdc74cf0 3621 }
3622 else
3623 {
3624 // $where = " WHERE Port.id = ? and remotePort.id is not NULL";
3625 $where = " WHERE Port.id = ?";
3626 $qparams[] = $port_id;
3627 }
3628
3629 // ORDER
3630 $order = " ORDER by oif_name, Port.Name";
3631
3632 $query .= $join.$where.$order;
3633
2a5cd259 3634 //echo "$port_id: $query<br><br>";
3635
fdc74cf0 3636 $result = usePreparedSelectBlade ($query, $qparams);
3637
3638 $row = $result->fetchAll(PDO::FETCH_ASSOC);
3639
3640 $result->closeCursor();
3641
3642 return $row;
3643 }
3644
3645 function _getcolor($type = 'object', $key = 'default', $alpha = 'ff', &$array = NULL , $arraykey = 'color') {
3646
3647 $object = array(