What’s new in Propel 2.0?
Propel 2 represents an evolution of our favorite orm: it follows PSR-0, PSR-1, PRS-2, PSR-3 Php standards, it has a more rational architecture and some enhancements which improve its features and make your coding easier and more enjoyable. But it presents some backward compatibility breaks. Migrating your projects from Propel 1.x to Propel 2 is easy, but it needs some work and a bit of attention.
Quick update reference
This paragraph is written for all those programmers who hasn’t time to go into details, by now. It exposes only those changes about Propel public api, without considering internal changes. Of course, we suggest to read in deep this chapter later.
Firstly, install Propel 2 via Composer, so that you have an autoload function ready to use, Propel classes namespace already set up and you can easily adjust your model namespaces, via composer.json
.
New feature | Explanation | Action to do | More details |
---|---|---|---|
New console | Propel command line has new commands with brand new syntax. | Run propel command without arguments and get a look at the new command list. |
See paragraph New console. |
PSR-0 standard | Both Propel and generated model classes follow PSR-0 standard. All classes have their namespace. Propel doesn’t have its own autoload function anymore. | 1) Use a PSR-0 autoload function to auto-load Propel classes and generated model. You can use the Composer one or your own. 2) Rebuild your model with namespaces feature enabled and adjust your autoload to correctly map your model classes namespace. |
See paragraph Namespaces. |
Removed Peer classes | All Peer classes were removed. Now Active Query is the first class citizen to perform queries. All methods, previously contained in Peer classes, now have an equivalent in Query classes and all constants were moved from Peer to TableMap classes. | Review your code to remove peer methods and substitute them with the ActiveQuery equivalent ones (i.e. BookPeer::count() now is BookQuery::create()->count() ). |
See paragraph From Peer to ActiveQuery. |
Removed validators | To properly follow the Separation of Concerns best practice, the validator system has been removed from Propel core. | Remove all references to <validator> tag in your schema.xml and rebuild your model. Use an external library to validate your data (i.e. Zend Validator, Symfony Validator, Valitron or Respect). If you prefer to still define your validators inside your schema.xml , you can use the new Validate behavior . |
See Validate Behaviour |
Propel\Runtime\Propel class refactor | Some Propel class methods have been renamed and now we have a ServiceContainer class. |
If you don’t explicit call Propel class methods in your code, simply rebuild your model. Otherwise, review your code to find all those methods that now are included in ServiceContainer or have been renamed. |
See paragraph Service Container |
Configuration | Propel now comes with a new configuration system, which supports more formats (php, yaml, json, ini, xml). Now all configuration properties are in a single file. | Remove build.properties , runtime-conf.xml , buildtime-conf.xml and write all properties in propel.ext file (‘.ext’ means one of the supported extensions of your choice) |
Strongly recommended to read Configuration |
New console
Propel 2 comes with a brand new console, based on Symfony Console Component. As usual, you can see a full list of available commands simply running from your command line:
vendor/bin/propel
Here is an extract of the output:
config
config:convert-xml Transform the XML configuration to PHP code leveraging the ServiceContainer
database
database:reverse Reverse-engineer a XML schema file based on given database
graphviz
graphviz:generate Generate Graphviz files (.dot)
migration
migration:diff Generate diff classes
migration:down Execute migrations down
migration:migrate Execute all pending migrations
migration:status Get migration status
migration:up Execute migrations up
model
model:build Build the model classes based on Propel XML schemas
sql
sql:build Build SQL files
sql:insert Insert SQL statements
test
test:prepare Prepare the Propel test suite by building fixtures
If you’ve run bin/propel
, you can see some other commands, not included in the previous panel, listed in your shell output. These commands are still here for compatibility with Propel 1.x, but they’re deprecated and (probably) they’ll be removed in future versions.
The Phing tasks that you used at buildtime are now refactored to Commands. They work the same, but their name has changed:
Old task | New command |
---|---|
build-model | model:build |
build-sql | sql:build |
insert-sql | sql:insert |
convert-conf | config:convert-xml |
diff | migration:diff |
status | migration:status |
migrate | migration:migrate |
up | migration:up |
down | migration:down |
reverse | database:reverse |
PSR-0 and namespaces
Propel 2 follows the PSR-0 standard, both for its internal and generated classes.
If you’ve never worked with namespace before, please read the PHP official documentation about it.
Propel directory structure has changed to adhere to the standard and class namespaces map this. Propel has no more an internal autoload function and you can use any PSR-0 autoload you prefer. If you install Propel via Composer, a PSR-0 autoloader is automatically provided and configured and you can use it simply including the relative file:
<?php
require_once 'vendor/autoload.php';
You should adjust your schema.xml to work with namespaces, according to Propel documentation (see http://www.propelorm.org/cookbook/namespaces.html) and rebuild your model. Now you are able to easily autoload your model classes:
<?php
use My\Model\Namespace\ModelClass;
$class = new ModelClass();
From Peer to ActiveQuery
In earlier versions, Propel provided database queries via some generated Peer classes. Starting from version 1.5, a new object oriented query API, called Active Query, was introduced. This feature was immediately a first class citizen in Propel world, near the good old Peer classes. Now, Propel 2 leaves Peers, which are no longer available, and Active Query generated classes are the only Propel query api (of course, it’s still possible to directly execute SQL code).
If you’ve never used Active Query before, but only Peer classes, please read this blog post.
All Peer methods are moved into Query classes, if they didn’t already have an equivalent. All instance pool references, previously contained in Peer, now have its own Instance Pool Trait. All Peer constants, about tables structure, now are in TableMap classes.
Please, refer to Propel API and read the generated Query and TableMap classes, for other details.
Adapter, Connection and Statement classes
Propel 2 introduces its own abstraction layer, based on PDO interface, to overcome some PDO limitations. Besides, thanks to this feature, now it’s possible to write a database adapter based on a non-PDO extension.
Propel abstraction layer is based on the following classes:
Propel\Runtime\Connection\ConnectionInterface
: Propel connection object, based on PHP builtin PDO classPropel\Runtime\Connection\StatementInterface
: Propel statement object, dased on PHP builtin PDOStatement interfacePropel\Runtime\Adapter\AdapterInterface
: Propel interface for specific DBMS adapters
All PDO connection references, now are ConnectionInterface
onces and all PDOStatement objects now are StatementInterface
.
Propel class refactor and Service Container
ServiceContainer
class includes all methods, properties and constants relate to “shared” services: connections, adapters, data sources, database map, logger and profiler.
Some ServiceContainer informations was previously included in Propel
class:
Replace… | With… |
---|---|
Propel::CONNECTION_WRITE |
ServiceContainerInterface::CONNECTION_WRITE |
Propel::CONNECTION_READ |
ServiceContainerInterface::CONNECTION_READ |
Some static methods from the Propel
class have been renamed. Therefore, you must replace the following occurrences in your code:
Replace... With...
Propel::getDB($name) Propel::getAdapter($name)
Propel::getConnection($name, Propel::CONNECTION_READ) Propel::getReadConnection($name)
Propel::getConnection($name, Propel::CONNECTION_WRITE) Propel::getWriteConnection($name)
Propel::getDefaultDB() Propel::getDefaultDatasource()
The generated model is automatically updated once you rebuild your model.
Tip
Internally,Propel::getAdapter()
proxies toPropel::getServiceContainer()->getAdapter()
. ThePropel
class was refactored to keep only one static class and to be more extensible. It remains the easy entry point to all the necessary services provided by Propel.
Also, Propel::setConnection()
was removed.
The instruction to initialize Propel
<?php
Propel::init($configFilePath);
now is deprecated and should be replaced with
<?php
include $configFilePath;
$configFilePath
is the path to the PHP configuration generated by the config:convert
command.
Configuration
The way of configuring Propel is changed. Now there’s only one configuration file and more formats are supported. You can write your configuration file in plain php, ini, json, yaml or xml format. Read the Configuration chapter of the documentation and configuration reference chapter for a complete explanation of configuration properties.
Migrations and reverse engineering
In addition to Mysql, now migrations system supports SQLite and PostgreSQL.
The schema reverse engineering now supports also SQLite, so you can generate a schema.xml
file from an existing SQLite database.
Other Refactors
All the refactors, described in this paragraph, affect your project only if you extended one of the modified classes. In all the other cases, just rebuild your model.
Builders renamed
The classes used by Propel internally to build the object model were renamed. This affects your project if you extended one of these classes.
Replace… | With… |
---|---|
OMBuilder.php | AbstractOMBuilder.php |
ObjectBuilder.php | AbstractObjectBuilder.php |
PeerBuilder.php | removed |
PHP5ExtensionObjectBuilder.php | ExtensionObjectBuilder.php |
PHP5ExtensionPeerBuilder.php | removed |
PHP5InterfaceBuilder.php | InterfaceBuilder.php |
PHP5MultiExtendObjectBuilder.php | MultiExtendObjectBuilder.php |
PHP5ObjectBuilder.php | ObjectBuilder.php |
PHP5PeerBuilder.php | removed |
PHP5TableMapBuilder.php | TableMapBuilder.php |
Base classes reorganized
Base classes are generated in a Base
directory, and base classes are no more prefixed by Base
.
Parameters basePrefix
and namespaceOm
have been removed
Model\Database methods renamed
Before:
<?php
public function setAppData(AppData $parent)
After:
<?php
public function setParentSchema(Schema $parent)
Before:
<?php
public function getAppData()
After:
<?php
public function getParentSchema()
Model\AppData class has been renamed to Schema
The AppData::joinAppDatas
method has been renamed to Schema::joinSchemas
.
Before:
<?php
public function joinAppDatas($ads)
After:
<?php
public function joinSchemas($schemas)
Builder\Util\XmlToAppData class has been renamed to SchemaReader
Both SchemaReader::parseString
and SchemaReader::parseFile
methods return
a Propel\Generator\Model\Schema
object instead of a Propel\Generator\Model\AppData
object.
Util\SchemaValidator constructor signature changed
Before:
<?php
public function __construct(AppData $appData)
After:
<?php
public function __construct(Schema $schema)
ActiveQuery\Criteria::addOr refactor
Propel\Runtime\ActiveQuery\Criteria::addOr
operates only on existing conditions, where prior it would OR
to a condition to on the same column (if it existed).
E.g.
<?php
$criteria->add('column1', 'value');
$criteria->add('column2', 'value');
$criteria->addOr('column1', 'value'); // this used to be OR`ed to the first add (matched by name)
All base object methods have been merged in generated Base Object classes. This could break, behaviors that call parent
methods
Om\Persistent Interface replaced by Om\ActiveRecordInterface
All methods from Propel\Runtime\Om\Persistent
Interface have been removed.
All Base Object classes now implements Propel\Runtime\Om\ActiveRecordInterface
this could be used to identify a Propel Object.
Util\PropelModelPager::count()
Propel\Runtime\Util\PropelModelPager::count()
now return the number of items in the collection.
To get the old behavior use Propel\Runtime\Util\PropelModelPager::getNbResults()
.
But also…
The following methods have been removed (under the Propel
namespace):
Generator\Model\Table::containsColumn
Generator\Model\VendorInfo::addParameter
Generator\Model\Column::setTypeFromString
Generator\Model\Column::getPropelType
Generator\Model\Column::getDefaultSetting
Generator\Model\Column::makeList
Generator\Model\ForeignKey::getLocalColumnNames
Generator\Model\ForeignKey::getForeignColumnNames
Generator\Model\Table::printPrimaryKey
Generator\Model\Table::printList
Generator\Model\PropelTypes::getCreoleTypes
Runtime\Om\BaseObject
The following methods and classes have been renamed (under the Propel
namespace):
Replace…. | With… |
---|---|
Generator\Model\ScopedElement |
Generator\Model\ScopedMappingModel |
Generator\Model\XmlElement |
Generator\Model\MappingModel |
Generator\Model\XmlElement::loadFromXml |
Generator\Model\MappingModel::loadMapping |
Generator\Model\Column::printSize |
Generator\Model\Column::getSizeDefinition |
Generator\Model\Column::getStudlyPhpName |
Generator\Model\Column::getCamelCaseName |
Generator\Model\Domain::printSize |
Generator\Model\Domain::getSizeDefinition |