diff --git a/README.md b/README.md index 37b3f62..cc600fd 100644 --- a/README.md +++ b/README.md @@ -104,9 +104,19 @@ seo()->twitterTitle('About us') By default, no favicon links will be included. You can manually enable the extension by calling: ```php -seo()->favicon('path/to/logo.png'); +seo()->favicon(); ``` +## Generating favicons + +To generate favicon, run: + +``` +php artisan seo:generate-favicons public/path-to/logo.png +``` + +from the artisan console. If no path argument is given we'll fallback to `public/assets/logo.png`. + We'll generate a 32x32px `public/favicon.ico` & `public/favicon.png` icon. This should be sufficient for most cases. **Please keep in mind that you need to install the [imagick](https://pecl.php.net/package/imagick) php extension and [intervention/image](http://image.intervention.io/) composer package.** diff --git a/src/Commands/GenerateFaviconsCommand.php b/src/Commands/GenerateFaviconsCommand.php new file mode 100644 index 0000000..da4628b --- /dev/null +++ b/src/Commands/GenerateFaviconsCommand.php @@ -0,0 +1,61 @@ +argument('from') ?? public_path('assets/logo.png'); + + if (! is_string($path)) { + $this->error('The `from` argument must be a string.'); + + return Command::FAILURE; + } + + $this->info('Generating favicons...'); + + if (! class_exists(ImageManager::class)) { + $this->error('Intervention not available, please run `composer require intervention/image`'); + + return Command::FAILURE; + } + + if (! file_exists($path)) { + $this->error("Given icon path `{$path}` does not exist."); + + return Command::FAILURE; + } + + // GD driver doesn't support .ico, that's why we use ImageMagick. + $manager = new ImageManager(['driver' => 'imagick']); + + $this->comment('Generating ico...'); + + $manager + ->make($path) + ->resize(32, 32) + ->save(public_path('favicon.ico')); + + $this->comment('Generating png...'); + + $manager + ->make($path) + ->resize(32, 32) + ->save(public_path('favicon.png')); + + $this->info('All favicons have been generated!'); + + return Command::SUCCESS; + } +} diff --git a/src/SEOManager.php b/src/SEOManager.php index 2a24a6a..f0c7fdc 100644 --- a/src/SEOManager.php +++ b/src/SEOManager.php @@ -5,9 +5,7 @@ declare(strict_types=1); namespace ArchTech\SEO; use Closure; -use Exception; use Illuminate\Support\Str; -use Intervention\Image\ImageManager; /** * @method $this title(string $title = null, ...$args) Set the title. @@ -182,36 +180,10 @@ class SEOManager } /** Enable favicon extension. */ - public function favicon(string $path): static + public function favicon(): static { - if (! class_exists(ImageManager::class)) { - throw new Exception('Intervention not available, please run `composer require intervention/image`'); - } - $this->extensions['favicon'] = true; - $doesntHaveFavicon = ! file_exists(public_path('favicon.ico')); - $sourceIconDoesntExist = ! file_exists($path); - - if ($sourceIconDoesntExist) { - throw new Exception("Given icon path `{$path}` does not exist."); - } - - if ($doesntHaveFavicon) { - // GD driver doesn't support .ico, that's why we use ImageMagick. - $manager = new ImageManager(['driver' => 'imagick']); - - $manager - ->make($path) - ->resize(32, 32) - ->save(public_path('favicon.ico')); - - $manager - ->make($path) - ->resize(32, 32) - ->save(public_path('favicon.png')); - } - return $this; } diff --git a/src/SEOServiceProvider.php b/src/SEOServiceProvider.php index 6c0ce03..7e063ca 100644 --- a/src/SEOServiceProvider.php +++ b/src/SEOServiceProvider.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace ArchTech\SEO; +use ArchTech\SEO\Commands\GenerateFaviconsCommand; use Illuminate\Support\ServiceProvider; use ImLiam\BladeHelper\BladeHelperServiceProvider; use ImLiam\BladeHelper\Facades\BladeHelper; @@ -20,6 +21,12 @@ class SEOServiceProvider extends ServiceProvider { $this->loadViewsFrom(__DIR__ . '/../assets/views', 'seo'); + if ($this->app->runningInConsole()) { + $this->commands([ + GenerateFaviconsCommand::class, + ]); + } + $this->publishes([ __DIR__ . '/../assets/views' => resource_path('views/vendor/seo'), ], 'seo-views'); diff --git a/tests/Pest/FaviconTest.php b/tests/Pest/FaviconTest.php index 50d47cc..2c9ca40 100644 --- a/tests/Pest/FaviconTest.php +++ b/tests/Pest/FaviconTest.php @@ -1,14 +1,43 @@ favicon('i-dont-exist.png'); -})->throws(Exception::class, 'Given icon path `i-dont-exist.png` does not exist.'); +// Clean up generated files +beforeEach(function () { + $files = [ + 'favicon.ico', + 'favicon.png', + ]; + + foreach ($files as $file) { + @unlink(public_path($file)); + } +}); test('it should generate two favicons', function () { - seo()->favicon(__DIR__ . '/../stubs/logo.png'); + seo()->favicon(); + + $from = __DIR__ . '/../stubs/logo.png'; + + artisan(GenerateFaviconsCommand::class, [ + 'from' => $from, + ])->assertSuccessful(); assertFileExists(public_path('favicon.ico')); assertFileExists(public_path('favicon.png')); }); + +test('it should fail because the from path is incorrect', function () { + seo()->favicon(); + + artisan(GenerateFaviconsCommand::class, [ + 'from' => 'i/dont/exist.png', + ])->assertFailed(); + + assertFileDoesNotExist(public_path('favicon.ico')); + assertFileDoesNotExist(public_path('favicon.png')); +});