PluginProbe
Simple Analytics / 1.46
Simple Analytics v1.46
1.109 1.108 1.107 1.106 1.73 1.74 1.75 1.76 1.77 1.78 1.79 1.8 1.80 1.81 1.82 1.83 1.84 1.85 1.86 1.87 1.88 1.89 1.9 1.90 1.91 All 98 releases
← All changes | src/Plugin.php +153 -49 1.1081.46 View file →
@@ -1,8 +1,9 @@
1 1 <?php
2 2
3 3 namespace SimpleAnalytics;
4 4
5 +use SimpleAnalytics\Settings\{Page, Tab};
5 6 use SimpleAnalytics\Actions\AddInactiveComment;
6 7 use SimpleAnalytics\Actions\AddNoScriptTag;
7 8 use SimpleAnalytics\Actions\AddPluginSettingsLink;
8 9 use SimpleAnalytics\Scripts\AnalyticsScript;
@@ -7,82 +8,185 @@
7 8 use SimpleAnalytics\Actions\AddPluginSettingsLink;
8 9 use SimpleAnalytics\Scripts\AnalyticsScript;
9 10 use SimpleAnalytics\Scripts\AutomatedEventsScript;
10 11 use SimpleAnalytics\Scripts\InactiveScript;
11 -use SimpleAnalytics\Settings\AdminPage;
12 12
13 13 final class Plugin
14 14 {
15 - protected $hooks;
16 - protected $settings;
17 - protected $trackingRules;
18 - protected $scripts;
19 - protected $adminPage;
15 + use PluginLifecycle;
20 16
21 - public function __construct(
22 - WordPressHooks $hooks,
23 - WordPressSettings $settings,
24 - TrackingRules $trackingRules,
25 - ScriptRegistry $scripts,
26 - AdminPage $adminPage
27 - ) {
28 - $this->hooks = $hooks;
29 - $this->settings = $settings;
30 - $this->trackingRules = $trackingRules;
31 - $this->scripts = $scripts;
32 - $this->adminPage = $adminPage;
17 + protected function onBoot(): void
18 + {
19 + if (is_admin()) {
20 + $this->defineAdminPage();
21 + AddPluginSettingsLink::register();
22 + }
33 23 }
34 24
35 - public function boot(): void
25 + public function onActivation(): void
36 26 {
37 - $this->hooks->addAction('init', \Closure::fromCallable([$this, 'onInit']));
38 - $this->hooks->onActivation(\Closure::fromCallable([$this, 'onActivation']));
39 - $this->hooks->onDeactivation(\Closure::fromCallable([$this, 'onUninstall']));
27 + $this->addOptions();
28 + }
40 29
41 - if ($this->hooks->isAdmin()) {
42 - $this->adminPage->register();
43 - AddPluginSettingsLink::register();
44 - }
30 + public function onUninstall(): void
31 + {
32 + $this->deleteOptions();
45 33 }
46 34
47 35 public function onInit(): void
48 36 {
49 - $hasExcludedIp = $this->trackingRules->hasExcludedIp();
50 - $hasExcludedUserRole = $this->trackingRules->hasExcludedUserRole();
51 - $tracking = ! $hasExcludedIp && ! $hasExcludedUserRole;
52 -
53 - if ($tracking) {
54 - $this->scripts->push(new AnalyticsScript);
55 - } else {
56 - $this->scripts->push(new InactiveScript);
57 - $reason = $hasExcludedIp ? 'Exclude IP Address' : 'Exclude User Role';
58 - AddInactiveComment::register($reason);
37 + $shouldCollect = (new TrackingPolicy)->shouldCollectAnalytics();
38 + $this->addScripts($shouldCollect);
39 + if (! $shouldCollect) {
40 + AddInactiveComment::register();
59 41 }
60 -
61 - if ($tracking && $this->settings->get(SettingName::NOSCRIPT)) {
42 + if ($shouldCollect && Setting::boolean(SettingName::NOSCRIPT)) {
62 43 AddNoScriptTag::register();
63 44 }
45 + }
64 46
65 - if ($this->settings->boolean(SettingName::AUTOMATED_EVENTS)) {
66 - $this->scripts->push(new AutomatedEventsScript);
47 + /**
48 + * Register plugin options and autoload them.
49 + *
50 + * @note Eliminates any unnecessary database lookups by preloading on each request.
51 + * @note Thanks to option autoloading, we don't need to use one serialized option, but several.
52 + * This allows the usage of native hooks and filters and reduces the chance of data corruption.
53 + */
54 + protected function addOptions(): void
55 + {
56 + // Add options with default values
57 + add_option(SettingName::ENABLED, '1', null, true);
58 +
59 + // Add all remaining options
60 + $optionNames = array_diff(SettingName::cases(), [SettingName::ENABLED]);
61 + foreach ($optionNames as $name) {
62 + add_option($name, null, null, true);
67 63 }
68 64
69 - $this->scripts->register();
65 + // Legacy. Update the option introduced in a previous release to use autoloading.
66 + update_option(SettingName::CUSTOM_DOMAIN, get_option(SettingName::CUSTOM_DOMAIN), true);
70 67 }
71 68
72 - public function onActivation(): void
69 + protected function deleteOptions(): void
73 70 {
74 - $this->settings->register(SettingName::ENABLED, true);
71 + foreach (SettingName::cases() as $name) {
72 + delete_option($name);
73 + }
74 + }
75 75
76 - foreach (array_diff(SettingName::cases(), [SettingName::ENABLED]) as $name) {
77 - $this->settings->register($name);
76 + protected function addScripts(bool $collect): void
77 + {
78 + $scripts = new ScriptManager;
79 +
80 + if ($collect) {
81 + $scripts->add(new AnalyticsScript);
82 + } elseif (is_user_logged_in()) {
83 + $scripts->add(new InactiveScript);
78 84 }
79 85
80 - // Legacy. Update the option introduced in a previous release to use autoloading.
81 - $this->settings->update(SettingName::CUSTOM_DOMAIN, $this->settings->get(SettingName::CUSTOM_DOMAIN), true);
86 + if (Setting::boolean(SettingName::AUTOMATED_EVENTS)) {
87 + $scripts->add(new AutomatedEventsScript);
88 + }
89 +
90 + $scripts->register();
82 91 }
83 92
84 - public function onUninstall(): void
93 + protected function defineAdminPage(): void
85 94 {
86 - foreach (SettingName::cases() as $key) $this->settings->delete($key);
95 + Page::title('Simple Analytics')
96 + ->slug('simpleanalytics')
97 + ->tab('General', function (Tab $tab) {
98 + $tab->input(SettingName::CUSTOM_DOMAIN, 'Custom Domain')
99 + ->placeholder('Enter your custom domain or leave it empty.')
100 + ->description('E.g. api.example.com. Leave empty to use the default domain (most users).')
101 + ->docs('https://docs.simpleanalytics.com/bypass-ad-blockers');
102 +
103 + $tab->checkbox(SettingName::ENABLED, 'Enabled')
104 + ->default(true)
105 + ->description('Enable or disable Simple Analytics on your website.');
106 + })
107 + ->tab('Ignore Rules', function (Tab $tab) {
108 + $tab->icon(get_icon('eye-slash'));
109 +
110 + $tab->input(SettingName::IGNORE_PAGES, 'Ignore Pages')
111 + ->description('Comma separated list of pages to ignore. E.g. /contact, /about')
112 + ->placeholder('Example: /page1, /page2, /category/*')
113 + ->docs('https://docs.simpleanalytics.com/ignore-pages');
114 +
115 + $tab->callout('IP and role exclusion only works when there is no page caching.');
116 +
117 + $tab->multiCheckbox(SettingName::EXCLUDED_ROLES, 'Exclude User Roles')
118 + ->options(function () {
119 + return wp_roles()->get_names();
120 + });
121 +
122 + $tab->ipList(SettingName::EXCLUDED_IP_ADDRESSES, 'Exclude IP Addresses')
123 + ->placeholder("127.0.0.1\n192.168.0.1")
124 + ->description('IP addresses to exclude from tracking.');
125 + })
126 + ->tab('Advanced', function (Tab $tab) {
127 + $tab->icon(get_icon('cog'));
128 +
129 + $tab->checkbox(SettingName::COLLECT_DNT, 'Collect Do Not Track')
130 + ->description('If you want to collect visitors with Do Not Track enabled, turn this on.')
131 + ->docs('https://docs.simpleanalytics.com/dnt');
132 +
133 + $tab->checkbox(SettingName::HASH_MODE, 'Hash mode')
134 + ->description('If your website uses hash (#) navigation, turn this on. On most WordPress websites this is not relevant.')
135 + ->docs('https://docs.simpleanalytics.com/hash-mode');
136 +
137 + $tab->checkbox(SettingName::MANUAL_COLLECT, 'Manually collect page views')
138 + ->description('In case you don’t want to auto collect page views, but via `sa_pageview` function in JavaScript.')
139 + ->docs('https://docs.simpleanalytics.com/trigger-custom-page-views#use-custom-collection-anyway');
140 +
141 + $tab->checkbox(SettingName::NOSCRIPT, 'Support no JavaScript mode')
142 + ->description('Collect analytics from visitors with disabled or no JavaScript.');
143 +
144 + $tab->input(SettingName::ONLOAD_CALLBACK, 'Onload Callback')
145 + ->description('JavaScript function to call when the script is loaded.')
146 + ->placeholder('Example: sa_event("My event")')
147 + ->docs('https://docs.simpleanalytics.com/trigger-custom-page-views#use-custom-collection-anyway');
148 +
149 + $tab->input(SettingName::HOSTNAME, 'Overwrite domain name')
150 + ->description('Override the domain that is sent to Simple Analytics. Useful for multi-domain setups.')
151 + ->placeholder('Example: example.com')
152 + ->docs('https://docs.simpleanalytics.com/overwrite-domain-name');
153 +
154 + $tab->input(SettingName::SA_GLOBAL, 'Global variable name')
155 + ->description('Change the global variable name of Simple Analytics. Default is `sa_event`.')
156 + ->placeholder('Example: ba_event')
157 + ->docs('https://docs.simpleanalytics.com/events#the-variable-sa_event-is-already-used');
158 + })
159 + ->tab('Events', function (Tab $tab) {
160 + $tab->title('Automated events')
161 + ->icon(get_icon('events'))
162 + ->description("It will track outbound links, email addresses clicks,
163 + and amount of downloads for common files (pdf, csv, docx, xIsx).
164 + Events will appear on your events page on simpleanalytics.com");
165 +
166 + $tab->checkbox(SettingName::AUTOMATED_EVENTS, 'Collect automated events');
167 +
168 + $tab->input(SettingName::EVENT_COLLECT_DOWNLOADS, 'Auto collect downloads')
169 + ->placeholder('Example: outbound,emails,downloads')
170 + ->docs('https://docs.simpleanalytics.com/automated-events');
171 +
172 + $tab->input(SettingName::EVENT_EXTENSIONS, 'Download file extensions')
173 + ->description('Comma separated list of file extensions to track as downloads. E.g. pdf, zip')
174 + ->placeholder('Example: pdf, zip')
175 + ->docs('https://docs.simpleanalytics.com/automated-events');
176 +
177 + $tab->checkbox(SettingName::EVENT_USE_TITLE, 'Use titles of page')
178 + ->description('Use the title of the page as the event name. Default is the URL.')
179 + ->docs('https://docs.simpleanalytics.com/automated-events');
180 +
181 + $tab->checkbox(SettingName::EVENT_FULL_URLS, 'Use full URLs')
182 + ->description('Use full URLs instead of the path. Default is the path.')
183 + ->docs('https://docs.simpleanalytics.com/automated-events');
184 +
185 + $tab->input(SettingName::EVENT_SA_GLOBAL, 'Override global')
186 + ->description('Override the global variable name of Simple Analytics. Default is `sa_event`.')
187 + ->placeholder('Example: ba_event')
188 + ->docs('https://docs.simpleanalytics.com/events#the-variable-sa_event-is-already-used');
189 + })
190 + ->register();
87 191 }
88 192 }