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-2009, 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-2009 Alexander Wirtz
  42.  * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
  43.  * @version     CVS: $Id: Ejse.php,v 1.28 2009/03/12 23:16:41 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-2009 Alexander Wirtz
  66.  * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
  67.  * @version     Release: 1.4.4
  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.      * Username at ejse.com
  76.      *
  77.      * @var     string                      $_username 
  78.      * @access  private
  79.      */
  80.     var $_username "";
  81.  
  82.     /**
  83.      * Password key at ejse.com
  84.      *
  85.      * @var     string                      $_password 
  86.      * @access  private
  87.      */
  88.     var $_password "";
  89.  
  90.     /**
  91.      * WSDL object, provided by EJSE
  92.      *
  93.      * @var     object                      $_wsdl 
  94.      * @access  private
  95.      */
  96.     var $_wsdl;
  97.  
  98.     /**
  99.      * SOAP object to access weather data, provided by EJSE
  100.      *
  101.      * @var     object                      $_weaterSoap 
  102.      * @access  private
  103.      */
  104.     var $_weatherSoap;
  105.     // }}}
  106.  
  107.     // {{{ constructor
  108.     /**
  109.      * Constructor
  110.      *
  111.      * Requires SOAP to be installed
  112.      *
  113.      * @param   array                       $options 
  114.      * @param   mixed                       $error 
  115.      * @throws  PEAR_Error
  116.      * @access  private
  117.      */
  118.     function Services_Weather_Ejse($options&$error)
  119.     {
  120.         $perror = null;
  121.         $this->Services_Weather_Common($options$perror);
  122.         if (Services_Weather::isError($perror)) {
  123.             $error $perror;
  124.         }
  125.     }
  126.     // }}}
  127.  
  128.     // {{{ _connectServer()
  129.     /**
  130.      * Connects to the SOAP server and retrieves the WSDL data
  131.      *
  132.      * @return  PEAR_Error|bool
  133.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
  134.      * @access  private
  135.      */
  136.     function _connectServer()
  137.     {
  138.         include_once "SOAP/Client.php";
  139.         $this->_wsdl = new SOAP_WSDL("http://www.ejse.com/WeatherService/Service.asmx?WSDL"$this->_httpOptions);
  140.         if (isset($this->_wsdl->fault&& Services_Weather::isError($this->_wsdl->fault)) {
  141.             $error Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA__FILE____LINE__);
  142.             return $error;
  143.         }
  144.  
  145.         eval($this->_wsdl->generateAllProxies());
  146.         if (!class_exists("WebService_Service_ServiceSoap")) {
  147.             $error Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA__FILE____LINE__);
  148.             return $error;
  149.         }
  150.         $this->_weatherSoap &new WebService_Service_ServiceSoap;
  151.  
  152.         return true;
  153.     }
  154.     // }}}
  155.  
  156.     // {{{ setAccountData()
  157.     /**
  158.      * Sets the neccessary account-information for ejse.com, you'll
  159.      * receive them after registering for the service
  160.      *
  161.      * @param   string                      $username 
  162.      * @param   string                      $password 
  163.      * @access  public
  164.      */
  165.     function setAccountData($username$password)
  166.     {
  167.         if (strlen($username)) {
  168.             $this->_username  $username;
  169.         }
  170.         if (strlen($password&& ctype_alnum($password)) {
  171.             $this->_password $password;
  172.         }
  173.     }
  174.     // }}}
  175.  
  176.     // {{{ _checkLocationID()
  177.     /**
  178.      * Checks the id for valid values and thus prevents silly requests to EJSE server
  179.      *
  180.      * @param   string                      $id 
  181.      * @return  PEAR_Error|bool
  182.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_NO_LOCATION
  183.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_INVALID_LOCATION
  184.      * @access  private
  185.      */
  186.     function _checkLocationID($id)
  187.     {
  188.         if (is_array($id|| is_object($id|| !strlen($id)) {
  189.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_NO_LOCATION__FILE____LINE__);
  190.         elseif (!ctype_digit($id|| (strlen($id!= 5)) {
  191.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_INVALID_LOCATION__FILE____LINE__);
  192.         }
  193.  
  194.         return true;
  195.     }
  196.     // }}}
  197.  
  198.     // {{{ searchLocation()
  199.     /**
  200.      * EJSE offers no search function to date, so this function is disabled.
  201.      * Maybe this is the place to interface to some online postcode service...
  202.      *
  203.      * @param   string                      $location 
  204.      * @param   bool                        $useFirst 
  205.      * @return  bool 
  206.      * @access  public
  207.      * @deprecated
  208.      */
  209.     function searchLocation($location = null$useFirst = null)
  210.     {
  211.         return false;
  212.     }
  213.     // }}}
  214.  
  215.     // {{{ searchLocationByCountry()
  216.     /**
  217.      * EJSE offers no search function to date, so this function is disabled.
  218.      * Maybe this is the place to interface to some online postcode service...
  219.      *
  220.      * @param   string                      $country 
  221.      * @return  bool 
  222.      * @access  public
  223.      * @deprecated
  224.      */
  225.     function searchLocationByCountry($country = null)
  226.     {
  227.         return false;
  228.     }
  229.     // }}}
  230.  
  231.     // {{{ getLocation()
  232.     /**
  233.      * Returns the data for the location belonging to the ID
  234.      *
  235.      * @param   string                      $id 
  236.      * @return  PEAR_Error|array
  237.      * @throws  PEAR_Error
  238.      * @access  public
  239.      */
  240.     function getLocation($id "")
  241.     {
  242.         $status $this->_checkLocationID($id);
  243.  
  244.         if (Services_Weather::isError($status)) {
  245.             return $status;
  246.         }
  247.  
  248.         $locationReturn = array();
  249.  
  250.         if ($this->_cacheEnabled && ($weather $this->_cache->get($id"weather"))) {
  251.             // Get data from cache
  252.             $this->_weather $weather;
  253.             $locationReturn["cache""HIT";
  254.         else {
  255.             // Check, if the weatherSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  256.             if (!$this->_weatherSoap{
  257.                 $status $this->_connectServer();
  258.                 if (Services_Weather::isError($status)) {
  259.                     return $status;
  260.                 }
  261.             }
  262.  
  263.             $weather $this->_weatherSoap->getWeatherInfo2($this->_username$this->_password$id);
  264.  
  265.             if (Services_Weather::isError($weather)) {
  266.                 return $weather;
  267.             }
  268.  
  269.             $this->_weather $weather;
  270.  
  271.             if ($this->_cacheEnabled{
  272.                 // ...and cache it
  273.                 $expire constant("SERVICES_WEATHER_EXPIRES_WEATHER");
  274.                 $this->_cache->extSave($id$this->_weather""$expire"weather");
  275.             }
  276.             $locationReturn["cache""MISS";
  277.         }
  278.         $locationReturn["name"$this->_weather->Location;
  279.  
  280.         return $locationReturn;
  281.     }
  282.     // }}}
  283.  
  284.     // {{{ getWeather()
  285.     /**
  286.      * Returns the weather-data for the supplied location
  287.      *
  288.      * @param   string                      $id 
  289.      * @param   string                      $unitsFormat 
  290.      * @return  PEAR_Error|array
  291.      * @throws  PEAR_Error
  292.      * @access  public
  293.      */
  294.     function getWeather($id ""$unitsFormat "")
  295.     {
  296.         $status $this->_checkLocationID($id);
  297.  
  298.         if (Services_Weather::isError($status)) {
  299.             return $status;
  300.         }
  301.  
  302.         // Get other data
  303.         $units    $this->getUnitsFormat($unitsFormat);
  304.  
  305.         $weatherReturn = array();
  306.         if ($this->_cacheEnabled && ($weather $this->_cache->get($id"weather"))) {
  307.             // Same procedure...
  308.             $this->_weather $weather;
  309.             $weatherReturn["cache""HIT";
  310.         else {
  311.             // Check, if the weatherSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  312.             if (!$this->_weatherSoap{
  313.                 $status $this->_connectServer();
  314.                 if (Services_Weather::isError($status)) {
  315.                     return $status;
  316.                 }
  317.             }
  318.  
  319.             // ...as last function
  320.             $weather $this->_weatherSoap->getWeatherInfo2($this->_username$this->_password$id);
  321.  
  322.             if (Services_Weather::isError($weather)) {
  323.                 return $weather;
  324.             }
  325.  
  326.             $this->_weather $weather;
  327.  
  328.             if ($this->_cacheEnabled{
  329.                 // ...and cache it
  330.                 $expire constant("SERVICES_WEATHER_EXPIRES_WEATHER");
  331.                 $this->_cache->extSave($id$this->_weather""$expire"weather");
  332.             }
  333.             $weatherReturn["cache""MISS";
  334.         }
  335.  
  336.         if (!isset($compass)) {
  337.             // Yes, NNE and the likes are multiples of 22.5, but as the other
  338.             // services return integers for this value, these directions are
  339.             // rounded up
  340.             $compass = array(
  341.                 "north"             => array("N",     0),
  342.                 "north northeast"   => array("NNE",  23),
  343.                 "northeast"         => array("NE",   45),
  344.                 "east northeast"    => array("ENE",  68),
  345.                 "east"              => array("E",    90),
  346.                 "east southeast"    => array("ESE"113),
  347.                 "southeast"         => array("SE",  135),
  348.                 "south southeast"   => array("SSE"158),
  349.                 "south"             => array("S",   180),
  350.                 "south southwest"   => array("SSW"203),
  351.                 "southwest"         => array("SW",  225),
  352.                 "west southwest"    => array("WSW"248),
  353.                 "west"              => array("W",   270),
  354.                 "west northwest"    => array("WNW"293),
  355.                 "northwest"         => array("NW",  315),
  356.                 "north northwest"   => array("NNW"338)
  357.             );
  358.         }
  359.  
  360.         // Initialize some arrays
  361.         $update             = array();
  362.         $temperature        = array();
  363.         $feltTemperature    = array();
  364.         $visibility         = array();
  365.         $pressure           = array();
  366.         $dewPoint           = array();
  367.         $uvIndex            = array();
  368.         $wind               = array();
  369.  
  370.         if (preg_match("/(\w+) (\d+), (\d+), at (\d+:\d+ \wM) [^\(]+(\(([^\)]+)\))?/"$this->_weather->LastUpdated$update)) {
  371.             if (isset($update[5])) {
  372.                 $timestring $update[6];
  373.             else {
  374.                 $timestring $update[2]." ".$update[1]." ".$update[3]." ".$update[4]." EST";
  375.             }
  376.             $weatherReturn["update"]            gmdate(trim($this->_dateFormat." ".$this->_timeFormat)strtotime($timestring));
  377.         else {
  378.             $weatherReturn["update"]            "";
  379.         }
  380.         $weatherReturn["updateRaw"]         $this->_weather->LastUpdated;
  381.         $weatherReturn["station"]           $this->_weather->ReportedAt;
  382.         $weatherReturn["conditionIcon"]     $this->_weather->IconIndex;
  383.         preg_match("/(-?\d+)\D+/"$this->_weather->Temprature$temperature);
  384.         $weatherReturn["temperature"]       $this->convertTemperature($temperature[1]"f"$units["temp"]);
  385.         preg_match("/(-?\d+)\D+/"$this->_weather->FeelsLike$feltTemperature);
  386.         $weatherReturn["feltTemperature"]   $this->convertTemperature($feltTemperature[1]"f"$units["temp"]);
  387.         $weatherReturn["condition"]         $this->_weather->Forecast;
  388.         if (preg_match("/([\d\.]+)\D+/"$this->_weather->Visibility$visibility)) {
  389.             $weatherReturn["visibility"]    $this->convertDistance($visibility[1]"sm"$units["vis"]);
  390.         else {
  391.             $weatherReturn["visibility"]    trim($this->_weather->Visibility);
  392.         }
  393.         preg_match("/([\d\.]+) inches and (\w+)/"$this->_weather->Pressure$pressure);
  394.         $weatherReturn["pressure"]          $this->convertPressure($pressure[1]"in"$units["pres"]);
  395.         $weatherReturn["pressureTrend"]     $pressure[2];
  396.         preg_match("/(-?\d+)\D+/"$this->_weather->DewPoint$dewPoint);
  397.         $weatherReturn["dewPoint"]          $this->convertTemperature($dewPoint[1]"f"$units["temp"]);
  398.         preg_match("/(\d+) (\w+)/"$this->_weather->UVIndex$uvIndex);
  399.         $weatherReturn["uvIndex"]           $uvIndex[1];
  400.         $weatherReturn["uvText"]            $uvIndex[2];
  401.         $weatherReturn["humidity"]          str_replace("%"""$this->_weather->Humidity);
  402.         if (preg_match("/From the ([\w\ ]+) at ([\d\.]+) (gusting to ([\d\.]+) )?mph/"$this->_weather->Wind$wind)) {
  403.             $weatherReturn["wind"]              $this->convertSpeed($wind[2]"mph"$units["wind"]);
  404.             if (isset($wind[4])) {
  405.                 $weatherReturn["windGust"]      $this->convertSpeed($wind[4]"mph"$units["wind"]);
  406.             }
  407.             $weatherReturn["windDegrees"]       $compass[strtolower($wind[1])][1];
  408.             $weatherReturn["windDirection"]     $compass[strtolower($wind[1])][0];
  409.         elseif (strtolower($this->_weather->Wind== "calm"{
  410.             $weatherReturn["wind"]          = 0;
  411.             $weatherReturn["windDegrees"]   = 0;
  412.             $weatherReturn["windDirection""CALM";
  413.         }
  414.  
  415.         return $weatherReturn;
  416.     }
  417.     // }}}
  418.  
  419.     // {{{ getForecast()
  420.     /**
  421.      * Get the forecast for the next days
  422.      *
  423.      * @param   string                      $int 
  424.      * @param   int                         $days           Values between 1 and 9
  425.      * @param   string                      $unitsFormat 
  426.      * @return  PEAR_Error|array
  427.      * @throws  PEAR_Error
  428.      * @access  public
  429.      */
  430.     function getForecast($id ""$days = 2$unitsFormat "")
  431.     {
  432.         $status $this->_checkLocationID($id);
  433.  
  434.         if (Services_Weather::isError($status)) {
  435.             return $status;
  436.         }
  437.         if (!in_array($daysrange(19))) {
  438.             $days = 2;
  439.         }
  440.  
  441.         // Get other data
  442.         $units    $this->getUnitsFormat($unitsFormat);
  443.  
  444.         $forecastReturn = array();
  445.         if ($this->_cacheEnabled && ($forecast $this->_cache->get($id"forecast"))) {
  446.             // Same procedure...
  447.             $this->_forecast $forecast;
  448.             $forecastReturn["cache""HIT";
  449.         else {
  450.             // Check, if the weatherSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  451.             if (!$this->_weatherSoap{
  452.                 $status $this->_connectServer();
  453.                 if (Services_Weather::isError($status)) {
  454.                     return $status;
  455.                 }
  456.             }
  457.  
  458.             // ...as last function
  459.             $forecast $this->_weatherSoap->GetNineDayForecastInfo2($this->_username$this->_password$id);
  460.  
  461.             if (Services_Weather::isError($forecast)) {
  462.                 return $forecast;
  463.             }
  464.  
  465.             $this->_forecast $forecast;
  466.  
  467.             if ($this->_cacheEnabled{
  468.                 // ...and cache it
  469.                 $expire constant("SERVICES_WEATHER_EXPIRES_FORECAST");
  470.                 $this->_cache->extSave($id$this->_forecast""$expire"forecast");
  471.             }
  472.             $forecastReturn["cache""MISS";
  473.         }
  474.  
  475.         $forecastReturn["days"]   = array();
  476.  
  477.         // Initialize some arrays
  478.         $temperatureHigh    = array();
  479.         $temperatureLow     = array();
  480.  
  481.         for ($i = 1; $i <= $days$i++{
  482.             preg_match("/(-?\d+)\D+/"$this->_forecast->{"Day".$i}->High$temperatureHigh);
  483.             preg_match("/(-?\d+)\D+/"$this->_forecast->{"Day".$i}->Low$temperatureLow);
  484.             $day = array(
  485.                 "tempertureHigh" => $this->convertTemperature($temperatureHigh[1]"f"$units["temp"]),
  486.                 "temperatureLow" => $this->convertTemperature($temperatureLow[1]"f"$units["temp"]),
  487.                 "day" => array(
  488.                     "condition"     => $this->_forecast->{"Day".$i}->Forecast,
  489.                     "conditionIcon" => $this->_forecast->{"Day".$i}->IconIndex,
  490.                     "precipitation" => trim(str_replace("%"""$this->_forecast->{"Day".$i}->PrecipChance))
  491.                 )
  492.             );
  493.  
  494.             $forecastReturn["days"][$day;
  495.         }
  496.  
  497.         return $forecastReturn;
  498.     }
  499.     // }}}
  500. }
  501. // }}}
  502. ?>

Documentation generated on Thu, 12 Mar 2009 23:30:06 +0000 by phpDocumentor 1.4.2. PEAR Logo Copyright © PHP Group 2004.