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.
- 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
- PHP 8.2 or higher
- Symfony Validator Component 7.3+
- Symfony PropertyAccess Component 7.3+
Install the constraint via Composer:
composer require gryfoss/symfony-unique-in-collection-constraintYou 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...
}<?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!
];<?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!
];<?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."
}
}This project includes both unit tests and functional tests to ensure reliability:
# Run the complete test suite (unit + functional)
./scripts/run-all-tests.sh# Basic unit tests
./vendor/bin/phpunit
# Unit tests with coverage report
./vendor/bin/phpunit --coverage-html coverage/# Ensures 100% test coverage
./scripts/check-coverage.shcd tests/functional
composer install
./vendor/bin/behat- 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
We welcome contributions to improve this constraint! Here's how you can help:
- π 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
- 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
- Maintain 100% test coverage
- Follow PSR-12 coding standards
- Add comprehensive documentation for new features
- Ensure backward compatibility when possible
- Write clear commit messages
This project is licensed under the MIT License - see the LICENSE file for details.
IDCT Bartosz PachoΕek
- Email: bartosz+github@idct.tech
- GitHub: @GryfOSS
Made with β€οΈ for the Symfony community