Reputation: 47057
I'm trying to match a GitHub-style URL (/{user}/{project}
) using Symfony2 @ParamConverter
s. They retrieve the correct entities, however I would like to ensure that the project belongs to the user in the URL. There is a Doctrine relation between the two entities.
For example, with a Project 'bar', belonging to 'foo', I can access it at /foo/bar
. However I can also access it under a different user: /baz/bar
.
Is it possible to do this using the ParamConverter, or do I need to manually check in the action?
/**
* @Route("/{user}")
* @ParamConverter("user", class="AcmeUserBundle:User", options={"mapping": {"user": "usernameCanonical"}})
*/
class ProjectController extends Controller
{
/**
* @Route("/{project}")
* @ParamConverter("project", class="AcmeProjectBundle:Project", options={"mapping": {"project": "slug"}})
* @Template()
*/
public function showAction(User $user, Project $project)
{
// Can I automate this check?
if ($user->getId() !== $project->getOwner()->getId()) {
throw $this->createNotFoundException();
}
}
}
Upvotes: 1
Views: 519
Reputation: 47057
Found the solution to this, largely thanks to @Qoop's comment. By adding "user": "owner"
to the mapping, the owner relation is queried using the $user
variable (which because of the first @ParamConverter
, is already a User instance.
Under-the-hood, this issues two queries - one to retrieve the first user and the second to retrieve the project (with project.owner_id = user.id and project.slug = slug). However I assume these are cacheable at the Doctrine-level.
The result of accessing the (non-existant) /baz/bar is a 404 with the message:
AcmeProjectBundle:Project object not found.
/**
* @Route("/{user}")
* @ParamConverter("user", class="AcmeUserBundle:User", options={"mapping": {"user": "usernameCanonical"}})
*/
class ProjectController extends Controller
{
/**
* @Route("/{project}")
* @ParamConverter("project", class="AcmeProjectBundle:Project", options={"mapping": {"user": "owner", "project": "slug"}})
* @Template()
*/
public function showAction(User $user, Project $project)
{
// Do something with $user and $project,
// where $project->getOwner() === $user
}
}
Upvotes: 3