Symfony2 Route get parameter only if integer - symfony

I got defined routes in routing.yml file
one route is:
Profile_user_profile:
path: /profile/{id}
defaults: { _controller: ProfileBundle:Users:profile }
methods: [get]
and second is:
Profile_accept_connection_proposal:
path: /profile/acceptProposal
defaults: { _controller:ProfileBundle:Users:acceptConnectionProposal }
methods: [put]
First route without methods: [get] listen also and [put] request and catch second url before it get to route definition. Is there way to define checking for parameter only if url is numeric.

Just add the requirements parameter to accept only digits for a determined route like this:
Profile_user_profile:
path: /profile/{id}
defaults: { _controller: ProfileBundle:Users:profile }
methods: [get]
requirements: <--- ADDED PARAMETER
id: \d+
For more infos read the Symfony book about Routing. There you can find more advanced example on how to use route parameters.

You can now do this with Annotations in your controller like so:
class UserController extends AbstractController
{
/**
* #Route("/profile/{id}", name="user_profile", requirements={"id"="\d+"})
*/
public function profile($id)
{
// ...
}
}
More info on Symfony's docs
Specifically defining routing requirements

Related

No route found for "GET /demo/koco/create" : 404 Not Found - NotFoundHttpException

Why I am getting errors for the route?
Other APIs for the CRUD operation are working fine.
I have added a new controller code for my new API and I am getting a route error.
What could be the mistake?
While I have already written my route in routing.yml
creat:
path: /create
defaults: { _controller: AcmeDemoBundle:DemoController:create }
methods: [GET]
Products:
path: /recentProducts/{id}
defaults: { _controller: AcmeDemoBundle:DemoController:recentProducts }
methods: [GET]
Update:
path: /updateProduct/{id}
defaults: { _controller: AcmeDemoBundle:DemoController:update }
methods: [POST]
Delete:
path: /deleteProduct/{id}
defaults: { _controller: AcmeDemoBundle:DemoController:delete }
methods: [DELETE]
referenceCreation:
path: /koco/create
defaults: { _controller: AcmeDemoBundle:DemoController:createReference }
methods: [GET]
My api is
http://localhost/koco1/web/app_dev.php/demo/koco/create
My Controller is
/**
* #Route("/koco/create", name="referenceCreation")
* #Template()
*/
public function createReferenceAction()
{
$organization = new Organization();
$organization->setName('Sensio Lab');
$user = new User();
$user->setName("Jonathan H. Wage");
$user->setOrganization($organization);
$dm = $this->get('doctrine_mongodb')->getManager();
$dm->persist($organization);
$dm->persist($user);
$dm->flush();
return new Response('Created product id ');
// $response = new Response('Hello Huzaifa ');
// return $response;
}
What is wrong here?
Kindly let me know.
Thanks
Your routing is off.
Also you are creating routes through yaml and through annotations. Should stick to one.
Also server setup looks off too, http://localhost/koco1/web/app_dev.php/demo/koco/create should be more like http://localhost/koco1/web/koco/create, you can try running php server. Going to /public and running php -S localhost:8000 you can read more here: https://www.php.net/manual/en/features.commandline.webserver.php
or symfony cli server https://symfony.com/download
Your routes does not match /demo/koco/create is not equal to /koco/create, you should first of all set up correctly, then it will be easier to debug.

Symfony 4 with translations, no route to / without _locale

I created a Symfony 4.4.8 project with translations to English and French languages, so I followed the steps:
https://symfony.com/doc/current/translation.html
and set:
config/packages/translation.yaml
framework:
default_locale: 'fr'
translator:
default_path: '%kernel.project_dir%/translations'
fallbacks: ['en', 'fr']
config/routes/annotations.yaml
controllers:
resource: ../../src/Controller/
type: annotation
prefix: /{_locale}/
requirements:
_locale: fr|en
and a src/Controller/HomeController.php with
class HomeController extends AbstractController
{
private $session;
public function __construct(SessionInterface $session)
{
$this->session = $session;
}
/**
* #Route("/", name="home")
*/
public function index() {
return $this->render('home/index.html.twig', [
'controller_name' => 'HomeController',
]);
}
I have the translation files in translations folder and when I run localhost:8000/fr or localhost:8000/en, it works fine, my home/index.html.twig is shown.
The issue is when I run localhost:8000/, it shows me the default Welcome to Symfony page with "You're seeing this page because you haven't configured any homepage URL."
Is this solution for sf2 will work on sf4?
Is anybody know how to solve it ?
I tested also to change the route in HomeController to:
#Route("/{_locale}", name="home", defaults={"_locale"="fr"}
but it returns exception:
Route pattern "/{_locale}/{_locale}" cannot reference variable name "_locale" more than once.
workaround, added:
RedirectMatch ^/$ /fr
in my virtualhost (with apache2 server)
pure symfony solution shoud be better !
I would guess a bad routing configuration. I couldn't recall a default behaviour where we can set the locale by adding the locale code in the URL so I would guess it is something your added ;)
Symfony resolves the route in the same order as you declare the route. So one solution would be to import 2 times the same route but with the prefix:
# config/route.yaml
app_front:
type: annotation
resource: '../src/Controller/*.php'
prefix: /
options:
expose: true
app_localized_front:
type: annotation
resource: '../src/Controller/*.php'
name_prefix: localized_
prefix: /{locale}
options:
expose: true
I know the previous config works, but I don't know if this is the more elegant way to do it :)

Symfony annotation routing order

I'm currently stuck with routing in my Symfony4 (4.3) project. My problem is pretty simple, I want to use route annotations in my controllers but I want to defined the order of these one.
For example, if I have two controllers with following routing :
class BarController extends AbstractController
{
/**
* #Route("/test/{data}", name="app_bar")
*/
public function index($data)
{
// ...
return $this->render('index.html.twig', [
'data' => $data,
]);
}
}
and
class FooController extends AbstractController
{
/**
* #Route("/test/my_value", name="app_foo")
*/
public function index()
{
// ...
return $this->render('index.html.twig', [
'data' => 'my_value',
]);
}
}
In config/routes/annotations.yaml I define my route like this
app_controllers:
resource: ../../src/Controller/
type: annotation
Then if I call /test/my_value I would like to be redirected to FooController since his index action define #Route("/test/my_value", name="app_foo") but like routes is loaded alphabetically the index action from BarController with app_bar route is called first.
So I have tried to defined following routing :
app_foo_controller:
resource: ../../src/Controller/FooController.php
type: annotation
app_controllers:
resource: ../../src/Controller/
type: annotation
But this didn't work, BarController and his app_bar route still called before app_foo route from FooController.
Also, I don't understand the purpose of config/routes/annotations.yaml vs config/routes.yaml since both could contains any type of routes... I miss something ?
Nevermind I found the solution. I just miss the fact that I override my specifically app_foo_controller routing when I define app_controllers the solution is to defined each controllers like that :
app_controllers:
resource: ../../src/Controller/
type: annotation
app_foo_controller:
resource: ../../src/Controller/FooController.php
type: annotation
app_bar_controller:
resource: ../../src/Controller/BarController.php
type: annotation

EventListeners for log\history. Doctrine2, Symfony

I want to make custom log \ history in order to track what happened. I have such Entities:
-Category
-Item
-AttrValue
-Attributes
All of them are related to each other like this:
I read it and decided to use EventListeners and write events to the table using doctrine. You do not need to offer to use bands for logging / auditing, the essence is what you need to do without them. Therefore, I determined such steps to realize this:
Create a new Entity with the following fields:
-Time (When);
-What (the action that occurred, for example, creating, updating, viewing or deleting records);
-OldValue (if it exists);
-NewValue (if it exists);
Create a new EventListener with prePersist, preUpdate and preRemove.
Create a method that will work with Doctrine and write values ​​from item 1 (something like buildLog (LifecycleEventArgs $args, $type), where $type is an action (create, update, or delete).
Therefore, I have such questions:
1. Can I use EventListeners for what I want to do?
2. If so, did I correctly describe the sequence of actions? (to define EventListeners in services.yml I do not consider)
3. How to determine what action has occurred? (I will attach my routing file below)
4. How to use this all for several Entities? Something like this will suit?
$ entity = $ args-> getEntity ();
Can there be somewhere a similar implementation, so that you can read?
My Routing:
getAllCategory:
path: /category
methods: [GET]
defaults: { _controller: AppBundle:Catalog:getAllCategory}
getCategory:
path: /category/{id}
methods: [GET]
defaults: { _controller: AppBundle:Catalog:getCategory}
postCategory:
path: /category
methods: [POST]
defaults: { _controller: AppBundle:Catalog:postCategory}
updateCategory:
path: /category
methods: [PATCH]
defaults: { _controller: AppBundle:Catalog:updateCategory}
deleteCategory:
path: /category/{id}
methods: [DELETE]
defaults: { _controller: AppBundle:Catalog:deleteCategory}
getAllItem:
path: /items
methods: [GET]
defaults: { _controller: AppBundle:Item:getAllItems}
getItem:
path: /item/{id}
methods: [GET]
defaults: { _controller: AppBundle:Item:getItem}
postItem:
path: /item
methods: [POST]
defaults: { _controller: AppBundle:Item:postItem}
updateItem:
path: /item
methods: [PATCH]
defaults: { _controller: AppBundle:Item:updateItem}
deleteItem:
path: /item/{id}
methods: [DELETE]
defaults: { _controller: AppBundle:Item:deleteItem}

Trailing slash for route default?

I have the following route:
reviews:
pattern: /reviews/{uid}{trailingSlash}
defaults: { _controller: unrealsp.cms.controller:handle_review, uid: "index", trailingSlash : "/" }
requirements: { trailingSlash : "[/]{0,1}" }
I made this work with trailing slashes using this stackoverflow answer.
The route will recognize the "/reviews" URL and refer to the index uid, displaying an index of available reviews (rather than single reviews it would call with any other uid). However, it will not recognize "/reviews/" as index, saying there is no such route. How do I go about changing that?
try changig it to:
pattern: /reviews/
{uid} makes the parameter required by the router, so if you want /reviews/ to be valid, you have to remove it from route definition. This way you would just add in the controller:
$uid = $request->get('uid','index');
Another solution is:
reviews:
pattern: /reviews/{uid}
defaults: { _controller: unrealsp.cms.controller:handle_review }
requirements: { uid: "\d+" }
reviews_index:
pattern: /reviews/
defaults: { _controller: unrealsp.cms.controller:handle_review }

Resources