7 min read

Building the database

The last step is to create the database and then create all of the tables. I have created my database called milkshake on the CLI using the following command:

$/home/timmy/workspace/milkshake>mysqladmin create milkshake -u root -p

Now that we have created the database, we need to generate the SQL that will create our tables. Again, we are going to use a Symfony task for this. Just like creating the ORM layer, the task will build the SQL based on the schema.xml file. From the CLI, execute the following task:

$/home/timmy/workspace/milkshake>symfony propel:build-sql

This has now generated a SQL file that contains all of the SQL statements needed to build the tables in our database. This file is located in the data/sql folder within the project folder. Looking at the generated lib.model.schema.sql file in this folder, you can view the SQL. Next, we need to insert the SQL into the database. Again using a Symfony task, execute the following on the CLI:

$/home/timmy/workspace/milkshake>symfony propel:insert-sql

During the execution of the task, you will be prompted to enter a y or N as to whether you want to delete the existing data. As this command will delete your existing tables and then create new tables, enter y. During development, the confirmation can become tiring. To get around this you can append the no-confirmation switch to the end as shown here:

>symfony propel:insert-sql --no-confirmation

Afterwards, check in your database and you should see all of the tables created as shown in the following screenshot:

Symfony 1.3 Web Application Development

I have showed you how to execute each of the tasks in order to build everything. But there is a simpler way to do this, and that is with yet another Symfony task which executes all of the above tasks:

$/home/timmy/workspace/milkshake>symfony propel:build-all

or

$/home/timmy/workspace/milkshake>symfony propel:build-all --no-confirmation

Our application is now all set up with a database and the ORM layer configured. Next, we can start on the application logic and produce a wireframe.

Creating the application modules

In Symfony, all requests are initially handled by a front controller before being passed to an action. The actions then implement the application logic before returning the presentation template that will be rendered.

Our application will initially contain four areas—home, location, menu, and vacancies. These areas will essentially form modules within our frontend application. A module is similar to an application, which is the place to group all application logic and is self contained. Let’s now create the modules on the CLI by executing the following tasks:

$/home/timmy/workspace/milkshake>symfony generate:module frontend home
$/home/timmy/workspace/milkshake>symfony generate:module frontend location
$/home/timmy/workspace/milkshake>symfony generate:module frontend menu
$/home/timmy/workspace/milkshake>symfony generate:module frontend vacancies

Executing these tasks will create all of the modules’ folder structures along with default actions, templates, and tests in our frontend application. You will see the following screenshot when running the first task:

Symfony 1.3 Web Application Development

Let’s examine the folder structure for a module:

Folder

Description

actions

This folder contains the actions class and components class for a module

templates

All modules templates are stored in this folder

Now browse to http://milkshake/frontend_dev.php/menu and you will see Symfony’s default page for our menu module. Notice that this page also provides useful information on what to do next. This information, of course, is to render our template rather than have Symfony forward the request.

Symfony 1.3 Web Application Development

Handling the routing

We have just tested our menu module and Symfony was able to handle this request without us having to set anything. This is because the URL was interpreted as http://milkshake/module/action/:params. If the action is missing, Symfony will automatically append index and execute the index action if one exists in the module. Looking at the URL for our menu module, we can use either http://milkshake/frontend_dev.php/menu or http://milkshake/frontend_dev.php/menu/index for the moment. Also, if you want to pass variables from the URL, then we can just add them to the end of the URL. For example, if we wanted to also pass page=1 to the menu module, the URL would be http://milkshake/frontend_dev.php/menu/index/page/1. The problem here is that we must also specify the name of the action, which doesn’t leave much room for customizing a URL.

Mapping the URL to the application logic is called routing. In the earlier example, we browsed to http://milkshake/frontend_dev.php/menu and Symfony was able to route that to our menu module without us having to configure anything. First, let’s take a look at the routing file located at apps/frontend/config/routing.yml.

# default rules
homepage:
URL: /
param: { module: default, action: index }
default_index:
URL: /:module
param: { action: index }
default:
URL: /:module/:action/*

This is the default routing file that was generated for us. Using the home page routing rules as an example, the route is broken down into three parts:

  • A unique label: homepage
  • A URL pattern: URL: /
  • An array of request parameters: param: { module: menu, action: index }

We refer to each one of the rules within the routing file using a unique label. A URL pattern is what Symfony uses to map the URL to a rule, and the array of parameters is what maps the request to the module and the action. By using a routing file, Symfony caters for complicated URLs, which can restrict parameter types, request methods, and associate parameters to our Propel ORM layer. In fact, Symfony includes an entire framework that handles the routing for us.

The application logic

As we have seen, Symfony routes all requests to an action within a module. So let’s open the actions class for our menu module, which is located at apps/frontend/modules/menu/actions/actions.class.php.

class menuActions extends sfActions
{
/**
* Executes index action
*
* @param sfRequest $request A request object
*/
public function executeIndex(sfWebRequest $request)
{
$this->forward('default', 'module');
}
}

This menuActions class contains all of the menu actions and as you can see, it extends the sfActions base class. This class was generated for us along with a default ‘index’ action (method). The default index action simply forwards the request to Symfony’s default module, which in turn generates the default page that we were presented with.

All of the actions follow the same naming convention, that is, the action name must begin with the word execute followed by the action name starting with a capital letter. Also, the request object is passed to the action, which contains all of the parameters that are in the request.

Let’s begin by modifying the default behavior of the menu module to display our own template. Here we need the application logic to return the template name that needs to be rendered. To do this, we simply replace the call to the forward function with a return statement that has the template name:

public function executeIndex(sfWebRequest $request)
{
return sfView::SUCCESS;
}

A default index template was also generated for us in the templates folder, that is, apps/frontend/modules/menu/templates/indexSuccess.php. Returning the sfView::SUCCESS constant will render this template for us. The template rendered will depend on the returned string from the action. All templates must also follow the naming convention of actionNameReturnString.php. Therefore, our action called index returns the sfView constant SUCCESS, meaning that the indexSuccess.php template needs to be present within the templates folder for our menu module. We can return other strings, such as these:

  • return sfView::ERROR: Looks for the indexError.php template
  • return myTemplate: Looks for the indexmyTemplate.php template
  • return sfView::NONE: Will not return a template and, therefore, bypass the view layer; this could be used as an example for an AJAX request

However, just removing the $this->forward(‘default’, ‘module’) function will also return indexSuccess.php by default. It is worth adding the return value for ease in reading. Now that we have rendered the menu template, go ahead and do the same for the home, locations, and vacancies modules.

LEAVE A REPLY

Please enter your comment!
Please enter your name here