Welcome Guest, Not a member yet? Register   Sign In
Array global between Controllers - Problem.
#1

[eluser]Jinme[/eluser]
I'm try use a array (global) for read permissions in a ACL, and not load anytime this from database, only one in a Login Controller. I refer this topic but don't work for me, some problem in this code?


File: application/libraries/MY_Controller.php

Code:
class MY_Controller extends Controller {

    var $permissions = array();

    function __construct()
    {
        parent::__construct();
    }

}

File: application/libraries/Acl.php

Code:
class Acl extends MY_Controller {

    var $CI;
    
    function Acl() {
        $this->CI =& get_instance();        
    }
    
    function get_permissions() {
        return $this->permissions;
    }

    function set_permissions($permissions) {
        if (is_array($permissions)) {
            $this->permissions = $permissions;
        }
    }

    function resource() {
        return $this->CI->router->class.'/'.$this->CI->router->method;
    }

}

File: application/controllers/login.php

Code:
class Login extends Controller {

    function Login()
    {
        parent::Controller();
        $this->load->database();
        $this->load->model('login_model');
        $permisos = $this->login_model->get_permisos();
        $this->acl->set_permissions($permisos);
    }
    
    function index()
    {
        $permisos = $this->acl->get_permissions();
        print_r($permisos);
        // print Array correctly :)
    }
}

File: application/controllers/test.php

Code:
class Test extends Controller {

    function Test()
    {
        parent::Controller();
        $this->load->database();
        $this->load->model('test_model');
    }
    
    function index()
    {
        $permisos = $this->acl->get_permissions();
        print_r($permisos);
        // print Array empty :(
    }
}

When load Test Controller after the Login Controller the Array $this->permissions is empty, Why? I don't understand.

Thanks in advance!

P.D. Acl is autoload.
#2

[eluser]WanWizard[/eluser]
How do you load the test controller after the login controller?

PHP is stateless, it doesn't remember anything between two requests unless you store it somewhere.
#3

[eluser]Jinme[/eluser]
With redirect, if is a valid login.

More code in login.php:

Code:
function index {

    $permisos = $this->acl->get_permissions();
    print_r($permisos);
    // print Array correctly :)

    // If is valid the user/pass
    $usuario = $this->login_model->get_usuario($correo, $clave);
    if ($usuario) {
        $this->session->set_userdata('ingreso', TRUE);
    }
    if ($this->session->userdata('ingreso')) {
        redirect('test');
    }

}

How make the Array global between all Controllers in my application using Class?
#4

[eluser]WanWizard[/eluser]
You can't.

A redirect is a second HTTP request, and since PHP as said is stateless, it doesn't have any idea that there was a request before.

The normal way for a PHP application to maintain state is to use sessions, and to store everything you want PHP to 'remember' in the session.
#5

[eluser]danmontgomery[/eluser]
Code:
function Acl() {
        $this->CI =& get_instance();        
    }

I'm kind of surprised this is working at all... You're extending the controller class, but overriding the constructor method. You need to add parent::__construct() to this method to call the controller construct
#6

[eluser]Jinme[/eluser]
Code:
function Acl() {
        parent::__construct();
        $this->CI =& get_instance();
    }

When i wrote this, return error in the Login Controller: Fatal error: Call to a member function get_permisos() on a non-object in this line:
Code:
$permisos = $this->login_model->get_permisos();
Before the call to Acl Class. Why? I understand less.
#7

[eluser]danmontgomery[/eluser]
Oh, er...

Acl is a library, not a controller, it shouldn't be extending the MY_Controller class at all, or using parent::__construct
#8

[eluser]WanWizard[/eluser]
Sorry, I missed the session bit in your example.

You use $this->acl, where is the ACL controller loaded? Normally, CI doesn't support multiple controllers or controllers calling controllers. You might want to convert your acl script into a library, that would also solve the MY_controller business and the error message when calling the parent.

Secondly, I don't see in the logic of your test controller a statement that reads back the contents of the session variable. You load the database library, your model, and then the index() method calls acl to get the permissions. Which aren't set, so an empty array is returned.

Convert acl into a library, and then in the constructor retrieve the session variable and store it in permissions so it can be queried by the test controller.
#9

[eluser]Jinme[/eluser]
Yeah, ACL is a library loaded in config/autoload.php, not a Controller, well I'm come back to initial question: How make the Array global between all Controllers in my application or accesible to Acl Class library?

Use Session is not a good idea for a array (it can be long). Note from UserGuide: Cookies can only hold 4KB of data.

Important (for WanWizard) or anybody:
The test.php is that for now... a test, but the real code should be:
Code:
function Test()
{
    parent::Controller();
    $this->load->database();
    $this->load->model('test_model');
    if ($this->acl->isallowed($this->session->userdata('profile_id'))) {
        // Continue
    } else {
        // Not permissions for accesing Controller
        redirect('error');
    }
}
And in the Acl Class, exist a function:
Code:
function isallowed($profile = NULL, $resource = NULL) {
    $allowed = FALSE;
    if ($profile) {
        if (!$resource) {
            $resource = $this->resource();
        }
        foreach($this->permissions as $permission) {
            if (($permission["profile"] == $profile) && ($permission["resource"] == $resource)) {
                $allowed = TRUE;
                break;
            }
        }
    }
    return $allowed;
}

The intention is not call anytime functions accesing to database for read permissions, array is very fast.

I apreciated your new answers again.
#10

[eluser]WanWizard[/eluser]
It's very difficult to help if you keep on changing your story and the example code.

In the end, my explanation remains the same. You need to store it somewhere between requests, it just doesn't magically appear.
If you don't want to store it in a session, and you don't want to store it in the database (session or otherwise), you have to store it in a file. I don't see any other options.




Theme © iAndrew 2016 - Forum software by © MyBB