So I have a POST URL with two parameters and I want to assign default values for both parameters .
I know you can implement this way for a URL with a single param:
Route::post('activity-log/datatable/{tag_access?}/{page_access?}',
'SettingsController#datatable_activity_log')
->defaults('tag_access', 'activity-log');
But how do i go about it with a URL that looks like this:
Route::post('activity-log/datatable/{tag_access?}/{page_access?}',
'SettingsController#datatable_activity_log')
You can achieve it by following way:
Keep your route as you want like this:
Route::post('activity-log/datatable/{tag_access?}/{page_access?}','SettingsController#datatable_activity_log')
Now, In controller function you can take these parameters with default value like this,
public function datatable_activity_log($tag_access='activity-log', $page_access='activity-log', Request $request){
// Here write your logic
}
This may not be the best way to achieve what you want but this is one of the way.
From what I see regarding the usage of defaults you can either do one at a time:
Route::post('activity-log/datatable/{tag_access?}/{page_access?}',
'SettingsController#datatable_activity_log')
->defaults('tag_access', 'activity-log')
->defaults('page_access', 'defaultValue');
An alternative (since defaults is public) is to do:
$route = Route::post('activity-log/datatable/{tag_access?}/{page_access?}',
'SettingsController#datatable_activity_log');
$route->defaults = [ 'tag_access' => 'activity-log', 'page_access' => 'defaultValue' ];
My personal favourite is what #Sagar Gautam suggest which is to use default function parameters.
Related
I have a problem with Laravel 5, and to be precise, I can't find the solution for it.
In C# (ASP.NET MVC) it's easy to solve.
For example, I have these routes (I'll just type the route content, and the function header, for the sake of simplicity)
/{category}/Page{page}
/Page{page}
/{category}
The function is defined inside Product controller.
function header looks like this:
public function list($page = 1, $category = null)
the problem is, whenever I enter just one argument, it doesn't send the value for the parameter by the name I set in the route, but rather, it pushes values by function parameter order.
So, when I open /Page1, it works properly, value of 1 is sent to $page variable,
but when I access /Golf(made up on the spot), it also sends the value to the $page variable.
Any possible idea how to avoid this, or do I really need to make different functions to handle these cases?
In C#, it properly sends the value, and keeps the default value for undefined parameter.
Hope you have an answer for me.
Thank you in advance and have a nice day :)
So, as you've seen the parameters are passed to the function in order, not by name.
To achieve what you want, you can access these route parameters from within your function by type hinting the request object to it like this:
class ProductController extends Controller
{
function list(Request $request){ # <----------- don't pass the params, just the request object
$page = $request->route('page'); # <--- Then access by name
$category = $request->route('category');
dd("Page: $page | Category: $category");
}
}
Then of course you would set all 3 of your routes to hit that same controller method:
Route::get('/{category}/Page{page}', 'ProductController#list');
Route::get('/Page{page}', 'ProductController#list');
Route::get('/{category}', 'ProductController#list');
Hope this helps..!
if you want to get the parameters in your controller, you can use this:
public function list() {
$params = $this->getRouter()->getCurrentRoute()->parameters();
}
for /aaa/Page3, the $params would be array(category => 'aaa', page => '3')
for /Page3, the $params would be array(page => '3')
for /aaa, the $params would be array(category => 'aaa')
I have a route like this:
Route::get('demo/{system?}', 'MonitorController#demo');
I am using it like so because I would like my url to look like so:
mysite.com/demo/spain-system
Where spain-system will be the variable I need to get.
Right now, I'm getting it like this:
public function demo($systemName = null){
}
But I would like to be able to access to it as if it were a URL parameter with Input::get('system') so I can access to it from other methods or even from other controllers such as BaseController.php.
Is there any way to achieve this?
I've played around with Route::input('system') but then it doesn't work when I pass it as a get parameter (in other Ajax calls and so on)
Update
In PHP we can get URL params by using the $_GET function and laravel provides the function Input::get() to do so as well.
If there were no routes in laravel, I would make use of .htaccess rewrite rules to change this:
mysite.com/demo/?system=spain-system
To this:
mysite.com/demo/spain-system
And I could still retrieve the variable system as a GET parameter by using $_GET["system"].
That's kind of what I would expect of laravel, but it seems it is just treating it as the parameter of the demo method and not really as a URL variable.
Is there any way to keep treating it as a URL variable and at the same time use it in a pretty URL without the ?system= ?
So you actually just want to get an url like this? mysite.com/demo/spain-system instead of mysite.com/demo/?system=spain-system? Laravel provides that by default?
Look, When you want to get the router variable {system?} to be accesible you'll need to do this:
In your router:
Route::get('demo/{system}', 'MonitorController#demo');
Then you have an controller where this noods to stand in:
public function demo($system)
{
//your further system
//You are be able to access the $system variable
echo $system; //just to show the idea of it.
}
When you now go to to localhost/demo/a-system-name/, You'll see a blank page with a-system-name.
Hope this helps, because your question is abit unclear.
How to forward with GET parameters?
I have two actions in same controller. I do some magic in the first action, and if all goes well, I want it to forward to the other one, but with GET parameters created in the first one.
What I have now is this:
return $this->forward('AppBundle:default:tracked', array(), array(
'tracking_code' => $tracking_code,
'company' => $tp_company_name
)));
Empty array in there because of a desperate effort to get it to work. Documentation tells that second array is for the query parameters, but nothing really happens, so I must be doing something wrong.
The second action tries to get the parameters like this:
/**
* #Route("/tracked", name="tracked")
*/
public function trackedAction()
{
$request = Request::createFromGlobals();
// If there is the required variables in the GET:
if($request->query->has('tracking_code') && $request->query->has('company'))
But no, variables never get there it seems.
Reason I have this kind of setup, is that user can get into the trackedAction from another place as well.
I think the proper way to get your parameters in your second action would be to do like this :
return $this->forward('AppBundle:default:tracked', array(
'tracking_code' => $tracking_code,
'company' => $tp_company_name
)));
And your second action would be :
/**
* #Route("/tracked/{tracking_code}/{company}", name="tracked")
*/
public function trackedAction($tracking_code=null, $company=null)
{
...
}
I used the $tracking_code = null because you specified this could be accessed from another place, that maybe does not provide these parameters. This way it works for both of them.
Hope this helps.
The way that Symfony controller forwarding works is by duplicating the current the Request with the options that you pass and then re-dispatching it through the HttpKernel component. You can see this in the code. Because it's a sub-request, your second action is creating a Request from globals (i.e. $_GET etc.) which haven't changed.
The solution is to change your second action method signature to:
public function trackedAction(Request $request)
This means that the $request variable will be "local" to your action and will contain the variables you want.
In practice you should always pass the Request in to your actions this way as it makes your controllers a lot more testable and prevents strange issues like this.
Alternatively to all of the above, you could use a redirect instead which would do an HTTP redirect rather than just forwarding within the Symfony request system.
I create a URL like this:
$app->createAbsoluteUrl('/', array(
'param1' => 'val1',
'param2' => 'var2',
);
The generated URL is:
http://mysite.com/param1/var1/param2/var2
But I expect a url like this:
http://mysite.com/?param1=var1¶m2=var2
In function manual it says:
$params array additional GET parameters (name=>value). Both the name and value will be URL-encoded.
But it doesn't seem to work like that. How I can generate the expected URL? Thanks.
You need to specify that the urlManager application component should use the "get" format for the URLs it generates; the default is to use the "path" format. The Yii guide explains how to do it inside your application configuration:
array(
......
'components'=>array(
......
'urlManager'=>array(
'urlFormat'=>'get',
),
),
);
Update: So your urlFormat is "path" and that's by design... what about alternatives?
If you don't mind extending CWebApplication and using your own derived class in its place then you have several options such as:
Define your own createUrlEx method based on the original createUrl. It could look like this:
public function createUrlEx($format,$route,$params=array(),$ampersand='&')
{
$oldFormat = $this->getUrlManager()->getUrlFormat();
$this->getUrlManager()->setUrlFormat($format);
$url = $this->getUrlManager()->createUrl($route,$params,$ampersand);
$this->getUrlManager()->setUrlFormat($oldFormat);
return $url;
}
Override registerCoreComponents so that you can have a second url manager:
protected function registerCoreComponents()
{
parent::registerCoreComponents();
$components=array(
'specialUrlManager'=>array(
'class'=>'CUrlManager',
'urlFormat'=>'get',
),
);
$this->setComponents($components);
}
You can now call Yii::app()->specialUrlManager->createUrl(...) anytime.
You can also approach the problem in other ways:
Extend CUrlManager and expose a method that allows you to select the flavor of url to create on the spot.
If you only need "get" urls in one or two places, you can always create a new CUrlManager object, configure it on the spot, call createUrl and then discard it. You could also hide this ugliness behind a free function. Essentially this (admittedly not recommended) approach is a low-tech version of the first workaround given that has the advantage that you don't need to extend CWebApplication.
You should be able to use something like Yii::app()->urlManager->createPathInfo This will generate the query string as ...&var=val&... using a custom & and = if you like. You could use this to create a query string version of a URL on demand with:
$url = $this->createAbsoluteUrl('/').'index.php?'.Yii::app()->urlManager->createPathInfo($arrayOfStuff);
Or you might even be able to do:
Yii::app()->urlManager->urlFormat = 'get';
$this->createAbsoluteUrl('My/Path');
Yii::app()->urlManager->urlFormat = 'path';
Although I haven't and don't want to test the second method.
URL route should be in the format of 'ControllerID/ActionID'. manual
Your manual link is for CController and isn't for CApplication.
I'm new to CodeIgniter and going to be using it for building a sort of reusable application with multiple instances of an application. For example, each instance of the application will have an id "12345", and inside that instance, there will be entry IDs of 1,2,3,4,5,6,7,8, etc.
to do this, I think I will want to be able to using Routing to set up something like:
http://example.com/12345/Entry/Details/1
Where this URI will go to the Details page of the Entry of ID=1, inside application ID 12345. This would be a different group of entries from a url of, say, /12346/Entry/Details/1. Is this a routing rule that needs to be set up, and if so, can someone please provide an example of how this could be configured, and then how I would be able to use 12345, and 1, inside of the function. Thanks so much for your help, in advance.
My suggestion would be that you route your urls like this:
$route['(:any)/{controller_name}/(:any)/(:any)'] = '{controller_name}/$2/$3/$1';
so that the last parameter for the function is always the id of the app (12345/12346). Doing this means that your Entry controller functions will look like this:
class Entry extends CI_Controller
{
function Details(var1, var2, ..., varn, app_id){}
function Someother_Function (var 1, app_id){}
}
you will also need to add a route for functions that don't have anything but the app_id:
$route['(:any)/{controller_name}/(:any)'] = '{controller_name}/$2/$1'; //This may work for everything.
I hope this is what you we're asking...
Edit:
If you are only going to be using numbers you could use (:num) instead of (:any)
You can achieve a routing like that by adding this rule to the application/config/routes.php file:
$route['default_controller'] = "yourdefaultcontroller";
$route['404_ovverride'] = "";
// custom route down here:
$route['(:num)/entry/details/(:num)'] = "entry/details/$1/$2",
of course assuming your URI to be like the example.
In your controller "Entry" you'll have a method "details" which takes 2 parameters, $contestID and $photoID, where $contestID is the unique instance you're assigning, while $photoID is the other (assumed) variable of your url (last segment).
class Entry extends CI_Controller(
{
function details {$contestID, $photoID)
{ //do your codeZ here }
}
See URI routing for more info on that. You might also want to consider the __remap() overriding function, in case.