Skip to content

Check if a translated value in a JSON column is unique in the database.

License

Notifications You must be signed in to change notification settings

cugrif/laravel-unique-translation

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

34 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Laravel Unique Translation

GitHub release License Build Status Code Coverage Scrutinizer Code Quality Total Downloads

ko-fi

Check if a translated value in a JSON column is unique in the database.

Imagine you want store a slug for a Post model in different languages.

The amazing spatie/laravel-translatable package makes this a cinch!

But then you want to make sure each translation is unique for its language.

That's where this package comes in to play.

โœ… Requirements

๐Ÿ“ฆ Installation

Require the package via Composer:

composer require codezero/laravel-unique-translation

Laravel will automatically register the ServiceProvider.

๐Ÿ›  Usage

For the following examples, I will use a slug in a posts table as the subject of our validation.

โ˜‘๏ธ Validate a Single Translation

Your form can submit a single slug:

<input name="slug">

We can then check if it is unique in the current locale:

$attributes = request()->validate([
    'slug' => 'required|unique_translation:posts',
]);

You could also use the Rule instance:

use CodeZero\UniqueTranslation\UniqueTranslationRule;

$attributes = request()->validate([
    'slug' => ['required', UniqueTranslationRule::for('posts')],
]);

โ˜‘๏ธ Validate an Array of Translations

Your form can also submit an array of slugs.

<input name="slug[en]">
<input name="slug[nl]">

We need to validate the entire array in this case. Mind the slug.* key.

$attributes = request()->validate([
    'slug.*' => 'unique_translation:posts',
    // or...
    'slug.*' => UniqueTranslationRule::for('posts'),
]);

โ˜‘๏ธ Specify a Column

Maybe your form field has a name of post_slug and your database field slug:

$attributes = request()->validate([
    'post_slug.*' => 'unique_translation:posts,slug',
    // or...
    'post_slug.*' => UniqueTranslationRule::for('posts', 'slug'),
]);

โ˜‘๏ธ Specify a Database Connection

If you are using multiple database connections, you can specify which one to use by prepending it to the table name, separated by a dot:

$attributes = request()->validate([
    'slug.*' => 'unique_translation:db_connection.posts',
    // or...
    'slug.*' => UniqueTranslationRule::for('db_connection.posts'),
]);

โ˜‘๏ธ Ignore a Record with ID

If you're updating a record, you may want to ignore the post itself from the unique check.

$attributes = request()->validate([
    'slug.*' => "unique_translation:posts,slug,{$post->id}",
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->ignore($post->id),
]);

โ˜‘๏ธ Ignore Records with a Specific Column and Value

If your ID column has a different name, or you just want to use another column:

$attributes = request()->validate([
    'slug.*' => 'unique_translation:posts,slug,ignore_value,ignore_column',
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->ignore('ignore_value', 'ignore_column'),
]);

โ˜‘๏ธ Use Additional Where Clauses

You can add 4 types of where clauses to the rule.

where

$attributes = request()->validate([
    'slug.*' => "unique_translation:posts,slug,null,null,column,value",
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->where('column', 'value'),
]);

whereNot

$attributes = request()->validate([
    'slug.*' => "unique_translation:posts,slug,null,null,column,!value",
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->whereNot('column', 'value'),
]);

whereNull

$attributes = request()->validate([
    'slug.*' => "unique_translation:posts,slug,null,null,column,NULL",
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->whereNull('column'),
]);

whereNotNull

$attributes = request()->validate([
    'slug.*' => "unique_translation:posts,slug,null,null,column,NOT_NULL",
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->whereNotNull('column'),
]);

๐Ÿ–ฅ Example

Your existing slug column (JSON) in a posts table:

{
  "en":"not-abc",
  "nl":"abc"
}

Your form input to create a new record:

<input name="slug[en]" value="abc">
<input name="slug[nl]" value="abc">

Your validation logic:

$attributes = request()->validate([
    'slug.*' => 'unique_translation:posts',
]);

The result is that slug[en] is valid, since the only en value in the database is not-abc.

And slug[nl] would fail, because there already is a nl value of abc.

โš ๏ธ Error Messages

Whether you are validating a single translation ('slug') or an array of translations ('slug.*'), if validation fails, you will find an error for both the single and the localized key:

$errors->first('slug');
$errors->first('slug.en');

You can pass your own error message with any of the following keys. The first one found will be used.

$attributes = request()->validate([
    'slug.*' => 'unique_translation:posts',
], [
    'slug.unique_translation' => 'Your custom :attribute error.',
    'slug.*.unique_translation' => 'Your custom :attribute error.',
    'slug.en.unique_translation' => 'Your custom :attribute error.',
]);

๐Ÿšง Testing

vendor/bin/phpunit

โ˜•๏ธ Credits

๐Ÿ”“ Security

If you discover any security related issues, please e-mail me instead of using the issue tracker.

๐Ÿ“‘ Changelog

See a list of important changes in the changelog.

๐Ÿ“œ License

The MIT License (MIT). Please see License File for more information.

About

Check if a translated value in a JSON column is unique in the database.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%