SlideShare a Scribd company logo
Symfony 2 meets Propel 1.5François Zaninotto
François ZaninottoHead of the Web Development Team at eTF1, editor the web properties of the leading TV network in France.Former symfony 1 contributorAuthor of “The Definitive Guide to Symfony” (APress)Lead Developer of Propel since October, 2009Interests: Web development, Usability, Agility, ROINot a developerTwitter: @francoisz, Github: fzaninotto
Propel 1.5
No surpriseBackwards compatible with Propel 1.3 and 1.4Faster than Propel 1.4, which was faster than Propel 1.3, which was...Very IDE friendlyBetter documentedMore robust (3 times as many unit tests as Propel 1.3)Fully integrated into symfony 1.3/1.4 (sfPropel15Plugin)
Surprise!Major new featuresModel QueriesCollectionsMany-to-many relationshipsMajor new behaviorsNested SetsConcrete Table InheritanceBetter Oracle Support
Surprise!Major new featuresModel QueriesCollectionsMany-to-many relationshipsMajor new behaviorsNested SetsConcrete Table InheritanceBetter Oracle SupportKiller FeatureKiller Feature
Model QueriesModel Queries are to the SQL query what ActiveRecord is to the table rowShift from the relational Paradigm to the Object paradigm in QueriesInspirations: SQL Alchemy, Doctrine, DbFinder, ArelCode generation makes it fast and IDE friendlyEasy to learn and useMUCH cleaner custom model codeBye bye, Criteria!
Model Queries$books = BookQuery::create()->filterByPublishedAt(array(    ‘max’ => time()  ))->filterByPublisher($publisher)->useAuthorQuery()->stillAlive()  ->endUse()->orderByTitle()->find();
 Concrete Table Inheritancecontentidtitlearticlebodyvideourlstructuredata
Concrete Table Inheritance: An Example$article = new Article();$article->setTitle(‘France loses World Cup’);$article->setBody(‘Lorem Ipsum’);$article->save();$video = new Video();$video->setTitle(‘World Cup Goals’);$video->setUrl(‘http://www.youtube.com/xxx’);$video->save();
> SELECT * FROMarticle;+----+------------------------+-------------+| id | title                  | body        |+----+------------------------+-------------+| 1  | France loses World Cup | Lorem Ipsum |+----+------------------------+-------------+> SELECT * FROMvideo;+----+-----------------+----------------------------+| id | title           | url                        |+----+-----------------+----------------------------+| 2  | World Cup goals | http://www.youtube.com/xxx |+----+-----------------+----------------------------+> SELECT * FROM content;+----+------------------------+| id | title                  |+----+------------------------+| 1  | France loses World Cup || 2  | World Cup goals        |+----+------------------------+
Design your model in a true object-oriented wayLet Propel do the mapping with the relational worldDenormalize with ease for optimal performanceLet PHP manipulate inheritance, not data replication.… Let PHP manipulate objects, not records.… Let PHP manipulate collections, not arrays.… Let PHP manipulate relations, not foreign keys.
Continuousimprovementsthroughminor versions1.5.1PropelObjectCollection::toKeyValue()One-to-manyjoinedhydration (no LIMIT support)CLI enhancements1.5.2Namespaces ! ModelQuery::findOneOrCreate()aggregate_columnbehaviorSQL Comments
Continuous improvements through minor versions1.5.1PropelObjectCollection::toKeyValue()One-to-many joined hydration (no LIMIT support)CLI enhancements1.5.2Namespaces ! ModelQuery::findOneOrCreate()aggregate_column behaviorSQL CommentsMust HaveKiller Feature
Namespaces// in schema.xml<table name="book"namespace="Bookstore">  ...</table>// in application codeuseBookstore\BookQuery;$book = BookQuery::create();->findOneByTitle(‘War And Peace’);echoget_class($book);  // Bookstore\Book$author = $book->getAuthor();echoget_class($author);  // Bookstore\People\Author
 Aggregate Table Behaviorauthoridnamebookidtitleauthor_id*<table name="author">  <behavior name="aggregate_column"><parameter name="name" value="nb_books" />    <parameter name="foreign_table" value="book" />    <parameter name="expression" value="COUNT(id)" />  </behavior>  ...</table>
 Aggregate Table Behaviorauthoridnamenb_booksbookidtitleauthor_id*<table name="author">  <behavior name="aggregate_column"><parameter name="name" value="nb_books" />    <parameter name="foreign_table" value="book" />    <parameter name="expression" value="COUNT(id)" />  </behavior>  ...</table>
Aggregate Table Behavior$author = new Author();$author->setName(‘Leo Tolstoi');$author->save();echo $author->getNbBooks(); // 0$book = new Book();$book->setTitle(‘War and Peace’);$book->setAuthor($author);$book->save();echo $author->getNbBooks(); // 1$book->delete();echo $author->getNbBooks(); // 0
No, really, Propel is definitely NOT DEAD
Propel 1.5 and Symfony
Propel Integration with symfony 1: sfPropel15Plugin Use sf configuration system (databases.yml, propel.ini) Use sf autoloading rather than Propel’s Use sf task system (and hides Phing, thank God) Adapt Propel to SF applications directory structureYAML format for the schema (and plugin override)
Web Debug Toolbar panel Form integration (Widgets, Validators, Model forms)Admin Generator Theme Routing integration (Model routes, Model route collections) Symfony BehaviorsPropel Integration with Symfony2: PropelBundle Use sf configuration system (config.yml, Dependency Injection) Use sf autoloading rather than Propel’s (thanks Namespaces) Use sf command system (and hides Phing, thank God) Adapt Propel to SF applications directory structureYAML format for the schema (and bundle override)Web Debug Toolbar Panel Form integration (Widgets, Validators, Model forms) Admin Generator ThemeRouting integration (Model routes, Model route collections)       Symfony Behaviors
Many of the symfony add-ons to Propel are now part of Propel 1.5Model hooks, query hooksBehavior system (at buildtime, for better performance and power)auto_add_pkbehaviortimestampable behaviorisPrimaryString column  attribute for automated __toString()No need for custom symfony code for these
Why you may want to use Propel rather than Doctrine 2No need to upgrade your Model codeIt’s fast (without any cache system - that’s code generation)It’s an ActiveRecord implementationIt has behaviorsIt’s IDE friendlyThe model code is easy to understand and debugIt has unique features (ModelQueries, concrete table inheritance, aggregate column behavior, etc.) It’s robust (3000+ unit tests) and already used by many developersIt’s not alpha, it’s not beta, it’s already stable
Installation
The PropelBundle is bundled with the Symfony2 FrameworkRegister the bundle in the kernel// in hello/HelloKernel.phpclassHelloKernelextendsKernel{public functionregisterBundles()  {    $bundles = array(      ...      new Symfony\Framework\PropelBundle\Bundle(),    );return $bundles;  }}
Add Propel and Phing libraries in src/vendor/> cd src/vendor> svn co http://svn.propelorm.org/branches/1.5/ propel> svn co http://svn.phing.info/tags/2.3.3 phingAdd Propel and Phing paths to the project configuration# in hello/config/config.ymlpropel.config:path:       %kernel.root_dir%/../src/vendor/propelphing_path: %kernel.root_dir%/../src/vendor/phing
Test the installation by calling the project console> hello/consoleSymfony version 2.0.0-DEV - helloUsage:  [options] command [arguments]propel:build        Hub for Propel build commands (model, sql):build-model  Build the Propel Object Model classes                   based on XML schemas:build-sql    Build the SQL generation code for all                 tables based on Propel XML schemas
Usage
Create an XML schema using namespaces// in src/Application/HelloBundle/Resources/config/schema.xml<?xml version="1.0" encoding="UTF-8"?><database name="default" namespace="Application\HelloBundle\Model" defaultIdMethod="native">  <table name="book">    <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />    <column name="title" type="varchar" primaryString="1" size="100" />    <column name="ISBN" type="varchar" size="20" />    <column name="author_id" type="integer" />    <foreign-key foreignTable="author">      <reference local="author_id" foreign="id" />    </foreign-key>  </table>  <table name="author">    <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />    <column name="first_name" type="varchar" size="100" />    <column name="last_name" type="varchar" size="100" />  </table></database>
Create an XML schemas using namespaces// in src/Application/HelloBundle/Resources/config/schema.xml<?xml version="1.0" encoding="UTF-8"?><database name="default" namespace="Application\HelloBundle\Model" defaultIdMethod="native">  <table name="book">    <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />    <column name="title" type="varchar" primaryString="1" size="100" />    <column name="ISBN" type="varchar" size="20" />    <column name="author_id" type="integer" />    <foreign-key foreignTable="author">      <reference local="author_id" foreign="id" />    </foreign-key>  </table>  <table name="author">    <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />    <column name="first_name" type="varchar" size="100" />    <column name="last_name" type="varchar" size="100" />  </table></database>
Build the model and SQL code> cd sandbox> hello/console propel:buildsrc/Application/HelloBundle/  Model/    map/    om/    Author.php    AuthorPeer.php    AuthorQuery.php    Book.php    BookPeer.php    BookQuery.phphello/propel/sql/  HelloBundle-schema.sql
// in sandbox/src/application/HelloBundle/Model/Book.phpnamespaceApplication\HelloBundle\Model;useApplication\HelloBundle\Model\Om\BaseBook;/** * Skeleton subclass for representing a row from the  * 'book' table. * * You should add additional methods to this class to meet * the application requirements. This class will only be * generated as long as it does not already exist in the * output directory. */classBookextendsBaseBook {} // Book
Setup your connection in the project configuration# in sandbox/hello/config/config.ymlpropel.dbal:driver:   mysqluser:     rootpassword: nulldsn:      mysql:host=localhost;dbname=test  options:  {}
Use models in your actions as with Propel 1.5 aloneSymfony handles the autoloading// in sandbox/src/Application/HelloBundle/Controller/HelloController.phpnamespaceApplication\HelloBundle\Controller;useSymfony\Framework\WebBundle\Controller;useApplication\HelloBundle\Model\AuthorQuery;classHelloControllerextendsController{public functionindexAction($name)  {    $author = AuthorQuery::create()      ->findOneByName($name);return $this->render('HelloBundle:Hello:index', array('author' => $author));  }}
That’s about itAll the Propel features are ready to use… in the Propel way
The Future of Propel 1.5 and Symfony2
Ask Fabien
A lot left to doYAML format for the schema (and bundle override)Web Debug Toolbar PanelForm integration (Widgets, Validators, Model forms)Admin Generator ThemeDocumentationUnit tests
And even moreEmbedded Relation FormsAdmin generator on steroidsEasy Custom FilterCross-module linksPlain text fieldsAdvanced Object RoutingCollection routesNested routesA thousand more ideas worth implementingcf. sfPropel15Plugincf. DbFinderPlugin
Not much time to do soI’m already developing PropelI’m already developing sfPropel15PluginI also have a full-time job…and a familyAny help is welcome!
Questions?Online Resourceshttp://github.com/fzaninotto/symfonyhttp://www.propelorm.org/http://www.symfony-project.org/plugins/sfPropel15PluginNews about all thathttp://propel.posterous.com/http://twitter.com/francoisz

More Related Content

What's hot (20)

ODP
Dexterity in 15 minutes or less
rijk.stofberg
 
KEY
Building and Distributing PostgreSQL Extensions Without Learning C
David Wheeler
 
PDF
PyFoursquare: Python Library for Foursquare
Marcel Caraciolo
 
PDF
잘 알려지지 않은 Php 코드 활용하기
형우 안
 
PDF
Yii, frameworks and where PHP is heading to
Alexander Makarov
 
PDF
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
James Titcumb
 
PPTX
Doctrine 2.0 Enterprise Persistence Layer for PHP
Guilherme Blanco
 
PDF
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
James Titcumb
 
PPT
Ant
sundar22in
 
PDF
P6 OO vs Moose (&Moo)
lichtkind
 
PPTX
A Functional Guide to Cat Herding with PHP Generators
Mark Baker
 
PDF
Anatomy of a reusable module
Alessandro Franceschi
 
KEY
DPC 2012 : PHP in the Dark Workshop
Jeroen Keppens
 
PDF
Ruby 2.0
Uģis Ozols
 
PDF
Why Every Tester Should Learn Ruby
Raimonds Simanovskis
 
PDF
PHP Enums - PHPCon Japan 2021
Ayesh Karunaratne
 
PPTX
Php on the Web and Desktop
Elizabeth Smith
 
PPTX
Speed up your developments with Symfony2
Hugo Hamon
 
PDF
Typed Properties and more: What's coming in PHP 7.4?
Nikita Popov
 
ODP
Moose - YAPC::NA 2012
xSawyer
 
Dexterity in 15 minutes or less
rijk.stofberg
 
Building and Distributing PostgreSQL Extensions Without Learning C
David Wheeler
 
PyFoursquare: Python Library for Foursquare
Marcel Caraciolo
 
잘 알려지지 않은 Php 코드 활용하기
형우 안
 
Yii, frameworks and where PHP is heading to
Alexander Makarov
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
James Titcumb
 
Doctrine 2.0 Enterprise Persistence Layer for PHP
Guilherme Blanco
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
James Titcumb
 
P6 OO vs Moose (&Moo)
lichtkind
 
A Functional Guide to Cat Herding with PHP Generators
Mark Baker
 
Anatomy of a reusable module
Alessandro Franceschi
 
DPC 2012 : PHP in the Dark Workshop
Jeroen Keppens
 
Ruby 2.0
Uģis Ozols
 
Why Every Tester Should Learn Ruby
Raimonds Simanovskis
 
PHP Enums - PHPCon Japan 2021
Ayesh Karunaratne
 
Php on the Web and Desktop
Elizabeth Smith
 
Speed up your developments with Symfony2
Hugo Hamon
 
Typed Properties and more: What's coming in PHP 7.4?
Nikita Popov
 
Moose - YAPC::NA 2012
xSawyer
 

Similar to Symfony2 meets propel 1.5 (20)

PPTX
Propel: A Open Source ORM Model and MVC Framework
Sachinkumar Durge
 
PDF
Propel Your PHP Applications
hozn
 
KEY
Object Relational Mapping in PHP
Rob Knight
 
PDF
Sfmodelsecondpartrefcard
Maksim Kotlyar
 
PDF
DBIx::Class introduction - 2010
leo lapworth
 
PDF
DBIx::Class beginners
leo lapworth
 
PDF
Symfony ORM
Nuuktal Consulting
 
ODP
Red beanphp orm presentation
Chris Chubb
 
PDF
The History of PHPersistence
Hugo Hamon
 
ODP
Achieve the norm with Idiorm
Stipe Predanic
 
PDF
Laravel doctrine
Christian Nastasi
 
ODP
Databases and doctrine
Glenn Guden
 
PPS
Simplify your professional web development with symfony
Francois Zaninotto
 
PDF
Object Oriented Programming with Laravel - Session 6
Shahrzad Peyman
 
PPT
Doctrine 2 - Introduction
Diego Lewin
 
PDF
What's new in Doctrine
Jonathan Wage
 
PDF
Doctrine For Beginners
Jonathan Wage
 
PDF
Doctrine in FLOW3
Karsten Dambekalns
 
PDF
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
Javier Eguiluz
 
PPTX
Agile data presentation 3 - cambridge
Romans Malinovskis
 
Propel: A Open Source ORM Model and MVC Framework
Sachinkumar Durge
 
Propel Your PHP Applications
hozn
 
Object Relational Mapping in PHP
Rob Knight
 
Sfmodelsecondpartrefcard
Maksim Kotlyar
 
DBIx::Class introduction - 2010
leo lapworth
 
DBIx::Class beginners
leo lapworth
 
Symfony ORM
Nuuktal Consulting
 
Red beanphp orm presentation
Chris Chubb
 
The History of PHPersistence
Hugo Hamon
 
Achieve the norm with Idiorm
Stipe Predanic
 
Laravel doctrine
Christian Nastasi
 
Databases and doctrine
Glenn Guden
 
Simplify your professional web development with symfony
Francois Zaninotto
 
Object Oriented Programming with Laravel - Session 6
Shahrzad Peyman
 
Doctrine 2 - Introduction
Diego Lewin
 
What's new in Doctrine
Jonathan Wage
 
Doctrine For Beginners
Jonathan Wage
 
Doctrine in FLOW3
Karsten Dambekalns
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
Javier Eguiluz
 
Agile data presentation 3 - cambridge
Romans Malinovskis
 
Ad

More from Francois Zaninotto (11)

PDF
Vous aimez les legos ? React est fait pour vous !
Francois Zaninotto
 
PDF
GraphQL, l'avenir du REST ?
Francois Zaninotto
 
PDF
La blockchain, quand l'individu sert au collectif... malgré lui
Francois Zaninotto
 
PDF
Le jeu vidéo à la rescousse du web
Francois Zaninotto
 
PDF
Frameworks : A history of violence
Francois Zaninotto
 
PDF
Php 100k
Francois Zaninotto
 
PDF
La migration continue vers Symfony
Francois Zaninotto
 
PDF
La programmation asynchrone... et les pates
Francois Zaninotto
 
PDF
Bonnes pratiques de développement avec Node js
Francois Zaninotto
 
PDF
Ce bon vieux propel
Francois Zaninotto
 
PDF
Developing for Developers
Francois Zaninotto
 
Vous aimez les legos ? React est fait pour vous !
Francois Zaninotto
 
GraphQL, l'avenir du REST ?
Francois Zaninotto
 
La blockchain, quand l'individu sert au collectif... malgré lui
Francois Zaninotto
 
Le jeu vidéo à la rescousse du web
Francois Zaninotto
 
Frameworks : A history of violence
Francois Zaninotto
 
La migration continue vers Symfony
Francois Zaninotto
 
La programmation asynchrone... et les pates
Francois Zaninotto
 
Bonnes pratiques de développement avec Node js
Francois Zaninotto
 
Ce bon vieux propel
Francois Zaninotto
 
Developing for Developers
Francois Zaninotto
 
Ad

Recently uploaded (20)

PPTX
Top iOS App Development Company in the USA for Innovative Apps
SynapseIndia
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
Smart Air Quality Monitoring with Serrax AQM190 LITE
SERRAX TECHNOLOGIES LLP
 
PDF
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PDF
SFWelly Summer 25 Release Highlights July 2025
Anna Loughnan Colquhoun
 
PDF
Complete JavaScript Notes: From Basics to Advanced Concepts.pdf
haydendavispro
 
PDF
Human-centred design in online workplace learning and relationship to engagem...
Tracy Tang
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PDF
Windsurf Meetup Ottawa 2025-07-12 - Planning Mode at Reliza.pdf
Pavel Shukhman
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Blockchain Transactions Explained For Everyone
CIFDAQ
 
PDF
TrustArc Webinar - Data Privacy Trends 2025: Mid-Year Insights & Program Stra...
TrustArc
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PDF
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
PDF
Why Orbit Edge Tech is a Top Next JS Development Company in 2025
mahendraalaska08
 
PPTX
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
Top iOS App Development Company in the USA for Innovative Apps
SynapseIndia
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
Smart Air Quality Monitoring with Serrax AQM190 LITE
SERRAX TECHNOLOGIES LLP
 
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
SFWelly Summer 25 Release Highlights July 2025
Anna Loughnan Colquhoun
 
Complete JavaScript Notes: From Basics to Advanced Concepts.pdf
haydendavispro
 
Human-centred design in online workplace learning and relationship to engagem...
Tracy Tang
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
Windsurf Meetup Ottawa 2025-07-12 - Planning Mode at Reliza.pdf
Pavel Shukhman
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Blockchain Transactions Explained For Everyone
CIFDAQ
 
TrustArc Webinar - Data Privacy Trends 2025: Mid-Year Insights & Program Stra...
TrustArc
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
Why Orbit Edge Tech is a Top Next JS Development Company in 2025
mahendraalaska08
 
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 

Symfony2 meets propel 1.5

  • 1. Symfony 2 meets Propel 1.5François Zaninotto
  • 2. François ZaninottoHead of the Web Development Team at eTF1, editor the web properties of the leading TV network in France.Former symfony 1 contributorAuthor of “The Definitive Guide to Symfony” (APress)Lead Developer of Propel since October, 2009Interests: Web development, Usability, Agility, ROINot a developerTwitter: @francoisz, Github: fzaninotto
  • 4. No surpriseBackwards compatible with Propel 1.3 and 1.4Faster than Propel 1.4, which was faster than Propel 1.3, which was...Very IDE friendlyBetter documentedMore robust (3 times as many unit tests as Propel 1.3)Fully integrated into symfony 1.3/1.4 (sfPropel15Plugin)
  • 5. Surprise!Major new featuresModel QueriesCollectionsMany-to-many relationshipsMajor new behaviorsNested SetsConcrete Table InheritanceBetter Oracle Support
  • 6. Surprise!Major new featuresModel QueriesCollectionsMany-to-many relationshipsMajor new behaviorsNested SetsConcrete Table InheritanceBetter Oracle SupportKiller FeatureKiller Feature
  • 7. Model QueriesModel Queries are to the SQL query what ActiveRecord is to the table rowShift from the relational Paradigm to the Object paradigm in QueriesInspirations: SQL Alchemy, Doctrine, DbFinder, ArelCode generation makes it fast and IDE friendlyEasy to learn and useMUCH cleaner custom model codeBye bye, Criteria!
  • 8. Model Queries$books = BookQuery::create()->filterByPublishedAt(array( ‘max’ => time() ))->filterByPublisher($publisher)->useAuthorQuery()->stillAlive() ->endUse()->orderByTitle()->find();
  • 9. Concrete Table Inheritancecontentidtitlearticlebodyvideourlstructuredata
  • 10. Concrete Table Inheritance: An Example$article = new Article();$article->setTitle(‘France loses World Cup’);$article->setBody(‘Lorem Ipsum’);$article->save();$video = new Video();$video->setTitle(‘World Cup Goals’);$video->setUrl(‘http://www.youtube.com/xxx’);$video->save();
  • 11. > SELECT * FROMarticle;+----+------------------------+-------------+| id | title | body |+----+------------------------+-------------+| 1 | France loses World Cup | Lorem Ipsum |+----+------------------------+-------------+> SELECT * FROMvideo;+----+-----------------+----------------------------+| id | title | url |+----+-----------------+----------------------------+| 2 | World Cup goals | http://www.youtube.com/xxx |+----+-----------------+----------------------------+> SELECT * FROM content;+----+------------------------+| id | title |+----+------------------------+| 1 | France loses World Cup || 2 | World Cup goals |+----+------------------------+
  • 12. Design your model in a true object-oriented wayLet Propel do the mapping with the relational worldDenormalize with ease for optimal performanceLet PHP manipulate inheritance, not data replication.… Let PHP manipulate objects, not records.… Let PHP manipulate collections, not arrays.… Let PHP manipulate relations, not foreign keys.
  • 13. Continuousimprovementsthroughminor versions1.5.1PropelObjectCollection::toKeyValue()One-to-manyjoinedhydration (no LIMIT support)CLI enhancements1.5.2Namespaces ! ModelQuery::findOneOrCreate()aggregate_columnbehaviorSQL Comments
  • 14. Continuous improvements through minor versions1.5.1PropelObjectCollection::toKeyValue()One-to-many joined hydration (no LIMIT support)CLI enhancements1.5.2Namespaces ! ModelQuery::findOneOrCreate()aggregate_column behaviorSQL CommentsMust HaveKiller Feature
  • 15. Namespaces// in schema.xml<table name="book"namespace="Bookstore"> ...</table>// in application codeuseBookstore\BookQuery;$book = BookQuery::create();->findOneByTitle(‘War And Peace’);echoget_class($book); // Bookstore\Book$author = $book->getAuthor();echoget_class($author); // Bookstore\People\Author
  • 16. Aggregate Table Behaviorauthoridnamebookidtitleauthor_id*<table name="author"> <behavior name="aggregate_column"><parameter name="name" value="nb_books" /> <parameter name="foreign_table" value="book" /> <parameter name="expression" value="COUNT(id)" /> </behavior> ...</table>
  • 17. Aggregate Table Behaviorauthoridnamenb_booksbookidtitleauthor_id*<table name="author"> <behavior name="aggregate_column"><parameter name="name" value="nb_books" /> <parameter name="foreign_table" value="book" /> <parameter name="expression" value="COUNT(id)" /> </behavior> ...</table>
  • 18. Aggregate Table Behavior$author = new Author();$author->setName(‘Leo Tolstoi');$author->save();echo $author->getNbBooks(); // 0$book = new Book();$book->setTitle(‘War and Peace’);$book->setAuthor($author);$book->save();echo $author->getNbBooks(); // 1$book->delete();echo $author->getNbBooks(); // 0
  • 19. No, really, Propel is definitely NOT DEAD
  • 20. Propel 1.5 and Symfony
  • 21. Propel Integration with symfony 1: sfPropel15Plugin Use sf configuration system (databases.yml, propel.ini) Use sf autoloading rather than Propel’s Use sf task system (and hides Phing, thank God) Adapt Propel to SF applications directory structureYAML format for the schema (and plugin override)
  • 22. Web Debug Toolbar panel Form integration (Widgets, Validators, Model forms)Admin Generator Theme Routing integration (Model routes, Model route collections) Symfony BehaviorsPropel Integration with Symfony2: PropelBundle Use sf configuration system (config.yml, Dependency Injection) Use sf autoloading rather than Propel’s (thanks Namespaces) Use sf command system (and hides Phing, thank God) Adapt Propel to SF applications directory structureYAML format for the schema (and bundle override)Web Debug Toolbar Panel Form integration (Widgets, Validators, Model forms) Admin Generator ThemeRouting integration (Model routes, Model route collections) Symfony Behaviors
  • 23. Many of the symfony add-ons to Propel are now part of Propel 1.5Model hooks, query hooksBehavior system (at buildtime, for better performance and power)auto_add_pkbehaviortimestampable behaviorisPrimaryString column attribute for automated __toString()No need for custom symfony code for these
  • 24. Why you may want to use Propel rather than Doctrine 2No need to upgrade your Model codeIt’s fast (without any cache system - that’s code generation)It’s an ActiveRecord implementationIt has behaviorsIt’s IDE friendlyThe model code is easy to understand and debugIt has unique features (ModelQueries, concrete table inheritance, aggregate column behavior, etc.) It’s robust (3000+ unit tests) and already used by many developersIt’s not alpha, it’s not beta, it’s already stable
  • 26. The PropelBundle is bundled with the Symfony2 FrameworkRegister the bundle in the kernel// in hello/HelloKernel.phpclassHelloKernelextendsKernel{public functionregisterBundles() { $bundles = array( ... new Symfony\Framework\PropelBundle\Bundle(), );return $bundles; }}
  • 27. Add Propel and Phing libraries in src/vendor/> cd src/vendor> svn co http://svn.propelorm.org/branches/1.5/ propel> svn co http://svn.phing.info/tags/2.3.3 phingAdd Propel and Phing paths to the project configuration# in hello/config/config.ymlpropel.config:path: %kernel.root_dir%/../src/vendor/propelphing_path: %kernel.root_dir%/../src/vendor/phing
  • 28. Test the installation by calling the project console> hello/consoleSymfony version 2.0.0-DEV - helloUsage: [options] command [arguments]propel:build Hub for Propel build commands (model, sql):build-model Build the Propel Object Model classes based on XML schemas:build-sql Build the SQL generation code for all tables based on Propel XML schemas
  • 29. Usage
  • 30. Create an XML schema using namespaces// in src/Application/HelloBundle/Resources/config/schema.xml<?xml version="1.0" encoding="UTF-8"?><database name="default" namespace="Application\HelloBundle\Model" defaultIdMethod="native"> <table name="book"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="title" type="varchar" primaryString="1" size="100" /> <column name="ISBN" type="varchar" size="20" /> <column name="author_id" type="integer" /> <foreign-key foreignTable="author"> <reference local="author_id" foreign="id" /> </foreign-key> </table> <table name="author"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="first_name" type="varchar" size="100" /> <column name="last_name" type="varchar" size="100" /> </table></database>
  • 31. Create an XML schemas using namespaces// in src/Application/HelloBundle/Resources/config/schema.xml<?xml version="1.0" encoding="UTF-8"?><database name="default" namespace="Application\HelloBundle\Model" defaultIdMethod="native"> <table name="book"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="title" type="varchar" primaryString="1" size="100" /> <column name="ISBN" type="varchar" size="20" /> <column name="author_id" type="integer" /> <foreign-key foreignTable="author"> <reference local="author_id" foreign="id" /> </foreign-key> </table> <table name="author"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="first_name" type="varchar" size="100" /> <column name="last_name" type="varchar" size="100" /> </table></database>
  • 32. Build the model and SQL code> cd sandbox> hello/console propel:buildsrc/Application/HelloBundle/ Model/ map/ om/ Author.php AuthorPeer.php AuthorQuery.php Book.php BookPeer.php BookQuery.phphello/propel/sql/ HelloBundle-schema.sql
  • 33. // in sandbox/src/application/HelloBundle/Model/Book.phpnamespaceApplication\HelloBundle\Model;useApplication\HelloBundle\Model\Om\BaseBook;/** * Skeleton subclass for representing a row from the * 'book' table. * * You should add additional methods to this class to meet * the application requirements. This class will only be * generated as long as it does not already exist in the * output directory. */classBookextendsBaseBook {} // Book
  • 34. Setup your connection in the project configuration# in sandbox/hello/config/config.ymlpropel.dbal:driver: mysqluser: rootpassword: nulldsn: mysql:host=localhost;dbname=test options: {}
  • 35. Use models in your actions as with Propel 1.5 aloneSymfony handles the autoloading// in sandbox/src/Application/HelloBundle/Controller/HelloController.phpnamespaceApplication\HelloBundle\Controller;useSymfony\Framework\WebBundle\Controller;useApplication\HelloBundle\Model\AuthorQuery;classHelloControllerextendsController{public functionindexAction($name) { $author = AuthorQuery::create() ->findOneByName($name);return $this->render('HelloBundle:Hello:index', array('author' => $author)); }}
  • 36. That’s about itAll the Propel features are ready to use… in the Propel way
  • 37. The Future of Propel 1.5 and Symfony2
  • 39. A lot left to doYAML format for the schema (and bundle override)Web Debug Toolbar PanelForm integration (Widgets, Validators, Model forms)Admin Generator ThemeDocumentationUnit tests
  • 40. And even moreEmbedded Relation FormsAdmin generator on steroidsEasy Custom FilterCross-module linksPlain text fieldsAdvanced Object RoutingCollection routesNested routesA thousand more ideas worth implementingcf. sfPropel15Plugincf. DbFinderPlugin
  • 41. Not much time to do soI’m already developing PropelI’m already developing sfPropel15PluginI also have a full-time job…and a familyAny help is welcome!