{"id":13601098,"url":"https://github.com/Aerendir/component-value-objects","last_synced_at":"2025-04-11T01:30:59.025Z","repository":{"id":36960407,"uuid":"38658138","full_name":"Aerendir/component-value-objects","owner":"Aerendir","description":"A set of PHP Value Objects to manage composite values","archived":false,"fork":false,"pushed_at":"2025-04-01T08:04:56.000Z","size":1666,"stargazers_count":20,"open_issues_count":8,"forks_count":1,"subscribers_count":1,"default_branch":"dev","last_synced_at":"2025-04-10T04:02:19.099Z","etag":null,"topics":["doctrine","php","value-object"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Aerendir.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-07-07T02:11:35.000Z","updated_at":"2025-03-20T08:24:43.000Z","dependencies_parsed_at":"2024-01-08T09:39:55.551Z","dependency_job_id":"2964e19f-345c-47c8-a44d-28f5412fe4f1","html_url":"https://github.com/Aerendir/component-value-objects","commit_stats":{"total_commits":812,"total_committers":7,"mean_commits":116.0,"dds":"0.46674876847290636","last_synced_commit":"bb6705456c7eccd63fd7a7a07cb037c0ec0e39c2"},"previous_names":[],"tags_count":83,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aerendir%2Fcomponent-value-objects","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aerendir%2Fcomponent-value-objects/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aerendir%2Fcomponent-value-objects/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aerendir%2Fcomponent-value-objects/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Aerendir","download_url":"https://codeload.github.com/Aerendir/component-value-objects/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248325051,"owners_count":21084860,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["doctrine","php","value-object"],"created_at":"2024-08-01T18:00:55.685Z","updated_at":"2025-04-11T01:30:54.017Z","avatar_url":"https://github.com/Aerendir.png","language":"PHP","readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"http://www.serendipityhq.com\" target=\"_blank\"\u003e\n        \u003cimg style=\"max-width: 350px\" src=\"http://www.serendipityhq.com/assets/open-source-projects/Logo-SerendipityHQ-Icon-Text-Purple.png\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eSerendipity HQ Value Objects\u003c/h1\u003e\n\u003cp align=\"center\"\u003eA set of \u003ca href=\"https://io.serendipityhq.com/experience/php-and-doctrine-immutable-objects-value-objects-and-embeddables/\" target=\"_blank\"\u003ePHP Value Objects\u003c/a\u003e to manage simple and composite values.\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/Aerendir/component-value-objects/releases\"\u003e\u003cimg src=\"https://img.shields.io/packagist/v/serendipity_hq/component-value-objects.svg?style=flat-square\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/Aerendir/component-value-objects/releases\"\u003e\u003cimg src=\"https://img.shields.io/packagist/php-v/serendipity_hq/component-value-objects?color=%238892BF\u0026style=flat-square\u0026logo=php\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp\u003e\n    Supports:\n    \u003ca title=\"Tested with Symfony ^4.4\" href=\"https://github.com/Aerendir/component-value-objects/actions\"\u003e\u003cimg title=\"Tested with Symfony ^4.4\" src=\"https://img.shields.io/badge/Symfony-%5E4.4-333?style=flat-square\u0026logo=symfony\" /\u003e\u003c/a\u003e\n    \u003ca title=\"Tested with Symfony ^5.4\" href=\"https://github.com/Aerendir/component-value-objects/actions\"\u003e\u003cimg title=\"Tested with Symfony ^5.4\" src=\"https://img.shields.io/badge/Symfony-%5E5.4-333?style=flat-square\u0026logo=symfony\" /\u003e\u003c/a\u003e\n    \u003ca title=\"Tested with Symfony ^6.0\" href=\"https://github.com/Aerendir/component-value-objects/actions\"\u003e\u003cimg title=\"Tested with Symfony ^6.0\" src=\"https://img.shields.io/badge/Symfony-%5E6.0-333?style=flat-square\u0026logo=symfony\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp\u003e\n    Tested with:\n    \u003ca title=\"Tested with Symfony ^4.4\" href=\"https://github.com/Aerendir/component-value-objects/actions\"\u003e\u003cimg title=\"Tested with Symfony ^4.4\" src=\"https://img.shields.io/badge/Symfony-%5E4.4-333?style=flat-square\u0026logo=symfony\" /\u003e\u003c/a\u003e\n    \u003ca title=\"Tested with Symfony ^5.4\" href=\"https://github.com/Aerendir/component-value-objects/actions\"\u003e\u003cimg title=\"Tested with Symfony ^5.4\" src=\"https://img.shields.io/badge/Symfony-%5E5.4-333?style=flat-square\u0026logo=symfony\" /\u003e\u003c/a\u003e\n    \u003ca title=\"Tested with Symfony ^6.0\" href=\"https://github.com/Aerendir/component-value-objects/actions\"\u003e\u003cimg title=\"Tested with Symfony ^6.0\" src=\"https://img.shields.io/badge/Symfony-%5E6.0-333?style=flat-square\u0026logo=symfony\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://www.php.net/manual/en/book.intl.php\"\u003e\u003cimg src=\"https://img.shields.io/badge/Suggests-ext--intl-%238892BF?style=flat-square\u0026logo=php\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.doctrine-project.org/\"\u003e\u003cimg src=\"https://img.shields.io/badge/Suggests-doctrine/orm-%238892BF?style=flat-square\u0026logo=php\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://symfony.com/doc/current/forms.html\"\u003e\u003cimg src=\"https://img.shields.io/badge/Suggests-symfony/form-%238892BF?style=flat-square\u0026logo=php\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/twigphp/intl-extra\"\u003e\u003cimg src=\"https://img.shields.io/badge/Suggests-twig/intl--extra-%238892BF?style=flat-square\u0026logo=php\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Current Status\n\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Aerendir_component-value-objects\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=Aerendir_component-value-objects)\n[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=Aerendir_component-value-objects\u0026metric=sqale_rating)](https://sonarcloud.io/dashboard?id=Aerendir_component-value-objects)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Aerendir_component-value-objects\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=Aerendir_component-value-objects)\n[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=Aerendir_component-value-objects\u0026metric=reliability_rating)](https://sonarcloud.io/dashboard?id=Aerendir_component-value-objects)\n[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=Aerendir_component-value-objects\u0026metric=security_rating)](https://sonarcloud.io/dashboard?id=Aerendir_component-value-objects)\n[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=Aerendir_component-value-objects\u0026metric=sqale_index)](https://sonarcloud.io/dashboard?id=Aerendir_component-value-objects)\n[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=Aerendir_component-value-objects\u0026metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=Aerendir_component-value-objects)\n\n[![Phan](https://github.com/Aerendir/component-value-objects/workflows/Phan/badge.svg)](https://github.com/Aerendir/component-value-objects/actions?query=branch%3Adev)\n[![PHPStan](https://github.com/Aerendir/component-value-objects/workflows/PHPStan/badge.svg)](https://github.com/Aerendir/component-value-objects/actions?query=branch%3Adev)\n[![PSalm](https://github.com/Aerendir/component-value-objects/workflows/PSalm/badge.svg)](https://github.com/Aerendir/component-value-objects/actions?query=branch%3Adev)\n[![PHPUnit](https://github.com/Aerendir/component-value-objects/workflows/PHPunit/badge.svg)](https://github.com/Aerendir/component-value-objects/actions?query=branch%3Adev)\n[![Composer](https://github.com/Aerendir/component-value-objects/workflows/Composer/badge.svg)](https://github.com/Aerendir/component-value-objects/actions?query=branch%3Adev)\n[![PHP CS Fixer](https://github.com/Aerendir/component-value-objects/workflows/PHP%20CS%20Fixer/badge.svg)](https://github.com/Aerendir/component-value-objects/actions?query=branch%3Adev)\n[![Rector](https://github.com/Aerendir/component-value-objects/workflows/Rector/badge.svg)](https://github.com/Aerendir/component-value-objects/actions?query=branch%3Adev)\n\n## Features\n\nIt supports `SimpleValueObjects` and `ComplexValueObjects`.\n\nComplex value objects are hydrated passing an array. If a key of the array isn't recognized as property of the object it\n is added to the `$otherData` array so it isn't lost.\n\nSome of those value objects support also the persistence in Doctrine providing [custom mapping types](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/custom-mapping-types.html) (See below).\n\n\u003chr /\u003e\n\u003ch3 align=\"center\"\u003e\n    \u003cb\u003eDo you like this library?\u003c/b\u003e\u003cbr /\u003e\n    \u003cb\u003e\u003ca href=\"#js-repo-pjax-container\"\u003eLEAVE A \u0026#9733;\u003c/a\u003e\u003c/b\u003e\n\u003c/h3\u003e\n\u003cp align=\"center\"\u003e\n    or run\u003cbr /\u003e\n    \u003ccode\u003ecomposer global require symfony/thanks \u0026\u0026 composer thanks\u003c/code\u003e\u003cbr /\u003e\n    to say thank you to all libraries you use in your current project, this included!\n\u003c/p\u003e\n\u003chr /\u003e\n\n## What are Value Objects\n\nValue Objects are PHP [`objects`](http://php.net/manual/en/language.types.object.php) that represent and manage simple\n or complex values. Once set, the value object cannot be modified without changing its identity.\n\n**Simple value objects** represent a simple value, like an email.\n**Complex value objects** represent complex values, that, in order to really represent a value, need more than one\nvalue, like a price that needs an amount and a currency to be understandable and have a sense.\n\nPHP supports only one value object: the [`DateTime`](http://php.net/manual/en/class.datetime.php) object.\n\nThis library gives support for other kind of values, differentiating them between complex and simple.\n\nTo better understand the concepts behind the value objects, you can [read this post](https://io.serendipityhq.com/experience/php-and-doctrine-immutable-objects-value-objects-and-embeddables/).\n\n## Install component-value-objects via Composer\n\n    $ composer require serendipity_hq/component-value-objects\n\nThis library follows the http://semver.org/ versioning conventions.\n\n[Instructions to install Intl PHP extension in MAMP for Mac](https://io.serendipityhq.com/experience/how-to-install-php-intl-module-in-mamp/)\n\n## Available Value Objects\n\nCurrently, this library supports the following Value Objects:\n\n* **[Address](docs/Address.md)**: Built-in. A more advanced value object is [`commerceguys/addressing`](https://github.com/commerceguys/addressing) (but it more suited for shipping addresses than for addresses themself);\n* **[CurrencyExchangeRate](docs/CurrencyExchangeRate.md)**: Built-in;\n* **[Email](docs/Email.md)**: A basic class derived from [Wowo's gist EmailValueObject](https://gist.github.com/wowo/b49ac45b975d5c489214). It implements [`egulias/email-validator](https://github.com/egulias/EmailValidator) to validate emails;\n* **[IP](docs/Ip.md)**: Just a proxy for the library [`darsyn/ip`](https://github.com/darsyn/ip);\n* **[Money](docs/Money.md)**: Just a proxy for the library [`moneyphp/money`](https://github.com/moneyphp/money);\n* **[Payment](docs/Payment.md)**: Built-in\n* **[Phone](docs/Phone.md)**: Just a proxy for the library [`giggsey/libphonenumber-for-php`](https://github.com/giggsey/libphonenumber-for-php);\n* **[Tax](docs/Tax.md)**: Built-in\n* **[Uri](docs/Uri.md)**: Just a proxy for the library [`Laminas\\Uri`](https://github.com/laminas/laminas-uri) (formerly Zend Uri). A more advanced value object is [`League\\Uri`](https://github.com/thephpleague/uri)\n* **[VatRate](docs/Vat.md)**: Built-in\n* **[VatNumber](docs/VatNumber.md)**: Built-in\n\n## Supported features\n\n\u003ctable\u003e\n    \u003cthead\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"col\"\u003eValueObject\u003c/th\u003e\n            \u003cth scope=\"col\" colspan=\"2\"\u003eDoctrine\u003c/th\u003e\n            \u003cth scope=\"col\" colspan=\"2\"\u003eSymfony\u003c/th\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"col\"\u003e\u003c/th\u003e\n            \u003cth scope=\"col\"\u003eEmbeddable\u003c/th\u003e\n            \u003cth scope=\"col\"\u003eType\u003c/th\u003e\n            \u003cth scope=\"col\"\u003eForm Type\u003c/th\u003e\n            \u003cth scope=\"col\"\u003eTwig filter\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/thead\u003e\n    \u003ctbody\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003eAddress\u003c/th\u003e\n            \u003ctd\u003e✓\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✓\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003eCurrency\u003c/th\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n            \u003ctd\u003e✓\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003eCurrencyExchangeRate\u003c/th\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003eEmail\u003c/th\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n            \u003ctd\u003e✓\u003c/td\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003eIP\u003c/th\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003eMoney\u003c/th\u003e\n            \u003ctd\u003eN/A\u003c/td\u003e\n            \u003ctd\u003e✓\u003c/td\u003e\n            \u003ctd\u003e✓\u003c/td\u003e\n            \u003ctd\u003e✓\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003ePayment\u003c/th\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003ePhone\u003c/th\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003eTax\u003c/th\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003eUri\u003c/th\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✓\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003eVAT Rate\u003c/th\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003cth scope=\"row\"\u003eVAT Number\u003c/th\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n            \u003ctd\u003e✕\u003c/td\u003e\n        \u003c/tr\u003e\n    \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003chr /\u003e\n\u003ch3 align=\"center\"\u003e\n    \u003cb\u003eDo you like this library?\u003c/b\u003e\u003cbr /\u003e\n    \u003cb\u003e\u003ca href=\"#js-repo-pjax-container\"\u003eLEAVE A \u0026#9733;\u003c/a\u003e\u003c/b\u003e\n\u003c/h3\u003e\n\u003cp align=\"center\"\u003e\n    or run\u003cbr /\u003e\n    \u003ccode\u003ecomposer global require symfony/thanks \u0026\u0026 composer thanks\u003c/code\u003e\u003cbr /\u003e\n    to say thank you to all libraries you use in your current project, this included!\n\u003c/p\u003e\n\u003chr /\u003e\n","funding_links":[],"categories":["Repositories"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAerendir%2Fcomponent-value-objects","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAerendir%2Fcomponent-value-objects","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAerendir%2Fcomponent-value-objects/lists"}