Created
March 20, 2014 16:09
-
-
Save evillemez/9667390 to your computer and use it in GitHub Desktop.
Idea for generating fixtures - this is generation only, not about persistence
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace AC\Fixtures; | |
/** | |
* Factories use Definitions and Pools to create and store (not persist) object instances. | |
*/ | |
interface Factory | |
{ | |
public function define($name); //create and returns Definition | |
public function getDefinition($name); //return definition | |
public function pool($number, $name); //define a pool of objects | |
public function populate(); //populate objects for defined pools | |
public function fetchOne($name, $comparator = null); //fetch from pool | |
public function fetchMultiple($num, $name, $comparator = null, $unique = true); //fetch multiple from pool, optionally pass matcher | |
public function fetchOneRandom($name); //fetch from pool | |
public function fetchMultipleRandom($num, $name, $unique = true); //fetch multiple from pool | |
public function fetchMatching($name, array $fields); //fetch multiple from pool | |
public function fetchAll($name); //fetch all | |
//one off creation of objects (not stored internally in pools, thus not fetchable directly) | |
public function generateOne($name, $args = null); //create one instance, not pooled | |
public function generate($num, $name, $args = null); //create multiple, not pooled | |
} | |
/** | |
* Defines creation of instances of a class. | |
*/ | |
interface Definition | |
{ | |
public function __construct($className); | |
public function setFactory(Factory $factory); //factory, if defined, is passed to callables | |
public function constructor($callable); //custom constructor, returns object instance | |
public function build($callable); //called after constructor | |
public function property($name, $callableOrValue); //set property generator | |
public function properties(array $map); //set multiple property generators | |
public function then($callable); //register a callable to be called after properties | |
public function generateOne($args = null); //instantiate and return 1 object | |
public function generate($num, $args = null); //instantiate and return multiple | |
} | |
/** | |
* Manages instances of objects created by Definitions | |
*/ | |
interface Pool | |
{ | |
public function __construct($num, Definition $def = null); | |
public function setNumber($num); | |
public function setDefinition(Definition $def); | |
public function populate($rebuild = false); | |
public function then($callable); | |
//calling a fetch method triggers "populate()" | |
public function fetchOne(); | |
public function fetchOneRandom(); | |
public function fetchMultiple($num, $comparator = null, $unique = true); | |
public function fetchMultipleRandom($num, $unique = true); | |
public function fetchMatching($comparator, $limit = null); | |
public function fetchMatchingFields(array $propertyComparators, $limit = null); | |
} | |
//stuff to use when creating | |
$f = new Faker(); | |
$em = new DoctrineEntityManager(); | |
$batchPersist = function($objs) use ($em) { foreach ($objs as $obj) { $em->persist($obj); } $em->flush(); }; | |
//create factory and define pools | |
$factory = new Factory(); | |
$factory->pool(100, "Hammerspace\ModelBundle\Entity\AO")->then($batchPersist); | |
$factory->pool(30, "Hammerspace\ModelBundle\Entity\Section")->then($batchPersist); | |
$factory->pool(20, "Hammerspace\ModelBundle\Entity\Form")->then($batchPersist); | |
$factory->pool(10, "Hammerspace\ModelBundle\Entity\Exam")->then($batchPersist); | |
$factory->define('Hammerspace\ModelBundle\Entity\AO') | |
->properties([ | |
'name' => function () use ($faker) { return $f->words(3); }, | |
'instructions' => function () use ($faker) { return $f->sentence(15); }, | |
'type' => function () use ($faker) { return $f->randomElement(['mc','cr']); }, | |
]) | |
->then(function($ao, $factory) { | |
if ('mc' == $ao->getType()) $items = $factory->generate(rand(1, 4), 'Hammerspace\ModelBundle\Entity\ItemMC', $ao); | |
if ('cr' == $ao->getType()) $items = $factory->generate(rand(1, 4), 'Hammerspace\ModelBundle\Entity\ItemCR', $ao); | |
//relies on model behavior to properly set "sequence" | |
$ao->addItems($items); | |
}) | |
; | |
$processBaseItem = function($item, $factory, $ao) { | |
//... | |
$item->setUic(); | |
//... | |
}; | |
$factory->define('Hammerspace\ModelBundle\Entity\ItemMC')->properties([ | |
//... set some fields | |
]) | |
->then(function ($item, $factory) { $item->addOptions($factory->generate(4, 'Hammerspace\ModelBundle\Entity\ItemMCOption')); }) | |
->then($processBaseItem); | |
$factory->define('Hammerspace\ModelBundle\Entity\ItemCR') | |
->properties([ | |
//set some fields directly | |
]) | |
->then(function($item) { | |
//do ItemCR specific stuff | |
}) | |
->then($processBaseItem); | |
$factory->populate(); //populates all defined pools, which may trigger persisting things, if set to do so | |
$adminDate = $factory->fetchOne('Hammerspace\ModelBundle\Entity\Exam')->getAdmins()[0]->getDates()[0]; | |
//not defined in pools, throw exceptions: | |
$obj = $factory->fetchOne('Hammerspace\ModelBundle\Entity\AdminDate'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment