TRAJOIN is an Application to Translate symfony documents Jointly.
home > 1.2/jobeet/en > 03.txt
[1] Edit ↑TOPThose of you itching to open your text editor and lay down some PHP will be happy to know today's tutorial will get us into some development. We will define the Jobeet data model, use an ORM to interact with the database, and build the first module of the application. But as symfony does a lot of the work for us, we will have a fully functional web module without writing too much PHP code.
sfDoctrinePluginIf you're reading this then you've decided to complete the Jobeet tutorial for
the ~Doctrine~ ~ORM~ instead of Propel. This is simple as all you need to do first
is enable sfDoctrinePlugin and disable sf#PropelPlugin. This can be done with
the following code in your config/ProjectConfiguration.class.php.
public function setup()
{
$this->enablePlugins(array('sfDoctrinePlugin'));
$this->disablePlugins(array('sf#PropelPlugin'));
}
If you prefer to have all plugins enabled by default, you can do the following:
public function setup()
{
$this->enableAllPluginsExcept(array('sf#PropelPlugin', 'sfCompat10Plugin'));
}
After this change you will get an error until we configure theconfig/databases.ymlfile at a later step to usesfDoctrineDatabase.
After making these changes be sure to clear your cache.
$ php symfony cc
As we will see later in the tutorial, each plugin can embed ~assets|Assets~ (images,
stylesheets, and JavaScripts). When installing or enabling a new plugin, we
should install them via the plugin:publish-assets task:
$ php symfony plugin:publish-assets
We also need to remove the web/sf#PropelPlugin directory:
$ rm web/sf#PropelPlugin
Another recommendation when using Doctrine instead of Propel is to remove theconfig/propel.iniandconfig/schema.ymlso you have a clean installation with no references to Propel.$ rm config/propel.ini $ rm config/schema.yml
昨日説明したユーザストーリーではプロジェクトの主なオブジェクトについて説明しています。それはjobs, affiliates, categoriesです。下図は対応するエンティティ関係図です。:

ストーリーで説明したカラムに加えて、いくつかのテーブルには created_at フィールドも追加しています。symfonyはそのフィールドを見分けて、レコードが生成されたとき現在のシステム時刻を値としてセットします。updated_at フィールドも同様なものです。レコードが更新されるとシステム時刻をセットします。
jobs, affiliates, categoriesを保存するために、当然リレーショナルデータベースが必要となります。
But as symfony is an Object-Oriented framework, we like to manipulate ~object|OOP~s whenever we can. For example, instead of writing SQL statements to retrieve records from the database, we'd rather prefer to use objects.
リレーショナルデータベースの情報はオブジェクトモデルとしてマッピングされなければなりません。これはありがたいことにORMツールを使って実現でき、symfonyでは2つのORM(PropelとDoctrine)をバンドルしています。このチュートリアルではPropel or Doctrineを使っていきます。
ORMはテーブルと生成する関連クラスとの関係を説明が必要です。スキーマの記述には2つの方法があります。それは既存のデータベースから作る方法と、手書きで作る方法の2つです。
Some tools allow you to build a database graphically
(for instance Fabforce's Dbdesigner)
and generate directly a schema.xml (with DB Designer 4 TO Propel Schema
Converter).
As the database does not exist yet and as we want to keep Jobeet database
agnostic, let's create the schema file by hand by editing the empty
~config/schema.yml|Database Schema~ file:
# config/schema.yml
propel:
jobeet_category:
id: ~
name: { type: varchar(255), required: true, index: unique }
jobeet_job:
id: ~
category_id: { type: integer, foreignTable: jobeet_category,
➥ foreignReference: id, required: true }
type: { type: varchar(255) }
company: { type: varchar(255), required: true }
logo: { type: varchar(255) }
url: { type: varchar(255) }
position: { type: varchar(255), required: true }
location: { type: varchar(255), required: true }
description: { type: longvarchar, required: true }
how_to_apply: { type: longvarchar, required: true }
token: { type: varchar(255), required: true, index: unique }
is_public: { type: boolean, required: true, default: 1 }
is_activated: { type: boolean, required: true, default: 0 }
email: { type: varchar(255), required: true }
expires_at: { type: timestamp, required: true }
created_at: ~
updated_at: ~
jobeet_affiliate:
id: ~
url: { type: varchar(255), required: true }
email: { type: varchar(255), required: true, index: unique }
token: { type: varchar(255), required: true }
is_active: { type: boolean, required: true, default: 0 }
created_at: ~
jobeet_category_affiliate:
category_id: { type: integer, foreignTable: jobeet_category,
➥ foreignReference: id, required: true, primaryKey: true,
➥ onDelete: cascade }
affiliate_id: { type: integer, foreignTable: jobeet_affiliate,
➥ foreignReference: id, required: true, primaryKey: true,
➥ onDelete: cascade }
As the database does not exist yet and as we want to keep Jobeet database
agnostic, let's create the schema file by hand by editing the empty
config/doctrine/schema.yml file:
You will need to manually create theconfig/doctrine/directory in your project as it does not already exist:$ mkdir config/doctrine
# config/doctrine/schema.yml
JobeetCategory:
actAs: { Timestampable: ~ }
columns:
name: { type: string(255), notnull: true, unique: true }
JobeetJob:
actAs: { Timestampable: ~ }
columns:
category_id: { type: integer, notnull: true }
type: { type: string(255) }
company: { type: string(255), notnull: true }
logo: { type: string(255) }
url: { type: string(255) }
position: { type: string(255), notnull: true }
location: { type: string(255), notnull: true }
description: { type: string(4000), notnull: true }
how_to_apply: { type: string(4000), notnull: true }
token: { type: string(255), notnull: true, unique: true }
is_public: { type: boolean, notnull: true, default: 1 }
is_activated: { type: boolean, notnull: true, default: 0 }
email: { type: string(255), notnull: true }
expires_at: { type: timestamp, notnull: true }
relations:
JobeetCategory: { onDelete: CASCADE, local: category_id, foreign: id, foreignAlias: JobeetJobs }
JobeetAffiliate:
actAs: { Timestampable: ~ }
columns:
url: { type: string(255), notnull: true }
email: { type: string(255), notnull: true, unique: true }
token: { type: string(255), notnull: true }
is_active: { type: boolean, notnull: true, default: 0 }
relations:
JobeetCategories:
class: JobeetCategory
refClass: JobeetCategoryAffiliate
local: affiliate_id
foreign: category_id
foreignAlias: JobeetAffiliates
JobeetCategoryAffiliate:
columns:
category_id: { type: integer, primary: true }
affiliate_id: { type: integer, primary: true }
relations:
JobeetCategory: { onDelete: CASCADE, local: category_id, foreign: id }
JobeetAffiliate: { onDelete: CASCADE, local: affiliate_id, foreign: id }
If you have decided to create the tables by writing SQL statements, you can generate the correspondingschema.ymlconfiguration file by running thepropel:build-schematask:$ php symfony propel:build-schemaThe above task requires that you have a configured database in
databases.yml. We show you how to configure the database in a later step. If you try and run this task now it won't work as it doesn't know what database to build the schema for.
スキーマはYAMLフォーマット内でエンティティ関係図の構成に直接変換されます。
The ~YAML~ FormatAccording to the official YAML website, YAML is \"a human friendly data serialization standard for all programming languages\"
Put another way, YAML is a simple language to describe data (strings, integers, dates, arrays, and hashes).
In YAML, structure is shown through indentation, sequence items are denoted by a dash, and key/value pairs within a map are separated by a colon. YAML also has a shorthand syntax to describe the same structure with fewer lines, where arrays are explicitly shown with
[]and hashes with{}.If you are not yet familiar with YAML, it is time to get started as the symfony framework uses it extensively for its configuration files.
There is one important thing you need to remember when editing a YAML file: indentation must be done with one or more spaces, but never with ~tabulations|Code Formatting~.
schema.yml ファイルは全てのテーブルとカラムの説明を含んでいます。各カラムは下記の情報をつけて記述されます。:
type: The column type (boolean, tinyint, smallint, integer,
bigint, double, float, real, decimal, char, varchar(size),
longvarchar, date, time, timestamp, blob, and clob)required: Set it to true if you want the column to be required~index|Database indexes~: Set it to true if you want to create an index
for the column or to unique if you want a unique index to be created on
the column.primaryKey: Define a column as the ~primary key|Primary Key~ for the table.foreignTable, foreignReference: Define a column to be a
~foreign key|Foreign Key~ to another table.For columns set to ~, which means null in YAML (id, created_at, and
updated_at), symfony will guess the best configuration (primary key for id
and timestamp for created_at and updated_at).
TheonDeleteattribute defines theON DELETE~behavior|Integrity constraints~ of foreign keys, and Propel supportsCASCADE,SETNULL, andRESTRICT. For instance, when ajobrecord is deleted, all thejobeet_category_affiliaterelated records will be automatically deleted by the database or by Propel if the underlying engine does not support this functionality.
type: The ~column type~ (boolean, integer, float, decimal,
string, array, object, blob, clob, timestamp,
time, date, enum, gzip)notnull: Set it to true if you want the column to be requiredunique: Set it to true if you want to create a unique index for the column.TheonDeleteattribute defines theON DELETEbehavior of foreign keys, and Doctrine supportsCASCADE,SET NULL, andRESTRICT. For instance, when ajobrecord is deleted, all thejobeet_category_affiliaterelated records will be automatically deleted by the database.
The symfony framework supports all PDO-supported databases (MySQL, PostgreSQL, SQLite, Oracle, MSSQL, ...). ~PDO~ is the ~database abstraction layer|Database Abstraction Layer~ bundled with PHP.
Let's use ~MySQL~ for this tutorial:
$ mysqladmin -uroot -p create jobeet
Enter password: mYsEcret ## The password will echo as ********
Feel free to choose another ~database engine|Database Engine~ if you want. It won't be difficult to adapt the code we will write as we will use the ORM will write the SQL for us.
We need to tell symfony to use this database for the Jobeet project:
$ php symfony configure:database
➥ "mysql:host=localhost;dbname=jobeet" root mYsEcret
The default config/~databases.yml~ contains a connection that references propel.
Because we're using Doctrine, we need to remove the config/databases.yml so we
can re-generate it for Doctrine.
$ rm config/databases.yml
Now simply run the following command to generate a new database configuration file for Doctrine:
$ php symfony configure:database --name=doctrine
➥ --class=sfDoctrineDatabase
➥ "mysql:host=localhost;dbname=jobeet" root mYsEcret
The configure:database task takes three arguments: the
~PDO DSN~, the username, and
the password to access the database. If you don't need a password to access
your database on the development server, just omit the third argument.
Theconfigure:database~task|Tasks~ stores the ~database configuration|Database Configuration~ into theconfig/databases.ymlconfiguration file. Instead of using the task, you can edit this file by hand.
-
Passing the database password on the command line is convenient but
~insecure|Security~.
Depending on who has access to your environment, it might be better to
edit the config/databases.yml to change the password. Of course, to
keep the password safe, the configuration file access mode should also
be restricted.
Thanks to the database description from the schema.yml file, we can use some
Propel or Doctrine built-in tasks to generate the ~SQL~ statements needed to create the
database tables:
First in order to generate the SQL you must build your models from your schema files.
$ php symfony doctrine:build-model
Now that your models are present you can generate and insert the SQL.
$ php symfony propel:build-sql
The propel:build-sql task generates SQL statements in the data/sql/
directory, optimized for the database engine we have configured:
# snippet from data/sql/lib.model.schema.sql
CREATE TABLE `jobeet_category`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `jobeet_category_U_1` (`name`)
)Type=InnoDB;
# snippet from data/sql/schema.sql
CREATE TABLE jobeet_category (id BIGINT AUTO_INCREMENT, name VARCHAR(255)
NOT NULL COMMENT 'test', created_at DATETIME, updated_at DATETIME, slug
VARCHAR(255), UNIQUE INDEX sluggable_idx (slug), PRIMARY KEY(id))
ENGINE = INNODB;
実際にデータベース上にテーブルを生成するには、propel:insert-sql タスクを実行する必要があります。:
$ php symfony propel:insert-sql
このタスクはテーブルを再生成する前に現在のテーブルを削除するので、確認ダイアログが出てきます。--no-confirmation オプションを使えば、その確認ダイアログを無視できるのでバッチに組みこむときは便利です。:
$ php symfony propel:insert-sql --no-confirmation
As for any ~command line|Command Line~ tool, symfony tasks can take arguments and options. Each task comes with a built-in help message that can be displayed by running thehelptask:$ php symfony help propel:insert-sqlThe help message lists all the possible arguments and options, gives the default values for each of them, and provides some useful usage examples.
ORMはテーブルレコードをオブジェクトにマッピングしたPHPクラスも生成します。:
$ php symfony propel:build-model
The propel:build-model task generates PHP files in the lib/model/
directory that can be used to interact with the database.
By browsing the generated files, you have probably noticed that Propel
generates four classes per ~table|Table (Database)~. For the jobeet_job
table:
JobeetJob: An object of this class represents a single
~record|Database Record~ of the jobeet_job table. The
class is empty by default.BaseJobeetJob: The parent class of JobeetJob. Each time you run
propel:build-model, this class is overwritten, so all
customizations must be done in the JobeetJob class.
JobeetJobPeer: The class defines static methods that mostly return
collections of JobeetJob objects. The class is empty
by default.
BaseJobeetJobPeer: The parent class of JobeetJobPeer. Each time you
run propel:build-model, this class is overwritten,
so all customizations must be done in the
JobeetJobPeer class.By browsing the generated files, you have probably noticed that Doctrine
generates three classes per table. For the jobeet_job table:
JobeetJob: An object of this class represents a single record of the
jobeet_job table. The class is empty by default.BaseJobeetJob: The parent class of JobeetJob. Each time you run
doctrine:build-model, this class is overwritten, so all
~customizations|Customization~ must be done in the
JobeetJob class.
JobeetJobTable: The class defines methods that mostly return
collections of JobeetJob objects. The class is empty by
default.
-
The column values of a record can be manipulated with a model object by using
some ~accessors|Accessors~ (get*() methods) and mutators (set*() methods):
$job = new JobeetJob();
$job->setPosition('Web developer');
$job->save();
echo $job->getPosition();
$job->delete();
You can also define ~foreign keys|Foreign Key~ directly by linking objects together:
$category = new JobeetCategory();
$category->setName('Programming');
$job = new JobeetJob();
$job->setCategory($category);
propel:build-all タスクはこの章で行ったタスクを一括してやってくれるショートカットです。また、formsやvalidatorsのJobeetモデルオブジェクトの生成もします。:
$ php symfony propel:build-all --no-confirmation
今日の最後にアクションにおけるvalidatorを見ることができます。formsについては10日目にもっと詳しく説明する予定です。
As you will see later on, symfony ~autoloads|Autoload~ PHP classes for you, which means
that you never need to use a require in your code. It is one of the numerous
things that symfony automates for the developer but there is one downside:
whenever you add a new class, you need to clear the symfony ~cache|Cache~. As the
propel:build-model has created a lot of new classes, let's clear the cache:
$ php symfony cache:clear
A symfony ~task|Tasks~ is made of a namespace and a task name. Each one can be shortened as much as there is no ambiguity with other tasks. So, the following commands are equivalent tocache:clear:$ php symfony cache:cl $ php symfony ca:cAs the
cache:cleartask is so commonly used, it has an even shorter hardwired abbreviation:$ php symfony cc
データベースにテーブルが作成されました、しかしデータがありません。Webアプリケーションでは3種類のデータがあります。:
Each time symfony creates the tables in the database, all the data are lost.
To populate the database with some initial data, we could create a PHP script,
or execute some SQL statements with the mysql program. But as the need is
quite common, there is a better way with symfony: create YAML files in the
data/fixtures/ directory and use the propel:data-load task to load them
into the database.
First, create the following ~fixture|Fixtures~ files:
# data/fixtures/010_categories.yml
JobeetCategory:
design: { name: Design }
programming: { name: Programming }
manager: { name: Manager }
administrator: { name: Administrator }
# data/fixtures/020_jobs.yml
JobeetJob:
job_sensio_labs:
category_id: programming
type: full-time
company: Sensio Labs
logo: sensio-labs.gif
url: http://www.sensiolabs.com/
position: Web Developer
location: Paris, France
description: |
You've already developed websites with symfony and you want to
work with Open-Source technologies. You have a minimum of 3
years experience in web development with PHP or Java and you
wish to participate to development of Web 2.0 sites using the
best frameworks available.
how_to_apply: |
Send your resume to fabien.potencier [at] sensio.com
is_public: true
is_activated: true
token: job_sensio_labs
email: job@example.com
expires_at: 2010-10-10
job_extreme_sensio:
category_id: design
type: part-time
company: Extreme Sensio
logo: extreme-sensio.gif
url: http://www.extreme-sensio.com/
position: Web Designer
location: Paris, France
description: |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in.
Voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.
how_to_apply: |
Send your resume to fabien.potencier [at] sensio.com
is_public: true
is_activated: true
token: job_extreme_sensio
email: job@example.com
expires_at: 2010-10-10
# data/fixtures/categories.yml
JobeetCategory:
design:
name: Design
programming:
name: Programming
manager:
name: Manager
administrator:
name: Administrator
# data/fixtures/jobs.yml
JobeetJob:
job_sensio_labs:
JobeetCategory: programming
type: full-time
company: Sensio Labs
logo: sensio-labs.gif
url: http://www.sensiolabs.com/
position: Web Developer
location: Paris, France
description: |
You've already developed websites with symfony and you want to work
with Open-Source technologies. You have a minimum of 3 years
experience in web development with PHP or Java and you wish to
participate to development of Web 2.0 sites using the best
frameworks available.
how_to_apply: |
Send your resume to fabien.potencier [at] sensio.com
is_public: true
is_activated: true
token: job_sensio_labs
email: job@example.com
expires_at: '2010-10-10'
job_extreme_sensio:
JobeetCategory: design
type: part-time
company: Extreme Sensio
logo: extreme-sensio.gif
url: http://www.extreme-sensio.com/
position: Web Designer
location: Paris, France
description: |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in.
Voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.
how_to_apply: |
Send your resume to fabien.potencier [at] sensio.com
is_public: true
is_activated: true
token: job_extreme_sensio
email: job@example.com
expires_at: '2010-10-10'
The job fixture file references two images. You can download them (http://www.symfony-project.org/get/jobeet/sensio-labs.gif,http://www.symfony-project.org/get/jobeet/extreme-sensio.gif) and put them under theweb/uploads/jobs/directory.
A fixtures file is written in YAML, and defines model objects, labelled with a
unique name (for instance, we have defined two jobs labelled job_sensio_labs
and job_extreme_sensio). This label is of great use to link related objects
without having to define ~primary keys|Primary Key~ (which are often
auto-incremented and cannot be set). For instance, the job_sensio_labs job
category is programming, which is the label given to the 'Programming'
category.
In a YAML file, when a string contains line breaks (like thedescriptioncolumn in the job fixture file), you can use the pipe (|) to indicate that the string will span several lines.
Although a fixture file can contain objects from one or several models, we have decided to create one file per model for the Jobeet fixtures.
Notice the numbers ~prefixing|Prefix~ the filenames. This is a simple way to control the order of data loading. Later in the project, if we need to insert some new fixture file, it will be easy as we have some free numbers between existing ones.
Propel requires that the fixtures files be prefixed with numbers to determine the order in which the files will be loaded. With Doctrine this is not required as all fixtures will be loaded and saved in the correct order to make sure foreign keys are set properly.
In a fixture file, you don't need to define all columns values. If not,
symfony will use the default value defined in the database schema. And as
symfony uses Propel or Doctrine to load the data into the database, all the built-in
~behaviors|Behaviors (ORM)~ (like automatically setting the created_at
or updated_at columns) and the custom behaviors you might have added to
the model classes are activated.
データベースに初期データをロードするには単に propel:data-load タスクを実行するだけです。:
$ php symfony propel:data-load
Thepropel:build-all-loadtask is a shortcut for thepropel:build-alltask followed by thepropel:data-loadtask.
Run the doctrine:build-all-reload task to make sure everything is generated from your schema. This will generate your forms, filters, models, drop your database and re-create it with all the tables.
$ php symfony doctrine:build-all-reload
たくさんのCLIを使いますが、あんまり面白いものではありません。とりわけWebプロジェクトにとっては。データベースと情報をやり取りするWebページを作ることができます。
Let's see how to display the list of jobs, how to edit an existing job, and how to delete a job. As explained during day 1, a symfony project is made of applications. Each ~application|Application~ is further divided into modules. A ~module|Module~ is a self-contained set of PHP code that represents a feature of the application (the API module for example), or a set of manipulations the user can do on a model object (a job module for example).
symfonyは自動で基本要素を操作できるモジュールを作ることができます。:
$ php symfony propel:generate-module --with-show
➥ --non-verbose-templates frontend job JobeetJob
The propel:generate-module generates a job module in the frontend
application for the JobeetJob model. As with most symfony tasks,
some files and directories have been created for you under the
apps/frontend/modules/job/ directory:
| Directory | Description |
|---|---|
actions/ |
The module actions |
templates/ |
The module templates |
The actions/actions.class.php file defines all the available ~action|Action~ for
the job module:
| Action name | Description |
|---|---|
index |
Displays the records of the table |
show |
Displays the fields and their values for a given record |
new |
Displays a form to create a new record |
create |
Creates a new record |
edit |
Displays a form to edit an existing record |
update |
Updates a record according to the user submitted values |
delete |
Deletes a given record from the table |
You can now test the job module in a browser:
http://jobeet.localhost/frontend_dev.php/job

If you try to edit a job, you will have an exception because symfony needs a
text representation of a category. A PHP object representation can be defined
with the PHP __toString() magic method. The text representation of a category
record should be defined in the JobeetCategory model class:
// lib/model/JobeetCategory.php
class JobeetCategory extends BaseJobeetCategory
{
public function __toString()
{
return $this->getName();
}
}
Now each time symfony needs a text representation of a category, it calls the
~__toString()~ method which returns the category name. As we will need a text
representation of all model classes at one point or another, let's define
a __toString() method for every model class:
If you try to edit a job, you will notice the Category id drop down has a list
of all the category names. The value of each option is gotten from the __toString() method.
Doctrine will try and provide a base ~__toString()~ method by guessing a
descriptive column name like, title, name, subject, etc. If you want
something custom then you will need to add your own __toString() methods like below.
The JobeetCategory model is able to guess the __toString() method by using the name
column of the jobeet_category table.
// lib/model/JobeetJob.php
// lib/model/doctrine/JobeetJob.class.php
class JobeetJob extends BaseJobeetJob
{
public function __toString()
{
return sprintf('%s at %s (%s)', $this->getPosition(),
➥ $this->getCompany(), $this->getLocation());
}
}
// lib/model/JobeetAffiliate.php
// lib/model/doctrine/JobeetAffiliate.class.php
class JobeetAffiliate extends BaseJobeetAffiliate
{
public function __toString()
{
return $this->getUrl();
}
}
これで仕事の作成と編集が使えるようになりました。必須項目を空にして保存しようとすると、symfonyはデータベーススキーマから基本バリデーションルールを作ります。

That's all for today. I have warned you in the introduction. Today, we have barely written PHP code but we have a working web module for the job model, ready to be tweaked and customized. Remember, no PHP code also means no bugs!
If you still have some energy left, feel free to read the generated code for the module and the model and try to understand how it works. If not, don't worry and sleep well, as tomorrow, we will talk about one of the most used paradigm in web frameworks, the MVC design pattern.
As for any other day, today's code is available on the Jobeet SVN repository.
Checkout the release_day_03 tag:
$ svn co http://svn.jobeet.org/##ORM_LOWER##/tags/release_day_03/ jobeet/
ORM
コピー完了 (2008-12-16 12:11:52 brtRiver)
Documentation
| __ORM__ ... | |
| brtRiver(2008-12-31 03:19:07) | |
| You can now create and ed ... | |
| brtRiver(2008-12-31 03:18:47) | |
| <propel> // lib ... | |
| brtRiver(2008-12-31 03:18:25) | |
| <propel> // lib ... | |
| brtRiver(2008-12-31 03:18:02) | |
| [php] ... | |
| brtRiver(2008-12-31 03:17:53) | |
| <propel> If you try ... | |
| brtRiver(2008-12-31 03:17:34) | |
| http://jobeet.localh ... | |
| brtRiver(2008-12-31 03:17:01) | |
| $ php symfony propel: ... | |
| brtRiver(2008-12-31 03:16:47) | |
| Symfony is able to automa ... | |
| brtRiver(2008-12-31 03:16:39) | |
| We have used the command ... | |
| brtRiver(2008-12-31 03:16:26) | |
| See it in Action in the B ... | |
| brtRiver(2008-12-31 03:16:18) | |
| $ php symfony propel: ... | |
| brtRiver(2008-12-31 03:16:10) | |
| <propel> >**TIP* ... | |
| brtRiver(2008-12-31 03:15:47) | |
| A fixture file can contai ... | |
| brtRiver(2008-12-31 03:15:22) | |
| A fixtures file is writte ... | |
| brtRiver(2008-12-31 03:15:14) | |
| <propel> [yml] ... | |
| brtRiver(2008-12-31 03:15:02) | |
| The Initial Data -------- ... | |
| brtRiver(2008-12-31 03:14:09) | |
| $ php symfony cache: ... | |
| brtRiver(2008-12-31 03:13:58) | |
| You will see validators i ... | |
| brtRiver(2008-12-31 03:13:38) | |
| $ php symfony propel: ... | |
| brtRiver(2008-12-31 03:13:31) |