{"action":"created","comment":{"url":"https://api.github.com/repos/piwik/piwik/pulls/comments/36493435","id":36493435,"diff_hunk":"@@ -0,0 +1,58 @@\n+<?php\n+/**\n+ * Piwik - free/libre analytics platform\n+ *\n+ * @link http://piwik.org\n+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later\n+ */\n+\n+namespace Piwik\\Tracker\\Visit;\n+\n+/**\n+ * Holds temporary data for tracking requests.\n+ *\n+ * RequestProcessors\n+ */\n+class VisitProperties\n+{\n+    /**\n+     * Information about the current visit. This array holds the column values that will be inserted or updated\n+     * in the `log_visit` table, or the values for the last known visit of the current visitor.\n+     *\n+     * @var array\n+     */\n+    public $visitorInfo = array();\n+\n+    /**\n+     * Stores plugin specific tracking request metadata. RequestProcessors can store\n+     * whatever they want in this array, and other RequestProcessors can modify these\n+     * values to change tracker behavior.\n+     *\n+     * @var string[][]\n+     */\n+    private $requestMetadata = array();\n+\n+    /**\n+     * Set a request metadata value.\n+     *\n+     * @param string $pluginName eg, `'Actions'`, `'Goals'`, `'YourPlugin'`\n+     * @param string $key\n+     * @param mixed $value\n+     */\n+    public function setRequestMetadata($pluginName, $key, $value)\n+    {\n+        $this->requestMetadata[$pluginName][$key] = $value;","path":"core/Tracker/Visit/VisitProperties.php","position":null,"original_position":44,"commit_id":"7baf3df7dcbf9ef7952612831b387ca72d75e165","original_commit_id":"7de209e02d757a49559de9b6f345079ecca13394","user":{"login":"tsteur","id":273120,"avatar_url":"https://avatars.githubusercontent.com/u/273120?v=3","gravatar_id":"","url":"https://api.github.com/users/tsteur","html_url":"https://github.com/tsteur","followers_url":"https://api.github.com/users/tsteur/followers","following_url":"https://api.github.com/users/tsteur/following{/other_user}","gists_url":"https://api.github.com/users/tsteur/gists{/gist_id}","starred_url":"https://api.github.com/users/tsteur/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tsteur/subscriptions","organizations_url":"https://api.github.com/users/tsteur/orgs","repos_url":"https://api.github.com/users/tsteur/repos","events_url":"https://api.github.com/users/tsteur/events{/privacy}","received_events_url":"https://api.github.com/users/tsteur/received_events","type":"User","site_admin":false},"body":"I don't mean actually doing it in core. The core should provide a getter and setter method eg for `isVisitKnown`. Any plugin will be able to change this value. The core knows about `(CoreHome, isVisitKnown)` so `isVisitKnown` is something that the core \"requires\" / \"knows about\" and therefore should be integrated in core by a getter / setter.  It shouldn't actually set it but other plugins. There were also some other ones that core required to be set, it would be the same for them. Something like this isn't metadata it is something specific needed for core to work.","created_at":"2015-08-07T06:16:34Z","updated_at":"2015-08-07T06:16:34Z","html_url":"https://github.com/piwik/piwik/pull/8317#discussion_r36493435","pull_request_url":"https://api.github.com/repos/piwik/piwik/pulls/8317","_links":{"self":{"href":"https://api.github.com/repos/piwik/piwik/pulls/comments/36493435"},"html":{"href":"https://github.com/piwik/piwik/pull/8317#discussion_r36493435"},"pull_request":{"href":"https://api.github.com/repos/piwik/piwik/pulls/8317"}}},"pull_request":{"url":"https://api.github.com/repos/piwik/piwik/pulls/8317","id":39629022,"html_url":"https://github.com/piwik/piwik/pull/8317","diff_url":"https://github.com/piwik/piwik/pull/8317.diff","patch_url":"https://github.com/piwik/piwik/pull/8317.patch","issue_url":"https://api.github.com/repos/piwik/piwik/issues/8317","number":8317,"state":"open","locked":false,"title":"Refactor tracker code for clarity, modularity and so plugins can have more granular control over tracking","user":{"login":"diosmosis","id":125140,"avatar_url":"https://avatars.githubusercontent.com/u/125140?v=3","gravatar_id":"","url":"https://api.github.com/users/diosmosis","html_url":"https://github.com/diosmosis","followers_url":"https://api.github.com/users/diosmosis/followers","following_url":"https://api.github.com/users/diosmosis/following{/other_user}","gists_url":"https://api.github.com/users/diosmosis/gists{/gist_id}","starred_url":"https://api.github.com/users/diosmosis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diosmosis/subscriptions","organizations_url":"https://api.github.com/users/diosmosis/orgs","repos_url":"https://api.github.com/users/diosmosis/repos","events_url":"https://api.github.com/users/diosmosis/events{/privacy}","received_events_url":"https://api.github.com/users/diosmosis/received_events","type":"User","site_admin":false},"body":"This PR heavily refactors the tracking code to make it easy for plugins to tweak, change and extend tracking behavior. It moves a big chunk of the code currently in Visit::handle() to other plugins, like Goals, Actions, CustomVariables, etc.\r\n\r\n**Note: Though this PR implements enough changes for the plugin I'm working on, it doesn't completely close #8071, there's still more logic that can be moved out of core.**\r\n\r\n# Concepts\r\n\r\nThis PR introduces the concept of the RequestProcessor. RequestProcessors handle and tweak tracker behavior. To learn more, read the class docs for the RequestProcessor class.\r\n\r\n# Changes\r\n\r\n* Added the RequestProcessor base class and added a new collection to DI, `tracker.request.processors`.\r\n\r\n* Made Tracker\\Settings a stateless service and moved it to DI.\r\n\r\n* Gutted the Tracker\\Visitor class. All the real logic was moved to a new stateless service, VisitorRecognizer. Visitor still exists because it is used in Dimension hooks, but it is at best a facade now.\r\n\r\n* Created a new Heartbeat plugin to hold the ping tracker behavior.\r\n\r\n* Moved action related tracking code in Visit::handle() to the Actions plugin, moved custom variables related tracking code to CustomVariables, moved goals related code to Goals, moved Ecommerce related code to Ecommerce and moved some core Visit handling code to CoreHome.\r\n\r\n* Added a method to the Plugin class, `isTrackerPlugin()`. Plugins that don't implement dimensions or use tracker events can override this method to make sure they are loaded during tracking (if they need it).\r\n\r\n# Future TODO\r\n\r\nThis TODO list can be added to #8071 or to a new issue:\r\n\r\n* [x] Make GoalManager a stateless service and store in DI.\r\n* [ ] Move Action class & related code to Actions plugin. Move GoalManager to Goals plugin. Move other plugin related code to plugins from core.\r\n* [ ] Move current code to insert/update visit data in core to CoreHome. To do this correctly, would need a new service (eg, VisitRecorder), so VisitRequestProcessor does not get bloated (or more bloated).\r\n* [ ] Remove lots of tracking events, I think many (if not most) are no longer needed.\r\n* [ ] Create a new method in RequestProcessor specifically for manipulating request metadata. Right now, `afterRequestProcessed()` is used for both defining metadata that depends on other plugins' metadata and for manipulating other plugins' metadata. This means metadata that uses other plugins' metadata, can't be manipulated. Order of plugins will be come a problem eventually if many plugins get involved together...\r\n* [ ] Refactor the system again for clarity and ease of use. This makes it possible to split up the code and correctly scope classes, but the code is still verbose and the tracking logic is still not obvious. Before the system is made `@api` it should be made as easy to use as possible.\r\n\r\nRefs #8071","created_at":"2015-07-09T21:14:07Z","updated_at":"2015-08-07T06:16:34Z","closed_at":null,"merged_at":null,"merge_commit_sha":"010cfa096c82d29766825417c5843c4e8c9c141e","assignee":{"login":"diosmosis","id":125140,"avatar_url":"https://avatars.githubusercontent.com/u/125140?v=3","gravatar_id":"","url":"https://api.github.com/users/diosmosis","html_url":"https://github.com/diosmosis","followers_url":"https://api.github.com/users/diosmosis/followers","following_url":"https://api.github.com/users/diosmosis/following{/other_user}","gists_url":"https://api.github.com/users/diosmosis/gists{/gist_id}","starred_url":"https://api.github.com/users/diosmosis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diosmosis/subscriptions","organizations_url":"https://api.github.com/users/diosmosis/orgs","repos_url":"https://api.github.com/users/diosmosis/repos","events_url":"https://api.github.com/users/diosmosis/events{/privacy}","received_events_url":"https://api.github.com/users/diosmosis/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/piwik/piwik/milestones/84","html_url":"https://github.com/piwik/piwik/milestones/2.15.0","labels_url":"https://api.github.com/repos/piwik/piwik/milestones/84/labels","id":1202482,"number":84,"title":"2.15.0","description":"","creator":{"login":"mattab","id":466765,"avatar_url":"https://avatars.githubusercontent.com/u/466765?v=3","gravatar_id":"","url":"https://api.github.com/users/mattab","html_url":"https://github.com/mattab","followers_url":"https://api.github.com/users/mattab/followers","following_url":"https://api.github.com/users/mattab/following{/other_user}","gists_url":"https://api.github.com/users/mattab/gists{/gist_id}","starred_url":"https://api.github.com/users/mattab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mattab/subscriptions","organizations_url":"https://api.github.com/users/mattab/orgs","repos_url":"https://api.github.com/users/mattab/repos","events_url":"https://api.github.com/users/mattab/events{/privacy}","received_events_url":"https://api.github.com/users/mattab/received_events","type":"User","site_admin":false},"open_issues":58,"closed_issues":23,"state":"open","created_at":"2015-07-10T13:26:16Z","updated_at":"2015-08-06T15:10:08Z","due_on":"2015-08-13T22:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/piwik/piwik/pulls/8317/commits","review_comments_url":"https://api.github.com/repos/piwik/piwik/pulls/8317/comments","review_comment_url":"https://api.github.com/repos/piwik/piwik/pulls/comments{/number}","comments_url":"https://api.github.com/repos/piwik/piwik/issues/8317/comments","statuses_url":"https://api.github.com/repos/piwik/piwik/statuses/7baf3df7dcbf9ef7952612831b387ca72d75e165","head":{"label":"piwik:8071_tracker_req_handler","ref":"8071_tracker_req_handler","sha":"7baf3df7dcbf9ef7952612831b387ca72d75e165","user":{"login":"piwik","id":698038,"avatar_url":"https://avatars.githubusercontent.com/u/698038?v=3","gravatar_id":"","url":"https://api.github.com/users/piwik","html_url":"https://github.com/piwik","followers_url":"https://api.github.com/users/piwik/followers","following_url":"https://api.github.com/users/piwik/following{/other_user}","gists_url":"https://api.github.com/users/piwik/gists{/gist_id}","starred_url":"https://api.github.com/users/piwik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/piwik/subscriptions","organizations_url":"https://api.github.com/users/piwik/orgs","repos_url":"https://api.github.com/users/piwik/repos","events_url":"https://api.github.com/users/piwik/events{/privacy}","received_events_url":"https://api.github.com/users/piwik/received_events","type":"Organization","site_admin":false},"repo":{"id":1548202,"name":"piwik","full_name":"piwik/piwik","owner":{"login":"piwik","id":698038,"avatar_url":"https://avatars.githubusercontent.com/u/698038?v=3","gravatar_id":"","url":"https://api.github.com/users/piwik","html_url":"https://github.com/piwik","followers_url":"https://api.github.com/users/piwik/followers","following_url":"https://api.github.com/users/piwik/following{/other_user}","gists_url":"https://api.github.com/users/piwik/gists{/gist_id}","starred_url":"https://api.github.com/users/piwik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/piwik/subscriptions","organizations_url":"https://api.github.com/users/piwik/orgs","repos_url":"https://api.github.com/users/piwik/repos","events_url":"https://api.github.com/users/piwik/events{/privacy}","received_events_url":"https://api.github.com/users/piwik/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/piwik/piwik","description":"Liberating Web Analytics. Star us on Github? +1. Piwik is the leading open alternative to Google Analytics that gives you full control over your data. Piwik lets you easily collect data from websites, apps & IoT and visualise this data and extract insights. Privacy is built-in. We love Pull Requests! ","fork":false,"url":"https://api.github.com/repos/piwik/piwik","forks_url":"https://api.github.com/repos/piwik/piwik/forks","keys_url":"https://api.github.com/repos/piwik/piwik/keys{/key_id}","collaborators_url":"https://api.github.com/repos/piwik/piwik/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/piwik/piwik/teams","hooks_url":"https://api.github.com/repos/piwik/piwik/hooks","issue_events_url":"https://api.github.com/repos/piwik/piwik/issues/events{/number}","events_url":"https://api.github.com/repos/piwik/piwik/events","assignees_url":"https://api.github.com/repos/piwik/piwik/assignees{/user}","branches_url":"https://api.github.com/repos/piwik/piwik/branches{/branch}","tags_url":"https://api.github.com/repos/piwik/piwik/tags","blobs_url":"https://api.github.com/repos/piwik/piwik/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/piwik/piwik/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/piwik/piwik/git/refs{/sha}","trees_url":"https://api.github.com/repos/piwik/piwik/git/trees{/sha}","statuses_url":"https://api.github.com/repos/piwik/piwik/statuses/{sha}","languages_url":"https://api.github.com/repos/piwik/piwik/languages","stargazers_url":"https://api.github.com/repos/piwik/piwik/stargazers","contributors_url":"https://api.github.com/repos/piwik/piwik/contributors","subscribers_url":"https://api.github.com/repos/piwik/piwik/subscribers","subscription_url":"https://api.github.com/repos/piwik/piwik/subscription","commits_url":"https://api.github.com/repos/piwik/piwik/commits{/sha}","git_commits_url":"https://api.github.com/repos/piwik/piwik/git/commits{/sha}","comments_url":"https://api.github.com/repos/piwik/piwik/comments{/number}","issue_comment_url":"https://api.github.com/repos/piwik/piwik/issues/comments{/number}","contents_url":"https://api.github.com/repos/piwik/piwik/contents/{+path}","compare_url":"https://api.github.com/repos/piwik/piwik/compare/{base}...{head}","merges_url":"https://api.github.com/repos/piwik/piwik/merges","archive_url":"https://api.github.com/repos/piwik/piwik/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/piwik/piwik/downloads","issues_url":"https://api.github.com/repos/piwik/piwik/issues{/number}","pulls_url":"https://api.github.com/repos/piwik/piwik/pulls{/number}","milestones_url":"https://api.github.com/repos/piwik/piwik/milestones{/number}","notifications_url":"https://api.github.com/repos/piwik/piwik/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/piwik/piwik/labels{/name}","releases_url":"https://api.github.com/repos/piwik/piwik/releases{/id}","created_at":"2011-03-30T21:18:17Z","updated_at":"2015-08-06T19:09:54Z","pushed_at":"2015-08-06T15:06:57Z","git_url":"git://github.com/piwik/piwik.git","ssh_url":"git@github.com:piwik/piwik.git","clone_url":"https://github.com/piwik/piwik.git","svn_url":"https://github.com/piwik/piwik","homepage":"http://piwik.org/","size":339666,"stargazers_count":4236,"watchers_count":4236,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":789,"mirror_url":null,"open_issues_count":1113,"forks":789,"open_issues":1113,"watchers":4236,"default_branch":"master"}},"base":{"label":"piwik:master","ref":"master","sha":"6c9b35d6494026babf01eb0e30d35a29ad3bab11","user":{"login":"piwik","id":698038,"avatar_url":"https://avatars.githubusercontent.com/u/698038?v=3","gravatar_id":"","url":"https://api.github.com/users/piwik","html_url":"https://github.com/piwik","followers_url":"https://api.github.com/users/piwik/followers","following_url":"https://api.github.com/users/piwik/following{/other_user}","gists_url":"https://api.github.com/users/piwik/gists{/gist_id}","starred_url":"https://api.github.com/users/piwik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/piwik/subscriptions","organizations_url":"https://api.github.com/users/piwik/orgs","repos_url":"https://api.github.com/users/piwik/repos","events_url":"https://api.github.com/users/piwik/events{/privacy}","received_events_url":"https://api.github.com/users/piwik/received_events","type":"Organization","site_admin":false},"repo":{"id":1548202,"name":"piwik","full_name":"piwik/piwik","owner":{"login":"piwik","id":698038,"avatar_url":"https://avatars.githubusercontent.com/u/698038?v=3","gravatar_id":"","url":"https://api.github.com/users/piwik","html_url":"https://github.com/piwik","followers_url":"https://api.github.com/users/piwik/followers","following_url":"https://api.github.com/users/piwik/following{/other_user}","gists_url":"https://api.github.com/users/piwik/gists{/gist_id}","starred_url":"https://api.github.com/users/piwik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/piwik/subscriptions","organizations_url":"https://api.github.com/users/piwik/orgs","repos_url":"https://api.github.com/users/piwik/repos","events_url":"https://api.github.com/users/piwik/events{/privacy}","received_events_url":"https://api.github.com/users/piwik/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/piwik/piwik","description":"Liberating Web Analytics. Star us on Github? +1. Piwik is the leading open alternative to Google Analytics that gives you full control over your data. Piwik lets you easily collect data from websites, apps & IoT and visualise this data and extract insights. Privacy is built-in. We love Pull Requests! ","fork":false,"url":"https://api.github.com/repos/piwik/piwik","forks_url":"https://api.github.com/repos/piwik/piwik/forks","keys_url":"https://api.github.com/repos/piwik/piwik/keys{/key_id}","collaborators_url":"https://api.github.com/repos/piwik/piwik/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/piwik/piwik/teams","hooks_url":"https://api.github.com/repos/piwik/piwik/hooks","issue_events_url":"https://api.github.com/repos/piwik/piwik/issues/events{/number}","events_url":"https://api.github.com/repos/piwik/piwik/events","assignees_url":"https://api.github.com/repos/piwik/piwik/assignees{/user}","branches_url":"https://api.github.com/repos/piwik/piwik/branches{/branch}","tags_url":"https://api.github.com/repos/piwik/piwik/tags","blobs_url":"https://api.github.com/repos/piwik/piwik/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/piwik/piwik/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/piwik/piwik/git/refs{/sha}","trees_url":"https://api.github.com/repos/piwik/piwik/git/trees{/sha}","statuses_url":"https://api.github.com/repos/piwik/piwik/statuses/{sha}","languages_url":"https://api.github.com/repos/piwik/piwik/languages","stargazers_url":"https://api.github.com/repos/piwik/piwik/stargazers","contributors_url":"https://api.github.com/repos/piwik/piwik/contributors","subscribers_url":"https://api.github.com/repos/piwik/piwik/subscribers","subscription_url":"https://api.github.com/repos/piwik/piwik/subscription","commits_url":"https://api.github.com/repos/piwik/piwik/commits{/sha}","git_commits_url":"https://api.github.com/repos/piwik/piwik/git/commits{/sha}","comments_url":"https://api.github.com/repos/piwik/piwik/comments{/number}","issue_comment_url":"https://api.github.com/repos/piwik/piwik/issues/comments{/number}","contents_url":"https://api.github.com/repos/piwik/piwik/contents/{+path}","compare_url":"https://api.github.com/repos/piwik/piwik/compare/{base}...{head}","merges_url":"https://api.github.com/repos/piwik/piwik/merges","archive_url":"https://api.github.com/repos/piwik/piwik/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/piwik/piwik/downloads","issues_url":"https://api.github.com/repos/piwik/piwik/issues{/number}","pulls_url":"https://api.github.com/repos/piwik/piwik/pulls{/number}","milestones_url":"https://api.github.com/repos/piwik/piwik/milestones{/number}","notifications_url":"https://api.github.com/repos/piwik/piwik/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/piwik/piwik/labels{/name}","releases_url":"https://api.github.com/repos/piwik/piwik/releases{/id}","created_at":"2011-03-30T21:18:17Z","updated_at":"2015-08-06T19:09:54Z","pushed_at":"2015-08-06T15:06:57Z","git_url":"git://github.com/piwik/piwik.git","ssh_url":"git@github.com:piwik/piwik.git","clone_url":"https://github.com/piwik/piwik.git","svn_url":"https://github.com/piwik/piwik","homepage":"http://piwik.org/","size":339666,"stargazers_count":4236,"watchers_count":4236,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":789,"mirror_url":null,"open_issues_count":1113,"forks":789,"open_issues":1113,"watchers":4236,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/piwik/piwik/pulls/8317"},"html":{"href":"https://github.com/piwik/piwik/pull/8317"},"issue":{"href":"https://api.github.com/repos/piwik/piwik/issues/8317"},"comments":{"href":"https://api.github.com/repos/piwik/piwik/issues/8317/comments"},"review_comments":{"href":"https://api.github.com/repos/piwik/piwik/pulls/8317/comments"},"review_comment":{"href":"https://api.github.com/repos/piwik/piwik/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/piwik/piwik/pulls/8317/commits"},"statuses":{"href":"https://api.github.com/repos/piwik/piwik/statuses/7baf3df7dcbf9ef7952612831b387ca72d75e165"}}}}