Symfony2 routing repeating pattern - symfony

I have a URL that can accept any number of parameters but not in exactly the same order. For example
example.com/myapp/service1/username1/service2/username2
or
example.com/myapp/service2/username2/service1/username1
or
example.com/myapp/service7/username7
How can I write a rounting yml entry to catch any of those routes so that I can split them into service/username for example array("service" => "Instagram", "username" => "JoBloggs") or how ever many were passed to the URL.
I have access to a pre-made list of about 30 services, but usernames could pretty much be any value.
I'm not really sure even how to ask this question so I'll give any additional info that would be useful.
Ideally, I'd like to avoid something like example.com/myapp/?service1=username1&...

Seems like I can add mimic catch all at the end of a URL Slash in parameter
route_name:
pattern: /myapp/{services}
defaults: { _controller: bundle.controller.homepage:index }
requirements:
services: ".+"

Related

Symfony - Defining a route only in dev. environment

I'm using SF2 and I created some routes helping the debugging of the project:
widget_debug_page:
path: /debug/widget/{widgetName}
defaults: { _controller: WidgetBundle:Debug:default }
The problem is that this route MUST never be reachable when going in production.
I could not find a parameter to specify the environment.
Just for people who want use with annotation system:
/**
* #Route("/my-route", condition="'dev' === '%kernel.environment%'")
*/
public function index() {}
You can add your route in routing_dev.yml (Symfony 2/3) or create a dev-only routing file in config/routes/dev/ (Symfony 4).
As mentioned perviously you can define the conditional route by adding 'condition' directive to the route definition. In case you need to limit the route for the appropriate environment you can check %kernel.environment% parameter value directly. For example:
widget_debug_page:
path: /debug/widget/{widgetName}
defaults: { _controller: WidgetBundle:Debug:default }
condition: "%kernel.environment% === 'dev'"
I just had a similar problem myself since I wanted to create a "System temporarily down due to maintenance"-page that would disable my site entirely in prod-environment only as I use dev-environment to make sure everything is alright after deploying an update to my production server. I guess its debatable whether this is good practice, but anyway...
The comment made by Leto to a previous answer gave me an idea how to solve it and I think I have successfully managed to make my route only work in dev-environment like so:
default_update_view:
path: /{route}
defaults: { _controller: WalanderBundle:Default:maintenanceInfo }
condition: "request.getScriptName() == '/app.php'"
requirements:
route: .+
No the question was to only enable a route in dev-environment which would then be done by changing the condition as follows if I'm not missing anything obvious:
condition: "request.getScriptName() == '/app_dev.php'"
Hope this helps although the question was a bit old!
Perhaps in the case when you want to enable a route in the dev-environment only the already provided answer by JonaPkr is best practice though.
Symfony >= 5.3
when#dev:
widget_debug_page:
path: /debug/widget/{widgetName}
defaults: { _controller: WidgetBundle:Debug:default }
reference: https://symfony.com/blog/new-in-symfony-5-3-configure-multiple-environments-in-a-single-file

Symfony 2.5 SEO Friendly URLs

I'm trying to build my own CMS based on Symfony 2 since I swapped jobs and now require some symfony practice, but got stuck when trying to do something sensible with routes. In Zend it was possible with preDispatch so I hope Symfony 2 will have something similar too.
Consider this URL: http://www.example.com/page_one/sub_page/another_sub_page/yet_another_sub/
What I am trying to achieve is to have http://www.example.com/page_one/ matching to some controller and getting me the content of the page that has the url_string parameter same as that portion of URL. Then http://www.example.com/page_one/sub_page/ should also match to the same controller but render content for the sub_page portion of URL.
The route must match n portions because I cannot know how deep the structure might go.
So I will not accept something like
/{slug1} or
/{slug1}/{slug2} or
/{slug1}/{slug2}/{slug3}
as that is nonsense.
I am planning to make this route as last one in the routing config so should there be some matches on other routes they will be picked up instead, and this one despite it is most important route will be last resort matching kinda thing.
Using the following config will match all urls, and the entire path will be passed into the controller "slug1/slug2/slug3".
SymfonyBundle/DefaultBundle/Resources/config/routing.yml:
symfony_default_page:
path: /{path}
defaults: { _controller: SymfonyBundle:Default:page }
requirements:
path: "^.+"
Or** ou can also use regex in the requirements path. This will exclude "admin", "login", "blog", however it's much easier if you simplify things and just place the routing in the correct order like you said
requirements:
path: "^(?!admin|login|blog).+"
app/config/routing.yml
By importing the default bundle routing last, it means any routing yml files above will take priority and therefore not match the default route which will catch any url.
SymfonyAdminBundle:
resource: "#SymfonyAdminBundle/Resources/config/routing.yml"
prefix: /admin
#import this last
SymfonyDefaultBundle:
resource: "#SymfonyDefaultBundle/Resources/config/routing.yml"
prefix: /
Controller:
class DefaultController extends Controller
{
public function pageAction($path)
{
//You could split the URL and handle accordingly, also filter / escape?
$parts = explode("/", $path);
}
}

Send multiple paths to one route without redirect function

I am updating my website to a Meteor application with iron-router, and need to change my urls. The old scheme had capitalized page names like this:
mysite.com/Contact
but I've changed everything to be lowercase:
mysite.com/contact
That contact route isn't complicated, so it's set up like this:
this.route('contact');
but I want the /Contact url to be redirected. I know I could just do this:
this.route('Contact', {
onBeforeAction: function() {
Router.go('contact');
}
});
but it's so much messier. I'd prefer to do something like this:
this.route('contact', {
path: ['/contact', '/Contact']
});
where the route simply is mapped to multiple paths.
Is there a feature like this? Or is my onBeforeAction the best I'm going to get?
https://github.com/EventedMind/iron-router/blob/devel/DOCS.md#dynamic-path-segments
You can use a Regular Expression for your path segment (see the last example in the Dynamic Path Segments link).
Your path would be:
this.route('contact', {
path: /contact/i
});
Where the 'i' after the forward-slash is the regular expression modifier to be case insensitive allowing you to accept any variation of 'contact' (whether cOntact, Contact, or conTACT).
See http://www.w3schools.com/jsref/jsref_regexp_i.asp for details on the RegEx modifier.

URL available only for administrator

How can I set that URL`s which have new in name are available only for ROLE_ADMINISTRATOR?
I`m sure that I must set it in security.yml access_control
But how to set for example
www.mydomain.com/user/new
www.mydomain.com/user/2/edit
only for ROLE_ADMINISTRATOR
{ path: ^/.*/new, role: ROLE_ADMINISTRATOR } doesn`t work :(
Symfony 2 will select the first pattern that matches. So, if a pattern above the one you shared gives access to that path (say something like ^/user) then the role of that line will be allowed.
Ensure that you have the restrictive paths above all of the others.
Also, I'm not sure if Symfony allows . to match /, so you might want to try ^/[\s\S]*/new (or even just /new$ if the new is always at the end) if it isn't just a problem with ordering.

Symfony2 Routing optional parameter with trailing slash

I am trying to write my first application with Symfony2. It's a fairly simple game just to get used to working with Symfony2, but the Routing is bugging me.
I use YAML for my routing and have the following routes:
upload:
path: /{_locale}/upload/{currentGameType}/
defaults: { _controller: BaseAcmeBundle:Default:upload, currentGameType: gameName, _locale: nl }
requirements:
_locale: nl|en
The currentGameType is optional, and always is 'gameName', a default game if it is not set.
So when going to en/upload the route upload: is ignored and I get the message that the route is not found
When for example I go to the en/upload/gameName the route does work and the gametype is set to gameName. Why does this parameter not want to be optional?
So.. I am completely lost the pas few hours and wish for some help/pointers.
Thanks in advance.
edit: So, few minutes after posting I found out that without the trailing slashes in the routing it does work. However knowing this it is still an issue.
just create a second path:
upload_bare:
path: /{_locale}/upload/
defaults: { _controller: BaseAcmeBundle:Default:upload, _locale: nl }
requirements:
_locale: nl|en
just note that in your function you should have gameName = null by default and it should be your last argument.

Resources