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-2011, 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-2011 Alexander Wirtz
  42.  * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
  43.  * @version     CVS: $Id$
  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-2011 Alexander Wirtz
  66.  * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
  67.  * @version     Release: 1.4.7
  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->_getCache($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.                 $this->_saveCache($id$this->_weather"""weather");
  274.             }
  275.             $locationReturn["cache""MISS";
  276.         }
  277.         $locationReturn["name"$this->_weather->Location;
  278.  
  279.         return $locationReturn;
  280.     }
  281.     // }}}
  282.  
  283.     // {{{ getWeather()
  284.     /**
  285.      * Returns the weather-data for the supplied location
  286.      *
  287.      * @param   string                      $id 
  288.      * @param   string                      $unitsFormat 
  289.      * @return  PEAR_Error|array
  290.      * @throws  PEAR_Error
  291.      * @access  public
  292.      */
  293.     function getWeather($id ""$unitsFormat "")
  294.     {
  295.         $status $this->_checkLocationID($id);
  296.  
  297.         if (Services_Weather::isError($status)) {
  298.             return $status;
  299.         }
  300.  
  301.         // Get other data
  302.         $units    $this->getUnitsFormat($unitsFormat);
  303.  
  304.         $weatherReturn = array();
  305.         if ($this->_cacheEnabled && ($weather $this->_getCache($id"weather"))) {
  306.             // Same procedure...
  307.             $this->_weather $weather;
  308.             $weatherReturn["cache""HIT";
  309.         else {
  310.             // Check, if the weatherSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  311.             if (!$this->_weatherSoap{
  312.                 $status $this->_connectServer();
  313.                 if (Services_Weather::isError($status)) {
  314.                     return $status;
  315.                 }
  316.             }
  317.  
  318.             // ...as last function
  319.             $weather $this->_weatherSoap->getWeatherInfo2($this->_username$this->_password$id);
  320.  
  321.             if (Services_Weather::isError($weather)) {
  322.                 return $weather;
  323.             }
  324.  
  325.             $this->_weather $weather;
  326.  
  327.             if ($this->_cacheEnabled{
  328.                 // ...and cache it
  329.                 $this->_saveCache($id$this->_weather"""weather");
  330.             }
  331.             $weatherReturn["cache""MISS";
  332.         }
  333.  
  334.         if (!isset($compass)) {
  335.             // Yes, NNE and the likes are multiples of 22.5, but as the other
  336.             // services return integers for this value, these directions are
  337.             // rounded up
  338.             $compass = array(
  339.                 "north"             => array("N",     0),
  340.                 "north northeast"   => array("NNE",  23),
  341.                 "northeast"         => array("NE",   45),
  342.                 "east northeast"    => array("ENE",  68),
  343.                 "east"              => array("E",    90),
  344.                 "east southeast"    => array("ESE"113),
  345.                 "southeast"         => array("SE",  135),
  346.                 "south southeast"   => array("SSE"158),
  347.                 "south"             => array("S",   180),
  348.                 "south southwest"   => array("SSW"203),
  349.                 "southwest"         => array("SW",  225),
  350.                 "west southwest"    => array("WSW"248),
  351.                 "west"              => array("W",   270),
  352.                 "west northwest"    => array("WNW"293),
  353.                 "northwest"         => array("NW",  315),
  354.                 "north northwest"   => array("NNW"338)
  355.             );
  356.         }
  357.  
  358.         // Initialize some arrays
  359.         $update             = array();
  360.         $temperature        = array();
  361.         $feltTemperature    = array();
  362.         $visibility         = array();
  363.         $pressure           = array();
  364.         $dewPoint           = array();
  365.         $uvIndex            = array();
  366.         $wind               = array();
  367.  
  368.         if (preg_match("/(\w+) (\d+), (\d+), at (\d+:\d+ \wM) [^\(]+(\(([^\)]+)\))?/"$this->_weather->LastUpdated$update)) {
  369.             if (isset($update[5])) {
  370.                 $timestring $update[6];
  371.             else {
  372.                 $timestring $update[2]." ".$update[1]." ".$update[3]." ".$update[4]." EST";
  373.             }
  374.             $weatherReturn["update"]            gmdate(trim($this->_dateFormat." ".$this->_timeFormat)strtotime($timestring));
  375.         else {
  376.             $weatherReturn["update"]            "";
  377.         }
  378.         $weatherReturn["updateRaw"]         $this->_weather->LastUpdated;
  379.         $weatherReturn["station"]           $this->_weather->ReportedAt;
  380.         $weatherReturn["conditionIcon"]     $this->_weather->IconIndex;
  381.         preg_match("/(-?\d+)\D+/"$this->_weather->Temprature$temperature);
  382.         $weatherReturn["temperature"]       $this->convertTemperature($temperature[1]"f"$units["temp"]);
  383.         preg_match("/(-?\d+)\D+/"$this->_weather->FeelsLike$feltTemperature);
  384.         $weatherReturn["feltTemperature"]   $this->convertTemperature($feltTemperature[1]"f"$units["temp"]);
  385.         $weatherReturn["condition"]         $this->_weather->Forecast;
  386.         if (preg_match("/([\d\.]+)\D+/"$this->_weather->Visibility$visibility)) {
  387.             $weatherReturn["visibility"]    $this->convertDistance($visibility[1]"sm"$units["vis"]);
  388.         else {
  389.             $weatherReturn["visibility"]    trim($this->_weather->Visibility);
  390.         }
  391.         preg_match("/([\d\.]+) inches and (\w+)/"$this->_weather->Pressure$pressure);
  392.         $weatherReturn["pressure"]          $this->convertPressure($pressure[1]"in"$units["pres"]);
  393.         $weatherReturn["pressureTrend"]     $pressure[2];
  394.         preg_match("/(-?\d+)\D+/"$this->_weather->DewPoint$dewPoint);
  395.         $weatherReturn["dewPoint"]          $this->convertTemperature($dewPoint[1]"f"$units["temp"]);
  396.         preg_match("/(\d+) (\w+)/"$this->_weather->UVIndex$uvIndex);
  397.         $weatherReturn["uvIndex"]           $uvIndex[1];
  398.         $weatherReturn["uvText"]            $uvIndex[2];
  399.         $weatherReturn["humidity"]          str_replace("%"""$this->_weather->Humidity);
  400.         if (preg_match("/From the ([\w\ ]+) at ([\d\.]+) (gusting to ([\d\.]+) )?mph/"$this->_weather->Wind$wind)) {
  401.             $weatherReturn["wind"]              $this->convertSpeed($wind[2]"mph"$units["wind"]);
  402.             if (isset($wind[4])) {
  403.                 $weatherReturn["windGust"]      $this->convertSpeed($wind[4]"mph"$units["wind"]);
  404.             }
  405.             $weatherReturn["windDegrees"]       $compass[strtolower($wind[1])][1];
  406.             $weatherReturn["windDirection"]     $compass[strtolower($wind[1])][0];
  407.         elseif (strtolower($this->_weather->Wind== "calm"{
  408.             $weatherReturn["wind"]          = 0;
  409.             $weatherReturn["windDegrees"]   = 0;
  410.             $weatherReturn["windDirection""CALM";
  411.         }
  412.  
  413.         return $weatherReturn;
  414.     }
  415.     // }}}
  416.  
  417.     // {{{ getForecast()
  418.     /**
  419.      * Get the forecast for the next days
  420.      *
  421.      * @param   string                      $int 
  422.      * @param   int                         $days           Values between 1 and 9
  423.      * @param   string                      $unitsFormat 
  424.      * @return  PEAR_Error|array
  425.      * @throws  PEAR_Error
  426.      * @access  public
  427.      */
  428.     function getForecast($id ""$days = 2$unitsFormat "")
  429.     {
  430.         $status $this->_checkLocationID($id);
  431.  
  432.         if (Services_Weather::isError($status)) {
  433.             return $status;
  434.         }
  435.         if (!in_array($daysrange(19))) {
  436.             $days = 2;
  437.         }
  438.  
  439.         // Get other data
  440.         $units    $this->getUnitsFormat($unitsFormat);
  441.  
  442.         $forecastReturn = array();
  443.         if ($this->_cacheEnabled && ($forecast $this->_getCache($id"forecast"))) {
  444.             // Same procedure...
  445.             $this->_forecast $forecast;
  446.             $forecastReturn["cache""HIT";
  447.         else {
  448.             // Check, if the weatherSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  449.             if (!$this->_weatherSoap{
  450.                 $status $this->_connectServer();
  451.                 if (Services_Weather::isError($status)) {
  452.                     return $status;
  453.                 }
  454.             }
  455.  
  456.             // ...as last function
  457.             $forecast $this->_weatherSoap->GetNineDayForecastInfo2($this->_username$this->_password$id);
  458.  
  459.             if (Services_Weather::isError($forecast)) {
  460.                 return $forecast;
  461.             }
  462.  
  463.             $this->_forecast $forecast;
  464.  
  465.             if ($this->_cacheEnabled{
  466.                 // ...and cache it
  467.                 $this->_saveCache($id$this->_forecast"""forecast");
  468.             }
  469.             $forecastReturn["cache""MISS";
  470.         }
  471.  
  472.         $forecastReturn["days"]   = array();
  473.  
  474.         // Initialize some arrays
  475.         $temperatureHigh    = array();
  476.         $temperatureLow     = array();
  477.  
  478.         for ($i = 1; $i <= $days$i++{
  479.             preg_match("/(-?\d+)\D+/"$this->_forecast->{"Day".$i}->High$temperatureHigh);
  480.             preg_match("/(-?\d+)\D+/"$this->_forecast->{"Day".$i}->Low$temperatureLow);
  481.             $day = array(
  482.                 "tempertureHigh" => $this->convertTemperature($temperatureHigh[1]"f"$units["temp"]),
  483.                 "temperatureLow" => $this->convertTemperature($temperatureLow[1]"f"$units["temp"]),
  484.                 "day" => array(
  485.                     "condition"     => $this->_forecast->{"Day".$i}->Forecast,
  486.                     "conditionIcon" => $this->_forecast->{"Day".$i}->IconIndex,
  487.                     "precipitation" => trim(str_replace("%"""$this->_forecast->{"Day".$i}->PrecipChance))
  488.                 )
  489.             );
  490.  
  491.             $forecastReturn["days"][$day;
  492.         }
  493.  
  494.         return $forecastReturn;
  495.     }
  496.     // }}}
  497. }
  498. // }}}
  499. ?>

Documentation generated on Mon, 11 Mar 2019 15:50:58 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.