gryfoss / symfony-unique-in-collection-constraint
Allows validation of objects inside a collection by a provided field.
Installs: 3
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/gryfoss/symfony-unique-in-collection-constraint
Requires
- symfony/property-access: ^7.3
- symfony/validator: ^7.3
Requires (Dev)
- phpunit/phpunit: ^12.4
README
A Symfony validation constraint that ensures uniqueness of specific fields within a collection. This constraint validates that the specified field(s) have unique values across all items in a collection, making it perfect for preventing duplicate entries based on certain properties.
π Features
- Field Uniqueness: Validate uniqueness of single or multiple fields within collections
- Composite Uniqueness: Support for checking uniqueness across multiple field combinations
- Symfony Integration: Native Symfony Validator component integration
- PHP 8+ Attributes: Modern attribute-based constraint definition
- 100% Test Coverage: Comprehensive unit and functional test suite
π Requirements
- PHP 8.2 or higher
- Symfony Validator Component 7.3+
- Symfony PropertyAccess Component 7.3+
π¦ Installation
Install the constraint via Composer:
composer require gryfoss/symfony-unique-in-collection-constraint
π οΈ Usage
Basic Usage with PHP Attributes
You can use the constraint directly on collection properties in your entities:
<?php use GryfOSS\SymfonyUniqueInCollectionConstraint\UniqueInCollection; class Team { #[UniqueInCollection('email')] private array $members = []; // Constructor, getters, setters... }
Advanced Usage Examples
Single Field Uniqueness
<?php use GryfOSS\SymfonyUniqueInCollectionConstraint\UniqueInCollection; class Company { #[UniqueInCollection('email')] private array $employees = []; } // Usage $employees = [ ['name' => 'John Doe', 'email' => 'john@company.com'], ['name' => 'Jane Smith', 'email' => 'jane@company.com'], ['name' => 'Bob Wilson', 'email' => 'john@company.com'], // β Duplicate email! ];
Multiple Field Uniqueness (Composite)
<?php use GryfOSS\SymfonyUniqueInCollectionConstraint\UniqueInCollection; class ProductCatalog { #[UniqueInCollection(['category', 'sku'])] private array $products = []; } // Usage $products = [ ['name' => 'Laptop', 'category' => 'electronics', 'sku' => 'LAP001'], ['name' => 'Phone', 'category' => 'electronics', 'sku' => 'PHN001'], ['name' => 'Tablet', 'category' => 'electronics', 'sku' => 'LAP001'], // β Same category+sku! ];
Manual Validation
<?php use GryfOSS\SymfonyUniqueInCollectionConstraint\UniqueInCollection; use Symfony\Component\Validator\Validation; $validator = Validation::createValidator(); $data = [ ['id' => 1, 'code' => 'ABC123'], ['id' => 2, 'code' => 'DEF456'], ['id' => 3, 'code' => 'ABC123'], // Duplicate code ]; $constraint = new UniqueInCollection('code'); $violations = $validator->validate($data, $constraint); if (count($violations) > 0) { foreach ($violations as $violation) { echo $violation->getMessage(); // "Must be unique within collection." } }
π§ͺ Running Tests
This project includes both unit tests and functional tests to ensure reliability:
Run All Tests
# Run the complete test suite (unit + functional)
./scripts/run-all-tests.sh
Run Unit Tests Only
# Basic unit tests ./vendor/bin/phpunit # Unit tests with coverage report ./vendor/bin/phpunit --coverage-html coverage/
Run Unit Tests with Coverage Check
# Ensures 100% test coverage
./scripts/check-coverage.sh
Run Functional Tests (Behat)
cd tests/functional
composer install
./vendor/bin/behat
Test Structure
- Unit Tests (
tests/unit/): Test individual components and constraint logic - Functional Tests (
tests/functional/): End-to-end Behat scenarios testing real-world usage - Coverage: Maintained at 100% to ensure reliability
π€ Contributing
We welcome contributions to improve this constraint! Here's how you can help:
Reporting Issues
- π Bug Reports: Create an issue with detailed reproduction steps
- π‘ Feature Requests: Submit an enhancement request with your use case
- π Documentation: Help improve documentation and examples
Pull Requests
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Write tests for your changes
- Ensure all tests pass:
./scripts/run-all-tests.sh - Commit your changes:
git commit -m 'Add amazing feature' - Push to your branch:
git push origin feature/amazing-feature - Submit a pull request
Development Guidelines
- Maintain 100% test coverage
- Follow PSR-12 coding standards
- Add comprehensive documentation for new features
- Ensure backward compatibility when possible
- Write clear commit messages
π License
This project is licensed under the MIT License - see the LICENSE file for details.
π¨βπ» Author
IDCT Bartosz PachoΕek
- Email: bartosz+github@idct.tech
- GitHub: @GryfOSS
Made with β€οΈ for the Symfony community