Zend Framework 1.x + Doctrine Migrations 2.x – How to ?

Hello everybody!

Hounddog (on irc freenode #dojo) and me have worked hard to make something useful to you!

I’m pretty sure some of you already encountered that situation when you feel like poping your eyes out because of incomplete documentations, or lack of help/support…
If you are reading this, you most likely were about to throw away your computer in anger… Fear not! We will try to save your day :)

Just follow the steps :

1. You can have a look at my repository on github : Doctrine Migration Scripts for Zend Framework support

2. You have now two choices :
– Integrates Migrations into your already existing Doctrine folder, in this path : Doctrine/DBAL/Migrations.
– Use Migrations as Standalone (in that case jump to step xxx).

///////// USING MIGRATIONS INSIDE DOCTRINE FOLDER /////////

3. So now basically you should have something like that :
– Doctrine/DBAl/Migrations
– Doctrine/DBAl/Migrations/Configuration
– Doctrine/DBAl/Migrations/Tools
– Doctrine/DBAl/Migrations/Tools/Console
– Doctrine/DBAl/Migrations/Tools/Console/Command

4. In the scripts directory you should have a file called ZendConfiguration.php (if not something went wrong go back to step 1)

5. If you have zend framework installed and running, with doctrine, you might want to create a file called doctrine.php (or whatever you like if you know already what we are talking about, or you could use the one provided in the scripts folder).

6. doctrine.php should look like that (DO NOT FORGET TO EDIT THE FILE AND CHANGE THE PATHS) :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php
// Display errors ?
//ini_set('display_errors', 1);
//error_reporting(E_ALL | E_STRICT);

// Define path to application directory
// DO NOT FORGET TO EDIT
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH','/path/to/your/application');

// Define application environment
defined('APPLICATION_ENV')
    || define(
        'APPLICATION_ENV',
        (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development')
    );


// Ensure library/ is on include_path
// DO NOT FORGET TO EDIT
set_include_path(
    '/path/to/where/your/zend/library/is' . PATH_SEPARATOR .
    '/path/to/Doctrine' . PATH_SEPARATOR .
    get_include_path()
);

// Requiring a batch of Classes we will need for namespacing
use Doctrine\Common\ClassLoader,
    Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper,
    Doctrine\ORM\Version,
    Doctrine\ORM\Tools\Console\ConsoleRunner,
    Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper,
    Symfony\Component\Console\Helper\HelperSet,
    Symfony\Component\Console\Helper\DialogHelper,
    Symfony\Component\Console\Application;

// namespacing migrations commands we will be needing later
use Doctrine\DBAL\Migrations\Tools\Console\Command\DiffCommand,
    Doctrine\DBAL\Migrations\Tools\Console\Command\ExecuteCommand,
    Doctrine\DBAL\Migrations\Tools\Console\Command\GenerateCommand,
    Doctrine\DBAL\Migrations\Tools\Console\Command\MigrateCommand,
    Doctrine\DBAL\Migrations\Tools\Console\Command\StatusCommand,
    Doctrine\DBAL\Migrations\Tools\Console\Command\VersionCommand;

// We need the Doctrine ClassLoader to manage autoloading
require_once 'Doctrine/Common/ClassLoader.php';

// Load Doctrine
$classLoader = new ClassLoader('Doctrine');
$classLoader->register();

// Load Symfony tools
$classLoader = new ClassLoader('Symfony', 'Doctrine');
$classLoader->register();

// Load Migration
$classLoader = new ClassLoader('Migrations', 'Doctrine/DBAL/');
$classLoader->register();

// Zend_Application
require_once 'Zend/Application.php';

// Create application
// DO NOT FORGET TO EDIT
$application = new Zend_Application(
    APPLICATION_ENV, '/path/to/application.ini'
);

// Bootstrap
$application->bootstrap();

// loading doctrine resource, sometimes called entityManager
// DO NOT FORGET TO EDIT, set the resource to your entityManager
$em = $application->getBootstrap()->getResource('db');

// Load doctrine helpers
$helperSet = new HelperSet(array(
    'db'     => new ConnectionHelper($em->getConnection()),
    'em'     => new EntityManagerHelper($em),
    'dialog' => new DialogHelper()
));

$cli = new Application('Doctrine Command Line Interface', Version::VERSION);
$cli->setCatchExceptions(true);
$cli->setHelperSet($helperSet);

// We are settign the commands to bypass the configuration process and
// directly use our ZendConfiguration
// Just make sure to load from where the file actually is
require_once('ZendConfiguration.php');
$connexion = $em->getConnection();
$zendConfig = new ZendConfiguration($connexion);

// injecting configurations necessary to our ZendConfiguration
// Pass the Application.ini Parameters to our Configuration
$applicationConfig = new Zend_Config(
    $application->getBootstrap()->getOptions(), true
);
// DO NOT FORGET TO EDIT, if needed
$zendConfig->setConfig($applicationConfig->resources->db->migration);
// Here we just need to put some string because the parameter is not optional
// though will not need it. Just need to call the function
$zendConfig->load('zend');

// Setting up Migrations Commands
$diffCmd = new DiffCommand();
$diffCmd->setMigrationConfiguration($zendConfig);

$executeCmd = new ExecuteCommand();
$executeCmd->setMigrationConfiguration($zendConfig);

$generateCmd = new GenerateCommand();
$generateCmd->setMigrationConfiguration($zendConfig);

$migrateCmd = new MigrateCommand();
$migrateCmd->setMigrationConfiguration($zendConfig);

$statusCmd = new StatusCommand();
$statusCmd->setMigrationConfiguration($zendConfig);

$versionCmd = new VersionCommand();
$versionCmd->setMigrationConfiguration($zendConfig);


// Register migration Commands
$cli->addCommands(array(
    $diffCmd, $executeCmd, $generateCmd, $migrateCmd, $statusCmd, $versionCmd
));

// Register All Doctrine Commands
ConsoleRunner::addCommands($cli);

// Runs console application
$cli->run();

for some more information you might want to check this article : Setting up doctrine 2 cli for zend framework

7. We now have to tweak your Zend Framework application.ini file. Add these few lines :

1
2
3
4
5
6
7
8
9
10
; ------------------------------------------------------------------------------
; Doctrine Migrations Configuration
; ------------------------------------------------------------------------------
resources.db.migration.name = "YourSoft (development) Database Migrations"
resources.db.migration.tableName = "doctrine_migration_versions"
resources.db.migration.namespace = "DoctrineMigrations"
resources.db.migration.directory = APPLICATION_PATH "/path/to/migrationsClass/directory"
;set the following two properties if you want to do manual naming on migration classes
;resources.doctrine.migration.migrations.migration1.version = "20111020071337"
;resources.doctrine.migration.migrations.migration1.class = "DoctrineMigrations\VersionNewMigration"

8. Now, try running from the scripts directory :

1
php doctrine.php list migrations

As a result, you should see the commands available, something like that :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Doctrine Command Line Interface version 2.2.1

Usage:
  [options] command [arguments]

Options:
  --help           -h Display this help message.
  --quiet          -q Do not output any message.
  --verbose        -v Increase verbosity of messages.
  --version        -V Display this program version.
  --ansi              Force ANSI output.
  --no-ansi           Disable ANSI output.
  --no-interaction -n Do not ask any interactive question.

Available commands for the "migration" namespace:
  migrations:diff       Generate a migration by comparing your...
  migrations:execute    Execute a single migration version up or down manually.
  migrations:generate   Generate a blank migration class.
  migrations:migrate    Execute a migration to a specified version...
  migrations:status     View the status of a set of migrations.
  migrations:version    Manually add and delete migration versions...

9. You are now supposed to cry of joy and let a Victory shout be heard by the whole company :)

///////// USING MIGRATIONS STANDALONE /////////
Oh well…
To Be Done Later, I feel sorry for you though…
Jokes asides, you should be able to deal with it even with what explained above :)

Share and Enjoy

This entry was posted in Doctrine, PHP, ZendFramework. Bookmark the permalink.

3 Responses to Zend Framework 1.x + Doctrine Migrations 2.x – How to ?

  1. shah says:

    Hi am a new be in zend+doctrine for migration i configure my doctrine.php following’
    My doctrine.php and ZendConfiguration.php file location is
    “E:\xampp\htdocs\zenddoctrine\bin\”
    <?php
    /*
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    * This software consists of voluntary contributions made by many individuals
    * and is licensed under the LGPL. For more information, see
    * .
    */

    define(‘APPLICATION_ENV’, ‘development’);

    define(‘APPLICATION_PATH’, realpath(dirname(__FILE__) . ‘/../application’));

    set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . ‘/../library’),
    get_include_path(),
    )));

    // Doctrine and Symfony Classes
    require_once ‘Doctrine/Common/ClassLoader.php’;
    $classLoader = new \Doctrine\Common\ClassLoader(‘Doctrine’, APPLICATION_PATH . ‘/../library’);
    $classLoader->register();
    $classLoader = new \Doctrine\Common\ClassLoader(‘Symfony’, APPLICATION_PATH . ‘/../library/Doctrine’);
    $classLoader->register();
    $classLoader = new \Doctrine\Common\ClassLoader(‘Entities’, APPLICATION_PATH . ‘/models’);
    $classLoader->setNamespaceSeparator(‘_’);
    $classLoader->register();
    $classLoader = new \Doctrine\Common\ClassLoader(‘MyDataFixtures’, APPLICATION_PATH . ‘/../library’);
    $classLoader->register();

    $classLoader = new \Doctrine\Common\ClassLoader(‘Migrations’, APPLICATION_PATH . ‘/../library/Doctrine/DBAL/’);
    $classLoader->register();

    // Zend Components
    require_once ‘Zend/Application.php’;

    // Create application
    $application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . ‘/configs/application.ini’
    );

    // bootstrap doctrine
    $application->getBootstrap()->bootstrap(‘doctrine’);
    $em = $application->getBootstrap()->getResource(‘doctrine’);

    // generate the Doctrine HelperSet
    $helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
    ‘db’ => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
    ’em’ => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em),
    ‘dialog’ => new \Symfony\Component\Console\Helper\DialogHelper()
    ));

    //\Doctrine\ORM\Tools\Console\ConsoleRunner::run($helperSet);

    $cli = new \Symfony\Component\Console\Application(‘Doctrine Command Line Interface’, Doctrine\ORM\Version::VERSION);
    $cli->setCatchExceptions(true);
    $cli->setHelperSet($helperSet);

    // We are settign the commands to bypass the configuration process and
    // directly use our ZendConfiguration
    require_once(‘ZendConfiguration.php’);
    $connexion = $em->getConnection();

    $zendConfig = new ZendConfiguration($connexion);

    // injecting configurations necessary to our ZendConfiguration
    // Pass the Application.ini Parameters to our Configuration
    $applicationConfig = new Zend_Config($application->getBootstrap()->getOptions(), true);
    $zendConfig->setConfig($applicationConfig->resources->migration);
    // Here we just need to put some string because the parameter is not optional
    // though will not need it. Just need to call the function
    $config->load(‘zend’);

    // Setting up Migrations Commands
    $diffCmd = new Doctrine\DBAL\Migrations\Tools\Console\Command\DiffCommand();
    $diffCmd->setMigrationConfiguration($zendConfig);

    $executeCmd = new Doctrine\DBAL\Migrations\Tools\Console\Command\ExecuteCommand();
    $executeCmd->setMigrationConfiguration($zendConfig);

    $generateCmd = new Doctrine\DBAL\Migrations\Tools\Console\Command\GenerateCommand();
    $generateCmd->setMigrationConfiguration($zendConfig);

    $migrateCmd = new Doctrine\DBAL\Migrations\Tools\Console\Command\MigrateCommand();
    $migrateCmd->setMigrationConfiguration($zendConfig);

    $statusCmd = new Doctrine\DBAL\Migrations\Tools\Console\Command\StatusCommand();
    $statusCmd->setMigrationConfiguration($zendConfig);

    $versionCmd = new Doctrine\DBAL\Migrations\Tools\Console\Command\VersionCommand();
    $versionCmd->setMigrationConfiguration($zendConfig);

    // Register migration Commands
    $cli->addCommands(array(
    $diffCmd, $executeCmd, $generateCmd, $migrateCmd, $statusCmd, $versionCmd
    ));

    // Register All Doctrine Commands
    ConsoleRunner::addCommands($cli);

    // Runs console application
    $cli->run();

    But I show the following error:

    Catchable fatal error: Argument 1 passed to ZendConfiguration::setConfig() must
    be an instance of Zend_Config, null given, called in E:\xampp\htdocs\zenddoctrin
    e\bin\doctrine.php on line 82 and defined in E:\xampp\htdocs\zenddoctrine\bin\Ze
    ndConfiguration.php on line 22

    How i solve this problem

    Thanks
    Shah

    • PEM says:

      As you can see the migration configuration is supposed to be put in the application.ini of your zend framework installation.

      1
      2
      $applicationConfig = new Zend_Config($application->getBootstrap()->getOptions(), true);
      $zendConfig->setConfig($applicationConfig->resources->migration);

      note the : $applicationConfig->resources->migration
      in our example it is : $applicationConfig->resources->db->migration

      if you typed resources.db.migration in your app.ini then your problem is here :)

  2. Mauricio Piber says:

    important topic but with a very bad explanation.

Leave a Reply

Your email address will not be published. Required fields are marked *