Propel and patForms integrated: powerful form generation
posted: May 3rd, 2005 · by: Sven
Propel is a php object persistence layer that enables you to:
- generate an xml database scheme from an existing database,
- generate ORM object and peer classes from this scheme and
- then already use these classes as a (part of the) model of your application
Propel lets you describe and configure in detail how your classes are to be build. You can define validatiors for example, against which you can check your objects before you save them to the database. And you can define foreign key table relations and resolve them in a really simple manner.
The form generation toolkit patForms on the other side comes along with lots of capabilities to create flexible forms, nicely separated into layers by design and easily extensible. patForms itself provides ready-made form validation rules, tools to populate form elements like Select boxes from Datasources and much more.
Plugging these both tools together makes up a powerful combination.
5 steps to heaven
Let’s have a look at what these both tools can do for you when they join forces.
- You simply throw a Propel class(name) into a patForms_Definition_Propel. This will look up information that’s necessary to build a form and write it to a form definition xml file on the fly.
- Once created you can tweak the form definition xml file according to your needs. For example you might want to rename labels, descriptions or display different values from related tables (linked by foreign keys).
- But you don’t need to tweak anything. Yet, handing this definition over to a patForms_Creator_Definition will create a complete and working patForms instance – full fledged with validation rules (both client- and server-side) and Html select boxes populated from related tables (via foreign keys).
- This patForms instance is able to connect to a patForms_Storage_Propel, that will (at present) look at the $_POST and $_GET vars and automagically retrieve, validate and save objects for you, populating the form from the object or – vice versa – populating the object from the form values.
- You can now render the patForms instance by using one of the provided patForms_Renderers and display the form elements and data using a template engine of your choice.
You’re done.
New data has been validated before it has been saved to the database. If a validation error has occured, the error will be displayed by your form template and nothing has gone to the database. Existing objects have been fetched from the database, have been validated and updated.
Yes, life can be that easy :)
To say the least: we are really impressed about how seamlessly everything in Propel and patForms (both being great projects for themselves) fits together with only some minor changes to both of them. The good design pays out on both sides, keeping the libraries flexible and extensible.
7 lines of code
Wanna see some code? Ok, let’s do it together …
By now, it takes less than 10 lines of code to create a working “Add a new book” form for the bookstore example application shipped with Propel:
$definition = patForms_Definition_Propel::create(array(
'name' => 'book', 'filename' => $filename));
$storage = patForms::createStorage('Propel');
$storage->setStorageLocation('BookPeer');
$form = &patForms::createCreator('Definition')->create($definition);
$form->setRenderer(patForms::createRenderer('Array'));
$form->setStorage($storage);
The result will look like this:

As you can see, there are two related tables (foreign keys) defined for the Propel Book entity: Author and Publisher, both referenced by ID. For each of them a Select box is created and already populated with the IDs available from those tables.

Some very little changes
Of cause, we’ll want to show something different than these IDs here. So, we’ll tweak the form definition xml file, that’s already been created on-the-fly.
For the AuthorId, we’ll change the lines
<members> <tag>Id</tag> </members> <mask>%s</mask>
to something like this:
<members> <tag>FirstName</tag> <tag>LastName</tag> </members> <mask>%s (%s)</mask>
And (after having additionally changed some labels and titles) we’ll get:

Save new and edit existing
When we fill in some valid form data and click the “Save Form” button, the data gets already saved to the database table. (This will be painlessly done by a patForms_Storage_Propel driver by simply registering it to the form.)
By the way … want an “Edit an existing book” form instead?
Just add one single line before rendering the form to the template:
$form->setValues(array('Id' => 1)); // the primary key
This will display the Book with the ID 1 and we will already be able to edit existing data and save it back to the database:

Even shorter?
It’s no big deal to further imagine a patForms_Factory::create() method, that could be called by something like this:
$form = patForms_Factory::create(array(
'type' => 'Propel',
'class' => 'Book',
'renderer' => 'Array',
'primary' => array('Id', 1)
));
One call for a complete and full-fledged, auto-validated form that’s defined by the database scheme and some very simple additional changes in an xml file.
Hey, don’t say that’s not really cool :)
Go and play with it …
You will need working installations of:
- Propel: http://propel.phpdb.org [edit: Please use the latest SVN version of Propel since we are using Propel enhancements that aren’t in the current release yet.]
- patForms http://www.php-tools.net/site.php?file=patForms [edit: Please use the latest SVN version of patForms
- patTemplate http://www.php-tools.net/site.php?file=patTemplate
- Xml_Serializer http://pear.php.net/package/XML_Serializer
... as well as a build version of the Propel Bookstore project (tested with mysql). Have a look at the Propel docs to get started with the Bookstore build.
But don’t use it!
Ok. :)
This is a proof of concept. There are several flaws and missing stuff, things to be discussed and solved. And yes: patForms itself is considered to be in alpha …
But with some extra work here and there these both tools will make up a really great team that can help you to get started very fast with a working prototype for your data(base)-driven web application.
Feedback?
Do you like this? Then please digg it!
Jeremy Seitz said June 2nd, 2005 at 02:24 AM ¶
I've been looking around a while for a good PHP framework (like DBObjects and HTMLQuickform), but this looks much more flexible. I will definitely try it out.
Is this being used for any live web sites? How does it perform, in terms of time saved and flexibility? With some frameworks, it can be difficult to do fancy interface things, like if you want related drop-downs (like, city/state) with javascript onChange()... are there ways to override the default renderers?
Sven said June 2nd, 2005 at 03:59 AM ¶
Jeremy,
this still is in pre-alpha state, really. So there's no performance optimization done yet (not even performance tests) and it's not used in any live pages.
Propel is known to be not as fast as PEAR DB. On the other hand, you will get a rock solid, very straight-forward and objectoriented object mapping layer (which is the reason for me to choose Propel instead of PEAR DB or other solutions). Propel is matured and has brilliant support via the mailing lists - Hans Lellelid and others are doing a great job over there.
PatForms also is in alpha state but under active development. It will already integrate nicely with patTemplate (also matured and used in production) and a currently boosted state-of-the art framework (still called "patPortal", the name will change in future).
The php-tools (pat-stuff) actually is very flexible because everything is nicely separated by design. You might want to have a look at the patForms design. Builder, Renderer, the form object itself, Storage etc. are all separate and extensible classes.
Drop me a mail if there's anything I can assist you with. Any reports on how this works for you also are very appreciated.
Stephan Schmidt said June 8th, 2005 at 03:23 PM ¶
Jeremy,
patForms is extremely extendible and the related drop-down functionilty is already available as a seperate rule, which allows you to connect an input field/radion group/whatever with a dropdown. Rules are able to generate javascript so the validation and user-interaction can be done on the client and the server.
Stephan
Tom Balon said October 6th, 2005 at 12:02 AM ¶
I've been using propel for a new project to define and collect pricing information on various products. I use hibernate on the java side, and I really appreciate propel.
The combination of patForms and propel sounds great. I wish I had this a year or so ago when I was building lots of dynamic php/html forms that needed to be updated via the web.
Tom
Michel Feldheim said February 1st, 2006 at 01:13 PM ¶
I am feeling like Alice in wonderland, a lot of new ways for developement, a lot of new innovative ideas.. nice!! Thanks to the pat team, thanks to the propel team.. i love you guys. Will enter active developement to help leaving alpha/beta states of many interesting packages
Ed Finkler said August 23rd, 2006 at 05:42 AM ¶
Looks cool. This is very similar to DBDataObjectFormBuilder, which basically combines DBDataObject and HTMLQuickForms.
moepMan said April 1st, 2008 at 09:46 AM ¶
as of 2008 the patform/propel team is not working together fine anymore
generation of a simple form is working as usual, but foreign keys and pre-loaded values are not working.
is there any development team left, the last release sems to be from 2005