Services_Weather
[ class tree: Services_Weather ] [ index: Services_Weather ] [ all elements ]

Source for file Ejse.php

Documentation is available at Ejse.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
  3.  
  4. /**
  5.  * PEAR::Services_Weather_Ejse
  6.  *
  7.  * PHP versions 4 and 5
  8.  *
  9.  * <LICENSE>
  10.  * Copyright (c) 2005, Alexander Wirtz
  11.  * All rights reserved.
  12.  *
  13.  * Redistribution and use in source and binary forms, with or without
  14.  * modification, are permitted provided that the following conditions
  15.  * are met:
  16.  * o Redistributions of source code must retain the above copyright notice,
  17.  *   this list of conditions and the following disclaimer.
  18.  * o Redistributions in binary form must reproduce the above copyright notice,
  19.  *   this list of conditions and the following disclaimer in the documentation
  20.  *   and/or other materials provided with the distribution.
  21.  * o Neither the name of the software nor the names of its contributors
  22.  *   may be used to endorse or promote products derived from this software
  23.  *   without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  26.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  29.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  30.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  31.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  32.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  34.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  35.  * POSSIBILITY OF SUCH DAMAGE.
  36.  * </LICENSE>
  37.  *
  38.  * @category    Web Services
  39.  * @package     Services_Weather
  40.  * @author      Alexander Wirtz <alex@pc4p.net>
  41.  * @copyright   2005 Alexander Wirtz
  42.  * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
  43.  * @version     CVS: $Id: Ejse.php,v 1.23 2005/11/13 21:56:16 eru Exp $
  44.  * @link        http://pear.php.net/package/Services_Weather
  45.  * @link        http://www.ejse.com/services/weather_xml_web_services.htm
  46.  * @example     examples/ejse-basic.php             ejse-basic.php
  47.  * @filesource
  48.  */
  49.  
  50. require_once "Services/Weather/Common.php";
  51.  
  52. // {{{ class Services_Weather_Ejse
  53. /**
  54.  * This class acts as an interface to the soap service of EJSE. It retrieves
  55.  * current weather data and forecasts based on postal codes (ZIP).
  56.  *
  57.  * Currently this service is only available for US territory.
  58.  *
  59.  * For a working example, please take a look at
  60.  *     docs/Services_Weather/examples/ejse-basic.php
  61.  *
  62.  * @category    Web Services
  63.  * @package     Services_Weather
  64.  * @author      Alexander Wirtz <alex@pc4p.net>
  65.  * @copyright   2005 Alexander Wirtz
  66.  * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
  67.  * @version     Release: 1.4.0
  68.  * @link        http://pear.php.net/package/Services_Weather
  69.  * @link        http://www.ejse.com/services/weather_xml_web_services.htm
  70.  * @example     examples/ejse-basic.php             ejse-basic.php
  71.  */
  72.  
  73.     // {{{ properties
  74.     /**
  75.      * WSDL object, provided by EJSE
  76.      *
  77.      * @var     object                      $_wsdl 
  78.      * @access  private
  79.      */
  80.     var $_wsdl;
  81.  
  82.     /**
  83.      * SOAP object to access weather data, provided by EJSE
  84.      *
  85.      * @var     object                      $_weaterSoap 
  86.      * @access  private
  87.      */
  88.     var $_weatherSoap;
  89.     // }}}
  90.  
  91.     // {{{ constructor
  92.     /**
  93.      * Constructor
  94.      *
  95.      * Requires SOAP to be installed
  96.      *
  97.      * @param   array                       $options 
  98.      * @param   mixed                       $error 
  99.      * @throws  PEAR_Error
  100.      * @access  private
  101.      */
  102.     function Services_Weather_Ejse($options&$error)
  103.     {
  104.         $perror = null;
  105.         $this->Services_Weather_Common($options$perror);
  106.         if (Services_Weather::isError($perror)) {
  107.             $error $perror;
  108.         }
  109.     }
  110.     // }}}
  111.  
  112.     // {{{ _connectServer()
  113.     /**
  114.      * Connects to the SOAP server and retrieves the WSDL data
  115.      *
  116.      * @return  PEAR_Error|bool
  117.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
  118.      * @access  private
  119.      */
  120.     function _connectServer()
  121.     {
  122.         include_once "SOAP/Client.php";
  123.         $this->_wsdl = new SOAP_WSDL("http://www.ejse.com/WeatherService/Service.asmx?WSDL"$this->_httpOptions);
  124.         if (isset($this->_wsdl->fault&& Services_Weather::isError($this->_wsdl->fault)) {
  125.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA__FILE____LINE__);
  126.         }
  127.  
  128.         eval($this->_wsdl->generateAllProxies());
  129.         if (!class_exists("WebService_Service_ServiceSoap")) {
  130.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA__FILE____LINE__);
  131.         }
  132.         $this->_weatherSoap &new WebService_Service_ServiceSoap;
  133.  
  134.         return true;
  135.     }
  136.     // }}}
  137.  
  138.     // {{{ _checkLocationID()
  139.     /**
  140.      * Checks the id for valid values and thus prevents silly requests to EJSE server
  141.      *
  142.      * @param   string                      $id 
  143.      * @return  PEAR_Error|bool
  144.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_NO_LOCATION
  145.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_INVALID_LOCATION
  146.      * @access  private
  147.      */
  148.     function _checkLocationID($id)
  149.     {
  150.         if (is_array($id|| is_object($id|| !strlen($id)) {
  151.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_NO_LOCATION__FILE____LINE__);
  152.         elseif (!ctype_digit($id|| (strlen($id!= 5)) {
  153.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_INVALID_LOCATION__FILE____LINE__);
  154.         }
  155.  
  156.         return true;
  157.     }
  158.     // }}}
  159.  
  160.     // {{{ searchLocation()
  161.     /**
  162.      * EJSE offers no search function to date, so this function is disabled.
  163.      * Maybe this is the place to interface to some online postcode service...
  164.      *
  165.      * @param   string                      $location 
  166.      * @param   bool                        $useFirst 
  167.      * @return  bool 
  168.      * @access  public
  169.      * @deprecated
  170.      */
  171.     function searchLocation($location = null$useFirst = null)
  172.     {
  173.         return false;
  174.     }
  175.     // }}}
  176.  
  177.     // {{{ searchLocationByCountry()
  178.     /**
  179.      * EJSE offers no search function to date, so this function is disabled.
  180.      * Maybe this is the place to interface to some online postcode service...
  181.      *
  182.      * @param   string                      $country 
  183.      * @return  bool 
  184.      * @access  public
  185.      * @deprecated
  186.      */
  187.     function searchLocationByCountry($country = null)
  188.     {
  189.         return false;
  190.     }
  191.     // }}}
  192.  
  193.     // {{{ getLocation()
  194.     /**
  195.      * Returns the data for the location belonging to the ID
  196.      *
  197.      * @param   string                      $id 
  198.      * @return  PEAR_Error|array
  199.      * @throws  PEAR_Error
  200.      * @access  public
  201.      */
  202.     function getLocation($id "")
  203.     {
  204.         $status $this->_checkLocationID($id);
  205.  
  206.         if (Services_Weather::isError($status)) {
  207.             return $status;
  208.         }
  209.  
  210.         $locationReturn = array();
  211.  
  212.         if ($this->_cacheEnabled && ($weather $this->_cache->get($id"weather"))) {
  213.             // Get data from cache
  214.             $this->_weather $weather;
  215.             $locationReturn["cache""HIT";
  216.         else {
  217.             // Check, if the weatherSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  218.             if (!$this->_weatherSoap{
  219.                 $status $this->_connectServer();
  220.                 if (Services_Weather::isError($status)) {
  221.                     return $status;
  222.                 }
  223.             }
  224.  
  225.             $weather $this->_weatherSoap->getWeatherInfo($id);
  226.  
  227.             if (Services_Weather::isError($weather)) {
  228.                 return $weather;
  229.             }
  230.  
  231.             $this->_weather $weather;
  232.  
  233.             if ($this->_cacheEnabled{
  234.                 // ...and cache it
  235.                 $expire constant("SERVICES_WEATHER_EXPIRES_WEATHER");
  236.                 $this->_cache->extSave($id$this->_weather""$expire"weather");
  237.             }
  238.             $locationReturn["cache""MISS";
  239.         }
  240.         $locationReturn["name"$this->_weather->Location;
  241.  
  242.         return $locationReturn;
  243.     }
  244.     // }}}
  245.  
  246.     // {{{ getWeather()
  247.     /**
  248.      * Returns the weather-data for the supplied location
  249.      *
  250.      * @param   string                      $id 
  251.      * @param   string                      $unitsFormat 
  252.      * @return  PEAR_Error|array
  253.      * @throws  PEAR_Error
  254.      * @access  public
  255.      */
  256.     function getWeather($id ""$unitsFormat "")
  257.     {
  258.         $status $this->_checkLocationID($id);
  259.  
  260.         if (Services_Weather::isError($status)) {
  261.             return $status;
  262.         }
  263.  
  264.         // Get other data
  265.         $units    $this->getUnitsFormat($unitsFormat);
  266.  
  267.         $weatherReturn = array();
  268.         if ($this->_cacheEnabled && ($weather $this->_cache->get($id"weather"))) {
  269.             // Same procedure...
  270.             $this->_weather $weather;
  271.             $weatherReturn["cache""HIT";
  272.         else {
  273.             // Check, if the weatherSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  274.             if (!$this->_weatherSoap{
  275.                 $status $this->_connectServer();
  276.                 if (Services_Weather::isError($status)) {
  277.                     return $status;
  278.                 }
  279.             }
  280.  
  281.             // ...as last function
  282.             $weather $this->_weatherSoap->getWeatherInfo($id);
  283.  
  284.             if (Services_Weather::isError($weather)) {
  285.                 return $weather;
  286.             }
  287.  
  288.             $this->_weather $weather;
  289.  
  290.             if ($this->_cacheEnabled{
  291.                 // ...and cache it
  292.                 $expire constant("SERVICES_WEATHER_EXPIRES_WEATHER");
  293.                 $this->_cache->extSave($id$this->_weather""$expire"weather");
  294.             }
  295.             $weatherReturn["cache""MISS";
  296.         }
  297.  
  298.         if (!isset($compass)) {
  299.             // Yes, NNE and the likes are multiples of 22.5, but as the other
  300.             // services return integers for this value, these directions are
  301.             // rounded up
  302.             $compass = array(
  303.                 "north"             => array("N",     0),
  304.                 "north northeast"   => array("NNE",  23),
  305.                 "northeast"         => array("NE",   45),
  306.                 "east northeast"    => array("ENE",  68),
  307.                 "east"              => array("E",    90),
  308.                 "east southeast"    => array("ESE"113),
  309.                 "southeast"         => array("SE",  135),
  310.                 "south southeast"   => array("SSE"158),
  311.                 "south"             => array("S",   180),
  312.                 "south southwest"   => array("SSW"203),
  313.                 "southwest"         => array("SW",  225),
  314.                 "west southwest"    => array("WSW"248),
  315.                 "west"              => array("W",   270),
  316.                 "west northwest"    => array("WNW"293),
  317.                 "northwest"         => array("NW",  315),
  318.                 "north northwest"   => array("NNW"338)
  319.             );
  320.         }
  321.  
  322.         // Initialize some arrays
  323.         $update             = array();
  324.         $temperature        = array();
  325.         $feltTemperature    = array();
  326.         $visibility         = array();
  327.         $pressure           = array();
  328.         $dewPoint           = array();
  329.         $uvIndex            = array();
  330.         $wind               = array();
  331.  
  332.         if (preg_match("/(\w+) (\d+), (\d+), at (\d+:\d+ \wM) [^\(]+(\(([^\)]+)\))?/"$this->_weather->LastUpdated$update)) {
  333.             if (isset($update[5])) {
  334.                 $timestring $update[6];
  335.             else {
  336.                 $timestring $update[2]." ".$update[1]." ".$update[3]." ".$update[4]." EST";
  337.             }
  338.             $weatherReturn["update"]            gmdate(trim($this->_dateFormat." ".$this->_timeFormat)strtotime($timestring));
  339.         else {
  340.             $weatherReturn["update"]            "";
  341.         }
  342.         $weatherReturn["updateRaw"]         $this->_weather->LastUpdated;
  343.         $weatherReturn["station"]           $this->_weather->ReportedAt;
  344.         $weatherReturn["conditionIcon"]     $this->_weather->IconIndex;
  345.         preg_match("/(-?\d+)\D+/"$this->_weather->Temprature$temperature);
  346.         $weatherReturn["temperature"]       $this->convertTemperature($temperature[1]"f"$units["temp"]);
  347.         preg_match("/(-?\d+)\D+/"$this->_weather->FeelsLike$feltTemperature);
  348.         $weatherReturn["feltTemperature"]   $this->convertTemperature($feltTemperature[1]"f"$units["temp"]);
  349.         $weatherReturn["condition"]         $this->_weather->Forecast;
  350.         if (preg_match("/([\d\.]+)\D+/"$this->_weather->Visibility$visibility)) {
  351.             $weatherReturn["visibility"]    $this->convertDistance($visibility[1]"sm"$units["vis"]);
  352.         else {
  353.             $weatherReturn["visibility"]    trim($this->_weather->Visibility);
  354.         }
  355.         preg_match("/([\d\.]+) inches and (\w+)/"$this->_weather->Pressure$pressure);
  356.         $weatherReturn["pressure"]          $this->convertPressure($pressure[1]"in"$units["pres"]);
  357.         $weatherReturn["pressureTrend"]     $pressure[2];
  358.         preg_match("/(-?\d+)\D+/"$this->_weather->DewPoint$dewPoint);
  359.         $weatherReturn["dewPoint"]          $this->convertTemperature($dewPoint[1]"f"$units["temp"]);
  360.         preg_match("/(\d+) (\w+)/"$this->_weather->UVIndex$uvIndex);
  361.         $weatherReturn["uvIndex"]           $uvIndex[1];
  362.         $weatherReturn["uvText"]            $uvIndex[2];
  363.         $weatherReturn["humidity"]          str_replace("%"""$this->_weather->Humidity);
  364.         if (preg_match("/From the ([\w\ ]+) at ([\d\.]+) (gusting to ([\d\.]+) )?mph/"$this->_weather->Wind$wind)) {
  365.             $weatherReturn["wind"]              $this->convertSpeed($wind[2]"mph"$units["wind"]);
  366.             if (isset($wind[4])) {
  367.                 $weatherReturn["windGust"]      $this->convertSpeed($wind[4]"mph"$units["wind"]);
  368.             }
  369.             $weatherReturn["windDegrees"]       $compass[strtolower($wind[1])][1];
  370.             $weatherReturn["windDirection"]     $compass[strtolower($wind[1])][0];
  371.         elseif (strtolower($this->_weather->Wind== "calm"{
  372.             $weatherReturn["wind"]          = 0;
  373.             $weatherReturn["windDegrees"]   = 0;
  374.             $weatherReturn["windDirection""CALM";
  375.         }
  376.  
  377.         return $weatherReturn;
  378.     }
  379.     // }}}
  380.  
  381.     // {{{ getForecast()
  382.     /**
  383.      * Get the forecast for the next days
  384.      *
  385.      * @param   string                      $int 
  386.      * @param   int                         $days           Values between 1 and 9
  387.      * @param   string                      $unitsFormat 
  388.      * @return  PEAR_Error|array
  389.      * @throws  PEAR_Error
  390.      * @access  public
  391.      */
  392.     function getForecast($id ""$days = 2$unitsFormat "")
  393.     {
  394.         $status $this->_checkLocationID($id);
  395.  
  396.         if (Services_Weather::isError($status)) {
  397.             return $status;
  398.         }
  399.         if (!in_array($daysrange(19))) {
  400.             $days = 2;
  401.         }
  402.  
  403.         // Get other data
  404.         $units    $this->getUnitsFormat($unitsFormat);
  405.  
  406.         $forecastReturn = array();
  407.         if ($this->_cacheEnabled && ($forecast $this->_cache->get($id"forecast"))) {
  408.             // Same procedure...
  409.             $this->_forecast $forecast;
  410.             $forecastReturn["cache""HIT";
  411.         else {
  412.             // Check, if the weatherSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  413.             if (!$this->_weatherSoap{
  414.                 $status $this->_connectServer();
  415.                 if (Services_Weather::isError($status)) {
  416.                     return $status;
  417.                 }
  418.             }
  419.  
  420.             // ...as last function
  421.             $forecast $this->_weatherSoap->GetNineDayForecastInfo($id);
  422.  
  423.             if (Services_Weather::isError($forecast)) {
  424.                 return $forecast;
  425.             }
  426.  
  427.             $this->_forecast $forecast;
  428.  
  429.             if ($this->_cacheEnabled{
  430.                 // ...and cache it
  431.                 $expire constant("SERVICES_WEATHER_EXPIRES_FORECAST");
  432.                 $this->_cache->extSave($id$this->_forecast""$expire"forecast");
  433.             }
  434.             $forecastReturn["cache""MISS";
  435.         }
  436.  
  437.         $forecastReturn["days"]   = array();
  438.  
  439.         // Initialize some arrays
  440.         $temperatureHigh    = array();
  441.         $temperatureLow     = array();
  442.  
  443.         for ($i = 1; $i <= $days$i++{
  444.             preg_match("/(-?\d+)\D+/"$this->_forecast->{"Day".$i}->High$temperatureHigh);
  445.             preg_match("/(-?\d+)\D+/"$this->_forecast->{"Day".$i}->Low$temperatureLow);
  446.             $day = array(
  447.                 "tempertureHigh" => $this->convertTemperature($temperatureHigh[1]"f"$units["temp"]),
  448.                 "temperatureLow" => $this->convertTemperature($temperatureLow[1]"f"$units["temp"]),
  449.                 "day" => array(
  450.                     "condition"     => $this->_forecast->{"Day".$i}->Forecast,
  451.                     "conditionIcon" => $this->_forecast->{"Day".$i}->IconIndex,
  452.                     "precipitation" => trim(str_replace("%"""$this->_forecast->{"Day".$i}->PrecipChance))
  453.                 )
  454.             );
  455.  
  456.             $forecastReturn["days"][$day;
  457.         }
  458.  
  459.         return $forecastReturn;
  460.     }
  461.     // }}}
  462. }
  463. // }}}
  464. ?>

Documentation generated on Mon, 11 Mar 2019 14:37:51 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.