@ -35,14 +35,19 @@ class DoctrineParamConverter implements ParamConverterInterface
public function apply(Request $request, ConfigurationInterface $configuration)
{
$class = $configuration->getClass();
$name = $configuration->getName();
$class = $configuration->getClass();
$options = $this->getOptions($configuration);
// find by identifier?
if (false === $object = $this->find($class, $request, $options)) {
if (false === $object = $this->find($class, $request, $options, $name )) {
// find by criteria
if (false === $object = $this->findOneBy($class, $request, $options)) {
throw new \LogicException('Unable to guess how to get a Doctrine instance from the request information.');
if ($configuration->isOptional()) {
$object = null;
} else {
throw new \LogicException('Unable to guess how to get a Doctrine instance from the request information.');
}
}
}
@ -50,28 +55,72 @@ class DoctrineParamConverter implements ParamConverterInterface
throw new NotFoundHttpException(sprintf('%s object not found.', $class));
}
$request->attributes->set($co nfiguration->getN ame() , $object);
$request->attributes->set($name, $object);
return true;
}
protected function find($class, Request $request, $options)
protected function find($class, Request $request, $options, $name )
{
$key = isset($options['id']) ? $options['id'] : 'id';
if (!$request->attributes->has($key)) {
if ($options['mapping'] || $options['exclude']) {
return false;
}
return $this->registry->getRepository($class, $options['entity_manager'])->find($request->attributes->get($key));
$id = $this->getIdentifier($request, $options, $name);
if (!$id) {
return false;
}
return $this->registry->getRepository($class, $options['entity_manager'])->find($id);
}
protected function getIdentifier(Request $request, $options, $name)
{
if (isset($options['id'])) {
if (!is_array($options['id'])) {
$name = $options['id'];
} elseif (is_array($options['id'])) {
$id = array();
foreach ($options['id'] as $field) {
$id[$field] = $request->attributes->get($field);
}
return $id;
}
}
if ($request->attributes->has($name)) {
return $request->attributes->get($name);
}
if ($request->attributes->has('id')) {
return $request->attributes->get('id');
}
return false;
}
protected function findOneBy($class, Request $request, $options)
{
if (!$options['mapping']) {
$keys = $request->attributes->keys();
$options['mapping'] = $keys ? array_combine($keys, $keys) : array();
}
foreach ($options['exclude'] as $exclude) {
unset($options['mapping'][$exclude]);
}
if (!$options['mapping']) {
return false;
}
$criteria = array();
$metadata = $this->registry->getManager($options['entity_manager'])->getClassMetadata($class);
foreach ($request->attributes->all() as $key => $value) {
if ($metadata->hasField($key)) {
$criteria[$key] = $value;
foreach ($options['mapping'] as $attribute => $field) {
if ($metadata->hasField($field) || ($metadata->hasAssociation($field) & & $metadata->isSingleValuedAssociation($field))) {
$criteria[$field] = $request->attributes->get($attribute);
}
}
@ -84,7 +133,8 @@ class DoctrineParamConverter implements ParamConverterInterface
public function supports(ConfigurationInterface $configuration)
{
if (null === $this->registry) {
// if there is no manager, this means that only Doctrine DBAL is configured
if (null === $this->registry || !count($this->registry->getManagers())) {
return false;
}
@ -104,6 +154,8 @@ class DoctrineParamConverter implements ParamConverterInterface
{
return array_replace(array(
'entity_manager' => null,
'exclude' => array(),
'mapping' => array(),
), $configuration->getOptions());
}
}