text:
<?php
/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Tools\Console\Command\ClearCache;

use Symfony\Component\Console\Input\InputArgument,
    Symfony\Component\Console\Input\InputOption,
    Symfony\Component\Console;

/**
 * Command to clear the result cache of the various cache drivers.
 *
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link    www.doctrine-project.org
 * @since   2.0
 * @version $Revision$
 * @author  Benjamin Eberlei <kontakt@beberlei.de>
 * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @author  Jonathan Wage <jonwage@gmail.com>
 * @author  Roman Borschel <roman@code-factory.org>
 */
class ResultCommand extends Console\Command\Command
{
    /**
     * @see Console\Command\Command
     */
    protected function configure()
    {
        $this
        ->setName('orm:clear-cache:result')
        ->setDescription('Clear result cache of the various cache drivers.')
        ->setDefinition(array(
            new InputOption(
                'id', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
                'ID(s) of the cache entry to delete (accepts * wildcards).', array()
            ),
            new InputOption(
                'regex', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
                'Delete cache entries that match the given regular expression(s).', array()
            ),
            new InputOption(
                'prefix', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
                'Delete cache entries that have the given prefix(es).', array()
            ),
            new InputOption(
                'suffix', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
                'Delete cache entries that have the given suffix(es).', array()
            ),
        ))
        ->setHelp(<<<EOT
Clear result cache of the various cache drivers.
If none of the options are defined, all cache entries will be removed.
EOT
        );
    }

    /**
     * @see Console\Command\Command
     */
    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
    {
        $em = $this->getHelper('em')->getEntityManager();
        $cacheDriver = $em->getConfiguration()->getResultCacheImpl();

        if ( ! $cacheDriver) {
            throw new \InvalidArgumentException('No Result cache driver is configured on given EntityManager.');
        }

        if ($cacheDriver instanceof \Doctrine\Common\Cache\ApcCache) {
            throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
        }

        $outputed = false;

        // Removing based on --id
        if (($ids = $input->getOption('id')) !== null && $ids) {
            foreach ($ids as $id) {
                $output->write($outputed ? PHP_EOL : '');
                $output->write(sprintf('Clearing Result cache entries that match the id "<info>%s</info>"', $id) . PHP_EOL);

                $deleted = $cacheDriver->delete($id);

                if (is_array($deleted)) {
                    $this->_printDeleted($output, $deleted);
                } else if (is_bool($deleted) && $deleted) {
                    $this->_printDeleted($output, array($id));
                }

                $outputed = true;
            }
        }

        // Removing based on --regex
        if (($regexps = $input->getOption('regex')) !== null && $regexps) {
            foreach($regexps as $regex) {
                $output->write($outputed ? PHP_EOL : '');
                $output->write(sprintf('Clearing Result cache entries that match the regular expression "<info>%s</info>"', $regex) . PHP_EOL);

                $this->_printDeleted($output, $cacheDriver->deleteByRegex('/' . $regex. '/'));

                $outputed = true;
            }
        }

        // Removing based on --prefix
        if (($prefixes = $input->getOption('prefix')) !== null & $prefixes) {
            foreach ($prefixes as $prefix) {
                $output->write($outputed ? PHP_EOL : '');
                $output->write(sprintf('Clearing Result cache entries that have the prefix "<info>%s</info>"', $prefix) . PHP_EOL);

                $this->_printDeleted($output, $cacheDriver->deleteByPrefix($prefix));

                $outputed = true;
            }
        }

        // Removing based on --suffix
        if (($suffixes = $input->getOption('suffix')) !== null && $suffixes) {
            foreach ($suffixes as $suffix) {
                $output->write($outputed ? PHP_EOL : '');
                $output->write(sprintf('Clearing Result cache entries that have the suffix "<info>%s</info>"', $suffix) . PHP_EOL);

                $this->_printDeleted($output, $cacheDriver->deleteBySuffix($suffix));

                $outputed = true;
            }
        }

        // Removing ALL entries
        if ( ! $ids && ! $regexps && ! $prefixes && ! $suffixes) {
            $output->write($outputed ? PHP_EOL : '');
            $output->write('Clearing ALL Result cache entries' . PHP_EOL);

            $this->_printDeleted($output, $cacheDriver->deleteAll());

            $outputed = true;
        }
    }

    private function _printDeleted(Console\Output\OutputInterface $output, array $items)
    {
        if ($items) {
            foreach ($items as $item) {
                $output->write(' - ' . $item . PHP_EOL);
            }
        } else {
            $output->write('No entries to be deleted.' . PHP_EOL);
        }
    }
}


text:
<?php
/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;

use Symfony\Component\Console\Input\InputArgument,
    Symfony\Component\Console\Input\InputOption,
    Symfony\Component\Console\Input\InputInterface,
    Symfony\Component\Console\Output\OutputInterface,
    Doctrine\ORM\Tools\SchemaTool;

/**
 * Command to drop the database schema for a set of classes based on their mappings.
 *
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link    www.doctrine-project.org
 * @since   2.0
 * @version $Revision$
 * @author  Benjamin Eberlei <kontakt@beberlei.de>
 * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @author  Jonathan Wage <jonwage@gmail.com>
 * @author  Roman Borschel <roman@code-factory.org>
 */
class DropCommand extends AbstractCommand
{
    /**
     * @see Console\Command\Command
     */
    protected function configure()
    {
        $this
        ->setName('orm:schema-tool:drop')
        ->setDescription(
            'Drop the complete database schema of EntityManager Storage Connection or generate the corresponding SQL output.'
        )
        ->setDefinition(array(
            new InputOption(
                'dump-sql', null, InputOption::VALUE_NONE,
                'Instead of try to apply generated SQLs into EntityManager Storage Connection, output them.'
            ),
            new InputOption(
                'force', null, InputOption::VALUE_NONE,
                "Don't ask for the deletion of the database, but force the operation to run."
            ),
            new InputOption(
                'full-database', null, InputOption::VALUE_NONE,
                'Instead of using the Class Metadata to detect the database table schema, drop ALL assets that the database contains.'
            ),
        ))
        ->setHelp(<<<EOT
Processes the schema and either drop the database schema of EntityManager Storage Connection or generate the SQL output.
Beware that the complete database is dropped by this command, even tables that are not relevant to your metadata model.
EOT
        );
    }

    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
    {
        $isFullDatabaseDrop = ($input->getOption('full-database'));

        if ($input->getOption('dump-sql') === true) {
            if ($isFullDatabaseDrop) {
                $sqls = $schemaTool->getDropDatabaseSQL();
            } else {
                $sqls = $schemaTool->getDropSchemaSQL($metadatas);
            }
            $output->write(implode(';' . PHP_EOL, $sqls) . PHP_EOL);
        } else if ($input->getOption('force') === true) {
            $output->write('Dropping database schema...' . PHP_EOL);
            if ($isFullDatabaseDrop) {
                $schemaTool->dropDatabase();
            } else {
                $schemaTool->dropSchema($metadatas);
            }
            $output->write('Database schema dropped successfully!' . PHP_EOL);
        } else {
            $output->write('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL . PHP_EOL);

            if ($isFullDatabaseDrop) {
                $sqls = $schemaTool->getDropDatabaseSQL();
            } else {
                $sqls = $schemaTool->getDropSchemaSQL($metadatas);
            }

            if (count($sqls)) {
                $output->write('Schema-Tool would execute ' . count($sqls) . ' queries to drop the database.' . PHP_EOL);
                $output->write('Please run the operation with --force to execute these queries or use --dump-sql to see them.' . PHP_EOL);
            } else {
                $output->write('Nothing to drop. The database is empty!' . PHP_EOL);
            }
        }
    }
}

repo_name: michael-romer/zf-boilerplate

repo_language: PHP

mime_type: text/html


text:
<?php
/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;

use Symfony\Component\Console\Input\InputArgument,
    Symfony\Component\Console\Input\InputOption,
    Symfony\Component\Console\Input\InputInterface,
    Symfony\Component\Console\Output\OutputInterface,
    Doctrine\ORM\Tools\SchemaTool;

/**
 * Command to create the database schema for a set of classes based on their mappings.
 *
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link    www.doctrine-project.org
 * @since   2.0
 * @version $Revision$
 * @author  Benjamin Eberlei <kontakt@beberlei.de>
 * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @author  Jonathan Wage <jonwage@gmail.com>
 * @author  Roman Borschel <roman@code-factory.org>
 */
class CreateCommand extends AbstractCommand
{
    /**
     * @see Console\Command\Command
     */
    protected function configure()
    {
        $this
        ->setName('orm:schema-tool:create')
        ->setDescription(
            'Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.'
        )
        ->setDefinition(array(
            new InputOption(
                'dump-sql', null, InputOption::VALUE_NONE,
                'Instead of try to apply generated SQLs into EntityManager Storage Connection, output them.'
            )
        ))
        ->setHelp(<<<EOT
Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.
EOT
        );
    }

    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
    {
        $output->write('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL . PHP_EOL);

        if ($input->getOption('dump-sql') === true) {
            $sqls = $schemaTool->getCreateSchemaSql($metadatas);
            $output->write(implode(';' . PHP_EOL, $sqls) . PHP_EOL);
        } else {
            $output->write('Creating database schema...' . PHP_EOL);
            $schemaTool->createSchema($metadatas);
            $output->write('Database schema created successfully!' . PHP_EOL);
        }
    }
}


text:
<?php
/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
*/

namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;

use Symfony\Component\Console\Input\InputArgument,
    Symfony\Component\Console\Input\InputOption,
    Symfony\Component\Console\Input\InputInterface,
    Symfony\Component\Console\Output\OutputInterface,
    Symfony\Component\Console\Command\Command,
    Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper,
    Doctrine\ORM\Tools\SchemaTool,
    Doctrine\ORM\Mapping\Driver\AbstractFileDriver;

abstract class AbstractCommand extends Command
{
    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @param SchemaTool $schemaTool
     * @param array $metadatas
     */
    abstract protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas);

    /**
     * @see Console\Command\Command
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $emHelper = $this->getHelper('em');

        /* @var $em \Doctrine\ORM\EntityManager */
        $em = $emHelper->getEntityManager();

        $metadatas = $em->getMetadataFactory()->getAllMetadata();

        if ( ! empty($metadatas)) {
            // Create SchemaTool
            $tool = new \Doctrine\ORM\Tools\SchemaTool($em);

            $this->executeSchemaCommand($input, $output, $tool, $metadatas);
        } else {
            $output->write('No Metadata Classes to process.' . PHP_EOL);
        }
    }
}


text:
<?php
/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;

use Symfony\Component\Console\Input\InputArgument,
    Symfony\Component\Console\Input\InputOption,
    Symfony\Component\Console\Input\InputInterface,
    Symfony\Component\Console\Output\OutputInterface,
    Doctrine\ORM\Tools\SchemaTool;

/**
 * Command to generate the SQL needed to update the database schema to match
 * the current mapping information.
 *
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link    www.doctrine-project.org
 * @since   2.0
 * @version $Revision$
 * @author  Benjamin Eberlei <kontakt@beberlei.de>
 * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @author  Jonathan Wage <jonwage@gmail.com>
 * @author  Roman Borschel <roman@code-factory.org>
 * @author  Ryan Weaver <ryan@thatsquality.com>
 */
class UpdateCommand extends AbstractCommand
{
    protected $name = 'orm:schema-tool:update';

    /**
     * @see Console\Command\Command
     */
    protected function configure()
    {
        $this
        ->setName($this->name)
        ->setDescription(
            'Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata.'
        )
        ->setDefinition(array(
            new InputOption(
                'complete', null, InputOption::VALUE_NONE,
                'If defined, all assets of the database which are not relevant to the current metadata will be dropped.'
            ),

            new InputOption(
                'dump-sql', null, InputOption::VALUE_NONE,
                'Dumps the generated SQL statements to the screen (does not execute them).'
            ),
            new InputOption(
                'force', null, InputOption::VALUE_NONE,
                'Causes the generated SQL statements to be physically executed against your database.'
            ),
        ));

        $fullName = $this->getName();
        $this->setHelp(<<<EOT
The <info>$fullName</info> command generates the SQL needed to
synchronize the database schema with the current mapping metadata of the
default entity manager.

For example, if you add metadata for a new column to an entity, this command
would generate and output the SQL needed to add the new column to the database:

<info>$fullName --dump-sql</info>

Alternatively, you can execute the generated queries:

<info>$fullName --force</info>

Finally, be aware that if the <info>--complete</info> option is passed, this
task will drop all database assets (e.g. tables, etc) that are *not* described
by the current metadata. In other words, without this option, this task leaves
untouched any "extra" tables that exist in the database, but which aren't
described by any metadata.
EOT
        );
    }

    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
    {
        // Defining if update is complete or not (--complete not defined means $saveMode = true)
        $saveMode = ($input->getOption('complete') !== true);

        $sqls = $schemaTool->getUpdateSchemaSql($metadatas, $saveMode);
        if (0 == count($sqls)) {
            $output->writeln('Nothing to update - your database is already in sync with the current entity metadata.');

            return;
        }

        $dumpSql = (true === $input->getOption('dump-sql'));
        $force = (true === $input->getOption('force'));
        if ($dumpSql && $force) {
            throw new \InvalidArgumentException('You can pass either the --dump-sql or the --force option (but not both simultaneously).');
        }

        if ($dumpSql) {
            $output->writeln(implode(';' . PHP_EOL, $sqls));
        } else if ($force) {
            $output->writeln('Updating database schema...');
            $schemaTool->updateSchema($metadatas, $saveMode);
            $output->writeln(sprintf('Database schema updated successfully! "<info>%s</info>" queries were executed', count($sqls)));
        } else {
            $output->writeln('<comment>ATTENTION</comment>: This operation should not be executed in a production environment.');
            $output->writeln('           Use the incremental update to detect changes during development and use');
            $output->writeln('           the SQL DDL provided to manually update your database in production.');
            $output->writeln('');

            $output->writeln(sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)));
            $output->writeln('Please run the operation by passing one of the following options:');

            $output->writeln(sprintf('    <info>%s --force</info> to execute the command', $this->getName()));
            $output->writeln(sprintf('    <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()));
        }
    }
}


text:
<?php
/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
*/

namespace Doctrine\ORM\Tools\Event;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\ORM\EntityManager;

/**
 * Event Args used for the Events::postGenerateSchema event.
 *
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link        www.doctrine-project.com
 * @since       1.0
 * @version     $Revision$
 * @author      Benjamin Eberlei <kontakt@beberlei.de>
 */
class GenerateSchemaEventArgs extends \Doctrine\Common\EventArgs
{
    private $_em = null;
    private $_schema = null;

    /**
     * @param ClassMetadata $classMetadata
     * @param Schema $schema
     * @param Table $classTable
     */
    public function __construct(EntityManager $em, Schema $schema)
    {
        $this->_em = $em;
        $this->_schema = $schema;
    }

    /**
     * @return EntityManager
     */
    public function getEntityManager() {
        return $this->_em;
    }

    /**
     * @return Schema
     */
    public function getSchema() {
        return $this->_schema;
    }
}


text:
<?php
/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
*/

namespace Doctrine\ORM\Tools\Event;

use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;

/**
 * Event Args used for the Events::postGenerateSchemaTable event.
 *
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link        www.doctrine-project.com
 * @since       1.0
 * @version     $Revision$
 * @author      Benjamin Eberlei <kontakt@beberlei.de>
 */
class GenerateSchemaTableEventArgs extends \Doctrine\Common\EventArgs
{
    private $_classMetadata = null;
    private $_schema = null;
    private $_classTable = null;

    /**
     * @param ClassMetadata $classMetadata
     * @param Schema $schema
     * @param Table $classTable
     */
    public function __construct(ClassMetadata $classMetadata, Schema $schema, Table $classTable)
    {
        $this->_classMetadata = $classMetadata;
        $this->_schema = $schema;
        $this->_classTable = $classTable;
    }

    /**
     * @return ClassMetadata
     */
    public function getClassMetadata() {
        return $this->_classMetadata;
    }

    /**
     * @return Schema
     */
    public function getSchema() {
        return $this->_schema;
    }

    /**
     * @return Table
     */
    public function getClassTable() {
        return $this->_classTable;
    }
}


text:
<?php

/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Tools\Export;

use Doctrine\ORM\Tools\Export\ExportException,
    Doctrine\ORM\EntityManager;

/**
 * Class used for converting your mapping information between the
 * supported formats: yaml, xml, and php/annotation.
 *
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link    www.doctrine-project.org
 * @since   2.0
 * @version $Revision$
 * @author  Jonathan Wage <jonwage@gmail.com>
 */
class ClassMetadataExporter
{
    private static $_exporterDrivers = array(
        'xml' => 'Doctrine\ORM\Tools\Export\Driver\XmlExporter',
        'yaml' => 'Doctrine\ORM\Tools\Export\Driver\YamlExporter',
        'yml' => 'Doctrine\ORM\Tools\Export\Driver\YamlExporter',
        'php' => 'Doctrine\ORM\Tools\Export\Driver\PhpExporter',
        'annotation' => 'Doctrine\ORM\Tools\Export\Driver\AnnotationExporter'
    );

    /**
     * Register a new exporter driver class under a specified name
     *
     * @param string $name
     * @param string $class
     */
    public static function registerExportDriver($name, $class)
    {
        self::$_exporterDrivers[$name] = $class;
    }

    /**
     * Get a exporter driver instance
     *
     * @param string $type   The type to get (yml, xml, etc.)
     * @param string $source    The directory where the exporter will export to
     * @return AbstractExporter $exporter
     */
    public function getExporter($type, $dest = null)
    {
        if ( ! isset(self::$_exporterDrivers[$type])) {
            throw ExportException::invalidExporterDriverType($type);
        }

        $class = self::$_exporterDrivers[$type];

        return new $class($dest);
    }
}


text:
<?php

namespace Doctrine\ORM\Tools\Export;

use Doctrine\ORM\ORMException;

class ExportException extends ORMException
{
    public static function invalidExporterDriverType($type)
    {
        return new self("The specified export driver '$type' does not exist");
    }

    public static function invalidMappingDriverType($type)
    {
        return new self("The mapping driver '$type' does not exist");
    }

    public static function attemptOverwriteExistingFile($file)
    {
        return new self("Attempting to overwrite an existing file '".$file."'.");
    }
}


text:
<?php

/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Tools\Export\Driver;

use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Tools\Export\ExportException;

/**
 * Abstract base class which is to be used for the Exporter drivers
 * which can be found in Doctrine\ORM\Tools\Export\Driver
 *
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link    www.doctrine-project.org
 * @since   2.0
 * @version $Revision$
 * @author  Jonathan Wage <jonwage@gmail.com>
 */
abstract class AbstractExporter
{
    protected $_metadata = array();
    protected $_outputDir;
    protected $_extension;
    protected $_overwriteExistingFiles = false;

    public function __construct($dir = null)
    {
        $this->_outputDir = $dir;
    }

    public function setOverwriteExistingFiles($overwrite)
    {
        $this->_overwriteExistingFiles = $overwrite;
    }

    /**
     * Converts a single ClassMetadata instance to the exported format
     * and returns it
     *
     * @param ClassMetadataInfo $metadata
     * @return mixed $exported
     */
    abstract public function exportClassMetadata(ClassMetadataInfo $metadata);

    /**
     * Set the array of ClassMetadataInfo instances to export
     *
     * @param array $metadata
     * @return void
     */
    public function setMetadata(array $metadata)
    {
        $this->_metadata = $metadata;
    }

    /**
     * Get the extension used to generated the path to a class
     *
     * @return string $extension
     */
    public function getExtension()
    {
        return $this->_extension;
    }

    /**
     * Set the directory to output the mapping files to
     *
     *     [php]
     *     $exporter = new YamlExporter($metadata);
     *     $exporter->setOutputDir(__DIR__ . '/yaml');
     *     $exporter->export();
     *
     * @param string $dir
     * @return void
     */
    public function setOutputDir($dir)
    {
        $this->_outputDir = $dir;
    }

    /**
     * Export each ClassMetadata instance to a single Doctrine Mapping file
     * named after the entity
     *
     * @return void
     */
    public function export()
    {
        if ( ! is_dir($this->_outputDir)) {
            mkdir($this->_outputDir, 0777, true);
        }

        foreach ($this->_metadata as $metadata) {
            $output = $this->exportClassMetadata($metadata);
            $path = $this->_generateOutputPath($metadata);
            $dir = dirname($path);
            if ( ! is_dir($dir)) {
                mkdir($dir, 0777, true);
            }
            if (file_exists($path) && !$this->_overwriteExistingFiles) {
                throw ExportException::attemptOverwriteExistingFile($path);
            }
            file_put_contents($path, $output);
        }
    }

    /**
     * Generate the path to write the class for the given ClassMetadataInfo instance
     *
     * @param ClassMetadataInfo $metadata
     * @return string $path
     */
    protected function _generateOutputPath(ClassMetadataInfo $metadata)
    {
        return $this->_outputDir . '/' . str_replace('\\', '.', $metadata->name) . $this->_extension;
    }

    /**
     * Set the directory to output the mapping files to
     *
     *     [php]
     *     $exporter = new YamlExporter($metadata, __DIR__ . '/yaml');
     *     $exporter->setExtension('.yml');
     *     $exporter->export();
     *
     * @param string $extension
     * @return void
     */
    public function setExtension($extension)
    {
        $this->_extension = $extension;
    }

    protected function _getInheritanceTypeString($type)
    {
        switch ($type)
        {
            case ClassMetadataInfo::INHERITANCE_TYPE_NONE:
                return 'NONE';
            break;

            case ClassMetadataInfo::INHERITANCE_TYPE_JOINED:
                return 'JOINED';
            break;

            case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE:
                return 'SINGLE_TABLE';
            break;

            case ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS:
                return 'PER_CLASS';
            break;
        }
    }

    protected function _getChangeTrackingPolicyString($policy)
    {
        switch ($policy)
        {
            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT:
                return 'DEFERRED_IMPLICIT';
            break;

            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT:
                return 'DEFERRED_EXPLICIT';
            break;

            case ClassMetadataInfo::CHANGETRACKING_NOTIFY:
                return 'NOTIFY';
            break;
        }
    }

    protected function _getIdGeneratorTypeString($type)
    {
        switch ($type)
        {
            case ClassMetadataInfo::GENERATOR_TYPE_AUTO:
                return 'AUTO';
            break;

            case ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE:
                return 'SEQUENCE';
            break;

            case ClassMetadataInfo::GENERATOR_TYPE_TABLE:
                return 'TABLE';
            break;

            case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
                return 'IDENTITY';
            break;
        }
    }
}


text:
<?php

/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Tools\Export\Driver;

use Doctrine\ORM\Mapping\ClassMetadataInfo,
    Doctrine\ORM\Mapping\AssociationMapping,
    Doctrine\ORM\Tools\EntityGenerator;

/**
 * ClassMetadata exporter for PHP classes with annotations
 *
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link    www.doctrine-project.org
 * @since   2.0
 * @version $Revision$
 * @author  Jonathan Wage <jonwage@gmail.com>
 */
class AnnotationExporter extends AbstractExporter
{
    protected $_extension = '.php';
    private $_entityGenerator;

    /**
     * Converts a single ClassMetadata instance to the exported format
     * and returns it
     *
     * @param ClassMetadataInfo $metadata
     * @return string $exported
     */
    public function exportClassMetadata(ClassMetadataInfo $metadata)
    {
        if ( ! $this->_entityGenerator) {
            throw new \RuntimeException('For the AnnotationExporter you must set an EntityGenerator instance with the setEntityGenerator() method.');
        }
        $this->_entityGenerator->setGenerateAnnotations(true);
        $this->_entityGenerator->setGenerateStubMethods(false);
        $this->_entityGenerator->setRegenerateEntityIfExists(false);
        $this->_entityGenerator->setUpdateEntityIfExists(false);

        return $this->_entityGenerator->generateEntityClass($metadata);
    }

    protected function _generateOutputPath(ClassMetadataInfo $metadata)
    {
        return $this->_outputDir . '/' . str_replace('\\', '/', $metadata->name) . $this->_extension;
    }

    public function setEntityGenerator(EntityGenerator $entityGenerator)
    {
        $this->_entityGenerator = $entityGenerator;
    }
}


text:
<?php

/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Tools\Export\Driver;

use Doctrine\ORM\Mapping\ClassMetadataInfo;

/**
 * ClassMetadata exporter for Doctrine XML mapping files
 *
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link    www.doctrine-project.org
 * @since   2.0
 * @version $Revision$
 * @author  Jonathan Wage <jonwage@gmail.com>
 */
class XmlExporter extends AbstractExporter
{
    protected $_extension = '.dcm.xml';

    /**
     * Converts a single ClassMetadata instance to the exported format
     * and returns it
     *
     * @param ClassMetadataInfo $metadata
     * @return mixed $exported
     */
    public function exportClassMetadata(ClassMetadataInfo $metadata)
    {
        $xml = new \SimpleXmlElement("<?xml version=\"1.0\" encoding=\"utf-8\"?><doctrine-mapping ".
            "xmlns=\"http://doctrine-project.org/schemas/orm/doctrine-mapping\" " .
            "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ".
            "xsi:schemaLocation=\"http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd\" />");

        /*$xml->addAttribute('xmlns', 'http://doctrine-project.org/schemas/orm/doctrine-mapping');
        $xml->addAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
        $xml->addAttribute('xsi:schemaLocation', 'http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd');*/

        if ($metadata->isMappedSuperclass) {
            $root = $xml->addChild('mapped-superclass');
        } else {
            $root = $xml->addChild('entity');
        }

        if ($metadata->customRepositoryClassName) {
            $root->addAttribute('repository-class', $metadata->customRepositoryClassName);
        }

        $root->addAttribute('name', $metadata->name);

        if (isset($metadata->table['name'])) {
            $root->addAttribute('table', $metadata->table['name']);
        }

        if (isset($metadata->table['schema'])) {
            $root->addAttribute('schema', $metadata->table['schema']);
        }

        if (isset($metadata->table['inheritance-type'])) {
            $root->addAttribute('inheritance-type', $metadata->table['inheritance-type']);
        }

        if ($metadata->discriminatorColumn) {
            $discriminatorColumnXml = $root->addChild('discriminiator-column');
            $discriminatorColumnXml->addAttribute('name', $metadata->discriminatorColumn['name']);
            $discriminatorColumnXml->addAttribute('type', $metadata->discriminatorColumn['type']);
            $discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']);
        }

        if ($metadata->discriminatorMap) {
            $discriminatorMapXml = $root->addChild('discriminator-map');
            foreach ($metadata->discriminatorMap as $value => $className) {
                $discriminatorMappingXml = $discriminatorMapXml->addChild('discriminator-mapping');
                $discriminatorMappingXml->addAttribute('value', $value);
                $discriminatorMappingXml->addAttribute('class', $className);
            }
        }

        $root->addChild('change-tracking-policy', $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy));

        if (isset($metadata->table['indexes'])) {
            $indexesXml = $root->addChild('indexes');

            foreach ($metadata->table['indexes'] as $name => $index) {
                $indexXml = $indexesXml->addChild('index');
                $indexXml->addAttribute('name', $name);
                $indexXml->addAttribute('columns', implode(',', $index['columns']));
            }
        }

        if (isset($metadata->table['uniqueConstraints'])) {
            $uniqueConstraintsXml = $root->addChild('unique-constraints');

            foreach ($metadata->table['uniqueConstraints'] as $unique) {
                $uniqueConstraintXml = $uniqueConstraintsXml->addChild('unique-constraint');
                $uniqueConstraintXml->addAttribute('name', $unique['name']);
                $uniqueConstraintXml->addAttribute('columns', implode(',', $unique['columns']));
            }
        }

        $fields = $metadata->fieldMappings;

        $id = array();
        foreach ($fields as $name => $field) {
            if (isset($field['id']) && $field['id']) {
                $id[$name] = $field;
                unset($fields[$name]);
            }
        }

        if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
            $id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType;
        }

        if ($id) {
            foreach ($id as $field) {
                $idXml = $root->addChild('id');
                $idXml->addAttribute('name', $field['fieldName']);
                $idXml->addAttribute('type', $field['type']);
                if (isset($field['columnName'])) {
                    $idXml->addAttribute('column', $field['columnName']);
                }
                if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
                    $generatorXml = $idXml->addChild('generator');
                    $generatorXml->addAttribute('strategy', $idGeneratorType);
                }
            }
        }

        if ($fields) {
            foreach ($fields as $field) {
                $fieldXml = $root->addChild('field');
                $fieldXml->addAttribute('name', $field['fieldName']);
                $fieldXml->addAttribute('type', $field['type']);
                if (isset($field['columnName'])) {
                    $fieldXml->addAttribute('column', $field['columnName']);
                }
                if (isset($field['length'])) {
                    $fieldXml->addAttribute('length', $field['length']);
                }
                if (isset($field['precision'])) {
                    $fieldXml->addAttribute('precision', $field['precision']);
                }
                if (isset($field['scale'])) {
                    $fieldXml->addAttribute('scale', $field['scale']);
                }
                if (isset($field['unique']) && $field['unique']) {
                    $fieldXml->addAttribute('unique', $field['unique']);
                }
                if (isset($field['options'])) {
                    $optionsXml = $fieldXml->addChild('options');
                    foreach ($field['options'] as $key => $value) {
                        $optionsXml->addAttribute($key, $value);
                    }
                }
                if (isset($field['version'])) {
                    $fieldXml->addAttribute('version', $field['version']);
                }
                if (isset($field['columnDefinition'])) {
                    $fieldXml->addAttribute('column-definition', $field['columnDefinition']);
                }
            }
        }

        foreach ($metadata->associationMappings as $name => $associationMapping) {
            if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_ONE) {
                $associationMappingXml = $root->addChild('one-to-one');
            } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_ONE) {
                $associationMappingXml = $root->addChild('many-to-one');
            } else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
                $associationMappingXml = $root->addChild('one-to-many');
            } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
                $associationMappingXml = $root->addChild('many-to-many');
            }

            $associationMappingXml->addAttribute('field', $associationMapping['fieldName']);
            $associationMappingXml->addAttribute('target-entity', $associationMapping['targetEntity']);

            if (isset($associationMapping['mappedBy'])) {
                $associationMappingXml->addAttribute('mapped-by', $associationMapping['mappedBy']);
            }
            if (isset($associationMapping['inversedBy'])) {
                $associationMappingXml->addAttribute('inversed-by', $associationMapping['inversedBy']);
            }
            if (isset($associationMapping['orphanRemoval'])) {
                $associationMappingXml->addAttribute('orphan-removal', $associationMapping['orphanRemoval']);
            }
            if (isset($associationMapping['joinTable']) && $associationMapping['joinTable']) {
                $joinTableXml = $associationMappingXml->addChild('join-table');
                $joinTableXml->addAttribute('name', $associationMapping['joinTable']['name']);
                $joinColumnsXml = $joinTableXml->addChild('join-columns');
                foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) {
                    $joinColumnXml = $joinColumnsXml->addChild('join-column');
                    $joinColumnXml->addAttribute('name', $joinColumn['name']);
                    $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']);
                    if (isset($joinColumn['onDelete'])) {
                        $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']);
                    }
                    if (isset($joinColumn['onUpdate'])) {
                        $joinColumnXml->addAttribute('on-update', $joinColumn['onUpdate']);
                    }
                }
                $inverseJoinColumnsXml = $joinTableXml->addChild('inverse-join-columns');
                foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) {
                    $inverseJoinColumnXml = $inverseJoinColumnsXml->addChild('join-column');
                    $inverseJoinColumnXml->addAttribute('name', $inverseJoinColumn['name']);
                    $inverseJoinColumnXml->addAttribute('referenced-column-name', $inverseJoinColumn['referencedColumnName']);
                    if (isset($inverseJoinColumn['onDelete'])) {
                        $inverseJoinColumnXml->addAttribute('on-delete', $inverseJoinColumn['onDelete']);
                    }
                    if (isset($inverseJoinColumn['onUpdate'])) {
                        $inverseJoinColumnXml->addAttribute('on-update', $inverseJoinColumn['onUpdate']);
                    }
                    if (isset($inverseJoinColumn['columnDefinition'])) {
                        $inverseJoinColumnXml->addAttribute('column-definition', $inverseJoinColumn['columnDefinition']);
                    }
                    if (isset($inverseJoinColumn['nullable'])) {
                        $inverseJoinColumnXml->addAttribute('nullable', $inverseJoinColumn['nullable']);
                    }
                    if (isset($inverseJoinColumn['orderBy'])) {
                        $inverseJoinColumnXml->addAttribute('order-by', $inverseJoinColumn['orderBy']);
                    }
                }
            }
            if (isset($associationMapping['joinColumns'])) {
                $joinColumnsXml = $associationMappingXml->addChild('join-columns');
                foreach ($associationMapping['joinColumns'] as $joinColumn) {
                    $joinColumnXml = $joinColumnsXml->addChild('join-column');
                    $joinColumnXml->addAttribute('name', $joinColumn['name']);
                    $joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']);
                    if (isset($joinColumn['onDelete'])) {
                        $joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']);
                    }
                    if (isset($joinColumn['onUpdate'])) {
                        $joinColumnXml->addAttribute('on-update', $joinColumn['onUpdate']);
                    }
                    if (isset($joinColumn['columnDefinition'])) {
                        $joinColumnXml->addAttribute('column-definition', $joinColumn['columnDefinition']);
                    }
                    if (isset($joinColumn['nullable'])) {
                        $joinColumnXml->addAttribute('nullable', $joinColumn['nullable']);
                    }
                }
            }
            if (isset($associationMapping['orderBy'])) {
                $orderByXml = $associationMappingXml->addChild('order-by');
                foreach ($associationMapping['orderBy'] as $name => $direction) {
                    $orderByFieldXml = $orderByXml->addChild('order-by-field');
                    $orderByFieldXml->addAttribute('name', $name);
                    $orderByFieldXml->addAttribute('direction', $direction);
                }
            }
            $cascade = array();
            if ($associationMapping['isCascadeRemove']) {
                $cascade[] = 'cascade-remove';
            }
            if ($associationMapping['isCascadePersist']) {
                $cascade[] = 'cascade-persist';
            }
            if ($associationMapping['isCascadeRefresh']) {
                $cascade[] = 'cascade-refresh';
            }
            if ($associationMapping['isCascadeMerge']) {
                $cascade[] = 'cascade-merge';
            }
            if ($associationMapping['isCascadeDetach']) {
                $cascade[] = 'cascade-detach';
            }
            if ($cascade) {
                $cascadeXml = $associationMappingXml->addChild('cascade');
                foreach ($cascade as $type) {
                    $cascadeXml->addChild($type);
                }
            }
        }

        if (isset($metadata->lifecycleCallbacks)) {
            $lifecycleCallbacksXml = $root->addChild('lifecycle-callbacks');
            foreach ($metadata->lifecycleCallbacks as $name => $methods) {
                foreach ($methods as $method) {
                    $lifecycleCallbackXml = $lifecycleCallbacksXml->addChild('lifecycle-callback');
                    $lifecycleCallbackXml->addAttribute('type', $name);
                    $lifecycleCallbackXml->addAttribute('method', $method);
                }
            }
        }

        return $this->_asXml($xml);
    }

    /**
     * @param \SimpleXMLElement $simpleXml
     * @return string $xml
     */
    private function _asXml($simpleXml)
    {
        $dom = new \DOMDocument('1.0', 'UTF-8');
        $dom->loadXML($simpleXml->asXML());
        $dom->formatOutput = true;

        $result = $dom->saveXML();
        return $result;
    }
}


text:
<?php

/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Tools\Export\Driver;

use Doctrine\ORM\Mapping\ClassMetadataInfo;

/**
 * ClassMetadata exporter for PHP code
 *
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link    www.doctrine-project.org
 * @since   2.0
 * @version $Revision$
 * @author  Jonathan Wage <jonwage@gmail.com>
 */
class PhpExporter extends AbstractExporter
{
    protected $_extension = '.php';

    /**
     * Converts a single ClassMetadata instance to the exported format
     * and returns it
     *
     * @param ClassMetadataInfo $metadata
     * @return mixed $exported
     */
    public function exportClassMetadata(ClassMetadataInfo $metadata)
    {
        $lines = array();
        $lines[] = '<?php';
        $lines[] = null;
        $lines[] = 'use Doctrine\ORM\Mapping\ClassMetadataInfo;';
        $lines[] = null;

        if ($metadata->isMappedSuperclass) {
            $lines[] = '$metadata->isMappedSuperclass = true;';
        }

        if ($metadata->inheritanceType) {
            $lines[] = '$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_' . $this->_getInheritanceTypeString($metadata->inheritanceType) . ');';
        }

        if ($metadata->customRepositoryClassName) {
            $lines[] = "\$metadata->customRepositoryClassName = '" . $metadata->customRepositoryClassName . "';";
        }

        if ($metadata->table) {
            $lines[] = '$metadata->setPrimaryTable(' . $this->_varExport($metadata->table) . ');';
        }

        if ($metadata->discriminatorColumn) {
            $lines[] = '$metadata->setDiscriminatorColumn(' . $this->_varExport($metadata->discriminatorColumn) . ');';
        }

        if ($metadata->discriminatorMap) {
            $lines[] = '$metadata->setDiscriminatorMap(' . $this->_varExport($metadata->discriminatorMap) . ');';
        }

        if ($metadata->changeTrackingPolicy) {
            $lines[] = '$metadata->setChangeTrackingPolicy(ClassMetadataInfo::CHANGETRACKING_' . $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy) . ');';
        }

        if ($metadata->lifecycleCallbacks) {
            foreach ($metadata->lifecycleCallbacks as $event => $callbacks) {
                foreach ($callbacks as $callback) {
                    $lines[] = "\$metadata->addLifecycleCallback('$callback', '$event');";
                }
            }
        }

        foreach ($metadata->fieldMappings as $fieldMapping) {
            $lines[] = '$metadata->mapField(' . $this->_varExport($fieldMapping) . ');';
        }

        if ($generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
            $lines[] = '$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_' . $generatorType . ');';
        }

        foreach ($metadata->associationMappings as $associationMapping) {
            $cascade = array('remove', 'persist', 'refresh', 'merge', 'detach');
            foreach ($cascade as $key => $value) {
                if ( ! $associationMapping['isCascade'.ucfirst($value)]) {
                    unset($cascade[$key]);
                }
            }
            $associationMappingArray = array(
                'fieldName'    => $associationMapping['fieldName'],
                'targetEntity' => $associationMapping['targetEntity'],
                'cascade'     => $cascade,
            );

            if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
                $method = 'mapOneToOne';
                $oneToOneMappingArray = array(
                    'mappedBy'      => $associationMapping['mappedBy'],
                    'inversedBy'    => $associationMapping['inversedBy'],
                    'joinColumns'   => $associationMapping['joinColumns'],
                    'orphanRemoval' => $associationMapping['orphanRemoval'],
                );

                $associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray);
            } else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
                $method = 'mapOneToMany';
                $potentialAssociationMappingIndexes = array(
                    'mappedBy',
                    'orphanRemoval',
                    'orderBy',
                );
                foreach ($potentialAssociationMappingIndexes as $index) {
                    if (isset($associationMapping[$index])) {
                        $oneToManyMappingArray[$index] = $associationMapping[$index];
                    }
                }
                $associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray);
            } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
                $method = 'mapManyToMany';
                $potentialAssociationMappingIndexes = array(
                    'mappedBy',
                    'joinTable',
                    'orderBy',
                );
                foreach ($potentialAssociationMappingIndexes as $index) {
                    if (isset($associationMapping[$index])) {
                        $manyToManyMappingArray[$index] = $associationMapping[$index];
                    }
                }
                $associationMappingArray = array_merge($associationMappingArray, $manyToManyMappingArray);
            }

            $lines[] = '$metadata->' . $method . '(' . $this->_varExport($associationMappingArray) . ');';
        }

        return implode("\n", $lines);
    }

    protected function _varExport($var)
    {
        $export = var_export($var, true);
        $export = str_replace("\n", PHP_EOL . str_repeat(' ', 8), $export);
        $export = str_replace('  ', ' ', $export);
        $export = str_replace('array (', 'array(', $export);
        $export = str_replace('array( ', 'array(', $export);
        $export = str_replace(',)', ')', $export);
        $export = str_replace(', )', ')', $export);
        $export = str_replace('  ', ' ', $export);

        return $export;
    }
}


text:
<?php

/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Tools\Export\Driver;

use Doctrine\ORM\Mapping\ClassMetadataInfo;

/**
 * ClassMetadata exporter for Doctrine YAML mapping files
 *
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link    www.doctrine-project.org
 * @since   2.0
 * @version $Revision$
 * @author  Jonathan Wage <jonwage@gmail.com>
 */
class YamlExporter extends AbstractExporter
{
    protected $_extension = '.dcm.yml';

    /**
     * Converts a single ClassMetadata instance to the exported format
     * and returns it
     *
     * TODO: Should this code be pulled out in to a toArray() method in ClassMetadata
     *
     * @param ClassMetadataInfo $metadata
     * @return mixed $exported
     */
    public function exportClassMetadata(ClassMetadataInfo $metadata)
    {
        $array = array();
        if ($metadata->isMappedSuperclass) {
            $array['type'] = 'mappedSuperclass';
        } else {
            $array['type'] = 'entity';
        }
        $array['table'] = $metadata->table['name'];

        if (isset($metadata->table['schema'])) {
            $array['schema'] = $metadata->table['schema'];
        }

        $inheritanceType = $metadata->inheritanceType;
        if ($inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
            $array['inheritanceType'] = $this->_getInheritanceTypeString($inheritanceType);
        }

        if ($column = $metadata->discriminatorColumn) {
            $array['discriminatorColumn'] = $column;
        }

        if ($map = $metadata->discriminatorMap) {
            $array['discriminatorMap'] = $map;
        }

        if ($metadata->changeTrackingPolicy !== ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT) {
            $array['changeTrackingPolicy'] = $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy);
        }

        if (isset($metadata->table['indexes'])) {
            $array['indexes'] = $metadata->table['indexes'];
        }

        if (isset($metadata->table['uniqueConstraints'])) {
            $array['uniqueConstraints'] = $metadata->table['uniqueConstraints'];
        }

        $fieldMappings = $metadata->fieldMappings;

        $ids = array();
        foreach ($fieldMappings as $name => $fieldMapping) {
            $fieldMapping['column'] = $fieldMapping['columnName'];
            unset(
                $fieldMapping['columnName'],
                $fieldMapping['fieldName']
            );

            if ($fieldMapping['column'] == $name) {
                unset($fieldMapping['column']);
            }

            if (isset($fieldMapping['id']) && $fieldMapping['id']) {
                $ids[$name] = $fieldMapping;
                unset($fieldMappings[$name]);
                continue;
            }

            $fieldMappings[$name] = $fieldMapping;
        }

        if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
            $ids[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $this->_getIdGeneratorTypeString($metadata->generatorType);
        }

        if ($ids) {
            $array['fields'] = $ids;
        }

        if ($fieldMappings) {
            if ( ! isset($array['fields'])) {
                $array['fields'] = array();
            }
            $array['fields'] = array_merge($array['fields'], $fieldMappings);
        }

        $associations = array();
        foreach ($metadata->associationMappings as $name => $associationMapping) {
            $cascade = array();
            if ($associationMapping['isCascadeRemove']) {
                $cascade[] = 'remove';
            }
            if ($associationMapping['isCascadePersist']) {
                $cascade[] = 'persist';
            }
            if ($associationMapping['isCascadeRefresh']) {
                $cascade[] = 'refresh';
            }
            if ($associationMapping['isCascadeMerge']) {
                $cascade[] = 'merge';
            }
            if ($associationMapping['isCascadeDetach']) {
                $cascade[] = 'detach';
            }
            $associationMappingArray = array(
                'targetEntity' => $associationMapping['targetEntity'],
                'cascade'     => $cascade,
            );

            if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
                $joinColumns = $associationMapping['joinColumns'];
                $newJoinColumns = array();
                foreach ($joinColumns as $joinColumn) {
                    $newJoinColumns[$joinColumn['name']]['referencedColumnName'] = $joinColumn['referencedColumnName'];
                    if (isset($joinColumn['onDelete'])) {
                        $newJoinColumns[$joinColumn['name']]['onDelete'] = $joinColumn['onDelete'];
                    }
                    if (isset($joinColumn['onUpdate'])) {
                        $newJoinColumns[$joinColumn['name']]['onUpdate'] = $joinColumn['onUpdate'];
                    }
                }
                $oneToOneMappingArray = array(
                    'mappedBy'      => $associationMapping['mappedBy'],
                    'inversedBy'    => $associationMapping['inversedBy'],
                    'joinColumns'   => $newJoinColumns,
                    'orphanRemoval' => $associationMapping['orphanRemoval'],
                );

                $associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray);
                $array['oneToOne'][$name] = $associationMappingArray;
            } else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
                $oneToManyMappingArray = array(
                    'mappedBy'      => $associationMapping['mappedBy'],
                    'inversedBy'    => $associationMapping['inversedBy'],
                    'orphanRemoval' => $associationMapping['orphanRemoval'],
                    'orderBy'       => isset($associationMapping['orderBy']) ? $associationMapping['orderBy'] : null
                );

                $associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray);
                $array['oneToMany'][$name] = $associationMappingArray;
            } else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
                $manyToManyMappingArray = array(
                    'mappedBy'   => $associationMapping['mappedBy'],
                    'inversedBy' => $associationMapping['inversedBy'],
                    'joinTable'  => isset($associationMapping['joinTable']) ? $associationMapping['joinTable'] : null,
                    'orderBy'    => isset($associationMapping['orderBy']) ? $associationMapping['orderBy'] : null
                );

                $associationMappingArray = array_merge($associationMappingArray, $manyToManyMappingArray);
                $array['manyToMany'][$name] = $associationMappingArray;
            }
        }
        if (isset($metadata->lifecycleCallbacks)) {
            $array['lifecycleCallbacks'] = $metadata->lifecycleCallbacks;
        }

        return \Symfony\Component\Yaml\Yaml::dump(array($metadata->name => $array), 10);
    }
}


text:
<?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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Id;

use Serializable, Doctrine\ORM\EntityManager;

/**
 * Represents an ID generator that uses a database sequence.
 *
 * @since 2.0
 * @author Roman Borschel <roman@code-factory.org>
 */
class SequenceGenerator extends AbstractIdGenerator implements Serializable
{
    private $_allocationSize;
    private $_sequenceName;
    private $_nextValue = 0;
    private $_maxValue = null;

    /**
     * Initializes a new sequence generator.
     *
     * @param Doctrine\ORM\EntityManager $em The EntityManager to use.
     * @param string $sequenceName The name of the sequence.
     * @param integer $allocationSize The allocation size of the sequence.
     */
    public function __construct($sequenceName, $allocationSize)
    {
        $this->_sequenceName = $sequenceName;
        $this->_allocationSize = $allocationSize;
    }

    /**
     * Generates an ID for the given entity.
     *
     * @param object $entity
     * @return integer|float The generated value.
     * @override
     */
    public function generate(EntityManager $em, $entity)
    {
        if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
            // Allocate new values
            $conn = $em->getConnection();
            $sql = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName);
            $this->_nextValue = $conn->fetchColumn($sql);
            $this->_maxValue = $this->_nextValue + $this->_allocationSize;
        }
        return $this->_nextValue++;
    }

    /**
     * Gets the maximum value of the currently allocated bag of values.
     *
     * @return integer|float
     */
    public function getCurrentMaxValue()
    {
        return $this->_maxValue;
    }

    /**
     * Gets the next value that will be returned by generate().
     *
     * @return integer|float
     */
    public function getNextValue()
    {
        return $this->_nextValue;
    }

    public function serialize()
    {
        return serialize(array(
            'allocationSize' => $this->_allocationSize,
            'sequenceName' => $this->_sequenceName
        ));
    }

    public function unserialize($serialized)
    {
        $array = unserialize($serialized);
        $this->_sequenceName = $array['sequenceName'];
        $this->_allocationSize = $array['allocationSize'];
    }
}


text:
<?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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Id;

use Doctrine\ORM\EntityManager;

/**
 * Id generator that uses a single-row database table and a hi/lo algorithm.
 *
 * @since   2.0
 * @author  Benjamin Eberlei <kontakt@beberlei.de>
 * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @author  Jonathan Wage <jonwage@gmail.com>
 * @author  Roman Borschel <roman@code-factory.org>
 */
class TableGenerator extends AbstractIdGenerator
{
    private $_tableName;
    private $_sequenceName;
    private $_allocationSize;
    private $_nextValue;
    private $_maxValue;

    public function __construct($tableName, $sequenceName = 'default', $allocationSize = 10)
    {
        $this->_tableName = $tableName;
        $this->_sequenceName = $sequenceName;
        $this->_allocationSize = $allocationSize;
    }

    public function generate(EntityManager $em, $entity)
    {
        if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
            // Allocate new values
            $conn = $em->getConnection();
            if ($conn->getTransactionNestingLevel() == 0) {

                // use select for update
                $sql = $conn->getDatabasePlatform()->getTableHiLoCurrentValSql($this->_tableName, $this->_sequenceName);
                $currentLevel = $conn->fetchColumn($sql);
                if ($currentLevel != null) {
                    $this->_nextValue = $currentLevel;
                    $this->_maxValue = $this->_nextValue + $this->_allocationSize;

                    $updateSql = $conn->getDatabasePlatform()->getTableHiLoUpdateNextValSql(
                        $this->_tableName, $this->_sequenceName, $this->_allocationSize
                    );

                    if ($conn->executeUpdate($updateSql, array(1 => $currentLevel, 2 => $currentLevel+1)) !== 1) {
                        // no affected rows, concurrency issue, throw exception
                    }
                } else {
                    // no current level returned, TableGenerator seems to be broken, throw exception
                }
            } else {
                // only table locks help here, implement this or throw exception?
                // or do we want to work with table locks exclusively?
            }
        }
        return $this->_nextValue++;
    }
}


text:
<?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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Id;

use Doctrine\ORM\EntityManager;

/**
 * Id generator that obtains IDs from special "identity" columns. These are columns
 * that automatically get a database-generated, auto-incremented identifier on INSERT.
 * This generator obtains the last insert id after such an insert.
 */
class IdentityGenerator extends AbstractIdGenerator
{
    /** @var string The name of the sequence to pass to lastInsertId(), if any. */
    private $_seqName;

    /**
     * @param string $seqName The name of the sequence to pass to lastInsertId()
     *                        to obtain the last generated identifier within the current
     *                        database session/connection, if any.
     */
    public function __construct($seqName = null)
    {
        $this->_seqName = $seqName;
    }

    /**
     * {@inheritdoc}
     */
    public function generate(EntityManager $em, $entity)
    {
        return $em->getConnection()->lastInsertId($this->_seqName);
    }

    /**
     * {@inheritdoc}
     */
    public function isPostInsertGenerator()
    {
        return true;
    }
}


text:
<?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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Id;

use Doctrine\ORM\EntityManager;

abstract class AbstractIdGenerator
{
    /**
     * Generates an identifier for an entity.
     *
     * @param Doctrine\ORM\Entity $entity
     * @return mixed
     */
    abstract public function generate(EntityManager $em, $entity);

    /**
     * Gets whether this generator is a post-insert generator which means that
     * {@link generate()} must be called after the entity has been inserted
     * into the database.
     *
     * By default, this method returns FALSE. Generators that have this requirement
     * must override this method and return TRUE.
     *
     * @return boolean
     */
    public function isPostInsertGenerator()
    {
        return false;
    }
}


text:
<?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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Id;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\ORMException;

/**
 * Special generator for application-assigned identifiers (doesnt really generate anything).
 *
 * @since   2.0
 * @author  Benjamin Eberlei <kontakt@beberlei.de>
 * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @author  Jonathan Wage <jonwage@gmail.com>
 * @author  Roman Borschel <roman@code-factory.org>
 */
class AssignedGenerator extends AbstractIdGenerator
{
    /**
     * Returns the identifier assigned to the given entity.
     *
     * @param object $entity
     * @return mixed
     * @override
     */
    public function generate(EntityManager $em, $entity)
    {
        $class = $em->getClassMetadata(get_class($entity));
        $identifier = array();
        if ($class->isIdentifierComposite) {
            $idFields = $class->getIdentifierFieldNames();
            foreach ($idFields as $idField) {
                $value = $class->reflFields[$idField]->getValue($entity);
                if (isset($value)) {
                    if (isset($class->associationMappings[$idField])) {
                        if (!$em->getUnitOfWork()->isInIdentityMap($value)) {
                            throw ORMException::entityMissingForeignAssignedId($entity, $value);
                        }

                        // NOTE: Single Columns as associated identifiers only allowed - this constraint it is enforced.
                        $identifier[$idField] = current($em->getUnitOfWork()->getEntityIdentifier($value));
                    } else {
                        $identifier[$idField] = $value;
                    }
                } else {
                    throw ORMException::entityMissingAssignedId($entity);
                }
            }
        } else {
            $idField = $class->identifier[0];
            $value = $class->reflFields[$idField]->getValue($entity);
            if (isset($value)) {
                if (isset($class->associationMappings[$idField])) {
                    if (!$em->getUnitOfWork()->isInIdentityMap($value)) {
                        throw ORMException::entityMissingForeignAssignedId($entity, $value);
                    }

                    // NOTE: Single Columns as associated identifiers only allowed - this constraint it is enforced.
                    $identifier[$idField] = current($em->getUnitOfWork()->getEntityIdentifier($value));
                } else {
                    $identifier[$idField] = $value;
                }
            } else {
                throw ORMException::entityMissingAssignedId($entity);
            }
        }

        return $identifier;
    }
}


text:
<?php
/*
 *  $Id$
 *
 * 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
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Persisters;

use Doctrine\ORM\PersistentCollection,
    Doctrine\ORM\UnitOfWork;

/**
 * Persister for one-to-many collections.
 *
 * IMPORTANT:
 * This persister is only used for uni-directional one-to-many mappings on a foreign key
 * (which are not yet supported). So currently this persister is not used.
 *
 * @since 2.0
 * @author Roman Borschel <roman@code-factory.org>
 * @todo Remove
 */
class OneToManyPersister extends AbstractCollectionPersister
{
    /**
     * Generates the SQL UPDATE that updates a particular row's foreign
     * key to null.
     *
     * @param PersistentCollection $coll
     * @return string
     * @override
     */
    protected function _getDeleteRowSQL(PersistentCollection $coll)
    {
        $mapping = $coll->getMapping();
        $targetClass = $this->_em->getClassMetadata($mapping->getTargetEntityName());
        $table = $targetClass->getTableName();

        $ownerMapping = $targetClass->getAssociationMapping($mapping['mappedBy']);

        $setClause = '';
        foreach ($ownerMapping->sourceToTargetKeyColumns as $sourceCol => $targetCol) {
            if ($setClause != '') $setClause .= ', ';
            $setClause .= "$sourceCol = NULL";
        }

        $whereClause = '';
        foreach ($targetClass->getIdentifierColumnNames() as $idColumn) {
            if ($whereClause != '') $whereClause .= ' AND ';
            $whereClause .= "$idColumn = ?";
        }

        return array("UPDATE $table SET $setClause WHERE $whereClause", $this->_uow->getEntityIdentifier($element));
    }

    protected function _getInsertRowSQL(PersistentCollection $coll)
    {
        return "UPDATE xxx SET foreign_key = yyy WHERE foreign_key = zzz";
    }

    /* Not used for OneToManyPersister */
    protected function _getUpdateRowSQL(PersistentCollection $coll)
    {
        return;
    }

    /**
     * Generates the SQL UPDATE that updates all the foreign keys to null.
     *
     * @param PersistentCollection $coll
     */
    protected function _getDeleteSQL(PersistentCollection $coll)
    {

    }

    /**
     * Gets the SQL parameters for the corresponding SQL statement to delete
     * the given collection.
     *
     * @param PersistentCollection $coll
     */
    protected function _getDeleteSQLParameters(PersistentCollection $coll)
    {}

    /**
     * Gets the SQL parameters for the corresponding SQL statement to insert the given
     * element of the given collection into the database.
     *
     * @param PersistentCollection $coll
     * @param mixed $element
     */
    protected function _getInsertRowSQLParameters(PersistentCollection $coll, $element)
    {}

    /**
     * Gets the SQL parameters for the corresponding SQL statement to delete the given
     * element from the given collection.
     *
     * @param PersistentCollection $coll
     * @param mixed $element
     */
    protected function _getDeleteRowSQLParameters(PersistentCollection $coll, $element)
    {}

    /**
     * {@inheritdoc}
     */
    public function count(PersistentCollection $coll)
    {
        $mapping = $coll->getMapping();
        $targetClass = $this->_em->getClassMetadata($mapping['targetEntity']);
        $sourceClass = $this->_em->getClassMetadata($mapping['sourceEntity']);

        $params = array();
        $id = $this->_em->getUnitOfWork()->getEntityIdentifier($coll->getOwner());

        $where = '';
        foreach ($targetClass->associationMappings[$mapping['mappedBy']]['joinColumns'] AS $joinColumn) {
            if ($where != '') {
                $where .= ' AND ';
            }
            $where .= $joinColumn['name'] . " = ?";
            if ($targetClass->containsForeignIdentifier) {
                $params[] = $id[$sourceClass->getFieldForColumn($joinColumn['referencedColumnName'])];
            } else {
                $params[] = $id[$sourceClass->fieldNames[$joinColumn['referencedColumnName']]];
            }
        }

        $sql = "SELECT count(*) FROM " . $targetClass->getQuotedTableName($this->_conn->getDatabasePlatform()) . " WHERE " . $where;
        return $this->_conn->fetchColumn($sql, $params);
    }

    /**
     * @param PersistentCollection $coll
     * @param int $offset
     * @param int $length
     * @return \Doctrine\Common\Collections\ArrayCollection
     */
    public function slice(PersistentCollection $coll, $offset, $length = null)
    {
        $mapping = $coll->getMapping();
        return $this->_em->getUnitOfWork()
                  ->getEntityPersister($mapping['targetEntity'])
                  ->getOneToManyCollection($mapping, $coll->getOwner(), $offset, $length);
    }

    /**
     * @param PersistentCollection $coll
     * @param object $element
     */
    public function contains(PersistentCollection $coll, $element)
    {
        $mapping = $coll->getMapping();
        $uow = $this->_em->getUnitOfWork();

        // shortcut for new entities
        if ($uow->getEntityState($element, UnitOfWork::STATE_NEW) == UnitOfWork::STATE_NEW) {
            return false;
        }

        // only works with single id identifier entities. Will throw an exception in Entity Persisters
        // if that is not the case for the 'mappedBy' field.
        $id = current( $uow->getEntityIdentifier($coll->getOwner()) );

        return $uow->getEntityPersister($mapping['targetEntity'])
                   ->exists($element, array($mapping['mappedBy'] => $id));
    }
}