{"action":"created","comment":{"url":"https://api.github.com/repos/magento/magento2/pulls/comments/29492232","id":29492232,"diff_hunk":"@@ -0,0 +1,49 @@\n+<?php\r\n+/**\r\n+ * Copyright © 2015 Magento. All rights reserved.\r\n+ * See COPYING.txt for license details.\r\n+ */\r\n+\r\n+namespace Magento\\Framework\\Module\\Dir;\r\n+\r\n+/**\r\n+ * Provides ability to statically register modules which do not reside in the modules directory\r\n+ *\r\n+ * @author Josh Di Fabio <joshdifabio@gmail.com>\r\n+ */\r\n+final class Resolver implements ResolverInterface\r\n+{\r\n+    /**\r\n+     * Paths to modules\r\n+     *\r\n+     * @var string[]\r\n+     */\r\n+    private static $modulePaths = [];\r\n+\r\n+    /**\r\n+     * Sets the location of a module. Necessary for modules which do not reside in modules directory\r\n+     *\r\n+     * @param string $moduleName Fully-qualified module name\r\n+     * @param string $path Absolute file path to the module\r\n+     */\r\n+    public static function setModulePath($moduleName, $path)\r","path":"lib/internal/Magento/Framework/Module/Dir/Resolver.php","position":29,"original_position":29,"commit_id":"834ff3ee440fa386a6028578f4b142bcdf25cbf7","original_commit_id":"834ff3ee440fa386a6028578f4b142bcdf25cbf7","user":{"login":"antonkril","id":767132,"avatar_url":"https://avatars.githubusercontent.com/u/767132?v=3","gravatar_id":"","url":"https://api.github.com/users/antonkril","html_url":"https://github.com/antonkril","followers_url":"https://api.github.com/users/antonkril/followers","following_url":"https://api.github.com/users/antonkril/following{/other_user}","gists_url":"https://api.github.com/users/antonkril/gists{/gist_id}","starred_url":"https://api.github.com/users/antonkril/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/antonkril/subscriptions","organizations_url":"https://api.github.com/users/antonkril/orgs","repos_url":"https://api.github.com/users/antonkril/repos","events_url":"https://api.github.com/users/antonkril/events{/privacy}","received_events_url":"https://api.github.com/users/antonkril/received_events","type":"User","site_admin":false},"body":"Static calls are hard-coded dependencies, they can not be substituted or decorated. So please avoid them. Other problem is that with such approach there is no strict rule when all module paths are available, because you don't know if all modules called setModulePaths, and module dev doesn't know when it should call setModulePath.\r\n","created_at":"2015-05-01T07:13:54Z","updated_at":"2015-05-01T07:13:54Z","html_url":"https://github.com/magento/magento2/pull/1206#discussion_r29492232","pull_request_url":"https://api.github.com/repos/magento/magento2/pulls/1206","_links":{"self":{"href":"https://api.github.com/repos/magento/magento2/pulls/comments/29492232"},"html":{"href":"https://github.com/magento/magento2/pull/1206#discussion_r29492232"},"pull_request":{"href":"https://api.github.com/repos/magento/magento2/pulls/1206"}}},"pull_request":{"url":"https://api.github.com/repos/magento/magento2/pulls/1206","id":33694997,"html_url":"https://github.com/magento/magento2/pull/1206","diff_url":"https://github.com/magento/magento2/pull/1206.diff","patch_url":"https://github.com/magento/magento2/pull/1206.patch","issue_url":"https://api.github.com/repos/magento/magento2/issues/1206","number":1206,"state":"open","locked":false,"title":"[WIP] Allow modules to live outside of app/code directory","user":{"login":"joshdifabio","id":5609851,"avatar_url":"https://avatars.githubusercontent.com/u/5609851?v=3","gravatar_id":"","url":"https://api.github.com/users/joshdifabio","html_url":"https://github.com/joshdifabio","followers_url":"https://api.github.com/users/joshdifabio/followers","following_url":"https://api.github.com/users/joshdifabio/following{/other_user}","gists_url":"https://api.github.com/users/joshdifabio/gists{/gist_id}","starred_url":"https://api.github.com/users/joshdifabio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joshdifabio/subscriptions","organizations_url":"https://api.github.com/users/joshdifabio/orgs","repos_url":"https://api.github.com/users/joshdifabio/repos","events_url":"https://api.github.com/users/joshdifabio/events{/privacy}","received_events_url":"https://api.github.com/users/joshdifabio/received_events","type":"User","site_admin":false},"body":"Partially resolves #1013.\r\n\r\nThis PR aims to enable Magento modules to reside in the `vendor` directory, or indeed anywhere else on disk, without the use of any Composer plugins and without copying or linking any module files.\r\n\r\n**How does it work?**\r\n\r\nThis PR adds the concept of a *module directory resolver* to the `Magento\\Framework\\Module` package. This *directory resolver* provides Magento with the locations of any modules which do not reside in the standard modules directory (currently `app/code`). This PR does not remove the existing module bootstrapping functionality and aims to be backwards compatible with Magento 2's existing module implementation.\r\n\r\nProvided in the PR is a `ResolverInterface` which exposes two non-static methods which allow Magento to locate modules. Also provided is a concrete `Resolver` implementation which implements the `ResolverInterface` while also implementing a static `setModulePath()` method which third party modules can use to register themselves with Magento. Magento itself does not depend on the static `setModulePath()` method, which will help with automated testing of those Magento classes which depend on `ResolverInterface`.\r\n\r\nModules will be installed using Composer but without the use of any Composer plugins. No code will be copied from vendor, or wherever else the modules are located, into the Magento application directory.\r\n\r\n**What would a module look like with this approach?**\r\n\r\nTo use this functionality, a module will need to call the static `Resolver::setModulePath()` method in order to notify the Magento application of its presence and location.\r\n\r\n`bootstrap.php`\r\n```php\r\n<?php\r\nMagento\\Framework\\Module\\Dir\\Resolver::setModulePath('FooVendor_BarModule', __DIR__);\r\n```\r\n\r\n`composer.json`\r\n```json\r\n{\r\n    \"name\": \"foo-vendor/bar-module\",\r\n    \"autoload\": {\r\n        \"psr-4\": { \"FooVendor\\\\BarModule\\\\\": \"\" },\r\n        \"files\": [ \"bootstrap.php\" ]\r\n    }\r\n}\r\n```\r\n\r\nWhen Composer's `vendor/autoload.php` is included, `autoload_real.php` first processes the various namespaces, class paths and include paths defined in all included composer packages and registers the autoloader. Next, `autoload_real.php` `include`s all files defined in `autoload.files`. This means that, in the above example, `bootstrap.php` will be included by Composer and will have access to any classes which are known to the Composer autoloader.\r\n\r\n**Why is this good?**\r\n\r\nCopying files around using Composer plugins adds a lot of complexity and I believe Magento already know most of the related difficulties. It also makes the standard process of downloading and testing a package very difficult:\r\n\r\n```\r\n$ git clone git@github.com:foo_vendor/bar_module.git\r\n$ cd bar_module\r\n$ composer install\r\n$ php vendor/bin/phpunit\r\n```\r\n\r\nHowever, this proposal enables the above process to work; even if the module is located in the root while the application code is installed to the vendor directory, the `bootstrap.php` file will be included by Composer and will register the module with Magento. This would mean that we could finally, easily, create modules and build our code on Travis, Scrutinizer, or any of the other brilliant, free code coverage and static analysis tools.\r\n\r\nThis weekend (2015-04-24 – 2015-04-26) I'll aim to finish this PR.","created_at":"2015-04-20T18:56:55Z","updated_at":"2015-05-01T07:13:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0fe583e14ffa64a333e9d075557857d4ccc36522","assignee":{"login":"otoolec","id":1630589,"avatar_url":"https://avatars.githubusercontent.com/u/1630589?v=3","gravatar_id":"","url":"https://api.github.com/users/otoolec","html_url":"https://github.com/otoolec","followers_url":"https://api.github.com/users/otoolec/followers","following_url":"https://api.github.com/users/otoolec/following{/other_user}","gists_url":"https://api.github.com/users/otoolec/gists{/gist_id}","starred_url":"https://api.github.com/users/otoolec/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/otoolec/subscriptions","organizations_url":"https://api.github.com/users/otoolec/orgs","repos_url":"https://api.github.com/users/otoolec/repos","events_url":"https://api.github.com/users/otoolec/events{/privacy}","received_events_url":"https://api.github.com/users/otoolec/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/magento/magento2/pulls/1206/commits","review_comments_url":"https://api.github.com/repos/magento/magento2/pulls/1206/comments","review_comment_url":"https://api.github.com/repos/magento/magento2/pulls/comments{/number}","comments_url":"https://api.github.com/repos/magento/magento2/issues/1206/comments","statuses_url":"https://api.github.com/repos/magento/magento2/statuses/834ff3ee440fa386a6028578f4b142bcdf25cbf7","head":{"label":"joshdifabio:modules-in-vendor2","ref":"modules-in-vendor2","sha":"834ff3ee440fa386a6028578f4b142bcdf25cbf7","user":{"login":"joshdifabio","id":5609851,"avatar_url":"https://avatars.githubusercontent.com/u/5609851?v=3","gravatar_id":"","url":"https://api.github.com/users/joshdifabio","html_url":"https://github.com/joshdifabio","followers_url":"https://api.github.com/users/joshdifabio/followers","following_url":"https://api.github.com/users/joshdifabio/following{/other_user}","gists_url":"https://api.github.com/users/joshdifabio/gists{/gist_id}","starred_url":"https://api.github.com/users/joshdifabio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joshdifabio/subscriptions","organizations_url":"https://api.github.com/users/joshdifabio/orgs","repos_url":"https://api.github.com/users/joshdifabio/repos","events_url":"https://api.github.com/users/joshdifabio/events{/privacy}","received_events_url":"https://api.github.com/users/joshdifabio/received_events","type":"User","site_admin":false},"repo":{"id":34133300,"name":"magento2","full_name":"joshdifabio/magento2","owner":{"login":"joshdifabio","id":5609851,"avatar_url":"https://avatars.githubusercontent.com/u/5609851?v=3","gravatar_id":"","url":"https://api.github.com/users/joshdifabio","html_url":"https://github.com/joshdifabio","followers_url":"https://api.github.com/users/joshdifabio/followers","following_url":"https://api.github.com/users/joshdifabio/following{/other_user}","gists_url":"https://api.github.com/users/joshdifabio/gists{/gist_id}","starred_url":"https://api.github.com/users/joshdifabio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joshdifabio/subscriptions","organizations_url":"https://api.github.com/users/joshdifabio/orgs","repos_url":"https://api.github.com/users/joshdifabio/repos","events_url":"https://api.github.com/users/joshdifabio/events{/privacy}","received_events_url":"https://api.github.com/users/joshdifabio/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/joshdifabio/magento2","description":"All Submissions you make to Magento, an eBay Inc. company (“Magento”) through GitHub are subject to the following terms and conditions: (1)\tYou grant Magento a perpetual, worldwide, non-exclusive, no charge, royalty free, irrevocable      license under your applicable copyrights and patents to reproduce, prepare derivative works of, display, publically perform, sublicense and distribute any feedback, ideas, code, or other information (“Submission”) you submit through GitHub. (2)\tYour Submission is an original work of authorship and you are the owner or are legally entitled to grant the license stated above. (3)\tYou agree to the Contributor License Agreement found here:  https://github.com/magento/magento2/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.html","fork":true,"url":"https://api.github.com/repos/joshdifabio/magento2","forks_url":"https://api.github.com/repos/joshdifabio/magento2/forks","keys_url":"https://api.github.com/repos/joshdifabio/magento2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/joshdifabio/magento2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/joshdifabio/magento2/teams","hooks_url":"https://api.github.com/repos/joshdifabio/magento2/hooks","issue_events_url":"https://api.github.com/repos/joshdifabio/magento2/issues/events{/number}","events_url":"https://api.github.com/repos/joshdifabio/magento2/events","assignees_url":"https://api.github.com/repos/joshdifabio/magento2/assignees{/user}","branches_url":"https://api.github.com/repos/joshdifabio/magento2/branches{/branch}","tags_url":"https://api.github.com/repos/joshdifabio/magento2/tags","blobs_url":"https://api.github.com/repos/joshdifabio/magento2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/joshdifabio/magento2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/joshdifabio/magento2/git/refs{/sha}","trees_url":"https://api.github.com/repos/joshdifabio/magento2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/joshdifabio/magento2/statuses/{sha}","languages_url":"https://api.github.com/repos/joshdifabio/magento2/languages","stargazers_url":"https://api.github.com/repos/joshdifabio/magento2/stargazers","contributors_url":"https://api.github.com/repos/joshdifabio/magento2/contributors","subscribers_url":"https://api.github.com/repos/joshdifabio/magento2/subscribers","subscription_url":"https://api.github.com/repos/joshdifabio/magento2/subscription","commits_url":"https://api.github.com/repos/joshdifabio/magento2/commits{/sha}","git_commits_url":"https://api.github.com/repos/joshdifabio/magento2/git/commits{/sha}","comments_url":"https://api.github.com/repos/joshdifabio/magento2/comments{/number}","issue_comment_url":"https://api.github.com/repos/joshdifabio/magento2/issues/comments{/number}","contents_url":"https://api.github.com/repos/joshdifabio/magento2/contents/{+path}","compare_url":"https://api.github.com/repos/joshdifabio/magento2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/joshdifabio/magento2/merges","archive_url":"https://api.github.com/repos/joshdifabio/magento2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/joshdifabio/magento2/downloads","issues_url":"https://api.github.com/repos/joshdifabio/magento2/issues{/number}","pulls_url":"https://api.github.com/repos/joshdifabio/magento2/pulls{/number}","milestones_url":"https://api.github.com/repos/joshdifabio/magento2/milestones{/number}","notifications_url":"https://api.github.com/repos/joshdifabio/magento2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/joshdifabio/magento2/labels{/name}","releases_url":"https://api.github.com/repos/joshdifabio/magento2/releases{/id}","created_at":"2015-04-17T18:31:22Z","updated_at":"2015-04-17T18:32:00Z","pushed_at":"2015-04-25T13:28:56Z","git_url":"git://github.com/joshdifabio/magento2.git","ssh_url":"git@github.com:joshdifabio/magento2.git","clone_url":"https://github.com/joshdifabio/magento2.git","svn_url":"https://github.com/joshdifabio/magento2","homepage":"http://www.magento.com","size":186041,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"develop"}},"base":{"label":"magento:develop","ref":"develop","sha":"ce82076cb45866f850f269e2810400133922c6f6","user":{"login":"magento","id":168457,"avatar_url":"https://avatars.githubusercontent.com/u/168457?v=3","gravatar_id":"","url":"https://api.github.com/users/magento","html_url":"https://github.com/magento","followers_url":"https://api.github.com/users/magento/followers","following_url":"https://api.github.com/users/magento/following{/other_user}","gists_url":"https://api.github.com/users/magento/gists{/gist_id}","starred_url":"https://api.github.com/users/magento/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/magento/subscriptions","organizations_url":"https://api.github.com/users/magento/orgs","repos_url":"https://api.github.com/users/magento/repos","events_url":"https://api.github.com/users/magento/events{/privacy}","received_events_url":"https://api.github.com/users/magento/received_events","type":"Organization","site_admin":false},"repo":{"id":2884111,"name":"magento2","full_name":"magento/magento2","owner":{"login":"magento","id":168457,"avatar_url":"https://avatars.githubusercontent.com/u/168457?v=3","gravatar_id":"","url":"https://api.github.com/users/magento","html_url":"https://github.com/magento","followers_url":"https://api.github.com/users/magento/followers","following_url":"https://api.github.com/users/magento/following{/other_user}","gists_url":"https://api.github.com/users/magento/gists{/gist_id}","starred_url":"https://api.github.com/users/magento/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/magento/subscriptions","organizations_url":"https://api.github.com/users/magento/orgs","repos_url":"https://api.github.com/users/magento/repos","events_url":"https://api.github.com/users/magento/events{/privacy}","received_events_url":"https://api.github.com/users/magento/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/magento/magento2","description":"All Submissions you make to Magento, an eBay Inc. company (“Magento”) through GitHub are subject to the following terms and conditions: (1)\tYou grant Magento a perpetual, worldwide, non-exclusive, no charge, royalty free, irrevocable      license under your applicable copyrights and patents to reproduce, prepare derivative works of, display, publically perform, sublicense and distribute any feedback, ideas, code, or other information (“Submission”) you submit through GitHub. (2)\tYour Submission is an original work of authorship and you are the owner or are legally entitled to grant the license stated above. (3)\tYou agree to the Contributor License Agreement found here:  https://github.com/magento/magento2/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.html","fork":false,"url":"https://api.github.com/repos/magento/magento2","forks_url":"https://api.github.com/repos/magento/magento2/forks","keys_url":"https://api.github.com/repos/magento/magento2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/magento/magento2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/magento/magento2/teams","hooks_url":"https://api.github.com/repos/magento/magento2/hooks","issue_events_url":"https://api.github.com/repos/magento/magento2/issues/events{/number}","events_url":"https://api.github.com/repos/magento/magento2/events","assignees_url":"https://api.github.com/repos/magento/magento2/assignees{/user}","branches_url":"https://api.github.com/repos/magento/magento2/branches{/branch}","tags_url":"https://api.github.com/repos/magento/magento2/tags","blobs_url":"https://api.github.com/repos/magento/magento2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/magento/magento2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/magento/magento2/git/refs{/sha}","trees_url":"https://api.github.com/repos/magento/magento2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/magento/magento2/statuses/{sha}","languages_url":"https://api.github.com/repos/magento/magento2/languages","stargazers_url":"https://api.github.com/repos/magento/magento2/stargazers","contributors_url":"https://api.github.com/repos/magento/magento2/contributors","subscribers_url":"https://api.github.com/repos/magento/magento2/subscribers","subscription_url":"https://api.github.com/repos/magento/magento2/subscription","commits_url":"https://api.github.com/repos/magento/magento2/commits{/sha}","git_commits_url":"https://api.github.com/repos/magento/magento2/git/commits{/sha}","comments_url":"https://api.github.com/repos/magento/magento2/comments{/number}","issue_comment_url":"https://api.github.com/repos/magento/magento2/issues/comments{/number}","contents_url":"https://api.github.com/repos/magento/magento2/contents/{+path}","compare_url":"https://api.github.com/repos/magento/magento2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/magento/magento2/merges","archive_url":"https://api.github.com/repos/magento/magento2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/magento/magento2/downloads","issues_url":"https://api.github.com/repos/magento/magento2/issues{/number}","pulls_url":"https://api.github.com/repos/magento/magento2/pulls{/number}","milestones_url":"https://api.github.com/repos/magento/magento2/milestones{/number}","notifications_url":"https://api.github.com/repos/magento/magento2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/magento/magento2/labels{/name}","releases_url":"https://api.github.com/repos/magento/magento2/releases{/id}","created_at":"2011-11-30T15:30:13Z","updated_at":"2015-04-30T15:40:50Z","pushed_at":"2015-04-30T15:40:51Z","git_url":"git://github.com/magento/magento2.git","ssh_url":"git@github.com:magento/magento2.git","clone_url":"https://github.com/magento/magento2.git","svn_url":"https://github.com/magento/magento2","homepage":"http://www.magento.com","size":440552,"stargazers_count":2274,"watchers_count":2274,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1256,"mirror_url":null,"open_issues_count":208,"forks":1256,"open_issues":208,"watchers":2274,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/magento/magento2/pulls/1206"},"html":{"href":"https://github.com/magento/magento2/pull/1206"},"issue":{"href":"https://api.github.com/repos/magento/magento2/issues/1206"},"comments":{"href":"https://api.github.com/repos/magento/magento2/issues/1206/comments"},"review_comments":{"href":"https://api.github.com/repos/magento/magento2/pulls/1206/comments"},"review_comment":{"href":"https://api.github.com/repos/magento/magento2/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/magento/magento2/pulls/1206/commits"},"statuses":{"href":"https://api.github.com/repos/magento/magento2/statuses/834ff3ee440fa386a6028578f4b142bcdf25cbf7"}}}}