Laravel: Passing custom variables to a controller from a route - laravel

I have the following code in my routes file:
$domain1 = 'www.domain1.co.uk';
Route::group(array('domain' => $domain1), function() use ($domain1)
{
Route::get('/', 'PrimaryController#index');
});
How can I pass the variable $domain1 to the controller method?
To expand to a more general question, how can I simply declare some variable in my routes file and then pass it to a controller? I know I can do this:
Route::get('tours/{id}/{title}', 'PrimaryController#tourHandler');
...and have access to the $id and $title variables in the controller- Which is great if those variables are present in the URL. But what if, for whatever reason, I want access to some specific variables which I want to set myself in the routes file?
Laravel seems too clever sometimes.

Related

How to route an dynamic url?

I am new to laravel. I am defining this route to an edit button:
<button class="btn btn-primary">Edit task</button>
The url is generated fine but the page is not found. I am returning a view with my TaskController#edit with this route:
Route::get('/editTasks/{{ $task->id }}', 'TaskController#edit');
Can someone help me out figuring what i am doing wrong?
When defining routes, the route parameters should only have one { around them. Also, you should not use a variable in the declaration but a name for the variable.
In your example, this could be a valid declaration:
Route::get('/editTasks/{id}', 'TaskController#edit');
More information can be found in the docs: https://laravel.com/docs/5.7/routing#route-parameters
It is also recommended to use route names, so the url can be automatically generated.
For example:
// Route declaration
Route::get('/editTasks/{id}', 'TaskController#edit')->name('tasks.edit');
// In view
Edit task
no you have to define in your route just like this :
Route::get('/editTasks/{id}', 'TaskController#edit');
you don't have $task in your route and you dont need to write any other thing in your route. in your controller you can access to this id like this :
public function edit($taskId) {
}
and only you do this
You need to use single { instead of double, so it needs to be the following in your route:
Route::get('/editTasks/{taskId}', 'TaskController#edit');
And in your edit function:
public function edit($taskId) { }
The double { in the template is correct as this indicates to retrieve a variable
Extra information/recommendation:
It is recommended to let the variable name in the route match the variable in your function definition (as shown above), so you always get the expected variable in your function. If they do not match Laravel will use indexing to resolve the variable, i.e. if you have multiple variables in your route pattern and only use one variable in the function it will take your first route parameter even if you might want the second variable.
Example:
If you have a route with the pattern /something/{var1}/something/{var2} and your function is public function test($variable2) it would use var1 instead of var2. So it it better to let these names match so you always get the expected value in your function.
It's better to use "Route Model Binding". Your route should be like this:
Route::get('/editTasks/{task}', 'TaskController#edit');
And in Controller use something like this:
public function edit($task){
}

Laravel Routes and 'Class#Method' notation - how to pass parameters in URL to method

I am new to Laravel so am uncertain of the notation. The Laravel documentation shows you can pass a parameter this way:
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});
Which is very intuitive. Here is some existing coding in a project I'm undertaking, found in routes.php:
Route::get('geolocate', 'Api\CountriesController#geolocate');
# which of course will call geolocate() in that class
And here is the code I want to pass a variable to:
Route::get('feed/{identifier}', 'Api\FeedController#feed');
The question being, how do I pass $identifier to the class as:
feed($identifier)
Thanks!
Also one further sequitir question from this, how would I notate {identifier} so that it is optional, i.e. simply /feed/ would match this route?
You should first create a link which looks like:
/feed/123
Then, in your controller the method would look like this:
feed($identifier)
{
// Do something with $identifier
}
Laravel is smart enough to map router parameters to controller method arguments, which is nice!
Alternatively, you could use the Request object to return the identifier value like this:
feed()
{
Request::get('identifier');
}
Both methods have their merits, I'd personally use the first example for grabbing one or two router parameters and the second example for when I need to do more complicated things.

Laravel 5: Sessions not working the way they should

On top of every controller and routes.php I used:
use Illuminate\Support\Facades\Session;
In routes.php I set the session using:
Session::put('key', 'value');
In a controller I want to call the session value of key using:
echo Session::get('key');
But once I set a new value to key in routes.php and call it in a controller, I still get the first value and not the new one. If I echo the the session using Session::all() in routes.php after setting it, I see the new value, but in a controller it flips back to the first value. I even tried using below in routes.php before setting the new value, but without success.
Session::forget('key');
Am I forgetting something here?
Using regular PHP $_SESSION my routes.php looks like this:
$slug = $_SERVER['REQUEST_URI'];
$slug = explode('/', $slug[0]);
if(in_array($slug[1], Language::all()->lists('iso'))) {
$_SESSION['language'] = $slug[1];
if(!$slug[2]) {
$_SESSION['slug'] = 'home';
Route::any('/{slug}', ['as' => 'pages.page', 'uses' => 'PagesController#page']);
} else {
if($slug[2] != 'dashboard' && $slug[2] != 'migrate' && $slug[2] != 'form-send') {
if (in_array($slug[2], ElementValue::where('element_field_id', 2)->lists('value_char')) && !isset($slug[3])) {
$_SESSION['slug'] = $slug[2];
Route::any('/{slug}', ['as' => 'pages.page', 'uses' => 'PagesController#page']);
} else {
$_SESSION['slug'] = 'home';
Route::any('/{slug}', ['as' => 'pages.page', 'uses' => 'PagesController#page']);
}
}
}
}
Where in routes.php are you setting the session value? It sounds like you're doing something like this:
Session::put('key', 'value');
Route::get('my-route', 'MyController#doSomething');
and then doing this:
class MyController {
public function doSomething()
{
Session::get('key');
}
}
Is that correct? If so, read on...
I'm no expert on the Laravel request lifecycle (for more, see the documentation), but it doesn't surprise me that this doesn't work. The way I think about it is this: the routes.php file is loaded and executed early in the life cycle - probably first - since it tells the application what code to execute next (ie. what do when a particular request is received). And when I say "early in the life cycle", I mean early - like before sessions are initialized. I believe that the Session::put call is simply being ignored, since at the time when you're setting the value, the session does not exist.
You may want expand your question with a little more detail about what you're trying to accomplish - there has got to be a better way to do it.
EDIT - in response to the comments below...
I am not saying you should touch the $_SESSION superglobal - that's a bad idea because I'm not even sure that Laravel uses the native PHP session facility and you have no guarantee that whatever you do will continue to work in the future.
It's not clear what you're trying to do, but to me this sounds like a value that does not belong in the session.
By placing the Session::put in the routes.php file, it sounds like you have some value that's important and should be set for every session and every request
If that's the case, and it's a static value, then it's not a session value, it's a configuration value.
If, instead, it's a dynamic value and/or it changes depending on which user is associated with a session, then you can set it in one of several places:
if you're using controller-based routing, you could set this in the controller constructor, although I wouldn't recommend it, because you will probably have to do it for several controllers, leading to code duplication
if you're using closures in your routes, set it there. E.g.
Route::get('some/route', function () {
Session::put('key', 'value');
// this works, because the closure isn't executed until after
// the application is initialized
});
you could also do it in middleware
or in a service provider (although I'm not certain that sessions would be available when the service providers are executed).
The best option is probably middleware - this would allow you to set (or calculate) the session value in one place in your code and also associate it with particular routes, if you don't need it for all routes.
Don't use $_SESSION in laravel. Uses the laravel Session class. See the following post How to access the globals $_SESSION and $_COOKIE from a laravel app?
Also, all your if logic should not be living in routes.php. You should add that to middleware to filter your routes.
Also, you are really making this hard for yourself. Laravel provides most of what you need in convenient helper classes e.g. Request::url(), Request::getHost(), Request::getLocale(). Have a read through the docs and get familiar with "The Laravel Way" it will be much easier and things will then work as you expect.
I moved the logic to the controller and now my routes are this simple:
Route::pattern('slug', '[a-zA-Z0-9\-_\/]+');
$slug = Request::path();
if(isset($slug)) {
Route::any('/{slug}', 'PagesController#index')->where('slug', '[a-zA-Z0-9\-_\/]+');
}
The session is stored in the PagesController and used further in the application. Thanks for your help guys.

Laravel passing all routes for a particular domain to a controller

Working on a Laravel 4.2 project. What I am trying to accomplish is pass every URI pattern to a controller that I can then go to the database and see if I need to redirect this URL (I know I can do this simple in PHP and do not need to go through Laravel, but just trying to use this as a learning experience.)
So what I have at the moment is this:
Route::group(array('domain' => 'sub.domain.com'), function()
{
Route::get('?', 'RedirectController#index');
});
I am routing any subdomain which I deem as a "redirect subdomain" ... The ? is where I am having the problem. From what I have read you should be able to use "*" for anything but that does not seem to be working. Anyone have a clue how to pass any URL to a controller?
And on top of that I would ideally like to pass the FULL URL so i can easily just check the DB and redirect so:
$url = URL::full();
Try this:
Route::group(array('domain' => 'sub.domain.com'), function()
{
Route::get('{path}', 'RedirectController#index')
->where('path', '.*');
});
And your controller will reseive the path as first argument
public function index($path){
// ...
}
In case you're wondering, the where is needed because without it {path} will only match the path until the first /. This way all characters, even /, are allowed as route parameter

Laravel form open with multiple parameters

I am trying to pass variables with form open with following code:
{{ Form::open(['method' => 'PATCH','route' => ['note.update','project','1','1']]) }}
Here is my NoteController.php file
Class NoteController extends BaseController{
public function update($belongs_to,$unique_id=0,$note_id=0){
return $unique_id;
}
}
routes.php file is
Route::resource('note', 'NoteController');
Why I am only able to access $belongs_to variable and $unique_id and $note_Id are always 0 as given as default value??
That's because the routes registered with Route::resource only take one url parameter.
Take a look a this
So what you need to do is use this route:
Route::patch('note/{belongs_to}/{unique_id?}/{note_id?}', 'NoteController#update');
If you want to keep the other routes from Route::resource just add it before Route::resource
Route::patch('note/{belongs_to}/{unique_id?}/{note_id?}', 'NoteController#update');
Route::resource('note', 'NoteController');
If you don't want to add the route like this, you'll have to use query parameters to pass additional information

Resources