{"action":"created","comment":{"url":"https://api.github.com/repos/shopware/shopware/pulls/comments/23603309","id":23603309,"diff_hunk":"@@ -667,6 +723,58 @@ protected function getAssociationProperty($table, $foreignKey)\n     }\n \n     /**\n+     * Creates the source code for the doctrine association properties,\n+     * which inverse the passed models. That is, models having a property\n+     * that references the currently generated model in an 'inversedBy' field\n+     * of a ManyToOne annotation.\n+     *\n+     * @param $referencingModels array\n+     * @return array\n+     */\n+    protected function getInversedAssociationProperties($referencingModels)\n+    {\n+        // Generate one property for each referncing model\n+        $properties = array();\n+        foreach ($referencingModels as $referencingModel => $relationProperties) {\n+            // Compile the source snippet\n+            $source = self::ONE_TO_MANY_ASSOCIATION_PROPERTY;\n+            $source = str_replace('%owningClass%', $referencingModel, $source);\n+            $source = str_replace('%owningProperty%', $relationProperties['owningProperty'], $source);\n+            $source = str_replace('%property%', $relationProperties['invertingProperty'], $source);\n+\n+            $properties[] = $source;\n+        }\n+\n+        return $properties;\n+    }\n+\n+    /**\n+     * Creates the source code for the custom constructor,\n+     * which initializes each ManyToOne property with an empty\n+     * ArrayCollection.\n+     *\n+     * @param $referencingModels array\n+     * @return string\n+     */\n+    protected function getConstructor($referencingModels) {","path":"engine/Shopware/Components/Model/Generator.php","position":212,"original_position":212,"commit_id":"45d6e1ad31c5609705bd0e06a77ddac1388b3ead","original_commit_id":"45d6e1ad31c5609705bd0e06a77ddac1388b3ead","user":{"login":"bcremer","id":55820,"avatar_url":"https://avatars.githubusercontent.com/u/55820?v=3","gravatar_id":"","url":"https://api.github.com/users/bcremer","html_url":"https://github.com/bcremer","followers_url":"https://api.github.com/users/bcremer/followers","following_url":"https://api.github.com/users/bcremer/following{/other_user}","gists_url":"https://api.github.com/users/bcremer/gists{/gist_id}","starred_url":"https://api.github.com/users/bcremer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bcremer/subscriptions","organizations_url":"https://api.github.com/users/bcremer/orgs","repos_url":"https://api.github.com/users/bcremer/repos","events_url":"https://api.github.com/users/bcremer/events{/privacy}","received_events_url":"https://api.github.com/users/bcremer/received_events","type":"User","site_admin":false},"body":"Please put the opening braces to the next line.","created_at":"2015-01-27T12:07:57Z","updated_at":"2015-01-27T12:07:57Z","html_url":"https://github.com/shopware/shopware/pull/230#discussion_r23603309","pull_request_url":"https://api.github.com/repos/shopware/shopware/pulls/230","_links":{"self":{"href":"https://api.github.com/repos/shopware/shopware/pulls/comments/23603309"},"html":{"href":"https://github.com/shopware/shopware/pull/230#discussion_r23603309"},"pull_request":{"href":"https://api.github.com/repos/shopware/shopware/pulls/230"}}},"pull_request":{"url":"https://api.github.com/repos/shopware/shopware/pulls/230","id":28100085,"html_url":"https://github.com/shopware/shopware/pull/230","diff_url":"https://github.com/shopware/shopware/pull/230.diff","patch_url":"https://github.com/shopware/shopware/pull/230.patch","issue_url":"https://api.github.com/repos/shopware/shopware/issues/230","number":230,"state":"open","locked":false,"title":"Allow generated attribute models to be referenced in custom models via a ManyToOne mapping","user":{"login":"svenmuennich","id":1932115,"avatar_url":"https://avatars.githubusercontent.com/u/1932115?v=3","gravatar_id":"","url":"https://api.github.com/users/svenmuennich","html_url":"https://github.com/svenmuennich","followers_url":"https://api.github.com/users/svenmuennich/followers","following_url":"https://api.github.com/users/svenmuennich/following{/other_user}","gists_url":"https://api.github.com/users/svenmuennich/gists{/gist_id}","starred_url":"https://api.github.com/users/svenmuennich/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/svenmuennich/subscriptions","organizations_url":"https://api.github.com/users/svenmuennich/orgs","repos_url":"https://api.github.com/users/svenmuennich/repos","events_url":"https://api.github.com/users/svenmuennich/events{/privacy}","received_events_url":"https://api.github.com/users/svenmuennich/received_events","type":"User","site_admin":false},"body":"Sometimes it is desirable to have a `ManyToOne` mapping from a custom model in a plugin to a default Shopware model. By utilizing the attribute model generation, this commit dynamically adds properties to the attribute models, which have the inverting `OneToMany` annotation. In addition, a custom constructor for initializing the `ArrayCollection`s as well as respective getter functions are added. This is done by just adding the `ManyToOne` annotation to a property in a custom model and setting the `targetEntity` and `inversedBy` attributes accordingly. That information will then be used to determine the name of the property and getter method in the generated model.\r\n\r\nExample:\r\n```php\r\n<?php\r\n\r\nnamespace Shopware\\CustomModels\\UniquePrefix;\r\n\r\n...\r\n\r\n/**\r\n * @ORM\\Table(name=\"s_test_attribute_feature\")\r\n * @ORM\\Entity\r\n */\r\nclass AttributeFeature extends ModelEntity\r\n{\r\n\r\n\t...\r\n\r\n\t/**\r\n\t * OWNING SIDE\r\n\t *\r\n\t * @ORM\\ManyToOne(targetEntity=\"Shopware\\Models\\Attribute\\Blog\", inversedBy=\"uniquePrefixAttributeFeatures\")\r\n\t * @ORM\\JoinColumn(name=\"attribute_id\", referencedColumnName=\"id\")\r\n\t */\r\n\tprivate $attribute;\r\n\r\n\t...\r\n\r\n}\r\n\r\n```\r\n\r\nPlease note that it's essential to use a unique prefix for the `inversedBy` attribute, since an exception will be thrown, if any two generated `OneToMany` properties have the same name. Additionally, only models, which are registered in the namespace `Shopware\\CustomModels`, will be considered when generating the inverting `OneToMany` properties.\r\n\r\nTo create such a mapping in a plugin, just add the following steps to the plugin `Bootstrap.php`:\r\n```php\r\n// 1. Register the custom models:\r\n$this->registerCustomModels();\r\n\r\n// 2. Re-generate the referenced ('inversedBy') attribute models\r\nShopware()->Models()->generateAttributeModels(array(\r\n\t's_blog_attributes'\r\n));\r\n\r\n// 3. Create the schema for the custom models\r\n$em = Shopware()->Models();\r\n$tool = new \\Doctrine\\ORM\\Tools\\SchemaTool($em);\r\n$tool->createSchema(array(\r\n\t$em->getClassMetadata('Shopware\\CustomModels\\UniquePrefix\\AttributeFeature')\r\n));\r\n```\r\n\r\nSteps `2.` and `3.` can be performed in any order. However, the custom models having the `ManyToOne` mappings must be registered before, using `registerCustomModels()` as defined in `Shopware_Components_Plugin_Bootstrap`.","created_at":"2015-01-27T11:07:09Z","updated_at":"2015-01-27T12:07:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f7ba4a8de9cf0df12264972411d074afc1888ff7","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/shopware/shopware/pulls/230/commits","review_comments_url":"https://api.github.com/repos/shopware/shopware/pulls/230/comments","review_comment_url":"https://api.github.com/repos/shopware/shopware/pulls/comments/{number}","comments_url":"https://api.github.com/repos/shopware/shopware/issues/230/comments","statuses_url":"https://api.github.com/repos/shopware/shopware/statuses/45d6e1ad31c5609705bd0e06a77ddac1388b3ead","head":{"label":"VIISON:attribute-model-one-to-many","ref":"attribute-model-one-to-many","sha":"45d6e1ad31c5609705bd0e06a77ddac1388b3ead","user":{"login":"VIISON","id":710194,"avatar_url":"https://avatars.githubusercontent.com/u/710194?v=3","gravatar_id":"","url":"https://api.github.com/users/VIISON","html_url":"https://github.com/VIISON","followers_url":"https://api.github.com/users/VIISON/followers","following_url":"https://api.github.com/users/VIISON/following{/other_user}","gists_url":"https://api.github.com/users/VIISON/gists{/gist_id}","starred_url":"https://api.github.com/users/VIISON/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/VIISON/subscriptions","organizations_url":"https://api.github.com/users/VIISON/orgs","repos_url":"https://api.github.com/users/VIISON/repos","events_url":"https://api.github.com/users/VIISON/events{/privacy}","received_events_url":"https://api.github.com/users/VIISON/received_events","type":"Organization","site_admin":false},"repo":{"id":13239451,"name":"shopware-4","full_name":"VIISON/shopware-4","owner":{"login":"VIISON","id":710194,"avatar_url":"https://avatars.githubusercontent.com/u/710194?v=3","gravatar_id":"","url":"https://api.github.com/users/VIISON","html_url":"https://github.com/VIISON","followers_url":"https://api.github.com/users/VIISON/followers","following_url":"https://api.github.com/users/VIISON/following{/other_user}","gists_url":"https://api.github.com/users/VIISON/gists{/gist_id}","starred_url":"https://api.github.com/users/VIISON/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/VIISON/subscriptions","organizations_url":"https://api.github.com/users/VIISON/orgs","repos_url":"https://api.github.com/users/VIISON/repos","events_url":"https://api.github.com/users/VIISON/events{/privacy}","received_events_url":"https://api.github.com/users/VIISON/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/VIISON/shopware-4","description":"Shopware 4 Repository","fork":true,"url":"https://api.github.com/repos/VIISON/shopware-4","forks_url":"https://api.github.com/repos/VIISON/shopware-4/forks","keys_url":"https://api.github.com/repos/VIISON/shopware-4/keys{/key_id}","collaborators_url":"https://api.github.com/repos/VIISON/shopware-4/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/VIISON/shopware-4/teams","hooks_url":"https://api.github.com/repos/VIISON/shopware-4/hooks","issue_events_url":"https://api.github.com/repos/VIISON/shopware-4/issues/events{/number}","events_url":"https://api.github.com/repos/VIISON/shopware-4/events","assignees_url":"https://api.github.com/repos/VIISON/shopware-4/assignees{/user}","branches_url":"https://api.github.com/repos/VIISON/shopware-4/branches{/branch}","tags_url":"https://api.github.com/repos/VIISON/shopware-4/tags","blobs_url":"https://api.github.com/repos/VIISON/shopware-4/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/VIISON/shopware-4/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/VIISON/shopware-4/git/refs{/sha}","trees_url":"https://api.github.com/repos/VIISON/shopware-4/git/trees{/sha}","statuses_url":"https://api.github.com/repos/VIISON/shopware-4/statuses/{sha}","languages_url":"https://api.github.com/repos/VIISON/shopware-4/languages","stargazers_url":"https://api.github.com/repos/VIISON/shopware-4/stargazers","contributors_url":"https://api.github.com/repos/VIISON/shopware-4/contributors","subscribers_url":"https://api.github.com/repos/VIISON/shopware-4/subscribers","subscription_url":"https://api.github.com/repos/VIISON/shopware-4/subscription","commits_url":"https://api.github.com/repos/VIISON/shopware-4/commits{/sha}","git_commits_url":"https://api.github.com/repos/VIISON/shopware-4/git/commits{/sha}","comments_url":"https://api.github.com/repos/VIISON/shopware-4/comments{/number}","issue_comment_url":"https://api.github.com/repos/VIISON/shopware-4/issues/comments/{number}","contents_url":"https://api.github.com/repos/VIISON/shopware-4/contents/{+path}","compare_url":"https://api.github.com/repos/VIISON/shopware-4/compare/{base}...{head}","merges_url":"https://api.github.com/repos/VIISON/shopware-4/merges","archive_url":"https://api.github.com/repos/VIISON/shopware-4/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/VIISON/shopware-4/downloads","issues_url":"https://api.github.com/repos/VIISON/shopware-4/issues{/number}","pulls_url":"https://api.github.com/repos/VIISON/shopware-4/pulls{/number}","milestones_url":"https://api.github.com/repos/VIISON/shopware-4/milestones{/number}","notifications_url":"https://api.github.com/repos/VIISON/shopware-4/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/VIISON/shopware-4/labels{/name}","releases_url":"https://api.github.com/repos/VIISON/shopware-4/releases{/id}","created_at":"2013-10-01T09:15:42Z","updated_at":"2014-12-14T17:04:36Z","pushed_at":"2015-01-27T10:53:35Z","git_url":"git://github.com/VIISON/shopware-4.git","ssh_url":"git@github.com:VIISON/shopware-4.git","clone_url":"https://github.com/VIISON/shopware-4.git","svn_url":"https://github.com/VIISON/shopware-4","homepage":"http://www.shopware.de","size":79242,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":5,"forks":0,"open_issues":5,"watchers":0,"default_branch":"master"}},"base":{"label":"shopware:master","ref":"master","sha":"fddab4a449ff95155b6711a18c2f3534a590fc51","user":{"login":"shopware","id":612628,"avatar_url":"https://avatars.githubusercontent.com/u/612628?v=3","gravatar_id":"","url":"https://api.github.com/users/shopware","html_url":"https://github.com/shopware","followers_url":"https://api.github.com/users/shopware/followers","following_url":"https://api.github.com/users/shopware/following{/other_user}","gists_url":"https://api.github.com/users/shopware/gists{/gist_id}","starred_url":"https://api.github.com/users/shopware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shopware/subscriptions","organizations_url":"https://api.github.com/users/shopware/orgs","repos_url":"https://api.github.com/users/shopware/repos","events_url":"https://api.github.com/users/shopware/events{/privacy}","received_events_url":"https://api.github.com/users/shopware/received_events","type":"Organization","site_admin":false},"repo":{"id":5682970,"name":"shopware","full_name":"shopware/shopware","owner":{"login":"shopware","id":612628,"avatar_url":"https://avatars.githubusercontent.com/u/612628?v=3","gravatar_id":"","url":"https://api.github.com/users/shopware","html_url":"https://github.com/shopware","followers_url":"https://api.github.com/users/shopware/followers","following_url":"https://api.github.com/users/shopware/following{/other_user}","gists_url":"https://api.github.com/users/shopware/gists{/gist_id}","starred_url":"https://api.github.com/users/shopware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shopware/subscriptions","organizations_url":"https://api.github.com/users/shopware/orgs","repos_url":"https://api.github.com/users/shopware/repos","events_url":"https://api.github.com/users/shopware/events{/privacy}","received_events_url":"https://api.github.com/users/shopware/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/shopware/shopware","description":"Shopware 4 Repository","fork":false,"url":"https://api.github.com/repos/shopware/shopware","forks_url":"https://api.github.com/repos/shopware/shopware/forks","keys_url":"https://api.github.com/repos/shopware/shopware/keys{/key_id}","collaborators_url":"https://api.github.com/repos/shopware/shopware/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/shopware/shopware/teams","hooks_url":"https://api.github.com/repos/shopware/shopware/hooks","issue_events_url":"https://api.github.com/repos/shopware/shopware/issues/events{/number}","events_url":"https://api.github.com/repos/shopware/shopware/events","assignees_url":"https://api.github.com/repos/shopware/shopware/assignees{/user}","branches_url":"https://api.github.com/repos/shopware/shopware/branches{/branch}","tags_url":"https://api.github.com/repos/shopware/shopware/tags","blobs_url":"https://api.github.com/repos/shopware/shopware/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/shopware/shopware/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/shopware/shopware/git/refs{/sha}","trees_url":"https://api.github.com/repos/shopware/shopware/git/trees{/sha}","statuses_url":"https://api.github.com/repos/shopware/shopware/statuses/{sha}","languages_url":"https://api.github.com/repos/shopware/shopware/languages","stargazers_url":"https://api.github.com/repos/shopware/shopware/stargazers","contributors_url":"https://api.github.com/repos/shopware/shopware/contributors","subscribers_url":"https://api.github.com/repos/shopware/shopware/subscribers","subscription_url":"https://api.github.com/repos/shopware/shopware/subscription","commits_url":"https://api.github.com/repos/shopware/shopware/commits{/sha}","git_commits_url":"https://api.github.com/repos/shopware/shopware/git/commits{/sha}","comments_url":"https://api.github.com/repos/shopware/shopware/comments{/number}","issue_comment_url":"https://api.github.com/repos/shopware/shopware/issues/comments/{number}","contents_url":"https://api.github.com/repos/shopware/shopware/contents/{+path}","compare_url":"https://api.github.com/repos/shopware/shopware/compare/{base}...{head}","merges_url":"https://api.github.com/repos/shopware/shopware/merges","archive_url":"https://api.github.com/repos/shopware/shopware/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/shopware/shopware/downloads","issues_url":"https://api.github.com/repos/shopware/shopware/issues{/number}","pulls_url":"https://api.github.com/repos/shopware/shopware/pulls{/number}","milestones_url":"https://api.github.com/repos/shopware/shopware/milestones{/number}","notifications_url":"https://api.github.com/repos/shopware/shopware/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/shopware/shopware/labels{/name}","releases_url":"https://api.github.com/repos/shopware/shopware/releases{/id}","created_at":"2012-09-05T05:32:50Z","updated_at":"2015-01-26T13:09:00Z","pushed_at":"2015-01-20T08:33:07Z","git_url":"git://github.com/shopware/shopware.git","ssh_url":"git@github.com:shopware/shopware.git","clone_url":"https://github.com/shopware/shopware.git","svn_url":"https://github.com/shopware/shopware","homepage":"http://www.shopware.com","size":108148,"stargazers_count":201,"watchers_count":201,"language":"PHP","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":146,"mirror_url":null,"open_issues_count":70,"forks":146,"open_issues":70,"watchers":201,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/shopware/shopware/pulls/230"},"html":{"href":"https://github.com/shopware/shopware/pull/230"},"issue":{"href":"https://api.github.com/repos/shopware/shopware/issues/230"},"comments":{"href":"https://api.github.com/repos/shopware/shopware/issues/230/comments"},"review_comments":{"href":"https://api.github.com/repos/shopware/shopware/pulls/230/comments"},"review_comment":{"href":"https://api.github.com/repos/shopware/shopware/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/shopware/shopware/pulls/230/commits"},"statuses":{"href":"https://api.github.com/repos/shopware/shopware/statuses/45d6e1ad31c5609705bd0e06a77ddac1388b3ead"}}}}