├── .gitignore ├── .travis.yml ├── LICENCE ├── README.md ├── composer.json ├── docs └── example.png ├── phpunit.xml ├── public ├── fonts │ ├── meteocons-webfont.eot │ ├── meteocons-webfont.svg │ ├── meteocons-webfont.ttf │ └── meteocons-webfont.woff └── weather.css ├── src ├── Torann │ └── LaravelWeather │ │ ├── Facade.php │ │ ├── ServiceProvider.php │ │ └── Weather.php ├── config │ └── config.php └── views │ └── widgets │ └── default.blade.php └── tests └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.phar 3 | composer.lock 4 | .DS_Store 5 | .idea -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3 5 | - 5.4 6 | - 5.5 7 | 8 | before_script: 9 | - curl -s http://getcomposer.org/installer | php 10 | - php composer.phar install --dev 11 | 12 | script: phpunit -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | The BSD 2-Clause License 2 | Copyright (c) 2013, Daniel Stainback 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > **NOTICE** This package no longer works as intended, the endpoint it uses no longer exists 2 | 3 | # Laravel Weather 4 | 5 | [![Latest Stable Version](https://poser.pugx.org/torann/laravel-weather/v/stable.png)](https://packagist.org/packages/torann/laravel-weather) [![Total Downloads](https://poser.pugx.org/torann/laravel-weather/downloads.png)](https://packagist.org/packages/torann/laravel-weather) 6 | 7 | Just a simple weather package for Laravel. 8 | 9 | ---------- 10 | 11 | ## Installation 12 | 13 | - [Laravel Weather on Packagist](https://packagist.org/packages/torann/laravel-weather) 14 | - [Laravel Weather on GitHub](https://github.com/torann/laravel-weather) 15 | 16 | To get the latest version of Laravel Weather simply require it in your `composer.json` file. 17 | 18 | ~~~ 19 | "torann/laravel-weather": "0.1.*@dev" 20 | ~~~ 21 | 22 | You'll then need to run `composer install` to download it and have the autoloader updated. 23 | 24 | Once installed you need to register the service provider with the application. Open up `app/config/app.php` and find the providers key. 25 | 26 | ```php 27 | 'providers' => [ 28 | 'Torann\LaravelWeather\ServiceProvider', 29 | ] 30 | ``` 31 | 32 | > **NOTE:** the is automatically registered during boot. 33 | 34 | ### Publish package assets: 35 | 36 | ``` 37 | $ php artisan asset:publish torann/laravel-weather 38 | ``` 39 | 40 | Add the following to the page where the Laravel Weather widget script will be active: 41 | 42 | ``` 43 | {{ HTML::style('/packages/torann/laravel-weather/weather.css') }} 44 | ``` 45 | 46 | If using [Duct](https://github.com/torann/asset-duct) add this to the CSS manifest file: 47 | 48 | ``` 49 | *= require torann/laravel-weather/weather.css 50 | ``` 51 | 52 | ## Rendering 53 | 54 | Rendering weather by point: 55 | 56 | ``` 57 | Weather::renderByPoint($lat, $lng) 58 | ``` 59 | 60 | Rendering weather by city name: 61 | 62 | ``` 63 | Weather::renderByName('Hamden, CT') 64 | ``` 65 | 66 | ## Example 67 | 68 | An live example can be seen on [Snowcrew.org](http://snowcrew.org) 69 | 70 | ![Example.png](./docs/example.png) 71 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "torann/laravel-weather", 3 | "description": "Simple weather forecaster for Laravel", 4 | "keywords": ["laravel", "weather", "forecast", "storms"], 5 | "license": "BSD 2-Clause", 6 | "authors": [ 7 | { 8 | "name": "Daniel Stainback", 9 | "email": "daniel@lyften.com" 10 | } 11 | ], 12 | "require": { 13 | "php": ">=5.4.0", 14 | "illuminate/support": "~4.2" 15 | }, 16 | "autoload": { 17 | "psr-0": { 18 | "Torann\\LaravelWeather": "src/" 19 | } 20 | }, 21 | "extra": { 22 | "branch-alias": { 23 | "dev-master": "0.1-dev" 24 | } 25 | }, 26 | "minimum-stability": "stable" 27 | } 28 | -------------------------------------------------------------------------------- /docs/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Torann/laravel-weather/722d9d41008cff9b87ec69f066ce0fe43b457f72/docs/example.png -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | -------------------------------------------------------------------------------- /public/fonts/meteocons-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Torann/laravel-weather/722d9d41008cff9b87ec69f066ce0fe43b457f72/public/fonts/meteocons-webfont.eot -------------------------------------------------------------------------------- /public/fonts/meteocons-webfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a custom SVG webfont generated by Font Squirrel. 6 | Designer : Alessio Atzeni 7 | Foundry : Alessio Atzeni 8 | Foundry URL : http://www.alessioatzeni.com/meteocons/ 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /public/fonts/meteocons-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Torann/laravel-weather/722d9d41008cff9b87ec69f066ce0fe43b457f72/public/fonts/meteocons-webfont.ttf -------------------------------------------------------------------------------- /public/fonts/meteocons-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Torann/laravel-weather/722d9d41008cff9b87ec69f066ce0fe43b457f72/public/fonts/meteocons-webfont.woff -------------------------------------------------------------------------------- /public/weather.css: -------------------------------------------------------------------------------- 1 | /* Meteocons Webfont */ 2 | @font-face { 3 | font-family: 'MeteoconsRegular'; 4 | src: url('/packages/torann/laravel-weather/fonts/meteocons-webfont.eot'); 5 | src: url('/packages/torann/laravel-weather/fonts/meteocons-webfont.eot?#iefix') format('embedded-opentype'), 6 | url('/packages/torann/laravel-weather/fonts/meteocons-webfont.woff') format('woff'), 7 | url('/packages/torann/laravel-weather/fonts/meteocons-webfont.ttf') format('truetype'), 8 | url('/packages/torann/laravel-weather/fonts/meteocons-webfont.svg#MeteoconsRegular') format('svg'); 9 | font-weight: normal; 10 | font-style: normal; 11 | } 12 | [data-icon]:before { 13 | font-family: 'MeteoconsRegular'; 14 | content: attr(data-icon); 15 | } 16 | 17 | /* Widget Style */ 18 | .weather-widget { 19 | text-align: center; 20 | } 21 | 22 | .weather-widget table { 23 | width: 100%; 24 | margin: 20px 0 0; 25 | text-align: left; 26 | } 27 | .weather-widget table tr td { 28 | padding: 5px 0; 29 | border-top: 1px solid #ddd; 30 | } 31 | .weather-widget table tr:last-child td { 32 | padding-bottom: 0; 33 | } 34 | 35 | .weather-widget .temp span { 36 | margin: 5px 0 5px 5px; 37 | } 38 | .weather-widget .degrees { 39 | display: block; 40 | font-size: 60px; 41 | line-height: 60px; 42 | width: auto; 43 | } 44 | 45 | .weather-widget .details { 46 | text-align: left; 47 | line-height: 20px; 48 | font-size: 12px; 49 | font-weight: normal; 50 | height: 60px; 51 | display: none; 52 | } 53 | .weather-widget .details em { 54 | font-style: normal; 55 | } 56 | 57 | .weather-widget .temp:hover .degrees { 58 | display: none; 59 | } 60 | .weather-widget .temp:hover .details { 61 | display: block; 62 | } 63 | 64 | .weather-widget h4 { 65 | margin: 0; 66 | } 67 | 68 | .weather-widget h5 { 69 | text-transform: uppercase; 70 | } -------------------------------------------------------------------------------- /src/Torann/LaravelWeather/Facade.php: -------------------------------------------------------------------------------- 1 | package('torann/laravel-weather'); 23 | 24 | // Auto create app alias with boot method. 25 | AliasLoader::getInstance()->alias('Weather', 'Torann\LaravelWeather\Facade'); 26 | } 27 | 28 | /** 29 | * Register the service provider. 30 | * 31 | * @return void 32 | */ 33 | public function register() 34 | { 35 | $this->app['torann.weather'] = $this->app->share(function($app) 36 | { 37 | // Get config 38 | $config = $app->config->get('laravel-weather::config', array()); 39 | 40 | return new Weather($app->cache, $app->view, $config); 41 | }); 42 | } 43 | 44 | /** 45 | * Get the services provided by the provider. 46 | * 47 | * @return array 48 | */ 49 | public function provides() 50 | { 51 | return array(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Torann/LaravelWeather/Weather.php: -------------------------------------------------------------------------------- 1 | cache = $cache; 39 | $this->view = $view; 40 | $this->config = $config; 41 | } 42 | 43 | /** 44 | * Render weather widget by location name. 45 | * 46 | * @param string $name 47 | * @param string $units 48 | * @return string 49 | */ 50 | public function renderByName($name = null, $units = null) 51 | { 52 | // Remove commas 53 | $name = strtolower(str_replace(', ', ',', $name)); 54 | 55 | return $this->generate(array( 56 | 'query' => "q={$name}", 57 | 'units' => $units ?: $this->config['defaults']['units'] 58 | )); 59 | } 60 | 61 | /** 62 | * Render weather widget by geo point. 63 | * 64 | * @param float $lat 65 | * @param float $lon 66 | * @param string $units 67 | * @return string 68 | */ 69 | public function renderByPoint($lat, $lon, $units = null) 70 | { 71 | return $this->generate(array( 72 | 'query' => "lat={$lat}&lon={$lon}", 73 | 'units' => $units ?: $this->config['defaults']['units'] 74 | )); 75 | } 76 | 77 | /** 78 | * Render weather widget. 79 | * 80 | * @param array $options 81 | * @return string 82 | */ 83 | public function generate($options = array()) 84 | { 85 | // Get options 86 | $options = array_merge($this->config['defaults'], $options); 87 | 88 | // Unify units 89 | $options['units'] = strtolower($options['units']); 90 | if (! in_array($options['units'], array('metric', 'imperial'))) { 91 | $options['units'] = 'imperial'; 92 | } 93 | 94 | // Create cache key 95 | $cacheKey = 'Weather.'.md5(implode($options)); 96 | 97 | // Check cache 98 | if ($this->config['cache'] && $this->cache->has($cacheKey)) { 99 | return $this->cache->get($cacheKey); 100 | } 101 | 102 | // Get current weather 103 | $current = $this->getWeather($options['query'], 0, $options['units'], 1); 104 | 105 | if($current['cod'] !== 200) { 106 | return 'Unable to load weather'; 107 | } 108 | 109 | // Get forecast 110 | $forecast = $this->getWeather($options['query'], $options['days'], $options['units']); 111 | 112 | // Render view 113 | $html = $this->view->make("{$this->config['views']}.{$options['style']}", array( 114 | 'current' => $current, 115 | 'forecast' => $forecast, 116 | 'units' => $options['units'], 117 | 'date' => $options['date'] 118 | ))->render(); 119 | 120 | // Add to cache 121 | if ($this->config['cache']) { 122 | $this->cache->put($cacheKey, $html, $this->config['cache']); 123 | } 124 | 125 | return $html; 126 | } 127 | 128 | public function getIcon($code) 129 | { 130 | switch ($code) { 131 | case 200 : return '0'; break; 132 | case 201 : return '0'; break; 133 | case 202 : return '0'; break; 134 | case 210 : return '0'; break; 135 | case 211 : return '0'; break; 136 | case 212 : return '0'; break; 137 | case 221 : return '0'; break; 138 | case 230 : return '0'; break; 139 | case 231 : return '0'; break; 140 | case 232 : return '0'; break; 141 | case 300 : return 'R'; break; 142 | case 301 : return 'R'; break; 143 | case 302 : return 'R'; break; 144 | case 310 : return 'R'; break; 145 | case 311 : return 'R'; break; 146 | case 312 : return 'R'; break; 147 | case 321 : return 'R'; break; 148 | case 500 : return 'Q'; break; 149 | case 501 : return 'Q'; break; 150 | case 502 : return 'Q'; break; 151 | case 503 : return 'Q'; break; 152 | case 504 : return 'Q'; break; 153 | case 511 : return 'X'; break; 154 | case 520 : return 'R'; break; 155 | case 521 : return 'R'; break; 156 | case 522 : return 'R'; break; 157 | case 600 : return 'U'; break; 158 | case 601 : return 'W'; break; 159 | case 602 : return 'W'; break; 160 | case 611 : return 'W'; break; 161 | case 621 : return 'W'; break; 162 | case 701 : return 'M'; break; 163 | case 711 : return 'M'; break; 164 | case 721 : return 'M'; break; 165 | case 731 : return 'M'; break; 166 | case 741 : return 'M'; break; 167 | case 800 : return 'B'; break; 168 | case 801 : return 'H'; break; 169 | case 802 : return 'N'; break; 170 | case 803 : return 'Y'; break; 171 | case 804 : return 'Y'; break; 172 | case 900 : return 'F'; break; 173 | case 901 : return 'F'; break; 174 | case 902 : return 'F'; break; 175 | case 905 : return 'F'; break; 176 | case 906 : return 'G'; break; 177 | } 178 | } 179 | 180 | public function getWindDirection($deg) 181 | { 182 | if ($deg >= 0 && $deg < 22.5) return 'N'; 183 | elseif ($deg >= 22.5 && $deg < 45) return 'NNE'; 184 | elseif ($deg >= 45 && $deg < 67.5) return 'NE'; 185 | elseif ($deg >= 67.5 && $deg < 90) return 'ENE'; 186 | elseif ($deg >= 90 && $deg < 122.5) return 'E'; 187 | elseif ($deg >= 112.5 && $deg < 135) return 'ESE'; 188 | elseif ($deg >= 135 && $deg < 157.5) return 'SE'; 189 | elseif ($deg >= 157.5 && $deg < 180) return 'SSE'; 190 | elseif ($deg >= 180 && $deg < 202.5) return 'S'; 191 | elseif ($deg >= 202.5 && $deg < 225) return 'SSW'; 192 | elseif ($deg >= 225 && $deg < 247.5) return 'SW'; 193 | elseif ($deg >= 247.5 && $deg < 270) return 'WSW'; 194 | elseif ($deg >= 270 && $deg < 292.5) return 'W'; 195 | elseif ($deg >= 292.5 && $deg < 315) return 'WNW'; 196 | elseif ($deg >= 315 && $deg < 337.5) return 'NW'; 197 | elseif ($deg >= 337.5 && $deg < 360) return 'NNW'; 198 | } 199 | 200 | private function getWeather($query, $days = 1, $units = 'internal', $type = 0, $lang = 'en') 201 | { 202 | $forecast = ($type == 0) ? 'forecast/daily?' : 'weather?'; 203 | return $this->request("http://api.openweathermap.org/data/2.5/{$forecast}{$query}&cnt={$days}&units={$units}&mode=json&lang={$lang}"); 204 | } 205 | 206 | private function request($url) 207 | { 208 | $ch = curl_init($url); 209 | 210 | curl_setopt($ch, CURLOPT_HEADER, false); 211 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); 212 | curl_setopt($ch, CURLOPT_TIMEOUT, 20); 213 | curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1"); 214 | curl_setopt($ch, CURLOPT_HTTPGET, true); 215 | curl_setopt($ch, CURLOPT_MAXREDIRS, 2); 216 | curl_setopt($ch, CURLOPT_MAXCONNECTS, 2); 217 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 218 | 219 | $response = curl_exec($ch); 220 | curl_close($ch); 221 | 222 | return json_decode( $response, true ); 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /src/config/config.php: -------------------------------------------------------------------------------- 1 | array( 15 | 'style' => 'default', 16 | 'query' => null, 17 | 'days' => 4, 18 | 'units' => 'imperial', 19 | 'night' => 'no', 20 | 'date' => 'l' 21 | ), 22 | 23 | /* 24 | |-------------------------------------------------------------------------- 25 | | Cache Time 26 | |-------------------------------------------------------------------------- 27 | | 28 | | How long to keep the forecast cached 29 | | 30 | */ 31 | 32 | 'cache' => 120, 33 | 34 | /* 35 | |-------------------------------------------------------------------------- 36 | | Weather Widget Views 37 | |-------------------------------------------------------------------------- 38 | | 39 | | The VIEWS used to render weather widget with Laravel Weather 40 | | method render. 41 | | 42 | | By default, the out of the box confide views are used 43 | | but you can create your own widgets and replace the view 44 | | names here. For example 45 | | 46 | | // To use app/views/widgets/weather/{different widgets} 47 | | 48 | | 'views' => 'widgets/weather' 49 | | 50 | | 51 | */ 52 | 53 | 'views' => 'laravel-weather::widgets', 54 | ); 55 | 56 | -------------------------------------------------------------------------------- /src/views/widgets/default.blade.php: -------------------------------------------------------------------------------- 1 |
2 |

{{ $current['name'] }}

3 | 4 |
5 | {{ ceil($current['main']['temp']) }}° 6 | 7 | {{ Lang::get("weather/widget.humidity") }}: {{ ceil( $current['main']['humidity'] ) }}%
8 | {{ Lang::get("weather/widget.clouds") }}: {{ ceil($current['clouds']['all']) }}%
9 | {{ Lang::get("weather/widget.wind") }}: ({{ Weather::getWindDirection($current['wind']['deg']) }}): {{ $units == 'metric' ? ceil($current['wind']['speed'] * 3.6).'kph' : ceil($current['wind']['speed'] * 3.6 / 1.609344).'mph' }}
10 |
11 |
12 | 13 |
{{ $current['weather'][0]['description'] }}
14 | 15 | @if($forecast['cnt'] > 1) 16 | 17 | @foreach($forecast['list'] as $key => $value) 18 | 19 | 20 | 21 | 22 | 23 | 24 | @endforeach 25 |
{{ date($date, $value['dt']) }}{{ ceil($value['temp']['day']) }}°{{ ceil($value['temp']['night']) }}°
26 | @endif 27 | 28 |
-------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Torann/laravel-weather/722d9d41008cff9b87ec69f066ce0fe43b457f72/tests/.gitkeep --------------------------------------------------------------------------------