Skip to content

Commit 2b970e0

Browse files
committed
WIP
1 parent 29a2ddf commit 2b970e0

File tree

7 files changed

+139
-58
lines changed

7 files changed

+139
-58
lines changed

README.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,29 @@ php artisan vendor:publish --tag="laravel-slug-auto-generator-views"
5151

5252
## Usage
5353

54+
1. **Integrate the Trait**: Simply integrate the `SlugGenerator` trait into your Eloquent model to unlock its powerful slug generation capabilities.
55+
56+
2. **Configuration**: Customize the slug generation behavior by modifying the `sluggenerator.php` configuration file located in your `config` directory.
57+
58+
3. **Effortless Integration**: With the trait seamlessly integrated into your model, enjoy automatic and unique slug generation without any additional setup.
59+
60+
## Example
61+
5462
```php
55-
$slugGenerator = new CodingWisely\SlugGenerator();
56-
echo $slugGenerator->echoPhrase('Hello, CodingWisely!');
57-
```
63+
use CodingWisely\SlugGenerator\SlugGenerator;
64+
use Illuminate\Database\Eloquent\Model;
65+
66+
class YourModel extends Model
67+
{
68+
use SlugGenerator;
5869

70+
// Your model's attributes and methods...
71+
}
72+
```
5973
## Testing
6074

6175
```bash
62-
composer test
76+
composer test
6377
```
6478

6579
## Changelog

config/slug-auto-generator.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
// config for CodingWisely/SlugGenerator
4+
// replace it with your model column
45
return [
5-
6+
'sluggable_field' => 'name',
67
];

database/factories/ModelFactory.php

Lines changed: 0 additions & 19 deletions
This file was deleted.

database/migrations/create_slug_auto_generator_table.php.stub

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/SlugGenerator.php

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,64 @@
22

33
namespace CodingWisely\SlugGenerator;
44

5-
class SlugGenerator
5+
use Illuminate\Support\Str;
6+
7+
trait SlugGenerator
68
{
9+
public static function bootSlugGenerator(): void
10+
{
11+
static::saving(function ($model) {
12+
$field = self::getSluggableField();
13+
$slug = $model->slug ? $model->slug : Str::slug($model->{$field});
14+
$model->slug = $model->generateUniqueSlug($slug);
15+
});
16+
}
17+
18+
public static function getSluggableField(): string
19+
{
20+
return config('sluggenerator.sluggable_field');
21+
}
22+
23+
public function generateUniqueSlug(string $slug): string
24+
{
25+
// Check if the slug already has a number at the end
26+
$originalSlug = $slug;
27+
$slugNumber = 0;
28+
29+
if (preg_match('/-(\d+)$/', $slug, $matches)) {
30+
$slugNumber = $matches[1];
31+
$slug = Str::replaceLast("-$slugNumber", '', $slug);
32+
}
33+
34+
$existingSlugs = $this->getExistingSlugs($slug, $this->getTable());
35+
36+
if (!in_array($slug, $existingSlugs)) {
37+
return $slug . ($slugNumber ? "-$slugNumber" : '');
38+
}
39+
40+
$i = $slugNumber ? ($slugNumber + 1) : 1;
41+
$uniqueSlugFound = false;
42+
43+
// Antoni will like this one :D
44+
while (!$uniqueSlugFound) {
45+
$newSlug = $slug . '-' . $i;
46+
47+
if (!in_array($newSlug, $existingSlugs)) {
48+
// Unique slug found
49+
return $newSlug;
50+
}
51+
52+
$i++;
53+
}
54+
55+
return $originalSlug . '-' . mt_rand(1000, 9999);
56+
}
57+
58+
private function getExistingSlugs(string $slug, string $table): array
59+
{
60+
return $this->where('slug', 'LIKE', $slug . '%')
61+
->where('id', '!=', $this->id ?? null)
62+
->pluck('slug')
63+
->toArray();
64+
}
765
}

tests/SlugGeneratorTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace CodingWisely\SlugGenerator\Tests;
4+
5+
use CodingWisely\SlugGenerator\SlugGenerator;
6+
use Illuminate\Support\Facades\Schema;
7+
use Illuminate\Database\Schema\Blueprint;
8+
use Illuminate\Support\Str;
9+
use Orchestra\Testbench\TestCase;
10+
11+
// Assumes SlugGenerator is a trait and not a Laravel Facade
12+
13+
14+
class SlugGeneratorTest extends TestCase
15+
{
16+
/** @test */
17+
public function it_generates_a_unique_slug()
18+
{
19+
$title = 'Existing Title';
20+
21+
// Create the first entry in test_models with the slug
22+
$model1 = TestModel::create(['title' => $title, 'slug' => Str::slug($title)]);
23+
$this->assertEquals('existing-title', $model1->slug);
24+
25+
// Create another model with the same title
26+
$model2 = TestModel::create(['title' => $title, 'slug' => Str::slug($title)]);
27+
$this->assertEquals('existing-title-1', $model2->slug);
28+
// Ensure that the two models have different slugs
29+
$this->assertNotEquals($model1->slug, $model2->slug);
30+
}
31+
32+
protected function getEnvironmentSetUp($app)
33+
{
34+
$app['config']->set('database.default', 'sqlite');
35+
$app['config']->set('database.connections.sqlite', [
36+
'driver' => 'sqlite',
37+
'database' => ':memory:',
38+
'prefix' => '',
39+
]);
40+
41+
// Database setup
42+
Schema::create('test_models', function (Blueprint $table) {
43+
$table->increments('id');
44+
$table->string('title');
45+
$table->string('slug');
46+
});
47+
}
48+
}
49+
class TestModel extends \Illuminate\Database\Eloquent\Model {
50+
use SlugGenerator;
51+
52+
protected $table = 'test_models';
53+
protected $guarded = [];
54+
public $timestamps = false;
55+
56+
public static function getSluggableField()
57+
{
58+
return 'title';
59+
}
60+
}

tests/TestCase.php

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ class TestCase extends Orchestra
1111
protected function setUp(): void
1212
{
1313
parent::setUp();
14-
15-
Factory::guessFactoryNamesUsing(
16-
fn (string $modelName) => 'CodingWisely\\SlugGenerator\\Database\\Factories\\'.class_basename($modelName).'Factory'
17-
);
1814
}
1915

2016
protected function getPackageProviders($app)
@@ -23,14 +19,4 @@ protected function getPackageProviders($app)
2319
SlugGeneratorServiceProvider::class,
2420
];
2521
}
26-
27-
public function getEnvironmentSetUp($app)
28-
{
29-
config()->set('database.default', 'testing');
30-
31-
/*
32-
$migration = include __DIR__.'/../database/migrations/create_laravel-slug-auto-generator_table.php.stub';
33-
$migration->up();
34-
*/
35-
}
3622
}

0 commit comments

Comments
 (0)