Source for file Weather_class.php

Documentation is available at Weather_class.php

  1. <?php
  2. /**
  3.  * PolarLava::Weather - A class to retrieve XML weather from the NOAA NWS.
  4.  *
  5.  * This class requires PHP >= 5.0.0
  6.  *
  7.  * @package PolarLavaWeather
  8.  * @version 1.0.1
  9.  * @copyright Copyright 2006-2007 Kevin L. Papendick
  10.  * @author Kevin L. Papendick <kevinp@polarlava.com>
  11.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  12.  * @filesource
  13.  */
  14.  
  15.  
  16. /**
  17.  * PolarLava::Weather - A class to retrieve XML weather from the NOAA NWS.
  18.  *
  19.  * This class requires PHP >= 5.0.0
  20.  *
  21.  * @package PolarLavaWeather
  22.  */
  23. class Weather {
  24.  
  25.     /**
  26.      * @var string Local XML data cache directory
  27.      * @access protected
  28.      */
  29.     protected $_cache_dir;
  30.  
  31.     /**
  32.      * @var int Local XML data cache valid time in minutes
  33.      * @access protected
  34.      */
  35.     protected $_cache_time;
  36.  
  37.     /**
  38.      * @var int Local XML station data cache valid time in minutes
  39.      * @access protected
  40.      */
  41.     protected $_cache_time_sid;
  42.  
  43.     /**
  44.      * @var boolean Error flag
  45.      * @access protected
  46.      */
  47.     protected $_error;
  48.  
  49.     /**
  50.      * @var string Error message for user
  51.      * @access protected
  52.      */
  53.     protected $_error_msg_user;
  54.  
  55.     /**
  56.      * @var string Error message for debugging
  57.      * @access protected
  58.      */
  59.     protected $_error_msg_debug;
  60.  
  61.     /**
  62.      * @var string Local conditions image directory
  63.      * @access protected
  64.      */
  65.     protected $_image_dir;
  66.  
  67.     /**
  68.      * @var string The weather observation station
  69.      * @access protected
  70.      */
  71.     protected $_obs_station;
  72.  
  73.     /**
  74.      * @var array weather station data array
  75.      * @access private
  76.      */
  77.     private $_station_array;
  78.  
  79.     /**
  80.      * @var string The base weather service URL
  81.      * @access protected
  82.      */
  83.     protected $_url;
  84.  
  85.     /**
  86.      * @var array weather data array
  87.      * @access private
  88.      */
  89.     private $_weather_array;
  90.  
  91.     /**
  92.      * @var string XML weather data
  93.      * @access private
  94.      * @link http://www.weather.gov/data/current_obs/
  95.      */
  96.     private $_xml;
  97.  
  98.  
  99.     /**
  100.      * Weather object constructor
  101.      *
  102.      * Accepts an array of configuration parameters as key/value pairs:
  103.      * <ul>
  104.      * <li>'url'            => 'Weather service XML url' default NOAA/NWS</li>
  105.      * <li>'obs_station'    => 'observation station code' default 'KIAG'</li>
  106.      * <li>'image_dir'        => 'local image directory' default NULL</li>
  107.      * <li>'cache_dir'        => 'local cache directory' default NULL</li>
  108.      * <li>'cache_time'        => 'local cache time in minutes' default 60 minutes</li>
  109.      * <li>'cache_time_sid'    => 'local cache time in minutes' for station data. Default 10080 (7 days)</li>
  110.      * <li>'fetch_weather'    => boolean flag, TRUE fetches weather data (default)</li>
  111.      * <li>'fetch_stations'    => boolean flag, TRUE fetches available weather stations data</li>
  112.      * <li>'cache_stations'    => boolean flag, TRUE serializes station data to cache</li>
  113.      * </ul>
  114.      *
  115.      * @param array $params 
  116.      */
  117.     public function __construct($params array()) {
  118.         $this->setError(FALSE);
  119.  
  120.         //Set Parameters
  121.         $url        (array_key_exists('url'$params)) $params['url''http://www.weather.gov/xml/current_obs/';
  122.         $loc        (array_key_exists('obs_station'$params)) $params['obs_station''KIAG';
  123.         $image_dir    (array_key_exists('image_dir'$params)) $params['image_dir'NULL;
  124.         $cache_dir    (array_key_exists('cache_dir'$params)) $params['cache_dir'NULL;
  125.         $cache_time    (array_key_exists('cache_time'$params)) ? (int) $params['cache_time'60;
  126.         $cache_time_sid    (array_key_exists('cache_time_sid'$params)) ? (int) $params['cache_time_sid'10080//1 week
  127.         $fetch_weather    (array_key_exists('fetch_weather'$params)) $params['fetch_weather'TRUE;
  128.         $fetch_stations    (array_key_exists('fetch_stations'$params)) $params['fetch_stations'FALSE;
  129.         $cache_stations    (array_key_exists('cache_stations'$params)) $params['cache_stations'FALSE;
  130.  
  131.         $this->setUrl($url);
  132.         $this->setObsStation($loc);
  133.         $this->setImageDir($image_dir);
  134.         $this->setCacheDir($cache_dir);
  135.         $this->setCachetime($cache_time);
  136.         $this->setCachetimeSid($cache_time_sid);
  137.  
  138.         if ($fetch_weather{
  139.             $this->_getWeatherXml();
  140.             $this->_setWeatherArray();
  141.             $this->_setLocalImage();
  142.         }
  143.  
  144.         if ($fetch_stations{
  145.             $this->_getWeatherStationXml();
  146.             $this->_setStationArray();
  147.             if ($cache_stations && $cache_dir{
  148.                 $this->_setStationCache();
  149.             }
  150.         }
  151.     }
  152.  
  153.     /***********************/
  154.     /***** Set Methods *****/
  155.     /***********************/
  156.  
  157.     /**
  158.      * Set the local XML data cache directory.
  159.      *
  160.      * @param string 
  161.      * @return NULL 
  162.      */
  163.     public function setCacheDir($a{
  164.         $this->_cache_dir = $a;
  165.     }
  166.  
  167.     /**
  168.      * Set the local XML data cache valid time in minutes.
  169.      *
  170.      * @param int 
  171.      * @return NULL 
  172.      */
  173.     public function setCacheTime($a{
  174.         $this->_cache_time = $a;
  175.     }
  176.  
  177.     /**
  178.      * Set the local XML station data cache valid time in minutes.
  179.      *
  180.      * @param int 
  181.      * @return NULL 
  182.      */
  183.     public function setCacheTimeSid($a{
  184.         $this->_cache_time_sid = $a;
  185.     }
  186.  
  187.     /**
  188.      * Set the error flag and message.
  189.      *
  190.      * @access protected
  191.      * @param boolean $err 
  192.      * @param string $usr_msg The user error message
  193.      * @param string $dbg_msg The debug error message
  194.      * @return NULL 
  195.      */
  196.     protected function setError($err$usr_msg NULL$dbg_msg NULL{
  197.         $this->_error = $err;
  198.         $this->_error_msg_user = $usr_msg;
  199.         $this->_error_msg_debug = $dbg_msg;
  200.     }
  201.  
  202.     /**
  203.      * Set the local conditions image directory.
  204.      *
  205.      * @param string 
  206.      * @return NULL 
  207.      */
  208.     public function setImageDir($a{
  209.         $this->_image_dir = $a;
  210.     }
  211.  
  212.     /**
  213.      * Checks and retrieves the local conditions image.
  214.      *
  215.      * @access protected
  216.      * @return NULL 
  217.      */
  218.     protected function _setLocalImage({
  219.         $dir $this->getImageDir();
  220.         $icon $this->getWeatherElement('icon_url_name');
  221.         if (!is_null($dir)) {
  222.             $image $dir $icon;
  223.             if (!file_exists($image)) {
  224.                 $url $this->getWeatherElement('icon_url_base'$icon;
  225.                 $curl curl_init();
  226.                 curl_setopt($curlCURLOPT_URL$url);
  227.                 curl_setopt($curlCURLOPT_RETURNTRANSFER1);
  228.                 $curl_data curl_exec($curl);
  229.                 curl_close($curl);
  230.                 file_put_contents($image$curl_dataLOCK_EX);
  231.                 @chmod($image0666);
  232.             }
  233.         }
  234.     }
  235.  
  236.     /**
  237.      * Set the weather observation station.
  238.      *
  239.      * @param string 
  240.      * @return NULL 
  241.      * @link http://www.weather.gov/data/current_obs/
  242.      */
  243.     public function setObsStation($a{
  244.         $this->_obs_station = $a;
  245.     }
  246.  
  247.     /**
  248.      * Set the weather data base URL.
  249.      *
  250.      * @param string 
  251.      * @return NULL 
  252.      */
  253.     public function setUrl($a{
  254.         $this->_url = $a;
  255.     }
  256.  
  257.     /**
  258.      * Convert XML weather data to array
  259.      *
  260.      * @access protected
  261.      * @return boolean success status
  262.      */
  263.     protected function _setWeatherArray({
  264.         $stat TRUE;
  265.         $this->_weather_array = array();
  266.         $values array();
  267.         $xml_parser xml_parser_create();
  268.         xml_parse_into_struct($xml_parser$this->getXml()$values);
  269.         xml_parser_free($xml_parser);
  270.         foreach (new ArrayObject($valuesas $xml_elem{
  271.             foreach (new ArrayObject($xml_elemas $sub_elem{
  272.                 if($xml_elem['type'!== 'cdata'{
  273.                     $this->_weather_array[strtolower($xml_elem['tag'])$xml_elem['value'];
  274.                     break;
  275.                 }
  276.             }
  277.         }
  278.  
  279.         if (count($this->_weather_array0{
  280.             //--- Clean up in isle 3!
  281.             $stat TRUE;
  282.             if (strpos($this->_weather_array['icon_url_base']'www'=== FALSE{
  283.                 //Correct 301 errors for local image download
  284.                 $this->_weather_array['icon_url_base'str_replace('weather.gov''www.weather.gov'$this->_weather_array['icon_url_base']);
  285.             }
  286.             $this->_weather_array['credit_image'$this->_weather_array['url'];
  287.             unset($this->_weather_array['url']);
  288.             unset($this->_weather_array['image']);
  289.             unset($this->_weather_array['current_observation']);
  290.             ksort($this->_weather_array);
  291.  
  292.             //--- Integrity Check
  293.             $size count($this->_weather_array);
  294.             if ($size !== 43{
  295.                 $this->setError(TRUE'Incomplete weather data retrieved.'"Only $size of 43 weather elements appear in the Weather::_weather_array.");
  296.                 $stat FALSE;
  297.             }
  298.         }
  299.  
  300.         return $stat;
  301.     }
  302.  
  303.     /**
  304.      * Convert XML weather station data to array
  305.      *
  306.      * @access protected
  307.      * @return boolean success status
  308.      */
  309.     protected function _setStationArray({
  310.         $stat FALSE;
  311.         $this->_station_array = array();
  312.  
  313.         $cache_dir $this->getCacheDir();
  314.         $cache_file  $cache_dir 'stations.dat';
  315.         $now time();
  316.         if (!is_null($cache_dir&& file_exists($cache_file)) {
  317.             if (filemtime($cache_file($this->getCacheTimeSid(60>= $now{
  318.                 $this->_station_array = unserialize(file_get_contents($cache_file));
  319.                 $stat TRUE;
  320.             }
  321.         }
  322.  
  323.         if (!$stat{
  324.             $values array();
  325.             $xml_parser xml_parser_create();
  326.             xml_parse_into_struct($xml_parser$this->getXml()$values);
  327.             xml_parser_free($xml_parser);
  328.  
  329.             $sid '';
  330.             $state '';
  331.             set_time_limit(600);
  332.             foreach (new ArrayObject($valuesas $xml_elem{
  333.                 foreach (new ArrayObject($xml_elemas $sub_elem{
  334.                     if($xml_elem['tag'== 'STATION_ID'{
  335.                         $sid $xml_elem['value'];
  336.                         break;
  337.                     elseif($xml_elem['tag'== 'STATE'{
  338.                         $state $xml_elem['value'];
  339.                         break;
  340.                     elseif($xml_elem['tag'== 'STATION_NAME'{
  341.                         $this->_station_array[$state][$sid$xml_elem['value'];
  342.                         $sid '';
  343.                         $state '';
  344.                         break;
  345.                     }
  346.                 }
  347.             }
  348.             $stat FALSE;
  349.         }
  350.  
  351.         return $stat;
  352.     }
  353.  
  354.     /**
  355.      * Serializes weather station data array and saves it to cache_dir
  356.      *
  357.      * @access protected
  358.      * @return boolean success status
  359.      */
  360.     protected function _setStationCache({
  361.         $stat FALSE;
  362.  
  363.         if (!is_null($this->getCacheDir())) {
  364.             $cache_file $this->getCacheDir('stations.dat';
  365.             file_put_contents($cache_fileserialize($this->getStationArray())LOCK_EX);
  366.             @chmod($cache_file0666);
  367.         }
  368.  
  369.         return (boolean) $stat;
  370.     }
  371.  
  372.     /**
  373.      * Set the weather xml data.
  374.      *
  375.      * @access protected
  376.      * @param string 
  377.      * @return NULL 
  378.      */
  379.     protected function setXml($a{
  380.         $this->_xml = $a;
  381.     }
  382.  
  383.     /***********************/
  384.     /***** Get Methods *****/
  385.     /***********************/
  386.  
  387.     /**
  388.      * Get the local XML data cache directory.
  389.      *
  390.      * @return string $this->_cache_dir
  391.      */
  392.     public function getCacheDir({
  393.         return $this->_cache_dir;
  394.     }
  395.  
  396.     /**
  397.      * Get the local cache valid time in minutes.
  398.      *
  399.      * @return int $this->_cache_time
  400.      */
  401.     public function getCacheTime({
  402.         return $this->_cache_time;
  403.     }
  404.  
  405.     /**
  406.      * Get the local station cache valid time in minutes.
  407.      *
  408.      * @return int $this->_cache_time_sid
  409.      */
  410.     public function getCacheTimeSid({
  411.         return $this->_cache_time_sid;
  412.     }
  413.  
  414.     /**
  415.      * Get the error status and messages.
  416.      *
  417.      * @return array $this->_error, $this->_error_msg_user, $this->_error_msg_debug
  418.      */
  419.     public function getError({
  420.         return array('error'        => $this->_error,
  421.                      'user_msg'        => $this->_error_msg_user,
  422.                      'debug_msg'    => $this->_error_msg_debug);
  423.     }
  424.  
  425.     /**
  426.      * Get the local conditions image directory.
  427.      *
  428.      * @return string $this->_image_dir
  429.      */
  430.     public function getImageDir({
  431.         return $this->_image_dir;
  432.     }
  433.  
  434.     /**
  435.      * Get the weather observation station.
  436.      *
  437.      * @return string $this->_obs_station
  438.      */
  439.     public function getObsStation({
  440.         return $this->_obs_station;
  441.     }
  442.  
  443.     /**
  444.      * Get the weather service URL.
  445.      *
  446.      * @return string $this->_url
  447.      */
  448.     public function getUrl({
  449.         return $this->_url;
  450.     }
  451.  
  452.     /**
  453.      * Get the weather data array.
  454.      *
  455.      * @return string $this->_weather_array
  456.      */
  457.     public function getWeatherArray({
  458.         return $this->_weather_array;
  459.     }
  460.  
  461.     /**
  462.      * Get the weather station data array.
  463.      *
  464.      * @return string $this->_station_array
  465.      */
  466.     public function getStationArray({
  467.         return $this->_station_array;
  468.     }
  469.  
  470.     /**
  471.      * Get the weather stations from the station data array.
  472.      *
  473.      * @param string $state The location's stations.
  474.      * @return array $this->_station_array[$state]
  475.      */
  476.     public function getStations($state{
  477.         return $this->_station_array[$state];
  478.     }
  479.  
  480.     /**
  481.      * Get a single element from the weather data array.
  482.      *
  483.      * @param string $a 
  484.      * @return string $this->_weather_array[$a]
  485.      */
  486.     public function getWeatherElement($a{
  487.         if (array_key_exists($a$this->_weather_array)) {
  488.             return $this->_weather_array[$a];
  489.         else {
  490.             return NULL;
  491.         }
  492.     }
  493.  
  494.     /**
  495.      * Get an array of all available data points from the weather data array.
  496.      *
  497.      * @return array Array keys from $this->_weather_array.
  498.      */
  499.     public function getWeatherElements({
  500.         if (isset($this->_weather_array)) {
  501.             return array_keys($this->_weather_array);
  502.         else {
  503.             return NULL;
  504.         }
  505.     }
  506.  
  507.     /**
  508.      * Retrieve XML weather data
  509.      *
  510.      * @access protected
  511.      * @param string $station_id Optional station ID.  Default is getObsStation().
  512.      * @param int $cache_time Optional cache_time override
  513.      * @return boolean success status
  514.      */
  515.     protected function _getWeatherXml($station_id NULL$cache_time = -1{
  516.         $station_id (is_null($station_id)) $this->getObsStation($station_id;
  517.         $cache_dir  $this->getCacheDir();
  518.         $cache_file $cache_dir $station_id '.xml';
  519.         $cache_time ($cache_time === -1$this->getCacheTime($cache_time;
  520.         $now time();
  521.         $stat FALSE;
  522.         if (!is_null($cache_dir&& file_exists($cache_file)) {
  523.             if (filemtime($cache_file($cache_time 60>= $now{
  524.                 $this->setXml(file_get_contents($cache_file));
  525.                 $stat TRUE;
  526.             }
  527.         }
  528.         if (!$stat{
  529.             $curl curl_init();
  530.             curl_setopt($curlCURLOPT_URL$this->getUrl($station_id '.xml');
  531.             curl_setopt($curlCURLOPT_HEADERFALSE);
  532.             curl_setopt($curlCURLOPT_RETURNTRANSFERTRUE);
  533.             $xml curl_exec($curl);
  534.             if (curl_errno($curl)) {
  535.                 $u 'An error has occurred retrieving the weather XML data.';
  536.                 $d 'cURL Error in Weather::_getXML: ' curl_error($curl);
  537.                 $this->setError(TRUE$u$d);
  538.                 $stat FALSE;
  539.             else {
  540.                 if (!is_null($cache_dir)) {
  541.                     file_put_contents($cache_file$xmlLOCK_EX);
  542.                     @chmod($cache_file0666);
  543.                 }
  544.                 $this->setXml($xml);
  545.                 $stat TRUE;
  546.             }
  547.             curl_close($curl);
  548.         }
  549.  
  550.         return $stat;
  551.     }
  552.  
  553.     /**
  554.      * Retrieve XML weather station data
  555.      *
  556.      * @access protected
  557.      * @return boolean success status
  558.      */
  559.     protected function _getWeatherStationXml({
  560.         return $this->_getWeatherXml('index'$this->getCacheTimeSid());
  561.     }
  562.  
  563.     /**
  564.      * Get the weather xml data.
  565.      *
  566.      * @return string $this->_xml
  567.      */
  568.     public function getXml({
  569.         return $this->_xml;
  570.     }
  571.  
  572.  
  573.     /*************************/
  574.     /***** Other Methods *****/
  575.     /*************************/
  576.  
  577.     /**
  578.      * Return an array dump of the (parsed XML) weather data
  579.      *
  580.      * @return array 
  581.      */
  582.     public function __toArray({
  583.         return print_r($this->getWeatherArray()TRUE);
  584.     }
  585.  
  586.     /**
  587.      * Return a dump of the XML data
  588.      *
  589.      * @return array 
  590.      */
  591.     public function __toString({
  592.         return print_r($this->getXml()TRUE);
  593.     }
  594. }
  595. ?>

Documentation generated on Sun, 18 Mar 2007 09:38:32 -0400 by phpDocumentor 1.3.1