CodeIgniter Forums
Output Class Question - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived General Discussion (https://forum.codeigniter.com/forumdisplay.php?fid=21)
+--- Thread: Output Class Question (/showthread.php?tid=28446)

Pages: 1 2


Output Class Question - El Forum - 03-11-2010

[eluser]wdcmatt[/eluser]
I have read the user guide and I am a bit unclear on how to do something or if it can be done (within the framework).

I've noticed that in a controller code igniter waits till my controller is finished (with all its functions and view calls) before displaying the page. This makes sense... but under some circumstances I do not want to get to the end of a function how would I go about doing this, I will provide an example:

Code:
class sample extends Controller
{
    function sample()
    {
        parent::Controller();
    }

    function display_page($id)
    {
        $this->load->model('mpage');    // my model to get the data from the db

        // skipping all validation for demo purposes

        $pageData = $this->mpage->get_page($id);  // returns associative array of page data...

        // Check to see if the page is allowed to be viewed publicly...
        if ( ! $pageData['content_published'])
        {
            //output the notification that content not published.
            $this->load->view('not_published.php');  
            // End here... some how...? and display output normally
        }

        // Check to see if the content has expired (content scheduling...)
        // this would normally involve dates and times... but for demo assume a bool answer
        if ( $pageData['expired'] )
        {
           // notify the user that the content has expired.
           $this->load->view('content_expired.php');
           // End here some how???? and display output normally
        }

        // if they made it through everything do something else...
        $this->load->view('show_page.php', $pageData);
    } // End display_page
}

I know some of you are already thinking of ways to rewrite the sample so that I don't have to terminate in the middle of a function... I know how to do that already. What I'm looking for is a way to end in the middle of a function and still display the output as usual. The project I'm working on is actually much more in depth and would be much much easier for me to perform that type of function.

Is there a way to do this? Can someone give me an example usage?


Output Class Question - El Forum - 03-11-2010

[eluser]danmontgomery[/eluser]
http://php.net/manual/en/function.return.php
http://php.net/manual/en/control-structures.elseif.php

Code:
function display_page($id) {
    if($some_value == true) {
        $this->load->view('a_view', $data);
        return true;
    }

    if($some_other_value == true) {
        $this->load->view('another_view', $data);
        return true;
    }

    $this->load->view('a_third_view', $data);
}

// or

function display_page($id) {
    if($some_value == true) {
        $this->load->view('a_view', $data);
    } else if($some_other_value == true) {
        $this->load->view('another_view', $data);
    } else {
        $this->load->view('a_third_view', $data);
    }
}



Output Class Question - El Forum - 03-11-2010

[eluser]wdcmatt[/eluser]
I had never considered returning something... that works. (I should have thought of that...)

The reason I posted is because I'm about 30 nested if/else statements in and it was getting very ugly. It is a project with lots of options and quite a few parameters to check. So nested if/else were getting out of control.

Thank you for the input, If nothing else comes up I will use the return statements. Is there a way in code igniter to tell it that I'm done something like $this->output->finished() ?


Output Class Question - El Forum - 03-29-2010

[eluser]wdcmatt[/eluser]
Ok, after a good bit of experimenting, this will not work in the case I need.

I have written a class to extend the Controller class, in the constructor I'm having it perform user validation (session and permissions)... At the end of the constructor I know if someone has permission to do what they are requesting or not... at that point I would like to Stop execution and display a forbidden page (without executing any code in the other controllers)... so here is an example.


Code:
<?php

/*
* class MY_Controller
*/

class MY_Controller extends Controller {
    
    function MY_Controller() {
        parent::Controller();

        // Init the permissions
        $this->getUserGroups();
        
        if($this->getModulePermissions() === FALSE)
        {
            $this->load->view('Forbidden');
            // Terminate script execution and display Forbidden view
        }
        
        // if true allow normal execution...
    }
    
    function getUserGroups()
    {
        // Some SQL data getting user data based on session
    }
    
    function getModulePermissions()
    {
        // Check the user data and see if they can access what they are requesting...
        // return boolean value true/false....
    }
}


I can already perform all checks and get it to display the forbidden page when expected... but it also shows the page they are not supposed to see underneath the forbidden text... I've tried $this->output->set_output(); and even $this->output->set_output($this->output->get_output()); I really need to know how to stop script execution and display what is in the output buffer and stop right there... gracefully...

I do not want to have to put code in every single function to test for permissions, this kinda defeats the purpose of having a central script to do this. Any help is appreciated. I have made good use of the "return" technique above... but in this case a return simply continues the script... right where it needs to stop.

Thanks in advance for any help.

For those of you who want to know here is a sample of how I use the controller.

Code:
/*
* class Blog
*/

class Blog extends MY_Conteroller {
    
    function Blog() {
        parent::MY_Controller();
        
        // all constructor functions
    }
    
    function display_page($id)
    {
        //sql... get data
        $data['content'] = $sql;  // sql data
        $this->load->view('template', $data);
    }
    
}



Output Class Question - El Forum - 03-29-2010

[eluser]wdcmatt[/eluser]
[quote author="wdcmatt" date="1269911339"]Ok, after a good bit of experimenting, this will not work in the case I need.

I have written a class to extend the Controller class, in the constructor I'm having it perform user validation (session and permissions)... At the end of the constructor I know if someone has permission to do what they are requesting or not... at that point I would like to Stop execution and display a forbidden page (without executing any code in the other controllers)... so here is an example.


Code:
<?php

/*
* class MY_Controller
*/

class MY_Controller extends Controller {
    
    function MY_Controller() {
        parent::Controller();

        // Init the permissions
        $this->getUserGroups();
        
        if($this->getModulePermissions() === FALSE)
        {
            $this->load->view('Forbidden');
            // Terminate script execution and display Forbidden view
        }
        
        // if true allow normal execution...
    }
    
    function getUserGroups()
    {
        // Some SQL data getting user data based on session
    }
    
    function getModulePermissions()
    {
        // Check the user data and see if they can access what they are requesting...
        // return boolean value true/false....
    }
}


I can already perform all checks and get it to display the forbidden page when expected... but it also shows the page they are not supposed to see underneath the forbidden text... I've tried $this->output->set_output(); and even $this->output->set_output($this->output->get_output()); I really need to know how to stop script execution and display what is in the output buffer and stop right there... gracefully...

I do not want to have to put code in every single function to test for permissions, this kinda defeats the purpose of having a central script to do this. Any help is appreciated. I have made good use of the "return" technique above... but in this case a return simply continues the script... right where it needs to stop.

Thanks in advance for any help.

For those of you who want to know here is a sample of how I use the controller.

Code:
/*
* class Blog
*/

class Blog extends MY_Controller {
    
    function Blog() {
        parent::MY_Controller();
        
        // all constructor functions
    }
    
    function display_page($id)
    {
        //sql... get data
        $data['content'] = $sql;  // sql data
        $this->load->view('template', $data);
    }
    
}
[/quote]


Output Class Question - El Forum - 03-29-2010

[eluser]cahva[/eluser]
I must be blind but you really have not taken advantage of the return, which will end the execution right there. If you would, it should look something like this:
Code:
if($this->getModulePermissions() === FALSE)
        {
            $this->load->view('Forbidden');

            return FALSE; // Terminate script execution and display Forbidden view

        }



Output Class Question - El Forum - 03-29-2010

[eluser]danmontgomery[/eluser]
Rather than trying to do access control like that in the construct, I would do it in a post_controller_constructor hook... This is what they're for.

http://ellislab.com/codeigniter/user-guide/general/hooks.html

Return will return out of the function, but not a script. Only one controller is executed, I think by "other controllers" you mean other functions...?

If you absolutely need to halt script execution you can use exit() or die(), but that will interrupt codeigniter's execution so you lose any functionality that occurs after the controller construct.


Output Class Question - El Forum - 03-29-2010

[eluser]wdcmatt[/eluser]
cahva: I've tried that... but it still continues script execution. if you place a return statement in the constructor, it simply ends the constructor and goes about it's business...

noctrum: I tried that as well but I was unable to get session variables out at any point during the hook. I thought (at first) hooks would be perfect for this. But after surfing the forums here for about it seems that quite a few people have had problems with it accessing data (I was unable to get session data to work at all in my hook.) In-fact the technique I'm trying now was recommended as the final solution to the problem using hooks and session data. (And yes I am auto-loading 'sessions')

I think (after much reading) There are 2 solutions here is one:

Although I'd like to understand any "side-effects" to doing it... here is what I have...

Code:
if($this->getModulePermissions() === FALSE)
        {
            $this->load->view('Forbidden');
            // Terminate script execution and display Forbidden view
            $this->output->_display();
            exit();
        }

Calling this function "$this->output->_display();" seems to dump everything out to the screen (and exit obviously ends the script).

The second solution seems to be using a hook with the [display_override] value... however I'm afraid (it sounds like) my controller code gets executed, then the output buffer is overwritten and displayed... I have not tried this yet as (according to what I read) the controller will get executed which is what I'm trying to avoid. I will tinker with this some as well. I know the first solution works (_display()), I just discovered the [display_override] option so I'm unsure of it's functionality.

Thanks, any more input is welcome.


Output Class Question - El Forum - 03-30-2010

[eluser]cahva[/eluser]
Sorry about the return thing. Ofcourse it works only in the "normal" controller, not base controller.

But is there a reason why not just do a failure controller and redirect to that? Thats usually how people seem to do it(including myself):
Code:
class MY_Controller extends Controller {
    
    function MY_Controller() {
        parent::Controller();

        // Init the permissions
        $this->getUserGroups();
        
        if($this->getModulePermissions() === FALSE)
        {
            // did not pass permission check, forward to forbidden page
            redirect('forbidden');
        }
        
        // if true allow normal execution...
    }

    ...



Output Class Question - El Forum - 03-30-2010

[eluser]wdcmatt[/eluser]
That is probably the answer I was looking for... looks like I was making it too complicated. I will try it out to make sure but that sounds like exactly what I was looking for. Thanks cahva.