{"action":"created","comment":{"url":"https://api.github.com/repos/symfony/symfony-docs/pulls/comments/240402689","pull_request_review_id":183426587,"id":240402689,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI0MDQwMjY4OQ==","diff_hunk":"@@ -0,0 +1,208 @@\n+.. index::\n+    single: Form; Data mappers\n+\n+When and How to Use Data Mappers\n+================================\n+\n+When a form is compound, the initial data needs to be passed to children so each can display their\n+own input value. On submission, children values need to be written back into the form.\n+\n+Data mappers are responsible for reading and writing data from and into parent forms.\n+\n+The main built-in data mapper uses the :doc:`PropertyAccess component </components/property_access>`\n+and will fit most cases. However, you can create your implementation that\n+could, for example, pass submitted data to immutable objects via their constructor.\n+\n+The Difference between Data Transformers and Mappers\n+----------------------------------------------------\n+\n+It is important to know the difference between\n+:doc:`data transformers </form/data_transformers>` and mappers.\n+\n+* **Data transformers** change the representation of a value. E.g. from\n+  ``\"2016-08-12\"`` to a ``DateTime`` instance;\n+* **Data mappers** map data (e.g. an object or array) to form fields, and vice versa.\n+\n+Changing a ``YYYY-mm-dd`` string value to a ``DateTime`` instance is done by a\n+data transformer. Populating inner fields (e.g year, hour, etc) of a compound date type using a ``DateTime`` instance is done by the data mapper.\n+\n+Creating a Data Mapper\n+----------------------\n+\n+Suppose that you want to save a set of colors to the database. For this, you're\n+using an immutable color object::\n+\n+    // src/App/Painting/Color.php\n+    namespace App\\Painting;\n+\n+    final class Color\n+    {\n+        private $red;\n+        private $green;\n+        private $blue;\n+\n+        public function __construct(int $red, int $green, int $blue)\n+        {\n+            $this->red = $red;\n+            $this->green = $green;\n+            $this->blue = $blue;\n+        }\n+\n+        public function getRed(): int\n+        {\n+            return $this->red;\n+        }\n+\n+        public function getGreen(): int\n+        {\n+            return $this->green;\n+        }\n+\n+        public function getBlue(): int\n+        {\n+            return $this->blue;\n+        }\n+    }\n+\n+The form type should be allowed to edit a color. But because you've decided to\n+make the ``Color`` object immutable, a new color object has to be created each time\n+one of the values is changed.\n+\n+.. tip::\n+\n+    If you're using a mutable object with constructor arguments, instead of\n+    using a data mapper, you should configure the ``empty_data`` with a closure\n+    as described in\n+    :ref:`How to Configure empty Data for a Form Class <forms-empty-data-closure>`.\n+\n+The red, green and blue form fields have to be mapped to the constructor\n+arguments and the ``Color`` instance has to be mapped to red, green and blue\n+form fields. Recognize a familiar pattern? It's time for a data mapper!\n+\n+.. code-block:: php\n+\n+    // src/App/Form/DataMapper/ColorMapper.php\n+    namespace App\\Form\\DataMapper;\n+\n+    use App\\Painting\\Color;\n+    use Symfony\\Component\\Form\\DataMapperInterface;\n+    use Symfony\\Component\\Form\\Exception\\UnexpectedTypeException;\n+    use Symfony\\Component\\Form\\FormInterface;\n+\n+    final class ColorMapper implements DataMapperInterface\n+    {\n+        /**\n+         * {@inheritdoc}","path":"form/data_mappers.rst","position":95,"original_position":95,"commit_id":"9da0f0ef4a8f07185f3f39c0af59c10938a854cd","original_commit_id":"9da0f0ef4a8f07185f3f39c0af59c10938a854cd","user":{"login":"vudaltsov","id":2552865,"node_id":"MDQ6VXNlcjI1NTI4NjU=","avatar_url":"https://avatars2.githubusercontent.com/u/2552865?v=4","gravatar_id":"","url":"https://api.github.com/users/vudaltsov","html_url":"https://github.com/vudaltsov","followers_url":"https://api.github.com/users/vudaltsov/followers","following_url":"https://api.github.com/users/vudaltsov/following{/other_user}","gists_url":"https://api.github.com/users/vudaltsov/gists{/gist_id}","starred_url":"https://api.github.com/users/vudaltsov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vudaltsov/subscriptions","organizations_url":"https://api.github.com/users/vudaltsov/orgs","repos_url":"https://api.github.com/users/vudaltsov/repos","events_url":"https://api.github.com/users/vudaltsov/events{/privacy}","received_events_url":"https://api.github.com/users/vudaltsov/received_events","type":"User","site_admin":false},"body":"Agree. @HeahDude , I searched  throughout the docs and found only 2 `{@inheritdoc}` tags. Although I would definitely put them in my project, here in docs they make examples unnecessarily verbose.","created_at":"2018-12-10T22:17:17Z","updated_at":"2018-12-10T22:17:17Z","html_url":"https://github.com/symfony/symfony-docs/pull/10756#discussion_r240402689","pull_request_url":"https://api.github.com/repos/symfony/symfony-docs/pulls/10756","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/symfony/symfony-docs/pulls/comments/240402689"},"html":{"href":"https://github.com/symfony/symfony-docs/pull/10756#discussion_r240402689"},"pull_request":{"href":"https://api.github.com/repos/symfony/symfony-docs/pulls/10756"}},"in_reply_to_id":240168376},"pull_request":{"url":"https://api.github.com/repos/symfony/symfony-docs/pulls/10756","id":237072753,"node_id":"MDExOlB1bGxSZXF1ZXN0MjM3MDcyNzUz","html_url":"https://github.com/symfony/symfony-docs/pull/10756","diff_url":"https://github.com/symfony/symfony-docs/pull/10756.diff","patch_url":"https://github.com/symfony/symfony-docs/pull/10756.patch","issue_url":"https://api.github.com/repos/symfony/symfony-docs/issues/10756","number":10756,"state":"open","locked":false,"title":"[Forms] Added data-mapper docs","user":{"login":"vudaltsov","id":2552865,"node_id":"MDQ6VXNlcjI1NTI4NjU=","avatar_url":"https://avatars2.githubusercontent.com/u/2552865?v=4","gravatar_id":"","url":"https://api.github.com/users/vudaltsov","html_url":"https://github.com/vudaltsov","followers_url":"https://api.github.com/users/vudaltsov/followers","following_url":"https://api.github.com/users/vudaltsov/following{/other_user}","gists_url":"https://api.github.com/users/vudaltsov/gists{/gist_id}","starred_url":"https://api.github.com/users/vudaltsov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vudaltsov/subscriptions","organizations_url":"https://api.github.com/users/vudaltsov/orgs","repos_url":"https://api.github.com/users/vudaltsov/repos","events_url":"https://api.github.com/users/vudaltsov/events{/privacy}","received_events_url":"https://api.github.com/users/vudaltsov/received_events","type":"User","site_admin":false},"body":"#SymfonyConHackday2018\r\n\r\nImproved version of https://github.com/symfony/symfony-docs/pull/6900\r\nThank you @wouterj for a great job and the initial text! Thanx @HeahDude for helping me with this PR.","created_at":"2018-12-08T15:06:36Z","updated_at":"2018-12-10T22:17:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"291de32881613f30b12bc10dee4ee55f081ca96c","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":32958317,"node_id":"MDU6TGFiZWwzMjk1ODMxNw==","url":"https://api.github.com/repos/symfony/symfony-docs/labels/Form","name":"Form","color":"DDDDDD","default":false},{"id":110985,"node_id":"MDU6TGFiZWwxMTA5ODU=","url":"https://api.github.com/repos/symfony/symfony-docs/labels/Missing%20Documentation","name":"Missing Documentation","color":"0b02e1","default":false},{"id":122168046,"node_id":"MDU6TGFiZWwxMjIxNjgwNDY=","url":"https://api.github.com/repos/symfony/symfony-docs/labels/Status:%20Reviewed","name":"Status: Reviewed","color":"0e8a16","default":false}],"milestone":{"url":"https://api.github.com/repos/symfony/symfony-docs/milestones/14","html_url":"https://github.com/symfony/symfony-docs/milestone/14","labels_url":"https://api.github.com/repos/symfony/symfony-docs/milestones/14/labels","id":2458541,"node_id":"MDk6TWlsZXN0b25lMjQ1ODU0MQ==","number":14,"title":"3.4","description":"","creator":{"login":"HeahDude","id":10107633,"node_id":"MDQ6VXNlcjEwMTA3NjMz","avatar_url":"https://avatars0.githubusercontent.com/u/10107633?v=4","gravatar_id":"","url":"https://api.github.com/users/HeahDude","html_url":"https://github.com/HeahDude","followers_url":"https://api.github.com/users/HeahDude/followers","following_url":"https://api.github.com/users/HeahDude/following{/other_user}","gists_url":"https://api.github.com/users/HeahDude/gists{/gist_id}","starred_url":"https://api.github.com/users/HeahDude/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HeahDude/subscriptions","organizations_url":"https://api.github.com/users/HeahDude/orgs","repos_url":"https://api.github.com/users/HeahDude/repos","events_url":"https://api.github.com/users/HeahDude/events{/privacy}","received_events_url":"https://api.github.com/users/HeahDude/received_events","type":"User","site_admin":false},"open_issues":31,"closed_issues":414,"state":"open","created_at":"2017-04-15T13:02:34Z","updated_at":"2018-12-10T11:23:12Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/symfony/symfony-docs/pulls/10756/commits","review_comments_url":"https://api.github.com/repos/symfony/symfony-docs/pulls/10756/comments","review_comment_url":"https://api.github.com/repos/symfony/symfony-docs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/symfony/symfony-docs/issues/10756/comments","statuses_url":"https://api.github.com/repos/symfony/symfony-docs/statuses/9da0f0ef4a8f07185f3f39c0af59c10938a854cd","head":{"label":"vudaltsov:data-mappers","ref":"data-mappers","sha":"9da0f0ef4a8f07185f3f39c0af59c10938a854cd","user":{"login":"vudaltsov","id":2552865,"node_id":"MDQ6VXNlcjI1NTI4NjU=","avatar_url":"https://avatars2.githubusercontent.com/u/2552865?v=4","gravatar_id":"","url":"https://api.github.com/users/vudaltsov","html_url":"https://github.com/vudaltsov","followers_url":"https://api.github.com/users/vudaltsov/followers","following_url":"https://api.github.com/users/vudaltsov/following{/other_user}","gists_url":"https://api.github.com/users/vudaltsov/gists{/gist_id}","starred_url":"https://api.github.com/users/vudaltsov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vudaltsov/subscriptions","organizations_url":"https://api.github.com/users/vudaltsov/orgs","repos_url":"https://api.github.com/users/vudaltsov/repos","events_url":"https://api.github.com/users/vudaltsov/events{/privacy}","received_events_url":"https://api.github.com/users/vudaltsov/received_events","type":"User","site_admin":false},"repo":{"id":48736229,"node_id":"MDEwOlJlcG9zaXRvcnk0ODczNjIyOQ==","name":"symfony-docs","full_name":"vudaltsov/symfony-docs","private":false,"owner":{"login":"vudaltsov","id":2552865,"node_id":"MDQ6VXNlcjI1NTI4NjU=","avatar_url":"https://avatars2.githubusercontent.com/u/2552865?v=4","gravatar_id":"","url":"https://api.github.com/users/vudaltsov","html_url":"https://github.com/vudaltsov","followers_url":"https://api.github.com/users/vudaltsov/followers","following_url":"https://api.github.com/users/vudaltsov/following{/other_user}","gists_url":"https://api.github.com/users/vudaltsov/gists{/gist_id}","starred_url":"https://api.github.com/users/vudaltsov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vudaltsov/subscriptions","organizations_url":"https://api.github.com/users/vudaltsov/orgs","repos_url":"https://api.github.com/users/vudaltsov/repos","events_url":"https://api.github.com/users/vudaltsov/events{/privacy}","received_events_url":"https://api.github.com/users/vudaltsov/received_events","type":"User","site_admin":false},"html_url":"https://github.com/vudaltsov/symfony-docs","description":"The Symfony documentation","fork":true,"url":"https://api.github.com/repos/vudaltsov/symfony-docs","forks_url":"https://api.github.com/repos/vudaltsov/symfony-docs/forks","keys_url":"https://api.github.com/repos/vudaltsov/symfony-docs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vudaltsov/symfony-docs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vudaltsov/symfony-docs/teams","hooks_url":"https://api.github.com/repos/vudaltsov/symfony-docs/hooks","issue_events_url":"https://api.github.com/repos/vudaltsov/symfony-docs/issues/events{/number}","events_url":"https://api.github.com/repos/vudaltsov/symfony-docs/events","assignees_url":"https://api.github.com/repos/vudaltsov/symfony-docs/assignees{/user}","branches_url":"https://api.github.com/repos/vudaltsov/symfony-docs/branches{/branch}","tags_url":"https://api.github.com/repos/vudaltsov/symfony-docs/tags","blobs_url":"https://api.github.com/repos/vudaltsov/symfony-docs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vudaltsov/symfony-docs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vudaltsov/symfony-docs/git/refs{/sha}","trees_url":"https://api.github.com/repos/vudaltsov/symfony-docs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vudaltsov/symfony-docs/statuses/{sha}","languages_url":"https://api.github.com/repos/vudaltsov/symfony-docs/languages","stargazers_url":"https://api.github.com/repos/vudaltsov/symfony-docs/stargazers","contributors_url":"https://api.github.com/repos/vudaltsov/symfony-docs/contributors","subscribers_url":"https://api.github.com/repos/vudaltsov/symfony-docs/subscribers","subscription_url":"https://api.github.com/repos/vudaltsov/symfony-docs/subscription","commits_url":"https://api.github.com/repos/vudaltsov/symfony-docs/commits{/sha}","git_commits_url":"https://api.github.com/repos/vudaltsov/symfony-docs/git/commits{/sha}","comments_url":"https://api.github.com/repos/vudaltsov/symfony-docs/comments{/number}","issue_comment_url":"https://api.github.com/repos/vudaltsov/symfony-docs/issues/comments{/number}","contents_url":"https://api.github.com/repos/vudaltsov/symfony-docs/contents/{+path}","compare_url":"https://api.github.com/repos/vudaltsov/symfony-docs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vudaltsov/symfony-docs/merges","archive_url":"https://api.github.com/repos/vudaltsov/symfony-docs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vudaltsov/symfony-docs/downloads","issues_url":"https://api.github.com/repos/vudaltsov/symfony-docs/issues{/number}","pulls_url":"https://api.github.com/repos/vudaltsov/symfony-docs/pulls{/number}","milestones_url":"https://api.github.com/repos/vudaltsov/symfony-docs/milestones{/number}","notifications_url":"https://api.github.com/repos/vudaltsov/symfony-docs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vudaltsov/symfony-docs/labels{/name}","releases_url":"https://api.github.com/repos/vudaltsov/symfony-docs/releases{/id}","deployments_url":"https://api.github.com/repos/vudaltsov/symfony-docs/deployments","created_at":"2015-12-29T08:09:34Z","updated_at":"2017-12-22T13:49:36Z","pushed_at":"2018-12-08T15:10:29Z","git_url":"git://github.com/vudaltsov/symfony-docs.git","ssh_url":"git@github.com:vudaltsov/symfony-docs.git","clone_url":"https://github.com/vudaltsov/symfony-docs.git","svn_url":"https://github.com/vudaltsov/symfony-docs","homepage":"http://symfony.com/doc","size":47011,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"symfony:3.4","ref":"3.4","sha":"9e938dbc3889280624885a46a775dd4729be930b","user":{"login":"symfony","id":143937,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MzkzNw==","avatar_url":"https://avatars3.githubusercontent.com/u/143937?v=4","gravatar_id":"","url":"https://api.github.com/users/symfony","html_url":"https://github.com/symfony","followers_url":"https://api.github.com/users/symfony/followers","following_url":"https://api.github.com/users/symfony/following{/other_user}","gists_url":"https://api.github.com/users/symfony/gists{/gist_id}","starred_url":"https://api.github.com/users/symfony/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/symfony/subscriptions","organizations_url":"https://api.github.com/users/symfony/orgs","repos_url":"https://api.github.com/users/symfony/repos","events_url":"https://api.github.com/users/symfony/events{/privacy}","received_events_url":"https://api.github.com/users/symfony/received_events","type":"Organization","site_admin":false},"repo":{"id":521583,"node_id":"MDEwOlJlcG9zaXRvcnk1MjE1ODM=","name":"symfony-docs","full_name":"symfony/symfony-docs","private":false,"owner":{"login":"symfony","id":143937,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MzkzNw==","avatar_url":"https://avatars3.githubusercontent.com/u/143937?v=4","gravatar_id":"","url":"https://api.github.com/users/symfony","html_url":"https://github.com/symfony","followers_url":"https://api.github.com/users/symfony/followers","following_url":"https://api.github.com/users/symfony/following{/other_user}","gists_url":"https://api.github.com/users/symfony/gists{/gist_id}","starred_url":"https://api.github.com/users/symfony/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/symfony/subscriptions","organizations_url":"https://api.github.com/users/symfony/orgs","repos_url":"https://api.github.com/users/symfony/repos","events_url":"https://api.github.com/users/symfony/events{/privacy}","received_events_url":"https://api.github.com/users/symfony/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/symfony/symfony-docs","description":"The Symfony documentation","fork":false,"url":"https://api.github.com/repos/symfony/symfony-docs","forks_url":"https://api.github.com/repos/symfony/symfony-docs/forks","keys_url":"https://api.github.com/repos/symfony/symfony-docs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/symfony/symfony-docs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/symfony/symfony-docs/teams","hooks_url":"https://api.github.com/repos/symfony/symfony-docs/hooks","issue_events_url":"https://api.github.com/repos/symfony/symfony-docs/issues/events{/number}","events_url":"https://api.github.com/repos/symfony/symfony-docs/events","assignees_url":"https://api.github.com/repos/symfony/symfony-docs/assignees{/user}","branches_url":"https://api.github.com/repos/symfony/symfony-docs/branches{/branch}","tags_url":"https://api.github.com/repos/symfony/symfony-docs/tags","blobs_url":"https://api.github.com/repos/symfony/symfony-docs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/symfony/symfony-docs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/symfony/symfony-docs/git/refs{/sha}","trees_url":"https://api.github.com/repos/symfony/symfony-docs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/symfony/symfony-docs/statuses/{sha}","languages_url":"https://api.github.com/repos/symfony/symfony-docs/languages","stargazers_url":"https://api.github.com/repos/symfony/symfony-docs/stargazers","contributors_url":"https://api.github.com/repos/symfony/symfony-docs/contributors","subscribers_url":"https://api.github.com/repos/symfony/symfony-docs/subscribers","subscription_url":"https://api.github.com/repos/symfony/symfony-docs/subscription","commits_url":"https://api.github.com/repos/symfony/symfony-docs/commits{/sha}","git_commits_url":"https://api.github.com/repos/symfony/symfony-docs/git/commits{/sha}","comments_url":"https://api.github.com/repos/symfony/symfony-docs/comments{/number}","issue_comment_url":"https://api.github.com/repos/symfony/symfony-docs/issues/comments{/number}","contents_url":"https://api.github.com/repos/symfony/symfony-docs/contents/{+path}","compare_url":"https://api.github.com/repos/symfony/symfony-docs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/symfony/symfony-docs/merges","archive_url":"https://api.github.com/repos/symfony/symfony-docs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/symfony/symfony-docs/downloads","issues_url":"https://api.github.com/repos/symfony/symfony-docs/issues{/number}","pulls_url":"https://api.github.com/repos/symfony/symfony-docs/pulls{/number}","milestones_url":"https://api.github.com/repos/symfony/symfony-docs/milestones{/number}","notifications_url":"https://api.github.com/repos/symfony/symfony-docs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/symfony/symfony-docs/labels{/name}","releases_url":"https://api.github.com/repos/symfony/symfony-docs/releases{/id}","deployments_url":"https://api.github.com/repos/symfony/symfony-docs/deployments","created_at":"2010-02-17T08:43:51Z","updated_at":"2018-12-10T04:54:46Z","pushed_at":"2018-12-10T21:08:29Z","git_url":"git://github.com/symfony/symfony-docs.git","ssh_url":"git@github.com:symfony/symfony-docs.git","clone_url":"https://github.com/symfony/symfony-docs.git","svn_url":"https://github.com/symfony/symfony-docs","homepage":"https://symfony.com/doc","size":51421,"stargazers_count":1522,"watchers_count":1522,"language":"PHP","has_issues":true,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":3771,"mirror_url":null,"archived":false,"open_issues_count":339,"license":null,"forks":3771,"open_issues":339,"watchers":1522,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/symfony/symfony-docs/pulls/10756"},"html":{"href":"https://github.com/symfony/symfony-docs/pull/10756"},"issue":{"href":"https://api.github.com/repos/symfony/symfony-docs/issues/10756"},"comments":{"href":"https://api.github.com/repos/symfony/symfony-docs/issues/10756/comments"},"review_comments":{"href":"https://api.github.com/repos/symfony/symfony-docs/pulls/10756/comments"},"review_comment":{"href":"https://api.github.com/repos/symfony/symfony-docs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/symfony/symfony-docs/pulls/10756/commits"},"statuses":{"href":"https://api.github.com/repos/symfony/symfony-docs/statuses/9da0f0ef4a8f07185f3f39c0af59c10938a854cd"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"vudaltsov"}}