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

Source for file Weatherdotcom.php

Documentation is available at Weatherdotcom.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
  3.  
  4. /**
  5.  * PEAR::Services_Weather_Weatherdotcom
  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: Weatherdotcom.php,v 1.58 2005/11/17 08:19:42 eru Exp $
  44.  * @link        http://pear.php.net/package/Services_Weather
  45.  * @link        http://www.weather.com/services/xmloap.html
  46.  * @example     examples/weather.com-basic.php      weather.com-basic.php
  47.  * @example     examples/weather.com-extensive.php  weather.com-extensive.php
  48.  * @filesource
  49.  */
  50.  
  51. require_once "Services/Weather/Common.php";
  52.  
  53. // {{{ class Services_Weather_Weatherdotcom
  54. /**
  55.  * This class acts as an interface to the xml service of weather.com. It
  56.  * searches for given locations and retrieves current weather data as well
  57.  * as forecast for up to 10 days.
  58.  *
  59.  * For using the weather.com xml-service please visit
  60.  *     http://www.weather.com/services/xmloap.html
  61.  * and follow the link to sign up, it's free! You will receive an email
  62.  * where to download the SDK with the needed images and guidelines how to
  63.  * publish live data from weather.com. Unfortunately the guidelines are a
  64.  * bit harsh, that's why there's no actual data-representation in this
  65.  * class, just the raw data. Also weather.com demands active caching, so I'd
  66.  * strongly recommend enabling the caching implemented in this class. It
  67.  * obeys to the times as written down in the guidelines.
  68.  *
  69.  * For working examples, please take a look at
  70.  *     docs/Services_Weather/examples/weather.com-basic.php
  71.  *     docs/Services_Weather/examples/weather.com-extensive.php
  72.  *
  73.  * @category    Web Services
  74.  * @package     Services_Weather
  75.  * @author      Alexander Wirtz <alex@pc4p.net>
  76.  * @copyright   2005 Alexander Wirtz
  77.  * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
  78.  * @version     Release: 1.4.0
  79.  * @link        http://pear.php.net/package/Services_Weather
  80.  * @link        http://www.weather.com/services/xmloap.html
  81.  * @example     examples/weather.com-basic.php      weather.com-basic.php
  82.  * @example     examples/weather.com-extensive.php  weather.com-extensive.php
  83.  */
  84.  
  85.     // {{{ properties
  86.     /**
  87.      * Partner-ID at weather.com
  88.      *
  89.      * @var     string                      $_partnerID 
  90.      * @access  private
  91.      */
  92.     var $_partnerID "";
  93.  
  94.     /**
  95.      * License key at weather.com
  96.      *
  97.      * @var     string                      $_licenseKey 
  98.      * @access  private
  99.      */
  100.     var $_licenseKey "";
  101.  
  102.     /**
  103.      * Switch to toggle pre-fetching of data in one single request
  104.      *
  105.      * @var     bool                        $_preFetch 
  106.      * @access  private
  107.      */
  108.      var $_preFetch = false;
  109.  
  110.     /**
  111.      * Object containing the promotional links-data
  112.      *
  113.      * @var     object stdClass             $_links 
  114.      * @access  private
  115.      */
  116.     var $_links;
  117.  
  118.     /**
  119.      * XML_Unserializer, used for processing the xml
  120.      *
  121.      * @var     object XML_Unserializer     $_unserializer 
  122.      * @access  private
  123.      */
  124.     var $_unserializer;
  125.     // }}}
  126.  
  127.     // {{{ constructor
  128.     /**
  129.      * Constructor
  130.      *
  131.      * Requires XML_Serializer to be installed
  132.      *
  133.      * @param   array                       $options 
  134.      * @param   mixed                       $error 
  135.      * @throws  PEAR_Error
  136.      * @access  private
  137.      */
  138.     function Services_Weather_Weatherdotcom($options&$error)
  139.     {
  140.         $perror = null;
  141.         $this->Services_Weather_Common($options$perror);
  142.         if (Services_Weather::isError($perror)) {
  143.             $error $perror;
  144.             return;
  145.         }
  146.  
  147.         // Set options accordingly
  148.         if (isset($options["partnerID"])) {
  149.             $this->setAccountData($options["partnerID"]);
  150.         }
  151.         if (isset($options["licenseKey"])) {
  152.             $this->setAccountData(""$options["licenseKey"]);
  153.         }
  154.         if (isset($options["preFetch"])) {
  155.             $this->enablePreFetch($options["preFetch"]);
  156.         }
  157.  
  158.         include_once "XML/Unserializer.php";
  159.         $unserializer &new XML_Unserializer(array("complexType" => "object""keyAttribute" => "type"));
  160.         if (Services_Weather::isError($unserializer)) {
  161.             $error $unserializer;
  162.             return;
  163.         else {
  164.             $this->_unserializer $unserializer;
  165.         }
  166.  
  167.         // Can't acquire an object here, has to be clean on every request
  168.         include_once "HTTP/Request.php";
  169.     }
  170.     // }}}
  171.  
  172.     // {{{ setAccountData()
  173.     /**
  174.      * Sets the neccessary account-information for weather.com, you'll
  175.      * receive them after registering for the XML-stream
  176.      *
  177.      * @param   string                      $partnerID 
  178.      * @param   string                      $licenseKey 
  179.      * @access  public
  180.      */
  181.     function setAccountData($partnerID$licenseKey)
  182.     {
  183.         if (strlen($partnerID&& ctype_digit($partnerID)) {
  184.             $this->_partnerID  $partnerID;
  185.         }
  186.         if (strlen($licenseKey&& ctype_alnum($licenseKey)) {
  187.             $this->_licenseKey $licenseKey;
  188.         }
  189.     }
  190.     // }}}
  191.  
  192.     // {{{ enablePreFetch()
  193.     /**
  194.      * Enables pre-fetching of data in one single request
  195.      *
  196.      * @param   bool                        $preFetch 
  197.      * @access  public
  198.      */
  199.     function enablePreFetch($preFetch)
  200.     {
  201.         if ($preFetch == true{
  202.             $this->_preFetch = true;
  203.         }
  204.     }
  205.     // }}}
  206.  
  207.     // {{{ _checkLocationID()
  208.     /**
  209.      * Checks the id for valid values and thus prevents silly requests to
  210.      * weather.com server
  211.      *
  212.      * @param   string                      $id 
  213.      * @return  PEAR_Error|bool
  214.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_NO_LOCATION
  215.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_INVALID_LOCATION
  216.      * @access  private
  217.      */
  218.     function _checkLocationID($id)
  219.     {
  220.         if (is_array($id|| is_object($id|| !strlen($id)) {
  221.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_NO_LOCATION__FILE____LINE__);
  222.         elseif (!ctype_alnum($id|| (strlen($id> 8)) {
  223.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_INVALID_LOCATION__FILE____LINE__);
  224.         }
  225.  
  226.         return true;
  227.     }
  228.     // }}}
  229.  
  230.     // {{{ _parseWeatherData()
  231.     /**
  232.      * Fetches the data based on the requested type and caches it
  233.      *
  234.      * @param   string                      $id 
  235.      * @param   string                      $reqType 
  236.      * @return  PEAR_Error|bool
  237.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
  238.      * @throws  PEAR_Error
  239.      * @access  private
  240.      */
  241.     function _parseWeatherData($id$reqType)
  242.     {
  243.         if ($this->_preFetch{
  244.             $reqType "all";
  245.         }
  246.  
  247.         $url "http://xoap.weather.com/weather/local/".$id."?prod=xoap&par=".$this->_partnerID."&key=".$this->_licenseKey;
  248.  
  249.         switch ($reqType{
  250.             case "links":
  251.                 $url .= "&link=xoap";
  252.                 break;
  253.             case "weather":
  254.                 $url .= "&cc=*&unit=s";
  255.                 break;
  256.             case "forecast":
  257.                 $url .= "&dayf=10&unit=s";
  258.                 break;
  259.             case "all":
  260.                 $url .= "&link=xoap&cc=*&dayf=10&unit=s";
  261.                 break;
  262.         }
  263.  
  264.         // Get data from URL...
  265.         $request &new HTTP_Request($url$this->_httpOptions);
  266.         $status $request->sendRequest();
  267.         if (Services_Weather::isError($status|| (int) $request->getResponseCode(<> 200{
  268.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA__FILE____LINE__);
  269.         }
  270.         $data $request->getResponseBody();
  271.  
  272.         // ...and unserialize
  273.         $status $this->_unserializer->unserialize($data);
  274.  
  275.         if (Services_Weather::isError($status)) {
  276.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA__FILE____LINE__);
  277.         else {
  278.             $root $this->_unserializer->getRootName();
  279.             $data $this->_unserializer->getUnserializedData();
  280.  
  281.             if (Services_Weather::isError($root|| $root == "HTML"{
  282.                 // Something wrong here, maybe not XML retrieved...
  283.                 return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA__FILE____LINE__);
  284.             elseif ($root == "error"{
  285.                 // We got an error back from weather.com
  286.                 $errno  key(get_object_vars($data));
  287.                 return Services_Weather::raiseError($errno__FILE____LINE__);
  288.             else {
  289.                 // Valid data, lets get started
  290.                 // Loop through the different sub-parts of the data fro processing
  291.                 foreach (get_object_vars($dataas $key => $val{
  292.                     switch ($key{
  293.                         case "head":
  294.                             continue 2;
  295.                         case "prmo":
  296.                             $varname  "links";
  297.                             break;
  298.                         case "loc":
  299.                             $varname  "location";
  300.                             break;
  301.                         case "cc":
  302.                             $varname  "weather";
  303.                             break;
  304.                         case "dayf":
  305.                             $varname  "forecast";
  306.                             break;
  307.                     }
  308.                     // Save data in object
  309.                     $this->{"_".$varname$val;
  310.                     if ($this->_cacheEnabled{
  311.                         // ...and cache if possible
  312.                         $expire constant("SERVICES_WEATHER_EXPIRES_".strtoupper($varname));
  313.                         $this->_cache->extSave($id$val""$expire$varname);
  314.                     }
  315.                 }
  316.             }
  317.         }
  318.  
  319.         return true;
  320.     }
  321.     // }}}
  322.  
  323.     // {{{ searchLocation()
  324.     /**
  325.      * Searches IDs for given location, returns array of possible locations
  326.      * or single ID
  327.      *
  328.      * @param   string                      $location 
  329.      * @param   bool                        $useFirst       If set, first ID of result-array is returned
  330.      * @return  PEAR_Error|array|string
  331.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
  332.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION
  333.      * @access  public
  334.      */
  335.     function searchLocation($location$useFirst = false)
  336.     {
  337.         $location trim($location);
  338.         $locLow   strtolower($location);
  339.         
  340.         // Check on cached data: MD5-hash of location has to be correct and the userdata has to be the same as the given location 
  341.         if ($this->_cacheEnabled && $locLow == $this->_cache->getUserData(md5($locLow)"search")) {
  342.             $search $this->_cache->get(md5($locLow)"search");
  343.         else {
  344.             // Get search data from server and unserialize
  345.             $request &new HTTP_Request("http://xoap.weather.com/search/search?where=".urlencode($location)$this->_httpOptions);
  346.             $status $request->sendRequest();
  347.             if (Services_Weather::isError($status|| (int) $request->getResponseCode(<> 200{
  348.                 return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA__FILE____LINE__);
  349.             }
  350.             $data $request->getResponseBody();
  351.     
  352.             // ...and unserialize
  353.             $status $this->_unserializer->unserialize($datafalsearray("overrideOptions" => true"complexType" => "array""keyAttribute" => "id"));
  354.     
  355.             if (Services_Weather::isError($status)) {
  356.                 return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA__FILE____LINE__);
  357.             }
  358.     
  359.             $root $this->_unserializer->getRootName();
  360.             $search $this->_unserializer->getUnserializedData();
  361.     
  362.             if (Services_Weather::isError($search|| $root == "HTML"{
  363.                 return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA__FILE____LINE__);
  364.             elseif (!is_array($search|| !sizeof($search)) {
  365.                 return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION__FILE____LINE__);
  366.             }
  367.  
  368.             if ($this->_cacheEnabled{
  369.                 // ...and cache if possible
  370.                 $expire constant("SERVICES_WEATHER_EXPIRES_SEARCH");
  371.                 $this->_cache->extSave(md5($locLow)$search$locLow$expire"search");
  372.             }
  373.         }
  374.  
  375.         if (!$useFirst && (sizeof($search> 1)) {
  376.             $searchReturn $search;
  377.         elseif ($useFirst || (sizeof($search== 1)) {
  378.             $searchReturn key($search);
  379.         }
  380.  
  381.         return $searchReturn;
  382.     }
  383.     // }}}
  384.  
  385.     // {{{ searchLocationByCountry()
  386.     /**
  387.      * Returns only false, as weather.com offers no country listing via
  388.      * its XML services
  389.      *
  390.      * @param   string                      $country 
  391.      * @return  bool 
  392.      * @access  public
  393.      * @deprecated
  394.      */
  395.     function searchLocationByCountry($country "")
  396.     {
  397.         return false;
  398.     }
  399.     // }}}
  400.  
  401.     // {{{ getLinks()
  402.     /**
  403.      * Returns the data for the promotional links belonging to the ID
  404.      *
  405.      * @param   string                      $id 
  406.      * @return  PEAR_Error|array
  407.      * @throws  PEAR_Error
  408.      * @access  public
  409.      */
  410.     function getLinks($id "")
  411.     {
  412.         $status $this->_checkLocationID($id);
  413.  
  414.         if (Services_Weather::isError($status)) {
  415.             return $status;
  416.         }
  417.  
  418.         $linksReturn = array();
  419.  
  420.         if ($this->_cacheEnabled && ($links $this->_cache->get($id"links"))) {
  421.             // Get data from cache
  422.             $this->_links = $links;
  423.             $linksReturn["cache""HIT";
  424.         else {
  425.             // Same as in the function above...
  426.             $status $this->_parseWeatherData($id"links");
  427.  
  428.             if (Services_Weather::isError($status)) {
  429.                 return $status;
  430.             }
  431.             $linksReturn["cache""MISS";
  432.         }
  433.  
  434.         $linksReturn["promo"= array();
  435.         for ($i = 0; $i sizeof($this->_links->link)$i++{
  436.             $linksReturn["promo"][$i= array();
  437.             $linksReturn["promo"][$i]["title"$this->_links->link[$i]->t;
  438.             // B0rked response (returned is &par=xoap, should be &prod=xoap), fix it
  439.             $linksReturn["promo"][$i]["link"]  str_replace("par=""prod="$this->_links->link[$i]->l);
  440.             $linksReturn["promo"][$i]["link".= "&par=".$this->_partnerID;
  441.         }
  442.  
  443.         return $linksReturn;
  444.     }
  445.     // }}}
  446.  
  447.     // {{{ getLocation()
  448.     /**
  449.      * Returns the data for the location belonging to the ID
  450.      *
  451.      * @param   string                      $id 
  452.      * @return  PEAR_Error|array
  453.      * @throws  PEAR_Error
  454.      * @access  public
  455.      */
  456.     function getLocation($id "")
  457.     {
  458.         $status $this->_checkLocationID($id);
  459.  
  460.         if (Services_Weather::isError($status)) {
  461.             return $status;
  462.         }
  463.  
  464.         $locationReturn = array();
  465.  
  466.         if ($this->_cacheEnabled && ($location $this->_cache->get($id"location"))) {
  467.             // Get data from cache
  468.             $this->_location = $location;
  469.             $locationReturn["cache""HIT";
  470.         else {
  471.             // Same as in the function above...
  472.             $status $this->_parseWeatherData($id"location");
  473.  
  474.             if (Services_Weather::isError($status)) {
  475.                 return $status;
  476.             }
  477.             $locationReturn["cache""MISS";
  478.         }
  479.  
  480.         $locationReturn["name"]      $this->_location->dnam;
  481.         $locationReturn["time"]      date($this->_timeFormatstrtotime($this->_location->tm));
  482.         $locationReturn["latitude"]  $this->_location->lat;
  483.         $locationReturn["longitude"$this->_location->lon;
  484.         $locationReturn["sunrise"]   date($this->_timeFormatstrtotime($this->_location->sunr));
  485.         $locationReturn["sunset"]    date($this->_timeFormatstrtotime($this->_location->suns));
  486.         $locationReturn["timezone"]  $this->_location->zone;
  487.  
  488.         return $locationReturn;
  489.     }
  490.     // }}}
  491.  
  492.     // {{{ getWeather()
  493.     /**
  494.      * Returns the weather-data for the supplied location
  495.      *
  496.      * @param   string                      $id 
  497.      * @param   string                      $unitsFormat 
  498.      * @return  PEAR_Error|array
  499.      * @throws  PEAR_Error
  500.      * @access  public
  501.      */
  502.     function getWeather($id ""$unitsFormat "")
  503.     {
  504.         $status $this->_checkLocationID($id);
  505.  
  506.         if (Services_Weather::isError($status)) {
  507.             return $status;
  508.         }
  509.  
  510.         // Get other data
  511.         $units    $this->getUnitsFormat($unitsFormat);
  512.  
  513.         $weatherReturn = array();
  514.  
  515.         if ($this->_cacheEnabled && ($weather $this->_cache->get($id"weather"))) {
  516.             // Same procedure...
  517.             $this->_weather = $weather;
  518.             $weatherReturn["cache""HIT";
  519.         else {
  520.             // ...as last function
  521.             $status $this->_parseWeatherData($id"weather");
  522.  
  523.             if (Services_Weather::isError($status)) {
  524.                 return $status;
  525.             }
  526.             $weatherReturn["cache""MISS";
  527.         }
  528.  
  529.         // Some explanation for the next two lines:
  530.         // weather.com isn't always supplying the timezone in the update string, but
  531.         // uses "Local Time" as reference, which is imho utterly stupid, because it's
  532.         // inconsistent. Well, what I do here is check for this string and if I can
  533.         // find it, I calculate the difference between the timezone at the location
  534.         // and this computers timezone. This amount of seconds is then subtracted from
  535.         // the time the update-string has delivered.
  536.         $update   str_replace("Local Time"""$this->_weather->lsup);
  537.         $adjustTZ ($update == $this->_weather->lsup? 0 : $this->_location->zone * 3600 - date("Z");
  538.         $weatherReturn["update"]            gmdate(trim($this->_dateFormat." ".$this->_timeFormat)strtotime($update$adjustTZ);
  539.         $weatherReturn["updateRaw"]         $this->_weather->lsup;
  540.         $weatherReturn["station"]           $this->_weather->obst;
  541.         $weatherReturn["temperature"]       $this->convertTemperature($this->_weather->tmp"f"$units["temp"]);
  542.         $weatherReturn["feltTemperature"]   $this->convertTemperature($this->_weather->flik"f"$units["temp"]);
  543.         $weatherReturn["condition"]         $this->_weather->t;
  544.         $weatherReturn["conditionIcon"]     $this->_weather->icon;
  545.         $weatherReturn["pressure"]          $this->convertPressure($this->_weather->bar->r"in"$units["pres"]);
  546.         $weatherReturn["pressureTrend"]     $this->_weather->bar->d;
  547.         $weatherReturn["wind"]              $this->convertSpeed($this->_weather->wind->s"mph"$units["wind"]);
  548.         $weatherReturn["windGust"]          $this->convertSpeed($this->_weather->wind->gust"mph"$units["wind"]);
  549.         $weatherReturn["windDegrees"]       $this->_weather->wind->d;
  550.         $weatherReturn["windDirection"]     $this->_weather->wind->t;
  551.         $weatherReturn["humidity"]          $this->_weather->hmid;
  552.         if (is_numeric($this->_weather->vis)) {
  553.             $weatherReturn["visibility"]    $this->convertDistance($this->_weather->vis"sm"$units["vis"]);
  554.         else {
  555.             $weatherReturn["visibility"]    $this->_weather->vis;
  556.         }
  557.         $weatherReturn["uvIndex"]           $this->_weather->uv->i;
  558.         $weatherReturn["uvText"]            $this->_weather->uv->t;
  559.         $weatherReturn["dewPoint"]          $this->convertTemperature($this->_weather->dewp"f"$units["temp"]);
  560.  
  561.         return $weatherReturn;
  562.     }
  563.     // }}}
  564.  
  565.     // {{{ getForecast()
  566.     /**
  567.      * Get the forecast for the next days
  568.      *
  569.      * @param   string                      $id 
  570.      * @param   int                         $days           Values between 1 and 10
  571.      * @param   string                      $unitsFormat 
  572.      * @return  PEAR_Error|array
  573.      * @throws  PEAR_Error
  574.      * @access  public
  575.      */
  576.     function getForecast($id ""$days = 2$unitsFormat "")
  577.     {
  578.         $status $this->_checkLocationID($id);
  579.  
  580.         if (Services_Weather::isError($status)) {
  581.             return $status;
  582.         }
  583.         if (!in_array($daysrange(110))) {
  584.             $days = 2;
  585.         }
  586.  
  587.         // Get other data
  588.         $units    $this->getUnitsFormat($unitsFormat);
  589.  
  590.         $forecastReturn = array();
  591.  
  592.         if ($this->_cacheEnabled && ($forecast $this->_cache->get($id"forecast"))) {
  593.             // Encore...
  594.             $this->_forecast = $forecast;
  595.             $forecastReturn["cache""HIT";
  596.         else {
  597.             // ...
  598.             $status $this->_parseWeatherData($id"forecast");
  599.  
  600.             if (Services_Weather::isError($status)) {
  601.                 return $status;
  602.             }
  603.             $forecastReturn["cache""MISS";
  604.         }
  605.  
  606.         // Some explanation for the next two lines: (same as above)
  607.         // weather.com isn't always supplying the timezone in the update string, but
  608.         // uses "Local Time" as reference, which is imho utterly stupid, because it's
  609.         // inconsistent. Well, what I do here is check for this string and if I can
  610.         // find it, I calculate the difference between the timezone at the location
  611.         // and this computers timezone. This amount of seconds is then subtracted from
  612.         // the time the update-string has delivered.
  613.         $update   str_replace("Local Time"""$this->_forecast->lsup);
  614.         $adjustTZ ($update == $this->_forecast->lsup? 0 : $this->_location->zone * 3600 - date("Z");
  615.         $forecastReturn["update"]    gmdate($this->_dateFormat." ".$this->_timeFormatstrtotime($update$adjustTZ);
  616.         $forecastReturn["updateRaw"$this->_forecast->lsup;
  617.         $forecastReturn["days"]      = array();
  618.  
  619.         for ($i = 0; $i $days$i++{
  620.             $day = array(
  621.                 "temperatureHigh" => $this->convertTemperature($this->_forecast->day[$i]->hi"f"$units["temp"]),
  622.                 "temperatureLow"  => $this->convertTemperature($this->_forecast->day[$i]->low"f"$units["temp"]),
  623.                 "sunrise"         => date($this->_timeFormatstrtotime($this->_forecast->day[$i]->sunr)),
  624.                 "sunset"          => date($this->_timeFormatstrtotime($this->_forecast->day[$i]->suns)),
  625.                 "day" => array(
  626.                     "condition"     => $this->_forecast->day[$i]->part[0]->t,
  627.                     "conditionIcon" => $this->_forecast->day[$i]->part[0]->icon,
  628.                     "wind"          => $this->convertSpeed($this->_forecast->day[$i]->part[0]->wind->s"mph"$units["wind"]),
  629.                     "windGust"      => $this->convertSpeed($this->_forecast->day[$i]->part[0]->wind->gust"mph"$units["wind"]),
  630.                     "windDegrees"   => $this->_forecast->day[$i]->part[0]->wind->d,
  631.                     "windDirection" => $this->_forecast->day[$i]->part[0]->wind->t,
  632.                     "precipitation" => $this->_forecast->day[$i]->part[0]->ppcp,
  633.                     "humidity"      => $this->_forecast->day[$i]->part[0]->hmid
  634.                 ),
  635.                 "night" => array (
  636.                     "condition"     => $this->_forecast->day[$i]->part[1]->t,
  637.                     "conditionIcon" => $this->_forecast->day[$i]->part[1]->icon,
  638.                     "wind"          => $this->convertSpeed($this->_forecast->day[$i]->part[1]->wind->s"mph"$units["wind"]),
  639.                     "windGust"      => $this->convertSpeed($this->_forecast->day[$i]->part[1]->wind->gust"mph"$units["wind"]),
  640.                     "windDegrees"   => $this->_forecast->day[$i]->part[1]->wind->d,
  641.                     "windDirection" => $this->_forecast->day[$i]->part[1]->wind->t,
  642.                     "precipitation" => $this->_forecast->day[$i]->part[1]->ppcp,
  643.                     "humidity"      => $this->_forecast->day[$i]->part[1]->hmid
  644.                 )
  645.             );
  646.  
  647.             $forecastReturn["days"][$day;
  648.         }
  649.  
  650.         return $forecastReturn;
  651.     }
  652.     // }}}
  653. }
  654. // }}}
  655. ?>

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