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-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: Weatherdotcom.php,v 1.67 2009/03/12 23:16:41 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 5 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-2009 Alexander Wirtz
  77.  * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
  78.  * @version     Release: 1.4.4
  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."?link=xoap&prod=xoap&par=".$this->_partnerID."&key=".$this->_licenseKey;
  248.  
  249.         switch ($reqType{
  250.             case "links":
  251.                 $url .= "";
  252.                 break;
  253.             case "weather":
  254.                 $url .= "&cc=*&unit=s";
  255.                 break;
  256.             case "forecast":
  257.                 $url .= "&dayf=5&unit=s";
  258.                 break;
  259.             case "all":
  260.                 $url .= "&cc=*&dayf=5&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.         else {
  380.             $searchReturn = array();
  381.         }
  382.  
  383.         return $searchReturn;
  384.     }
  385.     // }}}
  386.  
  387.     // {{{ searchLocationByCountry()
  388.     /**
  389.      * Returns only false, as weather.com offers no country listing via
  390.      * its XML services
  391.      *
  392.      * @param   string                      $country 
  393.      * @return  bool 
  394.      * @access  public
  395.      * @deprecated
  396.      */
  397.     function searchLocationByCountry($country "")
  398.     {
  399.         return false;
  400.     }
  401.     // }}}
  402.  
  403.     // {{{ getLinks()
  404.     /**
  405.      * Returns the data for the promotional links belonging to the ID
  406.      *
  407.      * @param   string                      $id 
  408.      * @return  PEAR_Error|array
  409.      * @throws  PEAR_Error
  410.      * @access  public
  411.      */
  412.     function getLinks($id "")
  413.     {
  414.         $status $this->_checkLocationID($id);
  415.  
  416.         if (Services_Weather::isError($status)) {
  417.             return $status;
  418.         }
  419.  
  420.         $linksReturn = array();
  421.  
  422.         if ($this->_cacheEnabled && ($links $this->_cache->get($id"links"))) {
  423.             // Get data from cache
  424.             $this->_links = $links;
  425.             $linksReturn["cache""HIT";
  426.         else {
  427.             // Same as in the function above...
  428.             $status $this->_parseWeatherData($id"links");
  429.  
  430.             if (Services_Weather::isError($status)) {
  431.                 return $status;
  432.             }
  433.             $linksReturn["cache""MISS";
  434.         }
  435.  
  436.         $linksReturn["promo"= array();
  437.         for ($i = 0; $i sizeof($this->_links->link)$i++{
  438.             $linksReturn["promo"][$i= array();
  439.             $linksReturn["promo"][$i]["title"$this->_links->link[$i]->t;
  440.             // B0rked response (returned is &par=xoap, should be &prod=xoap), fix it
  441.             $linksReturn["promo"][$i]["link"]  str_replace("par=""prod="$this->_links->link[$i]->l);
  442.             $linksReturn["promo"][$i]["link".= "&par=".$this->_partnerID;
  443.         }
  444.  
  445.         return $linksReturn;
  446.     }
  447.     // }}}
  448.  
  449.     // {{{ getLocation()
  450.     /**
  451.      * Returns the data for the location belonging to the ID
  452.      *
  453.      * @param   string                      $id 
  454.      * @return  PEAR_Error|array
  455.      * @throws  PEAR_Error
  456.      * @access  public
  457.      */
  458.     function getLocation($id "")
  459.     {
  460.         $status $this->_checkLocationID($id);
  461.  
  462.         if (Services_Weather::isError($status)) {
  463.             return $status;
  464.         }
  465.  
  466.         $locationReturn = array();
  467.  
  468.         if ($this->_cacheEnabled && ($location $this->_cache->get($id"location"))) {
  469.             // Get data from cache
  470.             $this->_location = $location;
  471.             $locationReturn["cache""HIT";
  472.         else {
  473.             // Same as in the function above...
  474.             $status $this->_parseWeatherData($id"location");
  475.  
  476.             if (Services_Weather::isError($status)) {
  477.                 return $status;
  478.             }
  479.             $locationReturn["cache""MISS";
  480.         }
  481.  
  482.         $locationReturn["name"]      $this->_location->dnam;
  483.         $locationReturn["time"]      date($this->_timeFormatstrtotime($this->_location->tm));
  484.         $locationReturn["latitude"]  $this->_location->lat;
  485.         $locationReturn["longitude"$this->_location->lon;
  486.         $locationReturn["sunrise"]   date($this->_timeFormatstrtotime($this->_location->sunr));
  487.         $locationReturn["sunset"]    date($this->_timeFormatstrtotime($this->_location->suns));
  488.         $locationReturn["timezone"]  $this->_location->zone;
  489.  
  490.         return $locationReturn;
  491.     }
  492.     // }}}
  493.  
  494.     // {{{ getWeather()
  495.     /**
  496.      * Returns the weather-data for the supplied location
  497.      *
  498.      * @param   string                      $id 
  499.      * @param   string                      $unitsFormat 
  500.      * @return  PEAR_Error|array
  501.      * @throws  PEAR_Error
  502.      * @access  public
  503.      */
  504.     function getWeather($id ""$unitsFormat "")
  505.     {
  506.         $status $this->_checkLocationID($id);
  507.  
  508.         if (Services_Weather::isError($status)) {
  509.             return $status;
  510.         }
  511.  
  512.         // Get other data
  513.         $units    $this->getUnitsFormat($unitsFormat);
  514.  
  515.         $weatherReturn = array();
  516.  
  517.         if ($this->_cacheEnabled && ($weather $this->_cache->get($id"weather"))) {
  518.             // Same procedure...
  519.             $this->_weather = $weather;
  520.             $weatherReturn["cache""HIT";
  521.         else {
  522.             // ...as last function
  523.             $status $this->_parseWeatherData($id"weather");
  524.  
  525.             if (Services_Weather::isError($status)) {
  526.                 return $status;
  527.             }
  528.             $weatherReturn["cache""MISS";
  529.         }
  530.  
  531.         // Some explanation for the next two lines:
  532.         // weather.com isn't always supplying the timezone in the update string, but
  533.         // uses "Local Time" as reference, which is imho utterly stupid, because it's
  534.         // inconsistent. Well, what I do here is check for this string and if I can
  535.         // find it, I calculate the difference between the timezone at the location
  536.         // and this computers timezone. This amount of seconds is then subtracted from
  537.         // the time the update-string has delivered.
  538.         $update   str_replace("Local Time"""$this->_weather->lsup);
  539.         $adjustTZ ($update == $this->_weather->lsup? 0 : $this->_location->zone * 3600 - date("Z");
  540.         $weatherReturn["update"]            gmdate(trim($this->_dateFormat." ".$this->_timeFormat)strtotime($update$adjustTZ);
  541.         $weatherReturn["updateRaw"]         $this->_weather->lsup;
  542.         $weatherReturn["station"]           $this->_weather->obst;
  543.         $weatherReturn["temperature"]       $this->convertTemperature($this->_weather->tmp"f"$units["temp"]);
  544.         $weatherReturn["feltTemperature"]   $this->convertTemperature($this->_weather->flik"f"$units["temp"]);
  545.         $weatherReturn["condition"]         $this->_weather->t;
  546.         $weatherReturn["conditionIcon"]     $this->_weather->icon;
  547.         $weatherReturn["pressure"]          $this->convertPressure($this->_weather->bar->r"in"$units["pres"]);
  548.         $weatherReturn["pressureTrend"]     $this->_weather->bar->d;
  549.         $weatherReturn["wind"]              $this->convertSpeed($this->_weather->wind->s"mph"$units["wind"]);
  550.         $weatherReturn["windGust"]          $this->convertSpeed($this->_weather->wind->gust"mph"$units["wind"]);
  551.         $weatherReturn["windDegrees"]       $this->_weather->wind->d;
  552.         $weatherReturn["windDirection"]     $this->_weather->wind->t;
  553.         $weatherReturn["humidity"]          $this->_weather->hmid;
  554.         if (is_numeric($this->_weather->vis)) {
  555.             $weatherReturn["visibility"]    $this->convertDistance($this->_weather->vis"sm"$units["vis"]);
  556.         else {
  557.             $weatherReturn["visibility"]    $this->_weather->vis;
  558.         }
  559.         $weatherReturn["uvIndex"]           $this->_weather->uv->i;
  560.         $weatherReturn["uvText"]            $this->_weather->uv->t;
  561.         $weatherReturn["dewPoint"]          $this->convertTemperature($this->_weather->dewp"f"$units["temp"]);
  562.  
  563.         return $weatherReturn;
  564.     }
  565.     // }}}
  566.  
  567.     // {{{ getForecast()
  568.     /**
  569.      * Get the forecast for the next days
  570.      *
  571.      * @param   string                      $id 
  572.      * @param   int                         $days           Values between 1 and 5
  573.      * @param   string                      $unitsFormat 
  574.      * @return  PEAR_Error|array
  575.      * @throws  PEAR_Error
  576.      * @access  public
  577.      */
  578.     function getForecast($id ""$days = 5$unitsFormat "")
  579.     {
  580.         $status $this->_checkLocationID($id);
  581.  
  582.         if (Services_Weather::isError($status)) {
  583.             return $status;
  584.         }
  585.         if (!is_int($days|| ($days < 1|| ($days > 5)) {
  586.             $days = 5;
  587.         }
  588.  
  589.         // Get other data
  590.         $units    $this->getUnitsFormat($unitsFormat);
  591.  
  592.         $forecastReturn = array();
  593.  
  594.         if ($this->_cacheEnabled && ($forecast $this->_cache->get($id"forecast"))) {
  595.             // Encore...
  596.             $this->_forecast = $forecast;
  597.             $forecastReturn["cache""HIT";
  598.         else {
  599.             // ...
  600.             $status $this->_parseWeatherData($id"forecast");
  601.  
  602.             if (Services_Weather::isError($status)) {
  603.                 return $status;
  604.             }
  605.             $forecastReturn["cache""MISS";
  606.         }
  607.  
  608.         // Some explanation for the next two lines: (same as above)
  609.         // weather.com isn't always supplying the timezone in the update string, but
  610.         // uses "Local Time" as reference, which is imho utterly stupid, because it's
  611.         // inconsistent. Well, what I do here is check for this string and if I can
  612.         // find it, I calculate the difference between the timezone at the location
  613.         // and this computers timezone. This amount of seconds is then subtracted from
  614.         // the time the update-string has delivered.
  615.         $update   str_replace("Local Time"""$this->_forecast->lsup);
  616.         $adjustTZ ($update == $this->_forecast->lsup? 0 : $this->_location->zone * 3600 - date("Z");
  617.         $forecastReturn["update"]    gmdate($this->_dateFormat." ".$this->_timeFormatstrtotime($update$adjustTZ);
  618.         $forecastReturn["updateRaw"$this->_forecast->lsup;
  619.         $forecastReturn["days"]      = array();
  620.  
  621.         for ($i = 0; $i $days$i++{
  622.             $day = array(
  623.                 "temperatureHigh" => $this->convertTemperature($this->_forecast->day[$i]->hi"f"$units["temp"]),
  624.                 "temperatureLow"  => $this->convertTemperature($this->_forecast->day[$i]->low"f"$units["temp"]),
  625.                 "sunrise"         => date($this->_timeFormatstrtotime($this->_forecast->day[$i]->sunr)),
  626.                 "sunset"          => date($this->_timeFormatstrtotime($this->_forecast->day[$i]->suns)),
  627.                 "day" => array(
  628.                     "condition"     => $this->_forecast->day[$i]->part[0]->t,
  629.                     "conditionIcon" => $this->_forecast->day[$i]->part[0]->icon,
  630.                     "wind"          => $this->convertSpeed($this->_forecast->day[$i]->part[0]->wind->s"mph"$units["wind"]),
  631.                     "windGust"      => $this->convertSpeed($this->_forecast->day[$i]->part[0]->wind->gust"mph"$units["wind"]),
  632.                     "windDegrees"   => $this->_forecast->day[$i]->part[0]->wind->d,
  633.                     "windDirection" => $this->_forecast->day[$i]->part[0]->wind->t,
  634.                     "precipitation" => $this->_forecast->day[$i]->part[0]->ppcp,
  635.                     "humidity"      => $this->_forecast->day[$i]->part[0]->hmid
  636.                 ),
  637.                 "night" => array (
  638.                     "condition"     => $this->_forecast->day[$i]->part[1]->t,
  639.                     "conditionIcon" => $this->_forecast->day[$i]->part[1]->icon,
  640.                     "wind"          => $this->convertSpeed($this->_forecast->day[$i]->part[1]->wind->s"mph"$units["wind"]),
  641.                     "windGust"      => $this->convertSpeed($this->_forecast->day[$i]->part[1]->wind->gust"mph"$units["wind"]),
  642.                     "windDegrees"   => $this->_forecast->day[$i]->part[1]->wind->d,
  643.                     "windDirection" => $this->_forecast->day[$i]->part[1]->wind->t,
  644.                     "precipitation" => $this->_forecast->day[$i]->part[1]->ppcp,
  645.                     "humidity"      => $this->_forecast->day[$i]->part[1]->hmid
  646.                 )
  647.             );
  648.  
  649.             $forecastReturn["days"][$day;
  650.         }
  651.  
  652.         return $forecastReturn;
  653.     }
  654.     // }}}
  655. }
  656. // }}}
  657. ?>

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