PHP Classes

How to Implement your Own PHP Fixtures Generator using the Yii2 Muffin Factory: Create objects with factories and fixtures

Recommend this page to a friend!
  Info   View files Documentation   View files View files (18)   DownloadInstall with Composer Download .zip   Reputation   Support forum   Blog    
Ratings Unique User Downloads Download Rankings
Not yet rated by the usersTotal: 10 All time: 11,306 This week: 560Up
Version License PHP version Categories
yii2-muffin-factory 1.0MIT/X Consortium ...5PHP 5, Language, Design Patterns
Description 

Author

This package can create objects with factories and fixtures.

It can define how to create an object with a given class using a factory object that can initialize the object variables to values returned by callback functions.

The factory class can create the object on demand and optionally change the object variables.

The package also provides an active fixture class that can use objects created by a factory class and adds new functions to the objects.

Innovation Award
PHP Programming Innovation award nominee
December 2022
Number 8
In PHP, you can create objects dynamically using factory classes to create those objects with given variable values.

Fixtures allow dynamically adding new functions to objects that are already created.

This package provides a PHP implementation of factories that can create objects and add functions to those objects using fixture classes.

This way, this package allows the implementation of PHP solutions to create and change objects' behavior at run time.

Manuel Lemos
Picture of Insolita
  Performance   Level  
Name: Insolita <contact>
Classes: 23 packages by
Country: Russian Federation Russian Federation
Age: 38
All time rank: 332791 in Russian Federation Russian Federation
Week rank: 75 Up8 in Russian Federation Russian Federation Up
Innovation award
Innovation award
Nominee: 16x

Documentation

Yii2 Muffin Factory

A Port of laravel factory for generate fixtures on fly and database seeding

yii2-muffin-factory

Installation

Either run

composer require -dev insolita/yii2-muffin-factory:~2.0.0

or add

"insolita/yii2-muffin-factory": "~2.0.0"

in require-dev section of your composer.json file.

Configure

Add in bootstrap for test suite (or in every app, where it can be used)

//with default factory path by alias @tests/factories
Yii::$container->setSingleton(
     \insolita\muffin\Factory::class,
      [],
     [\Faker\Factory::create('en_EN')]
  );

//with custom factory path
Yii::$container->setSingleton(
     \insolita\muffin\Factory::class,
     [],
     [
         \Faker\Factory::create('ru_RU'),  //Faker language
          '@common/data/factories'         // Custom directory for factories
     ]
 );

Create Factories

You can create all factories in single file, or in individual files in directory defined in factory configuration

example UserFactory.php

/
 * @var \insolita\muffin\Factory $factory
 /

 $factory->define(User::class, function (\Faker\Generator $faker) {
     static $password;
     return [
         'name' => $faker->name,
         'lastName' => $faker->name,
         'email' => $faker->unique()->safeEmail,
         'status'=>'default',
         'passwordHash' => $password ?: $password = Yii::$app->security->generatePasswordHash('secret'),
         'authKey' => Yii::$app->security->generateRandomString(),
         'accessToken' => Yii::$app->security->generateRandomString(64),
         'birthday' => $faker->date('Y-m-d', '-15 years'),
         'registered' => $faker->dateTimeThisMonth()->format('Y-m-d H:i:s'),
     ];
 });
$factory->state(User::class, 'developer', [
        'status' => 'developer',
]);
$factory->state(User::class, 'client', [
    'status' => 'client',
]);

Use Factories

Populate new record without saving

 /@var User $user/
$user = factory(User::class)->make();
$user = factory(User::class)->states('client')->make();
 /@var User[] $user/
$users = factory(User::class, 5)->make();
$users = factory(User::class, 5)->states(['client', 'developer'])->make();

Populate and persist records


 /@var User $user /
$user = factory(User::class)->create();
 /@var User[] $user/
$users = factory(User::class, 10)->states(['client'])->create(['registered'=>Carbon::now()]);

See more examples in FactoryTest

Use with ActiveFixtures

Create ActiveFixture extended classed in configured directory as usual


class UserFixture extends ActiveFixture
{
    public $modelClass = User::class;

    protected function getData()
    {
        return array_merge(
            factory(User::class, 1)->states('developer')->raw(),
            factory(User::class, 10)->states('client')->raw()
        );
    }
}

Fixtures with relation dependency

class PostFixture extends ActiveFixture
{
    public $modelClass = Post::class;
    public $depends = [UserFixture::class];

    public function load()
    {
        $this->data = [];
        $users = User::find()->select(['id'])->column();
        foreach ($users as $userId) {
            $posts = factory(Post::class, 5)->create(['createdBy' => $userId]);
            foreach ($posts as $post) {
                $this->data[$post->id] = $post->getAttributes();
            }
        }
        return $this->data;
    }
}

class SomeFixture extends ActiveFixture
{
    public $modelClass = Some::class;
    public $depends = [UserFixture::class];

    protected function getData()
    {
        $users = User::find()->select(['id'])->where(['status'=>'client'])->column();
        $developer = User::find()->where(['status'=>'developer'])->limit(1)->one();
        $data =  array_merge(
            factory(Some::class, 5)->raw(['user_id'=>ArrayHelper::random($users)]),
            factory(Some::class, 20)->states('one')->raw(['user_id'=>function() use(&$users){ return ArrayHelper::random($users);}]),
            factory(Some::class, 11)->states('two')->raw(['user_id'=>$developer->id])
        );
        return $data;
    }
}

  Files folder image Files  
File Role Description
Files folder image.github (1 directory)
Files folder imagesrc (3 files)
Files folder imagetests (3 files, 5 directories)
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file phpunit.xml Data Auxiliary data
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files  /  .github  
File Role Description
Files folder imageworkflows (1 file)

  Files folder image Files  /  .github  /  workflows  
File Role Description
  Accessible without login Plain text file test.yml Data Auxiliary data

  Files folder image Files  /  src  
File Role Description
  Plain text file Factory.php Class Class source
  Plain text file FactoryBuilder.php Class Class source
  Plain text file helpers.php Class Class source

  Files folder image Files  /  tests  
File Role Description
Files folder imageconfig (2 files)
Files folder imagefactories (1 file)
Files folder imagemigrations (2 files)
Files folder imagestubs (2 files)
Files folder imageunit (1 file)
  Accessible without login Plain text file bootstrap.php Aux. Auxiliary script
  Accessible without login Plain text file yii Example Example script
  Plain text file YiiCase.php Class Class source

  Files folder image Files  /  tests  /  config  
File Role Description
  Plain text file base.php Class Class source
  Plain text file console.php Class Class source

  Files folder image Files  /  tests  /  factories  
File Role Description
  Plain text file UserPostFactory.php Class Class source

  Files folder image Files  /  tests  /  migrations  
File Role Description
  Plain text file m171126_090933_user.php Class Class source
  Plain text file m171126_090944_post.php Class Class source

  Files folder image Files  /  tests  /  stubs  
File Role Description
  Plain text file Post.php Class Class source
  Plain text file User.php Class Class source

  Files folder image Files  /  tests  /  unit  
File Role Description
  Plain text file FactoryTest.php Class Class source

 Version Control Unique User Downloads Download Rankings  
 100%
Total:10
This week:0
All time:11,306
This week:560Up