PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 1.5
Independent Analytics – WordPress Analytics Plugin v1.5
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 / iawp.php
independent-analytics Last commit date
dist 4 years ago freemius 4 years ago img 4 years ago inc 4 years ago vendor 4 years ago iawp.php 4 years ago readme.txt 4 years ago
iawp.php
429 lines
1 <?php
2 /**
3 * Plugin Name: Independent Analytics
4 * Plugin URI: https://independentwp.com/
5 * Description: User-friendly website analytics built for WordPress
6 * Version: 1.5
7 * Requires at least: 5.5
8 * Tested up to: 6.0
9 * Requires PHP: 7.3.29
10 * Author: Independent Analytics
11 * Author URI: https://independentwp.com/
12 * License: GPL v2 or later
13 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
14 * Text Domain: iawp
15 * Domain Path: /languages
16 */
17
18 namespace IAWP;
19
20 require_once dirname(__FILE__) . '/vendor/scoper-autoload.php';
21
22 if (!function_exists('ia_fs')) {
23 // Create a helper function for easy SDK access.
24 function ia_fs()
25 {
26 global $ia_fs;
27
28 if (!isset($ia_fs)) {
29 // Include Freemius SDK.
30 require_once dirname(__FILE__) . '/freemius/start.php';
31
32 $ia_fs = fs_dynamic_init([
33 'id' => '9944',
34 'slug' => 'independent-analytics',
35 'type' => 'plugin',
36 'public_key' => 'pk_c228acaa28759b55d58766b1076d4',
37 'is_premium' => false,
38 'has_addons' => false,
39 'has_paid_plans' => false,
40 'menu' => [
41 'slug' => 'independent-analytics',
42 ],
43 ]);
44 }
45
46 return $ia_fs;
47 }
48
49 // Init Freemius.
50 ia_fs();
51 // Signal that SDK was initiated.
52 do_action('ia_fs_loaded');
53 }
54
55 if (!class_exists('Independent_Analytics')) {
56 class Independent_Analytics
57 {
58 // This enforces singleton behavior
59 public static function instance()
60 {
61 static $instance = null;
62 if ($instance === null) {
63 $instance = new self();
64 }
65
66 return $instance;
67 }
68
69 // This is where we attach functions to WP hooks
70 private function __construct()
71 {
72 $this->__setup_constants();
73 $this->__includes();
74
75 $this->db = new DB(IAWP_VERSION);
76 $this->rest_api = new REST_API();
77 $this->chart = new Chart();
78 $this->settings = new Settings();
79 new Filters_Ajax();
80 new Settings_AJAX();
81 new Delete_Data_Ajax();
82 new Track_Resource_Changes();
83
84 add_action('admin_menu', [$this, 'add_settings_page']);
85 add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts']);
86 add_action('plugins_loaded', [$this, 'update_db'], 99);
87 add_filter('plugin_action_links_independent-analytics/iawp.php', [$this, 'plugin_action_links']);
88 ia_fs()->add_filter('connect_message_on_update', [$this, 'filter_connect_message_on_update'], 10, 6);
89 ia_fs()->add_filter('connect_message', [$this, 'filter_connect_message_on_update'], 10, 6);
90 }
91
92 private function __setup_constants()
93 {
94 // Plugin Folder Path
95 if (!defined('IAWP_DIR')) {
96 define('IAWP_DIR', plugin_dir_path(__FILE__));
97 }
98 // Plugin Folder URL
99 if (!defined('IAWP_URL')) {
100 define('IAWP_URL', plugin_dir_url(__FILE__));
101 }
102 // Plugin Root File
103 if (!defined('IAWP_FILE')) {
104 define('IAWP_FILE', __FILE__);
105 }
106 // Plugin version
107 if (!defined('IAWP_VERSION')) {
108 define('IAWP_VERSION', '1.5');
109 }
110 }
111
112 private function __includes()
113 {
114 require_once IAWP_DIR . 'inc/db.php';
115 require_once IAWP_DIR . 'inc/rest_api.php';
116 require_once IAWP_DIR . 'inc/table.php';
117 require_once IAWP_DIR . 'inc/table_referrers.php';
118 require_once IAWP_DIR . 'inc/table_views.php';
119 require_once IAWP_DIR . 'inc/chart.php';
120 require_once IAWP_DIR . 'inc/filters.php';
121 require_once IAWP_DIR . 'inc/filters_ajax.php';
122 require_once IAWP_DIR . 'inc/delete_data_ajax.php';
123 require_once IAWP_DIR . 'inc/track_resource_changes.php';
124 require_once IAWP_DIR . 'inc/settings.php';
125 require_once IAWP_DIR . 'inc/settings_ajax.php';
126 require_once IAWP_DIR . 'inc/utils/array_to_csv.php';
127 require_once IAWP_DIR . 'inc/utils/date_format.php';
128 require_once IAWP_DIR . 'inc/utils/request.php';
129 require_once IAWP_DIR . 'inc/utils/relative_dates.php';
130 require_once IAWP_DIR . 'inc/utils/security.php';
131 require_once IAWP_DIR . 'inc/utils/timezone.php';
132 require_once IAWP_DIR . 'inc/queries/range_query.php';
133 require_once IAWP_DIR . 'inc/queries/views.php';
134 require_once IAWP_DIR . 'inc/queries/referrers.php';
135 require_once IAWP_DIR . 'inc/queries/resources.php';
136 require_once IAWP_DIR . 'inc/models/referrer.php';
137 require_once IAWP_DIR . 'inc/models/page.php';
138 require_once IAWP_DIR . 'inc/models/page_author_archive.php';
139 require_once IAWP_DIR . 'inc/models/page_date_archive.php';
140 require_once IAWP_DIR . 'inc/models/page_home.php';
141 require_once IAWP_DIR . 'inc/models/page_not_found.php';
142 require_once IAWP_DIR . 'inc/models/page_post_type_archive.php';
143 require_once IAWP_DIR . 'inc/models/page_search.php';
144 require_once IAWP_DIR . 'inc/models/page_singular.php';
145 require_once IAWP_DIR . 'inc/models/page_term_archive.php';
146 }
147
148 // Check this to run data migrations on plugins_loaded
149 public function update_db()
150 {
151 $this->db->update_db();
152 }
153
154 // Text domain is used for i18n
155 public function load_textdomain()
156 {
157 load_plugin_textdomain('iawp', false, IAWP_DIR . '/languages');
158 }
159
160 // Settings page where the analytics will appear
161 public function add_settings_page()
162 {
163 add_menu_page(
164 'Independent Analytics',
165 esc_html__('Analytics', 'iawp'),
166 'manage_options',
167 'independent-analytics',
168 [$this, 'settings_page_markup'],
169 'dashicons-analytics',
170 3
171 );
172 }
173
174 private function get_current_tab()
175 {
176 $valid_tabs = ['views', 'referrers', 'settings'];
177 $default_tab = $valid_tabs[0];
178 $tab = array_key_exists('tab', $_GET) ? sanitize_text_field($_GET['tab']) : false;
179 $is_valid = array_search($tab, $valid_tabs) != false;
180
181 if (!$tab || !$is_valid) {
182 $tab = $default_tab;
183 }
184
185 return $tab;
186 }
187
188 public function settings_page_markup()
189 {
190 // check user capabilities
191 if (!$this->min_permission_level('admin')) {
192 return;
193 }
194 $classes = get_option('iawp_dark_mode') ? 'iawp-parent dark-mode' : 'iawp-parent';
195 $tab = $this->get_current_tab(); ?>
196 <div id="iawp-parent" class="<?php echo esc_attr($classes); ?>">
197 <div class="header">
198 <div class="logo"><img src="<?php echo esc_url(IAWP_URL) . 'img/logo.png' ?>"/></div>
199 <div class="kb">
200 <a href="https://independentwp.com/knowledgebase/" class="iawp-button purple" target="_blank">
201 <span><?php esc_html_e('Knowledge Base', 'iawp'); ?></span>
202 <span class="dashicons dashicons-external"></span>
203 </a>
204 </div>
205 </div>
206 <nav class="menu">
207 <a href="?page=independent-analytics"
208 class="menu-item link-dark <?php if ($tab === 'views'): ?>active<?php endif; ?>">
209 <?php esc_html_e('Views', 'iawp'); ?>
210 </a>
211 <a href="?page=independent-analytics&tab=referrers"
212 class="menu-item link-dark <?php if ($tab === 'referrers'): ?>active<?php endif; ?>">
213 <?php esc_html_e('Referrers', 'iawp'); ?>
214 </a>
215 <a href="?page=independent-analytics&tab=settings"
216 class="menu-item link-dark <?php if ($tab === 'settings'): ?>active<?php endif; ?>">
217 <?php esc_html_e('Settings', 'iawp'); ?>
218 </a>
219 </nav>
220 <div class="tab-content"><?php
221 $views = new Views(Views::RESOURCES);
222 if ($tab == 'referrers') {
223 $table = new Table_Referrers();
224 echo '<div id="iawp-dashboard" class="iawp-dashboard">';
225 $quick_stats_html = IAWP()->chart->quick_stats($views);
226 $table->output_toolbar($table->columns(), $quick_stats_html);
227 echo $this->chart->output_chart($views);
228 $table = $table->output_data_table();
229 echo Security::html($table);
230 echo '</div>';
231 } elseif ($tab == 'settings') {
232 echo '<div id="iawp-dashboard" class="iawp-dashboard">';
233 Security::html($this->settings->render_settings());
234 echo '</div>';
235 } elseif ($tab == 'views') {
236 $table = new Table_Views();
237 echo '<div id="iawp-dashboard" class="iawp-dashboard">';
238 $quick_stats_html = IAWP()->chart->quick_stats($views);
239 Security::html($table->output_toolbar($table->columns(), $quick_stats_html));
240 echo $this->chart->output_chart($views);
241 $table = $table->output_data_table();
242 echo Security::html($table);
243 echo '</div>';
244 } ?>
245 </div>
246 <div id="loading-icon" class="loading-icon"><img src="<?php echo esc_url(IAWP_URL) . 'img/loading.svg' ?>"/></div>
247 </div>
248 <?php
249 }
250
251 public function enqueue_scripts($hook)
252 {
253 if ($hook == 'toplevel_page_independent-analytics') {
254 $tab = $this->get_current_tab();
255
256 wp_register_style('iawp-style', IAWP_URL . 'dist/styles/style.css', [], IAWP_VERSION);
257 wp_enqueue_style('iawp-style');
258
259 wp_register_script('iawp-js', IAWP_URL . 'dist/js/index.js', [], IAWP_VERSION);
260 wp_enqueue_script('iawp-js');
261 wp_add_inline_script('iawp-js', 'const IAWP_DELETE_DATA_NONCE = ' . json_encode(wp_create_nonce('iawp_delete_data')), 'before');
262
263 if ($tab == 'views' || $tab == 'referrers') {
264 wp_register_script('iawp-data-table', IAWP_URL . 'dist/js/data-table.js', [], IAWP_VERSION);
265 wp_enqueue_script('iawp-data-table');
266 wp_add_inline_script('iawp-data-table', 'const IAWP_AJAX = ' . json_encode([
267 'filter_nonce' => wp_create_nonce('iawp_filter'),
268 ]), 'before');
269 } elseif ($tab == 'settings') {
270 wp_register_script('iawp-settings', IAWP_URL . 'dist/js/settings.js', [], IAWP_VERSION);
271 wp_enqueue_script('iawp-settings');
272 wp_add_inline_script('iawp-settings', 'const IAWP_AJAX = ' . json_encode([
273 'export_views_nonce' => wp_create_nonce('iawp_export_views'),
274 'export_referrers_nonce' => wp_create_nonce('iawp_export_referrers'),
275 ]), 'before');
276 }
277 }
278 }
279
280 public function default_date_range()
281 {
282 $user_timezone = new \DateTimeZone(Timezone::local_offset());
283 $end = (new \DateTime(null, $user_timezone))->setTime(0, 0, 0);
284 $start = clone $end;
285 $start->modify('-29 days');
286
287 return [$start, $end];
288 }
289
290 public function previous_range(DateTime $start, DateTime $end)
291 {
292 $diff = $start->diff($end)->days + 1;
293 $prev_start = clone $start;
294 $prev_end = clone $end;
295
296 return [$prev_start->modify("-$diff days"), $prev_end->modify("-$diff days")];
297 }
298
299 // Returns bool based on minimum capability requirements
300 public function min_permission_level($role = 'subscriber')
301 {
302 if ($role == 'contributor') {
303 return current_user_can('edit_posts');
304 } elseif ($role == 'author') {
305 return current_user_can('publish_posts');
306 } elseif ($role == 'editor') {
307 return current_user_can('edit_others_posts');
308 } elseif ($role == 'admin') {
309 return current_user_can('manage_options');
310 } else {
311 return false;
312 }
313 }
314
315 public function get_full_permalink($id, $post_type)
316 {
317 // 0-> http://website.com/04/%postname%/
318 // 1-> example-post-title
319 $permalink_data = get_sample_permalink($id);
320 $permalink_base = $permalink_data[0];
321 if ($post_type == 'post') {
322 $permalink_base = trailingslashit(str_replace('%postname%', '', $permalink_base));
323 } else {
324 $permalink_base = trailingslashit(str_replace('%pagename%', '', $permalink_base));
325 }
326
327 $slug = $permalink_data[1];
328
329 $permalink = [
330 'base' => $permalink_base,
331 'slug' => $slug,
332 ];
333
334 return $permalink;
335 }
336
337 /* WP uses $default when get_option() is empty, but it also saves empty fields
338 ** as empty strings, meaning the return value can be "" instead of the default. This is
339 ** a defensive function that guarantees we get the proper default when the setting is empty. */
340 public function get_option($name, $default)
341 {
342 $option = get_option($name, $default);
343
344 return $option === '' ? $default : $option;
345 }
346
347 public function get_users_can_write()
348 {
349 $roles = [];
350 foreach (wp_roles()->roles as $role_name => $role_obj) {
351 if (!empty($role_obj['capabilities']['edit_posts'])) {
352 $roles[] = $role_name;
353 }
354 }
355
356 $users = get_users(['role__in' => $roles]);
357
358 return $users;
359 }
360
361 public function get_custom_types(bool $tax = false)
362 {
363 $args = [
364 'public' => true,
365 '_builtin' => false,
366 ];
367 if ($tax) {
368 return get_taxonomies($args);
369 } else {
370 return get_post_types($args);
371 }
372 }
373
374 public function filter_connect_message_on_update(
375 $message,
376 $user_first_name,
377 $product_title,
378 $user_login,
379 $site_link,
380 $freemius_link
381 ) {
382 // Add the heading HTML.
383 $plugin_name = 'Independent Analytics';
384 $title = '<h3>' . sprintf(esc_html__('We hope you love %1$s', 'iawp'), $plugin_name) . '</h3>';
385 $html = '';
386
387 // Add the introduction HTML.
388 $html .= '<p>';
389 $html .= sprintf(esc_html__('Hi, %1$s! This is an invitation to help the %2$s community. ', 'iawp'), $user_first_name, $plugin_name);
390 $html .= '<strong>';
391 $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);
392 $html .= '</strong>';
393 $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);
394 $html .= '</p>';
395
396 $html .= '<p>';
397 $html .= sprintf(esc_html__('And if you skip this, that\'s okay! %1$s will still work just fine.', 'iawp'), $plugin_name);
398 $html .= '</p>';
399
400 // Add the "Powered by" HTML.
401 $html .= '<div class="iawp-powered-by-freemius">' . esc_html__('Powered by Freemius', 'iawp') . '</div>';
402
403 return $title . $html;
404 }
405
406 public function plugin_action_links($links)
407 {
408 // Build the URL
409 $url = add_query_arg('page', 'independent-analytics', admin_url('admin.php'));
410
411 // Create the link
412 $settings_link = '<a class="calendar-link" href="' . esc_url($url) . '">' . esc_html__('Analytics Dashboard', 'iawp') . '</a>';
413
414 // Add the link to the start of the array
415 array_unshift($links, $settings_link);
416
417 return $links;
418 }
419 }
420 }
421
422 // Boot it up
423 function IAWP()
424 {
425 return Independent_Analytics::instance();
426 }
427
428 IAWP();
429