cndrsdrmn / eloquent-unique-attributes
A Laravel package to enforce automatic generation of unique attribute values for Eloquent models.
Requires
- php: ^8.3
- cndrsdrmn/php-string-formatter: ^0.2
Requires (Dev)
- larastan/larastan: ^2.9
- laravel/pint: ^1.18
- orchestra/testbench: ^9.6
- pestphp/pest: ^3.5
- pestphp/pest-plugin-type-coverage: ^3.2
- rector/rector: ^1.2
This package is auto-updated.
Last update: 2025-01-28 14:06:41 UTC
README
A Laravel package to enforce automatic generation of unique attribute values for Eloquent models, making it easy to maintain uniqueness without manual intervention.
๐ Features
- Automatically generate unique attribute values for Eloquent models.
- Customizable formats (
numerify
,lexify
, or mixed patterns). - Flexible configuration for prefixes, suffixes, separators, and retries.
- Supports models with soft deletes.
- Fully customizable events for enforcing and notifying unique attribute changes.
๐ Background
Managing unique attributes in Eloquent models often involves tedious logic, especially when combining custom formats and real-time checks. This package provides an automatic, extensible solution. It ensures attributes are unique within the database and adhere to defined configurations.
๐ Installation
Install the package using Composer:
composer require cndrsdrmn/eloquent-unique-attributes
โ๏ธ Configuration
To customize the default behavior, publish the configuration file:
php artisan vendor:publish --tag=unique-attributes-config
This will create a config/unique_attributes.php
file:
return [ /** * The prefix to add to the beginning of the generated unique value. */ 'prefix' => '', /** * The suffix to add to the end of the generated unique value. */ 'suffix' => '', /** * The separator to use between prefix, value, and suffix. */ 'separator' => '_', /** * The maximum number of retries to generate a unique value before increasing the length. */ 'max_retries' => 100, /** * The default length of the generated unique value. */ 'length' => 8, /** * The format of the unique value. * * Supported options: * - `numerify` - Replace `#` with random digits. * - `lexify` - Replace `?` with random letters. * - `bothify` - Replace `#` with digits and `?` with letters. * * @see https://github.com/cndrsdrmn/php-string-formatter */ 'format' => 'bothify', ];
Configurable Options:
prefix
: A string prepended to the generated value.suffix
: A string appended to the generated value.separator
: A separator betweenprefix
,value
, andsuffix
.max_retries
: Maximum attempts to generate a unique value before increasing length.length
: The initial length of the generated unique value.format
: Determines the type of value (numerify
for digits,lexify
for letters,botify
for mixed).
๐ Usage
1. Add the Trait to Your Model
Include the HasEnforcesUniqueAttributes
trait in any Eloquent model requiring unique attributes:
namespace App\Models; use Cndrsdrmn\EloquentUniqueAttributes\HasEnforcesUniqueAttributes; use Illuminate\Database\Eloquent\Model; class Product extends Model { use HasEnforcesUniqueAttributes; /** * Define the unique attributes configuration. */ public function enforcedUniqueColumns(): array { return [ 'barcode' => ['format' => 'numerify', 'separator' => '-'], 'sku' => ['prefix' => 'SKU', 'length' => 10], ]; } }
2. Generate Unique Attributes
When creating the model, the unique values will automatically be enforced:
$product = Product::create([ 'name' => 'Sample Product', ]); echo $product->sku; // Example: SKU_1234567890
๐ง Advanced Customization
Event Hooks
This package fires events during the unique value generation process:
eloquent.enforcing
: Fired before generating unique attributes. If a listener returns a value, the process of enforcing unique attributes is skipped.eloquent.enforced
: After unique attributes are generated.
You can listen to these events in your application to implement custom logic:
use Illuminate\Support\Facades\Event; Event::listen('eloquent.enforcing: App\Models\Product', function ($model, $event) { // Returning any value here will skip the enforcement of unique attributes. return true; }); Event::listen('eloquent.enforced: App\Models\Product', function ($model, $status) { // Execute logic after unique attributes are enforced. if ($status) { Log::info('Unique attributes enforced for model', ['model' => $model]); } });
Note: If a listener for the
eloquent.enforcing
event returns a value (truthy or falsy), the unique attribute generation process will be skipped for the current model.
๐งช Testing
This package includes PHPUnit tests. To run the tests, use the following command:
composer test
๐ค Contributing
We welcome contributions! Follow these steps to contribute:
- Fork the repository.
- Create a new branch (
git checkout -b feature-name
). - Commit your changes (
git commit -m "Add new feature"
). - Push to the branch (
git push origin feature-name
). - Open a Pull Request.
๐ License
This package is open-source software licensed under the MIT license.