In CakePHP we have beforeFilter and afterFilter to run methods before or after any controller methods (e.g. save log or check logged in etc.)
How can I do this in CodeIgniter?
You'll want to make use of hooks in Codeigniter, that is where they have implemented your desired functionality of running code before certain points of the framework code.
https://www.codeigniter.com/user_guide/general/hooks.html
There are some built-in hooks that allow you to call a method or class at various points during the request:
pre_system
pre_controller
post_controller_constructor
post_controller
display_override
cache_override
post_system
So what you want is probably something like pre_system or pre_controller.
Check out the _remap() function. It allows you to redirect to your own function before calling the normal controller function. You can include your own _remap function in your controller like this (copied from the User Guide):
public function _remap($method)
{
if ($method == 'some_method')
{
$this->$method();
}
else
{
$this->default_method();
}
}
The second segment of the URI gets passed to the _remap function as a parameter (in the example as $method), and you can then redirect the process however you need.
Related
Hi I have a class which includes two methods.
One of which is to initialize session , another one is for redirect the web page
I ve written the class such that it can be called repeatedly.
$obj->setSession(key,value)->redirect(url);
In this mode , the session is firstly initialized and then it redirects to the next page.
But if it's written like this
$obj->redirect(url)->setSession(key,value);
It just redirects to the defined location qnd the session is not initialized anymore ..
It s cuz when the resirect method is called, the page changes promptly and it causes the second method not to be called ..
Is there any way to be able to call methods repeatedly without the need of considering their order ?
When I usually face that issue, I add a method in the $obj object called render() or done() or something to that effect that checks all the flags I might have defined previously. One of those flags might be a header flag, which is what a redirect method usually does header(Location: $yourDestUrl).
So you end up with something like:
$obj->redirect(url)->setSession(key,value)->render();
When you call a method such as redirect or setSession, put those actions in a "stack" as a property of you class.
Then, when all your methods are called, call a method called exec (for example) that will execute all the actions in the "stack".
Here is a base class based on this idea using magic methods:
class Stack {
private $_stack = array();
public function __call($method, $args) {
// Adding method to stack
$this->_stack[$method] = $args;
return $this;
}
public function __isset($name) {
// Checks if method is in stack
return isset($this->_stack[$name];
}
public function exec() {
// setSession is executed first
if (isset($this->setSession))
call_user_func_array('setSessionMethod', $this->_stack['setSession']);
// redirect is executed second
if (isset($this->redirect))
call_user_func_array('redirectMethod', $this->_stack['redirect']);
}
}
To use this class, you would do:
$stack = new Stack;
$stack->redirect('arg')
->setSession('arg1', 'arg2')
->exec();
public function _remap($method)
{
if ($method == 'some_method')
{
$this->$method();
}
else
{
$this->default_method();
}
}
This is what i read from official site. As i understand _remap method is getting called before all actions. But this instruction $this->$method(); means that calling $method will call _remap again and it is being something like cycle. Isn't it?
No, _remap is called by the framework, during the init, but when you call some method directly, you only execute the function content...
Hope it's helpful!
Some explanation found here:
Important: If your controller contains a function named _remap(), it will always get called regardless of what your URI contains. It overrides the normal behavior in which the URI determines which function is called, allowing you to define your own function routing rules.
In Codeigniter, there are library and helper.
I can access controller and its sub function.
for eample.
login/getid
Is there any way to access library or helper through url?
Update :
I made a captcha library in login controller.
I want to use it in many other controller's view.
in view file, the captcha code should be like this,
<img src="/login/get_captcha" />
everytime I want to use captcha, I have to call login controller.
So, I thought that there should be better way to do this.
If library or helper can access through url, I can make this to helper.
can access another controller's view without loading login's controller.
You can create a wrapper controller to access those functions exclusively and use your routes to utilize said URL's
Example: yoursite.com/helper/geo/citiesNearZip/90210
class helperController extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->helper($this->uri->segment(1)); // geo helper in this example
if($this->uri->segment(2))
{
$helper_method = $this->uri->segment(2);
}
else
{
show_404();
return false;
}
// check if helper has function named after segment 2, function citiesNearZip($zip) in this example...
if(function_exists($helper_method)
{
// Execute function with provided uri params, xss filter, secure, etc...
// You would also want to grab all the remaining uri params and pass them as
// arguments to your helper function
$helper_method();
}
}
}
Nope. This is simply not the way the framework was designed to work.
If you think you have to access a helper/library directly, then you're probably doing something wrong.
Can explain what you're trying to do? There must be a better way.
Are functions inside of models directly accessible by users?
Can a user pass arguments directly to a function in a model? Or, do arguments have to be passed through php?
In otherwords:
I have a model called notifications and in there a function called get_notifs($user)... I use the controller to call the function like the get_notifs($_SESSION['user_id']) (which is encrypted). I don't want someone to be able to call get_notifs() with anything but their $_session as a argument. What is the best solution?
Am I already okay?
Should I rename get_notifs() to
_get_notifs()?
Should I check the
$_SESSION['user_id'] in the method
itself?
Or, is there another better solution
than any of these?
I have a controller: ajax.php which loads the model notification
function __construct()
{
parent::__construct();
$this->load->helper('url');
$this->load->library('tank_auth');
$this->load->model('notification');
$this->load->model('search');
}
function get_notifs()
{
$me = $this->session->userdata('user_id');
if ($e = $this->notification->get_notif($me))
{
...........
}
else{
echo "nothing was found wtf?";
}
.........................................................
model: notification.php
function get_notifs($user){
......
}
Your code is perfectly fine!
Am I already okay?
I Think so
Should I rename get_notifs() to _get_notifs()?
No, it's a public method so no need to make it look private.
Should I check the $_SESSION['user_id'] in the method itself?
No, this is the controller's job
Or, is there another better solution than any of these?
You only need a solution to a problem, and i don't see a problem here
it sounds liek your application may be used by people other then yourself, i.e the public developers, why would you want enforce developers to code things your way, that's going to make them upset at your application.
CI Only routes requests to a controller, the user cannot access a model or library or any other class, the route goes like so: /controller/method/param
the first segment will only ever load a controller file, the second will call the method in the param, passing any other variables such as param to that method.
Source: http://codeigniter.com/user_guide/overview/appflow.html
As you can see from the flow chart above, only the controller has access to the model's
If you'll only use it while in a session the best way would be this:
function get_notifs(){
if(!isset($_SESSION['user_id'])){
return false;
}
$user = $_SESSION['user_id'];
/* Your code here */
}
There's no point of requiring an argument when you'll only use the function with one specific variable which is also available globaly.
Edit: I don't know why you're using functions in your models. Doesn't make any sense, do you mean methods?
I have a class in codeigniter which deals solely with ajax. I have created a function within this class which checks if the refferal is an ajax refferal, I want to be able to call this function every time that any function from this class is used.
As such I've implemented the __call magic method
class Ajax_content extends Controller {
function __construct()
{
parent::Controller();
}
function __call($method, $arguments){
$this->ajaxCheck(); //set up to return false and exit.
call_user_func_array(array($this,"_".$method),$arguments);
}
At present ajaxCheck() always returns false and exit()s. But it's not being called (at present my ajax request still returns data) Is this a valid way of approaching the problem?
I want to be able to call this
function every time that any function
from this class is used
__call is only triggered when invoking inaccessible methods. If you want certain functionality to be executed every time a controller method is called (and by that, I assume you mean a method that's mapped to a web request, not any function in the class), you should put this functionality in the constructor.
If you want a method to run before any method instead of use magic php __call in codeigniter controller you can use Remaping method for codeigniter
public function _remap($method)
{
// call and start a method before any other method in codeigniter controller
}
for more info see this page