Skip to content

Commit b0db100

Browse files
committed
Merge branch 'dev'
2 parents 8af889f + 5df5365 commit b0db100

File tree

6 files changed

+53
-38
lines changed

6 files changed

+53
-38
lines changed

.github/workflows/dependabot-auto-merge.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414

1515
- name: Dependabot metadata
1616
id: metadata
17-
uses: dependabot/fetch-metadata@v1.6.0
17+
uses: dependabot/fetch-metadata@v2.0.0
1818
with:
1919
github-token: "${{ secrets.GITHUB_TOKEN }}"
2020

.github/workflows/fix-php-code-style-issues.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
ref: ${{ github.head_ref }}
2323

2424
- name: Fix PHP code style issues
25-
uses: aglipanci/laravel-pint-action@2.3.1
25+
uses: aglipanci/laravel-pint-action@2.4
2626

2727
- name: Commit changes
2828
uses: stefanzweifel/git-auto-commit-action@v5

.github/workflows/phpstan.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
coverage: none
2323

2424
- name: Install composer dependencies
25-
uses: ramsey/composer-install@v2
25+
uses: ramsey/composer-install@v3
2626

2727
- name: Run PHPStan
2828
run: ./vendor/bin/phpstan --error-format=github

config/slug-auto-generator.php

+1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
// replace it with your model column
55
return [
66
'sluggable_field' => 'name',
7+
'groupable_field' => null,
78
];

src/SlugGenerator.php

+19-29
Original file line numberDiff line numberDiff line change
@@ -26,45 +26,35 @@ protected static function getSluggableField(): string
2626
return config('sluggenerator.sluggable_field') ?? 'name';
2727
}
2828

29+
protected static function getGroupableField(): ?string
30+
{
31+
return config('sluggenerator.groupable_field') ?? null;
32+
}
33+
2934
public function generateUniqueSlug(string $slug): string
3035
{
31-
// Check if the slug already has a number at the end
3236
$originalSlug = $slug;
33-
$slugNumber = 0;
37+
$slugNumberSuffix = '';
3438

35-
if (preg_match('/-(\d+)$/', $slug, $matches)) {
36-
$slugNumber = $matches[1];
37-
$slug = Str::replaceLast("-$slugNumber", '', $slug);
38-
}
39-
40-
$existingSlugs = $this->getExistingSlugs($slug, $this->getTable());
39+
$existingSlugs = $this->getExistingSlugs($slug, $this->getTable(), $this->getGroupableField());
4140

42-
if (! in_array($slug, $existingSlugs)) {
43-
return $slug.($slugNumber ? "-$slugNumber" : '');
41+
while (in_array($slug . $slugNumberSuffix, $existingSlugs)) {
42+
$slugNumberSuffix = $slugNumberSuffix !== '' ? $slugNumberSuffix + 1 : 1;
4443
}
4544

46-
$i = $slugNumber ? ($slugNumber + 1) : 1;
47-
$uniqueSlugFound = false;
48-
49-
while (! $uniqueSlugFound) {
50-
$newSlug = $slug.'-'.$i;
45+
return $slug . ($slugNumberSuffix !== '' ? '-' . $slugNumberSuffix : '');
46+
}
5147

52-
if (! in_array($newSlug, $existingSlugs)) {
53-
// Unique slug found
54-
return $newSlug;
55-
}
48+
private function getExistingSlugs(string $slug, string $table, ?string $groupable): array
49+
{
50+
$query = $this->where('slug', 'LIKE', $slug.'%')
51+
->where('id', '!=', $this->id ?? null);
5652

57-
$i++;
53+
// If a groupable field is present and is not null in this model, handle grouping.
54+
if (!is_null($groupable) && !is_null($this->{$groupable})) {
55+
$query->where($groupable, $this->{$groupable});
5856
}
5957

60-
return $originalSlug.'-'.mt_rand(1000, 9999);
61-
}
62-
63-
private function getExistingSlugs(string $slug, string $table): array
64-
{
65-
return $this->where('slug', 'LIKE', $slug.'%')
66-
->where('id', '!=', $this->id ?? null)
67-
->pluck('slug')
68-
->toArray();
58+
return $query->pluck('slug')->toArray();
6959
}
7060
}

tests/SlugGeneratorTest.php

+30-6
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,46 @@ public function it_generates_a_unique_slug()
1818
$title = 'Existing Title';
1919

2020
// Create the first entry in test_models with the slug
21-
$model1 = TestModel::create(['title' => $title, 'slug' => Str::slug($title)]);
21+
$model1 = TestModel::create(['title' => $title]);
2222
$this->assertEquals('existing-title', $model1->slug);
2323

24-
// Create another model with the same title
25-
$model2 = TestModel::create(['title' => $title, 'slug' => Str::slug($title)]);
24+
// Create another model with the same title;
25+
// let the SlugGenerator trait handle the slug creation
26+
$model2 = TestModel::create(['title' => $title]);
2627
$this->assertEquals('existing-title-1', $model2->slug);
2728
// Ensure that the two models have different slugs
2829
$this->assertNotEquals($model1->slug, $model2->slug);
29-
}
3030

31+
$model3 = TestModel::create(['title' => 'Groupable Title', 'groupable_field' => 1]);
32+
$this->assertEquals('groupable-title', $model3->slug);
33+
34+
// Create another model with the same title and groupable_field;
35+
// let the SlugGenerator trait handle the slug creation
36+
$model4 = TestModel::create(['title' => $title, 'groupable_field' => 1]);
37+
$this->assertEquals('existing-title', $model4->slug);
38+
39+
$model5 = TestModel::create(['title' => $title]);
40+
$this->assertEquals('existing-title-1', $model5->slug);
41+
42+
43+
$model6 = TestModel::create(['title' => 'Groupable Title', 'groupable_field' => 1]);
44+
$this->assertEquals('groupable-title-1', $model6->slug);
45+
}
3146
protected function getEnvironmentSetUp($app)
3247
{
3348
$app['config']->set('database.default', 'sqlite');
3449
$app['config']->set('database.connections.sqlite', [
3550
'driver' => 'sqlite',
3651
'database' => ':memory:',
37-
'prefix' => '',
52+
'prefix' => 'cw-slug-generator-test-',
3853
]);
3954

4055
// Database setup
4156
Schema::create('test_models', function (Blueprint $table) {
4257
$table->increments('id');
4358
$table->string('title');
4459
$table->string('slug');
60+
$table->string('groupable_field')->nullable();
4561
});
4662
}
4763
}
@@ -51,12 +67,20 @@ class TestModel extends \Illuminate\Database\Eloquent\Model
5167

5268
protected $table = 'test_models';
5369

54-
protected $guarded = [];
70+
protected $fillable = [
71+
'title',
72+
'slug',
73+
'groupable_field',
74+
];
5575

5676
public $timestamps = false;
5777

5878
public static function getSluggableField()
5979
{
6080
return 'title';
6181
}
82+
public static function getGroupableField()
83+
{
84+
return 'groupable_field';
85+
}
6286
}

0 commit comments

Comments
 (0)