diff --git a/app/Http/Controllers/Sitemap.php b/app/Http/Controllers/Sitemap.php new file mode 100644 index 00000000..a72e248e --- /dev/null +++ b/app/Http/Controllers/Sitemap.php @@ -0,0 +1,98 @@ +content = $content; + } + + /** + * Get sitemap for all content pages + * + * @return mixed + */ + public function getMap() + { + // load all public pages + $pages = $this->content->getPageQuery() + ->get(); + + // iterate over all pages and add tag for each of them + foreach ($pages as $page) { + + // is this page a homepage? because of URL + if ($page->is_homepage) { + $route = route('page.index'); + $priority = 1; + } else { + $route = route('page.content', ['url' => $page->url]); + $priority = 0.8; + } + + // compute update frequency + $updateFrequency = $this->getUpdateFrequency($page->updated_at); + + // add to all pages + \Sitemap::addTag($route, $page->updated_at, $updateFrequency, $priority); + } + + // print sitemap + return \Sitemap::render(); + } + + /** + * Based on updatedAt compute "changefreq" for sitemap + * + * @param $updatedAt + */ + private function getUpdateFrequency($updatedAt) + { + // shortcuts for times + $day = 24 * 60 * 60; + $week = 7 * $day; + $month = 4 * $week; + $year = 12 * $month; + + // change frequencies in format "name" => maximum age of last editation + $changeFrequencies = [ + 'always' => 300, + 'hourly' => 3600, + 'daily' => $day, + 'weekly' => $week, + 'monthly' => $month, + 'yearly' => $year, + 'never' => PHP_INT_MAX, + ]; + + // get time difference + $timeDiffInMinutes = time() - strtotime($updatedAt); + + // iterate over array with all change frequencies and break when time of edit is smaller than maximum time + do { + $changeFrequency = key($changeFrequencies); + $changeFreqMinTime = next($changeFrequencies); + } while ($timeDiffInMinutes > $changeFreqMinTime); + + if ($changeFrequency != 'never') { + $changeFrequency = key($changeFrequencies); + } + + return $changeFrequency; + } +} diff --git a/app/Http/routes.php b/app/Http/routes.php index c2f3407e..fb2fbe13 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -222,8 +222,8 @@ Route::group([ Route::post('settings', 'Settings@saveSettings') ->name('settings.save'); - Route::get('search', 'Search@getSearch')->name('search'); - + Route::get('search', 'Search@getSearch') + ->name('search'); // custom fields // ------------------------------ @@ -267,6 +267,10 @@ Route::group(['middleware' => ['web']], function () { Route::post('admin/login', 'Admin\Login@postLogin') ->name('login'); + // route for sitemap + Route::get('sitemap.xml', 'Sitemap@getMap') + ->name('sitemap'); + // route for all content pages. This rule must be specified last (because it matches every route) Route::get('{url}', 'Visitor\ContentPage@getPage') ->name('page.content'); diff --git a/app/Models/Content.php b/app/Models/Content.php index e7251806..9172605b 100644 --- a/app/Models/Content.php +++ b/app/Models/Content.php @@ -40,7 +40,7 @@ class Content extends Model /** * Getter for query with setup filter for non-deleted and non-draft pages */ - protected function getPageQuery() + public function getPageQuery() { return Content::where('status', '!=', Content::STATUS_DELETED) ->where('status', '!=', Content::STATUS_DRAFT); diff --git a/composer.json b/composer.json index 76387c3c..05841dde 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ "php": ">=5.5.9", "laravel/framework": "5.2.*", "pingpong/modules": "~2.0", - "pingpong/menus": "^2.2" + "pingpong/menus": "^2.2", + "watson/sitemap": "^2.0" }, "require-dev": { "fzaninotto/faker": "~1.4", diff --git a/composer.lock b/composer.lock index e39e6dda..302bf315 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "f43cc062336dcfcf344900e76fdb89d2", - "content-hash": "9082c8690c449915674fa1b5194008ae", + "hash": "64dd6115505ac9f62926d5fccc14704d", + "content-hash": "8cefeb3bdf109c79d77ac6cb303a1a96", "packages": [ { "name": "classpreloader/classpreloader", @@ -104,7 +104,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/07a9af2d4de5f9ef0bf2d9ae94421e5fc50d7859", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/2e1b1f7597e2f647e99e96e747fcae9718ac817b", "reference": "07a9af2d4de5f9ef0bf2d9ae94421e5fc50d7859", "shasum": "" }, @@ -172,7 +172,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/e0ef9e9833ca024d251e77e8d82a00ca92b0aa71", + "url": "https://api.github.com/repos/doctrine/cache/zipball/4e3b8b9464d511eccbefe07cef94c275bce7e434", "reference": "e0ef9e9833ca024d251e77e8d82a00ca92b0aa71", "shasum": "" }, @@ -241,7 +241,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/866e100a425b8b73d15393fd081c6bf067f05bf9", + "url": "https://api.github.com/repos/doctrine/collections/zipball/9f89fd349fd2b537be8a0a0c41f87f2f640dfc8a", "reference": "866e100a425b8b73d15393fd081c6bf067f05bf9", "shasum": "" }, @@ -380,7 +380,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/61e1f860a304c3fb6961ecbec36927b5f20b71c6", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/3df22ccdf20a68fafe34cb1ae452aee7cde7d442", "reference": "61e1f860a304c3fb6961ecbec36927b5f20b71c6", "shasum": "" }, @@ -800,7 +800,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/3f45e9b25bd9c01f6205da3e05ae6eea9b3f4a0e", + "url": "https://api.github.com/repos/laravel/framework/zipball/3d95b0328395b2682ac507a1c81bbeafab8b646b", "reference": "3f45e9b25bd9c01f6205da3e05ae6eea9b3f4a0e", "shasum": "" }, @@ -982,7 +982,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/b334d6c5f95364948e06d2f620ab93d084074c6e", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a8294fb7d939433abfaeb0fc1a34a278acfa5b39", "reference": "b334d6c5f95364948e06d2f620ab93d084074c6e", "shasum": "" }, @@ -1065,7 +1065,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/5085630fd606c50d9b09efa0f93c0bdd83603d24", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/064b38c16790249488e7a8b987acf1c9d7383c09", "reference": "5085630fd606c50d9b09efa0f93c0bdd83603d24", "shasum": "" }, @@ -1234,7 +1234,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/06d9ba42dedcee9cda97e81aec92cd876a023e8c", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2d0c3b70f8e701b957fc2e5a35ff32ba57ee5d21", "reference": "06d9ba42dedcee9cda97e81aec92cd876a023e8c", "shasum": "" }, @@ -1699,7 +1699,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/8412f1e1650c27758908c584f63f05bfba3f0314", + "url": "https://api.github.com/repos/symfony/console/zipball/6b1175135bc2a74c08a28d89761272de8beed8cd", "reference": "8412f1e1650c27758908c584f63f05bfba3f0314", "shasum": "" }, @@ -1759,7 +1759,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/b7a2a52278d62b0c5abfdd2e4bb3b55f2109c77f", + "url": "https://api.github.com/repos/symfony/debug/zipball/a06d10888a45afd97534506afb058ec38d9ba35b", "reference": "b7a2a52278d62b0c5abfdd2e4bb3b55f2109c77f", "shasum": "" }, @@ -1816,7 +1816,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1df0dbedb6d9407e5305afe7ca34bee0f2878407", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3433bfec93209ce539751591c3a1d9a1ac5ff53b", "reference": "1df0dbedb6d9407e5305afe7ca34bee0f2878407", "shasum": "" }, @@ -1876,7 +1876,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/623bda0abd9aa29e529c8e9c08b3b84171914723", + "url": "https://api.github.com/repos/symfony/finder/zipball/c54e407b35bc098916704e9fd090da21da4c4f52", "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723", "shasum": "" }, @@ -1925,7 +1925,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8a7648cb85f12e707bab6b6f755ff5d108236023", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b508c1b4d86581ea2b577f067471333ce6b74221", "reference": "8a7648cb85f12e707bab6b6f755ff5d108236023", "shasum": "" }, @@ -1977,7 +1977,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/c554014544e924e88b6d409e4b0d3b0f19f14d45", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f7698089cb78b5f200263da8bd6dd7dfa219c114", "reference": "c554014544e924e88b6d409e4b0d3b0f19f14d45", "shasum": "" }, @@ -2226,7 +2226,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/36c9f90f2e9f97ce8a0bdfbe2c230934d64087a1", + "url": "https://api.github.com/repos/symfony/process/zipball/58c8a0217d8d02b902ed9a0f03913d1836db06e8", "reference": "36c9f90f2e9f97ce8a0bdfbe2c230934d64087a1", "shasum": "" }, @@ -2275,7 +2275,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/fa1e9a8173cf0077dd995205da453eacd758fdf6", + "url": "https://api.github.com/repos/symfony/routing/zipball/0013248050fbd7d00ee90e7ea50c26ec425d666a", "reference": "fa1e9a8173cf0077dd995205da453eacd758fdf6", "shasum": "" }, @@ -2350,7 +2350,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/2de0b6f7ebe43cffd8a06996ebec6aab79ea9e91", + "url": "https://api.github.com/repos/symfony/translation/zipball/f7a07af51ea067745a521dab1e3152044a2fb1f2", "reference": "2de0b6f7ebe43cffd8a06996ebec6aab79ea9e91", "shasum": "" }, @@ -2414,7 +2414,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9a6a883c48acb215d4825ce9de61dccf93d62074", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/140b51f11947ea959165fd4cae4e1946fa5aa5f0", "reference": "9a6a883c48acb215d4825ce9de61dccf93d62074", "shasum": "" }, @@ -2517,6 +2517,52 @@ "environment" ], "time": "2016-02-11 08:44:10" + }, + { + "name": "watson/sitemap", + "version": "2.0.13", + "source": { + "type": "git", + "url": "https://github.com/dwightwatson/sitemap.git", + "reference": "9d616948c1f997d500f48c8b426ac6dd5640cbff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dwightwatson/sitemap/zipball/9d616948c1f997d500f48c8b426ac6dd5640cbff", + "reference": "9d616948c1f997d500f48c8b426ac6dd5640cbff", + "shasum": "" + }, + "require": { + "illuminate/http": "~5.0", + "illuminate/support": "~5.0", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "4.3.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Watson\\": "src/Watson" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dwight Watson", + "email": "dwightwatson@studious.com.au" + } + ], + "description": "Generate Google Sitemaps in Laravel 4/5", + "keywords": [ + "laravel", + "sitemaps" + ], + "time": "2016-04-05 02:28:57" } ], "packages-dev": [ @@ -2584,7 +2630,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/416fb8ad1d095a87f1d21bc40711843cd122fd4a", "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", "shasum": "" }, @@ -2638,7 +2684,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/86ec14457afce95c9ad57ee8394c57f57a1aaf43", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/684eab1624a66a4c37762c747c88a7f8664c65bf", "reference": "86ec14457afce95c9ad57ee8394c57f57a1aaf43", "shasum": "" }, @@ -3259,7 +3305,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/264188ddf4d3586c80ea615f8ec8eaea34e652a1", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f9733ae34271bec6a6a6a1d4e9a8dd28f2ac1628", "reference": "264188ddf4d3586c80ea615f8ec8eaea34e652a1", "shasum": "" }, @@ -3812,7 +3858,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/a5a2d27385655d34fd08557f8a315b6f27cbc5cf", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/18a06d7a9af41718c20764a674a0ebba3bc40d1f", "reference": "a5a2d27385655d34fd08557f8a315b6f27cbc5cf", "shasum": "" }, @@ -3868,7 +3914,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/801d412451594f7c9e7950a016a377798cf9dfa0", + "url": "https://api.github.com/repos/symfony/yaml/zipball/407e31ad9742ace5c3d01642f02a3b2e6062bae5", "reference": "801d412451594f7c9e7950a016a377798cf9dfa0", "shasum": "" }, diff --git a/config/.gitignore b/config/.gitignore index 716bfb98..2475f7d1 100644 --- a/config/.gitignore +++ b/config/.gitignore @@ -16,4 +16,5 @@ !queue.php !services.php !session.php +!sitemap.php !view.php diff --git a/config/app.php b/config/app.php index 7fdee8dd..ae9dec1b 100644 --- a/config/app.php +++ b/config/app.php @@ -13,7 +13,7 @@ return [ | */ - 'env' => env('APP_ENV', 'production'), + 'env' => env('APP_ENV', 'production'), /* |-------------------------------------------------------------------------- | Application Debug Mode @@ -25,7 +25,7 @@ return [ | */ - 'debug' => env('APP_DEBUG', false), + 'debug' => env('APP_DEBUG', false), /* |-------------------------------------------------------------------------- | Application URL @@ -37,7 +37,7 @@ return [ | */ - 'url' => env('SITE_URL', 'http://localhost'), + 'url' => env('SITE_URL', 'http://localhost'), /* |-------------------------------------------------------------------------- | Application Timezone @@ -49,7 +49,7 @@ return [ | */ - 'timezone' => env('TIMEZONE', 'UTC'), + 'timezone' => env('TIMEZONE', 'UTC'), /* |-------------------------------------------------------------------------- | Application Locale Configuration @@ -61,7 +61,7 @@ return [ | */ - 'locale' => env('LOCALES', 'en'), + 'locale' => env('LOCALES', 'en'), /* |-------------------------------------------------------------------------- | Application Fallback Locale @@ -85,19 +85,19 @@ return [ | */ - 'key' => env('APP_KEY'), - 'cipher' => 'AES-256-CBC', + 'key' => env('APP_KEY'), + 'cipher' => 'AES-256-CBC', /* * Upload path used for storing all uploaded files */ - 'upload_path' => env('UPLOAD_PATH', public_path('uploads')), - 'thumbnail_path' => env('THUMBNAIL_PATH', public_path('uploads/thumbnails')), + 'upload_path' => env('UPLOAD_PATH', public_path('uploads')), + 'thumbnail_path' => env('THUMBNAIL_PATH', public_path('uploads/thumbnails')), /* * Artisan cannot access to website URL, therefore we need to use PHP_SAPI const for determining running from CLI. */ - 'upload_url' => env('UPLOAD_URL', PHP_SAPI === 'cli' ? '' : url('uploads')), - 'thumbnail_url' => env('THUMBNAIL_URL', PHP_SAPI === 'cli' ? '' : url('uploads/thumbnails')), - 'theme' => env('THEME'), + 'upload_url' => env('UPLOAD_URL', PHP_SAPI === 'cli' ? '' : url('uploads')), + 'thumbnail_url' => env('THUMBNAIL_URL', PHP_SAPI === 'cli' ? '' : url('uploads/thumbnails')), + 'theme' => env('THEME'), /* |-------------------------------------------------------------------------- | Logging Configuration @@ -111,7 +111,7 @@ return [ | */ - 'log' => env('APP_LOG', 'single'), + 'log' => env('APP_LOG', 'single'), /* |-------------------------------------------------------------------------- | Autoloaded Service Providers @@ -123,7 +123,7 @@ return [ | */ - 'providers' => [ + 'providers' => [ /* * Laravel Framework Service Providers... @@ -153,6 +153,7 @@ return [ App\Providers\ModuleManager::class, Pingpong\Modules\ModulesServiceProvider::class, Pingpong\Menus\MenusServiceProvider::class, + \Watson\Sitemap\SitemapServiceProvider::class, /* * Application Service Providers... */ @@ -174,7 +175,7 @@ return [ | */ - 'aliases' => [ + 'aliases' => [ 'App' => Illuminate\Support\Facades\App::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class, @@ -204,6 +205,7 @@ return [ 'Route' => Illuminate\Support\Facades\Route::class, 'Schema' => Illuminate\Support\Facades\Schema::class, 'Session' => Illuminate\Support\Facades\Session::class, + 'Sitemap' => Watson\Sitemap\Facades\Sitemap::class, 'Storage' => Illuminate\Support\Facades\Storage::class, 'URL' => Illuminate\Support\Facades\URL::class, 'Validator' => Illuminate\Support\Facades\Validator::class, diff --git a/config/sitemap.php b/config/sitemap.php new file mode 100644 index 00000000..91f0d89d --- /dev/null +++ b/config/sitemap.php @@ -0,0 +1,18 @@ + false, + 'cache_length' => 60 +]; diff --git a/index.php b/index.php index 3bfd7057..f65c7c44 100644 --- a/index.php +++ b/index.php @@ -1,4 +1,4 @@ -