I'm using Silex and would like to apply uniqueness validator constraints on MongoDB documents.
The UniqueEntity
validator constraint to be found in symfony/doctrine-bridge
wasn't designed to work with doctrine/mongodb-odm
but solely with the ORM since the service defined in Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity
is doctrine.orm.validator.unique
.
With Symfony however, there is a Unique
constraint validator in the doctrine/mongodb-odm-bundle
that can be used for this purpose.
Do I have to port the code of the bundle? Any workaround?
I found a solution using Saxulum Doctrine MongoDb providers:
1 - Create the unique document constraint
# file: /src/MySilexApplication/Constraint/UniqueDocument.php
namespace MySilexApplication\Constraint;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* Constraint for the unique document validator
*
* @Annotation
*/
class UniqueDocument extends UniqueEntity
{
public $service = 'doctrine_odm.mongodb.unique';
}
2 - Register the constraint in the Doctrine annotation registry
# file: /app/bootstrap.php
\Doctrine\Common\Annotations\AnnotationRegistry::registerFile(
'/src/MySilexApplication/Constraint/UniqueDocument.php'
);
3 - Use and register Saxulum providers (see documentation on Github for params declaration)
# file: /app/bootstrap.php
use Saxulum\DoctrineMongoDb\Silex\Provider\DoctrineMongoDbProvider;
use Saxulum\DoctrineMongoDbOdm\Silex\Provider\DoctrineMongoDbOdmProvider;
use Saxulum\DoctrineMongodbOdmManagerRegistry\Silex\Provider\DoctrineMongodbOdmManagerRegistryProvider;
$app->register(new DoctrineMongoDbProvider(), $params['mongodb']));
$app->register(new DoctrineMongoDbOdmProvider(), $params['mongodb_odm']);
$app->register(new DoctrineMongodbOdmManagerRegistryProvider());
4 - Reference the constraint validator into the Silex validator service provider and declare it as a Silex service
# file: /app/bootstrap.php
use Silex\Provider\ValidatorServiceProvider;
$app->register(new ValidatorServiceProvider(), array(
'validator.validator_service_ids' => array(
'doctrine_odm.mongodb.unique' => 'doctrine_odm.mongodb.unique',
)
));
$app['doctrine_odm.mongodb.unique'] = $app->share(function (Application $app) {
return new Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator($app['doctrine']);
});
5 - At last, use it into your document class
# file: /src/MySilexApplication/Document/Bar.php
namespace MySilexApplication\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use MySilexApplication\Constraint\UniqueDocument as UniqueDocument;
/**
* @MongoDB\Document(collection="Foo")
*
* @UniqueDocument(fields={"baz"})
*/
class Bar
{
/**
* @var string
*
* @MongoDB\String
*/
protected $baz;
...
}
If someone knows a better way ...