Front Controller Pattern

Magento Front Controller

Magento uses the Front Controller pattern for the following purposes:

  • Receiving and processing browser data, transferring it to other system elements;
  • Defining controller and proper action to perform using routes;
  • Displaying browser-requested data using blocks, templates and model data.

Front Controller main structure is stored in Core module:
Mage/Core/Controller/Varien/Front.

Let’s review the basic steps of Front Controller initialization.

The first call is performed in Mage_Core_Model_App constructor:

wherein getFrontController method is called. Before current request processing starts, Mage_Core_Controller_Varien_Front object is created and its initialization is called.

Let’s take a closer look at the init method:

Controller_front_init_before event is initially called:

It can be used to set the $routerInfo[‘disabled’] flag and to determine routes your way.

Next, routes, determined in config.xml in web/routes section (global configuration), are selected. At this application initialization stage, these are admin and standard sections, i.e. admin routing areas are determined:

(Mage_Core_Controller_Varien_Router_Admin) and standard (Mage_Core_Controller_Varien_Router_Standard):

Next, all active modules are processed and specified ones are added to their routes configurations:

Next, controller_front_init_routers event is called:

With the help of this event CMS module adds CMS routing area. We add our own routes as well.

Specified event:

method itself:

Default route is added after all (Mage_Core_Controller_Varien_Router_Default):

At the end we have routs processing order:

admin

standard

cms

default

Module route is determined in its config.xml

For a frontend:

Frontend and Admin routs should differ.

After routes are formed, current browser request processing route is being determined (dispatch).

Main application address is checked:

Basic variables are prepared and flag of route correspondence in false is set. It determines if search should be continued or finished.

Rewrite is chosen from the database for the current request:

If there is a match, the address, corresponding to this rewrite, is followed. This is the custom url mechanism.

We also loop through rewrite, determined in global/routes configuration section:

Rewrite controllers are determined here:

Next, corresponding controller is determined and required action is performed:

Match search among all the known routes $this->_routers is performed.

As soon as controller match is found, it is initialized and specified action or default action is performed (unless the action is determined directly in the request). Our later articles will explain routes as well as routes processing in greater detail.

As may be seen from the source code, the maximum number of attempts may not exceed 100.

Next, current request contents, including events before and after displaying setting, are prepared to be sent to the browser. Displaying can be prepared and changed in them correspondingly:

 

Application Initialization (Magento Certified Developer Exam)

Application initialization

Magento initialization process starts in index.php (with the exception of Magento integrated with some other sites or CMS).

Let’s take a look at the code of this file. Magento developers made their comments using multi line comment and PHPDoc style comments, so for my own comments I’ll use one line style (so called c++ style) comments.

index.php

 

Now we should dig into app/Mage.php. It contains about 1000 lines (to be precise, it’s 989), so we will explore the most important things only. However, I think it’s a good idea for you to open it and analyze the whole file.

At the beginning of the file Magento checks if Compilation mode was enabled. If compiler is not enabled, Magento will include default paths, load code pools, load app/code/core/Mage/functions.php (if it’s not overwritten in local or community pool), load lib/Varien/Autoload.php and finally call Varien_Autoload::register() method.

app/Mage.php

 

In register() method from lib/Varien/autoload.php system registers auotload using PHPspl_autoload_register which “registers a function with the spl provided __autoload stack. If the stack is not yet activated, it will be.”

 

Finally, Magento executes autoload method, which loads all class source codes (and again: depending on whether Compilation mode enabled or not it could go different ways).

 

So now we know that when Mage.php is included in index.php file, the include path set up and the auto loader is registered. After that, we can instantiate Models, Helpers and Blocks using static factory methods on the global Mage class (like Mage::getModel(‘catalog/product’))

As you remember, on the last line of index.php there was a call to Mage.php run() method (below I only put ‘try’ piece of this method without catch part). This is an entry point of front end rendering: request and response setters, initialization of global observers collection, etc.

 

Next, have a look at Mage_Core_Model_App::run() where most of app initialization work is done, i.e. config loading, request and routing initialization – so this method can be called the heart of application initialization process!

app/code/core/Mage/Core/Model/App.php

 

In this method, Magento calls $this->baseInit($options), which in turn loads Mage::getConfig and _init that initializes base system configuration (local.xml and config.xml files) (base configuration provides ability to initialize DB connection and cache backend) by calling loadBase in app/code/core/Mage/Core/Model/Config.php.

 

After we loaded local.xml and config.xml files, Magento runs _initModules() of the same class. It, by-turn, initializes active modules configuration and data via Mage_Core_Model_Config::loadModules(). In this loadModules method, Magento loads all active modules from “etc” folders and combines data from the specified xml file names to one object with the help of loadModulesConfiguration().

Then system executes setup scripts via Mage_Core_Model_Resource_Setup::applyAllUpdates() and loads config data from DB via Mage_Core_Model_App::loadDb()

After that, request/store initialization happens

 

And finally we have $this->getFrontController()->dispatch() So routing here is the domain of front controller. We already have the article on front controller pattern by Aleksander Tretjak describing its work in details.

I think that it’s always better to have a look into the source code to understand how things work, but in this case it’d be very helpful to see this request flow on the image. Here is a Magento request flow made by Pavel Novitsky.