Welcome Guest, Not a member yet? Register   Sign In
Controller Filters - Input needed
#21

(07-10-2016, 10:34 PM)prezire Wrote: I'd prefer CI4 to be consistent: Apps\Filters\Auth, Configs\Filter. It's a good thing the entire PHP community didn't follow Java samples like org\somefolder\something, com\somefolder\something.

Unfortunately, I don't think it's possible to standardize quite that far. A common convention that I've seen used many times is that a Controller is plural while the Model is singular. Both of those are classes, so we can't make a general rule. And I get what you're saying about Configs but a) it doesn't sound right to me, and b) other folders also wouldn't be correct as plural, like Database and ThirdParty.
Reply
#22

Makes sense. At the end of a the day, a large project will have a large lists of filters regardless. The reason I'm interested in this topic specifically is because I feel like this is one of those difficult design decisions that will be a pain to go back on so we want to try to get it right.
Codeigniter is simply one of the tools you need to learn to be a successful developer. Always add more tools to your coding arsenal!
Reply
#23

(This post was last modified: 07-10-2016, 11:48 PM by arma7x. Edit Reason: change policies to filter )

IMO, the filter should applied to controller and method directly. A bit different from @albertleao proposed.
PHP Code:
public $filter = [
    
'Blog' => ['add' => ['before' => ['isAdmin'], 'after' => ['somethingElse']],
           
'edit' => ['before' => ['isAdmin'], 'after' => ['somethingElse']],
           
'delete' => ['before' => ['isAdmin'], 'after' => ['somethingElse']],
           
'view' => ['before' => ['isLoggedIn'], 'after' => ['somethingElse']]
          ]
    ]; 
Keep calm.
Reply
#24

Going through all of this just makes me realize why most frameworks just do it in the routing file...
Codeigniter is simply one of the tools you need to learn to be a successful developer. Always add more tools to your coding arsenal!
Reply
#25

(This post was last modified: 07-11-2016, 05:25 AM by prezire.)

(07-10-2016, 10:50 PM)kilishan Wrote:
(07-10-2016, 10:34 PM)prezire Wrote: I'd prefer CI4 to be consistent: Apps\Filters\Auth, Configs\Filter. It's a good thing the entire PHP community didn't follow Java samples like org\somefolder\something, com\somefolder\something.

Unfortunately, I don't think it's possible to standardize quite that far. A common convention that I've seen used many times is that a Controller is plural while the Model is singular. Both of those are classes, so we can't make a general rule. And I get what you're saying about Configs but a) it doesn't sound right to me, and b) other folders also wouldn't be correct as plural, like Database and ThirdParty.

I agree there are some folders that can't be pluralized. It's a good thing though to change them into Databases and ThirdParties Smile

The reason other frameworks pluralize their controllers is because of a convention where they remove the word "Controller". But there's an option for CI4 not to follow this. I've seen a couple years back, other developers tend to create something like Users.php (plural name) instead of UsersList.php (singular name).

Let's say a developer would create a controller for a new Article feature in his app. In most cases, a Laravel developer would create something like ArticlesController.php. The word "Controller" is singular however, since it's their convention to remove that word to shorten the URI, what's left is the word "Articles" hence we get /articles, /articles/{id}, /articles/{slug}. But what most developers don't comprehend much is that "/articles" actually means "/articles/index". If we follow a singular name, it would be "/article/index" just like what Laravel does with its Eloquent inside a controller "\App\Article::all()". The class name is singular, followed by all(), which can be represented via "views/index.blade.php". The same goes for the ID. Pluralized controller name looks a bit odd with "/articles/1" (are there multiple Articles that have IDs of 1?) VS "/article/1".

Yes, these things can be configured via routes, but wouldn't it be nice if the entire CI4 properly practices good plural VS singular conventions for folders and classes by default? But that's just IMO. Hope that helps Smile

Apologies about constantly using Laravel as an example. I have a knack beating that framework in terms of conventions. I get annoyed of other developers constantly saying it's better than CI.
Long live CodeIgniter!
Reply
#26

OK, I think I may be getting closer here. I went through and took a look at some different existing middlewares out there (here and here), and then took a look at a couple of existing Laravel projects and how we used middleware there and had a few realizations.

1. Some common types of items apply only to one particular HTTP method, like applying CSRF/CORS or Request Throttling to all POST requests. This could also be expanded to include "methods" like 'ajax' and 'cli'.
2. Most of them (that weren't for specific forms) were applied in large groups of the site.

I went back and forth an whether my grouping by uris or by filter made more sense, worked the best overall for the site. Seeing how we were using them in other frameworks, it didn't make sense any longer to do it per controller/method as it would take a lot more work to make things correct.

With those things in mind, here's a revised example:

Code:
<?php namespace Config;

class Filters
{
    // Makes reading things below nicer,
    // and simpler to change out script that's used.
    public $aliases = [
        'isLoggedIn' => 'App\Filters\Authentication',
        'apiPrep' => [
            'App\Filters\First',
            'App\Filters\Second',
        ]
    ];

    // Always applied before every request
    public $globals = [
        'before' => [
            'isLoggedIn'               => ['except' => 'login'],
            'CodeIgniter\Filters\CSRF'
            'FullPageCache'
        ],
        'after' => ['FullPageCache' ]
    ];

    // Works on all of a particular HTTP method
    // (GET, POST, etc) as BEFORE filters only
    public $methods = [
        'post' => ['CSRF', 'throttle'],
        'ajax' => ['restrictToAJAX'],
        'cli'  => ['restrictToCLI']
    ];

    public $filters = [
        'isLoggedIn' => ['before' => ['account/*', 'profiles/*']],
        'adminAuth'  => ['before' => ['admin/*']],
        'apiPrep'    => ['before' => ['api/*']],
    ];
}

A few key points:

1. Aliases can now be groups of filters to clean things up a little more.
2. Globals can be applied before or after, and can blacklist some uri's but cannot whitelist (that's better handled in the $filters array)
3. Support for HTTP methods (and 'ajax'/'cli') has been added, but only for before actions. Not sure those make sense as after actions, but it might make sense to include them for completeness and consistency.
4. Finally, filters can have both before and after uri patterns specified.

Thoughts?
Reply
#27

Good work!

One question though, and I'm not sure this directly relates to just my application of CI but I declare all my routes in my routes.php file and have 650~ routes in my application. About 600 of those routes require authentication and I'd be putting an AuthFilter in front of them. Would that mean that I would have to rewrite all 600 routes in the Filters.php file? And if a route changes, I would have to change it in both locations?
Codeigniter is simply one of the tools you need to learn to be a successful developer. Always add more tools to your coding arsenal!
Reply
#28

(This post was last modified: 07-12-2016, 02:13 AM by arma7x.)

(07-11-2016, 10:23 PM)albertleao Wrote: Good work!

One question though, and I'm not sure this directly relates to just my application of CI but I declare all my routes in my routes.php file and have 650~ routes in my application. About 600 of those routes require authentication and I'd be putting an AuthFilter in front of them. Would that mean that I would have to rewrite all 600 routes in the Filters.php file? And if a route changes, I would have to change it in both locations?
IMO, filter should tie to controller and method. As example:
Filters rule;
PHP Code:
['Auth::login' => ['before' => 'IsGuest''after' => 'RecordLogin']]; 

Now if we we change the route;
PHP Code:
$routes->add('auth/local''Auth::login'); 
to
PHP Code:
$routes->add('auth/basic''Auth::login'); 
,
we don't have to change the filter, since the rules is applied to controller and method, not route itself.
Keep calm.
Reply
#29

@arma7x - I get what you're saying about tieing to a controller/method, I do. I don't think it's the most practical method though. I keep hearing people talk about having hundreds or thousands of controllers. That would be a horror trying to map up filters to. And by attaching to the uri, you can easily wild-card entire groups of routes to cut down on the maintenance.

@albertleao - Not at all! That's where wild-carding comes in. If all of those pages are behind an 'admin' uri, then you can specify it like:

Code:
'adminAuth'  => ['before' => ['admin/*']]

in the $filters array. That would apply to any uri that starts with **admin**. Or if it's you have a small section of your site or two that is easily group-able you could do it as an exclusion to the global setting, like:

Code:
public $globals = [
        'before' => [
            'isLoggedIn' => ['except' => ['auth/*', 'pages/*'] ],
        ]
    ];

Does that make sense?
Reply
#30

Yes, that sounds great.

One last thing, and this is minor, but what do you think about splitting the $aliases array into a separate file? A file where you can declare all your filters and a file where you 'attach' all your filters might keep it clean, but again very minor.
Codeigniter is simply one of the tools you need to learn to be a successful developer. Always add more tools to your coding arsenal!
Reply




Theme © iAndrew 2016 - Forum software by © MyBB