statement for forecast icon // $forecasttemp[$i] = Red Hi, Blue Lo temperature(s) // $forecasttext[$i] = Summary of forecast for icon // // $forecastdays[$n] = Day/night day of week for detail forecast // $forecastdetail[$n] = detailed forecast text // // Also returned are these useful variables filled in: // $title = updated/issued text in language selected // $textfcsthead = 'Current Forecast' or 'Textes des prévisions' // // $weather = fully formed html table with two rows of Icons and text // $textforecast = fully formed
with text forecast as
// // $alertstring = styled box with hotlinks to advisories/warnings // $currentConditions = table with current conditions at EC forecast site // $almanac = styled box with Average/Extreme data for the EC forecast site (V5.00) // $forecast24h = styled table with rolling 24hr forecast details (V5.00) // // you can set $printIT = false; and just echo/print the variables above // in your page to precisely position them. Or use $forecast[$i] to // print just one of the items where you need it. // // I'd recommend you NOT change any of the main code. You can do styling // for the results by using CSS. See the companion test page // ec-forecast-testpage.php to demonstrate CSS styling of results. // //--------------------------------------------------------------------------------------------- // ---------- main code ----------------- if (isset($_REQUEST['sce']) and strtolower($_REQUEST['sce']) == 'view' ) { //--self downloader -- $filenameReal = __FILE__; $download_size = filesize($filenameReal); header('Pragma: public'); header('Cache-Control: private'); header('Cache-Control: no-cache, must-revalidate'); header("Content-type: text/plain,charset=ISO-8859-1"); header("Accept-Ranges: bytes"); header("Content-Length: $download_size"); header('Connection: close'); readfile($filenameReal); exit; } // initialize arrays and expected variables $conditions = array(); $forecasticon = array(); $forecasttemp = array(); $forecasttemptype = array(); $forecasttempabn = array(); $forecasttempHigh = array(); $forecasttempLow = array(); $forecastpop = array(); $forecasttitles = array(); $forecast = array(); $forecasttemptxt = array(); $forecastrealday = array(); $forecasthours = array(); $updated = 'unknown'; $currentConditions = ''; // HTML for table of current conditions $alerttype = array(); $alerts = array(); $alertlinks = array(); $alertlinkstext = array(); $alertstring = ''; $forecast24h = ''; // HTML for 24hour forecast table $almanac = ''; // HTML for almanac table $charsetInput = 'UTF-8'; // they claim ISO-8859-1, but it's really UTF-8 in French XML. Sigh. if (! isset($PHP_SELF) ) { $PHP_SELF = $_SERVER['PHP_SELF']; } if(!function_exists('langtransstr')) { // shim function if not running in template set function langtransstr($input) { return($input); } } $t = pathinfo($PHP_SELF); // get our program name for the HTML comments $Program = $t['basename']; $Status = "\n"; if (! isset($doInclude)) { $doInclude = false ; } if( (isset($_REQUEST['inc']) and strtolower($_REQUEST['inc']) == 'y') or $doInclude ) {$printIt = false;} if(!isset($_REQUEST['lang'])) { $_REQUEST['lang'] = '';} // overrides from calling page if(isset($doPrint)) {$printIt = $doPrint; } if(isset($doShowConditions)) {$showConditions = $doShowConditions;} if(isset($doShowAlmanac)) {$showAlmanac = $doShowAlmanac; } if(isset($doShow24hour)) {$show24hour = $doShow24hour; } if(isset($_REQUEST['lang'])) { $Lang = strtolower($_REQUEST['lang']); } else { $Lang = ''; } if (isset($doLang)) {$Lang = $doLang;}; if (! $Lang) {$Lang = $defaultLang;}; $doDebug = (isset($_REQUEST['debug']) and strtolower($_REQUEST['debug']) == 'y')?true:false; if ($Lang == 'fr') { $LMode = 'f'; $ECNAME = "Environnement Canada"; $ECHEAD = 'Prévisions'; $abnormalString = '

* - Indique une tendance inverse de la température.

' . "\n"; } else { $Lang = 'en'; $LMode = 'e'; $ECNAME = "Environment Canada"; $ECHEAD = 'Forecast'; $abnormalString = '

* - Denotes an abnormal temperature trend.

' . "\n"; } // get the selected forecast location code $haveIndex = '0'; if (!empty($_GET['z']) && preg_match("/^[0-9]+$/i", htmlspecialchars($_GET['z']))) { $haveIndex = htmlspecialchars(strip_tags($_GET['z'])); // valid zone syntax from input } if(!isset($ECforecasts[0])) { // print "\n"; $ECforecasts = array("|$ECURL"); // create default entry } // print "\n"; // Set the default zone. The first entry in the $SITE['ECforecasts'] array. list($Nl,$Nn) = explode('|',$ECforecasts[0].'|||'); $FCSTlocation = $Nl; $ECURL = $Nn; if(!isset($ECforecasts[$haveIndex])) { $haveIndex = 0; } // locations added to the drop down menu and set selected zone values $dDownMenu = ''; for ($m=0;$m".langtransstr($Nlocation)."\n"; } // build the drop down menu $ddMenu = ''; // create menu if at least two locations are listed in the array if (isset($ECforecasts[0]) and isset($ECforecasts[1])) { $ddMenu .= '

'; } if(file_exists('ec-forecast-lookup.txt')) { include_once('ec-forecast-lookup.txt'); // load lookup table } else { print $Status; print "

ec-forecast.php ERROR: this script requires 'ec-forecast-lookup.txt' in the same directory, and it is not available.

\n"; return(false); } /* // we need to use an array like this, but sometimes this script will not be // saved as ASCII/ISO-8859-1, and the array of characters gets garbled. $trantab = array( 'ISO' => array('À','à','Â','â','Æ','æ', 'Ç','ç', 'É','é','È','è','Ê','ê','Ë','ë', 'Î','î','Ï','ï', 'Ô','ô','Œ','œ', 'Ù','ù','Û','û','Ü','ü', 'Ÿ','ÿ'), // UTF-8 characters represented as ISO-8859-1 'UTF' => array('À','à','Â','â','Æ','æ', 'Ç','ç', 'É','é','È','è','Ê','ê','Ë','ë', 'ÃŽ','î','Ã','ï', 'Ô','ô','Å’','Å“', 'Ù','ù','Û','û','Ãœ','ü', 'Ÿ','ÿ'), ); // so we used the following to encode it: $serialized = serialize($trantab); $base64 = base64_encode($serialized); // and used the output of the base64_encode in the define() statement below. // then we reconstitute the array with perfect fidelity using // $trantab = unserialize(base64_decode(ISO_UTF_ARRAY)); // below. */ if(!defined('ISO_UTF_ARRAY')) { define('ISO_UTF_ARRAY', 'YToyOntzOjM6IklTTyI7YTozMjp7aTowO3M6MToiwCI7aToxO3M6MToi4CI7aToyO3M6MToi wiI7aTozO3M6MToi4iI7aTo0O3M6MToixiI7aTo1O3M6MToi5iI7aTo2O3M6MToixyI7aTo3 O3M6MToi5yI7aTo4O3M6MToiySI7aTo5O3M6MToi6SI7aToxMDtzOjE6IsgiO2k6MTE7czox OiLoIjtpOjEyO3M6MToiyiI7aToxMztzOjE6IuoiO2k6MTQ7czoxOiLLIjtpOjE1O3M6MToi 6yI7aToxNjtzOjE6Is4iO2k6MTc7czoxOiLuIjtpOjE4O3M6MToizyI7aToxOTtzOjE6Iu8i O2k6MjA7czoxOiLUIjtpOjIxO3M6MToi9CI7aToyMjtzOjE6IowiO2k6MjM7czoxOiKcIjtp OjI0O3M6MToi2SI7aToyNTtzOjE6IvkiO2k6MjY7czoxOiLbIjtpOjI3O3M6MToi+yI7aToy ODtzOjE6ItwiO2k6Mjk7czoxOiL8IjtpOjMwO3M6MToinyI7aTozMTtzOjE6Iv8iO31zOjM6 IlVURiI7YTozMjp7aTowO3M6Mjoiw4AiO2k6MTtzOjI6IsOgIjtpOjI7czoyOiLDgiI7aToz O3M6Mjoiw6IiO2k6NDtzOjI6IsOGIjtpOjU7czoyOiLDpiI7aTo2O3M6Mjoiw4ciO2k6Nztz OjI6IsOnIjtpOjg7czoyOiLDiSI7aTo5O3M6Mjoiw6kiO2k6MTA7czoyOiLDiCI7aToxMTtz OjI6IsOoIjtpOjEyO3M6Mjoiw4oiO2k6MTM7czoyOiLDqiI7aToxNDtzOjI6IsOLIjtpOjE1 O3M6Mjoiw6siO2k6MTY7czoyOiLDjiI7aToxNztzOjI6IsOuIjtpOjE4O3M6Mjoiw48iO2k6 MTk7czoyOiLDryI7aToyMDtzOjI6IsOUIjtpOjIxO3M6Mjoiw7QiO2k6MjI7czoyOiLFkiI7 aToyMztzOjI6IsWTIjtpOjI0O3M6Mjoiw5kiO2k6MjU7czoyOiLDuSI7aToyNjtzOjI6IsOb IjtpOjI3O3M6Mjoiw7siO2k6Mjg7czoyOiLDnCI7aToyOTtzOjI6IsO8IjtpOjMwO3M6Mjoi xbgiO2k6MzE7czoyOiLDvyI7fX0='); } //reconstitute our trantab from the base64 encoded serialized value //so we won't have issues if someone inadvertantly saves this script as // UTF-8 instead of ASCII/ISO-8859-1 // global $trantab; $trantab = unserialize(base64_decode(ISO_UTF_ARRAY)); // support both french and english caches $ECURL = preg_replace('|weatheroffice|i','weather',$ECURL); // autochange Old EC URL if present $ECURL = preg_replace('|_.\.html|',"_$LMode.html",$ECURL); $ECURL = preg_replace('|http://|i','https://',$ECURL); // force HTTPS access // force refresh of cache if (isset($_REQUEST['cache'])) { $refetchSeconds = 1; } // refresh cached copy of page if needed // fetch/cache code by Tom at carterlake.org if($Lang == 'fr' and preg_match('|weather.gc.ca|i',$ECURL)) { $ECURL = str_replace('weather.gc.ca','meteo.gc.ca',$ECURL); $Status .= "\n"; } if($Lang == 'en' and preg_match('|meteo.gc.ca|i',$ECURL)) { $ECURL = str_replace('meteo.gc.ca','weather.gc.ca',$ECURL); $Status .= "\n"; } // NEW with V5.00: lookup/convert EC page URL to XML filename URL that we load/cache list($ECXMLURL,$ECpgcode,$EClang,$ECunits,$ECXMLbase) = ECF_XML_URL_info($ECURL); if($ECXMLURL === false) { print $Status; print "

ec-forecast.php ERROR: '$FCSTlocation' has an invalid EC page URL '$ECURL'.
The corresponding XML weather data file is not found for page ID='$ECpgcode'.

\n"; return(false); } // unique cache per language used $cacheName = preg_replace('|\.txt|is',"-$haveIndex-$ECpgcode-$ECXMLbase-$Lang.txt",$cacheName); $cacheName = $cacheFileDir.$cacheName; $cacheAge = (file_exists($cacheName))?time()-filemtime($cacheName):9999999; //--------------------------------------------------------------------------------------------- // load the XML from the EC or cache $total_time = 0.0; if (file_exists($cacheName) and $cacheAge < $refetchSeconds) { $Status .= "\n"; $content = file_get_contents($cacheName); } else { $Status .= "\n"; $Status .= "\n"; $time_start = ECF_fetch_microtime(); $rawhtml = ECF_fetch_URL($ECXMLURL,false); $time_stop = ECF_fetch_microtime(); $total_time += ($time_stop - $time_start); $time_fetch = sprintf("%01.3f",round($time_stop - $time_start,3)); $RC = ''; if (preg_match("|^HTTP\/\S+ (.*)\r\n|",$rawhtml,$matches)) { $RC = trim($matches[1]); } $Status .= "\n"; if(preg_match('|30\d |i',$RC)) { //oops.. a redirect.. retry the new location sleep(2); // wait two seconds and retry preg_match('|Location: (.*)\r\n|',$rawhtml,$matches); if(isset($matches[1])) {$ECURL = $matches[1];} // update the URL $time_start = ECF_fetch_microtime(); $rawhtml = ECF_fetch_URL($ECXMLURL,false); $time_stop = ECF_fetch_microtime(); $total_time += ($time_stop - $time_start); $time_fetch = sprintf("%01.3f",round($time_stop - $time_start,3)); $RC = ''; if (preg_match("|^HTTP\/\S+ (.*)\r\n|",$rawhtml,$matches)) { $RC = trim($matches[1]); } $Status .= "\n"; } $i = strpos($rawhtml,"\r\n\r\n"); $headers = substr($rawhtml,0,$i); $content = substr($rawhtml,$i+4); if(preg_match('|200|',$RC)) { // good return so save off the cache $fp = fopen($cacheName, "w"); if ($fp) { // $site = utf8_decode($site); // convert to ISO-8859-1 for use (like old EC site) $write = fputs($fp, $content); fclose($fp); $Status .= "\n"; } else { $Status .= "\n"; } } else { $Status .= "\n"; $Status .= "\n"; } // end of cache save } // load the XML into an array if(! file_exists($cacheName)) { print $Status; print "\n"; return (false); } $doIconv = ($charsetInput == $charsetOutput)?false:true; // only do iconv() if sets are different $Status .= "\n"; // Set up the built-in legends to use in both English and French $LegendsLang = array( // English 'en' => array( 'citycondition' => 'Condition', 'obsdate' => 'Date', 'cityobserved' => 'Observed at', 'temperature' => 'Temperature', 'pressure' => 'Pressure', 'tendency' => 'Tendency', 'humidity' => 'Humidity', 'windchill' => 'Wind
Chill', 'windchillabbr' => 'Wind Chill', 'humidex' => 'Humidex', 'visibility' => 'Visibility', 'dewpoint' => 'Dew point', 'wind' => 'Wind', 'gust' => 'gust', 'calm' => 'calm', 'aqhi' => 'Air Quality Health Index', 'maxtemp' => 'Max', 'mintemp' => 'Min', 'maxmin' => 'Normals', 'precip' => 'Total Precipitation', 'precip' => 'Rainfall', 'snow' => 'Snowfall', 'sunrise' => 'Sunrise', 'sunset' => 'Sunset', 'moonrise' => 'Moonrise', 'moonset' => 'Moonset', 'obs' => 'Currently', 'yday' => 'Yesterday', 'norms' => 'Normals', 'issued' => 'Issued', 'extremeMax' => 'Highest temperature', 'extremeMin' => 'Lowest temperature', 'normalMax' => 'Average high', 'normalMin' => 'Average low', 'normalMean' => 'Average', 'extremeRainfall' => 'Greatest rainfall', 'extremeSnowfall' => 'Greatest snowfall', 'extremePrecipitation' => 'Greatest precipitation', 'extremeSnowOnGround' => 'Most snow on the ground', 'almanacpop' => 'Monthly frequency of precipitation', 'avgexhead' => 'Averages and extremes', 'na' => 'n/a', 'forecast24' => '24 Hour Forecast', 'datetime' => 'Date/Time', 'temperature' => 'Temp.', 'weatherconds' => 'Weather Conditions', 'lop' => 'LOP †', 'lopnote' => '† Likelihood of Precipitation (LOP) as described in the public forecast '. 'as a chance of measurable precipitation for a period of time.
' . '  Nil: 0%
' . '  Low: 40% or below
' . '  Medium: 60% or 70%
' . '  High: Above 70%
', 'nonsig' => '‡ Value not significant ', ), 'fr'=> array( // French 'citycondition' => 'Condition', 'obsdate' => 'Date', 'cityobserved' => 'Enregistrées à', 'temperature' => 'Température', 'pressure' => 'Pression', 'tendency' => 'Tendance', 'humidity' => 'Humidité', 'windchill' => 'Refr.
éolien', 'windchillabbr' => 'refroidissement éolien', 'humidex' => 'Humidex', 'visibility' => 'Visibilité', 'dewpoint' => 'Point de rosée', 'wind' => 'Vent', 'calm' => 'calme', 'gust' => 'rafale', 'aqhi' => 'Cote air santé', 'maxmin' => 'Normales', 'maxtemp' => 'Max', 'mintemp' => 'Min', 'precip' => 'Précipitation totale', 'precip' => 'Pluie', 'snow' => 'Neige', 'sunrise' => 'Lever', 'sunset' => 'Coucher', 'moonrise' => 'Lever de la lune', 'moonset' => 'Coucher de la lune', 'obs' => 'Conditions actuelles', 'yday' => 'Données d\'hier', 'norms' => 'Normales', 'issued' => 'Émises à', 'extremeMax' => 'Température la plus élevée', 'extremeMin' => 'Température la plus basse', 'normalMax' => 'Température maximale moyenne', 'normalMin' => 'Température minimale moyenne', 'normalMean' => 'Température moyenne', 'extremeRainfall' => 'Pluie maximale', 'extremeSnowfall' => 'Neige maximale', 'extremePrecipitation' => 'Précipitation maximale', 'extremeSnowOnGround' => 'Maximum de neige au sol', 'almanacpop' => 'Fréquence mensuelle de précipitation', 'avgexhead' => 'Moyennes et extrêmes', 'na' => 'n.d.', 'forecast24' => 'Prévisions 24 heures', 'datetime' => 'Date/Heure', 'temperature' => 'Temp', 'weatherconds' => 'Condition météo', 'lop' => 'EdP †', 'wind' => 'Vents', 'lopnote' => '† Éventualité de précipitation (EdP) mesurable, indiqué dans la prévision '. 'publique comme probabilité de précipitation pour une période de temps.
' . '  Nulle: 0%
' . '  Basse: 40% et moins
' . '  Moyenne: 60% ou 70%
' . '  Élevée : 80% et plus
', 'nonsig' => '‡ Valeur non significative', ) ); $Legends = $LegendsLang[$Lang]; // use the legends based on language choice if($doIconv) { // put legends in UTF-8 for later conversion $TLegends = array(); foreach ($Legends as $key => $val) { $nval = iconv('ISO-8859-1','UTF-8//TRANSLIT',$val); $TLegends[$key] = $nval; } $Legends = $TLegends; $Status .= "\n"; } $MonthNamesLang = array( // easier to use this than switching locales... 'en' => array( '01' => 'January', '02' => 'February', '03' => 'March', '04' => 'April', '05' => 'May', '06' => 'June', '07' => 'July', '08' => 'August', '09' => 'September', '10' => 'October', '11' => 'November', '12' => 'December' ), 'fr' => array( '01' => 'janvier', '02' => 'février', '03' => 'mars', '04' => 'avril', '05' => 'mai', '06' => 'juin', '07' => 'juillet', '08' => 'août', '09' => 'septembre', '10' => 'octobre', '11' => 'novembre', '12' => 'décembre' ) ); $MonthNames = $MonthNamesLang[$Lang]; // month names (for 24hr forecast) based on language if($doIconv) { // put months in UTF-8 $TMonths = array(); foreach ($MonthNames as $key => $val) { $nval = iconv('ISO-8859-1','UTF-8//TRANSLIT',$val); $TMonths[$key] = $nval; } $MonthNames = $TMonths; $Status .= "\n"; } // load the XML forecast into an array for processing $xml = simplexml_load_string($content); //----------- handle the city conditions ----------------------------------------- $X = $xml->currentConditions; /* SimpleXMLElement Object ( [station] => Aéroport int. Munro de Hamilton [dateTime] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [name] => observation [zone] => UTC [UTCOffset] => 0 ) [year] => 2017 [month] => 09 [day] => 19 [hour] => 20 [minute] => 00 [timeStamp] => 20170919200000 [textSummary] => 19 septembre 2017 20h00 UTC ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [name] => observation [zone] => HAE [UTCOffset] => -4 ) [year] => 2017 [month] => 09 [day] => 19 [hour] => 16 [minute] => 00 [timeStamp] => 20170919160000 [textSummary] => 19 septembre 2017 16h00 HAE ) ) [condition] => Partiellement nuageux [iconCode] => 02 [temperature] => 24.9 [dewpoint] => 19.7 [humidex] => 32 [pressure] => 101.5 [visibility] => 24.1 [relativeHumidity] => 73 [wind] => SimpleXMLElement Object ( [speed] => 9 [gust] => SimpleXMLElement Object ( [@attributes] => Array ( [unitType] => metric [units] => km/h ) ) [direction] => E [bearing] => 83.0 ) )*/ // NOTE: we'll store the current conditions in the $conditions array for later assembly if(isset($X->station)) { // got an observation.. format it $conditions['cityobserved'] = $Legends['cityobserved'] . ': '. (string)$X->station . ''; $obsdate = (string)$X->dateTime[1]->textSummary; if($doIconv) { $obsdate = iconv($charsetInput,$charsetOutput.'//TRANSLIT',ECF_UTF_CLEANUP($obsdate)); } $conditions['obsdate'] = $Legends['obsdate'] .': '. $obsdate . ''; if(isset($X->condition) and strlen((string)$X->condition) > 0) { $conditions['citycondition'] = ''. (string)$X->condition . ''; $conditions['icon'] = (string)$X->iconCode . $iconTypeEC; } $conditions['pressure'] = $Legends['pressure'] . ': '. (string)$X->pressure . ' kPa'; $conditions['tendency'] = $Legends['tendency'] . ': '. (string)$X->pressure['tendency'] . ''; $conditions['temperature'] = $Legends['temperature'] . ': '. (string)$X->temperature . ' °C'; if(strlen((string)$X->dewpoint) > 0) { $conditions['dewpoint'] = $Legends['dewpoint'] . ': '. (string)$X->dewpoint . ' °C'; } if(strlen((string)$X->relativeHumidity) > 0) { $conditions['humidity'] = $Legends['humidity'] . ': '. (string)$X->relativeHumidity . ' %'; } $conditions['wind'] = $Legends['wind'] . ': '; if($X->wind->speed > 0) { $conditions['wind'] .= (string)$X->wind->direction . ' ' . (string)$X->wind->speed; if(isset($X->wind->gust) and strlen((string)$X->wind->gust)>0) { $conditions['wind'] .= ' ' . $Legends['gust'] . ' ' . (string)$X->wind->gust; } $conditions['wind'] .= ' km/h'; } else { $conditions['wind'] .= $Legends['calm']; } $conditions['wind'] .= ''; if(strlen((string)$X->humidex) > 0) { $conditions['humidex'] = $Legends['humidex'] . ': '. (string)$X->humidex . ''; } if(strlen((string)$X->windChill) > 0) { $tl = str_replace('
',' ',$Legends['windchill']); $conditions['windchill'] = $tl . ': '. (string)$X->windChill . ''; } if(strlen((string)$X->visibility) > 0) { $conditions['visibility'] = $Legends['visibility'] . ': '. (string)$X->visibility . ' km'; } } // extract the updated time and 'normals' $X = $xml->forecastGroup; if(isset($X->regionalNormals->temperature[1])) { $conditions['maxmin'] = $Legends['maxmin'] . ': Max ' . (string)$X->regionalNormals->temperature[0] . '°C Min ' . (string)$X->regionalNormals->temperature[1] . '°C'; } // extract the yesterday values $X = $xml->yesterdayConditions; if(isset($X->temperature[1])) { $conditions['ydayheading'] = $Legends['yday']; $conditions['ydaymaxtemp'] = $Legends['maxtemp'] . ': ' . (string)$X->temperature[0] . ' °C'; $conditions['ydaymintemp'] = $Legends['mintemp'] . ': ' . (string)$X->temperature[1] . ' °C'; $conditions['ydayprecip'] = $Legends['precip'] . ': ' . (string)$X->precip . ' mm'; } // extract the sunrise/sunset data $X = $xml->riseSet; if(isset($X->dateTime[1]->hour)) { $conditions['sunrise'] = $Legends['sunrise'] . ': ' . (string)$X->dateTime[1]->hour . ':' . (string)$X->dateTime[1]->minute . ''; $conditions['sunset'] = $Legends['sunset'] . ': ' . (string)$X->dateTime[3]->hour . ':' . (string)$X->dateTime[3]->minute . ''; } /* 28.9 0.6 19.5 9.0 14.3 44.5 0.0 44.5 0.0 37.0 */ //--------------------------------------------------------------------------------------------- // process the almanac data if($doDebug) {$Status .= "\n";} if(isset($xml->almanac->temperature[0])) { foreach ($xml->almanac->temperature as $i => $X) { $item = (string)$X['class']; $unit = (string)$X['units']; $period = empty($X['period'])?'':(string)$X['period']; $year = empty($X['year'])?'':(string)$X['year']; $value = (string)$X; if(empty($value)) { $conditions[$item] = $Legends['na'].'||'; } else { $conditions[$item] = "$value $unit|$period|$year"; } if($doDebug) { $Status .= "\n"; } } } if(isset($xml->almanac->precipitation[0])) { foreach ($xml->almanac->precipitation as $i => $X) { $item = (string)$X['class']; $unit = (string)$X['units']; $period = empty($X['period'])?'':(string)$X['period']; $year = empty($X['year'])?'':(string)$X['year']; $value = (string)$X; if(empty($value)) { $conditions[$item] = $Legends['na'].'||'; } else { $conditions[$item] = "$value $unit|$period|$year"; } if($doDebug) { $Status .= "\n"; } } } if(isset($xml->almanac->pop)) { $conditions['almanacpop'] = (string)$xml->almanac->pop; if(empty($conditions['almanacpop'])) { $conditions['almanacpop'] = $Legends['na'].'||'; } else { $conditions['almanacpop'] .= ' %||'; } } // change conditions back to ISO-8859-1 if needed if($doIconv) { foreach ($conditions as $key => $val) { if($key == 'obsdate') {continue;} // it's already in iso-8859-1 strangely $conditions[$key] = iconv($charsetInput,$charsetOutput.'//TRANSLIT',$val); } } $Status .= "\n"; /* Old example (in English) ( [cityobserved] => Observed at: Montréal-Trudeau Int'l Airport [obsdate] => Date: 1:00 PM EDT Thursday 27 October 2016 [citycondition] => Mostly Cloudy [pressure] => Pressure: 102.9 kPa [tendency] => Tendency: Falling [temperature] => Temperature: 4.8°C [dewpoint] => Dew point: -2.3°C [humidity] => Humidity: 60% [wind] => Wind: E 22 km/h [visibility] => Visibility: 24 km [maxmin] => Normals: Max 9°C. Min 1°C. [sunrise] => Sunrise: 7:27 EDT [sunset] => Sunset: 17:49 EDT [icon] => 03.png [ydayheading] => Yesterday's Data [ydaymaxtemp] => Max: 3.4°C [ydaymintemp] => Min: -0.8°C [ydayprecip] => Rainfall: Trace [ydaysnow] => Snowfall: 0.1 cm Note: moonrise/moonset, aqhi, tendency no longer available Array (new from XML, French example) ( [cityobserved] => Observed at: Hamilton Munro Int'l Airport [obsdate] => Date: Friday September 22, 2017 at 17:00 EDT [citycondition] => Mainly Sunny [pressure] => Pressure: 101.9 kPa [tendency] => Tendency: falling [temperature] => Temperature: 25.4 °C [dewpoint] => Dew point: 16.0 °C [humidity] => Humidity: 55 % [wind] => Wind: ENE 11 km/h [humidex] => Humidex: 30 [visibility] => Visibility: 19.3 km [icon] => 01.png [maxmin] => Normals: Max 19°C Min 9°C [ydayheading] => Yesterday [ydaymaxtemp] => Max: 27.0 °C [ydaymintemp] => Min: 14.2 °C [ydayprecip] => Rainfall: 0.0 mm [sunrise] => Sunrise: 07:07 [sunset] => Sunset: 19:18 [extremeMax] => 28.9 C|1960-2011|1965 [extremeMin] => 0.6 C|1960-2011|1999 [normalMax] => 19.5 C|| [normalMin] => 9.0 C|| [normalMean] => 14.3 C|| [extremeRainfall] => 44.5 mm|1960-2011|1989 [extremeSnowfall] => 0.0 cm|1960-2011|1960 [extremePrecipitation] => 44.5 mm|1960-2011|1989 [extremeSnowOnGround] => 0.0 cm|1970-2010|1970 [almanacpop] => 37.0|| ) */ //--------------------------------------------------------------------------------------------- // Process the Hourly Forecast (if availablel) /* 2017 09 25 15 00 20170925150000 Monday September 25, 2017 at 15:00 UTC 2017 09 25 11 00 20170925110000 Monday September 25, 2017 at 11:00 EDT Mainly sunny 01 30 0 38 10 SE */ if(isset($xml->hourlyForecastGroup)) { $UTCOffset = (integer)$xml->hourlyForecastGroup->dateTime[1]['UTCOffset']; $TZabbr = (string)$xml->hourlyForecastGroup->dateTime[1]['zone']; $UOMTempUsed = "°".(string)$xml->hourlyForecastGroup->hourlyForecast[0]->temperature['units']; $UOMWindUsed = (string)$xml->hourlyForecastGroup->hourlyForecast[0]->wind->speed['units']; $n = 0; $forecasthours['haveWindChill'] = false; // assume no Humidex found $forecasthours['haveHumidex'] = false; // assume no WindChill found $forecasthours['TZ'] = $TZabbr; $forecasthours['tempUOM'] = $UOMTempUsed; $forecasthours['windUOM'] = $UOMWindUsed; foreach ($xml->hourlyForecastGroup->hourlyForecast as $i => $X) { $forecasthours[$n]['UTCstring'] = (string)$X['dateTimeUTC']; $tDateTime = gmdate('Y-m-d H:i', ECF_get_time( $forecasthours[$n]['UTCstring'], $UTCOffset)); list($forecasthours[$n]['date'],$forecasthours[$n]['time']) = explode(' ',$tDateTime); list($forecasthours[$n]['year'],$tM,$forecasthours[$n]['day']) = explode('-',$forecasthours[$n]['date']); //$Status .= "\n"; $forecasthours[$n]['month'] = $tM; $forecasthours[$n]['monthname'] = $MonthNames[$tM]; if($doIconv) { $forecasthours[$n]['monthname'] = iconv($charsetInput,$charsetOutput.'//TRANSLIT', $forecasthours[$n]['monthname']); } $forecasthours[$n]['day'] = preg_replace('|^0|','',$forecasthours[$n]['day']); $forecasthours[$n]['TZ'] = $TZabbr; $forecasthours[$n]['cond'] = (string)$X->condition; if($doIconv) { $forecasthours[$n]['cond'] = iconv($charsetInput,$charsetOutput.'//TRANSLIT', $forecasthours[$n]['cond']); } $forecasthours[$n]['icon'] = ECF_replace_icon((string)$X->iconCode,(string)$X->lop); $forecasthours[$n]['lop'] = (string)$X->lop['category']; // likelyhood of precipitation if($doIconv) { $forecasthours[$n]['lop'] = iconv($charsetInput,$charsetOutput.'//TRANSLIT', $forecasthours[$n]['lop']); } $forecasthours[$n]['pop'] = (string)$X->lop; // actual PoP if any $forecasthours[$n]['temp'] = (string)$X->temperature; $forecasthours[$n]['wind'] = (string)$X->wind->direction." ".(string)$X->wind->speed; if(isset($X->wind->gust) and strlen((string)$X->wind->gust)>0) { $forecasthours[$n]['wind'] .= ' ' . $Legends['gust'] . ' ' . (string)$X->wind->gust; } if(!empty($X->windChill)) { $forecasthours[$n]['windchill'] = (string)$X->windChill; $forecasthours['haveWindChill'] = true; } if(!empty($X->humidex)) { $forecasthours[$n]['humidex'] = (string)$X->humidex; $forecasthours['haveHumidex'] = true; } $n++; } } // end Hourly Forecast processing if($doDebug) { $Status .= "\n"; $Status .= "\n"; } //--------------------------------------------------------------------------------------------- // process the forecast days $i = 0; $foundAbnormal = 0; // No abnormal indicators in XML (so far) $alertstring = ''; // get forecast issued date if(isset($xml->forecastGroup->dateTime[1]->textSummary)) { $updated = $Legends['issued'].': '.(string)$xml->forecastGroup->dateTime[1]->textSummary; if($doIconv) { $updated = iconv($charsetInput,$charsetOutput.'//TRANSLIT',ECF_UTF_CLEANUP($updated)); } $Status .= "\n"; } // get the official location name if(isset($xml->location->name)) { $title = (string)$xml->location->name . ', ' . strtoupper((string)$xml->location->province['code']); if($doIconv) { $title = iconv($charsetInput,$charsetOutput.'//TRANSLIT',$title); } } // process the forecast periods foreach ($xml->forecastGroup->forecast as $idx => $X) { /* [period] => ce soir et cette nuit [textSummary] => Partiellement nuageux avec 40 pour cent de probabilité d'averses. Risque d'un orage tôt ce soir. Nappes de brouillard se formant au cours de la nuit. Minimum 17. [cloudPrecip] => SimpleXMLElement Object ( [textSummary] => Partiellement nuageux avec 40 pour cent de probabilité d'averses. Risque d'un orage tôt ce soir. ) [abbreviatedForecast] => SimpleXMLElement Object ( [iconCode] => 39 [pop] => 40 [textSummary] => Possibilité d'averses ) [temperatures] => SimpleXMLElement Object ( [textSummary] => Minimum 17. [temperature] => 17 ) [winds] => SimpleXMLElement Object ( ) [precipitation] => SimpleXMLElement Object ( [textSummary] => SimpleXMLElement Object ( ) [precipType] => pluie ) [visibility] => SimpleXMLElement Object ( [otherVisib] => SimpleXMLElement Object ( [@attributes] => Array ( [cause] => other ) [textSummary] => Nappes de brouillard se formant au cours de la nuit. ) ) [relativeHumidity] => 90 ) */ $forecasticon[$i] = (string)$X->abbreviatedForecast->iconCode; $forecasttext[$i] = (string)$X->abbreviatedForecast->textSummary; $forecastpop[$i] = (string)$X->abbreviatedForecast->pop; $forecasticon[$i] = ECF_replace_icon($forecasticon[$i],$forecastpop[$i]); $tSummary = (string)$X->temperatures->textSummary; $forecasttemp[$i] = (string)$X->temperatures->temperature; $tAbn = ''; $forecasttempabn[$i] = ''; if(preg_match('!( rising | falling | hausse | baisse )!i',$tSummary)) { $tAbn = ' *'; $foundAbnormal++; } $forecasttemptype[$i] = strtolower(substr((string)$X->temperatures->temperature['class'],0,3)); $forecasttemptype[$i] = str_replace('low','min',$forecasttemptype[$i]); $forecasttemptype[$i] = str_replace('hig','max',$forecasttemptype[$i]); $forecasttempabn[$i] = $tAbn; $t = ucfirst($forecasttemptype[$i]).': '.$forecasttemp[$i].'°C'; $t .= $forecasttempabn[$i]."
"; $forecasttemp[$i] = $t; $forecasttitles[$i] = (string)$X->period; $forecastdetail[$i] = (string)$X->textSummary; $forecastdays[$i] = (string)$X->period['textForecastName']; //print "i=$i\n".print_r($X,true)."\n--------\n"; $i++; } // fix the charset if needed if($doIconv) { for ($i=0;$i\n"; $Status .= "\n"; $Status .= "\n"; $Status .= "\n"; $Status .= "\n"; $Status .= "\n"; $Status .= "\n"; $Status .= "\n"; } // end forecast period processing //--------------------------------------------------------------------------------------------- // generate the alerts display /* 2017 09 20 03 28 20170920032800 20 septembre 2017 03h28 UTC 2017 09 19 21 28 20170919212800 19 septembre 2017 21h28 HAR */ $X = $xml->warnings; if($doDebug) {$Status .= "\n";} if (isset($X['url'])) { // got one (or more) alerts $aURL = str_replace('http://','https://',(string)$X['url']); // accumulate all the alert data from the info for ($i=0;$ievent); $i++) { $alerttype[$i] = (string)$X->event[$i]['type']; $alerts[$i] = (string)$X->event[$i]['description']; if($doIconv) { $alerts[$i] = iconv($charsetInput,$charsetOutput.'//TRANSLIT', ECF_UTF_CLEANUP($alerts[$i])); } } } if (isset($alerts[0])) { // combine alerts of the same type foreach($alerttype as $i => $atype) { $alertlinks[$atype][] = $aURL; $alertlinkstext[$atype][] = $alerts[$i]; } } if($doDebug) { $Status .= "\n"; $Status .= "\n"; } // end of alerts processing //--------------------------------------------------------------------------------------------- // generate the HTML from the extracted data //--------------------------------------------------------------------------------------------- // make the Current conditions table from $conditions array $nC = 3; // number of columns in the conditions table if (isset($conditions['cityobserved']) ) { // only generate if we have the data if (isset($conditions['icon']) and ! $conditions['icon'] ) { $nC = 2; }; $currentConditions = '' . "\n"; $currentConditions .= ' ' . "\n\n"; if (isset($conditions['icon'])) { $currentConditions .= ' '; } // end of icon $currentConditions .= " '; $currentConditions .= ' '; $currentConditions .= '
' . $conditions['cityobserved'] . '
'. $conditions['obsdate'] . '
' . " \""
" . $conditions['citycondition'] . "\n"; $currentConditions .= '
\n"; if (isset($conditions['temperature'])) { $currentConditions .= $conditions['temperature'] . "
\n"; } if (isset($conditions['windchill'])) { $currentConditions .= $conditions['windchill'] . "
\n"; } if (isset($conditions['humidex'])) { $currentConditions .= $conditions['humidex'] . "
\n"; } if (isset($conditions['wind'])) { $currentConditions .= $conditions['wind'] . "
\n"; } if (isset($conditions['humidity'])) { $currentConditions .= $conditions['humidity'] . "
\n"; } if (isset($conditions['dewpoint'])) { $currentConditions .= $conditions['dewpoint'] . "
\n"; } if (isset($conditions['precip'])) { $currentConditions .= $conditions['precip'] . "
\n"; } $currentConditions .= $conditions['pressure'] . "
\n"; if (isset($conditions['tendency'])) { $currentConditions .= $conditions['tendency'] . "
\n" ; } if (isset($conditions['aqhi'])) { $currentConditions .= $conditions['aqhi'] . "
\n" ; } if (isset($conditions['visibility'])) { $currentConditions .= $conditions['visibility'] . "\n" ; } $currentConditions .= '
'; if(isset($conditions['sunrise']) and isset($conditions['sunset']) ) { $currentConditions .= $conditions['sunrise'] . "
\n" . $conditions['sunset'] . "
\n" ; } if (isset($conditions['moonrise']) and isset($conditions['moonset']) ) { $currentConditions .= $conditions['moonrise'] . "
\n" . $conditions['moonset'] ; } if(isset($conditions['maxmin']) ) { $currentConditions .= str_replace(':',':
',$conditions['maxmin']) . "
\n"; } if(isset($conditions['ydayheading']) and isset($conditions['ydaymaxtemp']) and isset($conditions['ydaymintemp']) ) { $currentConditions .= $conditions['ydayheading'] . "
\n" . '  ' . $conditions['ydaymaxtemp'] . "
\n" . '  ' . $conditions['ydaymintemp'] . "
\n"; if(isset($conditions['ydayprecip'])) { $currentConditions .= '  ' . $conditions['ydayprecip'] . "
\n"; } if(isset($conditions['ydaysnow'])) { $currentConditions .= '  ' . $conditions['ydaysnow'] . "
\n"; } $currentConditions .= "
\n"; } $currentConditions .= '
'; } // end of if isset($conditions['cityobserved']) // end of current conditions mods //--------------------------------------------------------------------------------------------- // Generate the $almanac HTML if(isset($conditions['extremeMax']) and strlen($conditions['extremeMax']) > 3 ) { // got any almanac? $almanacList = array( 'extremeMax', 'extremeMin', 'normalMax', 'normalMin', 'normalMean', 'extremeRainfall', 'extremeSnowfall', 'extremePrecipitation', 'extremeSnowOnGround', 'almanacpop', ); $almanac = '' . "\n"; $l = $Legends['avgexhead']; if($doIconv) { $l = iconv($charsetInput,$charsetOutput.'//TRANSLIT',$Legends['avgexhead']); } $almanac .= '\n"; foreach ($almanacList as $i => $key) { if(isset($conditions[$key])) { list($value,$period,$year) = explode('|',$conditions[$key]); if(strlen($period)>0) {$period = '('.$period.')';} $value = str_replace('C','°C',$value); $year = (strlen($year)>0)?$year:' '; $l = $Legends[$key]; if($doIconv) { $l = iconv($charsetInput,$charsetOutput.'//TRANSLIT',$Legends[$key]); } $almanac .= ''; $almanac .= ''; $almanac .= '\n"; } } $almanac .= "
'.$l."
'.$l.$period.''.$value.''.$year."
\n"; } // end of $almanac HTML generation //--------------------------------------------------------------------------------------------- // generate the HTML for the 24hr forecast table display if(count($forecasthours) > 0) { $tCols = 5; if($forecasthours['haveHumidex'] or $forecasthours['haveWindChill']) { $tCols++; } $nonSigFound = false; $tDateLast = ''; $forecast24h = '
'."\n"; $forecast24h .= '

'.$Legends['forecast24']." - $title

\n"; $forecast24h .= ''."\n"; $forecast24h .= "\n"; $forecast24h .= ' \n"; $forecast24h .= ' \n"; $forecast24h .= ' \n"; $forecast24h .= ' \n"; $forecast24h .= ' \n"; if($forecasthours['haveHumidex']) { $forecast24h .= ' \n"; } if($forecasthours['haveWindChill']) { $forecast24h .= ' \n"; } $forecast24h .= "\n"; for($i=0;$i<24;$i++) { // generate the detail line for the hour $F = $forecasthours[$i]; /* [UTCstring] => 201709262000 [time] => 16:00 [date] => 2017-09-26 [day] => 26 [year] => 2017 [month] => 09 [monthname] => septembre [TZ] => HAE [cond] => Généralement ensoleillé [icon] => 01 [lop] => Nulle [pop] => 0 [temp] => 29 [wind] => S 10 km/h [humidex] => 36 */ $t = ''; if($tDateLast !== $F['date']) { $t .= ''."\n"; $tDateLast = $F['date']; } $t .= ''."\n"; $t .= ' \n"; $t .= ' \n"; $t .= ' \n"; $t .= ' \n"; $t .= ' \n"; } else { $t .= $F['wind']."\n"; } if($forecasthours['haveHumidex']) { $t .= ' \n"; } if($forecasthours['haveWindChill']) { $t .= ' \n"; } $t .= ''."\n"; $forecast24h .= $t; } $forecast24h .= "\n"; $forecast24h .= ' '."\n"; $forecast24h .= "\n"; $forecast24h .= "\n"; $forecast24h .= ' \n"; $forecast24h .= "\n"; if($nonSigFound) { $forecast24h .= "\n"; $forecast24h .= ' \n"; $forecast24h .= "\n"; } $forecast24h .= "
'.$Legends['datetime'].'
('.$forecasthours['TZ'].")
'.$Legends['temperature'].'
('.$forecasthours['tempUOM'].")

'.$Legends['weatherconds']."

'.$Legends['lop']."
'.$Legends['wind'].'
('.$forecasthours['windUOM'].")

'.$Legends['humidex']."
'. ''.$Legends['windchill']."
'. $F['day'].' '.$F['monthname'].' '.$F['year']. '
'.$F['time']."'.$F['temp']."'; $alttext = $F['cond']; if ($F['pop'] <> '') { $alttext .= " (" . $F['pop'] ."%)"; } $t .= ''. "'.$alttext.''. '  '.$F['cond']. "'.$F['lop']."'; if(strpos($F['wind'],'VR') !== false) { $t .= ''.$F['wind']."'; if(isset($F['humidex'])) { $t .= $F['humidex']; } else { $t .= '‡'; $nonSigFound = true; } $t .= "'; if(isset($F['windchill'])) { $t .= $F['windchill']; } else { $t .= '‡'; $nonSigFound = true; } $t .= "
 
'. $Legends['lopnote']."
'. $Legends['nonsig']."
\n
\n"; if($doIconv) { $forecast24h = iconv($charsetInput,$charsetOutput.'//TRANSLIT',ECF_UTF_CLEANUP($forecast24h)); } } // end generate HTML for 24hr forecast table display //--------------------------------------------------------------------------------------------- // now format the forecast for display //----------------------------------------------------------------------------- // calc the width percentage based on number of icons to display $wdth = intval(100/(count($forecasticon)/2)); // set the legend $weather7days = ($Lang=='fr')?'Prévisions':'Extended Forecast'; // now make the table $weather = '
'."\n"; $weather .= ''."\n"; $weather .= "\n"; $weather .= '\n"; $weather .= "\n"; $weather .= "\n"; $tweather = array(); // generate the icon for each period foreach ($forecasticon as $i => $v) { $tweather[$i] = '\n"; $forecast[$i] = $forecasttitles[$i] . "
\n" . $forecasticon[$i] . "
\n" . $forecasttext[$i] . "
\n" . $forecasttemp[$i] . "\n"; } // end generate forecast icons in $tweather array // now loop over the $tweather array to build the two table rows with icons if($forecasttemptype[0] == 'min') { $iStart = -1; } else { $iStart = 0; } for ($i=0;$i<=count($tweather);$i=$i+2) { if(isset($tweather[$i+$iStart])) { $weather .= $tweather[$i+$iStart]; } else { $weather .= '\n"; } } $weather .= "\n\n"; for ($i=1;$i<=count($tweather);$i=$i+2) { if(isset($tweather[$i+$iStart])) { $weather .= $tweather[$i+$iStart]; } else { $weather .= '\n"; } } $weather .= "\n
 '.$weather7days." - $ECNAME
'. $forecasttitles[$i]."\n"; $alttext = $forecasttext[$i]; if ($forecastpop[$i] <> '') { $alttext .= " (" . $forecastpop[$i] ."%)"; } $forecasticon[$i] = " \"$alttext\"\n"
\n"; $tweather[$i] .= "
" . $forecasticon[$i] . "\n"; $tweather[$i] .= " " . $forecasttext[$i] . "
\n"; $tweather[$i] .= " " . $forecasttemp[$i] . "\n"; $tweather[$i] .= "
'; $weather .= " \n
'; $weather .= " \n
\n"; $weather .= "
\n\n"; /* note: finish styling of alert links in your .css by adding: .ECwarning a:link, .ECstatement a:link, .ECended a:link, .ECended a:visited { color:white !important; } .ECwarning a:hover, .ECended a:hover { color:black !important; } .ECwarning a:visited, .ECstatement a:visited { color:white !important; } .ECwatch a:link, .ECwatch a:visited { color:black !important; } .ECstatement a:hover, .ECwatch a:hover { color:red !important; } */ //--------------------------------------------------------------------------------------------- // finish processing alerts HTML if (count($alertlinks) > 0) { // create the $alertstring HTML if there are alert(s) $alertstyles = array( 'warning' => 'color: white; background-color: #b00; border: 2px solid black;', 'watch' => 'color: black; background-color: #ff0; border: 2px solid black;', 'statement' => 'color: white; background-color: #707070; border: 2px solid black;', 'ended' => 'color: white; background-color: #6c6; border: 2px solid black;', 'noalert' => 'color: black; background-color: #fff; border: 2px solid black;', 'advisory' => 'color: white; background-color: #707070; border: 2px solid black;', ); // group alerts by type and add to $alertstring foreach ($alertlinks as $atype => $alist) { $alertstring .= '

'."\n"; foreach ($alertlinks[$atype] as $g => $alks ) { $alertstring .= ' ' . $alertlinkstext[$atype][$g] . '
'."\n"; } $alertstring .= "

\n"; } } else { // no alerts to show $alertstring = ''; } // ---- end of alerts mods--- //--------------------------------------------------------------------------------------------- // finish HTML assembly for the page (detail text forecast) $textfcsthead = $ECHEAD; // assemble the text forecast as a definition list $textforecast = '

'.$textfcsthead.'

'."\n

$title ($updated)

\n
\n"; if($doDebug) { $Status .= "\n"; $Status .= "\n"; } for ($g=0;$g < count($forecastdays);$g++) { $textforecast .= "
" . $forecastdays[$g] ."
\n"; $textforecast .= "
" . $forecastdetail[$g] . "
\n"; } $textforecast .= "
\n"; $textforecast .= "
\n"; // ----- end of detail text forecast HTML assembly //--------------------------------------------------------------------------------------------- // print it out: if ($printIt and ! $doInclude ) { ?> <?php print "$ECHEAD - $ECNAME"; ?> \n"; print $currentConditions; print "\n"; } print $weather; if ($foundAbnormal > 0) {print $abnormalString; } print $textforecast; if($showAlmanac and strlen($almanac) > 0) { print "
\n"; print $almanac; print "
\n"; } if($show24hour and strlen($forecast24h) > 0) { print "
\n"; print $forecast24h; print "
\n"; } print "

$ECNAME

\n"; } if ($printIt and ! $doInclude ) {?> 0) { $testicon = $curicon."p$pop$iconTypeEC"; if (file_exists("$imagedirEC/$testicon")) { $newicon = $testicon; } else { $newicon = "$curicon$iconTypeEC"; } } else { $newicon = "$curicon$iconTypeEC"; } # $newicon = str_replace(".gif",$iconTypeEC,$newicon); // support other icon types return($newicon); } //--------------------------------------------------------------------------------------------- // get contents from one URL and return as string function ECF_fetch_URL($url,$useFopen) { global $Status, $needCookie; $overall_start = time(); if (! $useFopen) { // Set maximum number of seconds (can have floating-point) to wait for feed before displaying page without feed $numberOfSeconds=4; // Thanks to Curly from ricksturf.com for the cURL fetch functions $data = ''; $domain = parse_url($url,PHP_URL_HOST); $theURL = str_replace('nocache','?'.$overall_start,$url); // add cache-buster to URL if needed $Status .= "\n"; $ch = curl_init(); // initialize a cURL session curl_setopt($ch, CURLOPT_URL, $theURL); // connect to provided URL curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // don't verify peer certificate curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (ec-forecast.php - saratoga-weather.org)'); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $numberOfSeconds); // connection timeout curl_setopt($ch, CURLOPT_TIMEOUT, $numberOfSeconds); // data timeout curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return the data transfer curl_setopt($ch, CURLOPT_NOBODY, false); // set nobody curl_setopt($ch, CURLOPT_HEADER, true); // include header information if (isset($needCookie[$domain])) { curl_setopt($ch, $needCookie[$domain]); // set the cookie for this request curl_setopt($ch, CURLOPT_COOKIESESSION, true); // and ignore prior cookies $Status .= "\n"; } $data = curl_exec($ch); // execute session if(curl_error($ch) <> '') { // IF there is an error $Status .= "\n"; // display error notice } $cinfo = curl_getinfo($ch); // get info on curl exec. /* curl info sample Array ( [url] => http://saratoga-weather.net/clientraw.txt [content_type] => text/plain [http_code] => 200 [header_size] => 266 [request_size] => 141 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.125 [namelookup_time] => 0.016 [connect_time] => 0.063 [pretransfer_time] => 0.063 [size_upload] => 0 [size_download] => 758 [speed_download] => 6064 [speed_upload] => 0 [download_content_length] => 758 [upload_content_length] => -1 [starttransfer_time] => 0.125 [redirect_time] => 0 [redirect_url] => [primary_ip] => 74.208.149.102 [certinfo] => Array ( ) [primary_port] => 80 [local_ip] => 192.168.1.104 [local_port] => 54156 ) */ $Status .= "\n"; //$Status .= "\n"; curl_close($ch); // close the cURL session //$Status .= "\n"; $i = strpos($data,"\r\n\r\n"); $headers = substr($data,0,$i); $content = substr($data,$i+4); if($cinfo['http_code'] <> 200) { $Status .= "\n"; } return $data; // return headers+contents } else { // print "\n"; $STRopts = array( 'http'=>array( 'method'=>"GET", 'protocol_version' => 1.1, 'header'=>"Cache-Control: no-cache, must-revalidate\r\n" . "Cache-control: max-age=0\r\n" . "Connection: close\r\n" . "User-agent: Mozilla/5.0 (ec-forecast.php - saratoga-weather.org)\r\n" . "Accept: text/plain,text/html\r\n" ), 'https'=>array( 'method'=>"GET", 'protocol_version' => 1.1, 'header'=>"Cache-Control: no-cache, must-revalidate\r\n" . "Cache-control: max-age=0\r\n" . "Connection: close\r\n" . "User-agent: Mozilla/5.0 (ec-forecast.php - saratoga-weather.org)\r\n" . "Accept: text/plain,text/html\r\n" ) ); $STRcontext = stream_context_create($STRopts); $T_start = ECF_fetch_microtime(); $xml = file_get_contents($url,false,$STRcontext); $T_close = ECF_fetch_microtime(); $headerarray = get_headers($url,0); $theaders = join("\r\n",$headerarray); $xml = $theaders . "\r\n\r\n" . $xml; $ms_total = sprintf("%01.3f",round($T_close - $T_start,3)); $Status .= "\n"; $Status .= "<-- get_headers returns\n".$theaders."\n -->\n"; // print " file() stats: total=$ms_total secs.\n"; $overall_end = time(); $overall_elapsed = $overall_end - $overall_start; $Status .= "\n"; // print "fetch function elapsed= $overall_elapsed secs.\n"; return($xml); } } // end ECF_fetch_URL //--------------------------------------------------------------------------------------------- function ECF_fetch_microtime() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } //--------------------------------------------------------------------------------------------- function ECF_XML_URL_info($ECurl) { /* Function to change a http://weather.gc.ca/city/pages/... URL to the corresponding http://dd.weather.gc.ca/citypage_weather/xml/... URL for retrieval of the XML forecast desired. Uses the $EClookup table for the conversion of page-id to XML base filename. Returns: array( XML URL or false if requested page-id is not found pgcode (on-15, etc) lang ( 'e' or 'f') units ( 'metric' or 'imperial') XML file ('sNNNNNNN' or '' if not found) Author: Ken True - 18-Sep-2017 - saratoga-weather.org */ global $EClookup; $urlparts = parse_url($ECurl); $pathinfo = pathinfo($urlparts['path']); list($pgcode,$unit,$lang) = explode('_',$pathinfo['filename']); list($prov,$numb) = explode('-',$pgcode); $PROV = strtoupper($prov); if(isset($EClookup[$pgcode])) { list($Xprov,$Xfile,$XnameE,$XnameF,$Xlat,$Xlon) = explode("|",$EClookup[$pgcode]); return( array( "https://dd.weather.gc.ca/citypage_weather/xml/$PROV/{$Xfile}_$lang.xml", $pgcode, $lang, $unit, $Xfile ) ); } else { return (array( false, $pgcode, $lang, $unit, '' ) ); } } //--------------------------------------------------------------------------------------------- function ECF_get_time ($utcstring,$utcoffset) { // convert the YYYYDDMMHHmmss to ISO UTC format for strtotime use global $Status, $doDebug; $tstr = substr($utcstring,0,4).'-' . substr($utcstring,4,2).'-' . substr($utcstring,6,2).'T' . substr($utcstring,8,2).':' . substr($utcstring,10,2).':' . substr($utcstring,12,2). '00 UTC'; if($doDebug) { $Status .= "\n"; } return(strtotime($tstr)+$utcoffset*3600); } //--------------------------------------------------------------------------------------------- function ECF_UTF_CLEANUP ($str) { // Clean embedded ISO-8859-1 characters with UTF-8 replacements so iconv can work. // EC is a bit lazy about mixing character sets in descriptions. global $trantab; $cstr = str_replace( // ISO-8859-1 characters $trantab['ISO'], // UTF-8 characters represented as ISO-8859-1 $trantab['UTF'], $str); return($cstr); } // end of ec-forecast.php