jadb.io personal tidbits

Faker + CakePHP = gourmet/faker

Some time ago, I did some work on Faker to add built-in support for CakePHP’s awesome new ORM. It has just been merged, and I released gourmet/faker to make it even easier to use.

Here’s how to install it:

$ composer require gourmet/faker

At this point, Faker can already be used anywhere in the application. Here’s an example for seeding 20 records in the Posts table (i.e. in a migration file):

<?php
$faker = \Faker\Factory::create();
$entityPopulator = new \Faker\ORM\CakePHP\EntityPopulator('Posts');
$populator = new \Faker\ORM\CakePHP\Populator($faker);
$populator->addEntity($entityPopulator, 20);
$populator->execute(['validate' => false]);

It could also be used to auto-generate records in fixtures like so:

<?php

namespace App\Test\Fixture;

use Gourmet\Faker\TestSuite\Fixture\TestFixture;

class PostsFixture extends TestFixture {

    public $fields = [
        'id' => ['type' => 'integer'],
        'title' => ['type' => 'string', 'length' => 255, 'null' => false],
        'body' => 'text',
        'published' => ['type' => 'integer', 'default' => '0', 'null' => false],
        'created' => 'datetime',
        'updated' => 'datetime',
        '_constraints' => [
            'primary' => ['type' => 'primary', 'columns' => ['id']]
        ]
    ];

    public $records = [
        [
            'id' => 1,
            'title' => 'First Article',
            'body' => 'First Article Body',
            'published' => '1',
            'created' => '2007-03-18 10:39:23',
            'updated' => '2007-03-18 10:41:31'
        ],
        [
            'id' => 2,
            'title' => 'Second Article',
            'body' => 'Second Article Body',
            'published' => '1',
            'created' => '2007-03-18 10:41:23',
            'updated' => '2007-03-18 10:43:31'
        ],
        [
            'id' => 3,
            'title' => 'Third Article',
            'body' => 'Third Article Body',
            'published' => '1',
            'created' => '2007-03-18 10:43:23',
            'updated' => '2007-03-18 10:45:31'
        ]
    ];


    public $number = 20;
    public $guessers = ['\Faker\Guesser\Name'];

    public function init() {
        $this->customColumnFormatters = [
            'id' => function () { return $this->faker->numberBetween(count($this->records) + 2); },
            'published' => function () { return rand(0,3); }
        ];
        parent::init();
    }
}

What’s cool about this fixture is that it supports the default TestFixture inserting of custom records.

Here’s how it works under the hood:

<?php
public function create(Connection $db) {
    if (!parent::create($db)) {
        return false;
    }

    $entityPopulator = new EntityPopulator($this->table);
    $populator = new Populator($this->faker);
    array_walk($this->guessers, array($populator, 'addGuesser'));
    $populator->addEntity($entityPopulator, $this->number, $this->customColumnFormatters, $this->customModifiers);
    $populator->execute(['validate' => false]);
    return true;
}

That’s it! Happy faking :)

comments powered by Disqus