Welcome Guest, Not a member yet? Register   Sign In
Using other controller to display a view
#1

[eluser]sw[/eluser]
I'm not sure if this is the right MVC approach and if not please educate me.

From my main controller I want to display another controllers view, is it possible? How?



ie: I have an auth controller that has a function to display the login form. From my main controller, I want to call auth controller in order to display the login form.
I don't do it directly because the login form to be displayed depends on several parameters handled by the auth controller.


I hope that made sense.
Thanks in advance.
#2

[eluser]jedd[/eluser]
Hi sw, and welcome to the CI forums.

I think that rather than considering a view to be owned by another controller, as such, you might want to approach this from the authentication angle. That is, you'd test if the user was authenticated, and if they were not, you'd automatically send them off to the login page.

You can do that with the redirect command, so something like this in your code:

Code:
redirect ('auth/login');

That'll take them straight to the Auth controller, and the login method within same.

The line before that would probably be some test to see if you were already authenticated - this is usually a call to session data to see if a certain variable is set.

Is this the kind of thing you were thinking of?
#3

[eluser]sw[/eluser]
Thank you.

The thing is, I want the main controller to display more than just the login form. So it would have to load those other views and somehow manage to display either the login form (if user not logged in) or a logout button (which are two different views).

For ie.
load(header)
load(auth/login) <-
load(footer)


edit:
My issue is more MVC concept wise than anything else. I know several ways I can accomplish that but they don't make much sense in a MVC environment. It's something new to me.
#4

[eluser]jedd[/eluser]
Ah, okay - wasn't sure if that was the angle you were more interested in.

With your view/ folder, you can create sub-directories there to separate things more cleanly. So you could have your 'login form' as its own view snippet - a chunk of HTML wrapped in div or table tags, say - and you can call that from any controller.

The view snippet would, in the case of a user/pass login box, have a submit button that direct to your controller/method for authentication - but the view code itself would be portable for any controller that wanted to call it in.
#5

[eluser]sw[/eluser]
That is what I have at the moment.
Main controller decides whether to display the login form or the logout button which then call the auth controller when pushed.

The issue remains tho, if I want to display the login form in other pages, I'll have to rewrite the logic behind what form it displays (whether it is logged in or not).
This is why I wanted to move the logic to auth controller and somehow be able to call it from other controllers to display the login view.

Another option is to move the logic into the login view but that goes against MVC pattern, I guess.


I'm sorry for not being able to detail the problem accurately.
#6

[eluser]jedd[/eluser]
Ah, gotcha now.

Yes, you're right - you want to avoid putting that logic into the view per se - as there will be times when a controller/method (which pretty much should be the definition of your page, if not your layout) is just too busy, or it would be inappropriate, to display an extra login section.

So for this I think there are two MVC-friendly, code-lite, easy-to-read broad ways to handle it.

If your method of identifying if a user is logged in or not (ie. if they should see a login box) is really quite lightweight, then just deal with that line of code and the call to generate the view-ette inline. An example from my code:

Code:
// in my controller somewhere
if  ( $this-session->userdata('login_name') )
     // I'm logged in
else
     // I'm not.


Second, write a helper - I think most people end up with a helper file that is loaded all the time (with a handful of others that are used on demand). This is much the same as above, but far more readable. I don't think it's terribly expensive as you're referencing the extant CI object, not copying it. An example for your situation
Code:
// In controller
if (! is_logged_in() )
     // call in login view-ette
Code:
// In helper
function is_logged_in()  {
    $CI =& get_instance();
    return ($CI->session->userdata('login_name')) ? TRUE : FALSE ;
    } // end-function  is_logged_in ()
Code:
// Still in helper
// You could obviously have a small handful of these types of things
function is_admin()  {
    $CI =& get_instance();
    return ($CI->session->userdata('admin')) ? TRUE : FALSE ;
    } // end-function  is_admin ()


A variant on the second option is to utilise the MY_Controller approach, to get $this-> functions available to all inherited controller classes. In this instance I want to send them on a one-way street to the login page if they hit certain controllers without being logged in. This function could have been called 'kick_nonauthenticated_users'.
Code:
// In my forum controller's constructor (people must be logged in to get here)
     $this->_ensure_authenticated_user( "Forums" );

Code:
// In my MY_Controller library extension
    function  _ensure_authenticated_user ( $page_message = "this")  {
        if (! $this->session->userdata('login_name'))  {
            $this->session->set_flashdata('user_needs_to_login', $page_message);
            redirect('/people/login');
            }
        }


Am I getting closer?
#7

[eluser]sw[/eluser]
Yes, that covers it.

Thanks a lot.




Theme © iAndrew 2016 - Forum software by © MyBB