├── src ├── views │ ├── txt.php │ ├── xml-mobile.php │ ├── html.php │ ├── sitemapindex.php │ ├── ror-rss.php │ ├── ror-rdf.php │ ├── google-news.php │ └── xml.php ├── config │ └── config.php ├── Ultrono │ └── Sitemap │ │ ├── SitemapServiceProvider.php │ │ ├── Model.php │ │ └── Sitemap.php └── public │ └── styles │ ├── mobile.xsl │ ├── sitemapindex.xsl │ ├── google-news.xsl │ └── xml.xsl ├── CHANGELOG-9.x.md ├── phpunit.xml ├── composer.json ├── LICENSE.md ├── README.md └── .github └── workflows └── run-tests.yml /src/views/txt.php: -------------------------------------------------------------------------------- 1 | false, 6 | 'cache_key' => 'laravel-sitemap.'.config('app.url'), 7 | 'cache_duration' => 3600, 8 | 'escaping' => true, 9 | 'use_limit_size' => false, 10 | 'max_size' => null, 11 | 'use_styles' => true, 12 | 'styles_location' => '/vendor/sitemap/styles/', 13 | 'use_gzip' => false 14 | ]; 15 | -------------------------------------------------------------------------------- /src/views/xml-mobile.php: -------------------------------------------------------------------------------- 1 | '."\n" ?> 2 | '."\n"; 4 | } ?> 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/views/html.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <?= $channel['title'] ?> 5 | 6 | 7 |

8 | 16 | 17 | -------------------------------------------------------------------------------- /src/views/sitemapindex.php: -------------------------------------------------------------------------------- 1 | '."\n"; ?> 2 | '."\n"; 4 | } ?> 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/views/ror-rss.php: -------------------------------------------------------------------------------- 1 | '."\n"; ?> 2 | 3 | 4 | <?= $channel['title'] ?> 5 | 6 | 7 | 8 | 9 | <?= $item['title'] ?> 10 | 11 | 12 | 13 | sitemap 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/views/ror-rdf.php: -------------------------------------------------------------------------------- 1 | '."\n"; ?> 2 | 3 | 4 | <?= $channel['title'] ?> 5 | 6 | sitemap 7 | 8 | 9 | 10 | 11 | <?= $item['title'] ?> 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | 18 | 19 | ./src/Ultrono/Sitemap 20 | 21 | ./tests/ 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ultrono/laravel-sitemap", 3 | "description": "PHP 8 sitemap generator for Laravel 8, 9, 10 and 11", 4 | "keywords": ["laravel", "php", "sitemap", "generator", "xml", "html", "google-news"], 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Rumen Damyanov", 9 | "email": "r@alfamatter.com", 10 | "role": "Original Developer", 11 | "homepage": "https://darumen.com" 12 | }, 13 | { 14 | "name": "Rob Allport", 15 | "email": "rob@f9web.co.uk", 16 | "role": "Developer", 17 | "homepage": "https://f9web.co.uk" 18 | } 19 | ], 20 | "require": { 21 | "php": "^8.0", 22 | "illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0", 23 | "illuminate/filesystem": "^8.0|^9.0|^10.0|^11.0|^12.0" 24 | }, 25 | "require-dev": { 26 | "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0|^10.0", 27 | "phpunit/phpunit": "^9.4|^10.1|^11.5.3" 28 | }, 29 | "autoload": { 30 | "psr-0": { 31 | "Ultrono\\Sitemap": "src/" 32 | } 33 | }, 34 | "extra": { 35 | "laravel": { 36 | "providers": [ 37 | "Ultrono\\Sitemap\\SitemapServiceProvider" 38 | ] 39 | } 40 | }, 41 | "minimum-stability": "dev", 42 | "prefer-stable": true 43 | } 44 | -------------------------------------------------------------------------------- /src/Ultrono/Sitemap/SitemapServiceProvider.php: -------------------------------------------------------------------------------- 1 | loadViewsFrom(__DIR__.'/../../views', 'sitemap'); 20 | 21 | $config_file = __DIR__.'/../../config/config.php'; 22 | 23 | $this->mergeConfigFrom($config_file, 'sitemap'); 24 | 25 | $this->publishes([ 26 | $config_file => config_path('sitemap.php'), 27 | ], 'config'); 28 | 29 | $this->publishes([ 30 | __DIR__.'/../../views' => base_path('resources/views/vendor/sitemap'), 31 | ], 'views'); 32 | 33 | $this->publishes([ 34 | __DIR__.'/../../public' => public_path('vendor/sitemap'), 35 | ], 'public'); 36 | } 37 | 38 | /** 39 | * Register the service provider. 40 | * 41 | * @return void 42 | */ 43 | public function register() 44 | { 45 | $this->app->bind('sitemap', function (Container $app) { 46 | $config = $app->make('config'); 47 | 48 | return new Sitemap( 49 | $config->get('sitemap'), 50 | $app->make('cache.store'), 51 | $config, 52 | $app->make('files'), 53 | $app->make(ResponseFactory::class), 54 | $app->make('view') 55 | ); 56 | }); 57 | 58 | $this->app->alias('sitemap', Sitemap::class); 59 | } 60 | 61 | /** 62 | * {@inheritdoc} 63 | */ 64 | public function provides() 65 | { 66 | return ['sitemap', Sitemap::class]; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/views/google-news.php: -------------------------------------------------------------------------------- 1 | '."\n" ?> 2 | '."\n"; 4 | } ?> 5 | 6 | 7 | 8 | 9 | '.date('Y-m-d\TH:i:sP', strtotime($item['lastmod'])).''."\n"; 12 | } 13 | ?> 14 | '."\n"; 18 | } 19 | } 20 | ?> 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | '.$item['googlenews']['access'].''."\n"; 31 | } 32 | 33 | if (isset($item['googlenews']['keywords'])) { 34 | echo "\t\t".''.implode(',', $item['googlenews']['keywords']).''."\n"; 35 | } 36 | 37 | if (isset($item['googlenews']['genres'])) { 38 | echo "\t\t".''.implode(',', $item['googlenews']['genres']).''."\n"; 39 | } 40 | 41 | if (isset($item['googlenews']['stock_tickers'])) { 42 | echo "\t\t".''.implode(',', $item['googlenews']['stock_tickers']).''."\n"; 43 | } 44 | ?> 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Rumen Damyanov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | Developer’s Certificate of Origin 1.1 23 | 24 | By making a contribution to this project, I certify that: 25 | 26 | (a) The contribution was created in whole or in part by me and I 27 | have the right to submit it under the open source license 28 | indicated in the file; or 29 | 30 | (b) The contribution is based upon previous work that, to the best 31 | of my knowledge, is covered under an appropriate open source 32 | license and I have the right under that license to submit that 33 | work with modifications, whether created in whole or in part 34 | by me, under the same open source license (unless I am 35 | permitted to submit under a different license), as indicated 36 | in the file; or 37 | 38 | (c) The contribution was provided directly to me by some other 39 | person who certified (a), (b) or (c) and I have not modified 40 | it. 41 | 42 | (d) I understand and agree that this project and the contribution 43 | are public and that a record of the contribution (including all 44 | personal information I submit with it, including my sign-off) is 45 | maintained indefinitely and may be redistributed consistent with 46 | this project or the open source license(s) involved. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Packagist Version](https://img.shields.io/packagist/v/ultrono/laravel-sitemap?link=https%3A%2F%2Fpackagist.org%2Fpackages%2Fultrono%2Flaravel-sitemap) 2 | [![run-tests](https://github.com/ultrono/laravel-sitemap/actions/workflows/run-tests.yml/badge.svg)](https://github.com/ultrono/laravel-sitemap/actions/workflows/run-tests.yml) 3 | [![PHP ^8.0](https://img.shields.io/badge/php-%5E8.0-green)]() 4 | 5 | # Laravel Sitemap 6 | 7 | This is a Laravel 8, 9, 10, 11 and 12 only fork of [Laravelium/laravel-sitemap](https://github.com/Laravelium/laravel-sitemap). The original repository has been abandoned. 8 | 9 | PHP `^8.0` is required. 10 | 11 | ## Installation 12 | 13 | If `laravelium/sitemap` is already part of the project: 14 | 15 | ```bash 16 | composer remove laravelium/sitemap 17 | ``` 18 | Then run: 19 | 20 | ```bash 21 | composer require ultrono/laravel-sitemap 22 | ``` 23 | 24 | ```bash 25 | php artisan vendor:publish --provider="Ultrono\Sitemap\SitemapServiceProvider" 26 | ``` 27 | 28 | ## Generate a simple sitemap 29 | 30 | ```php 31 | Route::get('mysitemap', function() { 32 | $sitemap = resolve("sitemap"); 33 | 34 | $sitemap->add(URL::to(), '2012-08-25T20:10:00+02:00', '1.0', 'daily'); 35 | $sitemap->add(URL::to('page'), '2012-08-26T12:30:00+02:00', '0.9', 'monthly'); 36 | 37 | $posts = DB::table('posts')->orderBy('created_at', 'desc')->get(); 38 | 39 | foreach ($posts as $post) { 40 | $sitemap->add($post->slug, $post->modified, $post->priority, $post->freq); 41 | } 42 | 43 | // generate (format, filename) 44 | // sitemap.xml is stored within the public folder 45 | $sitemap->store('xml', 'sitemap'); 46 | }); 47 | ``` 48 | 49 | ## Examples 50 | 51 | - [How to generate dynamic sitemap (with optional caching)](https://web.archive.org/web/20201130155031/https://github.com/Laravelium/laravel-sitemap/wiki/Dynamic-sitemap) 52 | - [How to generate BIG sitemaps (with more than 1M items)](https://web.archive.org/web/20201130155031/https://github.com/Laravelium/laravel-sitemap/wiki/Sitemap-index) 53 | - [How to generate sitemap to a file](https://web.archive.org/web/20201130155030/https://github.com/Laravelium/laravel-sitemap/wiki/Generate-sitemap) 54 | - [How to use multiple sitemaps with sitemap index](https://web.archive.org/web/20201130155030/https://github.com/Laravelium/laravel-sitemap/wiki/Generate-BIG-sitemaps) 55 | 56 | and more in the [Wiki](https://web.archive.org/web/20201130155038/https://github.com/Laravelium/laravel-sitemap/wiki). 57 | -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: "Run Tests - Current" 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | 8 | runs-on: ubuntu-latest 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | php: [8.3, 8.2, 8.1, 8.0] 13 | laravel: ["^12.0", "^11.0", "^10.0", "^9.0", "^8.12"] 14 | dependency-version: [prefer-stable] 15 | include: 16 | - laravel: ^12.0 17 | testbench: 10.* 18 | - laravel: ^11.0 19 | testbench: 9.* 20 | - laravel: ^10.0 21 | testbench: 8.* 22 | - laravel: ^9.0 23 | testbench: 7.* 24 | - laravel: ^8.12 25 | testbench: ^6.23 26 | exclude: 27 | - laravel: ^8.12 28 | php: 8.3 29 | - laravel: ^10.0 30 | php: 8.0 31 | - laravel: ^11.0 32 | php: 8.0 33 | - laravel: ^11.0 34 | php: 8.1 35 | - laravel: ^12.0 36 | php: 8.0 37 | - laravel: ^12.0 38 | php: 8.1 39 | 40 | name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} 41 | 42 | steps: 43 | - name: Checkout code 44 | uses: actions/checkout@v4 45 | 46 | - name: Get Composer Cache Directory 47 | id: composer-cache 48 | run: | 49 | echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT 50 | 51 | - uses: actions/cache@v4 52 | with: 53 | path: ${{ steps.composer-cache.outputs.dir }} 54 | key: ${{ runner.os }}-composer-${{ matrix.os }}-php-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }} 55 | restore-keys: | 56 | ${{ runner.os }}-composer- 57 | 58 | # - name: Cache dependencies 59 | # uses: actions/cache@v4 60 | # with: 61 | # path: ~/.composer/cache/files 62 | # key: dependencies-laravel-${{ matrix.laravel }}-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} 63 | 64 | - name: Setup PHP 65 | uses: shivammathur/setup-php@v2 66 | with: 67 | php-version: ${{ matrix.php }} 68 | extensions: curl, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, iconv 69 | coverage: none 70 | 71 | - name: Install dependencies 72 | run: | 73 | composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "symfony/console:>=4.3.4" "mockery/mockery:^1.3.2" --no-interaction --no-update 74 | composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction 75 | 76 | - name: Display PHP version 77 | run: php -v | grep ^PHP | cut -d' ' -f2 78 | 79 | - name: Execute tests 80 | run: vendor/bin/phpunit 81 | -------------------------------------------------------------------------------- /src/public/styles/mobile.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | XML Sitemap (for Feature Phones) 8 | 9 | 10 | 18 | 98 | 99 | 100 |
101 |

XML Sitemap (for Feature Phones)

102 |

Generated by ultrono-sitemap. This is styled xml sitemap (for feature phones).

103 |

This sitemap contains URLs.

104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 |
URL
118 |
119 |
120 | 121 | 122 |
123 |
124 | -------------------------------------------------------------------------------- /src/public/styles/sitemapindex.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | XML Sitemap Index 8 | 9 | 10 | 18 | 98 | 99 | 100 |
101 |

XML Sitemap Index

102 |

Generated by ultrono-sitemap. This is styled xml sitemapindex, sorted by update date.

103 |

This sitemap contains URLs.

104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
URLUpdated at
120 |
121 |
122 | 123 | 124 |
125 |
126 | -------------------------------------------------------------------------------- /src/public/styles/google-news.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | XML Sitemap (for Google News) 8 | 9 | 10 | 18 | 96 | 97 | 98 |
99 |

XML Sitemap (for Google News)

100 |

Generated by ultrono-sitemap. This is styled xml sitemap (for Google News), sorted by update date.

101 |

This sitemap contains URLs.

102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 |
URLTitlePublisherLanguageGenresAccessUpdated at
128 |
129 |
130 | 131 | 132 |
133 |
134 | -------------------------------------------------------------------------------- /src/public/styles/xml.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | XML Sitemap 8 | 9 | 10 | 18 | 96 | 97 | 98 |
99 |

XML Sitemap

100 |

Generated by ultrono/laravel-sitemap. This is styled xml sitemap, sorted by update date.

101 |

This sitemap contains URLs.

102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 |
URLAlternatesImagesVideosPriorityUpdate freqUpdated at
128 |
129 |
130 | 131 | 132 |
133 |
134 | -------------------------------------------------------------------------------- /src/views/xml.php: -------------------------------------------------------------------------------- 1 | '."\n" ?> 2 | '."\n"; 4 | } ?> 5 | 6 | 7 | 8 | 9 | '."\n"; 14 | } 15 | } 16 | 17 | if (! empty($item['alternates'])) { 18 | foreach ($item['alternates'] as $alternate) { 19 | echo "\t\t".''."\n"; 20 | } 21 | } 22 | 23 | if ($item['priority'] !== null) { 24 | echo "\t\t".''.$item['priority'].''."\n"; 25 | } 26 | 27 | if ($item['lastmod'] !== null) { 28 | echo "\t\t".''.date('Y-m-d\TH:i:sP', strtotime($item['lastmod'])).''."\n"; 29 | } 30 | 31 | if ($item['freq'] !== null) { 32 | echo "\t\t".''.$item['freq'].''."\n"; 33 | } 34 | 35 | if (! empty($item['images'])) { 36 | foreach ($item['images'] as $image) { 37 | echo "\t\t".''."\n"; 38 | echo "\t\t\t".''.$image['url'].''."\n"; 39 | if (isset($image['title'])) { 40 | echo "\t\t\t".''.$image['title'].''."\n"; 41 | } 42 | if (isset($image['caption'])) { 43 | echo "\t\t\t".''.$image['caption'].''."\n"; 44 | } 45 | if (isset($image['geo_location'])) { 46 | echo "\t\t\t".''.$image['geo_location'].''."\n"; 47 | } 48 | if (isset($image['license'])) { 49 | echo "\t\t\t".''.$image['license'].''."\n"; 50 | } 51 | echo "\t\t".''."\n"; 52 | } 53 | } 54 | 55 | if (! empty($item['videos'])) { 56 | foreach ($item['videos'] as $video) { 57 | echo "\t\t".''."\n"; 58 | if (isset($video['thumbnail_loc'])) { 59 | echo "\t\t\t".''.$video['thumbnail_loc'].''."\n"; 60 | } 61 | if (isset($video['title'])) { 62 | echo "\t\t\t".''."\n"; 63 | } 64 | if (isset($video['description'])) { 65 | echo "\t\t\t".''."\n"; 66 | } 67 | if (isset($video['content_loc'])) { 68 | echo "\t\t\t".''.$video['content_loc'].''."\n"; 69 | } 70 | if (isset($video['duration'])) { 71 | echo "\t\t\t".''.$video['duration'].''."\n"; 72 | } 73 | if (isset($video['expiration_date'])) { 74 | echo "\t\t\t".''.$video['expiration_date'].''."\n"; 75 | } 76 | if (isset($video['rating'])) { 77 | echo "\t\t\t".''.$video['rating'].''."\n"; 78 | } 79 | if (isset($video['view_count'])) { 80 | echo "\t\t\t".''.$video['view_count'].''."\n"; 81 | } 82 | if (isset($video['publication_date'])) { 83 | echo "\t\t\t".''.$video['publication_date'].''."\n"; 84 | } 85 | if (isset($video['family_friendly'])) { 86 | echo "\t\t\t".''.$video['family_friendly'].''."\n"; 87 | } 88 | if (isset($video['requires_subscription'])) { 89 | echo "\t\t\t".''.$video['requires_subscription'].''."\n"; 90 | } 91 | if (isset($video['live'])) { 92 | echo "\t\t\t".''.$video['live'].''."\n"; 93 | } 94 | if (isset($video['player_loc'])) { 95 | echo "\t\t\t".''.$video['player_loc']['player_loc'].''."\n"; 97 | } 98 | if (isset($video['restriction'])) { 99 | echo "\t\t\t".''.$video['restriction']['restriction'].''."\n"; 100 | } 101 | if (isset($video['gallery_loc'])) { 102 | echo "\t\t\t".''.$video['gallery_loc']['gallery_loc'].''."\n"; 103 | } 104 | if (isset($video['price'])) { 105 | echo "\t\t\t".''.$video['price']['price'].''."\n"; 106 | } 107 | if (isset($video['uploader'])) { 108 | echo "\t\t\t".''.$video['uploader']['uploader'].''."\n"; 109 | } 110 | echo "\t\t".''."\n"; 111 | } 112 | } 113 | 114 | ?> 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /src/Ultrono/Sitemap/Model.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * @version 7.0.1 11 | * 12 | * @link https://github.com/ultrono/laravel-sitemap 13 | * 14 | * @license http://opensource.org/licenses/mit-license.php MIT License 15 | */ 16 | class Model 17 | { 18 | /** 19 | * @var bool 20 | */ 21 | public $testing = false; 22 | 23 | /** 24 | * @var array 25 | */ 26 | private $items = []; 27 | 28 | /** 29 | * @var array 30 | */ 31 | private $sitemaps = []; 32 | 33 | /** 34 | * @var string 35 | */ 36 | private $title = null; 37 | 38 | /** 39 | * @var string 40 | */ 41 | private $link = null; 42 | 43 | /** 44 | * Enable or disable xsl styles. 45 | * 46 | * @var bool 47 | */ 48 | private $useStyles = true; 49 | 50 | /** 51 | * Set custom location for xsl styles (must end with slash). 52 | * 53 | * @var string 54 | */ 55 | private $sloc = '/vendor/sitemap/styles/'; 56 | 57 | /** 58 | * Enable or disable cache. 59 | * 60 | * @var bool 61 | */ 62 | private $useCache = false; 63 | 64 | /** 65 | * Unique cache key. 66 | * 67 | * @var string 68 | */ 69 | private $cacheKey = 'laravel-sitemap.'; 70 | 71 | /** 72 | * Cache duration, can be int or timestamp. 73 | * 74 | * @var Carbon|Datetime|int 75 | */ 76 | private $cacheDuration = 3600; 77 | 78 | /** 79 | * Escaping html entities. 80 | * 81 | * @var bool 82 | */ 83 | private $escaping = true; 84 | 85 | /** 86 | * Use limitSize() for big sitemaps. 87 | * 88 | * @var bool 89 | */ 90 | private $useLimitSize = false; 91 | 92 | /** 93 | * Custom max size for limitSize(). 94 | * 95 | * @var bool 96 | */ 97 | private $maxSize = null; 98 | 99 | /** 100 | * Use gzip compression. 101 | * 102 | * @var bool 103 | */ 104 | private $useGzip = false; 105 | 106 | /** 107 | * Populating model variables from configuration file. 108 | * 109 | * @param array $config 110 | */ 111 | public function __construct(array $config) 112 | { 113 | $this->useCache = isset($config['use_cache']) ? $config['use_cache'] : $this->useCache; 114 | $this->cacheKey = isset($config['cache_key']) ? $config['cache_key'] : $this->cacheKey; 115 | $this->cacheDuration = isset($config['cache_duration']) ? $config['cache_duration'] : $this->cacheDuration; 116 | $this->escaping = isset($config['escaping']) ? $config['escaping'] : $this->escaping; 117 | $this->useLimitSize = isset($config['use_limit_size']) ? $config['use_limit_size'] : $this->useLimitSize; 118 | $this->useStyles = isset($config['use_styles']) ? $config['use_styles'] : $this->useStyles; 119 | $this->sloc = isset($config['styles_location']) ? $config['styles_location'] : $this->sloc; 120 | $this->maxSize = isset($config['max_size']) ? $config['max_size'] : $this->maxSize; 121 | $this->testing = isset($config['testing']) ? $config['testing'] : $this->testing; 122 | $this->useGzip = isset($config['use_gzip']) ? $config['use_gzip'] : $this->useGzip; 123 | } 124 | 125 | /** 126 | * Returns $items array. 127 | * 128 | * @return array 129 | */ 130 | public function getItems() 131 | { 132 | return $this->items; 133 | } 134 | 135 | /** 136 | * Returns $sitemaps array. 137 | * 138 | * @return array 139 | */ 140 | public function getSitemaps() 141 | { 142 | return $this->sitemaps; 143 | } 144 | 145 | /** 146 | * Returns $title value. 147 | * 148 | * @return string 149 | */ 150 | public function getTitle() 151 | { 152 | return $this->title; 153 | } 154 | 155 | /** 156 | * Returns $link value. 157 | * 158 | * @return string 159 | */ 160 | public function getLink() 161 | { 162 | return $this->link; 163 | } 164 | 165 | /** 166 | * Returns $useStyles value. 167 | * 168 | * @return bool 169 | */ 170 | public function getUseStyles() 171 | { 172 | return $this->useStyles; 173 | } 174 | 175 | /** 176 | * Returns $sloc value. 177 | * 178 | * @return string 179 | */ 180 | public function getSloc() 181 | { 182 | return $this->sloc; 183 | } 184 | 185 | /** 186 | * Returns $useCache value. 187 | * 188 | * @return bool 189 | */ 190 | public function getUseCache() 191 | { 192 | return $this->useCache; 193 | } 194 | 195 | /** 196 | * Returns $CacheKey value. 197 | * 198 | * @return string 199 | */ 200 | public function getCacheKey() 201 | { 202 | return $this->cacheKey; 203 | } 204 | 205 | /** 206 | * Returns $CacheDuration value. 207 | * 208 | * @return string 209 | */ 210 | public function getCacheDuration() 211 | { 212 | return $this->cacheDuration; 213 | } 214 | 215 | /** 216 | * Returns $escaping value. 217 | * 218 | * @return bool 219 | */ 220 | public function getEscaping() 221 | { 222 | return $this->escaping; 223 | } 224 | 225 | /** 226 | * Returns $useLimitSize value. 227 | * 228 | * @return bool 229 | */ 230 | public function getUseLimitSize() 231 | { 232 | return $this->useLimitSize; 233 | } 234 | 235 | /** 236 | * Returns $maxSize value. 237 | * 238 | * @param int $maxSize 239 | */ 240 | public function getMaxSize() 241 | { 242 | return $this->maxSize; 243 | } 244 | 245 | /** 246 | * Returns $useGzip value. 247 | * 248 | * @param bool $useGzip 249 | */ 250 | public function getUseGzip() 251 | { 252 | return $this->useGzip; 253 | } 254 | 255 | /** 256 | * Sets $escaping value. 257 | * 258 | * @param bool $escaping 259 | */ 260 | public function setEscaping($b) 261 | { 262 | $this->escaping = $b; 263 | } 264 | 265 | /** 266 | * Adds item to $items array. 267 | * 268 | * @param array $item 269 | */ 270 | public function setItems($items) 271 | { 272 | $this->items[] = $items; 273 | } 274 | 275 | /** 276 | * Adds sitemap to $sitemaps array. 277 | * 278 | * @param array $sitemap 279 | */ 280 | public function setSitemaps($sitemap) 281 | { 282 | $this->sitemaps[] = $sitemap; 283 | } 284 | 285 | /** 286 | * Sets $title value. 287 | * 288 | * @param string $title 289 | */ 290 | public function setTitle($title) 291 | { 292 | $this->title = $title; 293 | } 294 | 295 | /** 296 | * Sets $link value. 297 | * 298 | * @param string $link 299 | */ 300 | public function setLink($link) 301 | { 302 | $this->link = $link; 303 | } 304 | 305 | /** 306 | * Sets $useStyles value. 307 | * 308 | * @param bool $useStyles 309 | */ 310 | public function setUseStyles($useStyles) 311 | { 312 | $this->useStyles = $useStyles; 313 | } 314 | 315 | /** 316 | * Sets $sloc value. 317 | * 318 | * @param string $sloc 319 | */ 320 | public function setSloc($sloc) 321 | { 322 | $this->sloc = $sloc; 323 | } 324 | 325 | /** 326 | * Sets $useLimitSize value. 327 | * 328 | * @param bool $useLimitSize 329 | */ 330 | public function setUseLimitSize($useLimitSize) 331 | { 332 | $this->useLimitSize = $useLimitSize; 333 | } 334 | 335 | /** 336 | * Sets $maxSize value. 337 | * 338 | * @param int $maxSize 339 | */ 340 | public function setMaxSize($maxSize) 341 | { 342 | $this->maxSize = $maxSize; 343 | } 344 | 345 | /** 346 | * Sets $useGzip value. 347 | * 348 | * @param bool $useGzip 349 | */ 350 | public function setUseGzip($useGzip=true) 351 | { 352 | $this->useGzip = $useGzip; 353 | } 354 | 355 | /** 356 | * Limit size of $items array to 50000 elements (1000 for google-news). 357 | */ 358 | public function limitSize($max = 50000) 359 | { 360 | $this->items = array_slice($this->items, 0, $max); 361 | } 362 | 363 | /** 364 | * Reset $items array. 365 | * 366 | * @param array $items 367 | */ 368 | public function resetItems($items = []) 369 | { 370 | $this->items = $items; 371 | } 372 | 373 | /** 374 | * Reset $sitemaps array. 375 | * 376 | * @param array $sitemaps 377 | */ 378 | public function resetSitemaps($sitemaps = []) 379 | { 380 | $this->sitemaps = $sitemaps; 381 | } 382 | 383 | /** 384 | * Set use cache value. 385 | * 386 | * @param bool $useCache 387 | */ 388 | public function setUseCache($useCache = true) 389 | { 390 | $this->useCache = $useCache; 391 | } 392 | 393 | /** 394 | * Set cache key value. 395 | * 396 | * @param string $cacheKey 397 | */ 398 | public function setCacheKey($cacheKey) 399 | { 400 | $this->cacheKey = $cacheKey; 401 | } 402 | 403 | /** 404 | * Set cache duration value. 405 | * 406 | * @param Carbon|Datetime|int $cacheDuration 407 | */ 408 | public function setCacheDuration($cacheDuration) 409 | { 410 | $this->cacheDuration = $cacheDuration; 411 | } 412 | } 413 | -------------------------------------------------------------------------------- /src/Ultrono/Sitemap/Sitemap.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * @version 7.0.1 11 | * 12 | * @license http://opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | use Illuminate\Filesystem\Filesystem as Filesystem; 16 | use Illuminate\Contracts\View\Factory as ViewFactory; 17 | use Illuminate\Contracts\Cache\Repository as CacheRepository; 18 | use Illuminate\Contracts\Config\Repository as ConfigRepository; 19 | use Illuminate\Contracts\Routing\ResponseFactory as ResponseFactory; 20 | 21 | class Sitemap 22 | { 23 | /** 24 | * Model instance. 25 | * 26 | * @var Model 27 | */ 28 | public $model = null; 29 | 30 | /** 31 | * CacheRepository instance. 32 | * 33 | * @var CacheRepository 34 | */ 35 | public $cache = null; 36 | 37 | /** 38 | * ConfigRepository instance. 39 | * 40 | * @var ConfigRepository 41 | */ 42 | protected $configRepository = null; 43 | 44 | /** 45 | * Filesystem instance. 46 | * 47 | * @var Filesystem 48 | */ 49 | protected $file = null; 50 | 51 | /** 52 | * ResponseFactory instance. 53 | * 54 | * @var ResponseFactory 55 | */ 56 | protected $response = null; 57 | 58 | /** 59 | * ViewFactory instance. 60 | * 61 | * @var ViewFactory 62 | */ 63 | protected $view = null; 64 | 65 | /** 66 | * Using constructor we populate our model from configuration file 67 | * and loading dependencies. 68 | * 69 | * @param array $config 70 | */ 71 | public function __construct(array $config, CacheRepository $cache, ConfigRepository $configRepository, Filesystem $file, ResponseFactory $response, ViewFactory $view) 72 | { 73 | $this->cache = $cache; 74 | $this->configRepository = $configRepository; 75 | $this->file = $file; 76 | $this->response = $response; 77 | $this->view = $view; 78 | 79 | $this->model = new Model($config); 80 | } 81 | 82 | /** 83 | * Set cache options. 84 | * 85 | * @param string $key 86 | * @param \Carbon\Carbon|Datetime|int $duration 87 | * @param bool $useCache 88 | */ 89 | public function setCache($key = null, $duration = null, $useCache = true) 90 | { 91 | $this->model->setUseCache($useCache); 92 | 93 | if (null !== $key) { 94 | $this->model->setCacheKey($key); 95 | } 96 | 97 | if (null !== $duration) { 98 | $this->model->setCacheDuration($duration); 99 | } 100 | } 101 | 102 | /** 103 | * Checks if content is cached. 104 | * 105 | * @return bool 106 | */ 107 | public function isCached() 108 | { 109 | if ($this->model->getUseCache()) { 110 | if ($this->cache->has($this->model->getCacheKey())) { 111 | return true; 112 | } 113 | } 114 | 115 | return false; 116 | } 117 | 118 | /** 119 | * Add new sitemap item to $items array. 120 | * 121 | * @param string $loc 122 | * @param string $lastmod 123 | * @param string $priority 124 | * @param string $freq 125 | * @param array $images 126 | * @param string $title 127 | * @param array $translations 128 | * @param array $videos 129 | * @param array $googlenews 130 | * @param array $alternates 131 | * 132 | * @return void 133 | */ 134 | public function add($loc, $lastmod = null, $priority = null, $freq = null, $images = [], $title = null, $translations = [], $videos = [], $googlenews = [], $alternates = []) 135 | { 136 | $params = [ 137 | 'loc' => $loc, 138 | 'lastmod' => $lastmod, 139 | 'priority' => $priority, 140 | 'freq' => $freq, 141 | 'images' => $images, 142 | 'title' => $title, 143 | 'translations' => $translations, 144 | 'videos' => $videos, 145 | 'googlenews' => $googlenews, 146 | 'alternates' => $alternates, 147 | ]; 148 | 149 | $this->addItem($params); 150 | } 151 | 152 | /** 153 | * Add new sitemap one or multiple items to $items array. 154 | * 155 | * @param array $params 156 | * 157 | * @return void 158 | */ 159 | public function addItem($params = []) 160 | { 161 | 162 | // if is multidimensional 163 | if (array_key_exists(1, $params)) { 164 | foreach ($params as $a) { 165 | $this->addItem($a); 166 | } 167 | 168 | return; 169 | } 170 | 171 | // get params 172 | foreach ($params as $key => $value) { 173 | $$key = $value; 174 | } 175 | 176 | // set default values 177 | if (! isset($loc)) { 178 | $loc = '/'; 179 | } 180 | if (! isset($lastmod)) { 181 | $lastmod = null; 182 | } 183 | if (! isset($priority)) { 184 | $priority = null; 185 | } 186 | if (! isset($freq)) { 187 | $freq = null; 188 | } 189 | if (! isset($title)) { 190 | $title = null; 191 | } 192 | if (! isset($images)) { 193 | $images = []; 194 | } 195 | if (! isset($translations)) { 196 | $translations = []; 197 | } 198 | if (! isset($alternates)) { 199 | $alternates = []; 200 | } 201 | if (! isset($videos)) { 202 | $videos = []; 203 | } 204 | if (! isset($googlenews)) { 205 | $googlenews = []; 206 | } 207 | 208 | // escaping 209 | if ($this->model->getEscaping()) { 210 | $loc = htmlentities($loc, ENT_XML1); 211 | 212 | if ($title != null) { 213 | htmlentities($title, ENT_XML1); 214 | } 215 | 216 | if ($images) { 217 | foreach ($images as $k => $image) { 218 | foreach ($image as $key => $value) { 219 | $images[$k][$key] = htmlentities($value, ENT_XML1); 220 | } 221 | } 222 | } 223 | 224 | if ($translations) { 225 | foreach ($translations as $k => $translation) { 226 | foreach ($translation as $key => $value) { 227 | $translations[$k][$key] = htmlentities($value, ENT_XML1); 228 | } 229 | } 230 | } 231 | 232 | if ($alternates) { 233 | foreach ($alternates as $k => $alternate) { 234 | foreach ($alternate as $key => $value) { 235 | $alternates[$k][$key] = htmlentities($value, ENT_XML1); 236 | } 237 | } 238 | } 239 | 240 | if ($videos) { 241 | foreach ($videos as $k => $video) { 242 | if (! empty($video['title'])) { 243 | $videos[$k]['title'] = htmlentities($video['title'], ENT_XML1); 244 | } 245 | if (! empty($video['description'])) { 246 | $videos[$k]['description'] = htmlentities($video['description'], ENT_XML1); 247 | } 248 | } 249 | } 250 | 251 | if ($googlenews) { 252 | if (isset($googlenews['sitename'])) { 253 | $googlenews['sitename'] = htmlentities($googlenews['sitename'], ENT_XML1); 254 | } 255 | } 256 | } 257 | 258 | $googlenews['sitename'] = isset($googlenews['sitename']) ? $googlenews['sitename'] : ''; 259 | $googlenews['language'] = isset($googlenews['language']) ? $googlenews['language'] : 'en'; 260 | $googlenews['publication_date'] = isset($googlenews['publication_date']) ? $googlenews['publication_date'] : date('Y-m-d H:i:s'); 261 | 262 | $this->model->setItems([ 263 | 'loc' => $loc, 264 | 'lastmod' => $lastmod, 265 | 'priority' => $priority, 266 | 'freq' => $freq, 267 | 'images' => $images, 268 | 'title' => $title, 269 | 'translations' => $translations, 270 | 'videos' => $videos, 271 | 'googlenews' => $googlenews, 272 | 'alternates' => $alternates, 273 | ]); 274 | } 275 | 276 | /** 277 | * Add new sitemap to $sitemaps array. 278 | * 279 | * @param string $loc 280 | * @param string $lastmod 281 | * 282 | * @return void 283 | */ 284 | public function addSitemap($loc, $lastmod = null) 285 | { 286 | $this->model->setSitemaps([ 287 | 'loc' => $loc, 288 | 'lastmod' => $lastmod, 289 | ]); 290 | } 291 | 292 | /** 293 | * Add new sitemap to $sitemaps array. 294 | * 295 | * @param string $loc 296 | * @param string $lastmod 297 | * 298 | * @return void 299 | */ 300 | public function resetSitemaps($sitemaps = []) 301 | { 302 | $this->model->resetSitemaps($sitemaps); 303 | } 304 | 305 | /** 306 | * Returns document with all sitemap items from $items array. 307 | * 308 | * @param string $format (options: xml, html, txt, ror-rss, ror-rdf, google-news) 309 | * @param string $style (path to custom xls style like '/styles/xsl/xml-sitemap.xsl') 310 | * 311 | * @return \Illuminate\Http\Response 312 | */ 313 | public function render($format = 'xml', $style = null) 314 | { 315 | // limit size of sitemap 316 | if ($this->model->getMaxSize() > 0 && count($this->model->getItems()) > $this->model->getMaxSize()) { 317 | $this->model->limitSize($this->model->getMaxSize()); 318 | } elseif ('google-news' == $format && count($this->model->getItems()) > 1000) { 319 | $this->model->limitSize(1000); 320 | } elseif ('google-news' != $format && count($this->model->getItems()) > 50000) { 321 | $this->model->limitSize(); 322 | } 323 | 324 | $data = $this->generate($format, $style); 325 | 326 | return $this->response->make($data['content'], 200, $data['headers']); 327 | } 328 | 329 | /** 330 | * Generates document with all sitemap items from $items array. 331 | * 332 | * @param string $format (options: xml, html, txt, ror-rss, ror-rdf, sitemapindex, google-news) 333 | * @param string $style (path to custom xls style like '/styles/xsl/xml-sitemap.xsl') 334 | * 335 | * @return array 336 | */ 337 | public function generate($format = 'xml', $style = null) 338 | { 339 | // check if caching is enabled, there is a cached content and its duration isn't expired 340 | if ($this->isCached()) { 341 | ('sitemapindex' == $format) ? $this->model->resetSitemaps($this->cache->get($this->model->getCacheKey())) : $this->model->resetItems($this->cache->get($this->model->getCacheKey())); 342 | } elseif ($this->model->getUseCache()) { 343 | ('sitemapindex' == $format) ? $this->cache->put($this->model->getCacheKey(), $this->model->getSitemaps(), $this->model->getCacheDuration()) : $this->cache->put($this->model->getCacheKey(), $this->model->getItems(), $this->model->getCacheDuration()); 344 | } 345 | 346 | if (! $this->model->getLink()) { 347 | $this->model->setLink($this->configRepository->get('app.url')); 348 | } 349 | 350 | if (! $this->model->getTitle()) { 351 | $this->model->setTitle('Sitemap for '.$this->model->getLink()); 352 | } 353 | 354 | $channel = [ 355 | 'title' => $this->model->getTitle(), 356 | 'link' => $this->model->getLink(), 357 | ]; 358 | 359 | // check if styles are enabled 360 | if ($this->model->getUseStyles()) { 361 | if (null != $this->model->getSloc() && file_exists(public_path($this->model->getSloc().$format.'.xsl'))) { 362 | // use style from your custom location 363 | $style = $this->model->getSloc().$format.'.xsl'; 364 | } else { 365 | // don't use style 366 | $style = null; 367 | } 368 | } else { 369 | // don't use style 370 | $style = null; 371 | } 372 | 373 | switch ($format) { 374 | case 'ror-rss': 375 | return ['content' => $this->view->make('sitemap::ror-rss', ['items' => $this->model->getItems(), 'channel' => $channel, 'style' => $style])->render(), 'headers' => ['Content-type' => 'text/rss+xml; charset=utf-8']]; 376 | case 'ror-rdf': 377 | return ['content' => $this->view->make('sitemap::ror-rdf', ['items' => $this->model->getItems(), 'channel' => $channel, 'style' => $style])->render(), 'headers' => ['Content-type' => 'text/rdf+xml; charset=utf-8']]; 378 | case 'html': 379 | return ['content' => $this->view->make('sitemap::html', ['items' => $this->model->getItems(), 'channel' => $channel, 'style' => $style])->render(), 'headers' => ['Content-type' => 'text/html; charset=utf-8']]; 380 | case 'txt': 381 | return ['content' => $this->view->make('sitemap::txt', ['items' => $this->model->getItems(), 'style' => $style])->render(), 'headers' => ['Content-type' => 'text/plain; charset=utf-8']]; 382 | case 'sitemapindex': 383 | return ['content' => $this->view->make('sitemap::sitemapindex', ['sitemaps' => $this->model->getSitemaps(), 'style' => $style])->render(), 'headers' => ['Content-type' => 'text/xml; charset=utf-8']]; 384 | default: 385 | return ['content' => $this->view->make('sitemap::'.$format, ['items' => $this->model->getItems(), 'style' => $style])->render(), 'headers' => ['Content-type' => 'text/xml; charset=utf-8']]; 386 | } 387 | } 388 | 389 | /** 390 | * Generate sitemap and store it to a file. 391 | * 392 | * @param string $format (options: xml, html, txt, ror-rss, ror-rdf, sitemapindex, google-news) 393 | * @param string $filename (without file extension, may be a path like 'sitemaps/sitemap1' but must exist) 394 | * @param string $path (path to store sitemap like '/www/site/public') 395 | * @param string $style (path to custom xls style like '/styles/xsl/xml-sitemap.xsl') 396 | * 397 | * @return void 398 | */ 399 | public function store($format = 'xml', $filename = 'sitemap', $path = null, $style = null) 400 | { 401 | // turn off caching for this method 402 | $this->model->setUseCache(false); 403 | 404 | // use correct file extension 405 | (in_array($format, ['txt', 'html'], true)) ? $fe = $format : $fe = 'xml'; 406 | 407 | if (true == $this->model->getUseGzip()) { 408 | $fe = $fe.".gz"; 409 | } 410 | 411 | // use custom size limit for sitemaps 412 | if ($this->model->getMaxSize() > 0 && count($this->model->getItems()) > $this->model->getMaxSize()) { 413 | if ($this->model->getUseLimitSize()) { 414 | // limit size 415 | $this->model->limitSize($this->model->getMaxSize()); 416 | $data = $this->generate($format, $style); 417 | } else { 418 | // use sitemapindex and generate partial sitemaps 419 | foreach (array_chunk($this->model->getItems(), $this->model->getMaxSize()) as $key => $item) { 420 | // reset current items 421 | $this->model->resetItems($item); 422 | 423 | // generate new partial sitemap 424 | $this->store($format, $filename.'-'.$key, $path, $style); 425 | 426 | // add sitemap to sitemapindex 427 | if ($path != null) { 428 | // if using custom path generate relative urls for sitemaps in the sitemapindex 429 | $this->addSitemap($filename.'-'.$key.'.'.$fe); 430 | } else { 431 | // else generate full urls based on app's domain 432 | $this->addSitemap(url($filename.'-'.$key.'.'.$fe)); 433 | } 434 | } 435 | 436 | $data = $this->generate('sitemapindex', $style); 437 | } 438 | } elseif (('google-news' != $format && count($this->model->getItems()) > 50000) || ($format == 'google-news' && count($this->model->getItems()) > 1000)) { 439 | ('google-news' != $format) ? $max = 50000 : $max = 1000; 440 | 441 | // check if limiting size of items array is enabled 442 | if (! $this->model->getUseLimitSize()) { 443 | // use sitemapindex and generate partial sitemaps 444 | foreach (array_chunk($this->model->getItems(), $max) as $key => $item) { 445 | // reset current items 446 | $this->model->resetItems($item); 447 | 448 | // generate new partial sitemap 449 | $this->store($format, $filename.'-'.$key, $path, $style); 450 | 451 | // add sitemap to sitemapindex 452 | if (null != $path) { 453 | // if using custom path generate relative urls for sitemaps in the sitemapindex 454 | $this->addSitemap($filename.'-'.$key.'.'.$fe); 455 | } else { 456 | // else generate full urls based on app's domain 457 | $this->addSitemap(url($filename.'-'.$key.'.'.$fe)); 458 | } 459 | } 460 | 461 | $data = $this->generate('sitemapindex', $style); 462 | } else { 463 | // reset items and use only most recent $max items 464 | $this->model->limitSize($max); 465 | $data = $this->generate($format, $style); 466 | } 467 | } else { 468 | $data = $this->generate($format, $style); 469 | } 470 | 471 | // clear memory 472 | if ('sitemapindex' == $format) { 473 | $this->model->resetSitemaps(); 474 | } 475 | 476 | $this->model->resetItems(); 477 | 478 | // if custom path 479 | if (null == $path) { 480 | $file = public_path().DIRECTORY_SEPARATOR.$filename.'.'.$fe; 481 | } else { 482 | $file = $path.DIRECTORY_SEPARATOR.$filename.'.'.$fe; 483 | } 484 | 485 | if (true == $this->model->getUseGzip()) { 486 | // write file (gzip compressed) 487 | $this->file->put($file, gzencode($data['content'], 9)); 488 | } else { 489 | // write file 490 | $this->file->put($file, $data['content']); 491 | } 492 | } 493 | } 494 | --------------------------------------------------------------------------------