Skip to content

Commit d2138ad

Browse files
committed
Refactor
1 parent 504d66f commit d2138ad

File tree

9 files changed

+251
-194
lines changed

9 files changed

+251
-194
lines changed

simple-analytics.php

Lines changed: 105 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,13 @@
2929
*/
3030
require __DIR__ . '/src/Support/SvgIcon.php';
3131
require __DIR__ . '/helpers.php';
32-
require __DIR__ . '/src/PluginLifecycle.php';
3332
require __DIR__ . '/src/Plugin.php';
33+
require __DIR__ . '/src/WordPressHooks.php';
34+
require __DIR__ . '/src/WordPressSettings.php';
3435
require __DIR__ . '/src/Setting.php';
3536
require __DIR__ . '/src/SettingName.php';
3637
require __DIR__ . '/src/TrackingRules.php';
37-
require __DIR__ . '/src/ScriptManager.php';
38+
require __DIR__ . '/src/ScriptRegistry.php';
3839
require __DIR__ . '/src/Scripts/Contracts/Script.php';
3940
require __DIR__ . '/src/Scripts/Contracts/HideScriptId.php';
4041
require __DIR__ . '/src/Scripts/Contracts/HasAttributes.php';
@@ -52,7 +53,7 @@
5253
require __DIR__ . '/src/Settings/Concerns/HasPlaceholder.php';
5354
require __DIR__ . '/src/Settings/Concerns/ManagesBlocks.php';
5455
require __DIR__ . '/src/Settings/Concerns/WordPressPageIntegration.php';
55-
require __DIR__ . '/src/Settings/Page.php';
56+
require __DIR__ . '/src/Settings/AdminPage.php';
5657
require __DIR__ . '/src/Settings/Blocks/Fields/Field.php';
5758
require __DIR__ . '/src/Settings/Blocks/Fields/Input.php';
5859
require __DIR__ . '/src/Settings/Blocks/Fields/Checkboxes.php';
@@ -63,6 +64,105 @@
6364
require __DIR__ . '/src/UI/TabListComponent.php';
6465
require __DIR__ . '/src/UI/PageLayoutComponent.php';
6566

66-
use SimpleAnalytics\Plugin;
67+
use SimpleAnalytics\SettingName;
68+
use SimpleAnalytics\Settings\Tab;
69+
use function SimpleAnalytics\get_icon;
6770

68-
(new Plugin)->boot();
71+
$settings = new SimpleAnalytics\WordPressSettings();
72+
$hooks = new SimpleAnalytics\WordPressHooks();
73+
$rules = new SimpleAnalytics\TrackingRules($settings);
74+
$scripts = new SimpleAnalytics\ScriptRegistry(/*TODO TAKE $hooks WordPressHooks as arg/dependency*/);
75+
76+
$adminPage = SimpleAnalytics\Settings\AdminPage::title('Simple Analytics')
77+
->slug('simpleanalytics')
78+
->tab('General', function (Tab $tab) {
79+
$tab->input(SettingName::CUSTOM_DOMAIN, 'Custom Domain')
80+
->placeholder('Enter your custom domain or leave it empty.')
81+
->description('E.g. api.example.com. Leave empty to use the default domain (most users).')
82+
->docs('https://docs.simpleanalytics.com/bypass-ad-blockers');
83+
})
84+
->tab('Ignore Rules', function (Tab $tab) {
85+
$tab->icon(get_icon('eye-slash'));
86+
87+
$tab->input(SettingName::IGNORE_PAGES, 'Ignore Pages')
88+
->description('Comma separated list of pages to ignore. E.g. /contact, /about')
89+
->placeholder('Example: /page1, /page2, /category/*')
90+
->docs('https://docs.simpleanalytics.com/ignore-pages');
91+
92+
$tab->callout('IP and role exclusion only works when there is no page caching.');
93+
94+
$tab->multiCheckbox(SettingName::EXCLUDED_ROLES, 'Exclude User Roles')
95+
->options(function () {
96+
return wp_roles()->get_names();
97+
});
98+
99+
$tab->ipList(SettingName::EXCLUDED_IP_ADDRESSES, 'Exclude IP Addresses')
100+
->placeholder("127.0.0.1\n192.168.0.1")
101+
->description('IP addresses to exclude from tracking.');
102+
})
103+
->tab('Advanced', function (Tab $tab) {
104+
$tab->icon(get_icon('cog'));
105+
106+
$tab->checkbox(SettingName::COLLECT_DNT, 'Collect Do Not Track')
107+
->description('If you want to collect visitors with Do Not Track enabled, turn this on.')
108+
->docs('https://docs.simpleanalytics.com/dnt');
109+
110+
$tab->checkbox(SettingName::HASH_MODE, 'Hash mode')
111+
->description('If your website uses hash (#) navigation, turn this on. On most WordPress websites this is not relevant.')
112+
->docs('https://docs.simpleanalytics.com/hash-mode');
113+
114+
$tab->checkbox(SettingName::MANUAL_COLLECT, 'Manually collect page views')
115+
->description('In case you don’t want to auto collect page views, but via `sa_pageview` function in JavaScript.')
116+
->docs('https://docs.simpleanalytics.com/trigger-custom-page-views#use-custom-collection-anyway');
117+
118+
$tab->checkbox(SettingName::NOSCRIPT, 'Support no JavaScript mode')
119+
->description('Collect analytics from visitors with disabled or no JavaScript.');
120+
121+
$tab->input(SettingName::ONLOAD_CALLBACK, 'Onload Callback')
122+
->description('JavaScript function to call when the script is loaded.')
123+
->placeholder('Example: sa_event("My event")')
124+
->docs('https://docs.simpleanalytics.com/trigger-custom-page-views#use-custom-collection-anyway');
125+
126+
$tab->input(SettingName::HOSTNAME, 'Overwrite domain name')
127+
->description('Override the domain that is sent to Simple Analytics. Useful for multi-domain setups.')
128+
->placeholder('Example: example.com')
129+
->docs('https://docs.simpleanalytics.com/overwrite-domain-name');
130+
131+
$tab->input(SettingName::SA_GLOBAL, 'Global variable name')
132+
->description('Change the global variable name of Simple Analytics. Default is `sa_event`.')
133+
->placeholder('Example: ba_event')
134+
->docs('https://docs.simpleanalytics.com/events#the-variable-sa_event-is-already-used');
135+
})
136+
->tab('Events', function (Tab $tab) {
137+
$tab->title('Automated events')
138+
->icon(get_icon('events'))
139+
->description("It will track outbound links, email addresses clicks,
140+
and amount of downloads for common files (pdf, csv, docx, xIsx).
141+
Events will appear on your events page on simpleanalytics.com");
142+
143+
$tab->checkbox(SettingName::AUTOMATED_EVENTS, 'Collect automated events');
144+
145+
$tab->input(SettingName::EVENT_COLLECT_DOWNLOADS, 'Auto collect downloads')
146+
->placeholder('Example: outbound,emails,downloads')
147+
->docs('https://docs.simpleanalytics.com/automated-events');
148+
149+
$tab->input(SettingName::EVENT_EXTENSIONS, 'Download file extensions')
150+
->description('Comma separated list of file extensions to track as downloads. E.g. pdf, zip')
151+
->placeholder('Example: pdf, zip')
152+
->docs('https://docs.simpleanalytics.com/automated-events');
153+
154+
$tab->checkbox(SettingName::EVENT_USE_TITLE, 'Use titles of page')
155+
->description('Use the title of the page as the event name. Default is the URL.')
156+
->docs('https://docs.simpleanalytics.com/automated-events');
157+
158+
$tab->checkbox(SettingName::EVENT_FULL_URLS, 'Use full URLs')
159+
->description('Use full URLs instead of the path. Default is the path.')
160+
->docs('https://docs.simpleanalytics.com/automated-events');
161+
162+
$tab->input(SettingName::EVENT_SA_GLOBAL, 'Override global')
163+
->description('Override the global variable name of Simple Analytics. Default is `sa_event`.')
164+
->placeholder('Example: ba_event')
165+
->docs('https://docs.simpleanalytics.com/events#the-variable-sa_event-is-already-used');
166+
});
167+
168+
(new SimpleAnalytics\Plugin($hooks, $settings, $rules, $scripts, $adminPage))->boot();

src/Plugin.php

Lines changed: 46 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -2,191 +2,87 @@
22

33
namespace SimpleAnalytics;
44

5-
use SimpleAnalytics\Settings\{Page, Tab};
65
use SimpleAnalytics\Actions\AddInactiveComment;
76
use SimpleAnalytics\Actions\AddNoScriptTag;
87
use SimpleAnalytics\Actions\AddPluginSettingsLink;
98
use SimpleAnalytics\Scripts\AnalyticsScript;
109
use SimpleAnalytics\Scripts\AutomatedEventsScript;
1110
use SimpleAnalytics\Scripts\InactiveScript;
11+
use SimpleAnalytics\Settings\AdminPage;
1212

1313
final class Plugin
1414
{
15-
use PluginLifecycle;
16-
17-
protected function onBoot(): void
18-
{
19-
if (is_admin()) {
20-
$this->defineAdminPage();
21-
AddPluginSettingsLink::register();
22-
}
15+
protected $hooks;
16+
protected $settings;
17+
protected $trackingRules;
18+
protected $scripts;
19+
protected $adminPage;
20+
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;
2333
}
2434

25-
public function onActivation(): void
35+
public function boot(): void
2636
{
27-
$this->addOptions();
28-
}
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']));
2940

30-
public function onUninstall(): void
31-
{
32-
$this->deleteOptions();
41+
if ($this->hooks->isAdmin()) {
42+
$this->adminPage->register();
43+
AddPluginSettingsLink::register();
44+
}
3345
}
3446

3547
public function onInit(): void
3648
{
37-
$rules = new TrackingRules();
38-
$tracking = $rules->excludedIp();
39-
40-
$this->addScripts($tracking);
49+
$tracking = $this->trackingRules->hasExcludedIp();
4150

42-
if ($tracking && Setting::boolean(SettingName::NOSCRIPT)) {
51+
if ($tracking && $this->settings->get(SettingName::NOSCRIPT)) {
4352
AddNoScriptTag::register();
4453
}
4554

46-
if (! $rules->excludedUserRole()) {
55+
if (! $this->trackingRules->hasExcludedUserRole()) {
4756
AddInactiveComment::register();
4857
}
49-
}
5058

51-
/**
52-
* Register plugin options and autoload them.
53-
*
54-
* @note Eliminates any unnecessary database lookups by preloading on each request.
55-
* @note Thanks to option autoloading, we don't need to use one serialized option, but several.
56-
* This allows the usage of native hooks and filters and reduces the chance of data corruption.
57-
*/
58-
protected function addOptions(): void
59-
{
60-
// Add options with default values
61-
add_option(SettingName::ENABLED, '1', null, true);
62-
63-
// Add all remaining options
64-
$optionNames = array_diff(SettingName::cases(), [SettingName::ENABLED]);
65-
foreach ($optionNames as $name) {
66-
add_option($name, null, null, true);
59+
if ($tracking) {
60+
$this->scripts->push(new AnalyticsScript);
61+
} else {
62+
$this->scripts->push(new InactiveScript);
6763
}
6864

69-
// Legacy. Update the option introduced in a previous release to use autoloading.
70-
update_option(SettingName::CUSTOM_DOMAIN, get_option(SettingName::CUSTOM_DOMAIN), true);
71-
}
72-
73-
protected function deleteOptions(): void
74-
{
75-
foreach (SettingName::cases() as $name) {
76-
delete_option($name);
65+
if ($this->settings->boolean(SettingName::AUTOMATED_EVENTS)) {
66+
$this->scripts->push(new AutomatedEventsScript);
7767
}
68+
69+
$this->scripts->register();
7870
}
7971

80-
protected function addScripts(bool $collect): void
72+
public function onActivation(): void
8173
{
82-
$scripts = new ScriptManager;
83-
84-
if ($collect) {
85-
$scripts->add(new AnalyticsScript);
86-
} elseif (is_user_logged_in()) {
87-
$scripts->add(new InactiveScript);
88-
}
74+
$this->settings->register(SettingName::ENABLED, true);
8975

90-
if (Setting::boolean(SettingName::AUTOMATED_EVENTS)) {
91-
$scripts->add(new AutomatedEventsScript);
76+
foreach (array_diff(SettingName::cases(), [SettingName::ENABLED]) as $name) {
77+
$this->settings->register($name);
9278
}
9379

94-
$scripts->register();
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);
9582
}
9683

97-
protected function defineAdminPage(): void
84+
public function onUninstall(): void
9885
{
99-
Page::title('Simple Analytics')
100-
->slug('simpleanalytics')
101-
->tab('General', function (Tab $tab) {
102-
$tab->input(SettingName::CUSTOM_DOMAIN, 'Custom Domain')
103-
->placeholder('Enter your custom domain or leave it empty.')
104-
->description('E.g. api.example.com. Leave empty to use the default domain (most users).')
105-
->docs('https://docs.simpleanalytics.com/bypass-ad-blockers');
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();
86+
foreach (SettingName::cases() as $key) $this->settings->delete($key);
19187
}
19288
}

src/PluginLifecycle.php

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)