tobento / service-seeder
Generating fake data customized for your PHP application needs.
Requires
- php: >=8.0
- tobento/service-dater: ^1.0
- tobento/service-dir: ^1.0
- tobento/service-filesystem: ^1.0
Requires (Dev)
- phpunit/phpunit: ^9.5
- vimeo/psalm: ^4.0
README
Generating fake data customized for your PHP application needs.
Table of Contents
- Getting started
- Documentation
- Credits
Getting started
Add the latest version of the Seeder service project running this command.
composer require tobento/service-seeder
Requirements
- PHP 8.0 or greater
Highlights
- Framework-agnostic, will work with any project
- Decoupled design
- Flexible managing your resource data to fit your application
- Easily extendable
Documentation
Do only use for seeding. It will not generate cryptographically secure string and numbers as it focuses more on speed.
Create Seed
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\SeedInterface; $seed = new Seed( resources: new Resources(), locale: 'en', localeFallbacks: ['de' => 'en'], localeMapping: ['de' => 'de-CH'], ); var_dump($seed instanceof SeedInterface); // bool(true)
Add Seeders
use Tobento\Service\Seeder\UserSeeder; $seed->addSeeder( name: 'user', seeder: new UserSeeder($seed) );
Add callable seeder
use Tobento\Service\Seeder\SeedInterface; use Tobento\Service\Seeder\Lorem; $seed->addCallableSeeder( method: 'word', seeder: function(SeedInterface $seed, null|string|array $locale, array $params): string { return Lorem::word(...$params); } ); $words = $seed->word(number: 2);
Add callable seeder using resource items
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; use Tobento\Service\Seeder\SeedInterface; use Tobento\Service\Seeder\Arr; use Tobento\Service\Seeder\Lorem; $seed = new Seed( new Resources( new Resource('colors', 'en', [ 'blue', 'red', 'green', 'yellow', 'pink', ]), new Resource('colors', 'de', [ 'blau', 'rot', 'grün', 'gelb', 'pink', ]), ), ); $seed->addCallableSeeder( method: 'color', seeder: function(SeedInterface $seed, null|string|array $locale, array $params): string { $colors = $seed->getItems('colors', $locale); if (!empty($colors)) { return Arr::item($colors); } return ucfirst(Lorem::word(number: 1)); } ); // default locale used: $color = $seed->color(); // specific locale: $color = $seed->locale('de')->color(); // specific locales: $color = $seed->locale(['en', 'de'])->color(); // all locales: $color = $seed->locale([])->color();
Seed
seeding
The Seed::class dynamically calls a seeder method to seed data. It throws a SeedMethodCallException if no seeder is found supporting the called method.
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; use Tobento\Service\Seeder\ResourceSeeder; use Tobento\Service\Seeder\SeedMethodCallException; $seed = new Seed( new Resources( new Resource('countries', 'en', [ 'Usa', 'Switzerland', 'Germany', ]), ), ); $seed->addSeeder('resource', new ResourceSeeder($seed)); try { $value = $seed->itemFrom(resource: 'countries'); var_dump($value); // string(11) "Switzerland" } catch (SeedMethodCallException $e) { // handle }
seeder
You may use the seeder method to return a seeder added.
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; use Tobento\Service\Seeder\ResourceSeeder; use Tobento\Service\Seeder\SeederInterface; use Tobento\Service\Seeder\SeederNotFoundException; $seed = new Seed(new Resources()); $seed->addSeeder('resource', new ResourceSeeder($seed)); try { var_dump($seed->seeder('resource') instanceof SeederInterface); // bool(true) } catch (SeederNotFoundException $e) { // handle }
resources
You may use the resources method to return the resources.
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\ResourcesInterface; $seed = new Seed(new Resources()); var_dump($seed->resources() instanceof ResourcesInterface); // bool(true)
getItems
You may use the getItems method to return items of a specified resource. If multiple locales specified, it merges items.
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; $seed = new Seed( new Resources( new Resource('countries', 'en', [ 'Usa', 'Switzerland', 'Germany', ]), ), ); $items = $seed->getItems( name: 'countries', locale: 'en', // null|string|array ); var_dump($items); // array(3) { [0]=> string(3) "Usa" [1]=> string(11) "Switzerland" [2]=> string(7) "Germany" } // default locale used: $items = $seed->getItems('countries'); // specific locale: $items = $seed->getItems('countries', 'en'); // specific locales: $items = $seed->getItems('countries', ['en']); // all locales: $items = $seed->getItems('countries', []);
Localization
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; $seed = new Seed( resources: new Resources(), locale: 'en', localeFallbacks: ['de' => 'en'], localeMapping: ['de' => 'de-CH'], ); // set the default locale: $seed->setLocale('de'); // get the default locale: var_dump($seed->getLocale()); // string(2) "de" // set the locale fallbacks: $seed->setLocaleFallbacks(['de' => 'en']); // get the locale fallbacks: var_dump($seed->getLocaleFallbacks()); // array(1) { ["de"]=> string(2) "en" } // set the locale mapping: $seed->setLocaleMapping(['de' => 'de-CH']); // get the locale mapping: var_dump($seed->getLocaleMapping()); // array(1) { ["de"]=> string(5) "de-CH" }
seeding
Use the locale method before calling a seeder method to seed data from resources in the specific locale(s).
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; use Tobento\Service\Seeder\ResourceSeeder; $seed = new Seed( new Resources( new Resource('countries', 'en', [ 'Usa', 'Switzerland', 'Germany', ]), new Resource('countries', 'de', [ 'Usa', 'Schweiz', 'Deutschland', ]), ), ); $seed->addSeeder('resource', new ResourceSeeder($seed)); // default locale used: var_dump($seed->itemFrom(resource: 'countries')); // string(7) "Germany" // specific locale: var_dump($seed->locale('de')->itemFrom('countries')); // string(7) "Schweiz" // specific locales: var_dump($seed->locale(['en', 'de'])->itemFrom('countries')); // string(11) "Deutschland" // all locales: var_dump($seed->locale([])->itemFrom('countries')); // string(3) "Usa"
Random Seeding
You may use the random method before calling a seeder method to seed the specified value randomly by its probability percentage.
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; use Tobento\Service\Seeder\ResourceSeeder; $seed = new Seed( new Resources( new Resource('countries', 'en', [ 'Usa', 'Switzerland', 'Germany', ]), ), ); $seed->addSeeder('resource', new ResourceSeeder($seed)); $value = $seed->random( value: null, probability: 50 // between 0 (always get false) and 100 (always get true) )->itemFrom(resource: 'countries'); var_dump($value); // NULL
Seeders
Resource Seeder
The resource seeder provides handy methods to seed data using resource items. If no Resoucres for the methods are provided, it fallsback to Lorem Seeder word(s) depending on methods.
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; use Tobento\Service\Seeder\ResourceSeeder; $seed = new Seed( new Resources( new Resource('countries', 'en', [ 'Usa', 'Switzerland', 'Germany', ]), new Resource('countries', 'de', [ 'Usa', 'Schweiz', 'Deutschland', ]), ), ); $seed->addSeeder('resource', new ResourceSeeder($seed)); // default locale used: var_dump($seed->itemFrom(resource: 'countries')); // string(7) "Germany" // specific locale: var_dump($seed->locale('de')->itemFrom('countries')); // string(7) "Schweiz" // specific locales: var_dump($seed->locale(['en', 'de'])->itemFrom('countries')); // string(11) "Deutschland" // all locales: var_dump($seed->locale([])->itemFrom('countries')); // string(3) "Usa"
Available methods
DateTime Seeder
The DateTime seeder provides handy methods to seed DateTime data. You may visit Dater Service for more detail on the DateFormatter::class.
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\DateTimeSeeder; use Tobento\Service\Dater\DateFormatter; $seed = new Seed(new Resources()); $df = new DateFormatter( locale: $seed->getLocale() ); $seed->addSeeder('dateTime', new DateTimeSeeder($df)); $dateTime = $seed->dateTime(from: '-30 years', to: 'now'); var_dump($dateTime); // object(DateTimeImmutable)#8 (3) { ["date"]=> string(26) "2015-11-29 14:55:24.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/Berlin" } var_dump($seed->locale('de')->month(3, 6, 'MMM')); // string(5) "März" var_dump($seed->locale(['de', 'fr'])->weekday(1, 7, 'EEEE')); // string(7) "Sonntag"
Available methods
User Seeder
The user seeder provides handy methods to seed user data. If no Resoucres for the methods are provided, it fallsback to Lorem Seeder word(s) depending on methods.
use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; use Tobento\Service\Seeder\UserSeeder; $seed = new Seed( new Resources( new Resource('countries', 'en', [ 'Usa', 'Switzerland', 'Germany', ]), new Resource('countries', 'de', [ 'Usa', 'Schweiz', 'Deutschland', ]), ), ); $seed->addSeeder('user', new UserSeeder($seed)); // default locale used: var_dump($seed->country()); // string(7) "Germany" // specific locale: var_dump($seed->locale('de')->country()); // string(7) "Schweiz" // specific locales: var_dump($seed->locale(['en', 'de'])->country()); // string(11) "Deutschland" // all locales: var_dump($seed->locale([])->country()); // string(3) "Usa"
Available methods
Create Custom Seeder
You may create a custom seeder for your application.
use Tobento\Service\Seeder\Seeder; use Tobento\Service\Seeder\Seed; use Tobento\Service\Seeder\SeedInterface; use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Arr; use Tobento\Service\Seeder\Lorem; class CustomSeeder extends Seeder { /** * Create a new CustomSeeder. * * @param SeedInterface $seed */ public function __construct( protected SeedInterface $seed, ) {} /** * Returns the seed method names the seeder provides. * * @return array<int, string> */ public function seeds(): array { return [ 'paymentMethod', ]; } /** * Returns a randomly selected item from the specified resource items. * * @return mixed */ public function paymentMethod(): mixed { // get items from resource. $items = $this->seed->getItems('payment_methods', $this->locale); if (empty($items)) { // if no payment_methods resource is defined fallback to: $items = ['invoice', 'creditcard', 'paypal']; } return Arr::item($items); } } $seed = new Seed(new Resources()); $seed->addSeeder('custom', new CustomSeeder($seed)); var_dump($seed->paymentMethod()); // string(6) "paypal"
Resources
Create Resources
use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\ResourcesInterface; use Tobento\Service\Seeder\Resource; $resources = new Resources( new Resource( name: 'colors', locale: 'en', items: ['blue', 'red'] ), ); var_dump($resources instanceof ResourcesInterface); // bool(true)
Add Resources
You may add resources by using the add method:
add resource
use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; $resources = new Resources(); $resources->add(new Resource('colors', 'en', [ 'red', 'blue', ]));
add resources
use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; $resources = new Resources(); $resources->add(new Resources( new Resource('colors', 'en', [ 'red', 'blue', ]), ));
Filter Resources
You may use the filter methods returning a new instance.
filter
use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; use Tobento\Service\Seeder\ResourceInterface; $resources = new Resources( new Resource( name: 'colors', locale: 'en', items: ['blue', 'red'] ), new Resource( name: 'colors', locale: 'de', items: ['blau', 'rot'] ), ); // filter by locale: $resources = $resources->filter( fn(ResourceInterface $r): bool => $r->locale() === 'de' );
locale
use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; $resources = new Resources( new Resource( name: 'colors', locale: 'en', items: ['blue', 'red'] ), new Resource( name: 'colors', locale: 'de', items: ['blau', 'rot'] ), ); // filter by locale: $resources = $resources->locale('en');
locales
use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; $resources = new Resources( new Resource( name: 'colors', locale: 'en', items: ['blue', 'red'] ), new Resource( name: 'colors', locale: 'de', items: ['blau', 'rot'] ), ); // filter by locales: $resources = $resources->locales(['en', 'de']);
name
use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; $resources = new Resources( new Resource( name: 'colors', locale: 'en', items: ['blue', 'red'] ), new Resource( name: 'colors', locale: 'de', items: ['blau', 'rot'] ), ); // filter by name: $resources = $resources->name('colors');
File Resource
You may use the file resource to load data from json or php files.
use Tobento\Service\Seeder\ResourceFile; use Tobento\Service\Seeder\ResourceInterface; $resource = new ResourceFile( file: __DIR__.'/seeder/countries.json', locale: 'en', resourceName: 'countries' ); var_dump($resource instanceof ResourceInterface); bool(true)
Supported files are json and php
json
["Switzerland", "Germany"]
php
return ['Switzerland', 'Germany'];
Get Resources And Items
all
use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; use Tobento\Service\Seeder\ResourceInterface; $resources = new Resources( new Resource( name: 'colors', locale: 'en', items: ['blue', 'red'] ), ); foreach($resources->all() as $resource) { var_dump($resource instanceof ResourceInterface); // bool(true) var_dump($resource->name()); // string(6) "colors" var_dump($resource->locale()); // string(2) "en" var_dump($resource->items()); // array(2) { [0]=> string(4) "blue" [1]=> string(3) "red" } }
items
use Tobento\Service\Seeder\Resources; use Tobento\Service\Seeder\Resource; $resources = new Resources( new Resource( name: 'colors', locale: 'en', items: ['blue', 'red'] ), ); $items = $resources->locale('en')->items(); var_dump($items); // array(2) { [0]=> string(4) "blue" [1]=> string(3) "red" }
⚠️ You must call locale() or locales() before all() or items() method if you have added (sub or lazy) resources, otherwise they will not get loaded.
foreach($resources->locale('en')->all() as $resource) { var_dump($resource instanceof ResourceInterface); // bool(true) }
Files Resources
You may use the files resources to load resource data from a directory.
Create Files Resources
use Tobento\Service\Seeder\FilesResources; use Tobento\Service\Dir\Dirs; use Tobento\Service\Seeder\ResourcesInterface; $resources = new FilesResources( (new Dirs())->dir(dir: 'private/seeder/') ); var_dump($resources instanceof ResourcesInterface); // bool(true)
Directory Structure
private/
seeder/
en/
countries.json
firstnamesFemale.json
firstnamesMale.php
de-CH/
countries.json
firstnamesFemale.json
firstnamesMale.php
Supported Files
Currently supported files are json and php.
json
["Switzerland", "Germany"]
php
return ['Switzerland', 'Germany'];
Supporting Other Files
You may support others files by providing your own resource factory:
use Tobento\Service\Seeder\FilesResources; use Tobento\Service\Dir\Dirs; use Tobento\Service\Seeder\ResourceFactory; use Tobento\Service\Seeder\ResourceInterface; use Tobento\Service\Filesystem\File; class CustomResourceFactory extends ResourceFactory { /** * Create a new Resource from file. * * @param string|File $file * @param string $locale * @return ResourceInterface */ public function createResourceFromFile( string|File $file, string $locale, ): ResourceInterface { // Create your custom resource for the specific file extension // Otherwise use parent return parent::createResourceFromFile($file, $locale); } } $resources = new FilesResources( (new Dirs())->dir(dir: 'private/seeder/'), new CustomResourceFactory() );
Static Seeders
Str Seeder
use Tobento\Service\Seeder\Str; $string = Str::string(length: 10);
Available methods
replace
use Tobento\Service\Seeder\Str; use Tobento\Service\Seeder\Num; $string = Str::replace(string: 'foo/bar', with: [ 'foo' => Num::int(1, 9), 'bar' => Num::int(10, 20) ]);
Lorem Seeder
use Tobento\Service\Seeder\Lorem; $string = Lorem::word(number: 10);
Available methods
Num Seeder
use Tobento\Service\Seeder\Num; $float = Num::float(min: 1.5, max: 55.5);
Available methods
Json Seeder
use Tobento\Service\Seeder\Json; use Tobento\Service\Seeder\Num; $string = Json::encode([ 'tax_id' => Num::int(min: 1, max: 10), 'price_net' => Num::price(min: 1, max: 10), ]);
Available methods
Arr Seeder
use Tobento\Service\Seeder\Arr; $value = Arr::item(['green', 'red', 'blue']);
Available methods