├── .semver ├── .gitignore ├── TODO.md ├── CHANGELOG.md ├── .travis.yml ├── src ├── config │ └── config.php ├── Cviebrock │ └── LaravelNewsSitemap │ │ ├── ServiceProvider.php │ │ └── NewsSitemap.php └── views │ └── xml.blade.php ├── phpunit.xml ├── composer.json ├── LICENSE ├── tests └── NewsSitemapTest.php └── README.md /.semver: -------------------------------------------------------------------------------- 1 | --- 2 | :major: 0 3 | :minor: 9 4 | :patch: 1 5 | :special: '' 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.phar 3 | composer.lock 4 | .DS_Store 5 | .idea 6 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # Todos 2 | 3 | - [ ] Write tests 4 | - [ ] Better docblock and inline-commenting 5 | - [ ] Make code style consistent 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | 4 | ### 0.9.1 - 07-Oct-2014 5 | 6 | - Flesh-out XML declarations for validation. 7 | - add [Changelog](./CHANGELOG.md) and [To-do](./TODO.md) lists. 8 | - add [Travis CI](https://travis-ci.org/cviebrock/laravel-news-sitemap) testing. 9 | 10 | 11 | ### 0.9.0 - 07-Oct-2014 12 | 13 | - Initial release. 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Travis CI configuration 2 | 3 | language: php 4 | 5 | services: 6 | - redis-server 7 | 8 | php: 9 | - 5.4 10 | - 5.5 11 | - 5.6 12 | - hhvm 13 | 14 | before_script: 15 | - travis_retry composer self-update 16 | - travis_retry composer install --prefer-source --no-interaction --dev 17 | 18 | script: phpunit 19 | -------------------------------------------------------------------------------- /src/config/config.php: -------------------------------------------------------------------------------- 1 | [ 6 | 'enable' => false, 7 | 'key' => 'LaravelNewsSitemap', 8 | 'lifetime' => 60, // minutes 9 | ], 10 | 11 | 'defaults' => [ 12 | 'publication' => [ 13 | 'name' => null, 14 | 'language' => null 15 | ], 16 | 'access' => null, 17 | 'genres' => null, 18 | 'keywords' => [], 19 | 'stock_tickers' => [] 20 | ] 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cviebrock/laravel-news-sitemap", 3 | "description": "A simple Google News Sitemap generator for Laravel.", 4 | "keywords": [ 5 | "laravel", 6 | "sitemap", 7 | "google", 8 | "news" 9 | ], 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Colin Viebrock", 14 | "email": "colin@viebrock.ca" 15 | } 16 | ], 17 | "require": { 18 | "php": ">=5.4", 19 | "illuminate/http": "~4", 20 | "illuminate/support": "~4", 21 | "nesbot/carbon": "~1.0" 22 | }, 23 | "require-dev": { 24 | "phpunit/phpunit": "3.7.*", 25 | "orchestra/testbench": "2.2.*" 26 | }, 27 | "autoload": { 28 | "psr-0": { 29 | "Cviebrock\\LaravelNewsSitemap": "src/" 30 | } 31 | }, 32 | "minimum-stability": "stable" 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Colin Viebrock 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /src/Cviebrock/LaravelNewsSitemap/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | package('cviebrock/laravel-news-sitemap', 'news-sitemap'); 22 | } 23 | 24 | /** 25 | * Register the service provider. 26 | * 27 | * @return void 28 | */ 29 | public function register() { 30 | 31 | $this->app->bind('Cviebrock\LaravelNewsSitemap\NewsSitemap', function ($app) { 32 | 33 | $sitemap = new NewsSitemap( 34 | $app['cache'], 35 | $app['view'] 36 | ); 37 | 38 | $sitemap->setUseCache($app['config']->get('news-sitemap::cache.enable')); 39 | $sitemap->setCacheKey($app['config']->get('news-sitemap::cache.key')); 40 | $sitemap->setCacheLifetime($app['config']->get('news-sitemap::cache.lifetime')); 41 | $sitemap->setDefaults($app['config']->get('news-sitemap::defaults')); 42 | 43 | return $sitemap; 44 | }); 45 | } 46 | 47 | /** 48 | * Get the services provided by the provider. 49 | * 50 | * @return array 51 | */ 52 | public function provides() { 53 | return array(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/views/xml.blade.php: -------------------------------------------------------------------------------- 1 | {{ '<' . '?' . 'xml version="1.0" encoding="UTF-8"' . '?' . '>' }} 2 | 11 | @foreach($entries as $entry) 12 | 13 | {{ $entry['loc'] }} 14 | 15 | 16 | {{ $entry['news']['publication']['name'] }} 17 | {{ $entry['news']['publication']['language'] }} 18 | 19 | @if($entry['news']['access']) 20 | {{ $entry['news']['access'] }} 21 | @endif 22 | @if(count($entry['news']['genres'])) 23 | {{ join(', ', $entry['news']['genres']) }} 24 | @endif 25 | {{ $entry['news']['publication_date'] }} 26 | {{ $entry['news']['title'] }} 27 | @if(count($entry['news']['keywords'])) 28 | {{ join(', ', $entry['news']['keywords']) }} 29 | @endif 30 | @if(count($entry['news']['stock_tickers'])) 31 | {{ join(', ', $entry['news']['stock_tickers']) }} 32 | @endif 33 | 34 | @foreach($entry['images'] as $image) 35 | 36 | {{ $image['loc'] }} 37 | @if($image['caption']) 38 | {{ $image['caption'] }} 39 | @endif 40 | 41 | @endforeach 42 | 43 | @endforeach 44 | 45 | -------------------------------------------------------------------------------- /tests/NewsSitemapTest.php: -------------------------------------------------------------------------------- 1 | sitemap = $this->app->make('Cviebrock\LaravelNewsSitemap\NewsSitemap'); 20 | 21 | $defaults = [ 22 | 'publication' => [ 23 | 'name' => 'Test News Site', 24 | 'language' => 'en' 25 | ], 26 | 'access' => null, 27 | 'genres' => null, 28 | 'keywords' => [], 29 | 'stock_tickers' => [] 30 | ]; 31 | 32 | $this->sitemap->setDefaults($defaults); 33 | } 34 | 35 | public function testAddEntry() { 36 | 37 | $extras = [ 38 | 'keywords' => [ 39 | 'foo', 40 | 'bar' 41 | ] 42 | ]; 43 | 44 | $images = [ 45 | ['loc' => 'http://example.com/1.jpg'], 46 | ['loc' => 'http://example.com/2.jpg'], 47 | ]; 48 | 49 | $this->sitemap->addEntry('http://example.com/', 'Example News Article', '2014-09-26T00:00:00+00:00', $extras, $images); 50 | 51 | $items = $this->sitemap->getEntries(); 52 | 53 | $this->assertCount(1, $items); 54 | 55 | $item = $items[0]; 56 | 57 | $this->assertEquals('http://example.com/', $item['loc']); 58 | 59 | $news = $item['news']; 60 | $this->assertEquals('2014-09-26T00:00:00+00:00', $news['publication_date']); 61 | $this->assertEquals('Example News Article', $news['title']); 62 | 63 | $publication = $news['publication']; 64 | $this->assertEquals('Test News Site', $publication['name']); 65 | $this->assertEquals('en', $publication['language']); 66 | 67 | $this->assertCount(2, $news['keywords']); 68 | $this->assertEquals($extras['keywords'], $news['keywords']); 69 | 70 | $images = $item['images']; 71 | $this->assertCount(2, $images); 72 | $this->assertEquals('http://example.com/1.jpg', $images[0]['loc']); 73 | $this->assertEquals('http://example.com/2.jpg', $images[1]['loc']); 74 | } 75 | 76 | public function testSitemapRender() { 77 | // TODO: finish this test 78 | // $data = $this->sitemap->render() 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # laravel-news-sitemap 2 | 3 | A Google News sitemap generator for Laravel 4. 4 | 5 | [![Build Status](https://travis-ci.org/cviebrock/eloquent-sluggable.svg)](https://travis-ci.org/cviebrock/laravel-news-sitemap) 6 | [![Total Downloads](https://poser.pugx.org/cviebrock/laravel-news-sitemap/downloads.png)](https://packagist.org/packages/cviebrock/laravel-news-sitemap) 7 | [![Latest Stable Version](https://poser.pugx.org/cviebrock/laravel-news-sitemap/v/stable.png)](https://packagist.org/packages/cviebrock/laravel-news-sitemap) 8 | 9 | 10 | 11 | ## Installation 12 | 13 | Add the package to your `composer.json` file: 14 | 15 | ``` 16 | 'cviebrock/laravel-news-sitemap' => 'dev-master' 17 | ``` 18 | 19 | Add the service provider to `app/config/app.php` 20 | 21 | ```php 22 | 'providers' => array( 23 | ... 24 | 'Cviebrock\LaravelNewsSitemap\ServiceProvider', 25 | ); 26 | ``` 27 | 28 | Publish the configuration file: 29 | 30 | ```sh 31 | php artisan config:publish cviebrock/laravel-news-sitemap 32 | ``` 33 | 34 | 35 | 36 | ## Sample Usage 37 | 38 | ```php 39 | // create a new sitemap instance 40 | $sitemap = \App::make('Cviebrock\LaravelNewsSitemap\NewsSitemap'); 41 | 42 | // if it's not cached, then populate with entries 43 | if (!$sitemap->isCached()) { 44 | 45 | foreach (Posts::all() as $post) { 46 | 47 | $extras = []; 48 | $images = []; 49 | 50 | foreach ($post->images as $image) { 51 | $images[] = [ 52 | 'loc' => $image->url, 53 | 'caption' => $image->caption 54 | ]; 55 | } 56 | 57 | $extras['keywords'] = $post->topics->lists('name'); 58 | 59 | $this->sitemap->addEntry($post->url, $post->title, $post->published_at, $extras, $images); 60 | } 61 | 62 | } 63 | 64 | // returns an XML response 65 | return $sitemap->render(); 66 | ``` 67 | 68 | 69 | 70 | ## Bugs, Suggestions and Contributions 71 | 72 | Please use Github for bugs, comments, suggestions. 73 | 74 | 1. Fork the project. 75 | 2. Create your bugfix/feature branch and write your (well-commented) code. 76 | 3. Commit your changes and push to your repository. 77 | 4. Create a new pull request against this project's `master` branch. 78 | 79 | 80 | 81 | ## Copyright and License 82 | 83 | **laravel-news-sitemap** was written by Colin Viebrock and released under the MIT License. See the LICENSE file for details. 84 | 85 | Copyright 2014 Colin Viebrock 86 | -------------------------------------------------------------------------------- /src/Cviebrock/LaravelNewsSitemap/NewsSitemap.php: -------------------------------------------------------------------------------- 1 | cache = $cache; 58 | $this->view = $view; 59 | } 60 | 61 | /** 62 | * @return mixed 63 | */ 64 | public function getCacheKey() { 65 | return $this->cacheKey; 66 | } 67 | 68 | /** 69 | * @param mixed $cacheKey 70 | */ 71 | public function setCacheKey($cacheKey) { 72 | $this->cacheKey = $cacheKey; 73 | } 74 | 75 | /** 76 | * @return mixed 77 | */ 78 | public function getCacheLifetime() { 79 | return $this->cacheLifetime; 80 | } 81 | 82 | /** 83 | * @param mixed $cacheLifetime 84 | */ 85 | public function setCacheLifetime($cacheLifetime) { 86 | $this->cacheLifetime = $cacheLifetime; 87 | } 88 | 89 | /** 90 | * @return mixed 91 | */ 92 | public function getDefaults() { 93 | return $this->defaultValues; 94 | } 95 | 96 | /** 97 | * @param mixed $defaultValues 98 | */ 99 | public function setDefaults($defaultValues) { 100 | $this->defaultValues = $defaultValues; 101 | } 102 | 103 | /** 104 | * @return mixed 105 | */ 106 | public function getUseCache() { 107 | return $this->useCache; 108 | } 109 | 110 | /** 111 | * @param mixed $useCache 112 | */ 113 | public function setUseCache($useCache) { 114 | $this->useCache = $useCache; 115 | } 116 | 117 | /** 118 | * @param $location 119 | * @param $title 120 | * @param $date 121 | * @param array $extras 122 | * @param array $images 123 | */ 124 | public function addEntry($location, $title, $date, $extras = [], $images = []) { 125 | 126 | $news = array_merge( 127 | $this->getDefaults(), 128 | $extras 129 | ); 130 | 131 | $news['publication'] = array_merge( 132 | Arr::get($this->getDefaults(), 'publication', []), 133 | Arr::get($extras, 'publication', []) 134 | ); 135 | 136 | $news['title'] = $title; 137 | 138 | if (is_int($date)) { 139 | $date = Carbon::createFromTimeStamp($date); 140 | } else if (!($date instanceof Carbon)) { 141 | $date = Carbon::parse($date); 142 | } 143 | 144 | $news['publication_date'] = $date->toW3cString(); 145 | 146 | $this->entries[] = [ 147 | 'loc' => $location, 148 | 'news' => $news, 149 | 'images' => $images, 150 | ]; 151 | } 152 | 153 | 154 | /** 155 | * @return \Illuminate\Http\Response 156 | */ 157 | public function render() { 158 | if ($this->getUseCache()) { 159 | $data = $this->cache->remember($this->getCacheKey(), $this->getCacheLifetime(), function () { 160 | return $this->buildXML(); 161 | }); 162 | } else { 163 | $data = $this->buildXML(); 164 | } 165 | 166 | $headers = ['Content-type' => 'text/xml; charset=utf-8']; 167 | 168 | return new Response($data, 200, $headers); 169 | } 170 | 171 | /** 172 | * @return bool 173 | */ 174 | public function isCached() { 175 | return $this->getUseCache() && $this->cache->has($this->getCacheKey()); 176 | } 177 | 178 | /** 179 | * @return array 180 | */ 181 | public function getEntries() { 182 | return $this->entries; 183 | } 184 | 185 | /** 186 | * @return string 187 | */ 188 | protected function buildXML() { 189 | 190 | return $this->view->make('news-sitemap::xml') 191 | ->with('entries', $this->entries) 192 | ->render(); 193 | } 194 | } 195 | --------------------------------------------------------------------------------