I tried googling, but I can't phrase the question right, it is simple.
I have these 2 routes:
Route::get('admin_firme/{id_firma}/filijale/{id_filijala}', 'FilijalaAdminController#show');
Route::get('admin_firme/{id_firma}/filijale/create', 'FilijalaAdminController#create')
They call different controller actions. The problem is in the second route which calls the create method. The part /filijale/create is being interpreted as the parameter of the first route, thus calling the wrong method. How can I correct this?
I tried naming the route and generating an url to it, but it still calls the wrong method.
Just take the bottom one up ...
Route::get('admin_firme/{id_firma}/filijale/create', 'FilijalaAdminController#create');
Route::get('admin_firme/{id_firma}/filijale/{id_filijala}', 'FilijalaAdminController#show');
should work.
There's two things you can do. The first, and easiest, is to swap the order of them round so when checking matching routes it checks to see if it's create first, and if not anything else matches id_filijala.
The second thing you can do is use pattern matching for id_filijala, for example if it only contained numbers then you could use:
Route::get('admin_firme/{id_firma}/filijale/{id_filijala}', 'FilijalaAdminController#show')
->where('id_filijala', '[0-9]+');
You can use any regular expression in the where.
Related
I am new to Laravel and coming from PHP wanted to understand some of the aspects of the framework. I have never used a framework before and would like to understand some of the under the hood stuff. I saw this syntax for the route class:
// Second Route method – Root URL with ID will match this method
Route::get('ID/{id}',function($id){
echo 'ID: '.$id;
});
From my understanding Laravel does pattern matching for the URL and extracts the value from id and assigns it to $id and passes it to the closure.
Is my above understanding correct
Can someone point to the part in Laravel Code where the value of id is extracted and assigned to $id variable
Why are curly braces used? It it just to make pattern matching easier?
Yes, you are correct
Right here
The curly brackets are to let the route parser know that this is a dynamic part that will be able to change in the url. It could have been any other way, but this is how Laravel does things.
In a CakePHP Plugin documentation there is the following code line: $validator->provider('upload', \Josegonzalez\Upload\Validation\DefaultValidation::class);
\Josegonzalez\Upload\Validation\DefaultValidation is the namespace, but I didn't understand the ::class. Could someone explain it? I didn't find anything in PHP documentation.
the class constant simply returns the full name of the class (with namespace) as a string. So instead of passing as string to some method that requires it, you pass it the PHP way. It just looks nice, for example:
$validator->provider('upload',\Josegonzalez\Upload\Validation\DefaultValidation::class);
AND
$validator->provider('upload', '\Josegonzalez\Upload\Validation\DefaultValidation');
Both Are Same
And another advantage of this is that, if you need full class name several times in a single file.. say onto multiple method calls as a parameter. You can simply use it on the top & then only the classname will return the full name with namespace. like this:
use \Josegonzalez\Upload\Validation\DefaultValidation;
$validator->provider('upload', DefaultValidation::class);
//you can use it on other places as well, if required.
$someOtherClass->someOtherMethod(DefaultValidation::class);
So, in short, it reduces the number of characters you need to type, and makes your code look cleaner.
Is there any way of combining these two following routes?
Route::get('project/(:any)', 'dashboard.project#(:1)');
Route::get('project/(:any)/(:any)', 'dashboard.project#(:1)');
I'm asking because the second route, I had to add it in order for the following requests to work:
site.com/project/new => method
site.com/project/view/12351326 => method and parameter
You can use regex in the first parameter of the get() method to combine those.
See section Regular Expression Route Constraints in the docs.
Something like this might work:
Route::get('project/{name}', function($name)
{
//
})
->where('name', '[A-Za-z0-9\/]+');
Where the regex will match URLs such as /projects/something/anything. However that might be too loose - it will also match /projects/any/number/of/url/segments. But I believe some more RegEx can help make better constraints to get closer to what you're looking for.
So, I don't know how many times I have done similar with code igniter in the past across a handful of sites. However, just getting myself a fresh copy, and starting a rebuild on a new site Im already running into a twisted little issue that I can't figure out, I don't know what I am missing in this equation..
So this is my Routes currently:
$route['default_controller'] = "home";
$route['404_override'] = 'home/unknown';
$route['post/(:any)/(:any)'] = 'post/$1/$2';
//$route['post/(:any)'] = 'post/$1';
//$route['post'] = 'post';
$route['host-hotel'] = 'host_hotel';
$route['floor-plan'] = 'floor_plan';
$route['wine-facts'] = 'wine_facts';
$route['exhibitor-application'] = 'exhibitor_application';
$route['photo-gallery'] = 'photo_gallery';
$route['video-gallery'] = 'video_gallery';
Now the problem is specifically with this guy.
$route['post/(:any)/(:any)'] = 'post/$1/$2';
I've even tried naming the segment article instead of post, thinking maybe its a protected name of sorts in CI. If you notice above this line I have also tried adding varations of the URL so it could handle either just the first segment or one or two more there after. Grant it they are commented out in this example, but didn't work.
If I go to the domain.com/post the behavior is as expected. Anything there after is where the issue starts. If I did anything number or letter or combo there of..
ie: domain.com/post/s2hj or domain.com/post/s2hj/avd the page starts acting like the 404 behavior, page not found which to me makes no sense, as I said Ive done routes like this in the past. And to me this route looks proper? So anyone have any ideas/suggests what to look for?
:any matches literally any character, including slashes. This will be changed in CodeIgniter 3.0, but for the time being you can use ([^/]) to catch a single segment.
Another way to try this is through Good ol' regexp:
$route['post/([^/]+)/([^/]+)'] = 'post/$1/$2';
If also you need to be able to handle a total of 2 uri segments, consider:
$route['post/([^/]+)(?:/([^/]+))'] = 'post/$1/$2';
REGEXP explained:
() simply captures and handles the strings inside. Also gives us $1, $2 etc at the other end.
(?:) is the same as above, but doesn't capture $1
[] is the allowed combination of things inside. [0-9] will look for numbers only.
[^] is the reversed logic. everything exepct the given signs.
[^/] is everything but /, thus giving us desired result.
I have an application which makes decisions based on part of URL:
if ( isset($this->params['url']['url']) ) {
$url = $this->params['url']['url'];
$url = explode('/',$url);
$id = $this->Provider->getProviderID($url[0]);
$this->providerName = $url[0]; //set the provider name
return $id;
}
This happens to be in a cake app so $this->params['url'] contains an element of URL. I then use the element of the URL so decide which data to use in the rest of my app. My question is...
whats the best way to secure this input so that people can't pass in anything nasty?
thanks,
Other comments here are correct, in AppController's beforeFilter validate the provider against the providers in your db.
However, if all URLs should be prefixed with a provider string, you are going about extracting it from the URL the wrong way by looking in $this->params['url'].
This kind of problem is exactly what the router class, and it's ability to pass params to an action is for. Check out the manual page in the cookbook http://book.cakephp.org/view/46/Routes-Configuration. You might try something like:
Router::connect('/:provider/:controller/:action');
You'll also see in the manual the ability to validate the provider param in the route itself by a regex - if you have a small definite list of known providers, you can hard code these in the route regex.
By setting up a route that captures this part of the URL it becomes instantly available in $this->params['provider'], but even better than that is the fact that the html helper link() method automatically builds correctly formatted URLs, e.g.
$html->link('label', array(
'controller' => 'xxx',
'action' => 'yyy',
'provider' => 'zzz'
));
This returns a link like /zzz/xxx/yyy
What are valid provider names? Test if the URL parameter is one, otherwise reject it.
Hopefully you're aware that there is absolutely no way to prevent the user from submitting absolutely anything, including provider names they're not supposed to use.
I'd re-iterate Karsten's comment: define "anything nasty"
What are you expecting the parameter to be? If you're expecting it to be a URL, use a regex to validate URLs. If you're expecting an integer, cast it to an integer. Same goes for a float, boolean, etc.
These PHP functions might be helpful though:
www.php.net/strip_tags
www.php.net/ctype_alpha
the parameter will be a providername - alphanumeric string. i think the answer is basically to to use ctype_alpha() in combination with a check that the providername is a valid one, based on other application logic.
thanks for the replies
Also, if you have a known set of allowable URLs, a good idea is to whitelist those allowed URLs. You could even do that dynamically by having a DB table that contains the allowed URLs -- pull that from the database, make a comparison to the URL parameter passed. Alternatively, you could whitelist patterns (say you have allowed domains that can be passed, but the rest of the url changes... You can whitelist the domain and/ or use regexps to determine validity).
At the very least, make sure you use strip_tags, or the built-in mysql escape sequences (if using PHP5, parameterizing your SQL queries solves these problems).
It would be more cake-like to use the Sanitize class. In this case Sanitize::escape() or Sanitize::paranoid() seem appropriate.