{"action":"created","comment":{"url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/comments/35077853","id":35077853,"diff_hunk":"@@ -84,27 +85,52 @@ protected function applyAddCategoryAction(array $products, ProductAddCategoryAct\n     /**\n      * Applies a set category action on a subject set, if this category exists.\n      *\n-     * @param \\Pim\\Bundle\\CatalogBundle\\Model\\ProductInterface[] $products\n-     * @param ProductSetCategoryActionInterface                  $action\n+     * @param ProductInterface[]                $products\n+     * @param ProductSetCategoryActionInterface $action\n      *\n      * @return ProductsUpdater\n      */\n     protected function applySetCategoryAction(array $products, ProductSetCategoryActionInterface $action)\n     {\n-        foreach ($products as $product) {\n-            $previousCategories = $product->getCategories();\n-            foreach ($previousCategories as $category) {\n-                $product->removeCategory($category);\n-            }\n+        $category = $this->getCategory($action->getCategoryCode());\n+        $tree     = ($action->getTreeCode()) ? $this->getCategory($action->getTreeCode()) : null;\n \n-            if (null !== $action->getCategoryCode()) {\n-                $newCategory = $this->categoryRepository->findOneByIdentifier($action->getCategoryCode());\n-                if (null !== $newCategory) {\n-                    $product->addCategory($newCategory);\n+        foreach ($products as $product) {\n+            // Remove categories (only a tree if asked) from the product\n+            $categories = $product->getCategories();\n+            foreach ($categories as $category) {\n+                if (null === $tree) {\n+                    $product->removeCategory($category);\n+                } else if ($category->getRoot() === $tree->getId()) {","path":"Engine/ProductRuleApplier/ProductsUpdater.php","position":64,"original_position":64,"commit_id":"5974fc14f8c5f6e963e69a293b3c4dd81649b56a","original_commit_id":"5974fc14f8c5f6e963e69a293b3c4dd81649b56a","user":{"login":"fitn","id":2131005,"avatar_url":"https://avatars.githubusercontent.com/u/2131005?v=3","gravatar_id":"","url":"https://api.github.com/users/fitn","html_url":"https://github.com/fitn","followers_url":"https://api.github.com/users/fitn/followers","following_url":"https://api.github.com/users/fitn/following{/other_user}","gists_url":"https://api.github.com/users/fitn/gists{/gist_id}","starred_url":"https://api.github.com/users/fitn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fitn/subscriptions","organizations_url":"https://api.github.com/users/fitn/orgs","repos_url":"https://api.github.com/users/fitn/repos","events_url":"https://api.github.com/users/fitn/events{/privacy}","received_events_url":"https://api.github.com/users/fitn/received_events","type":"User","site_admin":false},"body":"I did not do it for now but will do ;)\r\nWill change the elseif right now","created_at":"2015-07-21T08:03:34Z","updated_at":"2015-07-21T08:03:34Z","html_url":"https://github.com/akeneo-labs/ClassificationRuleBundle/pull/6#discussion_r35077853","pull_request_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/6","_links":{"self":{"href":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/comments/35077853"},"html":{"href":"https://github.com/akeneo-labs/ClassificationRuleBundle/pull/6#discussion_r35077853"},"pull_request":{"href":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/6"}}},"pull_request":{"url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/6","id":40427771,"html_url":"https://github.com/akeneo-labs/ClassificationRuleBundle/pull/6","diff_url":"https://github.com/akeneo-labs/ClassificationRuleBundle/pull/6.diff","patch_url":"https://github.com/akeneo-labs/ClassificationRuleBundle/pull/6.patch","issue_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/issues/6","number":6,"state":"open","locked":false,"title":"[WIP] Tree deletion improvement","user":{"login":"fitn","id":2131005,"avatar_url":"https://avatars.githubusercontent.com/u/2131005?v=3","gravatar_id":"","url":"https://api.github.com/users/fitn","html_url":"https://github.com/fitn","followers_url":"https://api.github.com/users/fitn/followers","following_url":"https://api.github.com/users/fitn/following{/other_user}","gists_url":"https://api.github.com/users/fitn/gists{/gist_id}","starred_url":"https://api.github.com/users/fitn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fitn/subscriptions","organizations_url":"https://api.github.com/users/fitn/orgs","repos_url":"https://api.github.com/users/fitn/repos","events_url":"https://api.github.com/users/fitn/events{/privacy}","received_events_url":"https://api.github.com/users/fitn/received_events","type":"User","site_admin":false},"body":"Two improvements on this PR.\r\nFirst is on performance, throwing an exception if the category defined in the rule is not found. It avoids to call doctrine for each product and to continue to run a rule that is not applicable.\r\n\r\nThe second one is about tree management. Most of the time, we don't want to reset categories but we just want to reset them on a specific tree (to replace them by another for example one). Now you can define a tree in your rule to avoid removing categories from all the trees.\r\n\r\n| Q                    | A\r\n| -------------------- | ---\r\n| Bug fix?             | N\r\n| New feature?         | Y\r\n| BC breaks?           | N/A\r\n| Tests pass?          | ?\r\n| Checkstyle issues?*  | ?\r\n| PMD issues?**        | ?\r\n| Changelog updated?   | Y\r\n| Fixed tickets        | N/A\r\n| DB schema updated?   | N/A\r\n| Migration script?    |\r\n| Doc PR               |","created_at":"2015-07-21T06:58:56Z","updated_at":"2015-07-21T08:03:34Z","closed_at":null,"merged_at":null,"merge_commit_sha":"048ab45efa01aebb9bc89bf958a1154f356c3623","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/6/commits","review_comments_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/6/comments","review_comment_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/comments{/number}","comments_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/issues/6/comments","statuses_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/statuses/5974fc14f8c5f6e963e69a293b3c4dd81649b56a","head":{"label":"akeneo-labs:tree_deletion_improvement","ref":"tree_deletion_improvement","sha":"5974fc14f8c5f6e963e69a293b3c4dd81649b56a","user":{"login":"akeneo-labs","id":11755097,"avatar_url":"https://avatars.githubusercontent.com/u/11755097?v=3","gravatar_id":"","url":"https://api.github.com/users/akeneo-labs","html_url":"https://github.com/akeneo-labs","followers_url":"https://api.github.com/users/akeneo-labs/followers","following_url":"https://api.github.com/users/akeneo-labs/following{/other_user}","gists_url":"https://api.github.com/users/akeneo-labs/gists{/gist_id}","starred_url":"https://api.github.com/users/akeneo-labs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akeneo-labs/subscriptions","organizations_url":"https://api.github.com/users/akeneo-labs/orgs","repos_url":"https://api.github.com/users/akeneo-labs/repos","events_url":"https://api.github.com/users/akeneo-labs/events{/privacy}","received_events_url":"https://api.github.com/users/akeneo-labs/received_events","type":"Organization","site_admin":false},"repo":{"id":33362620,"name":"ClassificationRuleBundle","full_name":"akeneo-labs/ClassificationRuleBundle","owner":{"login":"akeneo-labs","id":11755097,"avatar_url":"https://avatars.githubusercontent.com/u/11755097?v=3","gravatar_id":"","url":"https://api.github.com/users/akeneo-labs","html_url":"https://github.com/akeneo-labs","followers_url":"https://api.github.com/users/akeneo-labs/followers","following_url":"https://api.github.com/users/akeneo-labs/following{/other_user}","gists_url":"https://api.github.com/users/akeneo-labs/gists{/gist_id}","starred_url":"https://api.github.com/users/akeneo-labs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akeneo-labs/subscriptions","organizations_url":"https://api.github.com/users/akeneo-labs/orgs","repos_url":"https://api.github.com/users/akeneo-labs/repos","events_url":"https://api.github.com/users/akeneo-labs/events{/privacy}","received_events_url":"https://api.github.com/users/akeneo-labs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/akeneo-labs/ClassificationRuleBundle","description":"Rules engine based automatic classification bundle","fork":false,"url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle","forks_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/forks","keys_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/keys{/key_id}","collaborators_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/teams","hooks_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/hooks","issue_events_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/issues/events{/number}","events_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/events","assignees_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/assignees{/user}","branches_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/branches{/branch}","tags_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/tags","blobs_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/git/refs{/sha}","trees_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/git/trees{/sha}","statuses_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/statuses/{sha}","languages_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/languages","stargazers_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/stargazers","contributors_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/contributors","subscribers_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/subscribers","subscription_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/subscription","commits_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/commits{/sha}","git_commits_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/git/commits{/sha}","comments_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/comments{/number}","issue_comment_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/issues/comments{/number}","contents_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/contents/{+path}","compare_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/compare/{base}...{head}","merges_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/merges","archive_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/downloads","issues_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/issues{/number}","pulls_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls{/number}","milestones_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/milestones{/number}","notifications_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/labels{/name}","releases_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/releases{/id}","created_at":"2015-04-03T12:39:34Z","updated_at":"2015-07-20T13:14:35Z","pushed_at":"2015-07-21T06:58:56Z","git_url":"git://github.com/akeneo-labs/ClassificationRuleBundle.git","ssh_url":"git@github.com:akeneo-labs/ClassificationRuleBundle.git","clone_url":"https://github.com/akeneo-labs/ClassificationRuleBundle.git","svn_url":"https://github.com/akeneo-labs/ClassificationRuleBundle","homepage":null,"size":245,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"akeneo-labs:master","ref":"master","sha":"b02a6978fddc690ab0d4a3531ac9fd8fa3a720e7","user":{"login":"akeneo-labs","id":11755097,"avatar_url":"https://avatars.githubusercontent.com/u/11755097?v=3","gravatar_id":"","url":"https://api.github.com/users/akeneo-labs","html_url":"https://github.com/akeneo-labs","followers_url":"https://api.github.com/users/akeneo-labs/followers","following_url":"https://api.github.com/users/akeneo-labs/following{/other_user}","gists_url":"https://api.github.com/users/akeneo-labs/gists{/gist_id}","starred_url":"https://api.github.com/users/akeneo-labs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akeneo-labs/subscriptions","organizations_url":"https://api.github.com/users/akeneo-labs/orgs","repos_url":"https://api.github.com/users/akeneo-labs/repos","events_url":"https://api.github.com/users/akeneo-labs/events{/privacy}","received_events_url":"https://api.github.com/users/akeneo-labs/received_events","type":"Organization","site_admin":false},"repo":{"id":33362620,"name":"ClassificationRuleBundle","full_name":"akeneo-labs/ClassificationRuleBundle","owner":{"login":"akeneo-labs","id":11755097,"avatar_url":"https://avatars.githubusercontent.com/u/11755097?v=3","gravatar_id":"","url":"https://api.github.com/users/akeneo-labs","html_url":"https://github.com/akeneo-labs","followers_url":"https://api.github.com/users/akeneo-labs/followers","following_url":"https://api.github.com/users/akeneo-labs/following{/other_user}","gists_url":"https://api.github.com/users/akeneo-labs/gists{/gist_id}","starred_url":"https://api.github.com/users/akeneo-labs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akeneo-labs/subscriptions","organizations_url":"https://api.github.com/users/akeneo-labs/orgs","repos_url":"https://api.github.com/users/akeneo-labs/repos","events_url":"https://api.github.com/users/akeneo-labs/events{/privacy}","received_events_url":"https://api.github.com/users/akeneo-labs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/akeneo-labs/ClassificationRuleBundle","description":"Rules engine based automatic classification bundle","fork":false,"url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle","forks_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/forks","keys_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/keys{/key_id}","collaborators_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/teams","hooks_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/hooks","issue_events_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/issues/events{/number}","events_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/events","assignees_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/assignees{/user}","branches_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/branches{/branch}","tags_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/tags","blobs_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/git/refs{/sha}","trees_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/git/trees{/sha}","statuses_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/statuses/{sha}","languages_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/languages","stargazers_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/stargazers","contributors_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/contributors","subscribers_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/subscribers","subscription_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/subscription","commits_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/commits{/sha}","git_commits_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/git/commits{/sha}","comments_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/comments{/number}","issue_comment_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/issues/comments{/number}","contents_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/contents/{+path}","compare_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/compare/{base}...{head}","merges_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/merges","archive_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/downloads","issues_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/issues{/number}","pulls_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls{/number}","milestones_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/milestones{/number}","notifications_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/labels{/name}","releases_url":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/releases{/id}","created_at":"2015-04-03T12:39:34Z","updated_at":"2015-07-20T13:14:35Z","pushed_at":"2015-07-21T06:58:56Z","git_url":"git://github.com/akeneo-labs/ClassificationRuleBundle.git","ssh_url":"git@github.com:akeneo-labs/ClassificationRuleBundle.git","clone_url":"https://github.com/akeneo-labs/ClassificationRuleBundle.git","svn_url":"https://github.com/akeneo-labs/ClassificationRuleBundle","homepage":null,"size":245,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/6"},"html":{"href":"https://github.com/akeneo-labs/ClassificationRuleBundle/pull/6"},"issue":{"href":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/issues/6"},"comments":{"href":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/issues/6/comments"},"review_comments":{"href":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/6/comments"},"review_comment":{"href":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/pulls/6/commits"},"statuses":{"href":"https://api.github.com/repos/akeneo-labs/ClassificationRuleBundle/statuses/5974fc14f8c5f6e963e69a293b3c4dd81649b56a"}}}}