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 HTML with current advisories/warnings with dropdown/expand // $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 $alertstring = ''; // HTML+Javascript for alert displays $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 # compute new URL based on old URL format if necessary list($ECURL,$PAGEURL,$cacheName) = gen_ecurl($ECURL); // force refresh of cache if (isset($_REQUEST['cache'])) { $refetchSeconds = 1; } function gen_ecurl($URL) { # convert old to new format URLS and process new format URLs # to generate data and link URLs global $Lang,$EClookup,$Status,$cacheFileDir; # input URLs: # # Old Format # $ECURL = 'https://weather.gc.ca/city/pages/on-107_metric_e.html'; # Old format # https://meteo.gc.ca/city/pages/on-107_metric_f.html #New format # https://weather.gc.ca/en/location/index.html?coords=49.245,-123.115 # https://meteo.gc.ca/fr/location/index.html?coords=49.245,-123.115 # return: # $ECURL = 'https://weather.gc.ca/api/app/en/Location/49.245,-123.115?type=city'; # https://meteo.gc.ca/api/app/fr/Location/49.245,-123.115?type=city $Status .= "\n"; if(strpos($URL,'/pages/')!==false) { # handle OLD forma # OLD format URL $U= parse_url($URL); $host = $U['host']; $path = $U['path']; $P = pathinfo($path); $pp = explode('_',$P['filename'].'_'); $id = $pp[0]; # gets the PP-nnn code from old url. if(isset($EClookup[$id])){ # 'ab-1' => 'AB|s0000493|Cochrane|Cochrane|51.21|-114.47', list($pv,$scode,$ENname,$FRname,$lat,$lon) = explode('|',$EClookup[$id]); $latlon = "$lat,$lon"; } else { $Status .= "\n"; } $cache = $cacheFileDir.'ecforecast-'.str_replace('.','_',$latlon)."-$Lang.json"; if($Lang == 'fr') { $ECURL = "https://meteo.gc.ca/api/app/v3/fr/Location/$latlon?type=city"; $PGURL = "https://meteo.gc.ca/fr/location/index.html?coords=$latlon"; $Status .= "\n"; $Status .= "\n"; } if($Lang == 'en') { $ECURL = "https://weather.gc.ca/api/app/v3/en/Location/$latlon?type=city"; $PGURL = "https://weather.gc.ca/en/location/index.html?coords=$latlon"; $Status .= "\n"; $Status .= "\n"; } $Status .= "\n"; return(array($ECURL,$PGURL,$cache)); } if(strpos($URL,'/location/')!==false) { # Handle new format URLs # NEW format URL $U= parse_url($URL); $host = $U['host']; $path = $U['path']; $query = $U['query']; $latlon = str_replace('coords=','',$query); $cache = $cacheFileDir.'ecforecast-'.str_replace('.','_',$latlon)."-$Lang.json"; if($Lang == 'fr') { $ECURL = "https://meteo.gc.ca/api/app/v3/fr/Location/$latlon?type=city"; $PGURL = "https://meteo.gc.ca/fr/location/index.html?coords=$latlon"; $Status .= "\n"; $Status .= "\n"; } if($Lang == 'en') { $ECURL = "https://weather.gc.ca/api/app/v3/en/Location/$latlon?type=city"; $PGURL = "https://weather.gc.ca/en/location/index.html?coords=$latlon"; $Status .= "\n"; $Status .= "\n"; } $Status .= "\n"; return(array($ECURL,$PGURL,$cache)); } } if($ECURL === false) { print $Status; print "

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

\n"; return(false); } $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($ECURL,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($ECURL,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"; } $stuff = explode("\r\n\r\n",$rawhtml); // maybe we have more than one header due to redirects. $content = (string)array_pop($stuff); // last one is the content $headers = (string)array_pop($stuff); // next-to-last-one is the headers 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 ', 'impact' => 'Impact Level: ', 'confidence' => 'Forecast Confidence: ', 'effectivefor' => 'In effect for:' ), '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', 'impact' => 'Niveau d\'impact: ', 'confidence' => 'Confiance dans les prévisions: ', 'effectivefor' => 'En vigueur pour:', ) ); $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"; } $RAWJSON = json_decode($content,true); $JSON = isset($RAWJSON[0]['lastUpdated'])?$RAWJSON[0]:array(); //----------- handle the city conditions ----------------------------------------- $X = $JSON['observation']; /* "observation": { "observedAt": "Hamilton Munro Int'l Airport", "provinceCode": "ON", "climateId": "6153193", "tcid": "yhm", "timeStamp": "2024-10-23T18:00:00.000Z", "timeStampText": "2:00 PM EDT Wednesday 23 October 2024", "iconCode": "03", "condition": "Mostly Cloudy", "temperature": { "imperial": "68", "imperialUnrounded": "68.4", "metric": "20", "metricUnrounded": "20.2", "qaValue": 100 }, "dewpoint": { "imperial": "51", "imperialUnrounded": "50.7", "metric": "10", "metricUnrounded": "10.4", "qaValue": 100 }, "feelsLike": { "imperial": "72", "metric": "22", "qaValue": 100 }, "pressure": { "imperial": "29.9", "metric": "101.1", "changeImperial": "0.01", "changeMetric": "0.04", "qaValue": 100 }, "tendency": "rising", "visibility": { "imperial": "15", "metric": "24", "qaValue": 100 }, "visUnround": 24.10000000000000142108547152020037174224853515625, "humidity": "53", "humidityQaValue": 100, "windSpeed": { "imperial": "17", "metric": "27", "qaValue": 100 }, "windGust": { "imperial": "24", "metric": "38", "qaValue": 100 }, "windDirection": "WSW", "windDirectionQAValue": 100, "windBearing": "243.0" }, */ // NOTE: we'll store the current conditions in the $conditions array for later assembly if(isset($X['observedAt'])) { // got an observation.. format it $conditions['cityobserved'] = $Legends['cityobserved'] . ': '. (string)$X['observedAt'] . ''; $obsdate = (string)$X['timeStampText']; 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']['metric'] . ' kPa'; $conditions['tendency'] = $Legends['tendency'] . ': '. (string)$X['pressure']['changeMetric'] . ' kPa'; $conditions['temperature'] = $Legends['temperature'] . ': '. (string)$X['temperature']['metric'] . ' °C'; if(strlen((string)$X['dewpoint']['metric']) > 0) { $conditions['dewpoint'] = $Legends['dewpoint'] . ': '. (string)$X['dewpoint']['metric'] . ' °C'; } if(isset($X['humidity'])) { $conditions['humidity'] = $Legends['humidity'] . ': '. (string)$X['humidity'] . ' %'; } $conditions['wind'] = $Legends['wind'] . ': '; if($X['windSpeed']['metric'] > 0) { $conditions['wind'] .= (string)$X['windDirection'] . ' ' . $X['windSpeed']['metric']; if(isset($X['windGust']['metric']) and strlen((string)$X['windGust']['metric'])>0) { $conditions['wind'] .= ' ' . $Legends['gust'] . ' ' . (string)$X['windGust']['metric']; } $conditions['wind'] .= ' km/h'; } else { $conditions['wind'] .= $Legends['calm']; } $conditions['wind'] .= ''; if(isset($X['humidex'])) { $conditions['humidex'] = $Legends['humidex'] . ': '. (string)$X['humidex'] . ''; } if($X['temperature']['metric'] <= 0 and isset($X['feelsLike']['metric'])) { $tl = str_replace('
',' ',$Legends['windchill']); $conditions['windchill'] = $tl . ': '. $X['feelsLike']['metric'] . ' °C'; } if(isset($X['visibility']['metric'])) { $conditions['visibility'] = $Legends['visibility'] . ': '. $X['visibility']['metric'] . ' km'; } } // extract 'normals' /* "dailyFcst": { "dailyIssuedTimeShrt": "5:00 AM PDT", "regionalNormals": { "metric": { "highTemp": 13, "lowTemp": 6, "text": "Low 6. High 13." }, "imperial": { "highTemp": 55, "lowTemp": 43, "text": "Low 6. High 13." } }, */ if(isset($JSON['dailyFcst']['dailyIssuedTimeShrt'])) { $X = $JSON['dailyFcst']; if(isset($X['regionalNormals']['metric']['text'])) { $conditions['maxmin'] = $Legends['maxmin'] . ': Max ' . $X['regionalNormals']['metric']['highTemp'] . '°C Min ' . $X['regionalNormals']['metric']['lowTemp'] . '°C'; } /* yesterday info not available // 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'; } */ /* "riseSet": { "set": { "time12h": "6:13 pm", "epochTimeRounded": "1729386000", "time": "18:13" }, "timeZone": "PDT", "rise": { "time12h": "7:41 am", "epochTimeRounded": "1729346400", "time": "7:41" } }, */ // extract the sunrise/sunset data $X = $JSON['riseSet']; if(isset($X['rise']['time'])) { $conditions['sunrise'] = $Legends['sunrise'] . ': ' . $X['rise']['time'] . ''; $conditions['sunset'] = $Legends['sunset'] . ': ' . $X['set']['time'] . ''; } } // Almanac info is not available in new JSON data // 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"; //--------------------------------------------------------------------------------------------- // Process the Hourly Forecast (if availablel) /* "hourlyFcst": { "hourlyIssuedTimeShrt": "5:00 AM PDT", "hourly": [ { "date": "19 October 2024", "periodID": 0, "windGust": { "metric": "", "imperial": "" }, "windDir": "SE", "feelsLike": { "metric": "", "imperial": "" }, "condition": "Rain at times heavy", "precip": "100", "temperature": { "metric": "14", "imperial": "57" }, "iconCode": "13", "time": "7 AM", "windSpeed": { "metric": "30", "imperial": "19" }, "epochTime": 1729346400, "dateShrt": "19 Oct" }, */ if(isset($JSON['hourlyFcst']['hourly'][0])) { $UOMTempUsed = "°C"; $UOMWindUsed = 'km/h'; $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; $lastDateShrt = ''; foreach ($JSON['hourlyFcst']['hourly'] as $i => $X) { if(isset($X['date'])) {$lastDateShrt = (string)$X['date'];} $forecasthours[$n]['UTCstring'] = (string)$X['epochTime']; $forecasthours[$n]['date'] = $lastDateShrt; $forecasthours[$n]['time'] = (string)$X['time']; $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['precip']); $forecasthours[$n]['lop'] = (string)$X['precip']; // likelyhood of precipitation $forecasthours[$n]['pop'] = (string)$X['precip']; // actual PoP if any $forecasthours[$n]['temp'] = (string)$X['temperature']['metric']; $forecasthours[$n]['wind'] = (string)$X['windDir']." ".(string)$X['windSpeed']['metric']; if(isset($X['windGust']['metric']) and strlen((string)$X['windGust']['metric'])>0) { $forecasthours[$n]['wind'] .= ' ' . $Legends['gust'] . ' ' . (string)$X['windGust']['metric']; } 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 daily forecast periods $i = 0; $foundAbnormal = 0; // No abnormal indicators in XML (so far) $alertstring = ''; // get forecast issued date if(isset($JSON['dailyFcst']['dailyIssuedTime'])) { $updated = $Legends['issued'].': '.(string)$JSON['dailyFcst']['dailyIssuedTime']; if($doIconv) { $updated = iconv($charsetInput,$charsetOutput.'//TRANSLIT',ECF_UTF_CLEANUP($updated)); } $Status .= "\n"; } // get the official location name if(isset($JSON['displayName'])) { $title = (string)$JSON['displayName'] . ', ' . strtoupper($JSON['province']); if($doIconv) { $title = iconv($charsetInput,$charsetOutput.'//TRANSLIT',$title); } } if(isset($JSON['dailyFcst']['daily'])) { foreach ($JSON['dailyFcst']['daily'] as $idx => $X) { /* "dailyFcst": { "dailyIssuedTimeShrt": "5:00 AM PDT", "regionalNormals": { "metric": { "highTemp": 13, "lowTemp": 6, "text": "Low 6. High 13." }, "imperial": { "highTemp": 55, "lowTemp": 43, "text": "Low 6. High 13." } }, "daily": [{ "date": "Sat, 19 Oct", "summary": "Rain at times heavy", "periodID": 1, "periodLabel": "Today", "windChill": { "calculated": [], "textSummary": "" }, "sun": { "value": "0", "units": "hours" }, "temperatureText": "High 15.", "humidex": [], "precip": "", "frost": { "textSummary": "" }, "titleText": "Today: Rain at times heavy. High 15.", "temperature": { "periodHigh": 15, "metric": "15", "imperial": "59" }, "iconCode": "13", "text": "Rain at times heavy. Amount 30 to 40 mm. Wind southeast 30 km\/h except gusting to 60 near the water. High 15. UV index 1 or low." }, ... */ $forecasticon[$i] = (string)$X['iconCode']; $forecasttext[$i] = (string)$X['summary']; $forecastpop[$i] = (string)$X['precip']; $forecasticon[$i] = ECF_replace_icon($forecasticon[$i],$forecastpop[$i]); $tSummary = (string)$X['summary']; $forecasttemp[$i] = (string)$X['temperature']['metric']; if(isset($X['temperature']['periodHigh'])) { $forecasttemp[$i] ='Max: '.$forecasttemp[$i]; } else { $forecasttemp[$i] ='Min: '.$forecasttemp[$i];} $tAbn = ''; $forecasttempabn[$i] = ''; if(preg_match('!( rising | falling | hausse | baisse )!i',$tSummary)) { $tAbn = ' *'; $foundAbnormal++; } $forecasttemptype[$i] = strtolower(substr((string)$X['temperatureText'],0,3)); $forecasttemptype[$i] = str_replace('low','min',$forecasttemptype[$i]); $forecasttemptype[$i] = str_replace('hig','max',$forecasttemptype[$i]); $forecasttempabn[$i] = $tAbn; $t = ''.$forecasttemp[$i].'°C'; $t .= $forecasttempabn[$i]."
"; $forecasttemp[$i] = $t; $forecasttitles[$i] = (string)$X['periodLabel']; $forecastdetail[$i] = (string)$X['text']; $forecastdays[$i] = (string)$X['periodLabel']; //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 daily forecast period 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 (note: data not present in JSON.. left this in case it appears in the future) 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"; $tTitle = $Legends['forecast24']." - $title"; if($doIconv) { $tTitle = @iconv($charsetInput,$charsetOutput."//TRANSLIT",ECF_UTF_CLEANUP($tTitle)); } $forecast24h .= '

'.$tTitle."

\n"; $forecast24h .= ''."\n"; $forecast24h .= "\n"; $forecast24h .= ' \n"; $forecast24h .= ' \n"; if($doIconv) { $Legends['weatherconds'] = iconv($charsetInput,$charsetOutput.'//TRANSLIT',$Legends['weatherconds']); } $forecast24h .= ' \n"; $forecast24h .= ' \n"; $forecast24h .= ' \n"; if($forecasthours['haveHumidex']) { $forecast24h .= ' \n"; } if($forecasthours['haveWindChill']) { $forecast24h .= ' \n"; } $forecast24h .= "\n"; $tDateLast = ''; 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 [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"; if($doIconv) { $Legends['lopnote'] = iconv($charsetInput,$charsetOutput.'//TRANSLIT',$Legends['lopnote']); } $forecast24h .= ' \n"; $forecast24h .= "\n"; if($nonSigFound) { $forecast24h .= "\n"; $forecast24h .= ' \n"; $forecast24h .= "\n"; } $forecast24h .= "
'.$Legends['datetime']."'.$Legends['temperature'].'
('.$forecasthours['tempUOM'].")

'.$Legends['weatherconds']."

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

'.$Legends['humidex']."
'. ''.$Legends['windchill']."
'. $F['date']. '
'.$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',$forecast24h); } } // end generate HTML for 24hr forecast table display //--------------------------------------------------------------------------------------------- // now format the forecast for display if (count($forecasticon) > 0) { //----------------------------------------------------------------------------- // 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: .ECred a:link, .ECred a:visited, .ECred a:hover, .ECgrey a:link, .ECgrey a:visited, .ECgrey a:hover, { color:white !important; } .ECyellow a:link, .ECyellow a:visited, .ECyellow a:hover, .ECorange a:link, .ECorange a:visited, .ECorange a:hover, { { color:black !important; } abbr[title]{cursor:help;} */ //--------------------------------------------------------------------------------------------- // process alerts JSON and generate HTML if (isset($JSON['alert']['zoneId'])) { // create the $alertstring HTML if there are alert(s) /* */ $alertstring = ''; // group alerts by type and add to $alertstring $XA = isset($JSON['alert']['alerts'])?$JSON['alert']['alerts']:array(); $n = 0; $ecAlertFontSize = '130%'; foreach ($XA as $i => $A) { $alertstring .= format_alert($A,$n,'weather'); $n++; } $XA = isset($JSON['alert']['hwyAlerts'])?$JSON['alert']['hwyAlerts']:array(); foreach ($XA as $i => $A) { $alertstring .= format_alert($A,$n,'highway'); $n++; } if(strlen($alertstring) > 0) { $alertstring .= " "; } } else { // no alerts to show $alertstring = ''; } // ---- end of alerts mods--- //--------------------------------------------------------------------------------------------- // finish HTML assembly for the page (detail text forecast) if(isset($forecastdays) and count($forecastdays) > 0){ $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 } else { $textforecast = ''; } if(!isset($weather)){$weather = '';} //--------------------------------------------------------------------------------------------- // print it out: if ($printIt and ! $doInclude ) { header('Content-type: text/html,charset='.$charsetOutput); ?> <?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 ) {?> 'color: white; background-color: #DI0000; border: 2px solid black;', 'orange' => 'color: black; background-color: #ff9500; border: 2px solid black;', 'yellow' => 'color: black; background-color: #FFFF00; border: 2px solid black;', 'grey' => 'color: white; background-color: #656565; border: 2px solid black;', ); $wIcon = ($A['program'] == 'highway')?'⛟':'⚠'; #9951, #128664 $alertstring = ''; $atype = $A['colour']; $ID = "alert_$n"; $IDI = "alert_$n".'_I'; if($A['status'] == 'ended') {return($alertstring);} $alertstring .= ''."\n"; $alertstring .= ""; $tLoc = ''; if($A['program'] == 'highway' and isset($A['refLocs']) and is_array($A['refLocs'])) { foreach ($A['refLocs'] as $key => $val) { $tLoc .= $A['refLocs'][$key]['name']."
"; } } $alertstring .= "\n"; $alertstring .= "\n
$wIcon"; $aHead = $tLoc.$A['bannerText']; /* if($wType == 'highway') { $tZoneNames = ''; foreach($A['zones'] as $k => $t) { $tZoneNames = $t."
"; } $aHead = $tZoneNames . $aHead; } */ if($doIconv) { $aHead = iconv($charsetInput,$charsetOutput."//TRANSLIT",$aHead); } $alertstring .= "".$aHead.""; $alertstring .= "
\n"; # assemble details panel $tText = $A['issueTimeText']."\n\n"; #$tText .= "".$A['alertHeaderText'].""; /* $tText .= "
    "; foreach ($A['zones'] as $k => $tZone) { $tText .= "
  • $tZone
  • "; } $tText .= "
"; */ if(isset($A['impact'])) {$tText .= $Legends['impact'].$A['impact']."\n\n";} if(isset($A['confidence'])) {$tText .= $Legends['confidence'].$A['confidence']."\n\n\n";} $tText .= $A['text']."\n"; if(isset($A['refLocs']) and is_array($A['refLocs'])) { $tText .= "\n".$Legends['effectivefor']. "
    "; foreach ($A['refLocs'] as $key => $val) { $tText .= "
  • ".$A['refLocs'][$key]['name']."
  • "; } $tText .= "
\n"; } $tText = str_replace("\n","
\n",$tText); if($doIconv) { $tText = iconv($charsetInput,$charsetOutput."//TRANSLIT",$tText); } $alertstring .= "
"; $alertstring .= "
$tText
"; $alertstring .= "
\n"; $alertstring .= "\n"; return ($alertstring); } //--------------------------------------------------------------------------------------------- function ECF_replace_icon($icon,$pop) { // now replace icon with spiffy updated icons with embedded PoP to // spruce up the dull ones from www.weatheroffice.ec.gc.ca global $imagedirEC,$iconTypeEC; $curicon = str_replace('.gif','',$icon); $curicon = str_replace('.png','',$curicon); if ($pop > 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"; $stuff = explode("\r\n\r\n",$data); // maybe we have more than one header due to redirects. $content = (string)array_pop($stuff); // last one is the content $headers = (string)array_pop($stuff); // next-to-last-one is the headers 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_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; return($str); # temp disable this function $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