MVC Developers Part 2 – Magento Controller Shipping and Hello World

  • mvc php hello world

The Model-View-Controller (MVC) architecture traces its roots back to the programming language Smalltalk and Xerox Parc. Since then, many systems to describe their architecture and MVC. Each system is different, but they all have the goal of separating data access, business logic and user interface code from each other.

The architecture of PHP MVC frameworks, most will look something like this.

1. A URL is intercepted by a PHP file (usually a Front Controller)
2. This PHP file will examine the URL, and coming from a controller name and name of the action (a process often called routing)
3. The controller is derived instantiated
4. The method that matches the name derived action name is mentioned on the controller
5. This action method will instantiate and call methods on models, depending on the request variables
6. The action method will also prepare a data structure of the information is passed to the view
7. The view than HTML, using the information in the data structure received from the responsible

Although this pattern is a major leap forward from the “every page is a php-file” pattern established early, for a number of software engineers, it’s still a hack. Common complaints are

* The Front Controller PHP file still works in the global namespace
* The convention over configuration leads to less modularity.
o URL routing is often inflexible
O controllers are often tied to specific positions
o Even if a system provides a way to override this default, the treaty will lead to applications where it is difficult / not in new fall a new model, view, or controller Implementation without massive re-factoring.

As you probably guessed, the Magento team shares this vision of the world and has a more abstract MVC pattern that looks something like this.

1. A URL is intercepted by a PHP file
2. This PHP file instantiates an application Magento
3. The Magento application instantiates an object Front Controller
4. Front Controller instantiates any number of objects Router (specified in the global configuration)
5. Routers or request URL for a “match”
6. If a match is found, an Action Controller and Action derivative
7. Action Controller is instantiated and the method that matches the name the name of the Action
8. This action method will instantiate and call methods on models, depending on the application
9. This action will then instantiate a Controller Layout Object
10. This layout will object to the request using some variables and properties (also known as “handles”), make a list of block objects that are valid for this request
11. Layout will also call an output method to block certain objects, which a nested rendering (other Blocks Blocks will start)
12. Each block has a corresponding template file. Logic blocks contain PHP, HTML templates and PHP code output
13. Blocks refer directly back to the models for their data. In other words, the Action Controller not they a data structure

We will eventually deal with each part of this request, but for now we are working with the Front Controller -> Routers -> Action Controller section
Hello World

Enough theory, it’s time for Hello World. We go

1. Create a Hello World module in the system Magento
2. Configure this module with routes
3. Take Action Controller (s) on our roads

Create Hello World Module

First, as we did before, we’ll create a directory structure for this module

app/code/local/Alanstormdotcom/Helloworld/Block
app/code/local/Alanstormdotcom/Helloworld/controllers
app/code/local/Alanstormdotcom/Helloworld/etc
app/code/local/Alanstormdotcom/Helloworld/Helper
app/code/local/Alanstormdotcom/Helloworld/Model
app/code/local/Alanstormdotcom/Helloworld/sql

and then a configuration file (config.xml) for the module

PATH: app/code/local/Alanstormdotcom/Helloworld/etc/config.xml
<config>
    <modules>
        <Alanstormdotcom_Helloworld>
            <version>0.1.0</version>
        </Alanstormdotcom_Helloworld>
    </modules>
</config>  

and a file to activate the module

PATH: app/etc/modules/Alanstormdotcom_Helloworld.xml
<config>
    <modules>
        <Alanstormdotcom_Helloworld>
            <active>true</active>
            <codePool>local</codePool>
        </Alanstormdotcom_Helloworld>
    </modules>
</config>  

Finally, ensure the module operates

1. Make your Magento cache
2. In the Magento admin, go to
System-> Configuration-> Advanced
3. Expand “Disable Output Modules (if not)
4. Make sure Alanstormdotcom_Helloworld shows up

Configuring Routes

Next, we configure a route. A route will show a URL in an Action Controller and a method. Unlike other systems PHP MVC, you must explicitly define a route in the global config Magento.

In your config.xml file, add the next chapter

<config>
    ...
    <frontend>
        <routers>
            <helloworld>
                <use>standard</use>
                <args>
                    <module>Alanstormdotcom_Helloworld</module>
                    <frontName>helloworld</frontName>
                </args>
            </helloworld>
        </routers>
    </frontend>
    ...
</config>

We have a lot of new terminology here

What is a <frontend />?

The <frontend /> tag refers to a Magento Area. For now, think of Magento areas as individual applications. The “frontend” Space is the public face Magneto shopping cart application. The “admin” Space is the private administrative console application. The “install” Space is the application you used to install Magento run but the first time.

Why a <routers /> tags if we’re configuring individual routes?

There is a famous quote about IT, often attributed to Phil Karlton

There are only two hard things in Computer Science: cache invalidation and naming things

Magento is suffering from the naming problem in spades. You will find there are many places in the global configuration, and the system in general, the naming conventions seem unintuitive or even ambiguous. This is one of those places. Sometimes the tag <routers> routers configuration information to add, other times it will add configuration information about the actual objects the router to do routing. This goes against our intuition seems at first, but when you start working with Magento more and more, you will begin its world view to understand a little better. (Or in the words of Han Solo, “Hey, trust me!”).

What is a <frontName />?

When a router parses a URL, it is separated as follows

http://example.com/frontName/actionControllerName/actionMethod/

Thus, by defining a value of “Hello World” in tags, we say that we Magento system respond to URLs in the form of want

http://example.com/helloworld/*

Many developers of new Magento confuse this with the front Front Controller Name object. They are not the same. FrontNames belong solely to the routing.

What’s the <helloworld /> tag for?

This label must be the small version of your module name. Our module name is helloWorld, hello World, this tag.

You’ll also notice our front name matches our module name. It is a loose convention to have frontNames match the module names, but it is not a requirement. In fact, a single module to define multiple and thus multiple frontNames.

What’s <module>Alanstormdotcom_Helloworld</module> for?

This module tag, the full name of your module, including its package / namespace name. This will be used by the system controller to find your files.

Create Action Controller(s) for our routes

One last step to go, and we have our Action Controller. Create a file

app/code/local/Alanstormdotcom/Helloworld/controllers/IndexController.php

That contains the following

class Alanstormdotcom_Helloworld_IndexController extends Mage_Core_Controller_Front_Action {
    public function indexAction() {
        echo 'Hello Index!';
    }
}

Clear your config cache, and load the following URL

http://exmaple.com/helloworld/index/index

You should also be able to load

http://exmaple.com/helloworld/index/
http://exmaple.com/helloworld/

You will see a blank page with the text “Hello World”. Congratulations, you’ve setup your first Magento controller!

Where do Action Controllers go?

Action Controllers are to be placed in a module controllers (small c) folder. This is where the system will search for them.

How should Action Controllers be named?

Remember the <module> tag back in config.xml?

<module>Alanstormdotcom_Helloworld</module>

An Action Controller’s name will
1. Start with this string in config.xml (Alanstormdotcom_Helloworld)
2. Followed by an underscore (Alanstormdotcom_Helloworld_)
3. That will be followed by the name of the Action Controller’s (Alanstormdotcom_Helloworld_Index)
4. And finally, the word “Controller” (Alanstormdotcom_Helloworld_IndexController)
All Action Controller needed Mage_Core_Controller_Front_Action as an ancestor.

What’s that index/index nonsense?

As we mentioned earlier, URLs routed Magento (default) as follows

http://example.com/frontName/actionControllerName/actionMethod/

So in the URL

http://exmaple.com/helloworld/index/index

the URI portion “Hello World” is the front name, which is followed by index (the Action Controller name), which is followed by another index, called the action method will be called. (A measure of the index will call the method public function index (){…}. Action

If a URL is incomplete, Magento utilizes “index” as the default, which is why the following URLs are equivalent..

http://exmaple.com/helloworld/index/
http://exmaple.com/helloworld/

If we had a URL that looked like this

http://exmaple.com/checkout/cart/add

Magento would
1. See the global configuration of the unit to the front checkout Name (Mage_Checkout found)
2. Look for the cart Action Controller (Mage_Checkout_CartController)
3. Call the method on the cart addAction Action Controller
Other tricks Action Controller
Let’s try adding a non-standard method to our Action Controller. Add the following code to IndexController.php

public function goodbyeAction() {
    echo 'Goodbye World!';
}

And then go to the URL to test out.

http://example.com/helloworld/index/goodbye

As we extend the Mage_Core_Controller_Front_Action class, we get a number of methods for free. For example, additional elements that URL is automatically included in the key / value pairs for us. Add the following method to your Action Controller.

public function paramsAction() {
    echo '<dl>';
    foreach($this->getRequest()->getParams() as $key=>$value) {
        echo '<dt><strong>Param: </strong>'.$key.'</dt>';
        echo '<dl><strong>Value: </strong>'.$value.'</dl>';
    }
    echo '</dl>';
}

and visit the following URL

http://example.com/helloworld/index/params?foo=bar&baz=eof

You should see each parameter and its value printed.
Finally, what would we do if we wanted a URL that responded to

http://example.com/helloworld/messages/goodbye

Here is our Action Controller is the name of the message, so we had a file on

app/code/local/Alanstormdotcom/Helloworld/controllers/MessagesController.php

with an Action Controller named

Alanstormdotcom_Helloworld_MessagesController

and an Action Method that looked something like

public function goodbyeAction()
{
    echo 'Another Goodbye';
}

And in a nutshell, is how the controller portion of MVC implement Magento. Although a little more complicated than other PHP MVC framework, it is a very flexible system that allows you to almost any URL structure to build you want.

(Based on Alanstorm Turtorial)

Comments

Leave a Reply

Your email address will not be published.

twenty − fourteen =

Security Code: