diff --git a/readme.md b/readme.md index 4d8f61c..0fca351 100644 --- a/readme.md +++ b/readme.md @@ -96,7 +96,7 @@ $f = Faktory::create("term", ["name" => "TDD", "taxonomy" => "post_tag"]); ```php $f = Faktory::create("term", ["name" => "Computer Science", "taxonomy" => "genre"]); ``` -#### Using the terms with another Factory +#### Using the terms with another factory ```php $term = Faktory::create("term", ["name" => "Programming"]); $page = Faktory::create("page", [ @@ -136,7 +136,7 @@ $f = Faktory::new("page"); $f->save(); ``` -## Pass the returned Faktory to a class +## Pass the returned factory to a class `Faktory::create` or `Faktory::new` will return an object. This object mimics a WordPress post object or term object. You may find yourself frequently passing the created fixture as a paramter to another class. This is where the `as` method can come in useful. ```php $f = Faktory::create("page")->as("TheClassIWant"); @@ -144,6 +144,38 @@ $f = Faktory::create("page")->as("TheClassIWant"); $f = new TheClassIWant(Faktory::create("page")); ``` +## Creating multiple factories at once +`Faktory::createMany` or `Faktory::newMany` will return an array of objects in a single line of code. +```php +$factories = Faktory::createMany(5, "post"); +``` + +`createMany` will save the objects to the database. +`newMany` will not save the objects to the database. + +They both support the following args: +- `count` (default: `2`): The number of objects to create. +- `type` (default: `page`): See [creating a page factory](https://github.com/substrakt/faktory?tab=readme-ov-file#creating-a-page-factory). +- `args` (default: `[]`): See [creating a page factory and setting attributes](https://github.com/substrakt/faktory?tab=readme-ov-file#creating-a-page-factory-setting-some-attributes). +- `class` (default `null`): The string of a class to instantiate the factories as. + +Each Factory is given an incrementing suffix to the `post_title` and `post_name`. See the following example for context. + +### Examples + +Basic use-case: + +```php +$fs = Faktory::createMany(3, 'post', ['post_title' => 'Foo'], 'My\Desired\Class'); +``` + +The above will: +- Create 3 factories. +- Assign them the `post_titles` of `Foo 0`, `Foo 1`, & `Foo 2`. +- Instantiate them as `My\Desired\Class`. +- Save them to the database. +- Return the results as an array. + ## Creating your own factories Add a directory called `factories` in your desired location. In this directory you will put all your custom factory files. If you create a file called, post.php, page.php or term.php it will overwrite the default factories used by Faktory. This is perfectly acceptable. diff --git a/src/Faktory.php b/src/Faktory.php index 2e6bea4..b167b5f 100644 --- a/src/Faktory.php +++ b/src/Faktory.php @@ -41,6 +41,24 @@ public static function create(string $type = "page", array $args = []): object return $f; } + /** + * Returns array of new Faktory objects. + * The objects are saved to the database. + * + * @param int $count The number of objects to create. + * @param string $type The name of the factory to load. + * @param array $args Array of properties and values to override. + * @param ?string $class Set to a class to instantiate the Faktory as. + * @return array + */ + public static function createMany(int $count = 2, string $type = "page", array $args = [], ?string $class = null): array + { + return array_map(function($post) use ($class) { + $post->save(); + return $class ? $post->as($class) : $post; + }, static::newMany($count, $type, $args)); + } + /** * Returns are new Faktory object. * The object is not saved to the database. @@ -54,6 +72,35 @@ public static function new(string $type = "page", array $args = []): object return static::generate($type, $args); } + /** + * Returns array of new Faktory objects. + * The objects are not saved to the database. + * + * @param int $count The number of objects to create. + * @param string $type The name of the factory to load. + * @param array $args Array of properties and values to override. + * @param ?string $class Set to a class to instantiate the Faktory as. + * @return array + */ + public static function newMany(int $count = 2, string $type = "page", array $args = [], ?string $class = null): array + { + $posts = []; + + for ($i = 0; $i < $count; $i++) { + $post = static::generate($type, $args); + $post->post_title .= " {$i}"; + $post->post_name .= " {$i}"; + + if ($class) { + $post = $post->as($class); + } + + $posts[] = $post; + } + + return $posts; + } + /** * Load a factory from the available directories and return the containing array. * diff --git a/tests/faktory-tests.php b/tests/faktory-tests.php index 7f7880b..8a13d07 100644 --- a/tests/faktory-tests.php +++ b/tests/faktory-tests.php @@ -348,4 +348,49 @@ public function test_undefined_factory_returns_post_factory_with_post_type_chang "Faktory::new should return a 'foobar' object when a type is passed" ); } + + public function test_newMany_returns_an_array() + { + $this->assertTrue( + is_array(Faktory::newMany()), + "Faktory::newMany should return an array" + ); + } + + public function test_newMany_returns_an_array_of_objects() + { + $this->assertIsObject( + Faktory::newMany()[0], + "Faktory::newMany should return an array of objects" + ); + } + + /** + * @testWith ["post_title"] + * ["post_title"] + */ + public function test_newMany_increments_suffix(string $property) + { + $objects = Faktory::newMany(2, 'post', [$property => "Foo Bar"]); + + $this->assertEquals( + "Foo Bar 0", $objects[0]->$property, + "Faktory::newMany should increment the {$property} suffix" + ); + + $this->assertEquals( + "Foo Bar 1", $objects[1]->$property, + "Faktory::newMany should increment the {$property} suffix" + ); + } + + public function test_newMany_instantiates_objects_as_specified_class() + { + $objects = Faktory::newMany(2, 'post', ["post_title" => "Foo Bar"], class: "Faktory\Page"); + + $this->assertEquals( + "Faktory\Page", get_class($objects[0]), + "Faktory::newMany should instantiate objects as the specified class" + ); + } }