source: trunk/src/inc/KMLFile.class.php@ 7797

Last change on this file since 7797 was 7788, checked in by Pieter Naber, 15 years ago

Added bandwith maximum en usage to lines. Just random numbers, needs work in a following project.

  • Property svn:eol-style set to native
File size: 16.0 KB
Line 
1<?php
2/*
3 * Project: NodeMap2.0
4 * File: KMLHandler.class.php
5 * Purpose: Creating of editing KML files
6 */
7
8define('NODE_STATUS_UP', 0);
9define('NODE_STATUS_ERROR', 1);
10define('NODE_STATUS_UNREACHABLE', 2);
11
12class KMLFile {
13 private $template = '
14 <kml xmlns="http://www.opengis.net/kml/2.2">
15 <Document>
16 <name>Wireless Leiden Interactive Nodemap 2.0</name>
17 <open>1</open>
18 <description>Wireless Leiden Interactive Nodemap 2.0</description>
19 <LookAt>
20 <longitude>%OVERALL_LONGITUDE%</longitude>
21 <latitude>%OVERALL_LATITUDE%</latitude>
22 <altitude>%OVERALL_ALTITUDE%</altitude>
23 <heading>%OVERALL_HEADING%</heading>
24 <tilt>%OVERALL_TILT%</tilt>
25 <range>%OVERALL_RANGE%</range>
26 </LookAt>
27 <Style id="blackLine">
28 <LineStyle>
29 <color>%LINE_BLACK%</color>
30 <width>3</width>
31 </LineStyle>
32 </Style>
33 <Style id="greenArrowIcon">
34 <IconStyle>
35 <Icon>
36 <href>%NODE_GREEN%</href>
37 </Icon>
38 </IconStyle>
39 </Style>
40 <Style id="orangeArrowIcon">
41 <IconStyle>
42 <Icon>
43 <href>%NODE_ORANGE%</href>
44 </Icon>
45 </IconStyle>
46 </Style>
47 <Style id="redArrowIcon">
48 <IconStyle>
49 <Icon>
50 <href>%NODE_RED%</href>
51 </Icon>
52 </IconStyle>
53 </Style>
54 <Folder id="nodes">
55 <name>Nodes</name>
56 <description>Nodes from the Wireless Leiden network</description>
57 <LookAt>
58 <longitude>%OVERALL_LONGITUDE%</longitude>
59 <latitude>%OVERALL_LATITUDE%</latitude>
60 <altitude>%OVERALL_ALTITUDE%</altitude>
61 <heading>%OVERALL_HEADING%</heading>
62 <tilt>%OVERALL_TILT%</tilt>
63 <range>%OVERALL_RANGE%</range>
64 </LookAt>
65 %NODESCONTENT%
66 </Folder>
67 <Folder id="lines">
68 <name>Lines</name>
69 <description>Lines from nodes to nodes from the Wireless Leiden network</description>
70 <LookAt>
71 <longitude>%OVERALL_LONGITUDE%</longitude>
72 <latitude>%OVERALL_LATITUDE%</latitude>
73 <altitude>%OVERALL_ALTITUDE%</altitude>
74 <heading>%OVERALL_HEADING%</heading>
75 <tilt>%OVERALL_TILT%</tilt>
76 <range>%OVERALL_RANGE%</range>
77 </LookAt>
78 %LINESCONTENT%
79 </Folder>
80 </Document>
81 </kml>';
82
83 // First line of the status file must be like this:
84 static $fileFirst = 'type,host_name,has_been_checked,check_execution_time,current_state,last_hard_state,last_check,problem_has_been_acknowledged';
85 // Every following line will be checked using these functions
86 private $fileContent = array('string', 'string', 'int', 'double', 'int', 'int', 'int', 'int');
87
88 private $KMLNodes;
89 private $KMLLines;
90 private $NetworkList;
91
92 /*
93 * Function: __construct (constructor)
94 * Description: Creating a new KMLFile
95 * Parameters: -
96 * Returns: -
97 */
98 public function __construct() {
99 $this->KMLNodes = array();
100 $this->KMLLines = array();
101 $this->NetworkList = new NetworkList();
102 }
103
104 /*
105 * Function: addNode
106 * Description: Add a node to the local node array
107 * Parameters: KMLNode $node
108 * Returns: -
109 */
110 public function addNode(KMLNode $node) {
111 $this->KMLNodes[] = $node;
112 }
113
114 /*
115 * Function: addLIne
116 * Description: Add a line to the local line array
117 * Parameters: KMLLine $line
118 * Returns: -
119 */
120 public function addLine(KMLLine $line) {
121 $this->KMLLines[] = $line;
122 }
123
124 /*
125 * Function: toString
126 * Description: Converts the content of this file and the placemarks to a KML valid string
127 * Parameters: -
128 * Returns: KML valid string
129 */
130 public function toString() {
131 global $config;
132
133 $toString = $this->template;
134
135 // Add all nodes to the string
136 $nodeString = '';
137 $nodeCount = count($this->KMLNodes);
138 for ($i = 0; $i < $nodeCount; $i++) {
139 $nodeString .= $this->KMLNodes[$i]->toString();
140 }
141
142 // Add all connected lines to the string
143 $lineString = '';
144 $lineCount = count($this->KMLLines);
145 for ($i = 0; $i < $lineCount; $i++) {
146 // If longitude2 and latitude2 aren't set, ignore the lines
147 // This happens with all the connections that don't connect 2 nodes
148 if ($this->KMLLines[$i]->isConnected()) {
149 $lineString .= $this->KMLLines[$i]->toString();
150 }
151 }
152
153 $toString = str_replace('%NODE_GREEN%', $config['node_green'], $toString);
154 $toString = str_replace('%NODE_ORANGE%', $config['node_orange'], $toString);
155 $toString = str_replace('%NODE_RED%', $config['node_red'], $toString);
156 $toString = str_replace('%LINE_BLACK%', $config['line_black'], $toString);
157 $toString = str_replace('%NODESCONTENT%', $nodeString, $toString);
158 $toString = str_replace('%LINESCONTENT%', $lineString, $toString);
159
160 $toString = str_replace('%OVERALL_LONGITUDE%', $config['overall_longitude'], $toString);
161 $toString = str_replace('%OVERALL_LATITUDE%', $config['overall_latitude'], $toString);
162 $toString = str_replace('%OVERALL_ALTITUDE%', $config['overall_altitude'], $toString);
163 $toString = str_replace('%OVERALL_HEADING%', $config['overall_heading'], $toString);
164 $toString = str_replace('%OVERALL_TILT%', $config['overall_tilt'], $toString);
165 $toString = str_replace('%OVERALL_RANGE%', $config['overall_range'], $toString);
166
167 return $toString;
168 }
169
170 /*
171 * Function: getNodeByName
172 * Description: Find the first KMLNode with the name $name and return its position. If not found, return false
173 * Parameters: string $name
174 * Returns: Position of node in our array, if not found false
175 */
176 public function getNodeByName($name) {
177 $nodesCount = count($this->KMLNodes);
178 for ($i = 0; $i < $nodesCount; $i++) {
179 if ($this->KMLNodes[$i]->getName() == $name) {
180 return $i;
181 }
182 }
183
184 return false;
185 }
186
187 /*
188 * Function: parseLocationFile
189 * Description: Parse the node location file updating or adding KMLNode objects to the current KMLFile object
190 * Parameters: string $file
191 * Returns: true is successfull, otherwise false
192 */
193 public function parseLocationFile($file) {
194 // We want to find all the nodes in the location file and store information of the nodes...
195 $nodesCount = preg_match_all('/\[[a-zA-Z0-9]*\]/i', $file, $nodes, PREG_OFFSET_CAPTURE);
196 for ($i = 0; $i < $nodesCount; $i++) {
197 // Looking for "location" of the node
198 if (!$location = $this->findInLocationFile($file, 'location = ', $nodes[0][$i][1])) {
199 trigger_log(SYSLOG_WARNING, 'Could not find the "location" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
200 continue;
201 }
202 // Looking for "status" of the node
203 if (!$status = $this->findInLocationFile($file, 'status = ', $nodes[0][$i][1])) {
204 trigger_log(SYSLOG_WARNING, 'Could not find the "status" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
205 continue;
206 }
207 // Looking for "latitude" of the node
208 if (!$latitude = $this->findInLocationFile($file, 'latitude = ', $nodes[0][$i][1])) {
209 trigger_log(SYSLOG_WARNING, 'Could not find the "latitude" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
210 continue;
211 }
212 // Looking for "longitude" of the node
213 if (!$longitude = $this->findInLocationFile($file, 'longitude = ', $nodes[0][$i][1])) {
214 trigger_log(SYSLOG_WARNING, 'Could not find the "longitude" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
215 continue;
216 }
217 // Looking for "interfaces" of the node
218 if (!$interfaces = $this->findInLocationFile($file, 'interfaces = ', $nodes[0][$i][1])) {
219 trigger_log(SYSLOG_WARNING, 'Could not find the "interfaces" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
220 continue;
221 }
222 // Looking for "masterip" of the node
223 if (!$masterip = $this->findInLocationFile($file, 'masterip = ', $nodes[0][$i][1])) {
224 trigger_log(SYSLOG_WARNING, 'Could not find the "masterip" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
225 continue;
226 }
227 // Looking for "nodetype" of the node
228 if (!$nodetype = $this->findInLocationFile($file, 'nodetype = ', $nodes[0][$i][1])) {
229 trigger_log(SYSLOG_WARNING, 'Could not find the "nodetype" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
230 continue;
231 }
232 // Looking for "name" of the node
233 if (!$name = $this->findInLocationFile($file, 'name = ', $nodes[0][$i][1])) {
234 trigger_log(SYSLOG_WARNING, 'Could not find the "name" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
235 continue;
236 }
237
238 // Creating a string with the complete description of the node using all data in the location file
239 $dataLocation = '
240 <Data name="location">
241 <value>
242 <![CDATA[
243 ' . $location . '
244 ]]>
245 </value>
246 </Data>
247 <Data name="status">
248 <value>' . $status . '</value>
249 </Data>
250 <Data name="interfaces">
251 <value>' . $interfaces . '</value>
252 </Data>
253 <Data name="masterIP">
254 <value>' . $masterip . '</value>
255 </Data>
256 <Data name="nodeType">
257 <value>' . $nodetype . '</value>
258 </Data>';
259
260 if ($placemarkPosition = $this->getNodeByName($name)) {
261 // Updating an excisting placemark
262 $this->KMLNodes[$placemarkPosition]->setDataLocation($dataLocation);
263 $this->KMLNodes[$placemarkPosition]->setLongitude($longitude);
264 $this->KMLNodes[$placemarkPosition]->setLatitude($latitude);
265 } else {
266 // Adding a new placemark
267 $placemark = new KMLNode();
268 $placemark->setID($name);
269 $placemark->setName($name);
270 $placemark->setDataLocation($dataLocation);
271 $placemark->setLongitude($longitude);
272 $placemark->setLatitude($latitude);
273 $this->addNode($placemark);
274 }
275
276 // Now let's find all interlinks with this node
277 $position = $nodes[0][$i][1];
278 while (($position = strpos($file, 'ip=', $position + 1)) && (isset($nodes[0][$i + 1][1]) && $position < $nodes[0][$i + 1][1])) {
279 $ipAddress = $this->findInLocationFile($file, 'ip=', $position);
280 $posSlash = strpos($ipAddress, '/');
281 $ip = substr($ipAddress, 0, $posSlash);
282 $netmask = substr($ipAddress, $posSlash + 1);
283
284 $posNetwork = $this->NetworkList->find($ip);
285 if ($posNetwork) {
286 // Network already excists in list, just need to add longitude2 en latitude2 to KMLLine
287 // and add the node name to the name of the line.
288 // Position in network equals position in KMLLine array :-)
289
290 $this->KMLLines[$posNetwork]->setName($this->KMLLines[$posNetwork]->getName() . $name);
291 $this->KMLLines[$posNetwork]->setLongitude2($longitude);
292 $this->KMLLines[$posNetwork]->setLatitude2($latitude);
293 } else {
294 // Network doesn't excist. We create a new network and a new line.
295
296 $network = new Network($ip, $netmask);
297 $this->NetworkList->add($network);
298
299 // TODO: For this project we'll use random numbers.
300 // In a following project this can be adjusted
301 $bandwithMax = rand(0, 200);
302 $bandwithUsage = rand(0, $bandwithMax);
303
304 $data = '
305 <Data name="netmaskDecimal">
306 <value>' . $network->netmaskDecimal . '</value>
307 </Data>
308 <Data name="netmaskBinary">
309 <value>' . $network->netmaskBinary . '</value>
310 </Data>
311 <Data name="wildcardDecimal">
312 <value>' . $network->wildcardDecimal . '</value>
313 </Data>
314 <Data name="wildcardBinary">
315 <value>' . $network->wildcardBinary . '</value>
316 </Data>
317 <Data name="networkDecimal">
318 <value>' . $network->networkDecimal . '</value>
319 </Data>
320 <Data name="networkBinary">
321 <value>' . $network->networkBinary . '</value>
322 </Data>
323 <Data name="broadcastDecimal">
324 <value>' . $network->broadcastDecimal . '</value>
325 </Data>
326 <Data name="broadcastBinary">
327 <value>' . $network->broadcastBinary . '</value>
328 </Data>
329 <Data name="hostMinDecimal">
330 <value>' . $network->hostminDecimal . '</value>
331 </Data>
332 <Data name="hostMinBinary">
333 <value>' . $network->hostminBinary . '</value>
334 </Data>
335 <Data name="hostMaxDecimal">
336 <value>' . $network->hostmaxDecimal . '</value>
337 </Data>
338 <Data name="hostMaxBinary">
339 <value>' . $network->hostmaxBinary . '</value>
340 </Data>
341 <Data name="hosts">
342 <value>' . $network->numberHosts . '</value>
343 </Data>
344 <Data name="bandwidthMax">
345 <value>' . $bandwithMax . '</value>
346 </Data>
347 <Data name="bandwidthUsage">
348 <value>' . $bandwithUsage . '</value>
349 </Data>';
350
351 $line = new KMLLine();
352 $line->setID(str_replace('.', '', $network->networkDecimal));
353 $line->setName('Link: Van ' . $name . ' naar ');
354 $line->setData($data);
355 $line->setLongitude1($longitude);
356 $line->setLatitude1($latitude);
357 $this->KMLLines[] = $line;
358 }
359 }
360 }
361 }
362
363 /*
364 * Function: findInLocationFile
365 * Description: Find the $keyword in $file and return the value of $keyword, starting at $offset
366 * Parameters: string $file, string $keyword, integer $offset
367 * Returns: The value of the keyword if found, otherwise return false
368 */
369 private function findInLocationFile($file, $keyword, $offset) {
370 $start = strpos($file, $keyword, $offset) + strlen($keyword);
371 $end = strpos($file, "\n", $start);
372
373 if ($start && $end && ($start < $end)) {
374 return substr($file, $start, $end - $start);
375 } else {
376 return false;
377 }
378 }
379
380 /*
381 * Function: parseStatusFile
382 * Description: Parse the node status file updating or adding KMLNode objects to the current KMLFile object
383 * Parameters: string $file
384 * Returns: true is successfull, otherwise false
385 */
386 public function parseStatusFile($file) {
387 $fileContents = explode("\r\n", $file);
388
389 if ($fileContents[0] != KMLFile::$fileFirst) {
390 trigger_log(SYSLOG_WARNING, 'Contents of file do not match with template of first line', __FILE__, __LINE__);
391 }
392
393 // For loop for all the lines in the file. Skipping first line (headers) and last line (blank)
394 $linesCount = count($fileContents);
395 for ($i = 1; $i < $linesCount - 1; $i++) {
396 $lineContent = explode(',', $fileContents[$i]);
397
398 // Names in the status file are in the format "CNode%NAME%".
399 // We need to remove the CNode so it matches the location file.
400 $lineContent[1] = str_replace('CNode', '', $lineContent[1]);
401
402 if (count($lineContent) != count($this->fileContent)) {
403 trigger_log(LOG_WARNING, 'Contents of the file do not match with template of lines on line "' . $i . '"', __FILE__, __LINE__);
404 continue;
405 }
406
407 // Checking for valid entries on this line
408 for ($j = 0; $j < 8; $j++) {
409 try {
410 switch ($this->fileContent[$j]) {
411 case 'string':
412 $lineContent[$j] = (string) $lineContent[$j];
413 break;
414 case 'int':
415 $lineContent[$j] = (int) $lineContent[$j];
416 break;
417 case 'double':
418 $lineContent[$j] = (double) $lineContent[$j];
419 break;
420 default:
421 break;
422 }
423 } catch (Exception $err) {
424 trigger_log(SYSLOG_WARNING, 'The value "' . $j . '" on line "' . $i . '" is not valid, skipping to next line', __FILE__, __LINE__);
425 continue;
426 }
427 }
428
429 // Creating a string with the complete description of the node using all data in the status file
430 $dataStatus = '
431 <Data name="type">
432 <value>' . $lineContent[0] . '</value>
433 </Data>
434 <Data name="hostName">
435 <value>' . $lineContent[1] . '</value>
436 </Data>
437 <Data name="hasBeenChecked">
438 <value>' . $lineContent[2] . '</value>
439 </Data>
440 <Data name="checkExecutionTime">
441 <value>' . $lineContent[3] . '</value>
442 </Data>
443 <Data name="currentState">
444 <value>' . $lineContent[4] . '</value>
445 </Data>
446 <Data name="lastHardState">
447 <value>' . $lineContent[5] . '</value>
448 </Data>
449 <Data name="lastCheck">
450 <value>' . $lineContent[6] . '</value>
451 </Data>
452 <Data name="problemHasBeenAcknowledged">
453 <value>' . $lineContent[7] . '</value>
454 </Data>';
455
456 $style = NODE_RED;
457 if ($lineContent[4] == NODE_STATUS_ERROR) {
458 $style = NODE_ORANGE;
459 } elseif ($lineContent[4] == NODE_STATUS_UP) {
460 $style = NODE_GREEN;
461 }
462
463 if ($placemarkPosition = $this->getNodeByName($lineContent[1])) {
464 // Updating an excisting placemark
465 $this->KMLNodes[$placemarkPosition]->setDataStatus($dataStatus);
466 $this->KMLNodes[$placemarkPosition]->setStyle($style);
467 } else {
468 // Adding a new placemark
469 $placemark = new KMLNode();
470 $placemark->setID($lineContent[1]);
471 $placemark->setName($lineContent[1]);
472 $placemark->setDataStatus($dataStatus);
473 $placemark->setStyle($style);
474 $this->addNode($placemark);
475 }
476 }
477 }
478}
479?>
Note: See TracBrowser for help on using the repository browser.