home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Services / Weather / Ejse.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  18.4 KB  |  504 lines

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