JonBlog
Thoughts on website ideas, PHP and other tech topics, plus going car-free
Generating Propel 1.5 classes programmatically
Categories: PHP

I am currently working on a project proposal that will allow the user to design and build their own Propel database, and to connect it to a database instance. I’d originally intended to use the propel-gen script plus a re-written build.properties file on every call, but I decided that this wasn’t very elegant, and that I should figure out how to do it in code. Took a few hours – here’s what I’ve got:

// Include Propel Generator and Phing command
$projectPath = realpath( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . '..' );
set_include_path(
 get_include_path() . PATH_SEPARATOR .
 $projectPath . '/lib/propel-1.5/generator/lib' . PATH_SEPARATOR .
 $projectPath . '/lib/phing-2.4/classes'
);
require_once 'phing/Phing.php';
require_once 'phing/Project.php';
require_once 'phing/types/FileSet.php';
require_once 'phing/system/io/PhingFile.php';
require_once 'phing/system/util/Properties.php';
require_once 'task/PropelOMTask.php';

// Set db type, schema and output folder here
$targetDb = 'pgsql';
$schemaFolder = $projectPath . '/database';
$schemas = "schema.xml,model.schema.xml";
$outputFolder = $projectPath . "/databases";
$propertiesFile = $projectPath . '/lib/propel-1.5/generator/default.properties';

// Set custom props here
$customProps = array(
    'propel.database' => $targetDb,                // Required for ${} replacements
);

echo "Target db: \t\t$targetDb\n";
echo "Schema(s): \t\t$schemas\n";
echo "Output folder: \t\t$outputFolder\n";
echo "Properties folder:\t$propertiesFile\n";

Phing::startup();
$project = new Project();

// Read in default properties file, and add custom values
$properties = new Properties();
$properties->load(new PhingFile($propertiesFile));
foreach( $customProps as $key => $value ) {
    $properties->put($key, $value);
}

// Then swap out placeholder values
foreach ( $properties->getProperties() as $key => $value )
{
    $value = ProjectConfigurator::replaceProperties($project, $value, $properties->getProperties());
    $project->setProperty($key, $value);
}

$OMTask = new PropelOMTask();
$OMTask->setProject($project);
$fileSet = new FileSet();
$fileSet->setDir($schemaFolder);
$fileSet->setIncludes($schemas);
$OMTask->addSchemaFileset($fileSet);
$OMTask->setPackageObjectModel('1');
$OMTask->setOutputDirectory(new PhingFile($outputFolder));
$OMTask->main();

I’ve had a problem including multiple schemas with joins between them, but I’ll hopefully fix that in a jiffy.

Update: the multiple schemas issue is fixed. The method setPackageObjectModel must be called, and as of Propel 1.5.x, this requires a ‘1’ string, rather than a Boolean true; the intention is to have this fixed in the next major version (see here).

Update 23rd Feb: I’ve added in the “phing-X/classes” folder as a PHP include folder. This ensures the Phing dependencies are correctly included using a local installation (i.e. no PEAR installation required).

Leave a Reply