CodeIgniter Forums
Writing Admin/User/Public controllers to insure authentication - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Using CodeIgniter (https://forum.codeigniter.com/forumdisplay.php?fid=5)
+--- Forum: Best Practices (https://forum.codeigniter.com/forumdisplay.php?fid=12)
+--- Thread: Writing Admin/User/Public controllers to insure authentication (/showthread.php?tid=580)

Pages: 1 2 3 4


Writing Admin/User/Public controllers to insure authentication - sneakyimp - 12-22-2014

I'm migrating a largish site to CodeIgniter 2 and we have roughly three types of pages we host:
* Public pages like about-us, documentation, etc.
* User pages that require an authenticated, registered user to be logged in
* Admin pages for our internal employees who are authenticated & registered with a different access_level than your run-of-the-mill users.

I am trying to mimic this tutorial:
http://avenir.ro/codeigniter-tutorials/no-more-my_controller-how-you-can-create-more-than-one-base-controller/

Basically, I'm trying to follow best practices in organizing my controllers such that I can easily force appropriate authentication for the appropriate user access level. I wonder if I'm following the right approach and can dimly foresee that such an approach may have a pretty restrictive effect on how I organize my controllers. If it works right, however, I can expect to avoid a lot of redundant code to check for authentication, etc.

Also, I'm wondering if using hooks as described in the article is in fact the recommended way to go.

Any input would be much appreciated. Thank you!


RE: Writing Admin/User/Public controllers to insure authentication - Avenirer - 12-23-2014

Well... If you are talking about best practices, the best practice would be to have only a MY_Controller. If you are talking about your needs and how you see it easier to implement them your application, CodeIgniter is basic enough to allow you to do whatever you want and make it as complex as you want, if you know how. Smile


RE: Writing Admin/User/Public controllers to insure authentication - Hobbes - 12-23-2014

well for me my application requires a separate parent controller for admin's so i created a MY_Controller and a Admin_Controller under: application/core folder.

in the MY_Controller.php create your class, then at the end of the file outside the MY_Controller Class i put this chunk of code:

Code:
if ( ! class_exists('Admin_Controller'))
{
    require_once APPPATH.'core/Admin_controller.php';
}

in your admin_controller __construct method you would put your check(s) to ensure only certain member groups can access it and any child controllers.


RE: Writing Admin/User/Public controllers to insure authentication - sneakyimp - 12-23-2014

(12-23-2014, 04:40 AM)Avenirer Wrote: Well... If you are talking about best practices, the best practice would be to have only a MY_Controller. If you are talking about your needs and how you see it easier to implement them your application, CodeIgniter is basic enough to allow you to do whatever you want and make it as complex as you want, if you know how. Smile
Avenirer, I'm guessing that's your article? It's nice. I'm inclined to trust you but just want to be sure. Perhaps you could more specifically address this question that I asked:
'sneakyimp Wrote:I'm wondering if using hooks as described in the article is in fact the recommended way to go.
There seem to be many ways to accomplish something in CI. I'm primarily interested in avoiding techniques that require special effort every time I have to upgrade CI to the next version. With that in mind, putting my custom code in files that are not touched by the CI devs seems very important to me. I would also agree that putting a lot of code in a configuration file seems like a bad idea. Perhaps you could explain why you think using hooks is the best approach. Is this code safe from a CI core upgrade?

As for my plan to use more than one controller, it seems pretty apparent to me that my site is likely to have session-related functionality whether visitors are logged in or not. It further seems likely that I'll have distinct functionality for administrators versus visiting authenticated users. I expect Admin_Controller to inherit from User_Controller which will inherit in turn from Basic_Controller (or something like that). If anyone thinks this is a bad idea, I'd love to know why. It seems like essentially the same thing recommended in Avenirer's article...

I also like Hobbes' suggestion of putting some code after the class definition to load the Admin_Controller (and possibly other classes). This seems simpler to me than creating an entirely separate hook and enabling hooks, etc. It has the additional advantage that it doesn't require me to alter files distributed as part of CI.


RE: Writing Admin/User/Public controllers to insure authentication - Avenirer - 12-23-2014

(12-23-2014, 10:27 AM)sneakyimp Wrote:
(12-23-2014, 04:40 AM)Avenirer Wrote: Well... If you are talking about best practices, the best practice would be to have only a MY_Controller. If you are talking about your needs and how you see it easier to implement them your application, CodeIgniter is basic enough to allow you to do whatever you want and make it as complex as you want, if you know how. Smile
Avenirer, I'm guessing that's your article? It's nice. I'm inclined to trust you but just want to be sure. Perhaps you could more specifically address this question that I asked:

\sneakyimp Wrote:I'm wondering if using hooks as described in the article is in fact the recommended way to go.
There seem to be many ways to accomplish something in CI. I'm primarily interested in avoiding techniques that require special effort every time I have to upgrade CI to the next version. With that in mind, putting my custom code in files that are not touched by the CI devs seems very important to me. I would also agree that putting a lot of code in a configuration file seems like a bad idea. Perhaps you could explain why you think using hooks is the best approach. Is this code safe from a CI core upgrade?

As for my plan to use more than one controller, it seems pretty apparent to me that my site is likely to have session-related functionality whether visitors are logged in or not. It further seems likely that I'll have distinct functionality for administrators versus visiting authenticated users. I expect Admin_Controller to inherit from User_Controller which will inherit in turn from Basic_Controller (or something like that). If anyone thinks this is a bad idea, I'd love to know why. It seems like essentially the same thing recommended in Avenirer's article...

I also like Hobbes' suggestion of putting some code after the class definition to load the Admin_Controller (and possibly other classes). This seems simpler to me than creating an entirely separate hook and enabling hooks, etc. It has the additional advantage that it doesn't require me to alter files distributed as part of CI.

In my opinion, putting an autoload inside... wherever (some people put it into config, some people put it into main index.php)... is  a bit hack'ish... That is because, after you've done that you may have forgotten where you've put it.

Hobbes' suggestion is no better than the first method, that is because is not a good practice, you simply put the autoload inside a MY_Controller.

On the other hand we have the hooking system which, logically seems better than the first options. That is because we establish an order of loading the classes, and also we know from the start where to look for the autoloader.

Another method, which I think would be the best but I didn't have the time to look into (that is "I don't know yet how to implement"...) would be to use the Composer and then use namespacing when defining and asking for the necessary controller.


RE: Writing Admin/User/Public controllers to insure authentication - sneakyimp - 12-23-2014

(12-23-2014, 05:07 PM)Avenirer Wrote: In my opinion, putting an autoload inside... wherever (some people put it into config, some people put it into main index.php)... is  a bit hack'ish... That is because, after you've done that you may have forgotten where you've put it.
Agreed it's a bit hackish. I'm not especially worried about forgetting where it is and would argue that it'd probably be easier to forget about one's hooks than one's config file. The hook syntax also a bit impenetrable. I'm more concerned that this is a config file. On the other hand, sort of makes on wonder if autoloaders are configuration or something else...

(12-23-2014, 05:07 PM)Avenirer Wrote: Hobbes' suggestion is no better than the first method, that is because is not a good practice, you simply put the autoload inside a MY_Controller.
Technically speaking, it's not an autoloader but specific require instructions. Still, awkward to have include/require statements in a class definition file.

(12-23-2014, 05:07 PM)Avenirer Wrote: On the other hand we have the hooking system which, logically seems better than the first options. That is because we establish an order of loading the classes, and also we know from the start where to look for the autoloader.
Unless I'm mistaken, autoloaders needn't worry about the sequence of class loading because their job is to automatically fetch class definitions as needed. If we put the require/include statements in MY_ROUTER, this would also specify a load sequence.

(12-23-2014, 05:07 PM)Avenirer Wrote: Another method, which I think would be the best but I didn't have the time to look into (that is "I don't know yet how to implement"...) would be to use the Composer and then use namespacing when defining and asking for the necessary controller.
Agreed that namespacing is a concern in CI. If you want nice simple class names for your controllers (e.g.,"Search") then you will probably end up using complicated names somewhere else -- or encountering a name collision.


RE: Writing Admin/User/Public controllers to insure authentication - mwhitney - 12-30-2014

Honestly, I think that when it comes to modifying the controller hierarchy in a CI application, almost anything is going to, eventually, become a bit hackish.

Bonfire uses Wiredesignz Modular Extensions/HMVC. When I originally started using it, all of the base controllers for Bonfire were defined inside the MY_Controller.php file. In the last couple of years, those controllers have been split up into their own files within the application/core directory (at the moment I don't remember whether this required a modification to the loader). In our case, the class hierarchy for the controllers looks something like this:

- MX_Controller (MX/HMVC - /application/third_party/MX/Controller.php)
- Base_Controller extends MX_Controller (/application/core/Base_Controller.php)
- Front_Controller extends Base_Controller (/application/core/Front_Controller.php)
- Authenticated_Controller extends Base_Controller (/application/core/Authenticated_Controller.php)
- Admin_Controller extends Authenticated_Controller (/application/core/Admin_Controller.php)

Then each controller in a given application usually extends Front_Controller, Admin_Controller, or Authenticated_Controller, depending on the requirements for that controller. In rare cases I've written controllers which extend either Base_Controller or MX_Controller itself, but those usually handled lower level functionality on the site.

The MX_Controller is itself quite a hackish bit of code to overload the controller and loader in CI, and it adds some weight and functionality that you probably aren't really looking for in this case.

In terms of best practices, if I were to implement something from scratch I would probably look into overloading the loader to allow me to load base controllers from the controllers directory. After dabbling in the guts of the loader and MX_Controller a few times, though, I really don't know how long I'd remain interested in doing it myself.


RE: Writing Admin/User/Public controllers to insure authentication - sneakyimp - 12-31-2014

Thanks for the thoughts, mwhitney.

(12-30-2014, 03:53 PM)mwhitney Wrote: Honestly, I think that when it comes to modifying the controller hierarchy in a CI application, almost anything is going to, eventually, become a bit hackish.
I don't think this is unique to CI. I think that if one did not write the framework, one usually ends up hacking something to make it one's own. I remember someone saying ot me "by the time you finish any engineering project, you've already thought of a dozen ways you could have done it better."

(12-30-2014, 03:53 PM)mwhitney Wrote: In terms of best practices, if I were to implement something from scratch I would probably look into overloading the loader to allow me to load base controllers from the controllers directory. After dabbling in the guts of the loader and MX_Controller a few times, though, I really don't know how long I'd remain interested in doing it myself.
I'd strongly recommend registering an autoloading function in a pre-system hook. You can say goodbye to include/require statements and stop worrying about inheritance.


RE: Writing Admin/User/Public controllers to insure authentication - bclinton - 12-31-2014

(12-31-2014, 12:04 PM)sneakyimp Wrote: I'd strongly recommend registering an autoloading function in a pre-system hook. You can say goodbye to include/require statements and stop worrying about inheritance.

Most of this thread seems like a lot of conversation devoted to avoiding the following line of code:


PHP Code:
include_once(APPPATH.'core/Admin_Controller.php'); 


What's so horrible about an include_once statement above your controller class declaration that indicates the location of the custom controller class you are extending?


RE: Writing Admin/User/Public controllers to insure authentication - ivantcholakov - 01-01-2015

@bclinton
Nothing horrible. But also, there is nothing horrible a computer to do the job for you.