bobthecow/population

A simpler way to populate your Doctrine 2 databases

dev-master / 1.0.x-dev 2012-12-08 19:43 UTC

This package is auto-updated.

Last update: 2024-12-20 11:02:13 UTC


README

A simpler way to populate your Doctrine 2 databases.

Inspired by Populator for ActiveRecord.

Usage

You really should use this library with Faker. You'll see why in a second.

The easiest way to use Population is to extend \Population\DataFixture. It's a valid base class for both ORM and ODM data fixtures:

<?php

namespace Application\BlogBundle\DataFixtures\ORM;

use Doctrine\ORM\EntityManager;
use MyApplication\BlogBundle\Document\Post;
use MyApplication\BlogBundle\Document\Comment;

class BlogPostsFixture extends \Population\DataFixture
{
    public function load(EntityManager $em)
    {
        // Generate 10 blog posts
        $this->populate($em->getRepository('MainBundle:Post'), 10, function(Post $post) {
            $post->setTitle(\Faker\Lorem::sentence());
            $post->setContent(implode("\n\n", \Faker\Lorem::paragraphs(6)));
            $post->setCreatedAt(new \DateTime(\Faker\DateTime::timestamp()));
        });

        // Add a few comments to each
        foreach ($em->getRepository('BlogBundle:Post')->find() as $post) {
            $this->populate($em->getRepository('BlogBundle:Comment'), rand(5, 10), function(Comment $comment) {
                $name = \Faker\Name::name();
                $comment->setAuthor($name);
                $comment->setEmail(\Faker\Internet::email($name));
                $comment->setSubject(\Faker\Lorem::sentence());
                $comment->setContent(\Faker\Lorem::paragraph());
                $comment->setCreatedAt(new \DateTime(\Faker\DateTime::timestamp()));
                $comment->setPost($post);
            });
        }
    }
}

If you need Population elsewhere, or if you don't particularly like using base classes, you can strike out on your own with the Populator service:

<?php

$populator = new Populator();
$populator->populate($em->getRepository('BlogBundle:Category'), 5, function($category) {
    $name = \Faker\Lorem::word();
    $category->setName($name);
    $category->setSlug(strtolower($name));
});

$categories = $em->getRepository('BlogBundle:Category')->find()->toArray();
foreach ($em->getRepository('BlogBundle:Post') as $post) {
    $post->setCategory($categories[array_rand($categories)]);
}

$em->flush();

Advanced usage

populate accepts a couple of additional options:

<?php

$populator = new Populator();
$populator->populate($em->getRepository('BlogBundle:Tag'), 1000, function($tag) {
    $tag->setName(\Faker\Lorem::word());
}, array(
    'perFlush'        => 10,
    'clearAfterFlush' => false,
    'factory'         => function($tagName) {
        return new Tag($tagName);
    },
    'constructorArgs' => array('foo'),
));
  • perFlush will limit the number of objects flushed in a single query. By default it's 100. Set to 0 or false to only flush once at the end.

  • clearAfterFlush lets you disable clearing the ObjectManager after every flush. Changing this to false can make things really slow and / or crashy.

  • factory is an optional callback for construction objects to populate. Use this if your class needs constructor dependency injection or special instantiation.

  • constructorArgs an array of args, passed directly to the object's constructor. If you specified a factory option, your factory will receive these arguments.