Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract the key generator out to use an interface #262

Merged
merged 5 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions config/short-url.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,16 @@
|
*/
'user_agent_driver' => \AshAllenDesign\ShortURL\Classes\UserAgent\ParserPhpDriver::class,

/*
|--------------------------------------------------------------------------
| Short URL Key Generator Class
|--------------------------------------------------------------------------
|
| Define the class that should be used to handle the creation of a unique
| short URL key. This class must implement the following interface:
| AshAllenDesign\ShortURL\Interfaces\UrlKeyGenerator.
|
*/
'url_key_generator' => \AshAllenDesign\ShortURL\Classes\KeyGenerator::class,
];
15 changes: 5 additions & 10 deletions src/Classes/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use AshAllenDesign\ShortURL\Controllers\ShortURLController;
use AshAllenDesign\ShortURL\Exceptions\ShortURLException;
use AshAllenDesign\ShortURL\Exceptions\ValidationException;
use AshAllenDesign\ShortURL\Interfaces\UrlKeyGenerator;
use AshAllenDesign\ShortURL\Models\ShortURL;
use Carbon\Carbon;
use Closure;
Expand All @@ -19,10 +20,8 @@ class Builder
/**
* The class that is used for generating the
* random URL keys.
*
* @var KeyGenerator
*/
private $keyGenerator;
private UrlKeyGenerator $keyGenerator;

/**
* The destination URL that the short URL will
Expand Down Expand Up @@ -177,19 +176,18 @@ class Builder
* config variables are validated.
*
* @param Validation|null $validation
* @param KeyGenerator|null $keyGenerator
*
* @throws ValidationException
*/
public function __construct(Validation $validation = null, KeyGenerator $keyGenerator = null)
public function __construct(UrlKeyGenerator $urlKeyGenerator, Validation $validation = null)
{
if (! $validation) {
$validation = new Validation();
}

$validation->validateConfig();

$this->keyGenerator = $keyGenerator ?? new KeyGenerator();
$this->keyGenerator = $urlKeyGenerator;
}

/**
Expand Down Expand Up @@ -422,11 +420,8 @@ public function urlKey(string $key): self

/**
* Explicitly set the key generator.
*
* @param KeyGenerator $keyGenerator
* @return $this
*/
public function keyGenerator(KeyGenerator $keyGenerator): self
public function keyGenerator(UrlKeyGenerator $keyGenerator): self
{
$this->keyGenerator = $keyGenerator;

Expand Down
21 changes: 9 additions & 12 deletions src/Classes/KeyGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

namespace AshAllenDesign\ShortURL\Classes;

use AshAllenDesign\ShortURL\Interfaces\UrlKeyGenerator;
use AshAllenDesign\ShortURL\Models\ShortURL;
use Hashids\Hashids;

class KeyGenerator
class KeyGenerator implements UrlKeyGenerator
{
/**
* The library class that is used for generating
Expand All @@ -18,21 +19,17 @@ class KeyGenerator
/**
* KeyGenerator constructor.
*/
public function __construct(Hashids $hashids = null)
public function __construct(Hashids $hashids)
{
$this->hashids = $hashids ?: new Hashids(config('short-url.key_salt'), config('short-url.key_length'), config('short-url.alphabet'));
$this->hashids = $hashids;
}

/**
* Generate a unique and random URL key using the
* Hashids package. We start by predicting the
* unique ID that the ShortURL will have in
* the database. Then we can encode the ID
* to create a unique hash. On the very
* unlikely chance that a generated
* key collides with another key,
* we increment the ID and then
* attempt to create a new
* Generate a unique and random URL key using the Hashids package. We start by
* predicting the unique ID that the ShortURL will have in the database.
* Then we can encode the ID to create a unique hash. On the very
* unlikely chance that a generated key collides with another
* key, we increment the ID and then attempt to create a new
* unique key again.
*
* @return string
Expand Down
5 changes: 3 additions & 2 deletions src/Facades/ShortURL.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
namespace AshAllenDesign\ShortURL\Facades;

use AshAllenDesign\ShortURL\Classes\Builder;
use AshAllenDesign\ShortURL\Classes\KeyGenerator;
use AshAllenDesign\ShortURL\Interfaces\UrlKeyGenerator;
use Carbon\Carbon;
use Closure;
use Illuminate\Support\Facades\Facade;
use RuntimeException;

Expand All @@ -22,7 +23,7 @@
* @method static self trackRefererURL(bool $track)
* @method static self trackDeviceType(bool $track)
* @method static self urlKey(string $key)
* @method static self keyGenerator(KeyGenerator $keyGenerator)
* @method static self keyGenerator(UrlKeyGenerator $keyGenerator)
* @method static self redirectStatusCode(int $statusCode)
* @method static self resetOptions()
* @method static self activateAt(Carbon $activationTime)
Expand Down
12 changes: 12 additions & 0 deletions src/Interfaces/UrlKeyGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace AshAllenDesign\ShortURL\Interfaces;

interface UrlKeyGenerator
{
public function generateRandom(): string;

public function generateKeyUsing(int $seed = null): string;
}
3 changes: 2 additions & 1 deletion src/Models/Factories/ShortURLFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use AshAllenDesign\ShortURL\Classes\KeyGenerator;
use AshAllenDesign\ShortURL\Models\ShortURL;
use Hashids\Hashids;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
Expand All @@ -15,7 +16,7 @@ class ShortURLFactory extends Factory

public function definition(): array
{
$urlKey = (new KeyGenerator())->generateRandom();
$urlKey = (new KeyGenerator(new Hashids()))->generateRandom();

return [
'destination_url' => $this->faker->url(),
Expand Down
23 changes: 19 additions & 4 deletions src/Providers/ShortURLProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
namespace AshAllenDesign\ShortURL\Providers;

use AshAllenDesign\ShortURL\Classes\Builder;
use AshAllenDesign\ShortURL\Classes\KeyGenerator;
use AshAllenDesign\ShortURL\Classes\Validation;
use AshAllenDesign\ShortURL\Exceptions\ValidationException;
use AshAllenDesign\ShortURL\Interfaces\UrlKeyGenerator;
use AshAllenDesign\ShortURL\Interfaces\UserAgentDriver;
use Hashids\Hashids;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;

class ShortURLProvider extends ServiceProvider
Expand All @@ -19,9 +23,22 @@ public function register(): void
{
$this->mergeConfigFrom(__DIR__.'/../../config/short-url.php', 'short-url');

$this->app->bind('short-url.builder', function () {
return new Builder();
$this->app->bind(UserAgentDriver::class, config('short-url.user_agent_driver'));
$this->app->bind(UrlKeyGenerator::class, config('short-url.url_key_generator'));

$this->app->bind('short-url.builder', function (Application $app): Builder {
return new Builder(
urlKeyGenerator: $app->make(UrlKeyGenerator::class),
);
});

$this->app->when(KeyGenerator::class)
->needs(Hashids::class)
->give(fn (): Hashids => new Hashids(
salt: config('short-url.key_salt'),
minHashLength: (int) config('short-url.key_length'),
alphabet: config('short-url.alphabet')
));
}

/**
Expand Down Expand Up @@ -49,7 +66,5 @@ public function boot(): void
if (config('short-url') && config('short-url.validate_config')) {
(new Validation())->validateConfig();
}

$this->app->bind(UserAgentDriver::class, config('short-url.user_agent_driver'));
}
}
Loading
Loading