Skip to content

Commit

Permalink
Refactor to command (#13)
Browse files Browse the repository at this point in the history
* wip

* wip

* wip
  • Loading branch information
Larsklopstra authored Nov 15, 2021
1 parent 5ca343a commit 7b24a50
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 34 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.**
Expand Down
61 changes: 61 additions & 0 deletions src/Commands/GenerateFaviconsCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

namespace ArchTech\SEO\Commands;

use Illuminate\Console\Command;
use Intervention\Image\ImageManager;

class GenerateFaviconsCommand extends Command
{
protected $signature = 'seo:generate-favicons {from?}';

protected $description = 'Generate favicons based on a source file';

public function handle(): int
{
$path = $this->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;
}
}
30 changes: 1 addition & 29 deletions src/SEOManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
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.
Expand Down Expand Up @@ -179,36 +177,10 @@ public function flipp(string $alias, string|array $data = null): string|static
}

/** 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;
}

Expand Down
7 changes: 7 additions & 0 deletions src/SEOServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace ArchTech\SEO;

use ArchTech\SEO\Commands\GenerateFaviconsCommand;
use Illuminate\Support\ServiceProvider;
use ImLiam\BladeHelper\BladeHelperServiceProvider;
use ImLiam\BladeHelper\Facades\BladeHelper;
Expand All @@ -20,6 +21,12 @@ public function boot(): void
{
$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');
Expand Down
37 changes: 33 additions & 4 deletions tests/Pest/FaviconTest.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,43 @@
<?php

use ArchTech\SEO\Commands\GenerateFaviconsCommand;

use function Pest\Laravel\artisan;
use function PHPUnit\Framework\assertFileDoesNotExist;
use function PHPUnit\Framework\assertFileExists;

test("it should throw an exception if the given source icon doesn't exist", function () {
seo()->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'));
});

0 comments on commit 7b24a50

Please sign in to comment.