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