A bunch of general-purpose value objects you can use in your Laravel application.

Overview

Laravel Value Objects

Latest Version on Packagist Total Downloads Code Quality Code Coverage GitHub Tests Action Status PHPStan

A bunch of general-purpose value objects you can use in your Laravel application.


The package requires PHP ^8.0 and Laravel ^9.7.

#StandWithUkraine

SWUbanner

Installation

Install the package using composer:

composer require michael-rubel/laravel-value-objects

Built-in value objects

Artisan command

You can generate custom value objects with Artisan command:

php artisan make:value-object YourNameValueObject

Usage

Boolean

$bool = new Boolean('1');
$bool = Boolean::make('1');
$bool = Boolean::from('1');

$bool->value();   // true
(string) $bool;   // 'true'
$bool->toArray(); // ['true']

Decimal

$decimal = new Decimal('10.20999', scale: 2);
$decimal = Decimal::make('10.20999', scale: 2);
$decimal = Decimal::from('10.20999', scale: 2);

$decimal->value();   // '10.20'
(string) $decimal;   // '10.20'
$decimal->toArray(); // ['10.20']

Integer

$integer = new Integer(10);
$integer = Integer::make(10);
$integer = Integer::from(10);

$integer->value();   // 10
(string) $integer;   // '10'
$integer->toArray(); // [10]

Text

$text = new Text('Lorem Ipsum is simply dummy text.');
$text = Text::make('Lorem Ipsum is simply dummy text.');
$text = Text::from('Lorem Ipsum is simply dummy text.');

$text->value();   // 'Lorem Ipsum is simply dummy text.'
(string) $text;   // 'Lorem Ipsum is simply dummy text.'
$text->toArray(); // ['Lorem Ipsum is simply dummy text.']

ClassString

$classString = new ClassString('\Exception');
$classString = ClassString::make('\Exception');
$classString = ClassString::from('\Exception');

$classString->value(); // '\Exception'
(string) $classString; // '\Exception'
$name->toArray();      // ['\Exception']

$classString->classExists();     // true
$classString->interfaceExists(); // false
$classString->instantiate();     // Exception { ... }
$classString->instantiateWith(['message' => 'My message.']); // Exception { #message: "test" ... }

FullName

$name = new FullName(' Taylor   Otwell ');
$name = FullName::make(' Taylor   Otwell ');
$name = FullName::from(' Taylor   Otwell ');

$name->value();   // 'Taylor Otwell'
(string) $name;   // 'Taylor Otwell'
$name->toArray(); // ['fullName' => 'Taylor Otwell', 'firstName' => 'Taylor', 'lastName' => 'Otwell']

$name->fullName();  // 'Taylor Otwell'
$name->firstName(); // 'Taylor'
$name->lastName();  // 'Otwell'

Name

$name = new Name(' Company name! ');
$name = Name::make(' Company name! ');
$name = Name::from(' Company name! ');

$name->value();   // 'Company name!'
(string) $name;   // 'Company name!'
$name->toArray(); // ['Company name!']

TaxNumber

$taxNumber = new TaxNumber('0123456789', 'PL');
$taxNumber = TaxNumber::make('0123456789', 'PL');
$taxNumber = TaxNumber::from('0123456789', 'PL');

$taxNumber->value();   // 'PL0123456789'
(string) $taxNumber;   // 'PL0123456789'
$taxNumber->toArray(); // ['fullTaxNumber' => 'PL0123456789', 'taxNumber' => '0123456789', 'prefix' => 'PL']

$taxNumber->fullTaxNumber(); // 'PL0123456789'
$taxNumber->taxNumber();     // '0123456789'
$taxNumber->prefix();        // 'PL'

Uuid

$uuid = new Uuid('8547d10c-7a37-492a-8d33-be0e5ae6119b', 'Optional name');
$uuid = Uuid::make('8547d10c-7a37-492a-8d33-be0e5ae6119b', 'Optional name');
$uuid = Uuid::from('8547d10c-7a37-492a-8d33-be0e5ae6119b', 'Optional name');

$uuid->value();   // '8547d10c-7a37-492a-8d33-be0e5ae6119b'
(string) $uuid;   // '8547d10c-7a37-492a-8d33-be0e5ae6119b'
$uuid->toArray(); // ['name' => 'Optional name', 'value' => '8547d10c-7a37-492a-8d33-be0e5ae6119b']

$uuid->uuid(); // '8547d10c-7a37-492a-8d33-be0e5ae6119b'
$uuid->name(); // 'Optional name'

Handle failed validation

If you want to avoid try/catching your value object when the validation fails, you can use makeOrNull method:

$bool = Boolean::makeOrNull('bad input'); // null

$bool?->value(); // null

Extending functionality

All value objects are Macroable. This way you can add new methods dynamically. If you need to extend existing methods, you can create a value object locally with make:value-object command and use inheritance.

For example:

ValueObject::macro('str', function () {
    return str($this->value());
});

$name = new Text('Lorem ipsum');

$name->str()->is('Lorem ipsum'); // true

Conditionable

Value objects utilize a Conditionable trait. You can use when and unless methods.

TaxNumber::from('PL0123456789')->when(function ($number) {
    return $number->prefix() !== null;
})->prefix();

Testing

composer test

License

The MIT License (MIT). Please see License File for more information.

Comments
  • Values object must be immutable

    Values object must be immutable

    According to the principles of DDD, Values object must be immutable, but here the constructor are public. So i can easily do this.

    $test = new Text('value1');
    $test->__construct('value2');
    
    echo $test->value; // value2
    

    Shouldn't you protect this method, and make it call from a static method like ValueObject::new($value) ?

    opened by MuntzMathias 3
  • FullName doesn’t work with multi-word surnames

    FullName doesn’t work with multi-word surnames

    My surname is ‘Le Poidevin’ but this gets changed to just ‘Poidevin’.

    $name = new FullName('Richard Le Poidevin');
    
    dd($name->toArray());
    
    //
    array:3 [
      "fullName" => "Richard Le Poidevin"
      "firstName" => "Richard"
      "lastName" => "Poidevin" // should be: Le Poidevin
    ]
    

    It’s a tricky one, where should you break, always the first space? Some people may have multiple first names but I think that’s more likely to be hyphenated whilst surnames with ‘Le’ etc. are pretty common. It’s still better than what usually happens to my name - ‘Richard L’ 😅

    Maybe the default behaviour should be firstName is the first word and everything else forms lastName?

    opened by RicLeP 1
  • Uppercase only first letter of each word in `FullName` object

    Uppercase only first letter of each word in `FullName` object

    About

    This PR fixes the formatting behavior in FullName object. There was a lack of coverage for names like McKenzie.

    We're now converting the first letter of each word instead of doing a regular Title Case.


    BC break major release 
    opened by michael-rubel 0
  • Update `Boolean` object 🔧

    Update `Boolean` object 🔧

    About

    This PR updates the Boolean object:

    • Adds support for "on", "off", "yes", and "no" values;
    • Makes comparisons case-insensitive;
    • Refactors some methods.

    The changes are marked to ship in the major release as these are breaking changes.


    BC break major release 
    opened by michael-rubel 0
  • Add additional values in `Boolean` 🔧

    Add additional values in `Boolean` 🔧

    About

    This PR allows "on", "yes", "off", and "no" values in the Boolean object by default.

    The changes are marked to ship in the major release as these are breaking changes.


    enhancement BC break major release 
    opened by michael-rubel 0
  • Forward methods to underlying object in `Number`

    Forward methods to underlying object in `Number`

    About

    This PR updates the Number object:

    • Adds method forwarding to the underlying object;
    • Adds asBigNumber method to retrieve the underlying object.

    enhancement 
    opened by michael-rubel 0
  • Add `toString` convenience method

    Add `toString` convenience method

    About

    As we have the toArray method in every value object, it's also nice to have a toString method to be able to get the string representation of the object without using a native (string) cast.

    $bool = new Boolean(1);
    
    $bool->toString(); // 'true'
    
    enhancement 
    opened by michael-rubel 0
  • Allow passing formatted value in `Number`

    Allow passing formatted value in `Number`

    About

    This PR adds value sanitization to accept a locale-formatted number in Number object.

    $number = new Number('1 230,00');
    
    $number->value(); // 1230.00
    
    enhancement 
    opened by michael-rubel 0
  • Remove unnecessary methods from Email class

    Remove unnecessary methods from Email class

    The Email class currently does more than handling email logic such as validating active urls, validating alphabetic characters, date validation, file validation, image validation and many other public method from the ValidatesAttributes trait which has no meaning to the Email value object.

    opened by bryanlopezinc 0
  • Add `domain` and `username` methods to `Email`

    Add `domain` and `username` methods to `Email`

    About

    Adds handy extraction of the username and domain parts from the email.

    $email = new Email('[email protected]');
    
    $email->username(); // 'michael'
    $email->domain();   // 'laravel.software'
    $email->toArray();  // ['email' => '[email protected]', 'username' => 'michael', 'domain' => 'laravel.software']
    

    enhancement 
    opened by michael-rubel 0
  • Introduce break control in `FullName` 🧱

    Introduce break control in `FullName` 🧱

    • Resolves #11

    About

    Adds an additional parameter to FullName object to let the developer control how the split breaks your internal value. This way we can solve issues like the one described in #11.

    Example

    $name = 'Richard Le Poidevin';
    
    $fullName = new FullName($name, 2);
    
    $fullName->toArray();
    
    // array:3 [
    //  "fullName" => "Richard Le Poidevin"
    //  "firstName" => "Richard"
    //  "lastName" => "Le Poidevin"
    // ]
    


    enhancement 
    opened by michael-rubel 0
Releases(5.0.0)
  • 5.0.0(Dec 16, 2022)

    What's Changed

    • Uppercase only first letter of each word in FullName object by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/33
    • Update Boolean object 🔧 by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/30
    • Add float support in Number by @olsza in https://github.com/michael-rubel/laravel-value-objects/pull/34

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/4.2.1...5.0.0


    Backward-incompatible changes

    [BC] CHANGED: The parameter $number of MichaelRubel\ValueObjects\Concerns\SanitizesNumbers#sanitize() changed from int|string|null to int|string|float|null [BC] REMOVED: Method MichaelRubel\ValueObjects\Collection\Primitive\Boolean#isInTrueValues() was removed [BC] REMOVED: Method MichaelRubel\ValueObjects\Collection\Primitive\Boolean#isInFalseValues() was removed [BC] CHANGED: Type of property MichaelRubel\ValueObjects\Collection\Primitive\Boolean#$value changed from bool|int|string to bool [BC] CHANGED: Property MichaelRubel\ValueObjects\Collection\Primitive\Boolean#$trueValues changed default value [BC] CHANGED: Property MichaelRubel\ValueObjects\Collection\Primitive\Boolean#$falseValues changed default value [BC] CHANGED: The parameter $number of MichaelRubel\ValueObjects\Collection\Primitive\Number#__construct() changed from int|string to int|string|float [BC] CHANGED: The parameter $number of MichaelRubel\ValueObjects\Concerns\SanitizesNumbers#sanitize() changed from int|string|null to int|string|float|null


    Source code(tar.gz)
    Source code(zip)
  • 4.2.1(Dec 10, 2022)

    What's Changed

    • Allow passing BigNumber object to underlying methods 📚 by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/29
    • Refactor tests for Number object by @olsza in https://github.com/michael-rubel/laravel-value-objects/pull/31
    • Add new test for Number object by @olsza in https://github.com/michael-rubel/laravel-value-objects/pull/32
    • PHP 8.2 build 🐘 by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/35

    New Contributors

    • @olsza made their first contribution in https://github.com/michael-rubel/laravel-value-objects/pull/31

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/4.2.0...4.2.1

    Source code(tar.gz)
    Source code(zip)
  • 4.2.0(Nov 23, 2022)

    What's Changed

    • Forward methods to underlying object in Number by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/27

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/4.1.0...4.2.0

    Source code(tar.gz)
    Source code(zip)
  • 4.1.0(Nov 23, 2022)

    What's Changed

    • Add asFloat casting method to Number 🔨 by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/26

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/4.0.2...4.1.0

    Source code(tar.gz)
    Source code(zip)
  • 4.0.2(Nov 22, 2022)

    What's Changed

    • Make internal BigNumber object immutable 🔧 by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/25

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/4.0.1...4.0.2

    Source code(tar.gz)
    Source code(zip)
  • 4.0.1(Nov 14, 2022)

    What's Changed

    • Update formatters' version 🔖 by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/24

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/4.0.0...4.0.1

    Source code(tar.gz)
    Source code(zip)
  • 4.0.0(Nov 12, 2022)

    What's Changed

    • Add toString convenience method by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/22
    • Introduce mutation testing | Improve code quality & tests by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/23

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/3.5.0...4.0.0

    Source code(tar.gz)
    Source code(zip)
  • 3.5.0(Nov 10, 2022)

    What's Changed

    • Allow passing formatted value in Number by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/21

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/3.4.1...3.5.0

    Source code(tar.gz)
    Source code(zip)
  • 3.4.1(Nov 7, 2022)

    What's Changed

    • Remove unnecessary methods from Email class by @bryanlopezinc in https://github.com/michael-rubel/laravel-value-objects/pull/20

    New Contributors

    • @bryanlopezinc made their first contribution in https://github.com/michael-rubel/laravel-value-objects/pull/20

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/3.4.0...3.4.1

    Source code(tar.gz)
    Source code(zip)
  • 3.4.0(Nov 6, 2022)

    What's Changed

    • Offload sanitization logic to Formatter in Name by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/18
    • Add domain and username methods to Email by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/19

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/3.3.0...3.4.0

    Source code(tar.gz)
    Source code(zip)
  • 3.3.0(Nov 2, 2022)

    What's Changed

    • Move callback logic to trait 🧹 by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/15
    • Move message to interface 🧹 by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/16
    • Introduce break control in FullName 🧱 by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/17

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/3.2.0...3.3.0

    Source code(tar.gz)
    Source code(zip)
  • 3.2.0(Nov 2, 2022)

    What's Changed

    • Improve objects' immutability by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/14

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/3.1.0...3.2.0

    Source code(tar.gz)
    Source code(zip)
  • 3.1.0(Nov 2, 2022)

    What's Changed

    • Add Phone object by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/10
    • Trim value in Phone by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/12

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/3.0.0...3.1.0

    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Oct 31, 2022)

    What's Changed

    • v3 update by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/9

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/2.1.0...3.0.0

    Source code(tar.gz)
    Source code(zip)
  • 2.1.0(Oct 31, 2022)

    What's Changed

    • Add Email object by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/8

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/2.0.1...2.1.0

    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Oct 6, 2022)

    What's Changed

    • Allow passing null to makeOrNull method by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/6

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/2.0.0...2.0.1

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Oct 6, 2022)

    What's Changed

    • Correcting typo on Usage / Boolean sample code by @ramnzys in https://github.com/michael-rubel/laravel-value-objects/pull/3
    • Consistent API for object input validation by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/2
    • Add makeOrNull method to ValueObject by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/4
    • Add Name object by @michael-rubel in https://github.com/michael-rubel/laravel-value-objects/pull/5

    New Contributors

    • @ramnzys made their first contribution in https://github.com/michael-rubel/laravel-value-objects/pull/3
    • @michael-rubel made their first contribution in https://github.com/michael-rubel/laravel-value-objects/pull/2

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/1.0.0...2.0.0

    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Oct 4, 2022)

  • 0.0.5(Sep 29, 2022)

  • 0.0.4(Sep 29, 2022)

  • 0.0.3(Sep 28, 2022)

    What's Changed

    • Fixes require constraint so Composer on Windows can actually resolve correct version between Testbench and Laravel Framework by @crynobone in https://github.com/michael-rubel/laravel-value-objects/pull/1

    New Contributors

    • @crynobone made their first contribution in https://github.com/michael-rubel/laravel-value-objects/pull/1

    Full Changelog: https://github.com/michael-rubel/laravel-value-objects/compare/0.0.2...0.0.3

    Source code(tar.gz)
    Source code(zip)
  • 0.0.2(Sep 26, 2022)

  • 0.0.1(Sep 23, 2022)

Owner
Michael Rubél
Laravel Certified Developer
Michael Rubél
Fresns core library: Cross-platform general-purpose multiple content forms social network service software

About Fresns Fresns is a free and open source social network service software, a general-purpose community product designed for cross-platform, and su

Fresns 82 Dec 31, 2022
YCOM Impersonate. Login as selected YCOM user 🧙‍♂️in frontend.

YCOM Impersonate Login as selected YCOM user in frontend. Features: Backend users with admin rights or YCOM[] rights, can be automatically logged in v

Friends Of REDAXO 17 Sep 12, 2022
PHP package to make your objects strict and throw exception when you try to access or set some undefined property in your objects.

?? Yell PHP package to make your objects strict and throw exception when you try to access or set some undefined property in your objects. Requirement

Zeeshan Ahmad 20 Dec 8, 2018
Parse DSN strings into value objects to make them easier to use, pass around and manipulate

DSN parser Parse DSN strings into value objects to make them easier to use, pass around and manipulate. Install Via Composer composer require nyholm/d

Tobias Nyholm 77 Dec 13, 2022
3D trashcan model with a bunch of features

3D Trashcan plugin with a bunch of features.

broki 5 Jun 20, 2022
SEOstats is a powerful open source PHP library to request a bunch of SEO relevant metrics.

SEOstats: SEO metrics library for PHP SEOstats is the open source PHP library to get SEO-relevant website metrics. SEOstats is used to gather metrics

Stephan Schmitz 1.4k Dec 28, 2022
Collection of value objects that represent the types of the PHP type system

sebastian/type Collection of value objects that represent the types of the PHP type system. Installation You can add this library as a local, per-proj

Sebastian Bergmann 1.1k Dec 29, 2022
A PHP 7 value objects helper library.

valueobjects Requirements Requires PHP >= 7.1 Installation Through Composer, obviously: composer require funeralzone/valueobjects Extensions This lib

Funeral Zone 56 Dec 16, 2022
It is a simple blog application coded with PHP, HTML, CSS. You can develop, edit. You can see it as a skeleton. ⚡

PHP-BLOG-SYSTEM Simple blog system Features Adding Text Update Text Text Deletion User Login and register Bootstrap Design Profile Page How to use blo

Selçuk 2 Aug 21, 2022
JSONFinder - a library that can find json values in a mixed text or html documents, can filter and search the json tree, and converts php objects to json without 'ext-json' extension.

JSONFinder - a library that can find json values in a mixed text or html documents, can filter and search the json tree, and converts php objects to json without 'ext-json' extension.

Eboubaker Eboubaker 2 Jul 31, 2022
My intention with this app is that new developers can have a concrete application with Laravel + VueJS where they can use it as example to learn the right way

My intention with this app is that new developers can have a concrete application with Laravel + VueJS where they can use it as example to learn the right way, implementing the best practices possible and at the same time learn how TDD is done. So this will be an example application but completely usable for any similar case.

Eng Hasan Hajjar 2 Sep 30, 2022
Deeper is a easy way to compare if 2 objects is equal based on values in these objects. This library is heavily inspired in Golang's reflect.DeepEqual().

Deeper Deeper is a easy way to compare if 2 objects is equal based on values in these objects. This library is heavily inspired in Golang's reflect.De

Joubert RedRat 4 Feb 12, 2022
Creating data transfer objects with the power of php objects. No php attributes, no reflection api, and no other under the hook work.

Super Simple DTO Creating data transfer objects with the power of php objects. No php attributes, no reflection api, and no other under the hook work.

Mohammed Manssour 8 Jun 8, 2023
This is a Native PHP MVC. If you will build your own PHP project in MVC with router, you can clone this ready to use MVC pattern repo.

Welcome to PHP-Native-MVC-Pattern ?? If you will build your own PHP project in MVC with router, you can clone this ready to use MVC pattern repo. Work

null 2 Jun 6, 2022
LendCash is a cash lending service that lets you take loans against your stocks portfolio value and pay back on a prorated basis.

LendCash is a cash lending service that lets you take loans against your stocks portfolio value and pay back on a prorated basis.

Teniola Fatunmbi 2 Aug 22, 2022
A PHP library that can be used manually as well as a CLI script that you can just run on your file

Run phpcs on files and only report new warnings/errors compared to the previous version. This is both a PHP library that can be used manually as well

Payton Swick 20 Aug 4, 2022
A horrendous PM plugin to manually load all the chunks in your world without logging on. Only for the sole purpose of aiding in PM4 -> DF world conversion.

ChunkLoader A horrendous PM plugin to manually load all the chunks in your world without logging on. Only for the sole purpose of aiding in PM4 -> DF

null 2 Aug 10, 2022
🌏 Webnux 🌏 , a videos streaming website where you can watch what you want when you want.

?? WEBNUX ?? Welcome to ?? Webnux ?? , a videos streaming website where you can watch what you want when you want. ☀️ ☀️ OBJECTIFS ☀️ ☀️ - A sessi

FrancisNtahimpera 1 Dec 3, 2021