Search code examples
phpmigrationpropelbootstrapping

Is there a clean way to set up class autoloading when calling Phing to run a Propel 1 database migration?


I'm using migrations in Propel 1, which works well enough. For some data operations I need access to the Propel class, and to a parent class for common migration methods, but since I am requesting the migration from Phing, this seems to be non-trivial.

I call the migration using this code:

php \
    /project/backend-app/vendor/phing/phing/bin/phing.php \
    -f /project/backend-app/vendor/propel/propel1/generator/build.xml \
    -Dusing.propel-gen=true \
    -Dproject.dir=/project/backend-app/db \
    -Dpropel.database.url='mysql:dbname=job_crawler_test;host=127.0.0.1' \
    -Dpropel.buildtime.conf.file='buildtime/job_crawler_test.xml' \
    -quiet \
    migrate

That works fine, as long as I have autoloading and initialisation code at the start of every class file that needs it:

$root = realpath(__DIR__ . '/../..');
require_once $root . '/vendor/autoload.php';
require_once $root . '/lib/autoload.php';
set_include_path($root . '/lib' . PATH_SEPARATOR . get_include_path());
Propel::init($root . '/config/propel-conf.php');

OK, that works, but it's a bit messy - even though it's an official recommendation (see the bottom of the manual page link above). For cleanliness I'd like to strip this repetitive code block out.

I could of course just put this in a file and use a single require line in each file, which will reduce some of the cruft, but that's not very satisfying. I wonder if there's a -D flag I can pass to Phing, maybe like a bootstrap PHP file?

I wondered if -Dphp.classpath would do something, given that this seems to be a Phing core property, but that doesn't seem to make any difference.


Solution

  • @mario made a kind suggestion in the comments, which fixed this issue flawlessly. I moved the autoload preamble to a separate script:

    <?php
    
    /*
     * db/scripts/propel-migration.php
     *
     * Bootstrap file for Propel migrations that need autoloading or access
     * to the Propel sub-system
     */
    
    $root = realpath(__DIR__ . '/../..');
    require_once $root . '/vendor/autoload.php';
    require_once $root . '/lib/autoload.php';
    set_include_path($root . '/lib' . PATH_SEPARATOR . get_include_path());
    \Propel::init($root . '/config/JobCrawler-conf.php');
    

    I then modified the php call (i.e. rather than the phing.php call) thus:

    php \
        -d 'auto_prepend_file=/project/backend-app/db/scripts/propel-migration.php' \
        <rest of call here>
    

    The Propel migration classes now have full auto-loading and access to Propel's system without any pre-class boilerplate code.