how to unset particular session in every controller except one controller - session

Laravel Problem: I want to unset particular session on every controller except one(specific) controller.
I am thinking of helper class. But if is there better way (like middle ware).
If is anyone have idea, please share.

Middleware is a good idea, you can use easily with your routes:
Route::group(['middleware' => 'clearSession'], function () {
// .. your controllers
});
// A controller where not clear
Route::controller('mycontroller', 'MyController');
But you can also add to your controllers constructor, and you don't have to mess with current routes, route groups.

Related

what middleware can what controller in Laravel cannot do?

while learning Laravel i came across this concept called middleware. I am wondering why we need middleware in the first place? We can implement the same logic in our controller too , then , whats the point of having middleware? what is it what we cannot do in controller and we need middleware for it?
If you have multiple controllers and you want to apply same condition on then, rather then writing same code in multiple files(Controllers). Write code in one file(middleware) and apply on all controllers.
Route::middleware('checkRole')->group(function() {
Route::get('user', 'UserController#index')
Route::get('order', 'OrderController#index')
Route::get('customers', 'CustomerController#index')
});

Links in view files that are called through different named routes

Our team is trying to convert an old multitenant architecture over to Laravel and having some difficulty staying DRY in our routes/views.
Our account section contains multiple page views: an account dashboard, edit profile, payment methods, registrations, etc. However, we provide multiple stand-alone websites for a client, and there are multiple URL structures for the user to access their account:
In addition to the standard...
https://clientone.ourdomain.com/account/
...they can also access their account via different standalone websites:
https://clientone.ourdomain.com/event-app-one/account/
https://clientone.ourdomain.com/event-app-two/account/
All of those URLs above give them the exact same information, but with a different layout/theme applied for each standalone website. Right now the routes I set up for those above look like this:
// #### CLIENT ONE - ROOT
Route::domain('{subdomain}.ourdomain.com')->group(function() {
Route::middleware(['setTheme:clientone-account-theme'])->group(function() {
Route::get('/', 'ClientController#index')->name('index');
Route::prefix('account')->group(function() {
Route::get('/', 'AccountController#index')->name('clientone.account.show');
Route::get('/edit', 'AccountController#edit')->name('clientone.account.edit');
...
});
});
// #### CLIENT ONE - EVENT APP ONE
Route::prefix('event-app-one')->group(function() {
Route::middleware(['setTheme:clientone-eventapp-one-theme'])->group(function() {
Route::get('/', 'EventAppController#index')->name('clientone.eventapp.one.index');
...
Route::prefix('account')->group(function() {
Route::get('/', 'AccountController#index')->name('clientone.eventapp.one.account.show');
Route::get('/edit', 'AccountController#edit')->name('clientone.eventapp.one.account.edit');
...
});
});
});
// #### CLIENT ONE - EVENT APP TWO
Route::prefix('event-app-2')->group(function() {
Route::middleware(['setTheme:clientone-eventapp-two-theme'])->group(function() {
Route::get('/', 'EventAppController#index')->name('clientone.eventapp.two.index');
...
Route::prefix('account')->group(function() {
Route::get('/', 'AccountController#index')->name('clientone.eventapp.two.account.show');
Route::get('/edit', 'AccountController#edit')->name('clientone.eventapp.two.account.edit');
...
});
});
});
Those routes all currently work. We don't like including the client or app name in all of our route names because they get rather long and can't be reused, but if we take those out we found out our route URLs will override each other.
However, if we do it this way, our account views that we share across all these URLs can't use named route links for href because we don't know which one to use. For example, we can't do this in blade...
Edit Profile
...because, while that will work while at clientone.ourdomain.com/account/, it won't work while at clientone.ourdomain.com/event-app-one/account/.
Should I just not use route names for links in our views and use a relative link instead? Or am I going about my route naming all wrong? The only other thing I can think of is to copy all the view files and have one version for .com/account/ and another for .com/all-event-apps/account/ and just use a different set of route names for each. Feels wrong to duplicate essentially the same functionality in those views though.
You can use a parameter for the prefix so you are not repeating the same exact routes and creating new names for them. You can then generate routes based on those route names.
You can set defaults for parameters for the UrlGenerator to help deal with this.
I would add a middleware to your group that checks the prefix then will assign that as a default parameter on the UrlGenerator:
// instead of app-one, app-two, etc etc
Route::prefix('{app}')->middleware('handleapp')...
// handleapp middleware
Url::defaults(['app' => $request->route()->parameter('app')]);
$request->route()->forgetParameter('app'); // if you dont want this passed into controller methods
// where you need to generate a route
route('eventapp.account.edit'); // {app} is handled by the default we set so doesn't have to be passed
I would also have a middleware that will add the default parameter for subdomain as well so you don't have to pass that yourself everywhere.
Basically it all becomes dynamic and based on the current request you can have defaults setup for all these parameters so you don't have to pass them into the route helpers yourself everywhere you need a URL from a route name.
This is just the basic idea in use.

Laravel 5 - Assign Middleware to Controller Namespace

I need to do an ACL check for the user before allowing access to the admin panel of a Laravel 5 website. What is the best way to do this for an entire controller group in the namespace App\Http\Controllers\Admin\*? Ultimately, I'm looking for a "set and forget" method to do this, and middleware looks like the best option so far.
The initial idea was to assign a middleware to the admin route, but this does not prevent any other non-admin route from accessing the controllers. This means a route can still target the admin controllers and bypass the ACL check.
The next idea was to insert the assignment in the constructor on the controllers, but this would require each additional controller to explicitly include the middleware. This would require a developer to know that the middleware should be included, which allows them to miss it entirely. This also applies to using one base controller as the parent for all admin controllers, since the developer would need to know that the base controller should be extended. Right now, this looks like the best solution.
This leads us back to the question: can middleware be assigned to a controller wildcard namespace like App\Http\Controllers\Admin\*? Or, is there a better way for the ACL check to never need to be explicitly assigned to every admin controller?
This leads us back to the question: can middleware be assigned to a controller wildcard namespace like App\Http\Controllers\Admin*?
No
The most simplest approach you can do is create a base controller such as App\Http\Controllers\Admin\Controller and include the middleware
while all other App\Http\Controllers\Admin\* extends it.
Alternatively, while still adding App\Http\Controllers\Admin\Controller, you could instead inject the middleware through IoC Container.
App::afterResolving('App\Http\Controllers\Admin\Controller', function ($controller) {
$controller->middleware('acl');
});
EDIT
My previous answer didn't quite work for all situations; it broke a lot of other routes. Here's what I ended up doing instead (in app/Http/routes.php):
Route::group(['namespace' => 'Admin', 'prefix' => 'admin', 'middleware' => 'App\Http\Middleware\Acl'], function()
{
Route::get('/', 'AdminController#index');
Route::get('/user', 'User\UserController#index');
...
});
This at least targets all admin controllers when I define a route. It's not exactly everything I had hope for, but it will do.

How to check value of parameters of RESTful controller's action

I use the Larvel 4.1
If I use routes for every action I can check parameters value into route like here
Route::get('user/{id}', 'UserController#showProfile')->where('id', '[0-9]+');
But I don't understand how to check this value when I define a route for a RESTful controller
Route::controller('users', 'UserController');
Do I check parameters directly into controller's action or there is another way?
Yeah, looks like this is not the way Route::controller() works, but if you do
Route::pattern('one', '[0-9]+');
It will work. Because this is how Laravel create controller routes parameters:
GET|HEAD myactions/id/{one?}/{two?}/{three?}/{four?}/{five?}
The problem is that you cannot filter those parameters this way because they may appear in actions of different controllers. So you probably will have to create some of those routes manually:
Route::get('user/{id}', 'UserController#showProfile')->where('id', '[0-9]+');
Which, in my opinion is better than use a generic Route::controller() or Route::resource(). And in Phil Sturgeon's opinion too, as you can see in his article: http://philsturgeon.uk/blog/2013/07/beware-the-route-to-evil
So, I actually use separated routes for each action this manner
Route::pattern('one', '[0-9]+');
Route::get('user/{id}', 'UserController#showProfile');
I simple was hoped do it in more short way.

How can I prevent duplicate content when re-routing pages in CodeIgniter?

Say I have a controller, "Articles" but I want it to appear as a sub-folder (e.g. "blog/articles"), I can add a route like this:
$route['blog/articles'] = 'articles';
$route['blog/articles/(:any)'] = 'articles/$1';
This works fine, the only problem now is that example.com/articles and example.com/blog/articles both use the Articles controller and thus resolve to the same content. Is there a way to prevent this?
To add a little more clarity in case people aren't understanding:
In this example, I don't have a 'blog' controller, but I want 'articles' etc to appear to be in that subfolder (it's an organization thing).
I could have a blog controller with an 'articles' function, but I'm likely to have a bunch of 'subcontrollers' and want to separate the functionality (otherwise I could end up with 30+ functions for separate entities in the blog controller).
I want example.com/articles to return a 404 since that is not the correct URL, example.com/blog/articles is.
Shove this in your controller:
function __construct()
{
parent::Controller();
$this->uri->uri_segment(1) == 'blog' OR show_404();
}
You can use subfolders in Codeigniter controllers, so in CI, the following directory structure works:
application/controllers/blog/articles.php and is then accessed at
http://example.com/blog/articles/*.
If, for some reason, you're set on routing instead of accessing the controllers in folders (you want to have a blog controller, for example, and don't want to route to it), you can do as suggested above and add the test for 'blog' to the constructor.
If you're in PHP5, you can use the constructor function like this:
function __construct()
{
parent::Controller();
$this->uri->uri_segment(1) == 'blog' OR redirect('/blog/articles');
}
or, in PHP4, like this:
function Articles()
{
parent::Controller();
$this->uri->uri_segment(1) == 'blog' OR redirect('/blog/articles');
}
I would suggest using redirect('blog/articles') instead of show_404(), though, so that you're directing users who hit /articles to the correct location, instead of just showing them a 404 page.
Routing there does not mean it will use a different controller, it just creates alias url segment to same controller. The way will be to create another controller if you are looking to use a different controller for those url segments.
If both /blog/ and /articles/ use the same controller, you can reroute one of them to a different one by just adding a new rule in your routes file.

Resources