PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 1.10
Independent Analytics – WordPress Analytics Plugin v1.10
2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / inc / independent_analytics.php
independent-analytics / inc Last commit date
ajax 3 years ago databases 3 years ago migrations 3 years ago models 3 years ago queries 3 years ago utils 3 years ago chart.php 3 years ago chart_geo.php 3 years ago dashboard_widget.php 3 years ago db.php 3 years ago filters.php 3 years ago freemius.php 3 years ago independent_analytics.php 3 years ago known_referrers.php 3 years ago quick_stats.php 3 years ago rest_api.php 3 years ago settings.php 3 years ago table.php 3 years ago table_geo.php 3 years ago table_referrers.php 3 years ago table_views.php 3 years ago track_resource_changes.php 3 years ago view_counter.php 3 years ago
independent_analytics.php
345 lines
1 <?php
2
3 namespace IAWP;
4
5 class Independent_Analytics
6 {
7 use Singleton;
8
9 // This is where we attach functions to WP hooks
10 private function __construct()
11 {
12 new REST_API();
13 new Dashboard_Widget();
14 new View_Counter();
15 new Delete_Data_AJAX();
16 new Filters_AJAX();
17 new Export_Geo_AJAX();
18 new Export_Referrers_AJAX();
19 new Export_Views_AJAX();
20 new Migration_Status_AJAX();
21 new Track_Resource_Changes();
22
23 $this->settings = new Settings();
24
25 add_action('admin_menu', [$this, 'add_settings_page']);
26 add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts']);
27 add_filter('plugin_action_links_independent-analytics/iawp.php', [$this, 'plugin_action_links']);
28 add_filter('admin_footer_text', [$this, 'ip_db_attribution'], 1, 11);
29 IAWP_FS()->add_filter('connect_message_on_update', [$this, 'filter_connect_message_on_update'], 10, 6);
30 IAWP_FS()->add_filter('connect_message', [$this, 'filter_connect_message_on_update'], 10, 6);
31 }
32
33 // Text domain is used for i18n
34 public function load_textdomain()
35 {
36 load_plugin_textdomain('iawp', false, path_to('/languages'));
37 }
38
39 // Settings page where the analytics will appear
40 public function add_settings_page()
41 {
42 add_menu_page(
43 'Independent Analytics',
44 esc_html__('Analytics', 'iawp'),
45 'manage_options',
46 'independent-analytics',
47 [$this, 'settings_page_markup'],
48 'dashicons-analytics',
49 3
50 );
51 }
52
53 private function get_current_tab()
54 {
55 $valid_tabs = ['views', 'referrers', 'geo', 'settings', 'learn'];
56 $default_tab = $valid_tabs[0];
57 $tab = array_key_exists('tab', $_GET) ? sanitize_text_field($_GET['tab']) : false;
58 $is_valid = array_search($tab, $valid_tabs) != false;
59
60 if (!$tab || !$is_valid) {
61 $tab = $default_tab;
62 }
63
64 return $tab;
65 }
66
67 public function settings_page_markup()
68 {
69 $classes = get_option('iawp_dark_mode') ? 'iawp-parent dark-mode' : 'iawp-parent';
70
71 // check user capabilities
72 if (!$this->min_permission_level('admin')) {
73 return;
74 }
75
76 // Show migration message if needed
77 if (Migration::is_migrating()) {
78 ?>
79 <div id="iawp-parent" class="<?php echo esc_attr($classes); ?>">
80 <?php echo IAWP()->templates()->render('layout/header', ['show_review' => false]) ?>
81 <?php echo IAWP()->templates()->render('migration_running') ?>
82 </div>
83 <?php
84 return;
85 }
86
87 $tab = $this->get_current_tab(); ?>
88 <div id="iawp-parent" class="<?php echo esc_attr($classes); ?>">
89 <?php echo IAWP()->templates()->render('layout/header') ?>
90 <nav class="menu">
91 <a href="?page=independent-analytics"
92 class="menu-item link-dark <?php if ($tab === 'views'): ?>active<?php endif; ?>">
93 <?php esc_html_e('Views', 'iawp'); ?>
94 </a>
95 <a href="?page=independent-analytics&tab=referrers"
96 class="menu-item link-dark <?php if ($tab === 'referrers'): ?>active<?php endif; ?>">
97 <?php esc_html_e('Referrers', 'iawp'); ?>
98 </a>
99 <a href="?page=independent-analytics&tab=geo"
100 class="menu-item link-dark <?php if ($tab === 'geo'): ?>active<?php endif; ?>">
101 <?php esc_html_e('Geographic', 'iawp'); ?>
102 </a>
103 <a href="?page=independent-analytics&tab=settings"
104 class="menu-item link-dark <?php if ($tab === 'settings'): ?>active<?php endif; ?>">
105 <?php esc_html_e('Settings', 'iawp'); ?>
106 </a>
107 <a href="?page=independent-analytics&tab=learn"
108 class="menu-item link-dark <?php if ($tab === 'learn'): ?>active<?php endif; ?>">
109 <?php esc_html_e('Learn', 'iawp'); ?>
110 </a>
111 </nav>
112 <div class="tab-content"><?php
113 if ($tab == 'views') {
114 $table = new Table_Views();
115 $views = new Views(Views::RESOURCES);
116 $stats = new Quick_Stats($views);
117 $chart = new Chart($views);
118 $this->interface($table, $stats, $chart);
119 } elseif ($tab == 'referrers') {
120 $table = new Table_Referrers();
121 $views = new Views(Views::RESOURCES);
122 $stats = new Quick_Stats($views);
123 $chart = new Chart($views);
124 $this->interface($table, $stats, $chart);
125 } elseif ($tab == 'geo') {
126 $table = new Table_Geo();
127 $views = new Views(Views::GEO);
128 $stats = new Quick_Stats($views);
129 $geos = new Geos(null, null, false, null);
130 $chart = new Chart_Geo($geos);
131 $this->interface($table, $stats, $chart);
132 } elseif ($tab == 'settings') {
133 echo '<div id="iawp-dashboard" class="iawp-dashboard">';
134 $this->settings->render_settings();
135 echo '</div>';
136 } elseif ($tab == 'learn') {
137 echo '<div id="iawp-dashboard" class="iawp-dashboard">';
138 echo IAWP()->templates()->render('learn/index');
139 echo '</div>';
140 } ?>
141 </div>
142 <div id="loading-icon" class="loading-icon"><img
143 src="<?php echo esc_url(url_to('img/loading.svg')) ?>"/>
144 </div>
145 <button id="scroll-to-top" class="scroll-to-top"><span
146 class="dashicons dashicons-arrow-up-alt"></span>
147 </button>
148 </div>
149 <?php
150 }
151
152 public function interface($table, $stats, $chart)
153 {
154 ?>
155 <div id="iawp-dashboard"
156 class="iawp-dashboard"
157 data-controller="report"
158 data-report-relative-range-id-value="LAST_THIRTY"
159 data-report-exact-start-value=""
160 data-report-exact-end-value=""
161 data-report-columns-value="<?php esc_attr_e(Security::json_encode($table->default_columns())) ?>"
162 >
163 <?php echo Security::html($table->output_toolbar($table->columns())); ?>
164 <?php echo $stats->get_html(); ?>
165 <?php echo $chart->get_html(); ?>
166 <?php echo Security::html($table->get_table_markup()); ?>
167 </div>
168 <?php
169 }
170
171 public function enqueue_scripts($hook)
172 {
173 if ($hook == 'toplevel_page_independent-analytics') {
174 $tab = $this->get_current_tab();
175
176 wp_register_style('iawp-style', url_to('dist/styles/style.css'), [], IAWP_VERSION);
177 wp_enqueue_style('iawp-style');
178
179 wp_register_script('iawp-js', url_to('dist/js/index.js'), [], IAWP_VERSION);
180 wp_enqueue_script('iawp-js');
181 wp_add_inline_script('iawp-js', 'const IAWP_DELETE_DATA_NONCE = ' . json_encode(wp_create_nonce('iawp_delete_data')), 'before');
182
183 if ($tab === 'views' || $tab === 'referrers' || $tab === 'geo') {
184 wp_register_script('iawp-data-table', url_to('dist/js/data-table.js'), [], IAWP_VERSION);
185 wp_enqueue_script('iawp-data-table');
186 wp_add_inline_script('iawp-data-table', 'const IAWP_AJAX = ' . json_encode([
187 'filter_nonce' => wp_create_nonce('iawp_filter'),
188 ]), 'before');
189 } elseif ($tab == 'settings') {
190 wp_register_script('iawp-settings', url_to('dist/js/settings.js'), [], IAWP_VERSION);
191 wp_enqueue_script('iawp-settings');
192 wp_add_inline_script('iawp-settings', 'const IAWP_AJAX = ' . json_encode([
193 'export_views_nonce' => wp_create_nonce('iawp_export_views'),
194 'export_referrers_nonce' => wp_create_nonce('iawp_export_referrers'),
195 'export_geo_nonce' => wp_create_nonce('iawp_export_geo'),
196 ]), 'before');
197 } elseif ($tab == 'learn') {
198 wp_register_script('iawp-learn', url_to('dist/js/learn.js'), [], IAWP_VERSION);
199 wp_enqueue_script('iawp-learn');
200 }
201 } elseif ($hook == 'index.php') {
202 wp_register_script('iawp-dashboard-widget', url_to('dist/js/dashboard_widget.js'), [], IAWP_VERSION);
203 wp_enqueue_script('iawp-dashboard-widget');
204 wp_register_style('iawp-dashboard-widget-css', url_to('dist/styles/dashboard_widget.css'), [], IAWP_VERSION);
205 wp_enqueue_style('iawp-dashboard-widget-css');
206 }
207 }
208
209 public function default_date_range()
210 {
211 $user_timezone = new \DateTimeZone(Timezone::local_offset());
212 $end = (new \DateTime(null, $user_timezone))->setTime(0, 0, 0);
213 $start = clone $end;
214 $start->modify('-29 days');
215
216 return [$start, $end];
217 }
218
219 // Returns bool based on minimum capability requirements
220 public function min_permission_level($role = 'subscriber')
221 {
222 if ($role == 'contributor') {
223 return current_user_can('edit_posts');
224 } elseif ($role == 'author') {
225 return current_user_can('publish_posts');
226 } elseif ($role == 'editor') {
227 return current_user_can('edit_others_posts');
228 } elseif ($role == 'admin') {
229 return current_user_can('manage_options');
230 } else {
231 return false;
232 }
233 }
234
235 /* WP uses $default when get_option() is empty, but it also saves empty fields
236 ** as empty strings, meaning the return value can be "" instead of the default. This is
237 ** a defensive function that guarantees we get the proper default when the setting is empty. */
238 public function get_option($name, $default)
239 {
240 $option = get_option($name, $default);
241
242 return $option === '' ? $default : $option;
243 }
244
245 public function templates()
246 {
247 return new League\Plates\Engine(path_to('templates'));
248 }
249
250 public function get_users_can_write()
251 {
252 $roles = [];
253 foreach (wp_roles()->roles as $role_name => $role_obj) {
254 if (!empty($role_obj['capabilities']['edit_posts'])) {
255 $roles[] = $role_name;
256 }
257 }
258
259 $users = get_users(['role__in' => $roles]);
260
261 return $users;
262 }
263
264 public function get_custom_types(bool $tax = false)
265 {
266 $args = [
267 'public' => true,
268 '_builtin' => false,
269 ];
270 if ($tax) {
271 return get_taxonomies($args);
272 } else {
273 return get_post_types($args);
274 }
275 }
276
277 public function filter_connect_message_on_update(
278 $message,
279 $user_first_name,
280 $product_title,
281 $user_login,
282 $site_link,
283 $freemius_link
284 ) {
285 // Add the heading HTML.
286 $plugin_name = 'Independent Analytics';
287 $title = '<h3>' . sprintf(esc_html__('We hope you love %1$s', 'iawp'), $plugin_name) . '</h3>';
288 $html = '';
289
290 // Add the introduction HTML.
291 $html .= '<p>';
292 $html .= sprintf(esc_html__('Hi, %1$s! This is an invitation to help the %2$s community. ', 'iawp'), $user_first_name, $plugin_name);
293 $html .= '<strong>';
294 $html .= sprintf(esc_html__('If you opt-in, some data about your usage of %2$s will be shared with us', 'iawp'), $user_first_name, $plugin_name);
295 $html .= '</strong>';
296 $html .= sprintf(esc_html__(' so we can improve %2$s. We will also share some helpful info on using the plugin so you can get the most out of your sites analytics.', 'iawp'), $user_first_name, $plugin_name);
297 $html .= '</p>';
298
299 $html .= '<p>';
300 $html .= sprintf(esc_html__('And if you skip this, that\'s okay! %1$s will still work just fine.', 'iawp'), $plugin_name);
301 $html .= '</p>';
302
303 // Add the "Powered by" HTML.
304 $html .= '<div class="iawp-powered-by-freemius">' . esc_html__('Powered by Freemius', 'iawp') . '</div>';
305
306 return $title . $html;
307 }
308
309 public function plugin_action_links($links)
310 {
311 // Build the URL
312 $url = add_query_arg('page', 'independent-analytics', admin_url('admin.php'));
313
314 // Create the link
315 $settings_link = '<a class="calendar-link" href="' . esc_url($url) . '">' . esc_html__('Analytics Dashboard', 'iawp') . '</a>';
316
317 // Add the link to the start of the array
318 array_unshift($links, $settings_link);
319
320 return $links;
321 }
322
323 public function set_time_limit($limit = 0)
324 {
325 if (
326 !function_exists('set_time_limit')
327 && false !== strpos(ini_get('disable_functions'), 'set_time_limit')
328 && ini_get('safe_mode')
329 ) {
330 return false;
331 }
332
333 return @set_time_limit($limit);
334 }
335
336 public function ip_db_attribution($text)
337 {
338 if ($this->get_current_tab() === 'geo') {
339 $text = $text . ' ' . esc_html_x('Geolocation data powered by', 'Following text is a noun: DB-IP', 'iawp') . ' ' . '<a href="https://db-ip.com" class="geo-message" target="_blank">DB-IP</a>.';
340 }
341
342 return $text;
343 }
344 }
345