Generate Bag Value Objects, Collections, and Factories
Bag includes the make:bag artisan command to make it easy to generate new Bag classes, Factories, and Collections.
Namespaces
The make:bag command will use the provided namespace to determine the location of the generated classes. You can set the namespace using the --namespace option or you will be prompted for it. The default namespace is \App\Values.
Generating Bags
To create a new Bag class, use the make:bag command:
php artisan make:bag MyBagThis will create a new MyBag class in app/Values/MyBag.php:
<?php
declare(strict_types=1);
namespace App\Values;
use Bag\Bag;
readonly class MyBag extends Bag
{
public function __construct() {
}
}Generating Bag Collections
To create a new Bag Collection class, use the make:bag command with the --collection option:
php artisan make:bag MyBag --collectionYou can optionally specify the name of the collection class:
php artisan make:bag MyBag --collection=MyBagCollectionIf none is specified, it will use prompt you for the collection name, and defaults to the Bag class name with Collection appended to it.
This will create a new MyBagCollection class in app/Values/Collections/MyBagCollection.php.
<?php
declare(strict_types=1);
namespace App\Values\Collections;
use Bag\Collection;
class MyBagCollection extends Collection
{
}NOTE
When creating a new Bag or when specifying the --update flag, it will automatically add the Collection attribute to the Bag class if necessary.
Generating Bag Factories
The make:bag command can also generate Bag Factory classes, and will automatically generate the definition() function based on the Bag class properties.
To create a new Bag Factory class, use the make:bag command with the --factory option:
php artisan make:bag MyBag --factoryThis will create a new MyBagFactory class in app/Values/Factories/MyBagFactory.php:
<?php
declare(strict_types=1);
namespace App\Values\Factories;
use Bag\Factory;
class TestFactory extends Factory
{
public function definition(): array
{
return [
];
}
}TIP
When creating a new Bag or when specifying the --update flag, it will automatically add the Factory attribute and HasFactory trait to the Bag class.
Updating Factories
Once you had added properties to your Bag class, you can update the Factory class using the --update option:
php artisan make:bag MyBag --factory --docs --updateTIP
If you update the Bag class properties, you can re-run the make:bag command with the --update and --force-excluding-bag options to update the Factory class.
For example, if we update our MyBag constructor to look like the following:
public function __construct(
public string $name,
public int $age,
#[Cast(DateTime::class, 'y-m-d')]
public CarbonImmutable $birthday,
public Money $money,
public AnotherBag $test,
#[Cast(CollectionOf::class, AnotherBag::class)]
public Collection $collection,
) {
}The generated factory will look like this:
<?php
declare(strict_types=1);
namespace App\Values\Factories;
use App\Values\AnotherBag;
use Bag\Factory;
use Brick\Money\Money;
use Carbon\CarbonImmutable;
class MyBagFactory extends Factory
{
public function definition(): array
{
return [
'name' => $this->faker->word(),
'age' => $this->faker->randomNumber(),
'birthday' => new CarbonImmutable(),
'money' => Money::ofMinor($this->faker->numberBetween(100, 10000), 'USD'),
'test' => AnotherBag::factory()->make(),
'collection' => AnotherBag::collect([AnotherBag::factory()->make()]),
];
}
}Documentation/Auto-Complete Helpers
To enable easier use of named/positional arguments when creating a new Bag, you can use the --docs option to automatically generate it for the Bag, this will add an @method annotation to the Bag class to provide auto-complete for the ::from() method:
php artisan make:bag MyBag --docsThis will add the following to the MyBag class:
/**
* @method static static from(array $data)
*/Updating Documentation
Similar to Factories, you can update the documentation using the --update option:
php artisan make:bag MyBag --docs --updateThis will update the @method annotation to include documentation for all defined Value attributes. For example, given the following bag:
use App\Values\Collections\ReportCollection;
use App\Values\Report;
use App\Values\Team;
use Carbon\CarbonImmutable;
readonly class User extends Bag {
public function __construct(
public string $name,
public int $age,
public Team $team,
#[Cast(CollectionOf::class, Report::class)]
public ReportCollection $reports,
public CarbonImmutable $lastLogin,
) {
}
}The @method annotation will added to the User class:
use App\Values\Collections\ReportCollection;
use App\Values\Report;
use App\Values\Team;
use Carbon\CarbonImmutable;
/**
* @method static static from(string $name, int $age, Team $team, ReportCollection<Report> $reports, CarbonImmutable $lastLogin)
*/
readonly class User extends Bag {
public function __construct(
public string $name,
public int $age,
public Team $team,
#[Cast(CollectionOf::class, Report::class)]
public ReportCollection $reports,
public CarbonImmutable $lastLogin,
) {
}
}Expected Usage
Because the factory is based on the Bag class properties, you will typically create and customize the Bag value object, and then create the factory and add docs. To do this, you would follow these steps:
- Create the Bag class (optionally, with a collection):
php artisan make:bag MyBag --collectionCustomize the Bag class
Create the Bag Factory and docs:
php artisan make:bag MyBag --factory --docs --updateIf you have already created the factory, you must add the --force-except-bag option to overwrite it:
php artisan make:bag MyBag --factory --docs --update --force-except-bagWARNING
If you use the --force option instead of --force-except-bag it will overwrite your customized Bag Value class, losing any customizations.
The make:bag Command
The make:bag command has the following options:
Description:
Create a new Bag value class, with optional factory and collection.
Usage:
make:bag [options] [--] <name>
Arguments:
name
Options:
-F, --force Force overwriting all files
-E, --force-except-bag Force overwriting Factory/Collection files
-u, --update Update Bag class to add factory/collection
-f, --factory[=FACTORY] Create a Factory for the Bag [default: "interactive"]
-c, --collection[=COLLECTION] Create a Collection for the Bag [default: "interactive"]
-d, --docs Add Bag::from() docs to the Bag for IDE auto-complete
-N, --namespace[=NAMESPACE] Specify the namespace for the Bag
--pretend Dump the file contents instead of writing to disk
-h, --help Display help for the given command. When no command is given display help for the list command
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
-n, --no-interaction Do not ask any interactive question
--env[=ENV] The environment the command should run under
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug