Adding a post_system hook from inside a controller method in CodeIgniter - codeigniter

I have some code i want to work after the request is sent to the client and closed so i want to add a post_system hook to the system from inside a controller, so the post_system hook runs only when specific method is invoked.
does CodeIgniter allow that in some workaround?
My version is 3.0rc3

It should be possible. One approach is to setup the post_system hook as described in the documentation - $config['enable_hooks'] = TRUE;, define the hook in application/config/hooks.php, and write the hook class.
In the controller that will use the post_system hook define a var that will be used to decide if the hook function should actually run. Set the default value to FALSE in the constructor and set it TRUE in specific method you have in mind.
Check the value of this var in your post_system_hook function. You may want to start by checking that the controller is the one that should be hooked. Let's assume that class is 'Welcome';
post_system_hook_function(){
//the type of $CI will be the name of the controller
if(get_class($CI) !== 'welcome') {
return false;
}
if(! $var_that_flags_do_the_task){
return false
}
//do post system code here
}

i understand that you want to check a controller like if it has permition to be in ther like logged.
you need to enable the hook in your application/config/config.php
$config['enable_hooks'] = TRUE;
Then you need to add this lines in your application/config/hooks.php with the code
$hook['pre_controller'] = array(
'class' => 'PreLogin',
'function' => 'auth',
'filename' => 'PreLogin.php',
'filepath' => 'hooks'
);
in your apllication/hooks/PreLogin.php
class PreLogin{
public function __construct(){
$CI =& get_instance();
$this->CI->load->library('session');
}
public function auth(){
if( ! isset($this->CI->session->userdata('id'))){
$this->CI->session->set_flashdata('error', 'You do not have permission to enter this url');
redirect(base_url(), 'refresh');
}
}
}

Related

Before method with multiple role restrictions

Im curious to know if it is possible to prevent users who don't have a role of owner or administrator from accessing certain controllers in a laravel application?
Yes you can. You can do this with a route filter.
routes.php
Route::group(['prefix' => 'admin', 'before' => 'auth.admin'), function()
{
// Your routes
}
]);
and in filters.php
Route::filter('auth.admin', function()
{
// logic to set $isAdmin to true or false
if(!$isAdmin)
{
return Redirect::to('login')->with('flash_message', 'Please Login with your admin credentials');
}
});
Route filters have already been proposed but since your filter should be Controller specific you might want to try controller filters.
First off, lets add this your controller(s)
public function __construct()
{
$this->beforeFilter(function()
{
// check permissions
});
}
This function gets called before a controller action is executed.
In there it depends on you what you want to do. I'm just guessing now, because I don't know your exact architecture but I suppose you want to do something like this:
$user = Auth::user();
$role = $user->role->identifier;
if($role !== 'admin' && $role !== 'other-role-that-has-access'){
App::abort(401); // Throw an unauthorized error
}
Instead of throwing an error you could also make a redirect, render a view or do basically whatever you want. Just do something that stops further execution so your controller action doesn't get called.
Edit
Instead of using Closure function, you can use predefined filters (from the routes.php or filters.php)
$this->beforeFilter('filter-name', array('only' => array('fooAction', 'barAction')));
For more information, check out the documentation

Trouble using hook in codeigniter

I want to use hook in codeigniter after perticular function of a controller. As per the documentation it will lead the hook to run after all controllers. But i want my hook to run after perticular function.
Please help with some example...
Thank You
If you want to set few function use hook you can add it to them straightly,
If most function use hook then set hook.And judge particular function in hook.
Here is my example:
config/config.php
$config['enable_hooks'] = TRUE;
config/hook.php
// I set the hook type to 'post_system', after rendering page hook execute.
$hook['post_system'] = array(
'class' => 'HookClass',
'function' => 'abc',
'filename' => 'hookClass.php',
'filepath' => 'hooks',
'params' => ''
);
hooks/hookClass.php
class HookClass{
private $particularFunction;
private $CI;
function __construct(){
$this->particularFunction=array('f1','f2');//set particular function name
$this->CI=& get_instance(); //important!get CI class
}
function abc(){
//if method not in particular function array,execute hook
if(!in_array($this->CI->router->method, $this->particularFunction))){
//$this->CI->router->method gets the executing method name
//execute hooks
}
}
}
example_controller.php
class Example_controller extends CI_controller{
function f1(){
//f1 function,and hooks will not execute.
}
function d1(){
//d1 function and hooks will execute
}
}

Codeigniter: Extend CI_Lang class when controller loaded to use &get_instance()

I want to extend my CI_Lang class to get language values from the database. So I created a copy of the CI_Lang file and rewrote the load and construct functions.
private $CI;
function __construct()
{
parent::__construct();
log_message('debug', "Language Class Initialized");
$this->CI = &get_instance();
}
I enabled hooks in the config file and created a new hook:
$hook['post_controller_constructor'] = array(
'class' => 'MY_Lang',
'function' => '__construct',
'filename' => 'MY_Lang.php',
'filepath' => 'hooks'
);
This is working correctly. However, when I try to load languages, it's still using the old functions from CI_Lang and not the extended one. Any ideas?
Ok I found the solution without using any hooks.
First: I had to place MY_Lang.php to 'core' folder.
Second: "$this->CI = &get_instance();" has to be placed in the "load" function and not in the construct.
Hope it helps, its working here. :)

Codeigniter Hooks advance

Hello i am using post_controller hooks to validate user whether logged in or not
But when validation fails i redirect user to login controller....
Now the problem is when it redirect to defaults controller post_controller hooks is called again and in this way infinite loop starts with redirection repeatedly.
i want to call post_controller hook for every controller except login controller....
also is there way that i don't need to load session library again and again because, if user is logged in then it loads session library in post controller as well as via auto-load in config file...
Here is my code
//Hooks
$hook['post_controller'] = array(
'class' => 'is_login',
'function' => 'index',
'filename' => 'is_login.php',
'filepath' => 'hooks'
);
//Is_Login Hook
class is_login {
function __construct(){
$this->CI =& get_instance();
if(!isset($this->CI->session)) //Check if session lib is loaded or not
$this->CI->load->library('session'); //If not loaded, then load it here
}
public function index()
{
$login_id = $this->CI->session->userdata('login_id');
$login_flag = $this->CI->session->userdata('logged_in');
if ($login_flag != TRUE || $login_id == "")
{
redirect(site_url().'/welcome_login', 'refresh');
}
}
}
It seems it is not a good place to use Codeigniter hooks. It is better if you extend the Controller class in your application and in the constructor you can check if user is logged in and redirect to login controller. But no need to extend the login controller from your controller instead extend it from CI_Controller.
I validate logins by hooks without problem. I just generate the login view when logged out and exit the application so that the only thing showing is the login, and the controller (and rest) gets ignored.
There's no need for redirect, really.
if ($this->CI->uri->segment(1) != 'auth') {
//Authenticate
if (empty($user->user_id))redirect('auth');
}

cannot set user data in session codeigniter

please look at this.
The code below is from my model class (using datamapper orm)
function login()
{
$u = new User();
$u->where('username', $this->username)->get();
$this->salt = $u->salt;
$this->validate()->get();
if (empty($this->id))
{
// Login failed, so set a custom error message
$this->error_message('login', 'Username or password invalid');
return FALSE;
}
else
{
// Login succeeded
$data = array
(
'username' => $u->username,
'usergroup' => $u->usergroup->get(),
'is_logged_in' => true
);
$this->session->set_userdata($data);
return TRUE;
}
}
when i do this i get
**Fatal error: Call to a member function set_userdata() on a non-object**
but when i do this instead
$data = array
(
'username' => $u->username,
'usergroup' => $u->usergroup->get(),
'is_logged_in' => true
);
$obj=& get_instance();
$obj->session->set_userdata($data);
It works.
Please what is the right way to get this working ?
Thanks in advance.
your model did not extends CI_Model
after that you have to add constructor to your model
add this code to yours
function __construct()
{
parent::__construct();
$this->load->library('session');
}
Well, you didn't provide enough information.
The first code looks fine, provided that:
You actually load the session class before calling it (you also need to create an encryption key in your configs).
$this->load->library('session');
$this->session->set_userdata($data);
The above code, or your code, is inside a controller, a model or a view.
$this relates to the CI's superclass, in particular to an instance of the Session class, so if you're calling that inside a helper (collection of functions), or inside a library (where you need to create a CI instance first), it won't work.

Resources