I am using request object in twig extension class to get the current route. For instance, having the following url:
http://www.localhost/project/user/page/2
Inside of the twig extension I'm able to get user/page/2 string and do something with it.
The problem arises when I wanna get the default route using the same method, which I have to do. For example, accessing the following url:
http://www.localhost/project/user
I want to get user/page/1 string inside the twig extension class, and not just user.
The controller looks like this:
/**
* #Route(name="user",
* default="user/page/1")
*/
Is there a way to achieve that? Or do I have to stop using default routes?
Write a comment if you need more explanation, it's 9AM here in Poland and I'm sleeping yet.
The #Route documentation explains that you can do this for set a default page number:
/**
* #Route("/project/user/page/{page}",
* name="user",
* defaults={"page" = 1},
* requirements={"page" = "\d+"}
* )
*/
Related
I am using the #Security annotation to control which roles have access to certain routes in my Symfony 3.4 application, it works when I am logged in however when the user object doesn't exist such as when the session times out I get the following exception thrown.
Unable to get a property on a non-object.
vendor/symfony/symfony/src/Symfony/Component/ExpressionLanguage/ExpressionLanguage.php:78
at
Symfony\Component\ExpressionLanguage\ExpressionLanguage->evaluate('\'ROLE_MANAGER\'
in user.getRoles()',
My method definition looks like this:
/**
* #Route("/club/{id}/trophies", name="club_trophies", methods={"GET","POST"})
* #IsGranted("IS_AUTHENTICATED_FULLY")
* #Security("'ROLE_MANAGER' in user.getRoles()")
* #param Club $club
* #return Response
*/
public function trophies(Club $club): Response
{
Is there a way using the Symfony Expression Language, or similar, that I can check that user exists. Or is there a better way?
When you are not authenticated, the value of user is null, so it's normal that your check is throwing an exception (as you're trying to access the method getRoles() of a null object).
The proper ways to check if a user has a given role using annotations are :
#IsGranted("ROLE_MANAGER")
Or :
#Security("is_granted('ROLE_MANAGER')")
You can see more here : https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/security.html
I have created a custom endpoint using API Platform. Here is the annotation I have used:
/**
* We only want the POST option for now.
*
* #ApiResource(
* itemOperations={},
* collectionOperations={"post"={
* "method"="POST",
* "controller"=PairingController::class,
* "path"="/devices/pairing",
* "defaults"={"_api_receive"=false}
* }},
* )
*
*
*/
class Pairing
{
...
The controller I am calling executes some custom logic. I am happy with how things are working so far. But the documentation generated by API Platform is now inaccurate. It says:
/devices/pairing Creates a Pairing resource.
... which is no longer true, since my controller does not generate a pairing. (It calls out to a different API instead, asking that API to do some stuff.)
So here's my question: How do I change my annotation to allow me to write a custom piece of documentation for this endpoint?
You can use the swagger_context key to change any Swagger field, including description (the one you are looking for): https://api-platform.com/docs/core/swagger/#changing-operations-in-the-swagger-documentation
It didn't works for me, here is how I did it with openapi_context:
"openapi_context"={
"summary"="test",
},
From another question:
/**
* #SWG\Post(
* path="/user/login",
* #SWG\Response(response=200, description="OK")
* )
* #SWG\Path(path="/user/", ref="#/user/login");
*/
function login() {
...
}
The above code not working - no definition coming in swagger integrated page. Do I need two definitions for same method for different URLs?
Try changing the reference to
#SWG\Path(path="/user/", ref="#/paths/~1user~1login");
OpenAPI/Swagger path references use the syntax #/paths/path_name, where path_name is the string /user/login with the special character / escaped as ~1. (This answer has more escaping examples.)
I'm currently researching Symfony CMF and PHPCR for a project I recently started. What I'm currently trying to figure out is how to create a Route and save it into the database. As far as I understand, I must use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route and persist the element into the database. This works fine, but automatically generates a route path, which is not what I want. What I need to do is generate a custom route which links to a specific controller. Here is my code:
$em = $this->get('doctrine_phpcr.odm.document_manager');
$parent = $em->find(null, '/cms/routes');
$route = new \Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route();
$route->setParentDocument($parent);
$route->setName('my_route_name');
$route->setDefault('_controller', 'AppBaseBundle:Frontend/Users:index');
$em->persist($route);
$em->flush();
If i execute this code, the generated route will be /cms/routes/my_route_name. From what I can see, you could use $route->setPath('/testing');, but that generates the following exception:
Can not determine the prefix. Either this is a new, unpersisted document or the listener that calls setPrefix is not set up correctly.
Does anybody have any ideas how to solve this?
In PHPCR, every document has a path where it is store. If you are familiar with doctrine ORM, the path has the role of the ID. The difference with ORM is that all documents (regardless of their type) live in the same tree. This is great, because your route can reference just anything, it is not limited to specific document types. But we need to create some structure with the paths. This is why we have the prefix concept. All routes are placed under a prefix (/cms/routes by default). That part of the document path is removed for the URL path. So repository path /cms/route/testing is the url domain.com/testing.
About your sample code: Usually, you want to configure the controller either by class of the content document or by route "type" attribute to avoid storing a controller name into your database to allow for future refactoring. A lot of this is explained in the [routing chapter of the CMF documentation][1] but the prefix is only used there, not explicitly explained. We need to improve the documentation there.
[1] http://symfony.com/doc/master/cmf/book/routing.html
I managed to find a way to overcome this issue. Because in my project I also have the RouteAutoBundle, I created a class which extends \Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route. Inside that class I added:
/**
* #PHPCR\Document(referenceable=true)
*/
class MenuRoute extends Route
{
protected $url;
/**
* Get $this->url
*
* #return mixed
*/
public function getUrl() {
return $this->url;
}
/**
* Set $this->url
*
* #param mixed $url
*/
public function setUrl($url) {
$this->url = $url;
}
}
After that I added this to cmf_routing_auto.yml:
App\MenuBundle\Document\MenuRoute:
uri_schema: /{getUrl}
token_providers:
getUrl: [content_method, { method: getUrl }]
So now one would just create an instance of MenuRoute (just like when using Route) and call the method setUrl($your_url) passing the desired url.
If anybody finds a better way, I'm opened to suggestions.
I'm using annotation to set my routes and method types. Is there a way to only allow certain types of post data. Currently I'm doing the following:
/**
* #Route("/myurl", requirements={"varID" = "\d+"} )
* #Method({"POST"})
* #Template()
*/
But if a varID gets submitted with a string value then it goes through anyway... I'm guessing due partly to there being no {varID} in the route? Is there a way to validate POST data like this in Symfony?
Change annotation into this:
/**
* #Route("/myurl/{varID}", requirements={"varID" = "\d+"} )
* #Method({"POST"})
* #Template()
*/
You must tell symfony wich part of url is yours varID variable to allow engine to check datatype. Than you get an exception:
No route found for "GET /myurl/somestring"
404 Not Found - NotFoundHttpException
1 linked Exception: