/**
  * @param string $targetString The string from the config file
  * @param the $map A reference to the map object (redundant)
  * @param the $mapItem A reference to the object this target is attached to
  * @return array invalue, outvalue, unix timestamp that the data was valid
  */
 function ReadData($targetString, &$map, &$mapItem)
 {
     $data[IN] = null;
     $data[OUT] = null;
     $data_time = 0;
     $matches = 0;
     if (preg_match("/^time:(.*)\$/", $targetString, $matches)) {
         $timezone = $matches[1];
         $offset = "now";
         if (preg_match("/^([^:]+):(.*)\$/", $timezone, $matches2)) {
             $timezone = $matches2[1];
             $offset = $matches2[2];
             // test that the offset is valid
             $timestamp = strtotime($offset);
             if ($timestamp === false || $timestamp === -1) {
                 warn("Time ReadData: Offset String ({$offset}) is bogus - ignoring [WMTIME03]\n");
                 $offset = "now";
             }
         }
         $timezone_l = strtolower($timezone);
         if (array_key_exists($timezone_l, $this->timezones)) {
             $tz = $this->timezones[$timezone_l];
             wm_debug("Time ReadData: Timezone exists: {$tz}\n");
             $dateTime = new DateTime($offset, new DateTimeZone($tz));
             $mapItem->add_note("time_time12", $dateTime->format("h:i"));
             $mapItem->add_note("time_time12ap", $dateTime->format("h:i A"));
             $mapItem->add_note("time_time24", $dateTime->format("H:i"));
             $mapItem->add_note("time_timet", $dateTime->format("U"));
             $mapItem->add_note("time_timezone", $tz);
             $data[IN] = $dateTime->format("H");
             $data[OUT] = $dateTime->format("i");
             $data_time = time();
             $matches++;
         }
         if ($matches == 0) {
             wm_warn("Time ReadData: Couldn't recognize {$timezone} as a valid timezone name [WMTIME02]\n");
         }
     } else {
         // some error code to go in here
         wm_warn("Time ReadData: Couldn't recognize {$targetString} \n");
     }
     wm_debug("Time ReadData: Returning (" . WMUtility::valueOrNull($data[IN]) . "," . WMUtility::valueOrNull($data[OUT]) . ",{$data_time})\n");
     return array($data[IN], $data[OUT], $data_time);
 }
 function ReadData($targetString, &$map, &$mapItem)
 {
     $data[IN] = null;
     $data[OUT] = null;
     $data_time = 0;
     if (preg_match("/^dbplug:([^:]+)\$/", $targetString, $matches)) {
         $database_user = $map->get_hint('dbplug_dbuser');
         $database_pass = $map->get_hint('dbplug_dbpass');
         $database_name = $map->get_hint('dbplug_dbname');
         $database_host = $map->get_hint('dbplug_dbhost');
         $key = mysql_real_escape_string($matches[1]);
         // This is the one line you will certainly need to change
         $SQL = "select in,out from table where host={$key} LIMIT 1";
         if (mysql_connect($database_host, $database_user, $database_pass)) {
             if (mysql_select_db($database_name)) {
                 $result = mysql_query($SQL);
                 if (!$result) {
                     wm_warn("dbplug ReadData: Invalid query: " . mysql_error() . "\n");
                 } else {
                     $row = mysql_fetch_assoc($result);
                     $data[IN] = $row['in'];
                     $data[OUT] = $row['out'];
                 }
             } else {
                 wm_warn("dbplug ReadData: failed to select database: " . mysql_error() . "\n");
             }
         } else {
             wm_warn("dbplug ReadData: failed to connect to database server: " . mysql_error() . "\n");
         }
         $data_time = now();
     }
     wm_debug("RRD ReadData dbplug: Returning (" . ($data[IN] === null ? 'null' : $data[IN]) . "," . ($data[OUT] === null ? 'null' : $data[IN]) . ", {$data_time})\n");
     return array($data[IN], $data[OUT], $data_time);
 }
 function ReadData($targetString, &$map, &$mapItem)
 {
     $data[IN] = null;
     $data[OUT] = null;
     $data_time = 0;
     $matches = 0;
     if (preg_match($this->regexpsHandled[0], $targetString, $matches)) {
         $dataFileName = $matches[1];
         $dataItemName = $matches[2];
     }
     if (!file_exists($dataFileName)) {
         wm_warn("WMData ReadData: {$dataFileName} doesn't exist [WMWMDATA01]");
         return array(null, null, 0);
     }
     $fileHandle = fopen($targetString, "r");
     if (!$fileHandle) {
         wm_warn("WMData ReadData: Couldn't open ({$dataFileName}). [WMWMDATA02]\n");
         return array(null, null, 0);
     }
     list($found, $data) = $this->findDataItem($fileHandle, $dataItemName, $data);
     if ($found === true) {
         $stats = stat($dataFileName);
         $data_time = $stats['mtime'];
     } else {
         wm_warn("WMData ReadData: Data name '{$dataItemName}' didn't exist in '{$dataFileName}'. [WMWMDATA03]\n");
     }
     wm_debug(sprintf("WMData ReadData: Returning (%s, %s, %s)\n", string_or_null($data[IN]), string_or_null($data[OUT]), $data_time));
     return array($data[IN], $data[OUT], $data_time);
 }
 function ReadData($targetstring, &$map, &$item)
 {
     $data[IN] = NULL;
     $data[OUT] = NULL;
     $data_time = 0;
     $itemname = $item->name;
     $matches = 0;
     if (preg_match("/^time:(.*)\$/", $targetstring, $matches)) {
         $timezone = $matches[1];
         $timezone_l = strtolower($timezone);
         $timezone_identifiers = DateTimeZone::listIdentifiers();
         foreach ($timezone_identifiers as $tz) {
             if (strtolower($tz) == $timezone_l) {
                 wm_debug("Time ReadData: Timezone exists: {$tz}\n");
                 $dateTime = new DateTime("now", new DateTimeZone($tz));
                 $item->add_note("time_time12", $dateTime->format("h:i"));
                 $item->add_note("time_time12ap", $dateTime->format("h:i A"));
                 $item->add_note("time_time24", $dateTime->format("H:i"));
                 $item->add_note("time_timezone", $tz);
                 $data[IN] = $dateTime->format("H");
                 $data_time = time();
                 $data[OUT] = $dateTime->format("i");
                 $matches++;
             }
         }
         if ($matches == 0) {
             wm_warn("Time ReadData: Couldn't recognize {$timezone} as a valid timezone name [WMTIME02]\n");
         }
     } else {
         // some error code to go in here
         wm_warn("Time ReadData: Couldn't recognize {$targetstring} \n");
     }
     wm_debug("Time ReadData: Returning (" . ($data[IN] === NULL ? 'NULL' : $data[IN]) . "," . ($data[OUT] === NULL ? 'NULL' : $data[OUT]) . ",{$data_time})\n");
     return array($data[IN], $data[OUT], $data_time);
 }
 /**
  * @param $timezone
  * @param $offset
  * @return array
  * @internal param $mapItem
  * @internal param $data
  * @internal param $matches
  * @internal param $timezone_l
  */
 private function getTimeForTimeZone($timezone, $offset)
 {
     $timezone_l = strtolower($timezone);
     if (array_key_exists($timezone_l, $this->timezones)) {
         $timezone_name = $this->timezones[$timezone_l];
         wm_debug("Time ReadData: Timezone exists: {$timezone_name}\n");
         $dateTime = new DateTime($offset, new DateTimeZone($timezone_name));
         return array($dateTime, $timezone_name);
     }
     wm_warn("Time ReadData: Couldn't recognize {$timezone} as a valid timezone name [WMTIME02]\n");
     return null;
 }
 /**
  * @param $fullpath
  * @return resource
  */
 protected function validateAndOpenFile($fullpath)
 {
     wm_debug("Opening {$fullpath}\n");
     if (!file_exists($fullpath)) {
         wm_warn("File '{$fullpath}' doesn't exist.");
         return null;
     }
     if (!is_readable($fullpath)) {
         wm_warn("File '{$fullpath}' isn't readable.");
         return null;
     }
     $fileHandle = fopen($fullpath, "r");
     return $fileHandle;
 }
 function ReadData($targetstring, &$map, &$item)
 {
     $data[IN] = null;
     $data[OUT] = null;
     $data_time = 0;
     $itemname = $item->name;
     $matches = 0;
     if (preg_match("/^wmdata:([^:]*):(.*)", $targetstring, $matches)) {
         $datafile = $matches[1];
         $dataname = $matches[2];
     }
     if (file_exists($datafile)) {
         $fd = fopen($targetstring, "r");
         if ($fd) {
             $found = false;
             while (!feof($fd)) {
                 $buffer = fgets($fd, 4096);
                 # strip out any Windows line-endings that have gotten in here
                 $buffer = str_replace("\r", "", $buffer);
                 $fields = explode("\t", $buffer);
                 if ($fields[0] == $dataname) {
                     $data[IN] = $fields[1];
                     $data[OUT] = $fields[2];
                     $found = true;
                 }
             }
             if ($found === true) {
                 $stats = stat($datafile);
                 $data_time = $stats['mtime'];
             } else {
                 wm_warn("WMData ReadData: Data name ({$dataname}) didn't exist in ({$datafile}). [WMWMDATA03]\n");
             }
         } else {
             wm_warn("WMData ReadData: Couldn't open ({$datafile}). [WMWMDATA02]\n");
         }
     } else {
         wm_warn("WMData ReadData: {$datafile} doesn't exist [WMWMDATA01]");
     }
     wm_debug(sprintf("WMData ReadData: Returning (%s, %s, %s)\n", string_or_null($data[IN]), string_or_null($data[OUT]), $data_time));
     return array($data[IN], $data[OUT], $data_time);
 }
function wm_module_checks()
{
    if (!extension_loaded('gd')) {
        wm_warn("\n\nNo image (gd) extension is loaded. This is required by weathermap. [WMWARN20]\n\n");
        wm_warn("\nrun check.php to check PHP requirements.\n\n");
        return false;
    }
    if (!function_exists('imagecreatefrompng')) {
        wm_warn("Your GD php module doesn't support PNG format. [WMWARN21]\n");
        wm_warn("\nrun check.php to check PHP requirements.\n\n");
        return false;
    }
    if (!function_exists('imagecreatetruecolor')) {
        wm_warn("Your GD php module doesn't support truecolor. [WMWARN22]\n");
        wm_warn("\nrun check.php to check PHP requirements.\n\n");
        return false;
    }
    if (!function_exists('imagecopyresampled')) {
        wm_warn("Your GD php module doesn't support thumbnail creation (imagecopyresampled). [WMWARN23]\n");
    }
    return true;
}
 public function ReadData($targetString, &$map, &$mapItem)
 {
     $data[IN] = null;
     $data[OUT] = null;
     $data_time = 0;
     $timeout = intval($this->owner->get_hint("snmp_timeout", 1000000));
     $abort_count = intval($this->owner->get_hint("snmp_abort_count"), 0);
     $retries = intval($this->owner->get_hint("snmp_retries"), 2);
     if (preg_match($this->regexpsHandled[0], $targetString, $matches)) {
         $community = $matches[1];
         $host = $matches[2];
         $oids = array();
         $oids[IN] = $matches[3];
         $oids[OUT] = $matches[4];
         if ($abort_count == 0 || $abort_count > 0 && (!isset($this->down_cache[$host]) || intval($this->down_cache[$host]) < $abort_count)) {
             $this->changeSNMPSettings();
             $channels = array("in" => IN, "out" => OUT);
             foreach ($channels as $channelName => $channel) {
                 if ($oids[$channel] != '-') {
                     $result = snmpget($host, $community, $oids[$channel], $timeout, $retries);
                     if ($result !== false) {
                         $data[$channel] = floatval($result);
                         $mapItem->add_hint("snmp_" . $channelName . "_raw", $result);
                     } else {
                         $this->down_cache[$host]++;
                     }
                 }
                 wm_debug("SNMP ReadData: Got {$result} for {$channelName}\n");
             }
             $data_time = time();
             $this->restoreSNMPSettings();
         } else {
             wm_warn("SNMP for {$host} has reached {$abort_count} failures. Skipping. [WMSNMP01]");
         }
     }
     wm_debug("SNMP ReadData: Returning (" . ($data[IN] === null ? 'null' : $data[IN]) . "," . ($data[OUT] === null ? 'null' : $data[OUT]) . ",{$data_time})\n");
     return array($data[IN], $data[OUT], $data_time);
 }
function imagecreatefromfile($filename)
{
    $bgimage = null;
    if (is_readable($filename)) {
        list(, , $type, ) = getimagesize($filename);
        switch ($type) {
            case IMAGETYPE_GIF:
                if (imagetypes() & IMG_GIF) {
                    $bgimage = imagecreatefromgif($filename);
                } else {
                    wm_warn("Image file {$filename} is GIF, but GIF is not supported by your GD library. [WMIMG01]\n");
                }
                break;
            case IMAGETYPE_JPEG:
                if (imagetypes() & IMG_JPEG) {
                    $bgimage = imagecreatefromjpeg($filename);
                } else {
                    wm_warn("Image file {$filename} is JPEG, but JPEG is not supported by your GD library. [WMIMG02]\n");
                }
                break;
            case IMAGETYPE_PNG:
                if (imagetypes() & IMG_PNG) {
                    $bgimage = imagecreatefrompng($filename);
                } else {
                    wm_warn("Image file {$filename} is PNG, but PNG is not supported by your GD library. [WMIMG03]\n");
                }
                break;
            default:
                wm_warn("Image file {$filename} wasn't recognised (type={$type}). Check format is supported by your GD library. [WMIMG04]\n");
                break;
        }
    } else {
        wm_warn("Image file {$filename} is unreadable. Check permissions. [WMIMG05]\n");
    }
    return $bgimage;
}
 function pre_render($im, &$map)
 {
     // don't bother drawing if there's no position - it's a template
     if (is_null($this->x)) {
         return;
     }
     if (is_null($this->y)) {
         return;
     }
     // apparently, some versions of the gd extension will crash
     // if we continue...
     if ($this->label == '' && $this->iconfile == '') {
         return;
     }
     // start these off with sensible values, so that bbox
     // calculations are easier.
     $icon_x1 = $this->x;
     $icon_x2 = $this->x;
     $icon_y1 = $this->y;
     $icon_y2 = $this->y;
     $label_x1 = $this->x;
     $label_x2 = $this->x;
     $label_y1 = $this->y;
     $label_y2 = $this->y;
     $boxwidth = 0;
     $boxheight = 0;
     $icon_w = 0;
     $icon_h = 0;
     $col = new Colour(-1, -1, -1);
     # print $col->as_string();
     // if a target is specified, and you haven't forced no background, then the background will
     // come from the SCALE in USESCALE
     if (!empty($this->targets) && $this->usescale != 'none') {
         $pc = 0;
         if ($this->scalevar == 'in') {
             $pc = $this->inpercent;
             $col = $this->colours[IN];
         }
         if ($this->scalevar == 'out') {
             $pc = $this->outpercent;
             $col = $this->colours[OUT];
         }
     } elseif ($this->labelbgcolour != array(-1, -1, -1)) {
         // $col=myimagecolorallocate($node_im, $this->labelbgcolour[0], $this->labelbgcolour[1], $this->labelbgcolour[2]);
         $col = new Colour($this->labelbgcolour);
     }
     $colicon = null;
     if (!empty($this->targets) && $this->useiconscale != 'none') {
         wm_debug("Colorising the icon\n");
         $pc = 0;
         $val = 0;
         if ($this->iconscalevar == 'in') {
             $pc = $this->inpercent;
             $col = $this->colours[IN];
             $val = $this->bandwidth_in;
         }
         if ($this->iconscalevar == 'out') {
             $pc = $this->outpercent;
             $col = $this->colours[OUT];
             $val = $this->bandwidth_out;
         }
         if ($this->iconscaletype == 'percent') {
             list($colicon, $node_iconscalekey, $icontag) = $map->NewColourFromPercent($pc, $this->useiconscale, $this->name);
         } else {
             // use the absolute value if we aren't doing percentage scales.
             list($colicon, $node_iconscalekey, $icontag) = $map->NewColourFromPercent($val, $this->useiconscale, $this->name, FALSE);
         }
     }
     // figure out a bounding rectangle for the label
     if ($this->label != '') {
         $padding = 4.0;
         $padfactor = 1.0;
         $this->proclabel = $map->ProcessString($this->label, $this, TRUE, TRUE);
         // if screenshot_mode is enabled, wipe any letters to X and wipe any IP address to 127.0.0.1
         // hopefully that will preserve enough information to show cool stuff without leaking info
         if ($map->get_hint('screenshot_mode') == 1) {
             $this->proclabel = screenshotify($this->proclabel);
         }
         list($strwidth, $strheight) = $map->myimagestringsize($this->labelfont, $this->proclabel);
         if ($this->labelangle == 90 || $this->labelangle == 270) {
             $boxwidth = $strheight * $padfactor + $padding;
             $boxheight = $strwidth * $padfactor + $padding;
             wm_debug("Node->pre_render: " . $this->name . " Label Metrics are: {$strwidth} x {$strheight} -> {$boxwidth} x {$boxheight}\n");
             $label_x1 = $this->x - $boxwidth / 2;
             $label_y1 = $this->y - $boxheight / 2;
             $label_x2 = $this->x + $boxwidth / 2;
             $label_y2 = $this->y + $boxheight / 2;
             if ($this->labelangle == 90) {
                 $txt_x = $this->x + $strheight / 2;
                 $txt_y = $this->y + $strwidth / 2;
             }
             if ($this->labelangle == 270) {
                 $txt_x = $this->x - $strheight / 2;
                 $txt_y = $this->y - $strwidth / 2;
             }
         }
         if ($this->labelangle == 0 || $this->labelangle == 180) {
             $boxwidth = $strwidth * $padfactor + $padding;
             $boxheight = $strheight * $padfactor + $padding;
             wm_debug("Node->pre_render: " . $this->name . " Label Metrics are: {$strwidth} x {$strheight} -> {$boxwidth} x {$boxheight}\n");
             $label_x1 = $this->x - $boxwidth / 2;
             $label_y1 = $this->y - $boxheight / 2;
             $label_x2 = $this->x + $boxwidth / 2;
             $label_y2 = $this->y + $boxheight / 2;
             $txt_x = $this->x - $strwidth / 2;
             $txt_y = $this->y + $strheight / 2;
             if ($this->labelangle == 180) {
                 $txt_x = $this->x + $strwidth / 2;
                 $txt_y = $this->y - $strheight / 2;
             }
             # $this->width = $boxwidth;
             # $this->height = $boxheight;
         }
         $map->nodes[$this->name]->width = $boxwidth;
         $map->nodes[$this->name]->height = $boxheight;
         # print "TEXT at $txt_x , $txt_y\n";
     }
     // figure out a bounding rectangle for the icon
     if ($this->iconfile != '') {
         $icon_im = NULL;
         $icon_w = 0;
         $icon_h = 0;
         if ($this->iconfile == 'rbox' || $this->iconfile == 'box' || $this->iconfile == 'round' || $this->iconfile == 'inpie' || $this->iconfile == 'outpie' || $this->iconfile == 'gauge' || $this->iconfile == 'nink') {
             wm_debug("Artificial Icon type " . $this->iconfile . " for {$this->name}\n");
             // this is an artificial icon - we don't load a file for it
             $icon_im = imagecreatetruecolor($this->iconscalew, $this->iconscaleh);
             imageSaveAlpha($icon_im, TRUE);
             $nothing = imagecolorallocatealpha($icon_im, 128, 0, 0, 127);
             imagefill($icon_im, 0, 0, $nothing);
             $fill = NULL;
             $ink = NULL;
             $aifill = new Colour($this->aiconfillcolour);
             $aiink = new Colour($this->aiconoutlinecolour);
             if ($aifill->is_copy() && !$col->is_none()) {
                 $fill = $col;
             } else {
                 if ($aifill->is_real()) {
                     $fill = $aifill;
                 }
             }
             if ($this->aiconoutlinecolour != array(-1, -1, -1)) {
                 $ink = $aiink;
             }
             if ($this->iconfile == 'box') {
                 if ($fill !== NULL && !$fill->is_none()) {
                     imagefilledrectangle($icon_im, 0, 0, $this->iconscalew - 1, $this->iconscaleh - 1, $fill->gdallocate($icon_im));
                 }
                 if ($ink !== NULL && !$ink->is_none()) {
                     imagerectangle($icon_im, 0, 0, $this->iconscalew - 1, $this->iconscaleh - 1, $ink->gdallocate($icon_im));
                 }
             }
             if ($this->iconfile == 'rbox') {
                 if ($fill !== NULL && !$fill->is_none()) {
                     imagefilledroundedrectangle($icon_im, 0, 0, $this->iconscalew - 1, $this->iconscaleh - 1, 4, $fill->gdallocate($icon_im));
                 }
                 if ($ink !== NULL && !$ink->is_none()) {
                     imageroundedrectangle($icon_im, 0, 0, $this->iconscalew - 1, $this->iconscaleh - 1, 4, $ink->gdallocate($icon_im));
                 }
             }
             if ($this->iconfile == 'round') {
                 $rx = $this->iconscalew / 2 - 1;
                 $ry = $this->iconscaleh / 2 - 1;
                 if ($fill !== NULL && !$fill->is_none()) {
                     imagefilledellipse($icon_im, $rx, $ry, $rx * 2, $ry * 2, $fill->gdallocate($icon_im));
                 }
                 if ($ink !== NULL && !$ink->is_none()) {
                     imageellipse($icon_im, $rx, $ry, $rx * 2, $ry * 2, $ink->gdallocate($icon_im));
                 }
             }
             if ($this->iconfile == 'nink') {
                 // print "NINK **************************************************************\n";
                 $rx = $this->iconscalew / 2 - 1;
                 $ry = $this->iconscaleh / 2 - 1;
                 $size = $this->iconscalew;
                 $quarter = $size / 4;
                 $col1 = $this->colours[OUT];
                 $col2 = $this->colours[IN];
                 assert('!is_null($col1)');
                 assert('!is_null($col2)');
                 imagefilledarc($icon_im, $rx - 1, $ry, $size, $size, 270, 90, $col1->gdallocate($icon_im), IMG_ARC_PIE);
                 imagefilledarc($icon_im, $rx + 1, $ry, $size, $size, 90, 270, $col2->gdallocate($icon_im), IMG_ARC_PIE);
                 imagefilledarc($icon_im, $rx - 1, $ry + $quarter, $quarter * 2, $quarter * 2, 0, 360, $col1->gdallocate($icon_im), IMG_ARC_PIE);
                 imagefilledarc($icon_im, $rx + 1, $ry - $quarter, $quarter * 2, $quarter * 2, 0, 360, $col2->gdallocate($icon_im), IMG_ARC_PIE);
                 if ($ink !== NULL && !$ink->is_none()) {
                     // XXX - need a font definition from somewhere for NINK text
                     $font = 1;
                     $instr = $map->ProcessString("{node:this:bandwidth_in:%.1k}", $this);
                     $outstr = $map->ProcessString("{node:this:bandwidth_out:%.1k}", $this);
                     list($twid, $thgt) = $map->myimagestringsize($font, $instr);
                     $map->myimagestring($icon_im, $font, $rx - $twid / 2, $ry - $quarter + $thgt / 2, $instr, $ink->gdallocate($icon_im));
                     list($twid, $thgt) = $map->myimagestringsize($font, $outstr);
                     $map->myimagestring($icon_im, $font, $rx - $twid / 2, $ry + $quarter + $thgt / 2, $outstr, $ink->gdallocate($icon_im));
                     imageellipse($icon_im, $rx, $ry, $rx * 2, $ry * 2, $ink->gdallocate($icon_im));
                     // imagearc($icon_im, $rx,$ry,$quarter*4,$quarter*4, 0,360, $ink->gdallocate($icon_im));
                 }
                 // print "NINK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
             }
             // XXX - needs proper colours
             if ($this->iconfile == 'inpie' || $this->iconfile == 'outpie') {
                 # list($colpie,$node_iconscalekey,$icontag) = $map->NewColourFromPercent($pc, $this->useiconscale,$this->name);
                 if ($this->iconfile == 'inpie') {
                     $segment_angle = $this->inpercent / 100 * 360;
                 }
                 if ($this->iconfile == 'outpie') {
                     $segment_angle = $this->outpercent / 100 * 360;
                 }
                 $rx = $this->iconscalew / 2 - 1;
                 $ry = $this->iconscaleh / 2 - 1;
                 if ($fill !== NULL && !$fill->is_none()) {
                     imagefilledellipse($icon_im, $rx, $ry, $rx * 2, $ry * 2, $fill->gdallocate($icon_im));
                 }
                 if ($ink !== NULL && !$ink->is_none()) {
                     // imagefilledarc  ( resource $image  , int $cx  , int $cy  , int $width  , int $height  , int $start  , int $end  , int $color  , int $style  )
                     imagefilledarc($icon_im, $rx, $ry, $rx * 2, $ry * 2, 0, $segment_angle, $ink->gdallocate($icon_im), IMG_ARC_PIE);
                 }
                 if ($fill !== NULL && !$fill->is_none()) {
                     imageellipse($icon_im, $rx, $ry, $rx * 2, $ry * 2, $fill->gdallocate($icon_im));
                 }
                 // warn('inpie AICON not implemented yet [WMWARN99]');
             }
             // if($this->iconfile=='outpie') { warn('outpie AICON not implemented yet [WMWARN99]'); }
             if ($this->iconfile == 'gauge') {
                 wm_warn('gauge AICON not implemented yet [WMWARN99]');
             }
         } else {
             $this->iconfile = $map->ProcessString($this->iconfile, $this);
             if (is_readable($this->iconfile)) {
                 imagealphablending($im, true);
                 // draw the supplied icon, instead of the labelled box
                 $icon_im = imagecreatefromfile($this->iconfile);
                 # $icon_im = imagecreatefrompng($this->iconfile);
                 if (function_exists("imagefilter") && isset($colicon) && $this->get_hint("use_imagefilter") == 1) {
                     imagefilter($icon_im, IMG_FILTER_COLORIZE, $colicon->r, $colicon->g, $colicon->b);
                 } else {
                     if (isset($colicon)) {
                         // debug("Skipping unavailable imagefilter() call.\n");
                         imagecolorize($icon_im, $colicon->r, $colicon->g, $colicon->b);
                     }
                 }
                 wm_debug("If this is the last thing in your logs, you probably have a buggy GD library. Get > 2.0.33 or use PHP builtin.\n");
                 if ($icon_im) {
                     $icon_w = imagesx($icon_im);
                     $icon_h = imagesy($icon_im);
                     if ($this->iconscalew * $this->iconscaleh > 0) {
                         imagealphablending($icon_im, true);
                         wm_debug("SCALING ICON here\n");
                         if ($icon_w > $icon_h) {
                             $scalefactor = $icon_w / $this->iconscalew;
                         } else {
                             $scalefactor = $icon_h / $this->iconscaleh;
                         }
                         $new_width = $icon_w / $scalefactor;
                         $new_height = $icon_h / $scalefactor;
                         $scaled = imagecreatetruecolor($new_width, $new_height);
                         imagealphablending($scaled, false);
                         imagecopyresampled($scaled, $icon_im, 0, 0, 0, 0, $new_width, $new_height, $icon_w, $icon_h);
                         imagedestroy($icon_im);
                         $icon_im = $scaled;
                     }
                 } else {
                     wm_warn("Couldn't open ICON: '" . $this->iconfile . "' - is it a PNG, JPEG or GIF? [WMWARN37]\n");
                 }
             } else {
                 if ($this->iconfile != 'none') {
                     wm_warn("ICON '" . $this->iconfile . "' does not exist, or is not readable. Check path and permissions. [WMARN38]\n");
                 }
             }
         }
         if ($icon_im) {
             $icon_w = imagesx($icon_im);
             $icon_h = imagesy($icon_im);
             $icon_x1 = $this->x - $icon_w / 2;
             $icon_y1 = $this->y - $icon_h / 2;
             $icon_x2 = $this->x + $icon_w / 2;
             $icon_y2 = $this->y + $icon_h / 2;
             $map->nodes[$this->name]->width = imagesx($icon_im);
             $map->nodes[$this->name]->height = imagesy($icon_im);
             // $map->imap->addArea("Rectangle", "NODE:" . $this->name . ':0', '', array($icon_x1, $icon_y1, $icon_x2, $icon_y2));
             $map->nodes[$this->name]->boundingboxes[] = array($icon_x1, $icon_y1, $icon_x2, $icon_y2);
         }
     }
     // do any offset calculations
     $dx = 0;
     $dy = 0;
     if ($this->labeloffset != '' && $this->iconfile != '') {
         $this->labeloffsetx = 0;
         $this->labeloffsety = 0;
         list($dx, $dy) = calc_offset($this->labeloffset, $icon_w + $boxwidth - 1, $icon_h + $boxheight);
         #$this->labeloffsetx = $dx;
         #$this->labeloffsety = $dy;
     }
     $label_x1 += $this->labeloffsetx + $dx;
     $label_x2 += $this->labeloffsetx + $dx;
     $label_y1 += $this->labeloffsety + $dy;
     $label_y2 += $this->labeloffsety + $dy;
     if ($this->label != '') {
         // $map->imap->addArea("Rectangle", "NODE:" . $this->name .':1', '', array($label_x1, $label_y1, $label_x2, $label_y2));
         $map->nodes[$this->name]->boundingboxes[] = array($label_x1, $label_y1, $label_x2, $label_y2);
     }
     // work out the bounding box of the whole thing
     $bbox_x1 = min($label_x1, $icon_x1);
     $bbox_x2 = max($label_x2, $icon_x2) + 1;
     $bbox_y1 = min($label_y1, $icon_y1);
     $bbox_y2 = max($label_y2, $icon_y2) + 1;
     #           imagerectangle($im,$bbox_x1,$bbox_y1,$bbox_x2,$bbox_y2,$map->selected);
     #         imagerectangle($im,$label_x1,$label_y1,$label_x2,$label_y2,$map->black);
     #       imagerectangle($im,$icon_x1,$icon_y1,$icon_x2,$icon_y2,$map->black);
     // create TWO imagemap entries - one for the label and one for the icon
     // (so we can have close-spaced icons better)
     $temp_width = $bbox_x2 - $bbox_x1;
     $temp_height = $bbox_y2 - $bbox_y1;
     // create an image of that size and draw into it
     $node_im = imagecreatetruecolor($temp_width, $temp_height);
     // ImageAlphaBlending($node_im, FALSE);
     imageSaveAlpha($node_im, TRUE);
     $nothing = imagecolorallocatealpha($node_im, 128, 0, 0, 127);
     imagefill($node_im, 0, 0, $nothing);
     #$col = $col->gdallocate($node_im);
     // imagefilledrectangle($node_im,0,0,$temp_width,$temp_height,  $nothing);
     $label_x1 -= $bbox_x1;
     $label_x2 -= $bbox_x1;
     $label_y1 -= $bbox_y1;
     $label_y2 -= $bbox_y1;
     $icon_x1 -= $bbox_x1;
     $icon_x2 -= $bbox_x1;
     $icon_y1 -= $bbox_y1;
     $icon_y2 -= $bbox_y1;
     // Draw the icon, if any
     if (isset($icon_im)) {
         imagecopy($node_im, $icon_im, $icon_x1, $icon_y1, 0, 0, imagesx($icon_im), imagesy($icon_im));
         imagedestroy($icon_im);
     }
     // Draw the label, if any
     if ($this->label != '') {
         $txt_x -= $bbox_x1;
         $txt_x += $this->labeloffsetx + $dx;
         $txt_y -= $bbox_y1;
         $txt_y += $this->labeloffsety + $dy;
         #       print "FINAL TEXT at $txt_x , $txt_y\n";
         // if there's an icon, then you can choose to have no background
         if (!$col->is_none()) {
             imagefilledrectangle($node_im, $label_x1, $label_y1, $label_x2, $label_y2, $col->gdallocate($node_im));
         }
         if ($this->selected) {
             imagerectangle($node_im, $label_x1, $label_y1, $label_x2, $label_y2, $map->selected);
             // would be nice if it was thicker, too...
             wimagerectangle($node_im, $label_x1 + 1, $label_y1 + 1, $label_x2 - 1, $label_y2 - 1, $map->selected);
         } else {
             $olcol = new Colour($this->labeloutlinecolour);
             if ($olcol->is_real()) {
                 imagerectangle($node_im, $label_x1, $label_y1, $label_x2, $label_y2, $olcol->gdallocate($node_im));
             }
         }
         #}
         $shcol = new Colour($this->labelfontshadowcolour);
         if ($shcol->is_real()) {
             $map->myimagestring($node_im, $this->labelfont, $txt_x + 1, $txt_y + 1, $this->proclabel, $shcol->gdallocate($node_im), $this->labelangle);
         }
         $txcol = new Colour($this->labelfontcolour[0], $this->labelfontcolour[1], $this->labelfontcolour[2]);
         #$col=myimagecolorallocate($node_im, $this->labelfontcolour[0], $this->labelfontcolour[1],
         #	$this->labelfontcolour[2]);
         if ($txcol->is_contrast()) {
             if ($col->is_real()) {
                 $txcol = $col->contrast();
             } else {
                 wm_warn("You can't make a contrast with 'none'. [WMWARN43]\n");
                 $txcol = new Colour(0, 0, 0);
             }
         }
         $map->myimagestring($node_im, $this->labelfont, $txt_x, $txt_y, $this->proclabel, $txcol->gdallocate($node_im), $this->labelangle);
         //$map->myimagestring($node_im, $this->labelfont, $txt_x, $txt_y, $this->proclabel, $txcol->gdallocate($node_im),90);
     }
     # imagerectangle($node_im,$label_x1,$label_y1,$label_x2,$label_y2,$map->black);
     # imagerectangle($node_im,$icon_x1,$icon_y1,$icon_x2,$icon_y2,$map->black);
     $map->nodes[$this->name]->centre_x = $this->x - $bbox_x1;
     $map->nodes[$this->name]->centre_y = $this->y - $bbox_y1;
     if (1 == 0) {
         imageellipse($node_im, $this->centre_x, $this->centre_y, 8, 8, $map->selected);
         foreach (array("N", "S", "E", "W", "NE", "NW", "SE", "SW") as $corner) {
             list($dx, $dy) = calc_offset($corner, $this->width, $this->height);
             imageellipse($node_im, $this->centre_x + $dx, $this->centre_y + $dy, 5, 5, $map->selected);
         }
     }
     # $this->image = $node_im;
     $map->nodes[$this->name]->image = $node_im;
 }
Esempio n. 12
0
function DrawMap($filename = '', $thumbnailfile = '', $thumbnailmax = 250, $withnodes = TRUE, $use_via_overlay = FALSE, $use_rel_overlay=FALSE)
{
	wm_debug("Trace: DrawMap()\n");
	metadump("# start",true);
	$bgimage=NULL;
	if($this->configfile != "")
	{
		$this->cachefile_version = crc32(file_get_contents($this->configfile));
	}
	else
	{
		$this->cachefile_version = crc32("........");
	}

	wm_debug("Running Post-Processing Plugins...\n");
	foreach ($this->postprocessclasses as $post_class)
	{
		wm_debug("Running $post_class"."->run()\n");
		//call_user_func_array(array($post_class, 'run'), array(&$this));
		$this->plugins['post'][$post_class]->run($this);

	}
	wm_debug("Finished Post-Processing Plugins...\n");

	wm_debug("=====================================\n");
	wm_debug("Start of Map Drawing\n");

	$this->datestamp = strftime($this->stamptext, time());

	// do the basic prep work
	if ($this->background != '')
	{
		if (is_readable($this->background))
		{
			$bgimage=imagecreatefromfile($this->background);

			if (!$bgimage) { wm_warn
				("Failed to open background image.  One possible reason: Is your BACKGROUND really a PNG?\n");
			}
			else
			{
				$this->width=imagesx($bgimage);
				$this->height=imagesy($bgimage);
			}
		}
		else { wm_warn
			("Your background image file could not be read. Check the filename, and permissions, for "
			. $this->background . "\n"); }
	}

	$image=wimagecreatetruecolor($this->width, $this->height);

	# $image = imagecreate($this->width, $this->height);
	if (!$image) { wm_warn
		("Couldn't create output image in memory (" . $this->width . "x" . $this->height . ")."); }
	else
	{
		ImageAlphaBlending($image, true);
		# imageantialias($image,true);

		// by here, we should have a valid image handle

		// save this away, now
		$this->image=$image;

		$this->white=myimagecolorallocate($image, 255, 255, 255);
		$this->black=myimagecolorallocate($image, 0, 0, 0);
		$this->grey=myimagecolorallocate($image, 192, 192, 192);
		$this->selected=myimagecolorallocate($image, 255, 0, 0); // for selections in the editor

		$this->AllocateScaleColours($image);

		// fill with background colour anyway, in case the background image failed to load
		wimagefilledrectangle($image, 0, 0, $this->width, $this->height, $this->colours['DEFAULT']['BG']['gdref1']);

		if ($bgimage)
		{
			imagecopy($image, $bgimage, 0, 0, 0, 0, $this->width, $this->height);
			imagedestroy ($bgimage);
		}

		// Now it's time to draw a map

		// do the node rendering stuff first, regardless of where they are actually drawn.
		// this is so we can get the size of the nodes, which links will need if they use offsets
		foreach ($this->nodes as $node)
		{
			// don't try and draw template nodes
			wm_debug("Pre-rendering ".$node->name." to get bounding boxes.\n");
			if(!is_null($node->x)) $this->nodes[$node->name]->pre_render($image, $this);
		}
		
		$all_layers = array_keys($this->seen_zlayers);
		sort($all_layers);

		foreach ($all_layers as $z)
		{
			$z_items = $this->seen_zlayers[$z];
			wm_debug("Drawing layer $z\n");
			// all the map 'furniture' is fixed at z=1000
			if($z==1000)
			{
				foreach ($this->colours as $scalename=>$colours)
				{
					wm_debug("Drawing KEY for $scalename if necessary.\n");

					if( (isset($this->numscales[$scalename])) && (isset($this->keyx[$scalename])) && ($this->keyx[$scalename] >= 0) && ($this->keyy[$scalename] >= 0) )
					{
						if($this->keystyle[$scalename]=='classic') $this->DrawLegend_Classic($image,$scalename,FALSE);
						if($this->keystyle[$scalename]=='horizontal') $this->DrawLegend_Horizontal($image,$scalename,$this->keysize[$scalename]);
						if($this->keystyle[$scalename]=='vertical') $this->DrawLegend_Vertical($image,$scalename,$this->keysize[$scalename]);
						if($this->keystyle[$scalename]=='inverted') $this->DrawLegend_Vertical($image,$scalename,$this->keysize[$scalename],true);
						if($this->keystyle[$scalename]=='tags') $this->DrawLegend_Classic($image,$scalename,TRUE);
					}
				}

				$this->DrawTimestamp($image, $this->timefont, $this->colours['DEFAULT']['TIME']['gdref1']);
				if(! is_null($this->min_data_time))
				{
					$this->DrawTimestamp($image, $this->timefont, $this->colours['DEFAULT']['TIME']['gdref1'],"MIN");
					$this->DrawTimestamp($image, $this->timefont, $this->colours['DEFAULT']['TIME']['gdref1'],"MAX");
				}
				$this->DrawTitle($image, $this->titlefont, $this->colours['DEFAULT']['TITLE']['gdref1']);
			}
			
			if(is_array($z_items))
			{
				foreach($z_items as $it)
				{
					if(strtolower(get_class($it))=='weathermaplink')
					{
						// only draw LINKs if they have NODES defined (not templates)
						// (also, check if the link still exists - if this is in the editor, it may have been deleted by now)
						if ( isset($this->links[$it->name]) && isset($it->a) && isset($it->b))
						{
							wm_debug("Drawing LINK ".$it->name."\n");
							$this->links[$it->name]->Draw($image, $this);
						}
					}
					if(strtolower(get_class($it))=='weathermapnode')
					{
						// if(!is_null($it->x)) $it->pre_render($image, $this);
						if($withnodes)
						{
							// don't try and draw template nodes
							if( isset($this->nodes[$it->name]) && !is_null($it->x))
							{
								# print "::".get_class($it)."\n";
								wm_debug("Drawing NODE ".$it->name."\n");
								$this->nodes[$it->name]->NewDraw($image, $this);
								$ii=0;
								foreach($this->nodes[$it->name]->boundingboxes as $bbox)
								{
									# $areaname = "NODE:" . $it->name . ':'.$ii;
									$areaname = "NODE:N". $it->id . ":" . $ii;
									$this->imap->addArea("Rectangle", $areaname, '', $bbox);
									wm_debug("Adding imagemap area");
									$ii++;
								}
								wm_debug("Added $ii bounding boxes too\n");
							}
						}						
					}
				}
			}
		}

		$overlay = myimagecolorallocate($image, 200, 0, 0);
		
		// for the editor, we can optionally overlay some other stuff
        if($this->context == 'editor')
        {
		if($use_rel_overlay)
		{
		#		$overlay = myimagecolorallocate($image, 200, 0, 0);
		
			// first, we can show relatively positioned NODEs
			foreach ($this->nodes as $node) {
					if($node->relative_to != '')
					{
							$rel_x = $this->nodes[$node->relative_to]->x;
							$rel_y = $this->nodes[$node->relative_to]->y;
							imagearc($image,$node->x, $node->y,
									15,15,0,360,$overlay);
							imagearc($image,$node->x, $node->y,
									16,16,0,360,$overlay);
		
							imageline($image,$node->x, $node->y,
									$rel_x, $rel_y, $overlay);
					}
			}
		}
		
		if($use_via_overlay)
		{
			// then overlay VIAs, so they can be seen
			foreach($this->links as $link)
			{
				foreach ($link->vialist as $via)
				{
					if(isset($via[2]))
					{
						$x = $this->nodes[$via[2]]->x + $via[0];
						$y = $this->nodes[$via[2]]->y + $via[1];
					}
					else
					{	
						$x = $via[0];
						$y = $via[1];
					}
					imagearc($image, $x,$y, 10,10,0,360,$overlay);
					imagearc($image, $x,$y, 12,12,0,360,$overlay);
				}
			}
		}
        }

		#$this->myimagestring($image, 3, 200, 100, "Test 1\nLine 2", $overlay,0);
		
#	$this->myimagestring($image, 30, 100, 100, "Test 1\nLine 2", $overlay,0);
		#$this->myimagestring($image, 30, 200, 200, "Test 1\nLine 2", $overlay,45);

		// Ready to output the results...

		if($filename == 'null')
		{
			// do nothing at all - we just wanted the HTML AREAs for the editor or HTML output
		}
		else
		{
			if ($filename == '') { imagepng ($image); }
			else {
				$result = FALSE;
				$functions = TRUE;
				if(function_exists('imagejpeg') && preg_match("/\.jpg/i",$filename))
				{
					wm_debug("Writing JPEG file to $filename\n");
					$result = imagejpeg($image, $filename);
				}
				elseif(function_exists('imagegif') && preg_match("/\.gif/i",$filename))
				{
					wm_debug("Writing GIF file to $filename\n");
					$result = imagegif($image, $filename);
				}
				elseif(function_exists('imagepng') && preg_match("/\.png/i",$filename))
				{
					wm_debug("Writing PNG file to $filename\n");
					$result = imagepng($image, $filename);
				}
				else
				{
					wm_warn("Failed to write map image. No function existed for the image format you requested. [WMWARN12]\n");
					$functions = FALSE;
				}

				if(($result==FALSE) && ($functions==TRUE))
				{
					if(file_exists($filename))
					{
						wm_warn("Failed to overwrite existing image file $filename - permissions of existing file are wrong? [WMWARN13]");
					}
					else
					{
						wm_warn("Failed to create image file $filename - permissions of output directory are wrong? [WMWARN14]");
					}
				}
			}
		}

		if($this->context == 'editor2')
		{
			$cachefile = $this->cachefolder.DIRECTORY_SEPARATOR.dechex(crc32($this->configfile))."_bg.".$this->cachefile_version.".png";
			imagepng($image, $cachefile);
			$cacheuri = $this->cachefolder.'/'.dechex(crc32($this->configfile))."_bg.".$this->cachefile_version.".png";
			$this->mapcache = $cacheuri;
		}

		if (function_exists('imagecopyresampled'))
		{
			// if one is specified, and we can, write a thumbnail too
			if ($thumbnailfile != '')
			{
				$result = FALSE;
				if ($this->width > $this->height) { $factor=($thumbnailmax / $this->width); }
				else { $factor=($thumbnailmax / $this->height); }

				$this->thumb_width = $this->width * $factor;
				$this->thumb_height = $this->height * $factor;

				$imagethumb=imagecreatetruecolor($this->thumb_width, $this->thumb_height);
				imagecopyresampled($imagethumb, $image, 0, 0, 0, 0, $this->thumb_width, $this->thumb_height,
					$this->width, $this->height);
				$result = imagepng($imagethumb, $thumbnailfile);
				imagedestroy($imagethumb);
				
				

				if(($result==FALSE))
				{
					if(file_exists($filename))
					{
						wm_warn("Failed to overwrite existing image file $filename - permissions of existing file are wrong? [WMWARN15]");
					}
					else
					{
						wm_warn("Failed to create image file $filename - permissions of output directory are wrong? [WMWARN16]");
					}
				}
			}
		}
		else
		{
			wm_warn("Skipping thumbnail creation, since we don't have the necessary function. [WMWARN17]");
		}
		imagedestroy ($image);
	}
}
Esempio n. 13
0
function weathermap_run_maps($mydir) {
	global $config;
	global $weathermap_debugging, $WEATHERMAP_VERSION;
	global $weathermap_map;
	global $weathermap_warncount;
	global $weathermap_poller_start_time;

	include_once($mydir.DIRECTORY_SEPARATOR."lib".DIRECTORY_SEPARATOR."HTML_ImageMap.class.php");
	include_once($mydir.DIRECTORY_SEPARATOR."lib".DIRECTORY_SEPARATOR."Weathermap.class.php");

	$total_warnings = 0;
	$warning_notes = "";

	$start_time = time();
	if($weathermap_poller_start_time==0) $weathermap_poller_start_time = $start_time;

	$outdir = $mydir.DIRECTORY_SEPARATOR.'output';
	$confdir = $mydir.DIRECTORY_SEPARATOR.'configs';

	$mapcount = 0;

	// take our debugging cue from the poller - turn on Poller debugging to get weathermap debugging
	if (read_config_option("log_verbosity") >= POLLER_VERBOSITY_DEBUG)
	{
		$weathermap_debugging = TRUE;
		$mode_message = "DEBUG mode is on";
	}
	else
	{
		$mode_message = "Normal logging mode. Turn on DEBUG in Cacti for more information";
	}
	$quietlogging = read_config_option("weathermap_quiet_logging");  
	// moved this outside the module_checks, so there should always be something in the logs!
	if($quietlogging==0) cacti_log("Weathermap $WEATHERMAP_VERSION starting - $mode_message\n",true,"WEATHERMAP");

	if(wm_module_checks())
	{
		weathermap_memory_check("MEM Initial");
		// move to the weathermap folder so all those relatives paths don't *have* to be absolute
		$orig_cwd = getcwd();
		chdir($mydir);

		db_execute("replace into settings values('weathermap_last_start_time','".mysql_real_escape_string(time())."')");

		// first, see if the output directory even exists
		if(is_dir($outdir))
		{
			// next, make sure that we stand a chance of writing files
			//// $testfile = realpath($outdir."weathermap.permissions.test");
			$testfile = $outdir.DIRECTORY_SEPARATOR."weathermap.permissions.test";
			$testfd = fopen($testfile, 'w');
			if($testfd)
			{ 
				fclose($testfd); 
				unlink($testfile);

				$queryrows = db_fetch_assoc("select m.*, g.name as groupname from weathermap_maps m,weathermap_groups g where m.group_id=g.id and active='on' order by sortorder,id");

				if( is_array($queryrows) )
				{
					wm_debug("Iterating all maps.");

					$imageformat = strtolower(read_config_option("weathermap_output_format"));
					$rrdtool_path =  read_config_option("path_rrdtool");

					foreach ($queryrows as $map) {
						// reset the warning counter
						$weathermap_warncount=0;
						// this is what will prefix log entries for this map
						$weathermap_map = "[Map ".$map['id']."] ".$map['configfile'];
	
						wm_debug("FIRST TOUCH\n");
						
						if(weathermap_check_cron($weathermap_poller_start_time,$map['schedule']))
						{
							$mapfile = $confdir.DIRECTORY_SEPARATOR.$map['configfile'];
							$htmlfile = $outdir.DIRECTORY_SEPARATOR.$map['filehash'].".html";
							$imagefile = $outdir.DIRECTORY_SEPARATOR.$map['filehash'].".".$imageformat;
							$thumbimagefile = $outdir.DIRECTORY_SEPARATOR.$map['filehash'].".thumb.".$imageformat;

							if(file_exists($mapfile))
							{
								if($quietlogging==0) wm_warn("Map: $mapfile -> $htmlfile & $imagefile\n",TRUE);
								db_execute("replace into settings values('weathermap_last_started_file','".mysql_real_escape_string($weathermap_map)."')");
								$map_start = time();
								weathermap_memory_check("MEM starting $mapcount");
								$wmap = new Weathermap;
								$wmap->context = "cacti";

								// we can grab the rrdtool path from Cacti's config, in this case
								$wmap->rrdtool  = $rrdtool_path;

								$wmap->ReadConfig($mapfile);							

								$wmap->add_hint("mapgroup",$map['groupname']);
								$wmap->add_hint("mapgroupextra",($map['group_id'] ==1 ? "" : $map['groupname'] ));
							
								# in the order of precedence - global extras, group extras, and finally map extras
								$queries = array();
								$queries[] = "select * from weathermap_settings where mapid=0 and groupid=0";
								$queries[] = "select * from weathermap_settings where mapid=0 and groupid=".intval($map['group_id']);
								$queries[] = "select * from weathermap_settings where mapid=".intval($map['id']);

								foreach ($queries as $sql)
								{
									$settingrows = db_fetch_assoc($sql);
									if( is_array($settingrows) && count($settingrows) > 0 ) 
									{ 

									foreach ($settingrows as $setting)
									{
										if($setting['mapid']==0 && $setting['groupid']==0)
										{
											wm_debug("Setting additional (all maps) option: ".$setting['optname']." to '".$setting['optvalue']."'\n");
											$wmap->add_hint($setting['optname'],$setting['optvalue']);
										}
										elseif($setting['groupid']!=0)
										{
											wm_debug("Setting additional (all maps in group) option: ".$setting['optname']." to '".$setting['optvalue']."'\n");
											$wmap->add_hint($setting['optname'],$setting['optvalue']);
										}
										else
										{	wm_debug("Setting additional map-global option: ".$setting['optname']." to '".$setting['optvalue']."'\n");
											$wmap->add_hint($setting['optname'],$setting['optvalue']);
										}
									}
									}
								}																
								
								weathermap_memory_check("MEM postread $mapcount");
								$wmap->ReadData();
								weathermap_memory_check("MEM postdata $mapcount");

								// why did I change this before? It's useful...
								// $wmap->imageuri = $config['url_path'].'/plugins/weathermap/output/weathermap_'.$map['id'].".".$imageformat;
								$wmap->imageuri = 'weathermap-cacti-plugin.php?action=viewimage&id='.$map['filehash']."&time=".time();
	
								if($quietlogging==0) wm_warn("About to write image file. If this is the last message in your log, increase memory_limit in php.ini [WMPOLL01]\n",TRUE);
								weathermap_memory_check("MEM pre-render $mapcount");
								
								$wmap->DrawMap($imagefile,$thumbimagefile,read_config_option("weathermap_thumbsize"));
								
								if($quietlogging==0) wm_warn("Wrote map to $imagefile and $thumbimagefile\n",TRUE);
								$fd = @fopen($htmlfile, 'w');
								if($fd != FALSE)
								{
									fwrite($fd, $wmap->MakeHTML('weathermap_'.$map['filehash'].'_imap'));
									fclose($fd);
									wm_debug("Wrote HTML to $htmlfile");
								}
								else
								{
									if(file_exists($htmlfile))
									{
										wm_warn("Failed to overwrite $htmlfile - permissions of existing file are wrong? [WMPOLL02]\n");
									}
									else
									{
										wm_warn("Failed to create $htmlfile - permissions of output directory are wrong? [WMPOLL03]\n");
									}
								}

								$processed_title = $wmap->ProcessString($wmap->title,$wmap);
								
								db_execute("update weathermap_maps set titlecache='".mysql_real_escape_string($processed_title)."' where id=".intval($map['id']));
								if(intval($wmap->thumb_width) > 0)
								{
									db_execute("update weathermap_maps set thumb_width=".intval($wmap->thumb_width).", thumb_height=".intval($wmap->thumb_height)." where id=".intval($map['id']));
								}
								
								$wmap->CleanUp();
								unset($wmap);
								
								$map_duration = time() - $map_start;
								wm_debug("TIME: $mapfile took $map_duration seconds.\n");
								weathermap_memory_check("MEM after $mapcount");
								$mapcount++;
								db_execute("replace into settings values('weathermap_last_finished_file','".mysql_real_escape_string($weathermap_map)."')");
							}
							else
							{
								wm_warn("Mapfile $mapfile is not readable or doesn't exist [WMPOLL04]\n");
							}
							db_execute("update weathermap_maps set warncount=".intval($weathermap_warncount)." where id=".intval($map['id']));
							$total_warnings += $weathermap_warncount;
							$weathermap_warncount = 0;
							$weathermap_map="";
						}
						else
						{
							wm_debug("Skipping ".$map['id']." (".$map['configfile'].") due to schedule.\n");
						}
					}
					wm_debug("Iterated all $mapcount maps.\n");
				}
				else
				{
					if($quietlogging==0) wm_warn("No activated maps found. [WMPOLL05]\n");
				}
			}
			else
			{
				wm_warn("Output directory ($outdir) isn't writable (tried to create '$testfile'). No maps created. You probably need to make it writable by the poller process (like you did with the RRA directory) [WMPOLL06]\n");
				$total_warnings++;
				$warning_notes .= " (Permissions problem prevents any maps running WMPOLL06)";
			}
		}
		else
		{
			wm_warn("Output directory ($outdir) doesn't exist!. No maps created. You probably need to create that directory, and make it writable by the poller process (like you did with the RRA directory) [WMPOLL07]\n");
			$total_warnings++;
			$warning_notes .= " (Output directory problem prevents any maps running WMPOLL07)";
		}
		weathermap_memory_check("MEM Final");
		chdir($orig_cwd);
		$duration = time() - $start_time;
		
		$stats_string = date(DATE_RFC822) . ": $mapcount maps were run in $duration seconds with $total_warnings warnings." . $warning_notes;
		if($quietlogging==0) wm_warn("STATS: Weathermap $WEATHERMAP_VERSION run complete - $stats_string\n", TRUE);
		db_execute("replace into settings values('weathermap_last_stats','".mysql_real_escape_string($stats_string)."')");
		db_execute("replace into settings values('weathermap_last_finish_time','".mysql_real_escape_string(time())."')");
	}
	else
	{
		wm_warn("Required modules for PHP Weathermap $WEATHERMAP_VERSION were not present. Not running. [WMPOLL08]\n");
	}
}
 public function readData(&$map, &$mapItem)
 {
     wm_debug("ReadData for {$mapItem} ({$this->pluginName} {$this->pluginRunnable})\n");
     if (!$this->pluginRunnable) {
         wm_debug("Plugin %s isn't runnable\n", $this->pluginName);
         return;
     }
     if ($this->scaleFactor != 1) {
         wm_debug("Will multiply result by %f\n", $this->scaleFactor);
     }
     list($in, $out, $dataTime) = $this->pluginObject->ReadData($this->finalTargetString, $map, $mapItem);
     if ($in === null && $out === null) {
         wm_warn(sprintf("ReadData: %s, target: %s had no valid data, according to %s [WMWARN70]\n", $mapItem, $this->finalTargetString, $this->pluginName));
         return;
     }
     wm_debug("Collected data %f,%f\n", $in, $out);
     $in *= $this->scaleFactor;
     $out *= $this->scaleFactor;
     $this->values[IN] = $in;
     $this->values[OUT] = $out;
     $this->timestamp = $dataTime;
     $this->dataValid = true;
 }
 function Draw($im, &$map)
 {
     // Get the positions of the end-points
     $x1 = $map->nodes[$this->a->name]->x;
     $y1 = $map->nodes[$this->a->name]->y;
     $x2 = $map->nodes[$this->b->name]->x;
     $y2 = $map->nodes[$this->b->name]->y;
     if (is_null($x1)) {
         wm_warn("LINK " . $this->name . " uses a NODE with no POSITION! [WMWARN35]\n");
         return;
     }
     if (is_null($y1)) {
         wm_warn("LINK " . $this->name . " uses a NODE with no POSITION! [WMWARN35]\n");
         return;
     }
     if (is_null($x2)) {
         wm_warn("LINK " . $this->name . " uses a NODE with no POSITION! [WMWARN35]\n");
         return;
     }
     if (is_null($y2)) {
         wm_warn("LINK " . $this->name . " uses a NODE with no POSITION! [WMWARN35]\n");
         return;
     }
     if ($this->linkstyle == 'twoway' && $this->labeloffset_in < $this->labeloffset_out && intval($map->get_hint("nowarn_bwlabelpos")) == 0) {
         wm_warn("LINK " . $this->name . " probably has it's BWLABELPOSs the wrong way around [WMWARN50]\n");
     }
     list($dx, $dy) = calc_offset($this->a_offset, $map->nodes[$this->a->name]->width, $map->nodes[$this->a->name]->height);
     $x1 += $dx;
     $y1 += $dy;
     list($dx, $dy) = calc_offset($this->b_offset, $map->nodes[$this->b->name]->width, $map->nodes[$this->b->name]->height);
     $x2 += $dx;
     $y2 += $dy;
     if ($x1 == $x2 && $y1 == $y2 && sizeof($this->vialist) == 0) {
         wm_warn("Zero-length link " . $this->name . " skipped. [WMWARN45]");
         return;
     }
     $outlinecol = new Colour($this->outlinecolour);
     $commentcol = new Colour($this->commentfontcolour);
     $outline_colour = $outlinecol->gdallocate($im);
     $xpoints = array();
     $ypoints = array();
     $xpoints[] = $x1;
     $ypoints[] = $y1;
     # warn("There are VIAs.\n");
     foreach ($this->vialist as $via) {
         # imagearc($im, $via[0],$via[1],20,20,0,360,$map->selected);
         if (isset($via[2])) {
             $xpoints[] = $map->nodes[$via[2]]->x + $via[0];
             $ypoints[] = $map->nodes[$via[2]]->y + $via[1];
         } else {
             $xpoints[] = $via[0];
             $ypoints[] = $via[1];
         }
     }
     $xpoints[] = $x2;
     $ypoints[] = $y2;
     # list($link_in_colour,$link_in_scalekey, $link_in_scaletag) = $map->NewColourFromPercent($this->inpercent,$this->usescale,$this->name);
     # list($link_out_colour,$link_out_scalekey, $link_out_scaletag) = $map->NewColourFromPercent($this->outpercent,$this->usescale,$this->name);
     $link_in_colour = $this->colours[IN];
     $link_out_colour = $this->colours[OUT];
     $gd_in_colour = $link_in_colour->gdallocate($im);
     $gd_out_colour = $link_out_colour->gdallocate($im);
     //	$map->links[$this->name]->inscalekey = $link_in_scalekey;
     //	$map->links[$this->name]->outscalekey = $link_out_scalekey;
     $link_width = $this->width;
     // these will replace the one above, ultimately.
     $link_in_width = $this->width;
     $link_out_width = $this->width;
     // for bulging animations
     if ($map->widthmod || $map->get_hint('link_bulge') == 1) {
         // a few 0.1s and +1s to fix div-by-zero, and invisible links
         $link_width = ($link_width * $this->inpercent * 1.5 + 0.1) / 100 + 1;
         // these too
         $link_in_width = ($link_in_width * $this->inpercent * 1.5 + 0.1) / 100 + 1;
         $link_out_width = ($link_out_width * $this->outpercent * 1.5 + 0.1) / 100 + 1;
     }
     // If there are no vias, treat this as a 2-point angled link, not curved
     if (sizeof($this->vialist) == 0 || $this->viastyle == 'angled') {
         // Calculate the spine points - the actual not a curve really, but we
         // need to create the array, and calculate the distance bits, otherwise
         // things like bwlabels won't know where to go.
         $this->curvepoints = calc_straight($xpoints, $ypoints);
         // then draw the "curve" itself
         draw_straight($im, $this->curvepoints, array($link_in_width, $link_out_width), $outline_colour, array($gd_in_colour, $gd_out_colour), $this->name, $map, $this->splitpos, $this->linkstyle == 'oneway' ? TRUE : FALSE);
     } elseif ($this->viastyle == 'curved') {
         // Calculate the spine points - the actual curve
         $this->curvepoints = calc_curve($xpoints, $ypoints);
         // then draw the curve itself
         draw_curve($im, $this->curvepoints, array($link_in_width, $link_out_width), $outline_colour, array($gd_in_colour, $gd_out_colour), $this->name, $map, $this->splitpos, $this->linkstyle == 'oneway' ? TRUE : FALSE);
     }
     if (!$commentcol->is_none()) {
         if ($commentcol->is_contrast()) {
             $commentcol_in = $link_in_colour->contrast();
             $commentcol_out = $link_out_colour->contrast();
         } else {
             $commentcol_in = $commentcol;
             $commentcol_out = $commentcol;
         }
         $comment_colour_in = $commentcol_in->gdallocate($im);
         $comment_colour_out = $commentcol_out->gdallocate($im);
         $this->DrawComments($im, array($comment_colour_in, $comment_colour_out), array($link_in_width * 1.1, $link_out_width * 1.1));
     }
     $curvelength = $this->curvepoints[count($this->curvepoints) - 1][2];
     // figure out where the labels should be, and what the angle of the curve is at that point
     list($q1_x, $q1_y, $junk, $q1_angle) = find_distance_coords_angle($this->curvepoints, $this->labeloffset_out / 100 * $curvelength);
     list($q3_x, $q3_y, $junk, $q3_angle) = find_distance_coords_angle($this->curvepoints, $this->labeloffset_in / 100 * $curvelength);
     # imageline($im, $q1_x+20*cos(deg2rad($q1_angle)),$q1_y-20*sin(deg2rad($q1_angle)), $q1_x-20*cos(deg2rad($q1_angle)), $q1_y+20*sin(deg2rad($q1_angle)), $this->owner->selected );
     # imageline($im, $q3_x+20*cos(deg2rad($q3_angle)),$q3_y-20*sin(deg2rad($q3_angle)), $q3_x-20*cos(deg2rad($q3_angle)), $q3_y+20*sin(deg2rad($q3_angle)), $this->owner->selected );
     # warn("$q1_angle $q3_angle\n");
     if (!is_null($q1_x)) {
         $outbound = array($q1_x, $q1_y, 0, 0, $this->outpercent, $this->bandwidth_out, $q1_angle, OUT);
         $inbound = array($q3_x, $q3_y, 0, 0, $this->inpercent, $this->bandwidth_in, $q3_angle, IN);
         if ($map->sizedebug) {
             $outbound[5] = $this->max_bandwidth_out;
             $inbound[5] = $this->max_bandwidth_in;
         }
         if ($this->linkstyle == 'oneway') {
             $tasks = array($outbound);
         } else {
             $tasks = array($inbound, $outbound);
         }
         foreach ($tasks as $task) {
             $thelabel = "";
             $thelabel = $map->ProcessString($this->bwlabelformats[$task[7]], $this);
             if ($thelabel != '') {
                 wm_debug("Bandwidth for label is " . $task[5] . "\n");
                 $padding = intval($this->get_hint('bwlabel_padding'));
                 // if screenshot_mode is enabled, wipe any letters to X and wipe any IP address to 127.0.0.1
                 // hopefully that will preserve enough information to show cool stuff without leaking info
                 if ($map->get_hint('screenshot_mode') == 1) {
                     $thelabel = screenshotify($thelabel);
                 }
                 if ($this->labelboxstyle == 'angled') {
                     $angle = $task[6];
                 } else {
                     $angle = 0;
                 }
                 $map->DrawLabelRotated($im, $task[0], $task[1], $angle, $thelabel, $this->bwfont, $padding, $this->name, $this->bwfontcolour, $this->bwboxcolour, $this->bwoutlinecolour, $map, $task[7]);
                 // imagearc($im, $task[0], $task[1], 10,10,0,360,$map->selected);
             }
         }
     }
 }
 function readConfigLines($inputLines)
 {
     $matches = null;
     wm_debug("in readConfig\n");
     foreach ($inputLines as $buffer) {
         wm_debug("Processing: {$buffer}\n");
         $lineMatched = false;
         $this->lineCount++;
         $buffer = trim($buffer);
         if ($buffer == '' || substr($buffer, 0, 1) == '#') {
             // this is a comment line, or a blank line, just skip to the next line
             continue;
         }
         $this->objectLineCount++;
         // break out the line into words (quoted strings are one word)
         $args = $this::parseString($buffer);
         #   wm_debug("  First: $args[0] in $this->currentType\n");
         // From here, the aim of the game is to get out of this loop as
         // early as possible, without running more preg_match calls than
         // necessary. In 0.97, this per-line loop accounted for 50% of
         // the running time!
         // this next loop replaces a whole pile of duplicated ifs with something with consistent handling
         if (!$lineMatched && true === isset($args[0])) {
             // check if there is even an entry in this context for the current keyword
             if (true === isset($this->configKeywords[$this->currentType][$args[0]])) {
                 // if there is, then the entry is an array of arrays - iterate them to validate the config
                 #  wm_debug("    Possible!\n");
                 foreach ($this->configKeywords[$this->currentType][$args[0]] as $keyword) {
                     unset($matches);
                     #   wm_debug("      Trying $keyword[1]\n");
                     if (substr($keyword[1], 0, 1) != '/' || 1 === preg_match($keyword[1], $buffer, $matches)) {
                         #   wm_debug("Might be $args[0]\n");
                         // if we came here without a regexp, then the \1 etc
                         // refer to arg numbers, not match numbers
                         if (false === isset($matches)) {
                             $matches = $args;
                         }
                         if (is_array($keyword[2])) {
                             $this->readConfigSimpleLine($keyword, $matches);
                             $lineMatched = true;
                         } else {
                             // the third arg wasn't an array, it was a function name.
                             // call that function to handle this keyword
                             if (call_user_func(array($this, $keyword[2]), $buffer, $args, $matches)) {
                                 $lineMatched = true;
                             }
                         }
                     }
                     // jump out of this loop if there's been a match
                     if ($lineMatched) {
                         break;
                     }
                 }
             }
         }
         if (!$lineMatched && $buffer != '') {
             wm_warn("Unrecognised config on line {$this->lineCount}: {$buffer}\n");
         }
     }
     // Commit the last item
     $this->commitItem();
     wm_debug("ReadConfig has finished reading the config ({$this->lineCount} lines)\n");
     wm_debug("------------------------------------------\n");
     return $this->lineCount;
 }
/**
 * @param $mapParameters
 * @param $configDirectory
 * @param $outputDirectory
 * @param $imageFormat
 * @param $quietLogging
 * @param $global_debug
 * @param $mapCount
 * @param $rrdtool_path
 * @param $weathermap_error_suppress
 * @param $weathermap_poller_start_time
 * @param $total_warnings
 * @return array
 */
function weathermap_run_map($mapParameters, $configDirectory, $outputDirectory, $imageFormat, $quietLogging, $global_debug, $mapCount, $rrdtool_path, $weathermap_error_suppress, $weathermap_poller_start_time, $total_warnings)
{
    global $weathermap_debugging;
    global $weathermap_error_suppress;
    // reset the warning counter
    $weathermap_warncount = 0;
    // this is what will prefix log entries for this map
    $logTag = "[Map " . $mapParameters['id'] . "] " . $mapParameters['configfile'];
    wm_debug("{$logTag} - FIRST TOUCH\n");
    $runner = new WeatherMapRunner($configDirectory, $outputDirectory, $mapParameters['configfile'], $mapParameters['filehash'], $imageFormat);
    if ($global_debug === false && ($mapParameters['debug'] == 'on' || $mapParameters['debug'] == 'once')) {
        $weathermap_debugging = true;
        $runner->setDebug(true);
        wm_debug("{$logTag} - Per-map debugging enabled for this map.\n");
    } else {
        $weathermap_debugging = $global_debug;
        $runner->setDebug(false);
    }
    $runner->setRrdtool($rrdtool_path);
    // Log where we are up to so the Cacti UI can tell someone
    WMCactiAPI::setConfigOption("weaathermap_last_started_file", $logTag);
    $runner->LoadMap();
    $mapStartTime = microtime(true);
    weathermap_memory_check("MEM starting {$mapCount}");
    // $weathermapObject = new Weathermap;
    // $weathermapObject->context = "cacti";
    // we can grab the rrdtool path from Cacti's config, in this case
    // $weathermapObject->rrdtool = $rrdtool_path;
    // $weathermapObject->ReadConfig($mapfile);
    $runner->applyAllHints($mapParameters);
    //    weathermap_memory_check("MEM postread");
    //        $weathermapObject->readData();
    //        weathermap_memory_check("MEM postdata");
    if ($quietLogging == 0) {
        wm_warn("About to write image file. If this is the last message in your log, increase memory_limit in php.ini [WMPOLL01]\n", true);
    }
    weathermap_memory_check("MEM pre-render");
    // used to write files before moving them into place
    //    $tempImageFilename = $outputDirectory . DIRECTORY_SEPARATOR . $mapParameters['filehash'] . '.tmp.png';
    //    $imageFilename = $outputDirectory . DIRECTORY_SEPARATOR . $mapParameters['filehash'] . "." . $imageFormat;
    //    $thumbImageFilename = $outputDirectory . DIRECTORY_SEPARATOR . $mapParameters['filehash'] . ".thumb." . $imageFormat;
    //    $thumb48ImageFilename = $outputDirectory . DIRECTORY_SEPARATOR . $mapParameters['filehash'] . ".thumb48." . $imageFormat;
    // Write the image to a temporary file first - it turns out that libpng is not that fast
    // and this way we avoid showing half a map
    // $weathermapObject->drawMapImage($tempImageFilename, $thumbImageFilename, read_config_option("weathermap_thumbsize"));
    $runner->run();
    //        // Firstly, don't move or delete anything if the image saving failed
    //        if (file_exists($tempImageFilename)) {
    //            // Don't try and delete a non-existent file (first run)
    //            if (file_exists($imageFilename)) {
    //                unlink($imageFilename);
    //            }
    //            rename($tempImageFilename, $imageFilename);
    //        }
    //
    //        $gdThumbImage = imagecreatefrompng($thumbImageFilename);
    //        $gdThumb48Image = imagecreatetruecolor(48, 48);
    //        imagecopyresampled($gdThumb48Image, $gdThumbImage, 0, 0, 0, 0, 48, 48, imagesx($gdThumbImage), imagesy($gdThumbImage));
    //        imagepng($gdThumb48Image, $thumb48ImageFilename);
    //        imagedestroy($gdThumb48Image);
    //        imagedestroy($gdThumbImage);
    // $configured_imageuri = $weathermapObject->imageuri;
    // $weathermapObject->imageuri = 'weathermap-cacti-plugin.php?action=viewimage&id=' . $mapParameters['filehash'] . "&time=" . time();
    //        if ($quietLogging == 0) {
    //            wm_warn("Wrote map to $imageFilename and $thumbImageFilename\n", true);
    //        }
    $runner->createAllHTML();
    $runner->writeDataFile();
    // $weathermapObject->writeDataFile($dataFilename);
    // put back the configured imageuri
    // $weathermapObject->imageuri = $configured_imageuri;
    // if an htmloutputfile was configured, output the HTML there too
    // but using the configured imageuri and imagefilename
    //        if ($weathermapObject->htmloutputfile != "") {
    //            $htmlFilename = $weathermapObject->htmloutputfile;
    //
    //            $fileHandle = @fopen($htmlFilename, 'w');
    //
    //            if ($fileHandle !== false) {
    //                fwrite(
    //                    $fileHandle,
    //                    $weathermapObject->makeHTML('weathermap_' . $mapParameters['filehash'] . '_imap')
    //                );
    //                fclose($fileHandle);
    //                wm_debug("Wrote HTML to %s\n", $htmlFilename);
    //            } else {
    //                if (true === file_exists($htmlFilename)) {
    //                    wm_warn('Failed to overwrite ' . $htmlFilename
    //                        . " - permissions of existing file are wrong? [WMPOLL02]\n");
    //                } else {
    //                    wm_warn('Failed to create ' . $htmlFilename
    //                        . " - permissions of output directory are wrong? [WMPOLL03]\n");
    //                }
    //            }
    //        }
    //        if ($weathermapObject->imageoutputfile != "" && $weathermapObject->imageoutputfile != "weathermap.png" && file_exists($imageFilename)) {
    //            // copy the existing file to the configured location too
    //            @copy($imageFilename, $weathermapObject->imageoutputfile);
    //        }
    // If archiving is enabled for this map, then save copies with datestamps, for animation etc
    if ($mapParameters['archiving'] == 'on') {
        // TODO - additionally save a copy with a datestamp file format
        $archiveDatestamp = strftime("%Y-%m-%d-%H-%M", $weathermap_poller_start_time);
        $archiveFilename = $outputDirectory . DIRECTORY_SEPARATOR . sprintf("%s-archive-%s.%s", $mapParameters['filehash'], $archiveDatestamp, $imageFormat);
        @copy($imageFilename, $archiveFilename);
        weathermap_manage_archiving($mapParameters['filehash'] . "-archive-", $outputDirectory);
    }
    db_execute("update weathermap_maps set titlecache='" . mysql_real_escape_string($runner->getProcessedTitle()) . "' where id=" . intval($mapParameters['id']));
    $runner->cleanUp();
    unset($runner);
    // $weathermapObject->cleanUp();
    // unset($weathermapObject);
    $mapEndTime = microtime(true);
    $mapDuration = $mapEndTime - $mapStartTime;
    wm_debug("TIME: %s took %f seconds.\n", $mapParameters['configfile'], $mapDuration);
    weathermap_memory_check("MEM after");
    WMCactiAPI::setConfigOption("weaathermap_last_finished_file", $logTag);
    // if the debug mode was set to once for this map, then that
    // time has now passed, and it can be turned off again.
    $newDebugState = $mapParameters['debug'];
    if ($newDebugState == 'once') {
        $newDebugState = 'off';
    }
    WMCactiAPI::executeDBQuery(sprintf("update weathermap_maps set warncount=%d, runtime=%f, debug='%s',lastrun=NOW() where id=%d", $weathermap_warncount, $mapDuration, $newDebugState, $mapParameters['id']));
    //    $total_warnings += $weathermap_warncount;
    return;
}
 public function draw($imageRef)
 {
     $txt_x = $this->textPosition->x;
     $txt_y = $this->textPosition->y;
     // XXX - this had better be temporary!
     $label_x1 = $this->labelRectangle->topLeft->x;
     $label_y1 = $this->labelRectangle->topLeft->y;
     $label_x2 = $this->labelRectangle->bottomRight->x;
     $label_y2 = $this->labelRectangle->bottomRight->y;
     // if there's an icon, then you can choose to have no background
     if (!$this->labelFillColour->isNone()) {
         imagefilledrectangle($imageRef, $label_x1, $label_y1, $label_x2, $label_y2, $this->labelFillColour->gdAllocate($imageRef));
     }
     if ($this->map->selected) {
         imagerectangle($imageRef, $label_x1, $label_y1, $label_x2, $label_y2, $this->map->selected);
         // would be nice if it was thicker, too...
         imagerectangle($imageRef, $label_x1 + 1, $label_y1 + 1, $label_x2 - 1, $label_y2 - 1, $this->map->selected);
     } else {
         // $label_outline_colour = $this->labeloutlinecolour;
         if ($this->labelOutlineColour->isRealColour()) {
             imagerectangle($imageRef, $label_x1, $label_y1, $label_x2, $label_y2, $this->labelOutlineColour->gdallocate($imageRef));
         }
     }
     // $shcol = $this->labelfontshadowcolour;
     if ($this->labelShadowColour->isRealColour()) {
         $this->map->myimagestring($imageRef, $this->labelFont, $txt_x + 1, $txt_y + 1, $this->labelString, $this->labelShadowColour->gdallocate($imageRef), $this->labelAngle);
     }
     $txcol = $this->labelTextColour;
     if ($txcol->isContrast()) {
         if ($this->labelFillColour->isRealColour()) {
             $txcol = $this->labelFillColour->getContrastingColour();
         } else {
             wm_warn("You can't make a contrast with 'none'. [WMWARN43]\n");
             $txcol = new WMColour(0, 0, 0);
         }
     }
     $this->map->myimagestring($imageRef, $this->labelFont, $txt_x, $txt_y, $this->labelString, $txcol->gdAllocate($imageRef), $this->labelAngle);
 }
Esempio n. 19
0
								wm_debug("ConvertDS: Converting to $new_target");		
								$converted++;

								if($type == 'NODE')
								{
									$map->nodes[$name]->targets[$tindex][4] = $new_target;
								}
								if($type == 'LINK')
								{
									$map->links[$name]->targets[$tindex][4] = $new_target;
								}											
								
							}
							else
							{
								wm_warn("ConvertDS: Failed to find a match for $db_rrdname - can't convert back to rrdfile.");
							}
							
						}
					
						$tindex++;
					}

					wm_debug ("ReadData complete for $type $name\n");
				}
				else
				{
					wm_debug("ReadData: No targets for $type $name\n");
				}
			}
			else
 /**
  * @param $local_data_id
  * @param $data
  * @param $dsnames
  */
 private function registerWMDataRequirement($local_data_id, $data, $dsnames)
 {
     wm_debug("Didn't get data for 'wm' source. Inserting new tasks.");
     // insert the required details into weathermap_data, so it will be picked up next time
     $SQL = sprintf("select data_template_data.data_source_path as path from data_template_data,data_template_rrd where data_template_data.local_data_id=data_template_rrd.local_data_id and data_template_rrd.local_data_id=%d", $local_data_id);
     $result = db_fetch_row($SQL);
     if (sizeof($result) > 0) {
         $db_rrdname = $result['path'];
         wm_debug("Filename is {$db_rrdname}");
         foreach (array(IN, OUT) as $dir) {
             if ($data[$dir] === null) {
                 $SQLins = "insert into weathermap_data (rrdfile, data_source_name, sequence, local_data_id) values ('" . mysql_real_escape_string($db_rrdname) . "','" . mysql_real_escape_string($dsnames[$dir]) . "', 0," . $local_data_id . ")";
                 // warn($SQLins);
                 db_execute($SQLins);
             }
         }
     } else {
         wm_warn("DSStats ReadData: Failed to find a filename for DS id {$local_data_id} [WMDSTATS01]");
     }
 }
Esempio n. 21
0
 /**
  * Get a value for a config variable. Follow the template inheritance tree if necessary.
  * Return an array with the value followed by the status (whether it came from the source object or
  * a template, or just didn't exist). This will replace all that CopyFrom stuff.
  *
  * @param $keyname
  * @return array
  */
 public function getConfigValue($keyname)
 {
     if (isset($this->config[$keyname])) {
         return array($this->config[$keyname], CONF_FOUND_DIRECT);
     } else {
         if (!is_null($this->parent)) {
             list($value, $direct) = $this->parent->getConfig($keyname);
             if ($direct != CONF_NOT_FOUND) {
                 $direct = CONF_FOUND_INHERITED;
             }
         } else {
             $value = null;
             $direct = CONF_NOT_FOUND;
         }
         // if we got to the top of the tree without finding it, that's probably a typo in the original getConfig()
         if (is_null($value) && is_null($this->parent)) {
             wm_warn("Tried to get config keyword '{$keyname}' with no result. [WMWARN300]");
         }
         return array($value, $direct);
     }
 }
 function preCalculate(&$map)
 {
     wm_debug("Link " . $this->name . ": Calculating geometry.\n");
     // don't bother doing anything if it's a template
     if ($this->isTemplate()) {
         return;
     }
     $points = array();
     list($dx, $dy) = WMUtility::calculateOffset($this->a_offset, $this->a->width, $this->a->height);
     $points[] = new WMPoint($this->a->x + $dx, $this->a->y + $dy);
     foreach ($this->vialist as $via) {
         wm_debug("VIALIST...\n");
         // if the via has a third element, the first two are relative to that node
         if (isset($via[2])) {
             $relativeTo = $map->getNode($via[2]);
             wm_debug("Relative to {$relativeTo}\n");
             $point = new WMPoint($relativeTo->x + $via[0], $relativeTo->y + $via[1]);
         } else {
             $point = new WMPoint($via[0], $via[1]);
         }
         wm_debug("Adding {$point}\n");
         $points[] = $point;
     }
     list($dx, $dy) = WMUtility::calculateOffset($this->b_offset, $this->b->width, $this->b->height);
     $points[] = new WMPoint($this->b->x + $dx, $this->b->y + $dy);
     if ($points[0]->closeEnough($points[1]) && sizeof($this->vialist) == 0) {
         wm_warn("Zero-length link " . $this->name . " skipped. [WMWARN45]");
         $this->geometry = null;
         return;
     }
     $widths = array($this->width, $this->width);
     // for bulging animations, modulate the width with the percentage value
     if ($map->widthmod || $map->get_hint('link_bulge') == 1) {
         // a few 0.1s and +1s to fix div-by-zero, and invisible links
         $widths[0] = ($widths[0] * $this->percentUsages[IN] * 1.5 + 0.1) / 100 + 1;
         $widths[1] = ($widths[1] * $this->percentUsages[OUT] * 1.5 + 0.1) / 100 + 1;
     }
     $style = $this->viastyle;
     // don't bother with any curve stuff if there aren't any Vias defined, even if the style is 'curved'
     if (count($this->vialist) == 0) {
         $style = "angled";
     }
     $this->geometry = WMLinkGeometryFactory::create($style);
     $this->geometry->Init($this, $points, $widths, $this->linkstyle == 'oneway' ? 1 : 2, $this->splitpos, $this->arrowstyle);
 }
 /**
  * @param $ping_count
  * @param $target
  * @return resource
  */
 protected function openPipeToFping($target, $ping_count)
 {
     // TODO - this doesn't really validate the target in any way!!
     if (!is_executable($this->fping_cmd)) {
         wm_warn("FPing ReadData: Can't find fping executable. Check path at line 20 of WeatherMapDataSource_fping.php [WMFPING01]\n");
         return null;
     }
     $command = $this->fping_cmd . " -t100 -r1 -p20 -u -C {$ping_count} -i10 -q {$target} 2>&1";
     wm_debug("Running {$command}\n");
     $pipe = popen($command, "r");
     if (!isset($pipe)) {
         wm_warn("FPing ReadData: Couldn't open pipe to fping [WMFPING04]\n");
     }
     return $pipe;
 }
Esempio n. 24
0
function weathermap_poller_output($rrd_update_array) {
	global $config;
	// global $weathermap_debugging;

	$logging = read_config_option("log_verbosity");

	if($logging >= POLLER_VERBOSITY_DEBUG) cacti_log("WM poller_output: STARTING\n",true,"WEATHERMAP");

	// partially borrowed from Jimmy Conner's THold plugin.
	// (although I do things slightly differently - I go from filenames, and don't use the poller_interval)

	
	// $requiredlist = db_fetch_assoc("select distinct weathermap_data.*, data_template_data.local_data_id, data_template_rrd.data_source_type_id from weathermap_data, data_template_data, data_template_rrd where weathermap_data.rrdfile=data_template_data.data_source_path and data_template_rrd.local_data_id=data_template_data.local_data_id");
	// new version works with *either* a local_data_id or rrdfile in the weathermap_data table, and returns BOTH
	$requiredlist = db_fetch_assoc("select distinct weathermap_data.id, weathermap_data.last_value, weathermap_data.last_time, weathermap_data.data_source_name, data_template_data.data_source_path, data_template_data.local_data_id, data_template_rrd.data_source_type_id from weathermap_data, data_template_data, data_template_rrd where weathermap_data.local_data_id=data_template_data.local_data_id and data_template_rrd.local_data_id=data_template_data.local_data_id and weathermap_data.local_data_id<>0;");
	
	$path_rra = $config["rra_path"];
	
	# especially on Windows, it seems that filenames are not reliable (sometimes \ and sometimes / even though path_rra is always /) .
	# let's make an index from local_data_id to filename, and then use local_data_id as the key...
	
	foreach (array_keys($rrd_update_array) as $key)
	{
		if(isset( $rrd_update_array[$key]['times']) && is_array($rrd_update_array[$key]['times']) )
		{
			# if($logging >= POLLER_VERBOSITY_DEBUG) cacti_log("WM poller_output: Adding $key",true,"WEATHERMAP");
			$knownfiles[ $rrd_update_array[$key]["local_data_id"] ] = $key;
			
		}
	}
	
	foreach ($requiredlist as $required)
	{
		$file = str_replace("<path_rra>", $path_rra, $required['data_source_path']);
		$dsname = $required['data_source_name'];
		$local_data_id = $required['local_data_id'];
		
		if(isset($knownfiles[$local_data_id]))
		{
			$file2 = $knownfiles[$local_data_id];			
			if($file2 != '') $file = $file2;
		}
				
	    if($logging >= POLLER_VERBOSITY_DEBUG) cacti_log("WM poller_output: Looking for $file ($local_data_id) (".$required['data_source_path'].")\n",true,"WEATHERMAP");
		
		if( isset($rrd_update_array[$file]) && is_array($rrd_update_array[$file]) && isset($rrd_update_array[$file]['times']) && is_array($rrd_update_array[$file]['times']) && isset( $rrd_update_array{$file}['times'][key($rrd_update_array[$file]['times'])]{$dsname} ) )
		{
			$value = $rrd_update_array{$file}['times'][key($rrd_update_array[$file]['times'])]{$dsname};
			$time = key($rrd_update_array[$file]['times']);
			if (read_config_option("log_verbosity") >= POLLER_VERBOSITY_MEDIUM) 
				cacti_log("WM poller_output: Got one! $file:$dsname -> $time $value\n",true,"WEATHERMAP");
			
			$period = $time - $required['last_time'];
			$lastval = $required['last_value'];
			
			// if the new value is a NaN, we'll give 0 instead, and pretend it didn't happen from the point
			// of view of the counter etc. That way, we don't get those enormous spikes. Still doesn't deal with
			// reboots very well, but it should improve it for drops.
			if($value == 'U')
			{
				$newvalue = 0;
				$newlastvalue = $lastval;
				$newtime = $required['last_time'];
			}
			else
			{
				$newlastvalue = $value;
				$newtime = $time;
				
				switch($required['data_source_type_id'])
				{
					case 1: //GAUGE
						$newvalue = $value;
						break;
					
					case 2: //COUNTER
						if ($value >= $lastval) {
							// Everything is normal
							$newvalue = $value - $lastval;
						} else {
							// Possible overflow, see if its 32bit or 64bit
							if ($lastval > 4294967295) {
								$newvalue = (18446744073709551615 - $lastval) + $value;
							} else {
								$newvalue = (4294967295 - $lastval) + $value;
							}
						}
						$newvalue = $newvalue / $period;
						break;
					
					case 3: //DERIVE
						$newvalue = ($value-$lastval) / $period;
						break;
					
					case 4: //ABSOLUTE
						$newvalue = $value / $period;
						break;
					
					default: // do something somewhat sensible in case something odd happens
						$newvalue = $value;
						wm_warn("poller_output found an unknown data_source_type_id for $file:$dsname");
						break;
				}
			}
			db_execute("UPDATE weathermap_data SET last_time=$newtime, last_calc='$newvalue', last_value='$newlastvalue',sequence=sequence+1  where id = " . $required['id']);
	        	if($logging >= POLLER_VERBOSITY_DEBUG) cacti_log("WM poller_output: Final value is $newvalue (was $lastval, period was $period)\n",true,"WEATHERMAP");
		}
		else
		{
			if(1==0 && $logging >= POLLER_VERBOSITY_DEBUG)
			{
			#	cacti_log("WM poller_output: ENDING\n",true,"WEATHERMAP");
				cacti_log("WM poller_output: Didn't find it.\n",true,"WEATHERMAP");
				cacti_log("WM poller_output: DID find these:\n",true,"WEATHERMAP");
				
				foreach (array_keys($rrd_update_array) as $key)
				{
					$local_data_id = $rrd_update_array[$key]["local_data_id"];
					cacti_log("WM poller_output:    $key ($local_data_id)\n",true,"WEATHERMAP");
				}			
			}
		}
	}

	if($logging >= POLLER_VERBOSITY_DEBUG) cacti_log("WM poller_output: ENDING\n",true,"WEATHERMAP");
	
	return $rrd_update_array;
}
 public static function calculateOffset($offsetstring, $width, $height)
 {
     if (preg_match('/^([-+]?\\d+):([-+]?\\d+)$/', $offsetstring, $matches)) {
         wm_debug("Numeric Offset found\n");
         return array($matches[1], $matches[2]);
     }
     if (preg_match('/(NE|SE|NW|SW|N|S|E|W|C)(\\d+)?$/i', $offsetstring, $matches)) {
         return self::calculateCompassOffset($matches[1], isset($matches[2]) ? $matches[2] : null, $width, $height);
     }
     if (preg_match('/(-?\\d+)r(\\d+)$/i', $offsetstring, $matches)) {
         $angle = intval($matches[1]);
         $distance = intval($matches[2]);
         $rangle = deg2rad($angle);
         $offsets = array($distance * sin($rangle), -$distance * cos($rangle));
         return $offsets;
     }
     // TODO - where is the named offset handling!!
     wm_warn("Got a position offset that didn't make sense ({$offsetstring}).");
     return array(0, 0);
 }
 function preRender($im, &$map)
 {
     // don't bother drawing if it's a template
     if ($this->isTemplate()) {
         return;
     }
     // apparently, some versions of the gd extension will crash if we continue...
     if ($this->label == '' && $this->iconfile == '') {
         return;
     }
     // start these off with sensible values, so that bbox
     // calculations are easier.
     $labelBoundingBox = new WMBoundingBox();
     $labelBoundingBox->addWMPoint($this->getPosition());
     $iconBoundingBox = new WMBoundingBox();
     $iconBoundingBox->addWMPoint($this->getPosition());
     $icon_x1 = $this->x;
     $icon_x2 = $this->x;
     $icon_y1 = $this->y;
     $icon_y2 = $this->y;
     $label_x1 = $this->x;
     $label_x2 = $this->x;
     $label_y1 = $this->y;
     $label_y2 = $this->y;
     $boxWidth = 0;
     $boxHeight = 0;
     $icon_w = 0;
     $icon_h = 0;
     list($labelFillColour, $iconFillColour) = $this->calculateColours($map);
     // figure out a bounding rectangle for the label
     if ($this->label != '') {
         $padding = 4.0;
         $padFactor = 1.0;
         $this->processedLabel = $map->ProcessString($this->label, $this, true, true);
         // if screenshot_mode is enabled, wipe any letters to X and wipe any IP address to 127.0.0.1
         // hopefully that will preserve enough information to show cool stuff without leaking info
         if ($map->get_hint('screenshot_mode') == 1) {
             $this->processedLabel = WMUtility::stringAnonymise($this->processedLabel);
         }
         list($stringWidth, $stringHeight) = $map->myimagestringsize($this->labelfont, $this->processedLabel);
         if ($this->labelangle == 90 || $this->labelangle == 270) {
             $boxWidth = $stringHeight * $padFactor + $padding;
             $boxHeight = $stringWidth * $padFactor + $padding;
         } else {
             $boxWidth = $stringWidth * $padFactor + $padding;
             $boxHeight = $stringHeight * $padFactor + $padding;
         }
         $halfWidth = $boxWidth / 2;
         $halfHeight = $boxHeight / 2;
         $label_x1 = $this->x - $halfWidth;
         $label_y1 = $this->y - $halfHeight;
         $label_x2 = $this->x + $halfWidth;
         $label_y2 = $this->y + $halfHeight;
         $labelBoundingBox->addPoint($this->x - $halfWidth, $this->y - $halfHeight);
         $labelBoundingBox->addPoint($this->x + $halfWidth, $this->y + $halfHeight);
         wm_debug("Node->pre_render: " . $this->name . " Label Metrics are: {$stringWidth} x {$stringHeight} -> {$boxWidth} x {$boxHeight}\n");
         if ($this->labelangle == 90) {
             $txt_x = $this->x + $stringHeight / 2;
             $txt_y = $this->y + $stringWidth / 2;
         }
         if ($this->labelangle == 270) {
             $txt_x = $this->x - $stringHeight / 2;
             $txt_y = $this->y - $stringWidth / 2;
         }
         if ($this->labelangle == 0) {
             $txt_x = $this->x - $stringWidth / 2;
             $txt_y = $this->y + $stringHeight / 2;
         }
         if ($this->labelangle == 180) {
             $txt_x = $this->x + $stringWidth / 2;
             $txt_y = $this->y - $stringHeight / 2;
         }
         $this->width = $boxWidth;
         $this->height = $boxHeight;
     }
     // figure out a bounding rectangle for the icon
     if ($this->iconfile != '') {
         $iconImageRef = null;
         $icon_w = 0;
         $icon_h = 0;
         if ($this->iconfile == 'rbox' || $this->iconfile == 'box' || $this->iconfile == 'round' || $this->iconfile == 'inpie' || $this->iconfile == 'outpie' || $this->iconfile == 'gauge' || $this->iconfile == 'nink') {
             wm_debug("Artificial Icon type " . $this->iconfile . " for {$this->name}\n");
             // this is an artificial icon - we don't load a file for it
             $iconImageRef = imagecreatetruecolor($this->iconscalew, $this->iconscaleh);
             imageSaveAlpha($iconImageRef, true);
             $nothing = imagecolorallocatealpha($iconImageRef, 128, 0, 0, 127);
             imagefill($iconImageRef, 0, 0, $nothing);
             $fill = null;
             $ink = null;
             $aiconFillColour = $this->aiconfillcolour;
             $aiconInkColour = $this->aiconoutlinecolour;
             // if useiconscale isn't set, then use the static colour defined, or copy the colour from the label
             if ($this->useiconscale == "none") {
                 if ($aiconFillColour->isCopy() && !$labelFillColour->isNone()) {
                     $fill = $labelFillColour;
                 } else {
                     if ($aiconFillColour->isRealColour()) {
                         $fill = $aiconFillColour;
                     }
                 }
             } else {
                 // if useiconscale IS defined, use that to figure out the fill colour
                 $fill = $iconFillColour;
             }
             if (!$this->aiconoutlinecolour->isNone()) {
                 $ink = $aiconInkColour;
             }
             wm_debug("AICON colours are {$ink} and {$fill}\n");
             if ($this->iconfile == 'box') {
                 $this->drawAIconBox($iconImageRef, $fill, $ink);
             }
             if ($this->iconfile == 'rbox') {
                 $this->drawAIconRoundedBox($iconImageRef, $fill, $ink);
             }
             if ($this->iconfile == 'round') {
                 $this->drawAIconRound($iconImageRef, $fill, $ink);
             }
             if ($this->iconfile == 'nink') {
                 $this->drawAIconNINK($iconImageRef, $ink);
             }
             // XXX - needs proper colours
             if ($this->iconfile == 'inpie' || $this->iconfile == 'outpie') {
                 $this->drawAIconPie($iconImageRef, $fill, $ink);
             }
             if ($this->iconfile == 'gauge') {
                 wm_warn('gauge AICON not implemented yet [WMWARN99]');
             }
         } else {
             $realiconfile = $map->ProcessString($this->iconfile, $this);
             if (is_readable($realiconfile)) {
                 imagealphablending($im, true);
                 // draw the supplied icon, instead of the labelled box
                 $iconImageRef = imagecreatefromfile($realiconfile);
                 if (true === isset($iconFillColour)) {
                     $this->colourizeImage($iconImageRef, $iconFillColour);
                 }
                 if ($iconImageRef) {
                     $icon_w = imagesx($iconImageRef);
                     $icon_h = imagesy($iconImageRef);
                     if ($this->iconscalew * $this->iconscaleh > 0) {
                         wm_debug("If this is the last thing in your logs, you probably have a buggy GD library. Get > 2.0.33 or use PHP builtin.\n");
                         imagealphablending($iconImageRef, true);
                         wm_debug("SCALING ICON here\n");
                         if ($icon_w > $icon_h) {
                             $scalefactor = $icon_w / $this->iconscalew;
                         } else {
                             $scalefactor = $icon_h / $this->iconscaleh;
                         }
                         $new_width = $icon_w / $scalefactor;
                         $new_height = $icon_h / $scalefactor;
                         $scaled = imagecreatetruecolor($new_width, $new_height);
                         imagealphablending($scaled, false);
                         imagecopyresampled($scaled, $iconImageRef, 0, 0, 0, 0, $new_width, $new_height, $icon_w, $icon_h);
                         imagedestroy($iconImageRef);
                         $iconImageRef = $scaled;
                     }
                 } else {
                     wm_warn("Couldn't open ICON: '" . $realiconfile . "' - is it a PNG, JPEG or GIF? [WMWARN37]\n");
                 }
             } else {
                 if ($realiconfile != 'none') {
                     wm_warn("ICON '" . $realiconfile . "' does not exist, or is not readable. Check path and permissions. [WMARN38]\n");
                 }
             }
         }
         if ($iconImageRef) {
             $icon_w = imagesx($iconImageRef);
             $icon_h = imagesy($iconImageRef);
             $icon_x1 = $this->x - $icon_w / 2;
             $icon_y1 = $this->y - $icon_h / 2;
             $icon_x2 = $this->x + $icon_w / 2;
             $icon_y2 = $this->y + $icon_h / 2;
             $this->width = imagesx($iconImageRef);
             $this->height = imagesy($iconImageRef);
             $this->boundingboxes[] = array($icon_x1, $icon_y1, $icon_x2, $icon_y2);
         }
     }
     // do any offset calculations
     $deltaX = 0;
     $deltaY = 0;
     if ($this->labeloffset != '' && $this->iconfile != '') {
         $this->labeloffsetx = 0;
         $this->labeloffsety = 0;
         list($deltaX, $deltaY) = WMUtility::calculateOffset($this->labeloffset, $icon_w + $boxWidth - 1, $icon_h + $boxHeight);
     }
     $label_x1 += $this->labeloffsetx + $deltaX;
     $label_x2 += $this->labeloffsetx + $deltaX;
     $label_y1 += $this->labeloffsety + $deltaY;
     $label_y2 += $this->labeloffsety + $deltaY;
     if ($this->label != '') {
         $this->boundingboxes[] = array($label_x1, $label_y1, $label_x2, $label_y2);
     }
     // work out the bounding box of the whole thing
     $bbox_x1 = min($label_x1, $icon_x1);
     $bbox_x2 = max($label_x2, $icon_x2) + 1;
     $bbox_y1 = min($label_y1, $icon_y1);
     $bbox_y2 = max($label_y2, $icon_y2) + 1;
     // create TWO imagemap entries - one for the label and one for the icon
     // (so we can have close-spaced icons better)
     $temp_width = $bbox_x2 - $bbox_x1;
     $temp_height = $bbox_y2 - $bbox_y1;
     // create an image of that size and draw into it
     $node_im = imagecreatetruecolor($temp_width, $temp_height);
     // ImageAlphaBlending($node_im, false);
     imageSaveAlpha($node_im, true);
     $nothing = imagecolorallocatealpha($node_im, 128, 0, 0, 127);
     imagefill($node_im, 0, 0, $nothing);
     $label_x1 -= $bbox_x1;
     $label_x2 -= $bbox_x1;
     $label_y1 -= $bbox_y1;
     $label_y2 -= $bbox_y1;
     $icon_x1 -= $bbox_x1;
     $icon_y1 -= $bbox_y1;
     // Draw the icon, if any
     if (isset($iconImageRef)) {
         imagecopy($node_im, $iconImageRef, $icon_x1, $icon_y1, 0, 0, imagesx($iconImageRef), imagesy($iconImageRef));
         imagedestroy($iconImageRef);
     }
     // Draw the label, if any
     if ($this->label != '') {
         $txt_x -= $bbox_x1;
         $txt_x += $this->labeloffsetx + $deltaX;
         $txt_y -= $bbox_y1;
         $txt_y += $this->labeloffsety + $deltaY;
         // if there's an icon, then you can choose to have no background
         if (!$this->labelbgcolour->isNone()) {
             imagefilledrectangle($node_im, $label_x1, $label_y1, $label_x2, $label_y2, $labelFillColour->gdAllocate($node_im));
         }
         if ($this->selected) {
             imagerectangle($node_im, $label_x1, $label_y1, $label_x2, $label_y2, $map->selected);
             // would be nice if it was thicker, too...
             imagerectangle($node_im, $label_x1 + 1, $label_y1 + 1, $label_x2 - 1, $label_y2 - 1, $map->selected);
         } else {
             // $label_outline_colour = $this->labeloutlinecolour;
             if ($this->labeloutlinecolour->isRealColour()) {
                 imagerectangle($node_im, $label_x1, $label_y1, $label_x2, $label_y2, $this->labeloutlinecolour->gdallocate($node_im));
             }
         }
         // $shcol = $this->labelfontshadowcolour;
         if ($this->labelfontshadowcolour->isRealColour()) {
             $map->myimagestring($node_im, $this->labelfont, $txt_x + 1, $txt_y + 1, $this->processedLabel, $this->labelfontshadowcolour->gdallocate($node_im), $this->labelangle);
         }
         $txcol = $this->labelfontcolour;
         if ($txcol->isContrast()) {
             if ($labelFillColour->isRealColour()) {
                 $txcol = $labelFillColour->getContrastingColour();
             } else {
                 wm_warn("You can't make a contrast with 'none'. [WMWARN43]\n");
                 $txcol = new WMColour(0, 0, 0);
             }
         }
         $map->myimagestring($node_im, $this->labelfont, $txt_x, $txt_y, $this->processedLabel, $txcol->gdAllocate($node_im), $this->labelangle);
     }
     $this->centre_x = $this->x - $bbox_x1;
     $this->centre_y = $this->y - $bbox_y1;
     $this->image = $node_im;
 }
 public function ColourFromValue($value, $itemName = '', $isPercentage = true, $showScaleWarnings = true)
 {
     $scaleName = $this->name;
     $nowarn_clipping = intval($this->owner->get_hint("nowarn_clipping"));
     $nowarn_scalemisses = !$showScaleWarnings || intval($this->owner->get_hint("nowarn_scalemisses"));
     if (!isset($this->colours)) {
         throw new WMException("ColourFromValue: SCALE {$scaleName} used with no spans defined?");
     }
     if ($this->spanCount() == 0) {
         if ($this->name != 'none') {
             wm_warn(sprintf("ColourFromValue: Attempted to use non-existent scale: %s for item %s [WMWARN09]\n", $this->name, $itemName));
         } else {
             return array(new WMColour(255, 255, 255), '', '');
         }
     }
     if ($isPercentage && $value > 100) {
         if ($nowarn_clipping == 0) {
             wm_warn("ColourFromValue: Clipped {$value}% to 100% for item {$itemName} [WMWARN33]\n");
         }
         $value = 100;
     }
     if ($isPercentage && $value < 0) {
         if ($nowarn_clipping == 0) {
             wm_warn("ColourFromValue: Clipped {$value}% to 0% for item {$itemName} [WMWARN34]\n");
         }
         $value = 0;
     }
     list($col, $key, $tag) = $this->findScaleHit($value);
     if (null === $col) {
         if ($nowarn_scalemisses == 0) {
             wm_warn("ColourFromValue: Scale {$scaleName} doesn't include a line for {$value}" . ($isPercentage ? "%" : "") . " while drawing item {$itemName} [WMWARN29]\n");
         }
         return array($this->scalemisscolour, '', '');
     }
     wm_debug("CFV {$itemName} {$scaleName} {$value} '{$tag}' {$key} " . $col->asConfig() . "\n");
     return array($col, $key, $tag);
 }
function calc_offset($offsetstring, $width, $height)
{
    if (preg_match("/^([-+]?\\d+):([-+]?\\d+)\$/", $offsetstring, $matches)) {
        wm_debug("Numeric Offset found\n");
        return array($matches[1], $matches[2]);
    } elseif (preg_match("/(NE|SE|NW|SW|N|S|E|W|C)(\\d+)?\$/i", $offsetstring, $matches)) {
        $multiply = 1;
        if (isset($matches[2])) {
            $multiply = intval($matches[2]) / 100;
            wm_debug("Percentage compass offset: multiply by {$multiply}");
        }
        $height = $height * $multiply;
        $width = $width * $multiply;
        switch (strtoupper($matches[1])) {
            case 'N':
                return array(0, -$height / 2);
                break;
            case 'S':
                return array(0, $height / 2);
                break;
            case 'E':
                return array(+$width / 2, 0);
                break;
            case 'W':
                return array(-$width / 2, 0);
                break;
            case 'NW':
                return array(-$width / 2, -$height / 2);
                break;
            case 'NE':
                return array($width / 2, -$height / 2);
                break;
            case 'SW':
                return array(-$width / 2, $height / 2);
                break;
            case 'SE':
                return array($width / 2, $height / 2);
                break;
            case 'C':
            default:
                return array(0, 0);
                break;
        }
    } elseif (preg_match("/(-?\\d+)r(\\d+)\$/i", $offsetstring, $matches)) {
        $angle = intval($matches[1]);
        $distance = intval($matches[2]);
        $x = $distance * sin(deg2rad($angle));
        $y = -$distance * cos(deg2rad($angle));
        return array($x, $y);
    } else {
        wm_warn("Got a position offset that didn't make sense ({$offsetstring}).");
        return array(0, 0);
    }
}
 function ReadData($targetstring, &$map, &$item)
 {
     global $config;
     $dsnames[IN] = "traffic_in";
     $dsnames[OUT] = "traffic_out";
     $data[IN] = NULL;
     $data[OUT] = NULL;
     $SQL[IN] = 'select null';
     $SQL[OUT] = 'select null';
     $rrdfile = $targetstring;
     if ($map->get_hint("rrd_default_in_ds") != '') {
         $dsnames[IN] = $map->get_hint("rrd_default_in_ds");
         wm_debug("Default 'in' DS name changed to " . $dsnames[IN] . ".\n");
     }
     if ($map->get_hint("rrd_default_out_ds") != '') {
         $dsnames[OUT] = $map->get_hint("rrd_default_out_ds");
         wm_debug("Default 'out' DS name changed to " . $dsnames[OUT] . ".\n");
     }
     $multiplier = 8;
     // default bytes-to-bits
     $inbw = NULL;
     $outbw = NULL;
     $data_time = 0;
     if (preg_match("/^(.*\\.rrd):([\\-a-zA-Z0-9_]+):([\\-a-zA-Z0-9_]+)\$/", $targetstring, $matches)) {
         $rrdfile = $matches[1];
         $dsnames[IN] = $matches[2];
         $dsnames[OUT] = $matches[3];
         wm_debug("Special DS names seen (" . $dsnames[IN] . " and " . $dsnames[OUT] . ").\n");
     }
     if (preg_match("/^rrd:(.*)/", $rrdfile, $matches)) {
         $rrdfile = $matches[1];
     }
     if (preg_match("/^gauge:(.*)/", $rrdfile, $matches)) {
         $rrdfile = $matches[1];
         $multiplier = 1;
     }
     if (preg_match("/^scale:([+-]?\\d*\\.?\\d*):(.*)/", $rrdfile, $matches)) {
         $rrdfile = $matches[2];
         $multiplier = $matches[1];
     }
     wm_debug("SCALING result by {$multiplier}\n");
     // try and make a complete path, if we've been given a clue
     // (if the path starts with a . or a / then assume the user knows what they are doing)
     if (!preg_match("/^(\\/|\\.)/", $rrdfile)) {
         $rrdbase = $map->get_hint('rrd_default_path');
         if ($rrdbase != '') {
             $rrdfile = $rrdbase . "/" . $rrdfile;
         }
     }
     $cfname = intval($map->get_hint('rrd_cf'));
     if ($cfname == '') {
         $cfname = 'AVERAGE';
     }
     $period = intval($map->get_hint('rrd_period'));
     if ($period == 0) {
         $period = 800;
     }
     $start = $map->get_hint('rrd_start');
     if ($start == '') {
         $start = "now-{$period}";
         $end = "now";
     } else {
         $end = "start+" . $period;
     }
     $use_poller_output = intval($map->get_hint('rrd_use_poller_output'));
     $nowarn_po_agg = intval($map->get_hint("nowarn_rrd_poller_output_aggregation"));
     $aggregatefunction = $map->get_hint('rrd_aggregate_function');
     if ($aggregatefunction != '' && $use_poller_output == 1) {
         $use_poller_output = 0;
         if ($nowarn_po_agg == 0) {
             wm_warn("Can't use poller_output for rrd-aggregated data - disabling rrd_use_poller_output [WMRRD10]\n");
         }
     }
     if ($use_poller_output == 1) {
         wm_debug("Going to try poller_output, as requested.\n");
         WeatherMapDataSource_rrd::wmrrd_read_from_poller_output($rrdfile, "AVERAGE", $start, $end, $dsnames, $data, $map, $data_time, $item);
     }
     // if poller_output didn't get anything, or if it couldn't/didn't run, do it the old-fashioned way
     // - this will still be the case for the first couple of runs after enabling poller_output support
     //   because there won't be valid data in the weathermap_data table yet.
     if ($dsnames[IN] != '-' && $data[IN] === NULL || $dsnames[OUT] != '-' && $data[OUT] === NULL) {
         if ($use_poller_output == 1) {
             wm_debug("poller_output didn't get anything useful. Kicking it old skool.\n");
         }
         if (file_exists($rrdfile) or file_exists($map->chdir . "/" . $rrdfile)) {
             wm_debug("RRD ReadData: Target DS names are " . $dsnames[IN] . " and " . $dsnames[OUT] . "\n");
             $values = array();
             if (1 == 0 && extension_loaded('RRDTool')) {
                 WeatherMapDataSource_rrd::wmrrd_read_from_php_rrd($rrdfile, $cfname, $start, $end, $dsnames, $data, $map, $data_time, $item);
             } else {
                 if ($aggregatefunction != '') {
                     WeatherMapDataSource_rrd::wmrrd_read_from_real_rrdtool_aggregate($rrdfile, $cfname, $aggregatefunction, $start, $end, $dsnames, $data, $map, $data_time, $item);
                 } else {
                     // do this the tried and trusted old-fashioned way
                     WeatherMapDataSource_rrd::wmrrd_read_from_real_rrdtool($rrdfile, $cfname, $start, $end, $dsnames, $data, $map, $data_time, $item);
                 }
             }
         } else {
             wm_warn("Target {$rrdfile} doesn't exist. Is it a file? [WMRRD06]\n");
         }
     }
     // if the Locale says that , is the decimal point, then rrdtool
     // will honour it. However, floatval() doesn't, so let's replace
     // any , with . (there are never thousands separators, luckily)
     //
     if ($data[IN] !== NULL) {
         $data[IN] = floatval(str_replace(",", ".", $data[IN]));
         $data[IN] = $data[IN] * $multiplier;
     }
     if ($data[OUT] !== NULL) {
         $data[OUT] = floatval(str_replace(",", ".", $data[OUT]));
         $data[OUT] = $data[OUT] * $multiplier;
     }
     wm_debug("RRD ReadData: Returning (" . ($data[IN] === NULL ? 'NULL' : $data[IN]) . "," . ($data[OUT] === NULL ? 'NULL' : $data[OUT]) . ",{$data_time})\n");
     return array($data[IN], $data[OUT], $data_time);
 }
 public function createHTML($htmlFilename)
 {
     $fileHandle = @fopen($htmlFilename, 'w');
     if ($fileHandle != false) {
         fwrite($fileHandle, $this->mapObject->makeHTML('weathermap_' . $this->filehash . '_imap'));
         fclose($fileHandle);
         wm_debug("Wrote HTML to {$htmlFilename}");
     } else {
         if (file_exists($htmlFilename)) {
             wm_warn("Failed to overwrite {$htmlFilename} - permissions of existing file are wrong? [WMPOLL02]\n");
         } else {
             wm_warn("Failed to create {$htmlFilename} - permissions of output directory are wrong? [WMPOLL03]\n");
         }
     }
 }