Zend: Execute something before a controller is executed - php

In my Zend framework project I want to check whether a cookie is set. If it is the case I want to use the cookie contents to login a user.
Since it is neccessary for me to do this automatic login before any controller is called I tried to put it in the Bootstrap. There I want to check the database if the user information is valid. Unfortunately at this point the default database adapter is not yet initialized.
So my question is the following: Where do I put those stuff that should be executed before any controller is called and after all initializing/bootstrapping stuff is done?

I'have not a great experience with Zend Framework but I think you should create a custom generic controller for example GenericController that extends the Zend_Controller_Action and put your code in the preDispatch() function. All your controllers will then a subclass of your custom controller, for example:
class GenericController extends Zend_Controller_Action{
function preDispatch(){
parent::preDispatch();
// put your code here
}
}
class FooController extends GenericController{
...
}

Use the methods:
init()
// and
preDispatch()
implement them in your class, init runs at creation, predispatch runs right before your action method iirc
api
On that page I linked above it states
Note: Usage of init() vs. preDispatch()
In the previous section, we introduced the init() method, and in this section, the preDispatch() method. What is the difference between them, and what actions would you take in each?
The init() method is primarily intended for extending the constructor. Typically, your constructor should simply set object state, and not perform much logic. This might include initializing resources used in the controller (such as models, configuration objects, etc.), or assigning values retrieved from the front controller, bootstrap, or a registry.
The preDispatch() method can also be used to set object or environmental (e.g., view, action helper, etc.) state, but its primary purpose is to make decisions about whether or not the requested action should be dispatched. If not, you should then _forward() to another action, or throw an exception.
Note: _forward() actually will not work correctly when executed from init(), which is a formalization of the intentions of the two methods.

Related

yii2 - can someone explain the meaning of parent::init(); statement

I have looked online for the meaning of parent::init(); . All I was able to find was that init() is to initialize some settings which want to be present every time the application runs.
Can anyone please explain the meaning of parent::init() in exact sense, like significance of both the words?
Thanks in advance.( I am sorry if its too simple! )
When we use parent::init(), we are just calling the parent method (in this case init()) inside a method of the current class.
About parent::
For example, let's say we have a class called MyClass. This class have a awesome method that runs alot of things:
class MyClass
{
public function runStuffs()
{
// trigger events, configure external stuff, adding default values to properties.
}
}
Now, after some time, we decided to create a new Class that extends from the first one. And we called MySecondClass:
class MySecondClass extends MyClass
{
}
It already have the method runStuffs(), but, for this second class, we need to do more things in this method, but maintaining what it have.
Sure we could rewrite the whole method and just copy and paste what we have in MyClass and add the new content. But this isn't elegant or even a good practice. what if later on We change the method in MyClass, you probably would like that MysecondClass have that changes too.
So, to solve that problem, we can call the parent method before write your new content:
class MySecondClass extends MyClass
{
public function runStuffs()
{
parent::runStuffs();
// do more things!
}
}
Now MySecondClass->runStuffs() will always do what its parent do and, after that, more stuff.
About the init() method.
init() is a method used in almost all classes from Yii2 framework (since most of then extends from yii\base\Object at some point) and works just like the __constructor() method (native from PHP). But there is some differences, you can read more here.
Actually the init() method is called inside the __constructor(), and the framework encorage us to use init() instead of __construct() whenever is possible.
Now if both are pretty much the same thing, why do they create this method? There is an answer for that here. (take a look at qiang's answer, from the dev team):
One of the reasons for init() is about life cycles of an object (or a component to be exact).
With an init() method, it is possible to configure an object after it is instantiated while before fully initialized. For example, an application component could be configured using app config. If you override its init() method, you will be sure that the configuration is applied and you can safely to check if everything is ready. Similar thing happens to a widget and other configurable components.
Even if init() is called within constructor rather than by another object, it has meaning. For example, in CApplication, there are preInit() and init(). They set up the life cycles of an application and may be overridden so that the customization only occurs at expected life cycles.
Conclusion
So, when you use a init() method and calls parent::init() you are just saying you want to add more things to that method without removing what it already was doing.
The parent::init(); Method is useful to execute a code before every controller and action,
With an init() method, it is possible to configure an object after it is instantiated while before fully initialized.
For example, an application component could be configured using app config.
If you override its init() method, you will be sure that the configuration is applied and you can safely to check if everything is ready.
Similar thing happens to a widget and other configurable components.
In Yii, init() method means that an object is already fully configured and some additional initialization work should be done in this method.
For More Information check this link :
https://stackoverflow.com/questions/27180059/execute-my-code-before-any-action-of-any-controller
Execute my code before any action of any controller
might be helpful to you.

In CakePHP, where would I put a method that performs a check on the Session User?

Background: I have a method levelCheck() which compares the current user's level to a few parameters, and returns a true or false. I need to be able to access this method from any controller, and I would also like to put a call to it inside a helper for use on menus, etc.
Question: Due to Cake's flexibility, I can call almost anything from almost anywhere with Cake. Where is the correct place to put this? In a custom Session (extended)? In the AppController? A new component dealing with the current user? In the UserModel or User Controller?
The important piece here is how would I (or others) determine the correct location for such a thing in the future?
Put this method in AppController
class AppController extends Controller
{
function levelCheck(){
# whatever
}
}
This is the correct place of this action. Because AppController is extended in all the controller so this method can called using current controller object that is $this->levelCheck().
On AppController
function beforeFilter()
{
$this->custome_componnetst_name->levelCheck(parameters.....);
/*action*/
}

CodeIgniter Controller Constructor

I'm very new to codeigniter ,
I wanted to know what is the meaning of a constructor in a controller . I saw the following code in a codeigniter tutorial -
class upload extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->helper(form);
}
// rest of the class...
My question is when is the constructor invoked - is it called every time the controller serves a request (e.g the controller class is instantiated for each request it receives?)
Well, that's a more general PHP question. Anyway, yes, the magic method __construct() is called (automatically) upon each instantiation of the class, as you can see in the manual: http://www.php.net/manual/en/language.oop5.decon.php
Usually, in CI is not necessary to call a constructor, unless you actually want one. In the example you posted, the code loads the helper on every instantiation of the class - which is the same as loading the helper in every method, just saves a lot of typing and ensures it's not forgotten. You can alternatively put the library/helper/model you want to have alywas loaded in the respective autoload array in config/autoload.php (check "autoloading" in CI's manual)
Once you define a constructor in your child Controller you're compelled to call the parent constructor (of the mail CI_Controller class), because there is where the main CI object is created and all the classes are loaded, and you need those in your child controller too; if fail to do so your child class will construct separately and won't inherit.
I hope I made myself clear, english is not my mothertongue :)
the constructor is magic Literally its called a magic method.
what makes the constructor cool is that it will do things for you BEFORE any of the methods. So if you have an admin class, and someone should be logged in in order to access it - you can check for login in the constructor and bounce them out if they are not authorized.
in the constructor you can load the models, libraries, helpers, etc that your class needs, and they will be available for any method in the class.
you can load in variables that are used by methods. this is really useful for models.
Don't use _construct() function in latest apache & codeigniter
Use helperlin in index() function
That's a general question. Constructor is a function that is automatically called when instantiated. this function helps us to intialize the things that we are going to need frequently in our code like when we have to load the models of helpers like form e.t.c.
$this->load->model('Model_name');
now when you write this line in your constructor you don't need to load this model again and again in your methods of that class.

Handling incorrect method (controller) parameters In Codeiginiter or other MVC

I'm codeing in codeigintier but this question equally applies to any MVC framework.
How do I abstract the logic for determining if a parameter for a controller method is valid across mutlple methods that take some of the same parameters?
EDIT: More detail
For example in the application I'm building at the moment there are multiple 'sites' and nearly all the data in different tables belongs to a site and a user can only view a subset of the sites. So lots of my methods start method($site_id,...) so it would be really nice if I was able to have a pre_controller hook which could look at the parameters for the methods and detect if there was a $site_id in the parameters, and if there was check the permissions.
The problem is that not all the methods in those controllers will all have a $site_id parameter, so I cannot do the checking automatically in the constructor of my extension of CI_Controller
For CodeIgniter one way of going about abstracting the logic is to create a super class as such:
class MY_Controller extends CI_Controller
{
public function __construct()
{
parent::__construct();
//...do stuff...
}
//...do stuff...
}
/* End of file MY_Controller.php */
/* Location: ./application/core/MY_Controller.php */
All your controllers that you want to share the same logic should then extend MY_Controller instead of CI_Controller
Now in your MY_Controller you can create functions to "handle incorrect parameters across multiple methods".
UPDATE
Your controller function params are coming from your route. e.g. mydomain.com/mycontroller/myfunction/param1/param2/ would go to the mycontroller public function myfunction($param1, $param2)
$site_id is just your variable naming. You can't tell what it's named and even if you could i doubt it's a good idea to based any logic on how you name your variables.
A simple way is just to explicitly call the validating function (stored once in your base controller, a library or a helper) in each controller's function that require it, that gives you fine grain control.
UPDATE
Extending the controller would only work if my parameters were the same for each method. I'd like to detect automatically the parameters and perform checks. I suppose a call to a helper might be the best I can do, but Id just like to be able to completely abstract it away from the method. I suppose one option would be to have an array of which controllers and methods have $site_id as their first parameter and have a pre_controller hook to do the checking. But this would mean keeping the array up-to-date which kind of defeats the object of my question which is to make things as DRY as possible!
Generally, to gain automation you must give up flexibly and follow conventions.
so to not go the "use helper" way and to go the auto detect way... create your own convention.
in your base controller use $this->uri->segment(n) to check if a certain URL pattern exist, if it does you know that the site_id param is incoming and that you can run automatic validation on it.
Extend the same controller and do some validation in a preDispatch or init method.
Or abstract the validation into a controller-helper and use it in both controllers.

Zend Framework: What are the differences between init() and preDispatch() functions in controller objects?

I think the order of execution is init(), preDispatch() and then action() is called.
Should I initialize my variables, which are common among all actions, in init() or preDispatch()? I've seen people using both functions for initialization. Probably as the name suggests it should be done in init() but then what kind of stuff would go in preDispatch()?
What happens between init() and preDispatch() function calls?
First preDispatch() is called for instances of Zend_Controller_Plugin_Abstract. Here you have the request and response objects, so you might filter the request or do some preparation using the information from the request.
init() of the Zend_Controller_Action is called next as part of the constructor. It's there to help you initialize your controller, without having to override and repeat the signature of the constructor (Zend_Controller_Action::__contruct()).
The controller's preDispatch() method is called here. You can call $request->setDispatched(false) to skip the current action - not sure if you can do that in init()
Then your action method is called (viewAction() for example). Here you do your normal work like fetching stuff from the model and populating the view.
So the distinction should now be clear:
If you want something to be executed before all actions - put it in a plugin and use one of the hooks (besides preDispatch() there is routeStartup and others),
if you want before every action in a controller - init or preDispatch(),
if only for a single action - the action itself.
What happens between init() and preDispatch() function calls?
Almost nothing - preDispatch() is executed, and if you haven't called $request->setDispatched(false), the action is executed.
The init() method is primarily intended for extending the constructor. Typically, your constructor should simply set object state, and not perform much logic. This might include initializing resources used in the controller (such as models, configuration objects, etc.), or assigning values retrieved from the front controller, bootstrap, or a registry.
The preDispatch() method can also be used to set object or environmental (e.g., view, action helper, etc.) state, but its primary purpose is to make decisions about whether or not the requested action should be dispatched. If not, you should then _forward to another action, or throw an exception.
Note: _forward actually will not work correctly when executed from init(), which is a formalization of the intentions of the two methods.
init(): Loaded before functions, So if you want to load it before all functions of project, Put it at bootstrap Class. If before a specified class functions, Put it at init() this class function.
preDispatch(): Loaded before the front Controller.

Categories