Login   Register  
PHP Classes
elePHPant
Icontem

File: weather/weathercore.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Samy Massoud  >  PHP Weather  >  weather/weathercore.php  >  Download  
File: weather/weathercore.php
Role: Class source
Content type: text/plain
Description: core class
Class: PHP Weather
Show widgets of weather got from OpenWeathermap
Author: By
Last change: - Added : Portuguese language
- Added : Paypal donation code
Date: 8 months ago
Size: 20,197 bytes
 

Contents

Class file image Download
<?php

/**
 * Weather widget class
 * All Documentation included in this document.
 * For further developer note please see the Weather.php class
 * 
 * @version 1.0.1
 * @author Samy Massoud <samymassoud@gmail.com>
 * @link  http://www.deploy2cloud.com/demo/weather
 * 
 * @tutorial 
 * This class main functionality is to provide weather wedget to use it easily and smoothly.
 * You can use this class with almost zero configuration , or configure it as far as you need !
 * 
 * When i started to write this class i put in mind to make it easy,clean and professional as much as i can.
 * 
 * To start using this class just do the following
 *  1- include attached weather.css file in your page.
 *  2- Make sure that you have embedded jquery version greater than 1.6 
 *  3- Include this class in your page and Make object from this class with required city
 *     $weather = new weather ("Cairo,EG");
 *     echo $weather->get_weather ();
 * And you will get a copy from this widget with cairo weather !
 * 
 * To start using this class as codeigniter library
 *  1- include attached weather.css file in your page.
 *  2- Make sure that you have embedded jquery version greater than 1.6 
 *  3- Move weather.php to application/libraries folder
 *     and you can load library by adding it to autoload.php or use
 *     $this->load->library ('weather');
 *     and at any place in your application (Controller or view)
 *     $this->weather->set_city ('Cairo,EG');
 *     echo $this->weather->get_weather ();
 * And you will get a copy from this widget with cairo weather !
 * 
 * 
 */
class weather {

    /**
     * Available themes for weather class
     * @var array 
     */
    private $themes = array(
	'blue' => 'theme-blue',
	'darkblue' => 'theme-darkblue',
	'green' => 'theme-green',
	'black' => 'theme-black',
	'darkred' => 'theme-darkred'
    );

    /**
     * Default theme , or user selected theme
     * @var string 
     */
    private $theme = "theme-darkblue";

    /**
     * Weather api link and weather forecast link
     * @var string 
     */
    private $weather_api = "http://api.openweathermap.org/data/2.5/weather?units=metric&";
    private $forecast_api = "http://api.openweathermap.org/data/2.5/forecast/daily/?cnt=4&units=metric&mode=json&";

    /**
     * City identifires , used to select city by name,id or lat. and lon.
     * @var string
     */
    private $city = "";
    private $city_id = "";
    private $city_lat = "";
    private $city_lon = "";

    /**
     * Selected temperature measurement
     * @var string 
     */
    private $temp_metric = "c";

    /**
     * Output type it can be empty or row for php array
     * @var string 
     */
    private $output = "";

    /**
     * Cache folder , this is the dfault folder , user can change it using configuration
     * @var string 
     */
    private $cache_folder = "./cache/";

    /**
     * Enable or disable cache
     * @var bool 
     */
    private $cache = false;

    /**
     * cache lifetime (By seconds)
     * @var integer 
     */
    private $cache_time = 600;

    /**
     * Widget dimention this is default values 
     * @var integer 
     */
    private $width = 270;
    private $height = 248;

    /**
     * weather info after processing it
     * @var array
     */
    private $weather_info = array();

    /**
     * Widget  languages,it can be extended by coping
     * for example 'En' array and translate it to any other language
     * @var array 
     */
    private $languages = array(
	'en' => array(
	    'cannot_access' => "Can't Access Weather API",
	    'invalid_city_info' => "Please select valid city information",
	    'show_next_days' => "Show weather next three days",
	    'back_to_weather' => "Back to current weather details",
	    'weather' => 'Weather',
	    'weather_desc' => "Weather description",
	    'wind' => 'Wind',
	    'wind_degree' => 'Wind degree',
	    'humidity' => 'Humidity',
	    'pressure' => 'Pressure',
	    'hi' => 'HI',
	    'lo' => 'LO'
	),
	'it' => array(
	    'cannot_access' => "Impossibile accedere Meteo",
	    'invalid_city_info' => "Si prega di selezionare le informazioni citt� valida",
	    'show_next_days' => "Mostra previsioni prossimi tre giorni",
	    'back_to_weather' => "Torna a correnti dettagli meteo",
	    'weather' => 'Meteo',
	    'weather_desc' => "descrizione Meteo",
	    'wind' => 'vento',
	    'wind_degree' => 'grado Vento',
	    'humidity' => 'umidit�',
	    'pressure' => 'pressione',
	    'hi' => 'alto',
	    'lo' => 'basso'
	),
	'fr' => array(
	    'cannot_access' => "Impossible d'acc�der � l'API M�t�o",
	    'invalid_city_info' => "S'il vous pla�t s�lectionner l'information de la ville valide",
	    'show_next_days' => "Montrez temps trois prochains jours",
	    'back_to_weather' => "Retour aux d�tails m�t�orologiques actuelles",
	    'weather' => 'm�t�o',
	    'weather_desc' => "Description m�t�o",
	    'wind' => 'vent',
	    'wind_degree' => 'Degr� de Vent',
	    'humidity' => 'humidit�',
	    'pressure' => 'pression',
	    'hi' => 'haut',
	    'lo' => 'faible'
	),//António Lourenço
        'pt' => array(
        'cannot_access' => "Impossivel aceder a 'API Meteorologia",
        'invalid_city_info' => "Selecione uma cidade válida",
        'show_next_days' => " Previsão nos próximos três dias",
        'back_to_weather' => "Voltar à previsão de hoje",
        'weather' => 'Meteorologia',
        'weather_desc' => "Previsão meteorológica",
        'wind' => 'Vento',
        'wind_degree' => 'Orientação do vento',
        'humidity' => 'Húmidade',
        'pressure' => 'Pressão atmosférica',
        'hi' => 'Alta',
        'lo' => 'Baixa'
        )
    );
    //Available API Languages ' don't modify
    private $api_lang = array('en', 'it', 'ru', 'fr', 'ua', 'de', 'pt', 'ro', 'pl', 'fi', 'nl', 'sp', 'bg', 'se', 'zh_tw', 'zh_cn', 'tr');

    /**
     * Selected language for api and widget
     * @var string
     */
    private $lang = 'en';
    private $lang_api = 'en';

    /**
     * Construct weather widget you can provide any configration you want 
     * Click right # to see more
     * @example  $config = array ('theme' => 'blue',
     * 			'city' => 'cairo,eg',
     * 			'temp_metrics' => 'f');
     * $weather = new weather ($config);
     * 
     * @param type array
     */
    public function __construct($config = null) {
	if (is_array($config)) {
	    foreach ($config as $key => $value) {
		//Set Theme
		if ($key == "theme" && isset($this->themes[$value])) {
		    $this->theme = $this->themes[$value];
		}

		//Set City Name
		if ($key == 'city') {
		    $this->city = $value;
                     $this->file_name =  $this->city;
		}
		if ($key == 'city_id') {
		    $this->city_id = $value;
                     $this->file_name =  $this->city_id;
		}
		if ($key == 'city_lat') {
		    $this->city_lat = $value;
                     $this->file_name =  $this->city_lat;
		}
		if ($key == 'city_lon') {
		    $this->city_lon = $value;
                     $this->file_name .=  '_'.$this->city_lon;
		}

		//Set Tempereature Metrics
		if ($key == 'temp_metrics' && ($value == "c" || $value == 'f')) {
		    $this->temp_metric = $value;
		}

		if ($key == "lang" && (isset($this->languages[$value]) || in_array($value, $this->api_lang))) {
		    if (isset($this->languages[$value])) {
			$this->lang = $value;
		    }

		    if (in_array($value, $this->api_lang)) {
			$this->lang_api = $value;
		    }
		}
		//Set Output
		if ($key == "output" && ($value == "row")) {
		    $this->output = "row";
		}
	    }
	} else {
	    $this->city = $config; //City Name
	}
    }

    // Start Setter Functions

    /**
     * set city by it's name or id or lat. and lon.
     * @param type string
     * @param type integer
     * @param type decimal
     * @param type decimal
     */
    public function set_city($name = null, $id = null, $lat = null, $lon = null) {
	if ($name) {
	    $this->city = $name;
	    $this->city_id = null;
	    $this->city_lat = null;
	    $this->city_lon = null;
            $this->file_name =  $this->city;
	}

	if ($id) {
	    $this->city_id = $id;
	    $this->city = null;
	    $this->city_lat = null;
	    $this->city_lon = null;
            $this->file_name = $this->city_id;
	}

	if ($lat && $lon) {
	    $this->city_lat = $lat;
            $this->city_lon = $lon;
	    $this->city_id = null;
	    $this->city = null;
            $this->file_name =  $this->city_lat."_".$this->city_lon;
	}

	
    }

    /**
     * Set Theme
     * 
     * @param type string
     */
    public function set_theme($theme) {
	if (isset($this->themes[$theme])) {
	    $this->theme = $this->themes[$theme];
	}
    }

    /**
     * Set temp. metrics
     * @param type char
     */
    public function set_temp_metrics($metrics = 'c') {
	if ($metrics == 'c' || $metrics == 'f')
	    $this->temp_metric = $metrics;
    }

    /**
     * Set language
     * @param type string
     */
    public function set_lang($lang) {
	if (isset($this->languages[$lang])) {
	    $this->lang = $lang;
	}

	if (in_array($lang, $this->api_lang)) {
	    $this->lang_api = $lang;
	}
    }

    /**
     * Set widget dimention
     * @param type integer
     * @param type integer
     */
    public function set_dimention($width, $height) {
	if ($width > 270)
	    $this->width = $width;
	if ($height > 248)
	    $this->height = $height;
    }

    /**
     * Set output type accept empty string or word 'row'
     * @param type string
     */
    public function set_output($out = "") {
	if ($out == "row") {
	    $this->output = "row";
	}
    }

    /**
     * set cache time and folder and this will enable cache
     * you have to provide cache time greater than 0 second
     * and cache folder name is optional , if you didn't provide it 
     * it will use default cache folder
     * @param type integer
     * @param type string
     */
    public function set_cache($cache_time, $cache_folder = false) {
	if ($cache_time > 0) {
	    $this->cache = TRUE;
	    $this->cache_time = $cache_time;
	    if ($cache_folder)
		$this->cache_folder = $cache_folder;
	}
    }

    /**
     * Stop caching
     */
    public function disable_cache() {
	$this->cache = FALSE;
    }

    /**
     * get weather widget or row array according to your config
     * $this->weather_info['rain'] array is available if any rain data available
     * AND it's array:)
     * Thank's for Ray <ray@tzweather.org>
     * @return type
     */
    public function get_weather() {
	if (!$this->city && !$this->city_id && (!$this->city_lat && !$this->city_lon))
	    return $this->languages[$this->lang]['invalid_city_info'];
	//City Detrmine method
	$search_q = "";
	if ($this->city) {
	    $search_q = "q=" . $this->city;
	} elseif ($this->city_id) {
	    $search_q = "id=" . $this->city_id;
	} else {
	    $search_q = "lat=" . $this->city_lat . "&lon=" . $this->city_lon;
	}

	$read_cache = $this->read_wether();

	if ($read_cache) {
	    $weather = true;
	} else {
	    $weather = @file_get_contents($this->weather_api . $search_q . '&lang=' . $this->lang_api);
	}
        
	if ($weather) {
	    if (!$read_cache) {
		$weather_forecast = @file_get_contents($this->forecast_api . $search_q . '&lang=' . $this->lang_api);
		$weather = json_decode($weather);
		$weather_forecast = json_decode($weather_forecast);
		//print_r($weather_forecast);

		if (isset($weather->message))
		    return ($weather->message);
		//Extract Weather
		$this->extract_weather($weather, $weather_forecast);
	    }

	    if ($this->output == "row") {
		return $this->weather_info;
	    }
	    //Else return markup
	    return $this->markup();
	} else {
	    return $this->languages[$this->lang]['cannot_access'];
	}
    }

    //Private Methods
    /**
     * extract weather to weather info
     * @param type object
     * @param type object
     */
    private function extract_weather($weather, $weather_forecast) {
	//Normal Weather data
	$this->weather_info['place'] = $weather->name . (($weather->name) ? ',' : '' ) . $weather->sys->country;
	$this->weather_info['icon'] = $weather->weather[0]->icon;
	$this->weather_info['weather_main'] = $weather->weather[0]->main;
	$this->weather_info['weather_description'] = $weather->weather[0]->description;
	$this->weather_info['temp_c'] = round($weather->main->temp, 1);
	$this->weather_info['temp_c_accurate'] = ($weather->main->temp);
	$this->weather_info['temp_f'] = round((9 / 5) * $weather->main->temp, 1) + 32;
	$this->weather_info['temp_f_accurate'] = ((9 / 5) * $weather->main->temp) + 32;
	$this->weather_info['temp'] = (($this->temp_metric == 'c') ? $this->weather_info['temp_c'] : $this->weather_info['temp_f']);
	$this->weather_info['symbol'] = (($this->temp_metric == 'c') ? 'C' : 'F');
	$this->weather_info['humidity'] = $weather->main->humidity;
	$this->weather_info['wind_speed'] = $weather->wind->speed;
        $this->weather_info['rain'] = (isset($weather->rain)) ? (array)$weather->rain : false;
	//Aditinal info
	$this->weather_info['wind_degree'] = $weather->wind->deg;
	$this->weather_info['pressure'] = $weather->main->pressure;
	$this->weather_info['lat'] = $weather->coord->lat;
	$this->weather_info['lon'] = $weather->coord->lon;

	//Forecast Data For Next Three days
	$forecaster = array();
	for ($i = 1; $i <= 3; $i++) {
	    $forecaster[$i]['day'] = date('D', $weather_forecast->list[$i]->dt);
	    $forecaster[$i]['month'] = date('M d', $weather_forecast->list[$i]->dt);
	    $forecaster[$i]['min_temp_c'] = round($weather_forecast->list[$i]->temp->min, 1);
	    $forecaster[$i]['min_temp_f'] = round((9 / 5) * $weather_forecast->list[$i]->temp->min, 1) + 32;
	    $forecaster[$i]['max_temp_c'] = round($weather_forecast->list[$i]->temp->max, 1);
	    $forecaster[$i]['max_temp_f'] = round((9 / 5) * $weather_forecast->list[$i]->temp->max, 1) + 32;
	    $forecaster[$i]['temp_max'] = (($this->temp_metric == 'c') ? $forecaster[$i]['max_temp_c'] : $forecaster[$i]['max_temp_f']);
	    $forecaster[$i]['temp_min'] = (($this->temp_metric == 'c') ? $forecaster[$i]['min_temp_c'] : $forecaster[$i]['min_temp_f']);
	    $forecaster[$i]['symbol'] = (($this->temp_metric == 'c') ? 'C' : 'F');
	    $forecaster[$i]['weather_main'] = $weather_forecast->list[$i]->weather[0]->main;
	    $forecaster[$i]['icon'] = $weather_forecast->list[$i]->weather[0]->icon;
	}
	//Append To weather info 
	$this->weather_info['forecast'] = $forecaster;

	//IF Cache enabled,save data to file
	if ($this->cache) {
	    $this->save_weather($this->weather_info);
	}
    }

    /**
     * save weather to cache
     * @param type array
     */
    private function save_weather($weather) {
	$weather_json = json_encode($weather);
	$file = $this->cache_folder . $this->file_name . '.txt';
	$handle = @fopen($file, 'w');
	if ($handle) {
	    fwrite($handle, $weather_json);
	    fclose($handle);
	}
    }

    /**
     * load weather from cache
     * @return boolean
     */
    private function read_wether() {
	$file = $this->cache_folder . $this->file_name . '.txt';
	if (file_exists($file)) {
	    if (((time() - $this->cache_time) > filemtime($file)) || !$this->cache)
		return false; //This file is not fresh or cache disabled
	    $handle = @fopen($file, 'r');
	    if ($handle) {
		$json_weather = fread($handle, filesize($file));
		$this->weather_info = json_decode($json_weather, true);
		/** CHECK FOR METRICS AND FIX IT * */
		if ($this->temp_metric == "c") {
		    $this->weather_info['temp'] = $this->weather_info['temp_c'];
		    $this->weather_info['symbol'] = 'C';

		    for ($i = 1; $i <= 3; $i++) {
			$this->weather_info['forecast'][$i]['temp_min'] = $this->weather_info['forecast'][$i]['min_temp_c'];
			$this->weather_info['forecast'][$i]['temp_max'] = $this->weather_info['forecast'][$i]['max_temp_c'];
			$this->weather_info['forecast'][$i]['symbol'] = 'C';
		    }
		} else {
		    $this->weather_info['temp'] = $this->weather_info['temp_f'];
		    $this->weather_info['symbol'] = 'F';
		    for ($i = 1; $i <= 3; $i++) {
			$this->weather_info['forecast'][$i]['temp_min'] = $this->weather_info['forecast'][$i]['min_temp_f'];
			$this->weather_info['forecast'][$i]['temp_max'] = $this->weather_info['forecast'][$i]['max_temp_f'];
			$this->weather_info['forecast'][$i]['symbol'] = 'F';
		    }
		}

		fclose($handle);
		return true;
	    }
	}

	return false;
    }

    /**
     * Get weather markup(Widget)
     * @return string
     */
    private function markup() {
	$next_weather = $this->languages[$this->lang]['show_next_days'];
	$back_weather = $this->languages[$this->lang]['back_to_weather'];
	$markup = '<div class="widget" style="width:' . $this->width . 'px;height:' . $this->height . 'px"> 
		   <div class="upper">
		   <div class="degree-box">
		   <div class="temp">
		   <h2 class="title"><span class="update">' . $this->weather_info['temp'] . '<sup>o</sup>' . $this->weather_info['symbol'] . '</span></h2></div>
		   <div class="place update ' . $this->theme . '-place">' . $this->weather_info['place'] . '</div></div>
		   <div id="change-weather" onclick="change_weather($(this))" show-ul="weather-forecast"  class="change-weather next-icon" title="' . $next_weather . '"></div>
		   </div>
		   <div class="clear"></div>
		   <div class="lower ' . $this->theme . '-lower">
		    
		   <ul id="weather-info" class="infos-w">
		   <li class="info-w weather"><h2 class="title"><span class="weather-bg" title="' . $this->languages[$this->lang]['weather'] . '"></span></h2>
		    <span class="update">' . $this->weather_info['weather_main'] . '</span>
		   <h2 class="title"><span><img title="' . $this->languages[$this->lang]['weather_desc'] . '" src="http://openweathermap.org/img/w/' . $this->weather_info['icon'] . '.png" /></span></h2>
		       <span class="update">' . $this->weather_info['weather_description'] . '</span></li>
		   <li class="info-w wind"><h2 class="title"><span class="wind-bg" title="' . $this->languages[$this->lang]['wind'] . '"></span></h2>
		       <span class="update">' . $this->weather_info['wind_speed'] . 'm/s</span>
		   <h2><span class="wind-degree" title="' . $this->languages[$this->lang]['wind_degree'] . '"></span></h2><p class="update">' . $this->weather_info['wind_degree'] . '<sup>o</sup></p></li>
		   <li class="info-w"><h2 class="title"><span class="humidity" title="' . $this->languages[$this->lang]['humidity'] . '"></span></h2>
		   <p class="update">' . $this->weather_info['humidity'] . '%</p>
		   <h2><span class="pressure" title="' . $this->languages[$this->lang]['pressure'] . '"></span> </h2><p class="update">' . $this->weather_info['pressure'] . ' hPa</p></li></ul>';


	$inner_li = "";
	foreach ($this->weather_info['forecast'] as $weather) {
	    $inner_li .= '<li class="info-w"><h2 class="title">' . $weather['day'] . '</h2><h3>' . $weather['month'] . '</h3>
		   <span class="main update">
		   <img title="' . $weather['weather_main'] . '" src="http://openweathermap.org/img/w/' . $weather['icon'] . '" /></span>
		   <br/><span class="des update">' . $this->languages[$this->lang]['hi'] . ': ' . $weather['temp_max'] . '<sup>o</sup>' . $weather['symbol'] . '<br/>
		    ' . $this->languages[$this->lang]['lo'] . ': ' . $weather['temp_min'] . '<sup>o</sup>' . $weather['symbol'] . '</span></li>';
	}

	$markup .= '<ul style="display:none"  id="weather-forecast" class="infos-w">' . $inner_li . '</ul></div></div>';

	//JAVASCRIPT
	$markup .= '<script type="text/javascript">
	    function change_weather (sender){
		var elm = sender.attr("show-ul");
		var next_elm = "";
		
		if(elm == "weather-forecast"){
		    next_elm = "weather-info";
		    sender.removeClass("next-icon");
		    sender.addClass("back-icon");
		    sender.prop("title","' . $back_weather . '");
		}
		else {
		    next_elm = "weather-forecast";
		    sender.removeClass("back-icon");
		    sender.addClass("next-icon");
		    sender.prop("title","' . $next_weather . '");
		}
		
		//Set element next item
		sender.attr("show-ul",next_elm);
		sender.parent().parent().find("#"+next_elm).slideUp("slow");
		sender.parent().parent().find("#"+elm).slideDown("slow");
	    }
	</script>';
	return $markup;
    }

}