PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 1.17
Independent Analytics – WordPress Analytics Plugin v1.17
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 / IAWP / independent_analytics.php
independent-analytics / IAWP Last commit date
Migrations 3 years ago ajax 3 years ago models 3 years ago queries 3 years ago sql 3 years ago tables 3 years ago utils 3 years ago campaign_builder.php 3 years ago capability_manager.php 3 years ago chart.php 3 years ago chart_geo.php 3 years ago chart_svg.php 3 years ago dashboard_options.php 3 years ago dashboard_widget.php 3 years ago email_reports.php 3 years ago filters.php 3 years ago freemius.php 3 years ago geo_database.php 3 years ago geo_database_download_job.php 3 years ago health_check.php 3 years ago independent_analytics.php 3 years ago known_referrers.php 3 years ago pdf.php 3 years ago query.php 3 years ago quick_stats.php 3 years ago real_time.php 3 years ago rest_api.php 3 years ago settings.php 3 years ago track_resource_changes.php 3 years ago view_counter.php 3 years ago
independent_analytics.php
681 lines
1 <?php
2
3 namespace IAWP;
4
5 function default_args( array $args = array(), array $defaults = array() ) : array
6 {
7 $args = array_filter( $args, function ( $value ) {
8 // Remove key/value pairs where value is null
9 return $value !== null;
10 } );
11 $args = array_intersect_key( $args, $defaults );
12 return array_replace( $defaults, $args );
13 }
14
15 class Independent_Analytics
16 {
17 use Singleton ;
18 // This is where we attach functions to WP hooks
19 private function __construct()
20 {
21 $this->settings = new Settings();
22 new REST_API();
23 new Dashboard_Widget();
24 new View_Counter();
25 new Delete_Data_AJAX();
26 new Filters_AJAX();
27 new Export_Geo_AJAX();
28 new Export_Referrers_AJAX();
29 new Export_Views_AJAX();
30 new Migration_Status_AJAX();
31 new Update_Capabilities_AJAX();
32 new Cleared_Cache_AJAX();
33 new Track_Resource_Changes();
34 add_filter( 'admin_body_class', function ( $classes ) {
35 if ( get_option( 'iawp_dark_mode' ) ) {
36 $classes .= ' iawp-dark-mode ';
37 }
38 return $classes;
39 } );
40 add_action( 'admin_menu', [ $this, 'add_settings_page' ] );
41 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
42 add_filter( 'plugin_action_links_independent-analytics/iawp.php', [ $this, 'plugin_action_links' ] );
43 add_filter(
44 'admin_footer_text',
45 [ $this, 'ip_db_attribution' ],
46 1,
47 11
48 );
49 add_filter( 'admin_head', [ $this, 'style_premium_menu_item' ] );
50 add_action( 'init', [ $this, 'load_textdomain' ] );
51 IAWP_FS()->add_filter(
52 'connect_message_on_update',
53 [ $this, 'filter_connect_message_on_update' ],
54 10,
55 6
56 );
57 IAWP_FS()->add_filter(
58 'connect_message',
59 [ $this, 'filter_connect_message_on_update' ],
60 10,
61 6
62 );
63 IAWP_FS()->add_filter(
64 'is_submenu_visible',
65 [ $this, 'hide_freemius_sub_menus' ],
66 10,
67 2
68 );
69 IAWP_FS()->add_filter( 'pricing_url', [ $this, 'change_freemius_pricing_url' ], 10 );
70 }
71
72 // Text domain is used for i18n
73 public function load_textdomain()
74 {
75 load_plugin_textdomain( 'iawp', false, IAWP_LANGUAGES_DIRECTORY );
76 }
77
78 // Settings page where the analytics will appear
79 public function add_settings_page()
80 {
81 add_menu_page(
82 'Independent Analytics',
83 esc_html__( 'Analytics', 'iawp' ),
84 Capability_Manager::can_view_string(),
85 'independent-analytics',
86 [ $this, 'settings_page_markup' ],
87 'dashicons-analytics',
88 3
89 );
90 if ( !Capability_Manager::white_labeled() ) {
91 add_submenu_page(
92 'independent-analytics',
93 esc_html__( 'Feedback', 'iawp' ),
94 esc_html__( 'Feedback', 'iawp' ),
95 Capability_Manager::can_view_string(),
96 esc_url( 'https://feedback.independentwp.com/boards/feature-requests' )
97 );
98 }
99 if ( !IAWP_FS()->can_use_premium_code__premium_only() && !Capability_Manager::white_labeled() ) {
100 add_submenu_page(
101 'independent-analytics',
102 esc_html__( 'Upgrade to Pro &rarr;', 'iawp' ),
103 esc_html__( 'Upgrade to Pro &rarr;', 'iawp' ),
104 Capability_Manager::can_view_string(),
105 esc_url( 'https://independentwp.com/pricing/?utm_source=User+Dashboard&utm_medium=WP+Admin&utm_campaign=Upgrade+to+Pro&utm_content=Sidebar' )
106 );
107 }
108 }
109
110 public function hide_freemius_sub_menus( $is_visible, $menu_id )
111 {
112
113 if ( 'pricing' == $menu_id ) {
114 return false;
115 } elseif ( 'support' == $menu_id && Capability_Manager::white_labeled() ) {
116 return false;
117 } else {
118 return true;
119 }
120
121 }
122
123 public function change_freemius_pricing_url()
124 {
125 return 'https://independentwp.com/pricing/?utm_source=User+Dashboard&utm_medium=WP+Admin&utm_campaign=Upgrade+to+Pro&utm_content=Account';
126 }
127
128 // The submenu item needs to be styled on all admin pages, and we only load stylesheets on our page
129 public function style_premium_menu_item()
130 {
131 echo '<style>#toplevel_page_independent-analytics .wp-submenu li:nth-child(4) a { color: #F69D0A; }</style>' ;
132 }
133
134 private function get_current_tab()
135 {
136 $valid_tabs = [
137 'views',
138 'referrers',
139 'geo',
140 'settings',
141 'learn'
142 ];
143 $default_tab = $valid_tabs[0];
144 $tab = ( array_key_exists( 'tab', $_GET ) ? sanitize_text_field( $_GET['tab'] ) : false );
145 $is_valid = array_search( $tab, $valid_tabs ) != false;
146 if ( !$tab || !$is_valid ) {
147 $tab = $default_tab;
148 }
149 return $tab;
150 }
151
152 public function settings_page_markup()
153 {
154 if ( !Capability_Manager::can_view() ) {
155 return;
156 }
157 // Show migration message if needed
158
159 if ( Migrations\Migration::is_migrating() ) {
160 ?>
161 <div id="iawp-parent" class="iawp-parent">
162 <?php
163 echo IAWP()->templates()->render( 'layout/header', [
164 'show_review' => false,
165 ] ) ;
166 ?>
167 <?php
168 echo IAWP()->templates()->render( 'migration_running' ) ;
169 ?>
170 </div>
171 <?php
172 return;
173 }
174
175 $tab = $this->get_current_tab();
176 ?>
177 <div id="iawp-parent" class="iawp-parent">
178 <?php
179 if ( !Capability_Manager::white_labeled() ) {
180 echo IAWP()->templates()->render( 'layout/header' ) ;
181 }
182 ?>
183 <nav class="nav">
184 <ul class="menu">
185 <li class="menu-item">
186 <a href="?page=independent-analytics"
187 data-controller="track-date-range"
188 data-test-menu="views"
189 class="menu-link link-dark <?php
190 if ( $tab === 'views' ) {
191 ?>active<?php
192 }
193 ?>">
194 <?php
195 esc_html_e( 'Pages', 'iawp' );
196 ?>
197 </a>
198 </li>
199 <li class="menu-item">
200 <a href="?page=independent-analytics&tab=referrers"
201 data-controller="track-date-range"
202 data-test-menu="referrers"
203 class="menu-link link-dark <?php
204 if ( $tab === 'referrers' ) {
205 ?>active<?php
206 }
207 ?>">
208 <?php
209 esc_html_e( 'Referrers', 'iawp' );
210 ?>
211 </a>
212 </li>
213 <li class="menu-item">
214 <a href="?page=independent-analytics&tab=geo"
215 data-controller="track-date-range"
216 data-test-menu="geo"
217 class="menu-link link-dark <?php
218 if ( $tab === 'geo' ) {
219 ?>active<?php
220 }
221 ?>">
222 <?php
223 esc_html_e( 'Geographic', 'iawp' );
224 ?>
225 </a>
226 </li>
227 <?php
228 ?>
229 <?php
230
231 if ( Capability_Manager::can_edit() ) {
232 ?>
233 <li class="menu-item">
234 <a href="?page=independent-analytics&tab=settings"
235 data-test-menu="settings"
236 class="menu-link link-dark <?php
237 if ( $tab === 'settings' ) {
238 ?>active<?php
239 }
240 ?>">
241 <?php
242 esc_html_e( 'Settings', 'iawp' );
243 ?>
244 </a>
245 </li>
246 <?php
247 }
248
249 ?>
250 <?php
251
252 if ( !Capability_Manager::white_labeled() ) {
253 ?>
254 <li class="menu-item">
255 <a href="?page=independent-analytics&tab=learn"
256 data-test-menu="learn"
257 class="menu-link link-dark <?php
258 if ( $tab === 'learn' ) {
259 ?>active<?php
260 }
261 ?>">
262 <?php
263 esc_html_e( 'Learn', 'iawp' );
264 ?>
265 </a>
266 </li>
267 <?php
268 }
269
270 ?>
271 <?php
272
273 if ( !Capability_Manager::white_labeled() && !IAWP_FS()->can_use_premium_code__premium_only() ) {
274 ?>
275 <li class="menu-item upgrade first" data-controller="modal">
276 <a href="#"
277 data-test-menu="campaigns"
278 data-action="modal#toggleModal"
279 data-modal-target="modalButton"
280 class="menu-link link-dark">
281 <?php
282 esc_html_e( 'Campaigns', 'iawp' );
283 ?>
284 </a>
285 <div class="upgrade-popup"
286 data-modal-target="modal"
287 >
288 <div class="title">
289 <span class="name"><?php
290 esc_html_e( 'Campaigns', 'iawp' );
291 ?></span>
292 <span class="label"><?php
293 esc_html_e( 'PRO', 'iawp' );
294 ?></span>
295 </div>
296 <div class="description">
297 <p><?php
298 esc_html_e( "Campaigns let you track visits from individual links you share online, whether that's a Tweet, ad, or guest post.", 'iawp' );
299 ?></p>
300 <a class="iawp-button purple" target="_blank"
301 href="https://independentwp.com/features/campaigns/?utm_source=User+Dashboard&utm_medium=WP+Admin&utm_campaign=Campaigns+menu+item&utm_content=Menu+item"><?php
302 esc_html_e( 'Upgrade', 'iawp' );
303 ?></a>
304 </div>
305 </div>
306 </li>
307 <li class="menu-item upgrade" data-controller="modal">
308 <a href="#"
309 data-test-menu="real-time"
310 data-action="modal#toggleModal"
311 data-modal-target="modalButton"
312 class="menu-link link-dark">
313 <?php
314 esc_html_e( 'Real-time', 'iawp' );
315 ?>
316 </a>
317 <div class="upgrade-popup"
318 data-modal-target="modal"
319 >
320 <div class="title">
321 <span class="name"><?php
322 esc_html_e( 'Real-time analytics', 'iawp' );
323 ?></span>
324 <span class="label"><?php
325 esc_html_e( 'PRO', 'iawp' );
326 ?></span>
327 </div>
328 <div class="description">
329 <p><?php
330 esc_html_e( "Real-time analytics let you see how many people are on your site right now, what pages they're viewing, and where they came from.", 'iawp' );
331 ?></p>
332 <a class="iawp-button purple" target="_blank"
333 href="https://independentwp.com/features/real-time/?utm_source=User+Dashboard&utm_medium=WP+Admin&utm_campaign=Real-time+menu+item&utm_content=Menu+item"><?php
334 esc_html_e( 'Upgrade', 'iawp' );
335 ?></a>
336 </div>
337 </div>
338 </li>
339 <?php
340 }
341
342 ?>
343 </ul>
344 </nav>
345 <div class="tab-content"><?php
346 $opts = new Dashboard_Options();
347 $date_label = $opts->date_label();
348 $range = $opts->date_range();
349 $columns = $opts->columns();
350
351 if ( $tab == 'views' ) {
352 $table = new Table_Views( $columns );
353 $views = new Views(
354 Views::RESOURCES,
355 null,
356 $range->start,
357 $range->end
358 );
359 $stats = new Quick_Stats( $views );
360 $chart = new Chart( $views, $date_label );
361 $this->interface( $table, $stats, $chart );
362 } elseif ( $tab == 'referrers' ) {
363 $table = new Table_Referrers( $columns );
364 $views = new Views(
365 Views::RESOURCES,
366 null,
367 $range->start,
368 $range->end
369 );
370 $stats = new Quick_Stats( $views );
371 $chart = new Chart( $views, $date_label );
372 $this->interface( $table, $stats, $chart );
373 } elseif ( $tab == 'geo' ) {
374 $table = new Table_Geo( $columns );
375 $views = new Views(
376 Views::GEO,
377 null,
378 $range->start,
379 $range->end
380 );
381 $stats = new Quick_Stats( $views );
382 $geos = new Geos( [
383 'start' => $range->start,
384 'end' => $range->end,
385 'include_sub_and_city' => false,
386 ] );
387 $chart = new Chart_Geo( $geos, $date_label );
388 $this->interface( $table, $stats, $chart );
389 } elseif ( $tab === 'campaigns' ) {
390 $table = new Table_Campaigns( $columns );
391 $views = new Views(
392 Views::CAMPAIGNS,
393 null,
394 $range->start,
395 $range->end
396 );
397 $stats = new Quick_Stats( $views );
398 $chart = new Chart( $views, $date_label );
399 $this->interface( $table, $stats, $chart );
400 } elseif ( $tab == 'campaign-builder' ) {
401 ( new Campaign_Builder() )->render_campaign_builder();
402 } elseif ( $tab === 'real-time' ) {
403 ( new Real_Time() )->render_real_time_analytics();
404 } elseif ( $tab == 'settings' ) {
405 echo '<div id="iawp-dashboard" class="iawp-dashboard">' ;
406
407 if ( Capability_Manager::can_edit() ) {
408 $this->settings->render_settings();
409 } else {
410 echo '<p class="permission-blocked">' . esc_html__( 'You do not have permission to edit the settings.', 'iawp' ) . '</p>' ;
411 }
412
413 echo '</div>' ;
414 } elseif ( $tab == 'learn' ) {
415 echo '<div id="iawp-dashboard" class="iawp-dashboard">' ;
416 echo IAWP()->templates()->render( 'learn/index' ) ;
417 echo '</div>' ;
418 }
419
420 ?>
421 </div>
422 <div id="loading-icon" class="loading-icon"><img
423 src="<?php
424 echo esc_url( url_to( 'img/loading.svg' ) ) ;
425 ?>"/>
426 </div>
427 <button id="scroll-to-top" class="scroll-to-top"><span
428 class="dashicons dashicons-arrow-up-alt"></span>
429 </button>
430 </div>
431 <?php
432 }
433
434 public function interface( $table, $stats, $chart )
435 {
436 $opts = new Dashboard_Options();
437 ?>
438 <div id="iawp-dashboard"
439 class="iawp-dashboard"
440 data-controller="report"
441 data-report-relative-range-id-value="<?php
442 echo Security::attr( $opts->relative_range() ) ;
443 ?>"
444 data-report-exact-start-value="<?php
445 echo Security::attr( $opts->start() ) ;
446 ?>"
447 data-report-exact-end-value="<?php
448 echo Security::attr( $opts->end() ) ;
449 ?>"
450 data-report-columns-value="<?php
451 esc_attr_e( Security::json_encode( $table->visible_column_ids() ) );
452 ?>"
453 >
454 <?php
455 echo Security::html( $table->output_toolbar() ) ;
456 ?>
457 <?php
458 echo $stats->get_html() ;
459 ?>
460 <?php
461 echo $chart->get_html() ;
462 ?>
463 <?php
464 echo Security::html( $table->get_table_markup() ) ;
465 ?>
466 </div>
467 <div class="iawp-notices"><?php
468 $health_check = new Health_Check();
469 if ( !$health_check->healthy() ) {
470 echo IAWP()->templates()->render( 'settings/notice', [
471 'notice_text' => $health_check->error(),
472 'button_text' => false,
473 'notice' => 'iawp-error',
474 'url' => 'https://independentwp.com/knowledgebase/common-questions/views-not-recording/',
475 ] ) ;
476 }
477 if ( get_option( 'iawp_need_clear_cache' ) ) {
478 echo IAWP()->templates()->render( 'settings/notice', [
479 'notice_text' => __( 'Please clear your cache to ensure tracking works properly.', 'iawp' ),
480 'button_text' => __( 'I\'ve cleared the cache', 'iawp' ),
481 'notice' => 'iawp-warning',
482 'url' => 'https://independentwp.com/knowledgebase/common-questions/views-not-recording/',
483 ] ) ;
484 }
485 ?>
486 </div><?php
487 }
488
489 public function enqueue_scripts( $hook )
490 {
491
492 if ( $hook == 'toplevel_page_independent-analytics' ) {
493 $tab = $this->get_current_tab();
494 wp_register_style(
495 'iawp-style',
496 url_to( 'dist/styles/style.css' ),
497 [],
498 IAWP_VERSION
499 );
500 wp_enqueue_style( 'iawp-style' );
501 wp_register_script(
502 'iawp-js',
503 url_to( 'dist/js/index.js' ),
504 [],
505 IAWP_VERSION
506 );
507 wp_enqueue_script( 'iawp-js' );
508 wp_add_inline_script( 'iawp-js', 'const IAWP_DELETE_DATA_NONCE = ' . json_encode( wp_create_nonce( 'iawp_delete_data' ) ), 'before' );
509
510 if ( $tab === 'views' || $tab === 'referrers' || $tab === 'geo' || $tab === 'campaigns' || $tab === 'campaign-builder' ) {
511 wp_register_script(
512 'iawp-data-table',
513 url_to( 'dist/js/data-table.js' ),
514 [],
515 IAWP_VERSION
516 );
517 wp_enqueue_script( 'iawp-data-table' );
518 wp_add_inline_script( 'iawp-data-table', 'const IAWP_AJAX = ' . json_encode( [
519 'filter_nonce' => wp_create_nonce( 'iawp_filter' ),
520 'create_campaign_nonce' => wp_create_nonce( 'iawp_create_campaign' ),
521 'copied_text' => esc_html( 'Copied!', 'iawp' ),
522 'iawp_need_clear_cache_nonce' => wp_create_nonce( 'iawp_need_clear_cache' ),
523 ] ), 'before' );
524 } elseif ( $tab == 'settings' ) {
525 wp_register_script(
526 'iawp-settings',
527 url_to( 'dist/js/settings.js' ),
528 [],
529 IAWP_VERSION
530 );
531 wp_enqueue_script( 'iawp-settings' );
532 wp_add_inline_script( 'iawp-settings', 'const IAWP_AJAX = ' . json_encode( [
533 'export_views_nonce' => wp_create_nonce( 'iawp_export_views' ),
534 'export_referrers_nonce' => wp_create_nonce( 'iawp_export_referrers' ),
535 'export_geo_nonce' => wp_create_nonce( 'iawp_export_geo' ),
536 'export_campaigns_nonce' => wp_create_nonce( 'iawp_export_campaigns' ),
537 'iawp_capabilities_nonce' => wp_create_nonce( 'iawp_capabilities' ),
538 'iawp_test_email_nonce' => wp_create_nonce( 'iawp_test_email' ),
539 'exporting_views_text' => esc_html( 'Exporting views...', 'iawp' ),
540 'export_views_text' => esc_html( 'Export views', 'iawp' ),
541 'exporting_referrers_text' => esc_html( 'Exporting referrers...', 'iawp' ),
542 'export_referrers_text' => esc_html( 'Export referrers', 'iawp' ),
543 'exporting_geo_text' => esc_html( 'Exporting geo...', 'iawp' ),
544 'export_geo_text' => esc_html( 'Export geo', 'iawp' ),
545 'exporting_campaigns_text' => esc_html( 'Exporting campaigns...', 'iawp' ),
546 'export_campaigns_text' => esc_html( 'Export campaigns', 'iawp' ),
547 ] ), 'before' );
548 } elseif ( $tab == 'learn' ) {
549 wp_register_script(
550 'iawp-learn',
551 url_to( 'dist/js/learn.js' ),
552 [],
553 IAWP_VERSION
554 );
555 wp_enqueue_script( 'iawp-learn' );
556 }
557
558 } elseif ( $hook == 'index.php' ) {
559 wp_register_script(
560 'iawp-dashboard-widget',
561 url_to( 'dist/js/dashboard_widget.js' ),
562 [],
563 IAWP_VERSION
564 );
565 wp_enqueue_script( 'iawp-dashboard-widget' );
566 wp_register_style(
567 'iawp-dashboard-widget-css',
568 url_to( 'dist/styles/dashboard_widget.css' ),
569 [],
570 IAWP_VERSION
571 );
572 wp_enqueue_style( 'iawp-dashboard-widget-css' );
573 }
574
575 }
576
577 /* WP uses $default when get_option() is empty, but it also saves empty fields
578 ** as empty strings, meaning the return value can be "" instead of the default. This is
579 ** a defensive function that guarantees we get the proper default when the setting is empty. */
580 public function get_option( $name, $default )
581 {
582 $option = get_option( $name, $default );
583 return ( $option === '' ? $default : $option );
584 }
585
586 public function templates()
587 {
588 return new League\Plates\Engine( path_to( 'templates' ) );
589 }
590
591 public function get_users_can_write()
592 {
593 $roles = [];
594 foreach ( wp_roles()->roles as $role_name => $role_obj ) {
595 if ( !empty($role_obj['capabilities']['edit_posts']) ) {
596 $roles[] = $role_name;
597 }
598 }
599 $users = get_users( [
600 'role__in' => $roles,
601 ] );
602 return $users;
603 }
604
605 public function get_custom_types( bool $tax = false )
606 {
607 $args = [
608 'public' => true,
609 '_builtin' => false,
610 ];
611
612 if ( $tax ) {
613 return get_taxonomies( $args );
614 } else {
615 return get_post_types( $args );
616 }
617
618 }
619
620 public function filter_connect_message_on_update(
621 $message,
622 $user_first_name,
623 $product_title,
624 $user_login,
625 $site_link,
626 $freemius_link
627 )
628 {
629 // Add the heading HTML.
630 $plugin_name = 'Independent Analytics';
631 $title = '<h3>' . sprintf( esc_html__( 'We hope you love %1$s', 'iawp' ), $plugin_name ) . '</h3>';
632 $html = '';
633 // Add the introduction HTML.
634 $html .= '<p>';
635 $html .= sprintf( esc_html__( 'Hi, %1$s! This is an invitation to help the %2$s community. ', 'iawp' ), $user_first_name, $plugin_name );
636 $html .= '<strong>';
637 $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 );
638 $html .= '</strong>';
639 $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 );
640 $html .= '</p>';
641 $html .= '<p>';
642 $html .= sprintf( esc_html__( 'And if you skip this, that\'s okay! %1$s will still work just fine.', 'iawp' ), $plugin_name );
643 $html .= '</p>';
644 // Add the "Powered by" HTML.
645 $html .= '<div class="iawp-powered-by-freemius">' . esc_html__( 'Powered by Freemius', 'iawp' ) . '</div>';
646 return $title . $html;
647 }
648
649 public function plugin_action_links( $links )
650 {
651 // Build the URL
652 $url = add_query_arg( 'page', 'independent-analytics', admin_url( 'admin.php' ) );
653 // Create the link
654 $settings_link = '<a class="calendar-link" href="' . esc_url( $url ) . '">' . esc_html__( 'Analytics Dashboard', 'iawp' ) . '</a>';
655 // Add the link to the start of the array
656 array_unshift( $links, $settings_link );
657 return $links;
658 }
659
660 public function set_time_limit( $limit = 0 )
661 {
662 if ( !function_exists( 'set_time_limit' ) && false !== strpos( ini_get( 'disable_functions' ), 'set_time_limit' ) && ini_get( 'safe_mode' ) ) {
663 return false;
664 }
665 return @set_time_limit( $limit );
666 }
667
668 public function ip_db_attribution( $text )
669 {
670 if ( $this->get_current_tab() === 'geo' ) {
671 $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>.';
672 }
673 return $text;
674 }
675
676 public function pagination_page_size()
677 {
678 return 50;
679 }
680
681 }