How to Integrate Propel 2 with Laravel 4.1.x

I was recently doing some prototyping with Laravel, the self-proclaimed “PHP Framework for Web Artisans”.  It seems to be gaining quite some traction within the framework community, and it boasts some cool features such as dependency injection via an Inversion of Control container and a groovy command-line interface called Artisan.  Even better, the framework documentation is clearly written, detailed enough to dig beneath surface level, and (most importantly) it works.

Laravel ships with its own home-brewed ORM called Eloquent (based on the Active Record pattern), but I wanted to see how easy or difficult it would be to integrate another popular ORM, Propel, into the framework.  This would be an important consideration if a project were already using Propel with another framework, but wanted to transition to Laravel without having to rewrite its data mappings.  I found a solid post online that outlined an integration for Laravel 4 and Propel 1.6, but Propel is now in version 2 so some steps were no longer accurate.  I ended up figuring my way around the integration, and wanted to share my notes in this post.

The following tutorial assumes the following:

  • Comfort with the command line.
  • An environment that can support minimum requirements for both Propel and Laravel.

Prep Work: Download and install Composer

Simply follow the installation instructions found here.  Composer is a cool command-line tool that leverages a JSON config file to manage your project dependencies with ease.  We will use it in this tutorial to install both Laravel and Propel.

Step 1: Download and install Laravel

Once you have Composer, installing Laravel is as simple as executing the following in your command line (e.g., Terminal):

$ composer create-project laravel/laravel --prefer-dist

Laravel will be installed by default in a new folder called “laravel” in the current working directory.  To specify a directory for installation other than “laravel”, simply add an argument before the —prefer-dist flag.  For example, use “composer create-project laravel/laravel ./newapp/ –prefer-dist” to install Laravel in a new directory called “newapp” in the present working directory.

Step 2: Add Propel 2 to your composer.json file

The composer.json file is located in the root directory of your Laravel project. It tells Composer what dependencies the current project has.  Open it up in your preferred text editor or IDE and add a line for Propel like so:

"require": {
"laravel/framework": "4.1.*",
"propel/propel": "2.0.*@dev"
},

Note that Propel 2.0.* is still in “dev”, so the @dev stability flag must be added to allow it to be loaded.  As an alternative, the minimum-stability property can be set to “dev”.

Step 3: Install Propel using Composer

Once composer.json has been modified, install Propel by running the following command in your Laravel install directory:

$ composer update

Propel will be installed in /path/to/laravel/vendor/bin/propel/.  You can test that Propel was properly installed by running the following (again, in your Laravel install directory):

$ vendor/bin/propel

Step 4: Create a Propel configuration directory

Execute the following command from your Laravel install directory to create a new configuration folder for Propel:

$ mkdir app/config/propel

Configuration files for Propel can technically live anywhere, so long as they are properly reference in step 8.  The application configuration folder is a natural place to put it, however.

Step 5: Copy, write, or reverse engineer your Propel schema.xml file

Propel uses an XML file to define the structure and interrelationships of your project’s data models.  These are somewhat inextricably tied to the underlying tables and columns of your database implementation – one weakness of the Active Record pattern – but it does mean that updating your database is as easy as updating your schema.xml and running the Propel diff and migrate tasks.  The schema.xml is also used to build the PHP model classes that you will use to interface with your data models (more on that in step 6).  Essentially, everything in Propel starts with the schema.xml.

A) If you have an existing schema.xml from previous work with Propel, simply copy it into the Propel configuration directory you created in the previous step.

B) If you are starting from scratch and don’t have an existing database or Propel schema.xml, write one to your needs per the schema documentation from Propel.

C) If you have an existing database that you’d like to use, Propel can reverse engineer a schema.xml and save you a bunch of time.  Simply run the following command in /path/to/laravel/app/config/propel/, replacing [VAR_NAME] with the relevant values:

$ ../../../vendor/bin/propel reverse "[DB_ADAPTER – e.g., mysql]:host=[HOST];port=[PORT];dbname=[DB_NAME];user=[DB_USER];password=[DB_PASS]" --input-dir="." --output-dir="." --database-name="[DB_NAME]"

Note that the reverse-engineered schema.xml may be somewhat limited based on what information your database encodes.  For example, if you are using SQLite – a typeless database – the column elements won’t have defined types.  Or if your database doesn’t have foreign key relationships (often the case with the MySQL-default MyISAM storage engine), you may have to define them explicitly after the schema.xml has been generated.

Step 6: Generate your Propel PHP model classes

Run the following command in /path/to/laravel/app/config/propel/ to generate your PHP model classes based on the schema.xml.

$ ../../../vendor/bin/propel model:build --mysql-engine="MyISAM" --output-dir="../../models/propel"

This will create a ton of PHP classes which Propel uses to handle its ORM goodness.  We’ve specified an output directory using the –output-dir flag, which will export all of the PHP classes into a “propel” directory within the “models” folder of the Laravel application.  Check out the Propel documentation for a more detailed description of the classes generated.

Step 7: Craft your Propel runtime configuration

You can either define your runtime configuration directly in PHP, or write an XML configuration and compile that into PHP.  We’ll describe the latter option here.  Below is an template runtime-conf.xml, which should go into your Propel configuration folder (/path/to/laravel/app/config/propel/).

<?xml version="1.0" encoding="UTF-8"?>
<config>
<propel>
<datasources default="[DB_NAME]">
<datasource id="[DB_NAME]">
<adapter>[DB_ADAPTER]</adapter>
<!-- e.g., "sqlite", "mysql", "myssql", or "pgsql" -->
<connection>
<dsn>[DB_ADAPTER]:host=[HOST];port=[PORT];dbname=[DB_NAME];user=[DB_USER];password=[DB_PASS]</dsn>
<user>[DB_USER]</user>
<password>[DB_PASS]</password>
</connection>
</datasource>
</datasources>
<log>
<logger name="defaultLogger">
<type>stream</type>
<path>../app/config/propel/propel.log</path>
<level>300</level>
</logger>
</log>
</propel>
</config>

Note that the id attribute of the <datasource> element in runtime-conf.xml must correspond to the database name supplied in the schema.xml back in step 5.

Once you have saved the runtime-conf.xml, run the following command in /path/to/laravel/app/config/propel/ to compile your config.php file into the same directory:

$ ../../../vendor/bin/propel config:convert-xml --input-dir="." --input-file="runtime-conf.xml" --output-dir="." --output-file="config.php"

Step 8: Add Propel to your Laravel startup

To ensure Propel is loaded in during Laravel bootstrapping, simply require the config file you just generated by adding the following line to /path/to/laravel/app/start/global.php, just prior to requiring filters (near the bottom):

// setup Propel
require_once app_path().'/config/propel/config.php';

Step 9: Clear the Autoload

Finally, run the following in your Laravel install directory to recompile autoload to recognize the newly added models:

$ php artisan dump-autoload

That’s all, folks!

And with that, Propel’s ORM classes and capability should be available to use within your Laravel implementation. To access the Propel class itself, simply use the following namespaced identifier:

\Propel\Runtime\Propel