Symfony Learning Note (1)

Project structure

A symfony project is made of applications.

An application is devided into modules.

Symfony data model

1. Database schema:

# config/doctrine/schema.yml

2. Database:

$ mysqladmin -uroot -p create jobeet

Enter password: ********

$ php symfony configure:database

“mysql:host=localhost;dbname=jobeet” root mYsEcret

3. ORM (Object Relational Model)

a. Model

$ php symfony doctrine:build –model

For each table generate three classes:

1)      JobeetJob.php

An object of this class represents a single of record of the JobeetJob table. This class is empty by default.

2)      BaseJobeetJob.php

The parent class of JobeetJob. Each time you run command doctrine:build –model, this class is overwritten, so all customizations must be done in the JobeetJob class.

3)      JobeetJobTable.php

This class defines methods that mostly return collections of JobeetJob objects. This class is empty by default.

b. SQL (data/sql/)

$ php symfony doctrine:build –sql

c. Insert SQL

$ php symfony doctrine:insert-sql

d. All compelete command

$ php symfony doctrine:build –all –and-load

4. Module

$ php symfony doctrine:generate-module –with-show –non-verbose-templates frontend job JobeetJob

The layout

The decorator design pattern: the template is decorated after the content is rendered by a global template, called layout in symfony.

Helper function:

# apps/frontend/templates/layout.php

include_stylesheets() –> apps/frontend/config/view.yml

# apps/frontend/config/view.yml

stylesheets: [main.css]

has_layout: true

layout: layout –> decorates every page with layout.php

Configuration Principles in symfony

For many symfony configuration files, the same setting can be defined at different levels:

• The default configuration is located in the framework

• The global configuration for the project (in config/)

• The local configuration for an application (in apps/APP/config/)

• The local configuration restricted to a module (in apps/APP/modules/MODULE/config/)

View configuration

is made by one of or both:

1)      view.yml

2)      use_stylesheet()

The Action



<?php include_slot(‘title’) ?>

<?php echo get_slot(‘title’) ?>

<?php include_stylesheets() ?>

<?php echo get_stylesheets() ?>


Object route class

# jobeet\frontend\config\routing.yml:


url:      /job/:company_slug/:location_slug/:id/:position_slug

class:    sfDoctrineRoute

options:  { model: JobeetJob, type: object }

param:    { module: job, action: show }


id: \d+

sf_method: get

# jobeet\frontend\modules\job\template\indexSuccess.php:

object > route > url

<a href=”<?php echo url_for(array(‘sf_route’ => ‘job_show_user’, ‘sf_subject’ => $job)) ?>”>;

<a href=”/frontend_dev.php/job/sensio-labs/paris-france/1/web-developer”>Web Developer</a>


<?php echo link_to($job->getPosition(), ‘job_show_user’, $job) ?>

<a href=”/job/sensio-labs/paris-france/1/web-developer”>Web Developer</a>

# jobeet\frontend\modules\job\actions\actions.class.php:

url > route > object

public function executeShow(sfWebRequest $request) {

$this->job = $this->getRoute()->getObject();


If you want to generate a URL from an action, you can use the generateUrl() method:

$this->redirect($this->generateUrl(‘job_show_user’, $job));

Route Debugging

$ php symfony app:routes frontend

$ php symfony app:routes frontend job_edit

More with the Model

Custom Configuration

# apps/frontend/config/app.yml:


active_days: 30

in the application: sfConfig::get(‘app_active_days’)

Dynamic Fixtures

# data/fixtures/jobs.yml:


# Starts at the beginning of the line (no whitespace before)

<?php for ($i = 100; $i <= 130; $i++): ?>

job_<?php echo $i ?>:

JobeetCategory: programming

company: Company <?php echo $i.”\n” ?>

position: Web Developer

location: Paris, France

description: Lorem ipsum dolor sit amet, consectetur adipisicing elit.

how_to_apply: |

Send your resume to lorem.ipsum [at] company_<?php echo $i ?>.sit

is_public: true

is_activated: true

token: job_<?php echo $i.”\n” ?>


<?php endfor ?>

Secure the Job Page

# apps/frontend/config/routing.yml:


url:      /job/:company_slug/:location_slug/:id/:position_slug

class:    sfDoctrineRoute


model: JobeetJob

type: object

method_for_query: retrieveActiveJob

param:    { module: job, action: show }


id: \d+

sf_method: [GET]

# lib/model/doctrine/JobeetJobTable.class.php:

class JobeetJobTable extends Doctrine_Table {

public function retrieveActiveJob(Doctrine_Query $q) {

$q->andWhere(‘a.expires_at > ?’, date(‘Y-m-d H:i:s’, time()));

return $q->fetchOne();



Final Thoughts

Playing with the Category Page

Whenever you start implementing a new feature, it is a good practice to first think about

the URL and create the associated route. And it is mandatory if you removed the default

routing rules.

  1. The category route: route.yml
  2. The category link: indexSuccess.php
  3. The category actions
  4. Job Category Module Creation: symfony generate:module frontend category
  5. Templates

The process to add a new feature to a symfony website is always the same:

1) think about the URLs,

2) create some actions,

3) update the model, and

4) write some templates.


// apps/frontend/modules/job/templates/_list.php:

<?php foreach ($jobs as $i => $job): ?>

// in apps/frontend/modules/job/templates/indexSuccess.php

<?php include_partial(‘job/list’,

array(‘jobs’ => $category->getActiveJobs(

sfConfig::get(‘app_max_jobs_on_homepage’)))) ?>

–          Is snippet of template code that can be shared among several templates

–          Starts with an underscore ( _ )

–          Include using include_partial(args1, args2)

–          First argument: [module name]/[partial name]. Eg. “job/list”

–          Second argument: an array of variables to pass to the partial

The Forms

How to:

  1. Define a widget: options, attributes
  2. Define validators for a widget: options, messages
    1. Logical operations of validators
    2. Pre and post validators
    3. Render a widget of a field: label, tag, error
    4. Render global errors
    5. Render hidden fields

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s