Skip to content

Commit

Permalink
Merge pull request #284 from mkeremcansev/main
Browse files Browse the repository at this point in the history
Add Fallback Locale and Additional Query Support to `findBySlug`
  • Loading branch information
freekmurze authored Dec 9, 2024
2 parents ed4a927 + 613c876 commit 26bd614
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 5 deletions.
26 changes: 21 additions & 5 deletions src/HasSlug.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,31 @@ protected function generateSubstring($slugSourceString)
return substr($slugSourceString, 0, $this->slugOptions->maximumLength);
}

public static function findBySlug(string $slug, array $columns = ['*'])
public static function findBySlug(string $slug, array $columns = ['*'], callable $additionalQuery = null)
{
$modelInstance = new static();
$field = $modelInstance->getSlugOptions()->slugField;

$field = in_array(HasTranslatableSlug::class, class_uses_recursive(static::class))
? "{$field}->{$modelInstance->getLocale()}"
: $field;
$query = static::query();

return static::where($field, $slug)->first($columns);
if (in_array(HasTranslatableSlug::class, class_uses_recursive(static::class))) {
$currentLocale = $modelInstance->getLocale();
$fallbackLocale = config('app.fallback_locale');

$currentField = "{$field}->{$currentLocale}";
$fallbackField = "{$field}->{$fallbackLocale}";

$query->where($currentField, $slug);

$query->orWhere($fallbackField, $slug);
} else {
$query->where($field, $slug);
}

if (is_callable($additionalQuery)) {
$additionalQuery($query);
}

return $query->first($columns);
}
}
59 changes: 59 additions & 0 deletions tests/HasSlugTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use Spatie\Sluggable\SlugOptions;
use Spatie\Sluggable\Tests\TestSupport\TestModel;
use Spatie\Sluggable\Tests\TestSupport\TestModelSoftDeletes;
use Spatie\Sluggable\Tests\TestSupport\TranslatableModel;

it('will save a slug when saving a model', function () {
$model = TestModel::create(['name' => 'this is a test']);
Expand Down Expand Up @@ -349,3 +350,61 @@ public function getSlugOptions(): SlugOptions

expect($savedModel->id)->toEqual($model->id);
});

it('can customize query using additionalQuery parameter in findBySlug', function () {
$model = new class () extends TestModel {
public function getSlugOptions(): SlugOptions
{
return parent::getSlugOptions()->saveSlugsTo('url');
}
};

$model->url = 'custom-slug';
$model->other_field = 'active';
$model->save();

$savedModel = $model::findBySlug('custom-slug', ['*'], function ($query) {
$query->where('other_field', 'active');
});

expect($savedModel)
->not->toBeNull()
->and($savedModel->id)
->toEqual($model->id);

$noMatch = $model::findBySlug('custom-slug', ['*'], function ($query) {
$query->where('status', 'inactive');
});

expect($noMatch)->toBeNull();
});

it('can find models using findBySlug with fallback locale', function () {
config()->set('app.fallback_locale', 'en');
app()->setLocale('tr');

$model = new class () extends TranslatableModel {
public function getSlugOptions(): SlugOptions
{
return parent::getSlugOptions()->saveSlugsTo('slug');
}
};

$model->slug = ['en' => 'english-slug', 'tr' => 'turkish-slug'];
$model->name = ['en' => 'English Name', 'tr' => 'Turkish Name'];
$model->save();

$foundModelInCurrentLocale = $model::findBySlug('turkish-slug');

expect($foundModelInCurrentLocale)
->not->toBeNull()
->and($foundModelInCurrentLocale->id)
->toEqual($model->id);

$foundModelInFallbackLocale = $model::findBySlug('english-slug');

expect($foundModelInFallbackLocale)
->not->toBeNull()
->and($foundModelInFallbackLocale->id)
->toEqual($model->id);
});

0 comments on commit 26bd614

Please sign in to comment.