ThirstyAffiliates Affiliate Link Manager - Version 3.3.3

Version Description

  • Improvement: Block bots on stats recording process for non-apache servers
  • Improvement: Remove report data query on page first load
  • Improvement: Add settings for blocking bots
  • Improvement: Ability to turn off IP address collection on stats (GDPR compliance)
  • Improvement: Move "Enable Enhanced Javascript Redirect on Frontend" setting to Link Appearance tab
  • Improvement: Code improvements
  • Bug Fix: Improve reliability of link scanner
  • Bug Fix: attachment page can be viewed with link prefix
  • Bug Fix: Improve accuracy of link performance report
Download this release

Release Info

Developer jkohlbach
Plugin Icon 128x128 ThirstyAffiliates Affiliate Link Manager
Version 3.3.3
Comparing to
See all releases

Code changes from version 3.3.2 to 3.3.3

Helpers/Helper_Functions.php CHANGED
@@ -236,12 +236,16 @@ class Helper_Functions {
236
  * Get user IP address.
237
  *
238
  * @since 3.0.0
 
239
  * @access public
240
  *
241
  * @return string User's IP address.
242
  */
243
  public function get_user_ip_address() {
244
 
 
 
 
245
  if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) )
246
  $ip = $_SERVER['HTTP_CLIENT_IP'];
247
  elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
@@ -494,4 +498,59 @@ class Helper_Functions {
494
  return ( gettype( $option_value ) === gettype( $default_value ) && $option_value ) ? $option_value : $default_value;
495
  }
496
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
497
  }
236
  * Get user IP address.
237
  *
238
  * @since 3.0.0
239
+ * @since 3.3.2 Added condition to disable IP address collection (for GDRP compliance).
240
  * @access public
241
  *
242
  * @return string User's IP address.
243
  */
244
  public function get_user_ip_address() {
245
 
246
+ if ( get_option( 'ta_disable_ip_address_collection' ) === 'yes' )
247
+ return;
248
+
249
  if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) )
250
  $ip = $_SERVER['HTTP_CLIENT_IP'];
251
  elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
498
  return ( gettype( $option_value ) === gettype( $default_value ) && $option_value ) ? $option_value : $default_value;
499
  }
500
 
501
+ /**
502
+ * Get blocked bots from settings or default value.
503
+ *
504
+ * @since 3.3.2
505
+ * @access public
506
+ *
507
+ * @return array List of blocked bots.
508
+ */
509
+ public function get_blocked_bots() {
510
+
511
+ $bots_string = $this->get_option( 'ta_blocked_bots' , Plugin_Constants::DEFAULT_BLOCKED_BOTS );
512
+ return str_replace( ',' , '|' , $bots_string );
513
+ }
514
+
515
+ /**
516
+ * Check if useragent is bot.
517
+ *
518
+ * @since 3.3.3
519
+ * @access public
520
+ *
521
+ * @return bool True if detected as bot, otherwise false.
522
+ */
523
+ public function is_user_agent_bot() {
524
+
525
+ $user_agent = isset( $_SERVER[ 'HTTP_USER_AGENT' ] ) ? strtolower( $_SERVER[ 'HTTP_USER_AGENT' ] ) : '';
526
+ $bots = apply_filters( 'ta_useragent_bots_phrase_list' , $this->get_blocked_bots() );
527
+ $pattern = '/' . $bots . '/i';
528
+
529
+ return preg_match( $pattern , $user_agent );
530
+ }
531
+
532
+ /**
533
+ * Get screen ID.
534
+ *
535
+ * @since 3.3.3
536
+ * @access public
537
+ */
538
+ public function get_screen_id( $object_id ) {
539
+
540
+ $screen_id = null;
541
+
542
+ if ( isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == Plugin_Constants::AFFILIATE_LINKS_CPT ) {
543
+
544
+ if ( isset( $_GET[ 'taxonomy' ] ) )
545
+ $screen_id = 'edit-' . $_GET[ 'taxonomy' ];
546
+ elseif ( isset( $_GET[ 'page' ] ) )
547
+ $screen_id = 'thirstylink_page_' . $_GET[ 'page' ];
548
+ else
549
+ $screen_id = 'edit-thirstylink';
550
+
551
+ } elseif ( $object_id )
552
+ $screen_id = 'thirstylink';
553
+
554
+ return apply_filters( 'ta_get_screen_id' , $screen_id );
555
+ }
556
  }
Helpers/Plugin_Constants.php CHANGED
@@ -27,7 +27,7 @@ class Plugin_Constants {
27
  // Plugin configuration constants
28
  const TOKEN = 'ta';
29
  const INSTALLED_VERSION = 'ta_installed_version';
30
- const VERSION = '3.3.2';
31
  const TEXT_DOMAIN = 'thirstyaffiliates';
32
  const THEME_TEMPLATE_PATH = 'thirstyaffiliates';
33
  const META_DATA_PREFIX = '_ta_';
@@ -50,6 +50,7 @@ class Plugin_Constants {
50
  const SHOW_TAPRO_NOTICE = 'ta_show_tapro_notice';
51
 
52
  // Settings Constants
 
53
 
54
  // DB Tables
55
  const LINK_CLICK_DB = 'ta_link_clicks';
27
  // Plugin configuration constants
28
  const TOKEN = 'ta';
29
  const INSTALLED_VERSION = 'ta_installed_version';
30
+ const VERSION = '3.3.3';
31
  const TEXT_DOMAIN = 'thirstyaffiliates';
32
  const THEME_TEMPLATE_PATH = 'thirstyaffiliates';
33
  const META_DATA_PREFIX = '_ta_';
50
  const SHOW_TAPRO_NOTICE = 'ta_show_tapro_notice';
51
 
52
  // Settings Constants
53
+ const DEFAULT_BLOCKED_BOTS = 'googlebot,bingbot,Slurp,DuckDuckBot,Baiduspider,YandexBot,Sogou,Exabot,facebo,ia_archiver';
54
 
55
  // DB Tables
56
  const LINK_CLICK_DB = 'ta_link_clicks';
Models/Affiliate_Link.php CHANGED
@@ -705,6 +705,7 @@ class Affiliate_Link {
705
  * Scan where links are inserted.
706
  *
707
  * @since 3.2.0
 
708
  * @access public
709
  *
710
  * @return array List of WP_Post IDs where affiliate link is inserted in content.
@@ -714,11 +715,21 @@ class Affiliate_Link {
714
  global $wpdb;
715
 
716
  // prepare the query.
717
- $post_ids = array();
718
- $link_id = $this->get_id();
719
- $link_slug = $this->get_prop( 'slug' );
720
- $cpt_slug = Plugin_Constants::AFFILIATE_LINKS_CPT;
721
- $query = "SELECT ID FROM $wpdb->posts WHERE ( post_content LIKE '%/$link_slug/%' OR post_content LIKE '%[thirstylink%ids=\"$link_id%' ) AND post_type NOT IN ( '$cpt_slug' , 'revision' ) AND post_status = 'publish'";
 
 
 
 
 
 
 
 
 
 
722
 
723
  // fetch WP_Post IDs where link is inserted to.
724
  $raw_ids = $wpdb->get_col( $query );
@@ -726,9 +737,6 @@ class Affiliate_Link {
726
  // save last scanned
727
  update_post_meta( $this->get_id() , Plugin_Constants::META_DATA_PREFIX . 'scanned_inserted' , current_time( 'mysql' , true ) );
728
 
729
- if ( ! is_array( $raw_ids ) || empty( $raw_ids ) )
730
- return $post_ids;
731
-
732
  // save to custom meta.
733
  $post_ids = array_map( 'intval' , $raw_ids );
734
  update_post_meta( $this->get_id() , Plugin_Constants::META_DATA_PREFIX . 'inserted_to' , $post_ids );
705
  * Scan where links are inserted.
706
  *
707
  * @since 3.2.0
708
+ * @since 3.3.3 Improve the query to specify the results by searching using the permalink value, and alternating between the used link prefixes.
709
  * @access public
710
  *
711
  * @return array List of WP_Post IDs where affiliate link is inserted in content.
715
  global $wpdb;
716
 
717
  // prepare the query.
718
+ $post_ids = array();
719
+ $link_id = $this->get_id();
720
+ $cpt_slug = Plugin_Constants::AFFILIATE_LINKS_CPT;
721
+ $types = get_post_types( array( 'public' => true ) , 'names' , 'and' );
722
+ $types_str = implode( "','" , $types );
723
+ $permalink = $this->get_prop( 'permalink' );
724
+ $link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
725
+ $link_prefixes = $this->_helper_functions->get_option( 'ta_used_link_prefixes' , array() );
726
+ $like_query = array();
727
+
728
+ foreach ( $link_prefixes as $prefix )
729
+ $like_query[] = str_replace( $link_prefix , $prefix , "post_content LIKE '%$permalink\"%'" );
730
+
731
+ $like_query_str = implode( ' OR ' , $like_query );
732
+ $query = "SELECT ID FROM $wpdb->posts WHERE ( $like_query_str OR post_content LIKE '%[thirstylink%ids=\"$link_id%' ) AND post_type IN ( '$types_str' ) AND post_status = 'publish'";
733
 
734
  // fetch WP_Post IDs where link is inserted to.
735
  $raw_ids = $wpdb->get_col( $query );
737
  // save last scanned
738
  update_post_meta( $this->get_id() , Plugin_Constants::META_DATA_PREFIX . 'scanned_inserted' , current_time( 'mysql' , true ) );
739
 
 
 
 
740
  // save to custom meta.
741
  $post_ids = array_map( 'intval' , $raw_ids );
742
  update_post_meta( $this->get_id() , Plugin_Constants::META_DATA_PREFIX . 'inserted_to' , $post_ids );
Models/Affiliate_Links_CPT.php CHANGED
@@ -118,6 +118,45 @@ class Affiliate_Links_CPT implements Model_Interface , Initiable_Interface {
118
 
119
  }
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  /**
122
  * Get thirstylink Affiliate_Link object.
123
  *
@@ -149,6 +188,7 @@ class Affiliate_Links_CPT implements Model_Interface , Initiable_Interface {
149
  * Register the 'thirstylink' custom post type.
150
  *
151
  * @since 3.0.0
 
152
  * @access private
153
  */
154
  private function register_thirstylink_custom_post_type() {
@@ -200,12 +240,9 @@ class Affiliate_Links_CPT implements Model_Interface , Initiable_Interface {
200
  'exclude_from_search' => true,
201
  'publicly_queryable' => true,
202
  'capability_type' => 'post',
203
- 'show_in_rest' => true
204
  );
205
 
206
- if ( ! current_user_can( apply_filters( 'ta_add_affiliate_link_capability' , 'publish_posts' ) ) )
207
- $args[ 'capabilities' ] = array( 'create_posts' => false , 'delete_posts' => false );
208
-
209
  register_post_type( Plugin_Constants::AFFILIATE_LINKS_CPT , apply_filters( 'ta_affiliate_links_cpt_args' , $args , $labels ) );
210
 
211
  do_action( 'ta_after_register_thirstylink_post_type' , $link_prefix );
@@ -215,6 +252,7 @@ class Affiliate_Links_CPT implements Model_Interface , Initiable_Interface {
215
  * Register the 'thirstylink-category' custom taxonomy.
216
  *
217
  * @since 3.0.0
 
218
  * @access private
219
  */
220
  private function register_thirstylink_category_custom_taxonomy() {
@@ -250,7 +288,10 @@ class Affiliate_Links_CPT implements Model_Interface , Initiable_Interface {
250
  'show_admin_column' => true,
251
  'show_in_nav_menus' => false,
252
  'show_tagcloud' => false,
253
- 'rewrite' => false
 
 
 
254
  );
255
 
256
  register_taxonomy( Plugin_Constants::AFFILIATE_LINKS_TAX , Plugin_Constants::AFFILIATE_LINKS_CPT , apply_filters( 'ta_affiliate_link_taxonomy_args' , $args , $labels ) );
@@ -926,7 +967,6 @@ class Affiliate_Links_CPT implements Model_Interface , Initiable_Interface {
926
 
927
  add_action( 'wp_ajax_ta_get_category_slug' , array( $this , 'ajax_get_category_slug' ) );
928
  add_action( 'wp_ajax_ta_link_inserted_scanner' , array( $this , 'ajax_link_inserted_scanner' ) );
929
-
930
  }
931
 
932
  /**
@@ -958,6 +998,9 @@ class Affiliate_Links_CPT implements Model_Interface , Initiable_Interface {
958
  // filter to add category on permalink
959
  add_filter( 'post_type_link' , array( $this , 'add_category_slug_to_permalink' ) , 10 , 2 );
960
 
 
 
 
961
  }
962
 
963
  }
118
 
119
  }
120
 
121
+ /**
122
+ * Register admin interfaces.
123
+ *
124
+ * @since 3.3.3
125
+ * @access public
126
+ *
127
+ * @param array $interfaces List of admin interfaces.
128
+ * @return array Filtered list of admin interfaces.
129
+ */
130
+ public function register_admin_interfaces( $interfaces ) {
131
+
132
+ $interfaces[ 'edit-thirstylink' ] = 'edit_posts';
133
+ $interfaces[ 'thirstylink' ] = 'edit_posts';
134
+ $interfaces[ 'edit-thirstylink-category' ] = 'manage_categories';
135
+
136
+ return $interfaces;
137
+ }
138
+
139
+ /**
140
+ * Register admin interfaces.
141
+ *
142
+ * @since 3.3.3
143
+ * @access public
144
+ *
145
+ * @param array $interfaces List of menu items.
146
+ * @return array Filtered list of menu items.
147
+ */
148
+ public function register_admin_menu_items( $menu_items ) {
149
+
150
+ $list_slug = 'edit.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
151
+ $new_post_slug = 'post-new.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
152
+ $link_cat_slug = 'edit-tags.php?taxonomy=' . Plugin_Constants::AFFILIATE_LINKS_TAX . '&post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
153
+ $menu_items[ $list_slug ] = 'edit_posts';
154
+ $menu_items[ $new_post_slug ] = 'edit_posts';
155
+ $menu_items[ $link_cat_slug ] = 'manage_categories';
156
+
157
+ return $menu_items;
158
+ }
159
+
160
  /**
161
  * Get thirstylink Affiliate_Link object.
162
  *
188
  * Register the 'thirstylink' custom post type.
189
  *
190
  * @since 3.0.0
191
+ * @since 3.3.2 Set manage_terms capability to read so we can control visibility natively. see Bootstrap::admin_interface_visibility.
192
  * @access private
193
  */
194
  private function register_thirstylink_custom_post_type() {
240
  'exclude_from_search' => true,
241
  'publicly_queryable' => true,
242
  'capability_type' => 'post',
243
+ 'show_in_rest' => true,
244
  );
245
 
 
 
 
246
  register_post_type( Plugin_Constants::AFFILIATE_LINKS_CPT , apply_filters( 'ta_affiliate_links_cpt_args' , $args , $labels ) );
247
 
248
  do_action( 'ta_after_register_thirstylink_post_type' , $link_prefix );
252
  * Register the 'thirstylink-category' custom taxonomy.
253
  *
254
  * @since 3.0.0
255
+ * @since 3.3.2 Set manage_terms capability to read so we can control visibility natively. see Bootstrap::admin_interface_visibility.
256
  * @access private
257
  */
258
  private function register_thirstylink_category_custom_taxonomy() {
288
  'show_admin_column' => true,
289
  'show_in_nav_menus' => false,
290
  'show_tagcloud' => false,
291
+ 'rewrite' => false,
292
+ 'capabilities' => array(
293
+ 'manage_terms' => 'read',
294
+ )
295
  );
296
 
297
  register_taxonomy( Plugin_Constants::AFFILIATE_LINKS_TAX , Plugin_Constants::AFFILIATE_LINKS_CPT , apply_filters( 'ta_affiliate_link_taxonomy_args' , $args , $labels ) );
967
 
968
  add_action( 'wp_ajax_ta_get_category_slug' , array( $this , 'ajax_get_category_slug' ) );
969
  add_action( 'wp_ajax_ta_link_inserted_scanner' , array( $this , 'ajax_link_inserted_scanner' ) );
 
970
  }
971
 
972
  /**
998
  // filter to add category on permalink
999
  add_filter( 'post_type_link' , array( $this , 'add_category_slug_to_permalink' ) , 10 , 2 );
1000
 
1001
+ // Register admin interface and menus.
1002
+ add_filter( 'ta_admin_interfaces' , array( $this , 'register_admin_interfaces' ) );
1003
+ add_filter( 'ta_menu_items' , array( $this , 'register_admin_menu_items' ) );
1004
  }
1005
 
1006
  }
Models/Bootstrap.php CHANGED
@@ -392,6 +392,77 @@ class Bootstrap implements Model_Interface {
392
  return array_merge( $new_links , $links );
393
  }
394
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
  /**
396
  * Method that houses codes to be executed on init hook.
397
  *
@@ -441,6 +512,8 @@ class Bootstrap implements Model_Interface {
441
  // Execute codes that need to run on 'init' hook
442
  add_action( 'init' , array( $this , 'initialize' ) );
443
 
 
 
444
  }
445
 
446
  }
392
  return array_merge( $new_links , $links );
393
  }
394
 
395
+ /**
396
+ * Control admin interface visibility.
397
+ *
398
+ * @since 3.3.2
399
+ * @access public
400
+ */
401
+ public function admin_interface_visibility() {
402
+
403
+ $object_id = isset( $_GET[ 'post' ] ) ? absint( $_GET[ 'post' ] ) : 0;
404
+
405
+ if ( ! $screen_id = $this->_helper_functions->get_screen_id( $object_id ) )
406
+ return;
407
+
408
+ $current_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : '';
409
+
410
+ $post_type = isset( $_GET[ 'post_type' ] ) ? sanitize_text_field( $_GET[ 'post_type' ] ) : '';
411
+
412
+ $interfaces = apply_filters( 'ta_admin_interfaces' , array() );
413
+ $current_interface = $screen_id && isset( $interfaces[ $screen_id ] ) ? $interfaces[ $screen_id ] : null;
414
+
415
+ // if interface is not present then don't proceed
416
+ if ( ! $current_interface || empty( $current_interface ) ) return;
417
+ if ( $current_tab && ! isset( $current_interface[ $current_tab ] ) ) return;
418
+
419
+ // get the capability allowed for the interface
420
+ if ( is_array( $current_interface ) )
421
+ $capability = $current_tab ? $current_interface[ $current_tab ] : array_values( $current_interface )[0];
422
+ else
423
+ $capability = $current_interface;
424
+
425
+ // get error message.
426
+ $error_message = apply_filters( 'ta_admin_interface_error_message' , __( "xxSorry, you are not allowed to access this page." , 'thirstyaffiliates' ) , $screen_id , $current_tab , $capability , $current_interface );
427
+
428
+ // kill page display error message if current user does not have capability.
429
+ if ( ( $capability && ! current_user_can( $capability ) ) || ( $object_id && isset( $_GET[ 'post' ] ) && get_current_user_id() != get_post_field( 'post_author' , $object_id ) && ! current_user_can( 'edit_others_posts' ) ) )
430
+ wp_die( $error_message );
431
+ }
432
+
433
+ /**
434
+ * Control admin menu items visibility.
435
+ *
436
+ * @since 3.3.2
437
+ * @access public
438
+ */
439
+ public function admin_menu_items_visibilty() {
440
+
441
+ global $submenu;
442
+
443
+ $menu_slug = 'edit.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
444
+ $menu_items = apply_filters( 'ta_menu_items' , array() );
445
+ $main_cap = null;
446
+
447
+ if ( ! is_array( $menu_items ) || empty( $menu_items ) ) return;
448
+
449
+ foreach ( $menu_items as $submenu_slug => $capability ) {
450
+
451
+ if ( $submenu_slug == $menu_slug ) {
452
+ $main_cap = $capability;
453
+ continue;
454
+ }
455
+
456
+ if ( $capability && ! current_user_can( $capability ) )
457
+ remove_submenu_page( $menu_slug , esc_attr( $submenu_slug ) );
458
+ }
459
+
460
+ $menu_count = isset( $submenu[ $menu_slug ] ) ? count( $submenu[ $menu_slug ] ) : 0;
461
+
462
+ if ( ( ! $main_cap || ! current_user_can( $main_cap ) ) && $menu_count <= 1 )
463
+ remove_menu_page( $menu_slug );
464
+ }
465
+
466
  /**
467
  * Method that houses codes to be executed on init hook.
468
  *
512
  // Execute codes that need to run on 'init' hook
513
  add_action( 'init' , array( $this , 'initialize' ) );
514
 
515
+ add_action( 'init' , array( $this , 'admin_interface_visibility' ) );
516
+ add_action( 'admin_menu' , array( $this , 'admin_menu_items_visibilty' ) , 20 );
517
  }
518
 
519
  }
Models/Rewrites_Redirection.php CHANGED
@@ -213,14 +213,26 @@ class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface
213
  *
214
  * @since 3.0.0
215
  * @since 3.2.2 Add implementation for disabling cache for 301 redirects.
 
216
  * @access public
217
  */
218
  public function redirect_url() {
219
 
220
  global $post , $wp_query;
221
 
222
- if ( is_admin() || ! is_object( $post ) || $post->post_type != Plugin_Constants::AFFILIATE_LINKS_CPT )
 
 
 
 
 
 
 
 
 
 
223
  return;
 
224
 
225
  $thirstylink = $this->get_thirstylink_post( $post->ID );
226
  $redirect_url = html_entity_decode( $thirstylink->get_prop( 'destination_url' ) );
@@ -256,23 +268,26 @@ class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface
256
  }
257
 
258
  /**
259
- * Validate the cloaked url. For now this only checks the category slug.
260
  *
261
  * @since 3.2.2
 
262
  * @access private
263
  *
264
  * @return boolean True if cloaked url is valid, false otherwise.
265
  */
266
- private function validate_cloaked_url( $thirstylink ) {
267
 
268
- $cat_slug = $thirstylink->get_category_slug();
269
- $referrer = isset( $_SERVER[ 'REQUEST_URI' ] ) ? $_SERVER[ 'REQUEST_URI' ] : '';
 
 
270
 
271
  // if setting is disabled or category slug is not defined, then return as validated.
272
- if ( get_option( 'ta_show_cat_in_slug' ) !== 'yes' || ! $cat_slug )
273
- return true;
274
 
275
- return ( strpos( $referrer , '/' . $cat_slug . '/' ) !== false );
276
  }
277
 
278
  /**
@@ -299,23 +314,23 @@ class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface
299
  * Add/Recreate htaccess rule to block bots access to affiliate links.
300
  *
301
  * @since 3.1.0
 
302
  * @access public
303
  */
304
  public function block_bots_to_access_affiliate_links_on_htaccess() {
305
 
306
  $htaccess = $this->remove_block_bots_htaccess_rules();
307
  $link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
308
- $bots_list = apply_filters( 'ta_block_bots_on_htaccess' , array( 'googlebot' , 'bingbot' , 'Slurp' , 'DuckDuckBot' , 'Baiduspider' , 'YandexBot' , 'Sogou' , 'Exabot' , 'facebo' , 'ia_archiver' ) );
309
 
310
  // prepare new TA block bots htaccess content.
311
- $bots_list_str = implode( $bots_list , '|' );
312
- $block_bots = "\n#BEGIN Block-Bots-ThirstyAffiliates\n";
313
- $block_bots .= "<IfModule mod_rewrite.c>\n";
314
- $block_bots .= "RewriteEngine On\n";
315
- $block_bots .= "RewriteCond %{HTTP_USER_AGENT} (" . $bots_list_str . ") [NC]\n";
316
- $block_bots .= "RewriteRule ^" . $link_prefix . "/ - [L,F]\n";
317
- $block_bots .= "</IfModule>\n";
318
- $block_bots .= "#END Block-Bots-ThirstyAffiliates\n\n";
319
 
320
  // prepend block bots rules in the htaccess content.
321
  $htaccess = $block_bots . $htaccess;
@@ -344,6 +359,26 @@ class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface
344
  return $htaccess;
345
  }
346
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
 
348
 
349
 
@@ -378,6 +413,7 @@ class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface
378
  add_filter( 'pre_update_option_ta_link_prefix' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
379
  add_filter( 'pre_update_option_ta_link_prefix_custom' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
380
  add_filter( 'pre_update_option_ta_show_cat_in_slug' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
 
381
  add_action( 'ta_after_register_thirstylink_post_type' , array( $this , 'set_rewrites' ) , 1 , 1 );
382
  add_action( 'ta_after_register_thirstylink_post_type' , array( $this , 'flush_rewrite_rules' ) );
383
 
@@ -386,5 +422,8 @@ class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface
386
 
387
  // filter redirect url before redirecting
388
  add_filter( 'ta_filter_redirect_url' , array( $this , 'pass_query_string_to_destination_url' ) , 10 , 2 );
 
 
 
389
  }
390
  }
213
  *
214
  * @since 3.0.0
215
  * @since 3.2.2 Add implementation for disabling cache for 301 redirects.
216
+ * @since 3.3.2 TA-265 when attachment page is viewed link prefix, set page to 404 via $wp_query object.
217
  * @access public
218
  */
219
  public function redirect_url() {
220
 
221
  global $post , $wp_query;
222
 
223
+ if ( is_admin() || ! is_object( $post ) || $post->post_type != Plugin_Constants::AFFILIATE_LINKS_CPT ) {
224
+
225
+ if ( is_object( $post ) && $post->post_type === 'attachment' && $this->validate_cloaked_url() )
226
+ $wp_query->set_404();
227
+
228
+ return;
229
+ }
230
+
231
+ if ( $this->_helper_functions->is_user_agent_bot() ) {
232
+ header("HTTP/1.1 403 Forbidden" );
233
+ wp_die();
234
  return;
235
+ }
236
 
237
  $thirstylink = $this->get_thirstylink_post( $post->ID );
238
  $redirect_url = html_entity_decode( $thirstylink->get_prop( 'destination_url' ) );
268
  }
269
 
270
  /**
271
+ * Validate the cloaked url.
272
  *
273
  * @since 3.2.2
274
+ * @since 3.3.2 improved code so it will always check the link prefix and only check category when it is present and eligible.
275
  * @access private
276
  *
277
  * @return boolean True if cloaked url is valid, false otherwise.
278
  */
279
+ private function validate_cloaked_url( $thirstylink = null ) {
280
 
281
+ $cat_slug = is_object( $thirstylink ) ? $thirstylink->get_category_slug() : '';
282
+ $link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
283
+ $referrer = isset( $_SERVER[ 'REQUEST_URI' ] ) ? $_SERVER[ 'REQUEST_URI' ] : '';
284
+ $needle = '/' . $link_prefix . '/';
285
 
286
  // if setting is disabled or category slug is not defined, then return as validated.
287
+ if ( get_option( 'ta_show_cat_in_slug' ) == 'yes' && $cat_slug )
288
+ $needle .= $cat_slug . '/';
289
 
290
+ return strpos( $referrer , $needle ) !== false;
291
  }
292
 
293
  /**
314
  * Add/Recreate htaccess rule to block bots access to affiliate links.
315
  *
316
  * @since 3.1.0
317
+ * @since 3.3.2 Get blocked bots from setting value.
318
  * @access public
319
  */
320
  public function block_bots_to_access_affiliate_links_on_htaccess() {
321
 
322
  $htaccess = $this->remove_block_bots_htaccess_rules();
323
  $link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
324
+ $bots_list = apply_filters( 'ta_block_bots_on_htaccess' , $this->_helper_functions->get_blocked_bots() );
325
 
326
  // prepare new TA block bots htaccess content.
327
+ $block_bots = "\n#BEGIN Block-Bots-ThirstyAffiliates\n";
328
+ $block_bots .= "<IfModule mod_rewrite.c>\n";
329
+ $block_bots .= "RewriteEngine On\n";
330
+ $block_bots .= "RewriteCond %{HTTP_USER_AGENT} (" . $bots_list . ") [NC]\n";
331
+ $block_bots .= "RewriteRule ^" . $link_prefix . "/ - [L,F]\n";
332
+ $block_bots .= "</IfModule>\n";
333
+ $block_bots .= "#END Block-Bots-ThirstyAffiliates\n\n";
 
334
 
335
  // prepend block bots rules in the htaccess content.
336
  $htaccess = $block_bots . $htaccess;
359
  return $htaccess;
360
  }
361
 
362
+ /**
363
+ * Block bots access to affiliate links for non-apache servers.
364
+ *
365
+ * @since 3.3.3
366
+ * @access public
367
+ */
368
+ public function block_bots_non_apache_server() {
369
+
370
+ global $post;
371
+
372
+ $is_apache = strpos( $_SERVER[ 'SERVER_SOFTWARE' ] , 'Apache' ) !== false;
373
+
374
+ if ( $is_apache || ! is_object( $post ) || $post->post_type !== Plugin_Constants::AFFILIATE_LINKS_CPT || ! $this->_helper_functions->is_user_agent_bot() )
375
+ return;
376
+
377
+ $message = apply_filters( 'ta_blocked_bots_non_apache_message' , sprintf( __( "<h1>Forbidden</h1><p>You don't have permission to access %s on this server.</p>" , 'thirstyaffiliates' ) , $_SERVER[ 'REQUEST_URI' ] ) );
378
+ header( 'HTTP/1.0 403 Forbidden' );
379
+ die( $message );
380
+ }
381
+
382
 
383
 
384
 
413
  add_filter( 'pre_update_option_ta_link_prefix' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
414
  add_filter( 'pre_update_option_ta_link_prefix_custom' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
415
  add_filter( 'pre_update_option_ta_show_cat_in_slug' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
416
+ add_filter( 'pre_update_option_ta_blocked_bots' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
417
  add_action( 'ta_after_register_thirstylink_post_type' , array( $this , 'set_rewrites' ) , 1 , 1 );
418
  add_action( 'ta_after_register_thirstylink_post_type' , array( $this , 'flush_rewrite_rules' ) );
419
 
422
 
423
  // filter redirect url before redirecting
424
  add_filter( 'ta_filter_redirect_url' , array( $this , 'pass_query_string_to_destination_url' ) , 10 , 2 );
425
+
426
+ // block bots on redirect (for non-apache servers).
427
+ add_filter( 'wp' , array( $this , 'block_bots_non_apache_server' ) );
428
  }
429
  }
Models/Settings.php CHANGED
@@ -177,6 +177,42 @@ class Settings implements Model_Interface , Activatable_Interface , Initiable_In
177
 
178
  }
179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
 
182
 
@@ -309,10 +345,19 @@ class Settings implements Model_Interface , Activatable_Interface , Initiable_In
309
  ),
310
 
311
  array(
312
- 'id' => 'ta_enable_javascript_frontend_redirect',
313
- 'title' => __( "Enable Enhanced Javascript Redirect on Frontend" , 'thirstyaffiliates' ),
314
- 'desc' => __( "By default affiliate links are redirected on the server side. Enabling this will set all affiliate links to be redirected via javascript on your website's frontend. This will then improve the accuracy of the link performance report." , 'thirstyaffiliates' ),
315
  'type' => 'toggle'
 
 
 
 
 
 
 
 
 
316
  )
317
 
318
  ) ),
@@ -361,6 +406,13 @@ class Settings implements Model_Interface , Activatable_Interface , Initiable_In
361
  'type' => 'toggle'
362
  ),
363
 
 
 
 
 
 
 
 
364
  array(
365
  'id' => 'ta_link_redirect_type',
366
  'title' => __( 'Link Redirect Type (server side redirects)' , 'thirstyaffiliates' ),
@@ -673,15 +725,18 @@ class Settings implements Model_Interface , Activatable_Interface , Initiable_In
673
  * Add settings page.
674
  *
675
  * @since 3.0.0
 
676
  * @access public
677
  */
678
  public function add_settings_page() {
679
 
 
 
680
  add_submenu_page(
681
  'edit.php?post_type=thirstylink',
682
  __( 'ThirstyAffiliates Settings' , 'thirstyaffiliates' ),
683
  __( 'Settings' , 'thirstyaffiliates' ),
684
- 'manage_options',
685
  'thirsty-settings',
686
  array( $this, 'view_settings_page' )
687
  );
@@ -1987,6 +2042,9 @@ class Settings implements Model_Interface , Activatable_Interface , Initiable_In
1987
  add_action( 'ta_before_settings_form' , array( $this , 'load_key_value_option_field_type_script' ) );
1988
  add_action( 'pre_update_option_ta_link_prefix' , array( $this , 'link_prefix_post_update_callback' ) , 10 , 3 );
1989
  add_action( 'pre_update_option_ta_link_prefix_custom' , array( $this , 'link_prefix_post_update_callback' ) , 10 , 3 );
 
 
 
1990
  }
1991
 
1992
  }
177
 
178
  }
179
 
180
+ /**
181
+ * Register admin interfaces.
182
+ *
183
+ * @since 3.3.2
184
+ * @access public
185
+ *
186
+ * @param array $interfaces List of admin interfaces.
187
+ * @return array Filtered list of admin interfaces.
188
+ */
189
+ public function register_admin_interfaces( $interfaces ) {
190
+
191
+ $interfaces[ 'thirstylink_page_thirsty-settings' ] = apply_filters( 'ta_settings_admin_interface' , array(
192
+ 'ta_general_settings' => 'manage_options',
193
+ 'ta_links_settings' => 'manage_options',
194
+ 'ta_modules_settings' => 'manage_options',
195
+ 'ta_help_settings' => 'manage_options',
196
+ ) );
197
+
198
+ return $interfaces;
199
+ }
200
+
201
+ /**
202
+ * Register admin interfaces.
203
+ *
204
+ * @since 3.3.2
205
+ * @access public
206
+ *
207
+ * @param array $interfaces List of menu items.
208
+ * @return array Filtered list of menu items.
209
+ */
210
+ public function register_admin_menu_items( $menu_items ) {
211
+
212
+ $menu_items[ 'thirsty-settings' ] = 'manage_options';
213
+ return $menu_items;
214
+ }
215
+
216
 
217
 
218
 
345
  ),
346
 
347
  array(
348
+ 'id' => 'ta_disable_ip_address_collection',
349
+ 'title' => __( "Disable IP address collection" , 'thirstyaffiliates' ),
350
+ 'desc' => __( "By default ThirstyAffiliates plugin collects visitor's IP address everytime they click an affiliate link as part of the statistics information. By checking this the IP address collection will be disabled, but other information will still be saved." , 'thirstyaffiliates' ),
351
  'type' => 'toggle'
352
+ ),
353
+
354
+ array(
355
+ 'id' => 'ta_blocked_bots',
356
+ 'title' => __( "Blocked bots" , 'thirstyaffiliates' ),
357
+ 'desc' => __( "By default ThirstyAffiliates blocks bots accessing your affiliate links to give you a more appropriate data in the report. Select bots, or enter new ones to block." , 'thirstyaffiliates' ),
358
+ 'type' => 'textarea',
359
+ 'default' => Plugin_Constants::DEFAULT_BLOCKED_BOTS,
360
+
361
  )
362
 
363
  ) ),
406
  'type' => 'toggle'
407
  ),
408
 
409
+ array(
410
+ 'id' => 'ta_enable_javascript_frontend_redirect',
411
+ 'title' => __( "Enable Enhanced Javascript Redirect on Frontend" , 'thirstyaffiliates' ),
412
+ 'desc' => __( "By default affiliate links are redirected on the server side. Enabling this will set all affiliate links to be redirected via javascript on your website's frontend. This will then improve the accuracy of the link performance report." , 'thirstyaffiliates' ),
413
+ 'type' => 'toggle'
414
+ ),
415
+
416
  array(
417
  'id' => 'ta_link_redirect_type',
418
  'title' => __( 'Link Redirect Type (server side redirects)' , 'thirstyaffiliates' ),
725
  * Add settings page.
726
  *
727
  * @since 3.0.0
728
+ * @since 3.2.2 Access to the settings page will now be controlled by the plugin. see Bootstrap::admin_interface_visibility.
729
  * @access public
730
  */
731
  public function add_settings_page() {
732
 
733
+ if ( ! current_user_can( 'edit_posts' ) ) return;
734
+
735
  add_submenu_page(
736
  'edit.php?post_type=thirstylink',
737
  __( 'ThirstyAffiliates Settings' , 'thirstyaffiliates' ),
738
  __( 'Settings' , 'thirstyaffiliates' ),
739
+ 'read',
740
  'thirsty-settings',
741
  array( $this, 'view_settings_page' )
742
  );
2042
  add_action( 'ta_before_settings_form' , array( $this , 'load_key_value_option_field_type_script' ) );
2043
  add_action( 'pre_update_option_ta_link_prefix' , array( $this , 'link_prefix_post_update_callback' ) , 10 , 3 );
2044
  add_action( 'pre_update_option_ta_link_prefix_custom' , array( $this , 'link_prefix_post_update_callback' ) , 10 , 3 );
2045
+
2046
+ add_filter( 'ta_admin_interfaces' , array( $this , 'register_admin_interfaces' ) );
2047
+ add_filter( 'ta_menu_items' , array( $this , 'register_admin_menu_items' ) );
2048
  }
2049
 
2050
  }
Models/Stats_Reporting.php CHANGED
@@ -120,6 +120,53 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
120
 
121
  }
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
 
125
 
@@ -354,7 +401,8 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
354
  else {
355
 
356
  // save timezone to use
357
- $this->_browser_zone_str = isset( $_POST[ 'timezone' ] ) ? sanitize_text_field( $_POST[ 'timezone' ] ) : '';
 
358
 
359
  $link_id = isset( $_POST[ 'link_id' ] ) ? (int) sanitize_text_field( $_POST[ 'link_id' ] ) : 0;
360
  $thirstylink = new Affiliate_Link( $link_id );
@@ -399,7 +447,8 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
399
  else {
400
 
401
  // save timezone to use
402
- $this->_browser_zone_str = isset( $_POST[ 'timezone' ] ) ? sanitize_text_field( $_POST[ 'timezone' ] ) : '';
 
403
 
404
  $cpt_slug = Plugin_Constants::AFFILIATE_LINKS_CPT;
405
  $current_range = isset( $_POST[ 'range' ] ) ? sanitize_text_field( $_POST[ 'range' ] ) : '7day';
@@ -509,15 +558,19 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
509
  * Register reports menu page.
510
  *
511
  * @since 3.0.0
 
 
512
  * @access public
513
  */
514
  public function add_reports_submenu() {
515
 
 
 
516
  add_submenu_page(
517
  'edit.php?post_type=thirstylink',
518
  __( 'ThirstyAffiliates Reports' , 'thirstyaffiliates' ),
519
  __( 'Reports' , 'thirstyaffiliates' ),
520
- 'manage_options',
521
  'thirsty-reports',
522
  array( $this, 'render_reports' )
523
  );
@@ -581,6 +634,7 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
581
  * Get Link performance report content.
582
  *
583
  * @since 3.0.0
 
584
  * @access public
585
  *
586
  * @return string Link performance report content.
@@ -604,17 +658,6 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
604
  // NOTE: when false, this needs to return an empty string as it is used for display.
605
  if ( $link_id ) $link_id = ( get_post_type( $link_id ) == $cpt_slug && get_post_status( $link_id ) == 'publish' ) ? $link_id : '';
606
 
607
- // get all published affiliate link ids
608
- $query = new \WP_Query( array(
609
- 'post_type' => $cpt_slug,
610
- 'post_status' => 'publish',
611
- 'fields' => 'ids',
612
- 'posts_per_page' => -1
613
- ) );
614
-
615
- $data = $this->prepare_data_for_flot( $range , $query->posts );
616
- $total_clicks = $this->count_total_clicks_from_flot_data( $data );
617
-
618
  ob_start();
619
  include( $this->_constants->VIEWS_ROOT_PATH() . 'reports/link-performance-report.php' );
620
 
@@ -645,7 +688,7 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
645
  public function get_report_range_details( $range = '7day' , $start_date = 'now -6 days' , $end_date = 'now' ) {
646
 
647
  $data = array();
648
- $zone_str = $this->_get_report_timezone_string();
649
  $timezone = new \DateTimeZone( $zone_str );
650
  $now = new \DateTime( 'now' , $timezone );
651
 
@@ -667,6 +710,7 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
667
  $data[ 'type' ] = 'month';
668
  $data[ 'start_date' ] = new \DateTime( 'first day of this month' , $timezone );
669
  $data[ 'end_date' ] = $now;
 
670
  break;
671
 
672
  case 'custom' :
@@ -697,6 +741,7 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
697
  *
698
  * @since 3.0.0
699
  * @since 3.2.2 Change method of getting timezone sting name.
 
700
  * @access public
701
  *
702
  * @param array $range Report range details
@@ -707,13 +752,16 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
707
 
708
  $start_date = $range[ 'start_date' ];
709
  $end_date = $range[ 'end_date' ];
710
- $zone_str = $this->_get_report_timezone_string();
711
  $timezone = new \DateTimeZone( $zone_str );
 
712
  $flot_data = array();
713
 
714
  if ( apply_filters( 'ta_report_set_start_date_time_to_zero' , true , $range ) )
715
  $start_date->setTime( 0 , 0 );
716
 
 
 
717
  $raw_data = $this->get_link_performance_data( $start_date->format( 'Y-m-d H:i:s' ) , $end_date->format( 'Y-m-d H:i:s' ) , $link_ids );
718
 
719
  // get number of days difference between start and end
@@ -770,7 +818,7 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
770
  // count each click data and assign to appropriate day.
771
  foreach ( $raw_data as $click_entry ) {
772
 
773
- $click_date = new \DateTime( $click_entry->date_clicked , new \DateTimeZone( 'UTC' ) );
774
  $click_date->setTimezone( $timezone );
775
 
776
  $click_timestamp = (int) $click_date->format( 'U' );
@@ -829,7 +877,7 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
829
  */
830
  public function get_month_first_day_datetime_obj( $month ) {
831
 
832
- $zone_str = $this->_get_report_timezone_string();
833
  $timezone = new \DateTimeZone( $zone_str );
834
 
835
  return new \DateTime( 'First day of ' . $month . ' ' . date( 'Y' ) , $timezone );
@@ -893,9 +941,10 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
893
  }
894
 
895
  /**
896
- * Prevent saving click data if useragent is a bot.
897
  *
898
  * @since 3.1.0
 
899
  * @access public
900
  *
901
  * @param boolean $response Default response of filter.
@@ -903,12 +952,7 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
903
  */
904
  public function prevent_save_click_if_useragent_is_bot( $response ) {
905
 
906
- $user_agent = isset( $_SERVER[ 'HTTP_USER_AGENT' ] ) ? strtolower( $_SERVER[ 'HTTP_USER_AGENT' ] ) : '';
907
- $bots = apply_filters( 'ta_useragent_bots_phrase_list' , array( 'bot' , 'crawl' , 'slurp' , 'spider' , 'mediapartners' ) );
908
- $bots_str = implode( $bots , '|' );
909
- $pattern = '/' . $bots_str . '/i';
910
-
911
- return preg_match( $pattern , $user_agent );
912
  }
913
 
914
  /**
@@ -948,11 +992,12 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
948
  * Get timezone to use for the report.
949
  *
950
  * @since 3.2.2
951
- * @access private
 
952
  *
953
  * @return string Timezone string name.
954
  */
955
- private function _get_report_timezone_string() {
956
 
957
  return $this->_browser_zone_str ? $this->_browser_zone_str : $this->_helper_functions->get_site_current_timezone();
958
  }
@@ -1016,5 +1061,8 @@ class Stats_Reporting implements Model_Interface , Initiable_Interface , Activat
1016
  add_action( 'ta_register_reports' , array( $this , 'register_link_performance_report' ) , 10 );
1017
  add_action( Plugin_Constants::CRON_STATS_TRIMMER , array( $this , 'implement_stats_trimmer' ) );
1018
  add_action( 'before_delete_post' , array( $this , 'delete_stats_data_on_affiliate_link_deletion' ) , 10 );
 
 
 
1019
  }
1020
  }
120
 
121
  }
122
 
123
+ /**
124
+ * Update $_browser_zone_str class property value.
125
+ *
126
+ * @since 3.3.3
127
+ * @access public
128
+ *
129
+ * @param string $timezone Timezone set on browser
130
+ */
131
+ public function set_browser_zone_str( $timezone ) {
132
+
133
+ if ( in_array( $timezone , timezone_identifiers_list() ) )
134
+ $this->_browser_zone_str = $timezone;
135
+ }
136
+
137
+ /**
138
+ * Register admin interfaces.
139
+ *
140
+ * @since 3.3.2
141
+ * @access public
142
+ *
143
+ * @param array $interfaces List of admin interfaces.
144
+ * @return array Filtered list of admin interfaces.
145
+ */
146
+ public function register_admin_interfaces( $interfaces ) {
147
+
148
+ $interfaces[ 'thirstylink_page_thirsty-reports' ] = apply_filters( 'ta_reports_admin_interface' , array(
149
+ 'link_performance' => 'manage_options'
150
+ ) );
151
+
152
+ return $interfaces;
153
+ }
154
+
155
+ /**
156
+ * Register admin interfaces.
157
+ *
158
+ * @since 3.3.2
159
+ * @access public
160
+ *
161
+ * @param array $interfaces List of menu items.
162
+ * @return array Filtered list of menu items.
163
+ */
164
+ public function register_admin_menu_items( $menu_items ) {
165
+
166
+ $menu_items[ 'thirsty-reports' ] = 'manage_options';
167
+ return $menu_items;
168
+ }
169
+
170
 
171
 
172
 
401
  else {
402
 
403
  // save timezone to use
404
+ $timezone = isset( $_POST[ 'timezone' ] ) ? sanitize_text_field( $_POST[ 'timezone' ] ) : '';
405
+ $this->set_browser_zone_str( $timezone );
406
 
407
  $link_id = isset( $_POST[ 'link_id' ] ) ? (int) sanitize_text_field( $_POST[ 'link_id' ] ) : 0;
408
  $thirstylink = new Affiliate_Link( $link_id );
447
  else {
448
 
449
  // save timezone to use
450
+ $timezone = isset( $_POST[ 'timezone' ] ) ? sanitize_text_field( $_POST[ 'timezone' ] ) : '';
451
+ $this->set_browser_zone_str( $timezone );
452
 
453
  $cpt_slug = Plugin_Constants::AFFILIATE_LINKS_CPT;
454
  $current_range = isset( $_POST[ 'range' ] ) ? sanitize_text_field( $_POST[ 'range' ] ) : '7day';
558
  * Register reports menu page.
559
  *
560
  * @since 3.0.0
561
+ * @since 3.2.2 Access to the settings page will now be controlled by the plugin. see Bootstrap::admin_interface_visibility.
562
+ *
563
  * @access public
564
  */
565
  public function add_reports_submenu() {
566
 
567
+ if ( ! current_user_can( 'edit_posts' ) ) return;
568
+
569
  add_submenu_page(
570
  'edit.php?post_type=thirstylink',
571
  __( 'ThirstyAffiliates Reports' , 'thirstyaffiliates' ),
572
  __( 'Reports' , 'thirstyaffiliates' ),
573
+ 'read',
574
  'thirsty-reports',
575
  array( $this, 'render_reports' )
576
  );
634
  * Get Link performance report content.
635
  *
636
  * @since 3.0.0
637
+ * @since 3.3.2 Remove report data query on page first load.
638
  * @access public
639
  *
640
  * @return string Link performance report content.
658
  // NOTE: when false, this needs to return an empty string as it is used for display.
659
  if ( $link_id ) $link_id = ( get_post_type( $link_id ) == $cpt_slug && get_post_status( $link_id ) == 'publish' ) ? $link_id : '';
660
 
 
 
 
 
 
 
 
 
 
 
 
661
  ob_start();
662
  include( $this->_constants->VIEWS_ROOT_PATH() . 'reports/link-performance-report.php' );
663
 
688
  public function get_report_range_details( $range = '7day' , $start_date = 'now -6 days' , $end_date = 'now' ) {
689
 
690
  $data = array();
691
+ $zone_str = $this->get_report_timezone_string();
692
  $timezone = new \DateTimeZone( $zone_str );
693
  $now = new \DateTime( 'now' , $timezone );
694
 
710
  $data[ 'type' ] = 'month';
711
  $data[ 'start_date' ] = new \DateTime( 'first day of this month' , $timezone );
712
  $data[ 'end_date' ] = $now;
713
+ $data[ 'start_date' ]->setTime( 0 , 0 , 0 );
714
  break;
715
 
716
  case 'custom' :
741
  *
742
  * @since 3.0.0
743
  * @since 3.2.2 Change method of getting timezone sting name.
744
+ * @since 3.3.3 Set range timezone to UTC before fetching raw data.
745
  * @access public
746
  *
747
  * @param array $range Report range details
752
 
753
  $start_date = $range[ 'start_date' ];
754
  $end_date = $range[ 'end_date' ];
755
+ $zone_str = $this->get_report_timezone_string();
756
  $timezone = new \DateTimeZone( $zone_str );
757
+ $utc = new \DateTimeZone( 'UTC' );
758
  $flot_data = array();
759
 
760
  if ( apply_filters( 'ta_report_set_start_date_time_to_zero' , true , $range ) )
761
  $start_date->setTime( 0 , 0 );
762
 
763
+ $start_date->setTimezone( $utc );
764
+ $end_date->setTimezone( $utc );
765
  $raw_data = $this->get_link_performance_data( $start_date->format( 'Y-m-d H:i:s' ) , $end_date->format( 'Y-m-d H:i:s' ) , $link_ids );
766
 
767
  // get number of days difference between start and end
818
  // count each click data and assign to appropriate day.
819
  foreach ( $raw_data as $click_entry ) {
820
 
821
+ $click_date = new \DateTime( $click_entry->date_clicked , $utc );
822
  $click_date->setTimezone( $timezone );
823
 
824
  $click_timestamp = (int) $click_date->format( 'U' );
877
  */
878
  public function get_month_first_day_datetime_obj( $month ) {
879
 
880
+ $zone_str = $this->get_report_timezone_string();
881
  $timezone = new \DateTimeZone( $zone_str );
882
 
883
  return new \DateTime( 'First day of ' . $month . ' ' . date( 'Y' ) , $timezone );
941
  }
942
 
943
  /**
944
+ * Prevent saving click data if useragent is a bot (for non-apache servers).
945
  *
946
  * @since 3.1.0
947
+ * @since 3.3.3 Moved code to a helper function (DRY).
948
  * @access public
949
  *
950
  * @param boolean $response Default response of filter.
952
  */
953
  public function prevent_save_click_if_useragent_is_bot( $response ) {
954
 
955
+ return $this->_helper_functions->is_user_agent_bot();
 
 
 
 
 
956
  }
957
 
958
  /**
992
  * Get timezone to use for the report.
993
  *
994
  * @since 3.2.2
995
+ * @since 3.3.3 Made the method public so TAP can utilize it.
996
+ * @access public
997
  *
998
  * @return string Timezone string name.
999
  */
1000
+ public function get_report_timezone_string() {
1001
 
1002
  return $this->_browser_zone_str ? $this->_browser_zone_str : $this->_helper_functions->get_site_current_timezone();
1003
  }
1061
  add_action( 'ta_register_reports' , array( $this , 'register_link_performance_report' ) , 10 );
1062
  add_action( Plugin_Constants::CRON_STATS_TRIMMER , array( $this , 'implement_stats_trimmer' ) );
1063
  add_action( 'before_delete_post' , array( $this , 'delete_stats_data_on_affiliate_link_deletion' ) , 10 );
1064
+
1065
+ add_filter( 'ta_admin_interfaces' , array( $this , 'register_admin_interfaces' ) );
1066
+ add_filter( 'ta_menu_items' , array( $this , 'register_admin_menu_items' ) );
1067
  }
1068
  }
css/admin/ta-reports.css CHANGED
@@ -153,7 +153,6 @@ ul.chart-legend li span {
153
  font-size: 11px;
154
  }
155
  ul.chart-legend li em.count {
156
- display: none !important; /* Remove on next version of TA (3.2.2) */
157
  position: absolute;
158
  top: 50%;
159
  right: 10px;
153
  font-size: 11px;
154
  }
155
  ul.chart-legend li em.count {
 
156
  position: absolute;
157
  top: 50%;
158
  right: 10px;
js/app/ta-settings.js CHANGED
@@ -103,6 +103,26 @@ jQuery( document ).ready( function($){
103
  } );
104
 
105
  $settingsBlock.find( 'select.toggle-cat' ).trigger( 'change' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  }
107
  };
108
 
@@ -112,5 +132,6 @@ jQuery( document ).ready( function($){
112
  thirstySettings.customLinkPrefix();
113
  thirstySettings.validLinkPrefix();
114
  thirstySettings.toggleCat();
 
115
 
116
  });
103
  } );
104
 
105
  $settingsBlock.find( 'select.toggle-cat' ).trigger( 'change' );
106
+ },
107
+
108
+ /**
109
+ * Initialize block bots settings as a selectized textarea.
110
+ *
111
+ * @since 3.3.2
112
+ */
113
+ blockBotsSettings : function() {
114
+
115
+ $settingsBlock.find( '#ta_blocked_bots' ).selectize({
116
+ plugins : [ 'restore_on_backspace' , 'remove_button' , 'drag_drop' ],
117
+ delimeter : ',',
118
+ persist : false,
119
+ create : function(input) {
120
+ return {
121
+ value : input,
122
+ text : input
123
+ }
124
+ }
125
+ });
126
  }
127
  };
128
 
132
  thirstySettings.customLinkPrefix();
133
  thirstySettings.validLinkPrefix();
134
  thirstySettings.toggleCat();
135
+ thirstySettings.blockBotsSettings();
136
 
137
  });
languages/thirstyaffiliates.pot CHANGED
@@ -2,7 +2,7 @@
2
  msgid ""
3
  msgstr ""
4
  "Project-Id-Version: ThirstyAffiliates\n"
5
- "POT-Creation-Date: 2018-04-18 07:13+0800\n"
6
  "PO-Revision-Date: 2016-04-29 07:38+0800\n"
7
  "Last-Translator: \n"
8
  "Language-Team: Rymera Web Co <support@thirstyaffiliates.com>\n"
@@ -21,15 +21,15 @@ msgstr ""
21
  "X-Poedit-SearchPathExcluded-2: js/lib\n"
22
  "X-Poedit-SearchPathExcluded-3: *node_modules*\n"
23
 
24
- #: Helpers/Plugin_Constants.php:88
25
  msgid "301 Permanent"
26
  msgstr ""
27
 
28
- #: Helpers/Plugin_Constants.php:89
29
  msgid "302 Temporary"
30
  msgstr ""
31
 
32
- #: Helpers/Plugin_Constants.php:90
33
  msgid "307 Temporary (alternative)"
34
  msgstr ""
35
 
@@ -38,22 +38,22 @@ msgid "Unable to save affiliate link as there are no changes registered on the o
38
  msgstr ""
39
 
40
  #: Models/Affiliate_Link_Attachment.php:130
41
- #: Models/Affiliate_Link_Attachment.php:200 Models/Affiliate_Links_CPT.php:857
42
- #: Models/Affiliate_Links_CPT.php:882 Models/Guided_Tour.php:313
43
  #: Models/Link_Fixer.php:216 Models/Link_Fixer.php:218
44
  #: Models/Link_Picker.php:279 Models/Link_Picker.php:337
45
  #: Models/Link_Picker.php:457 Models/Marketing.php:175 Models/Marketing.php:300
46
- #: Models/Marketing.php:445 Models/Settings.php:1791 Models/Settings.php:1839
47
- #: Models/Stats_Reporting.php:351 Models/Stats_Reporting.php:396
48
  msgid "Invalid AJAX call"
49
  msgstr ""
50
 
51
  #: Models/Affiliate_Link_Attachment.php:132
52
- #: Models/Affiliate_Link_Attachment.php:202 Models/Affiliate_Links_CPT.php:859
53
- #: Models/Affiliate_Links_CPT.php:884 Models/Link_Picker.php:281
54
  #: Models/Link_Picker.php:339 Models/Link_Picker.php:459
55
- #: Models/Marketing.php:302 Models/Stats_Reporting.php:353
56
- #: Models/Stats_Reporting.php:398
57
  msgid "Missing required post data"
58
  msgstr ""
59
 
@@ -73,196 +73,200 @@ msgstr ""
73
  msgid "Invalid attachment id to remove from an affiliate link"
74
  msgstr ""
75
 
76
- #: Models/Affiliate_Links_CPT.php:159 Models/Affiliate_Links_CPT.php:163
77
- #: Models/Affiliate_Links_CPT.php:175
78
  msgid "Affiliate Links"
79
  msgstr ""
80
 
81
- #: Models/Affiliate_Links_CPT.php:160
82
  msgid "Affiliate Link"
83
  msgstr ""
84
 
85
- #: Models/Affiliate_Links_CPT.php:161
86
  msgid "ThirstyAffiliates"
87
  msgstr ""
88
 
89
- #: Models/Affiliate_Links_CPT.php:162
90
  msgid "Parent Affiliate Link"
91
  msgstr ""
92
 
93
- #: Models/Affiliate_Links_CPT.php:164
94
  msgid "View Affiliate Link"
95
  msgstr ""
96
 
97
- #: Models/Affiliate_Links_CPT.php:165
98
  msgid "Add Affiliate Link"
99
  msgstr ""
100
 
101
- #: Models/Affiliate_Links_CPT.php:166
102
  msgid "New Affiliate Link"
103
  msgstr ""
104
 
105
- #: Models/Affiliate_Links_CPT.php:167
106
  msgid "Edit Affiliate Link"
107
  msgstr ""
108
 
109
- #: Models/Affiliate_Links_CPT.php:168
110
  msgid "Update Affiliate Link"
111
  msgstr ""
112
 
113
- #: Models/Affiliate_Links_CPT.php:169
114
  msgid "Search Affiliate Links"
115
  msgstr ""
116
 
117
- #: Models/Affiliate_Links_CPT.php:170
118
  msgid "No Affiliate Link found"
119
  msgstr ""
120
 
121
- #: Models/Affiliate_Links_CPT.php:171
122
  msgid "No Affiliate Links found in Trash"
123
  msgstr ""
124
 
125
- #: Models/Affiliate_Links_CPT.php:176
126
  msgid "ThirstyAffiliates affiliate links"
127
  msgstr ""
128
 
129
- #: Models/Affiliate_Links_CPT.php:223 Models/Affiliate_Links_CPT.php:225
130
  #: views/linkpicker/quick-add-affiliate-link.php:72
131
  msgid "Link Categories"
132
  msgstr ""
133
 
134
- #: Models/Affiliate_Links_CPT.php:224
135
  msgid "Link Category"
136
  msgstr ""
137
 
138
- #: Models/Affiliate_Links_CPT.php:226
139
  msgid "All Categories"
140
  msgstr ""
141
 
142
- #: Models/Affiliate_Links_CPT.php:227
143
  msgid "Parent Category"
144
  msgstr ""
145
 
146
- #: Models/Affiliate_Links_CPT.php:228
147
  msgid "Parent Category:"
148
  msgstr ""
149
 
150
- #: Models/Affiliate_Links_CPT.php:229
151
  msgid "New Category Name"
152
  msgstr ""
153
 
154
- #: Models/Affiliate_Links_CPT.php:230
155
  msgid "Add New Category"
156
  msgstr ""
157
 
158
- #: Models/Affiliate_Links_CPT.php:231
159
  msgid "Edit Category"
160
  msgstr ""
161
 
162
- #: Models/Affiliate_Links_CPT.php:232
163
  msgid "Update Category"
164
  msgstr ""
165
 
166
- #: Models/Affiliate_Links_CPT.php:233
167
  msgid "View Category"
168
  msgstr ""
169
 
170
- #: Models/Affiliate_Links_CPT.php:234
171
  msgid "Separate items with commas"
172
  msgstr ""
173
 
174
- #: Models/Affiliate_Links_CPT.php:235
175
  msgid "Add or remove items"
176
  msgstr ""
177
 
178
- #: Models/Affiliate_Links_CPT.php:236
179
  msgid "Choose from the most used"
180
  msgstr ""
181
 
182
- #: Models/Affiliate_Links_CPT.php:237
183
  msgid "Popular Categories"
184
  msgstr ""
185
 
186
- #: Models/Affiliate_Links_CPT.php:238
187
  msgid "Search Categories"
188
  msgstr ""
189
 
190
- #: Models/Affiliate_Links_CPT.php:239
191
  msgid "Not Found"
192
  msgstr ""
193
 
194
- #: Models/Affiliate_Links_CPT.php:240
195
  msgid "No items"
196
  msgstr ""
197
 
198
- #: Models/Affiliate_Links_CPT.php:241
199
  msgid "Category list"
200
  msgstr ""
201
 
202
- #: Models/Affiliate_Links_CPT.php:242
203
  msgid "Category list navigation"
204
  msgstr ""
205
 
206
- #: Models/Affiliate_Links_CPT.php:282
207
  msgid "Link ID:"
208
  msgstr ""
209
 
210
- #: Models/Affiliate_Links_CPT.php:298
211
  msgid "URLs"
212
  msgstr ""
213
 
214
- #: Models/Affiliate_Links_CPT.php:305
215
  msgid "Attach Images"
216
  msgstr ""
217
 
218
- #: Models/Affiliate_Links_CPT.php:312
219
  msgid "Link Inserted Scanner"
220
  msgstr ""
221
 
222
- #: Models/Affiliate_Links_CPT.php:322
223
  msgid "Save Affiliate Link"
224
  msgstr ""
225
 
226
- #: Models/Affiliate_Links_CPT.php:329
227
  msgid "Link Options"
228
  msgstr ""
229
 
230
- #: Models/Affiliate_Links_CPT.php:460
231
  msgid "Not yet scanned"
232
  msgstr ""
233
 
234
- #: Models/Affiliate_Links_CPT.php:465 Models/Affiliate_Links_CPT.php:896
235
  msgid "Last scanned on:"
236
  msgstr ""
237
 
238
- #: Models/Affiliate_Links_CPT.php:485
239
  msgid "No results found."
240
  msgstr ""
241
 
242
- #: Models/Affiliate_Links_CPT.php:616
243
  msgid "Link ID"
244
  msgstr ""
245
 
246
- #: Models/Affiliate_Links_CPT.php:617
247
  msgid "Redirect Type"
248
  msgstr ""
249
 
250
- #: Models/Affiliate_Links_CPT.php:618
251
  msgid "Cloaked URL"
252
  msgstr ""
253
 
254
- #: Models/Affiliate_Links_CPT.php:619
255
  msgid "Link Destination"
256
  msgstr ""
257
 
258
- #: Models/Affiliate_Links_CPT.php:751
259
  msgid "Show Link Categories"
260
  msgstr ""
261
 
262
- #: Models/Bootstrap.php:389 Models/Settings.php:683
263
  msgid "Settings"
264
  msgstr ""
265
 
 
 
 
 
266
  #: Models/Guided_Tour.php:151
267
  msgid ""
268
  "<h3>Congratulations, you just activated ThirstyAffiliates!</h3>\n"
@@ -370,7 +374,7 @@ msgstr ""
370
  msgid "No affiliate links found"
371
  msgstr ""
372
 
373
- #: Models/Marketing.php:177 Models/Settings.php:1841
374
  msgid "Required parameter not passed"
375
  msgstr ""
376
 
@@ -457,6 +461,11 @@ msgstr ""
457
  msgid "<b>ThirstyAffiliates is currently migrating your old affiliate link data to the new data model.<br>Please hold off making changes to your affiliate links. Please refresh the page and if this message has disappeared, the migration is complete.</b>"
458
  msgstr ""
459
 
 
 
 
 
 
460
  #: Models/Script_Loader.php:145
461
  msgid "affiliate link"
462
  msgstr ""
@@ -517,7 +526,7 @@ msgstr ""
517
  msgid "Start Tour"
518
  msgstr ""
519
 
520
- #: Models/Settings.php:229 views/cpt/view-link-options-metabox.php:12
521
  #: views/cpt/view-link-options-metabox.php:24
522
  #: views/cpt/view-link-options-metabox.php:36
523
  #: views/cpt/view-link-options-metabox.php:49
@@ -526,7 +535,7 @@ msgstr ""
526
  msgid "Yes"
527
  msgstr ""
528
 
529
- #: Models/Settings.php:230 views/cpt/view-link-options-metabox.php:13
530
  #: views/cpt/view-link-options-metabox.php:25
531
  #: views/cpt/view-link-options-metabox.php:37
532
  #: views/cpt/view-link-options-metabox.php:50
@@ -535,384 +544,400 @@ msgstr ""
535
  msgid "No"
536
  msgstr ""
537
 
538
- #: Models/Settings.php:231
539
  msgid "Per category"
540
  msgstr ""
541
 
542
- #: Models/Settings.php:237 views/reports/link-performance-report.php:39
543
  #: views/reports/link-performance-report.php:80
544
  msgid "General"
545
  msgstr ""
546
 
547
- #: Models/Settings.php:238
548
  msgid "Settings that change the general behaviour of ThirstyAffiliates."
549
  msgstr ""
550
 
551
- #: Models/Settings.php:241
552
  msgid "Link Appearance"
553
  msgstr ""
554
 
555
- #: Models/Settings.php:242
556
  msgid "Settings that specifically affect the behaviour & appearance of your affiliate links."
557
  msgstr ""
558
 
559
- #: Models/Settings.php:245
560
  msgid "Modules"
561
  msgstr ""
562
 
563
- #: Models/Settings.php:246
564
  msgid "This section allows you to turn certain parts of ThirstyAffiliates on or off. Below are the individual modules and features of the plugin that can be controlled."
565
  msgstr ""
566
 
567
- #: Models/Settings.php:249
568
  msgid "Import/Export"
569
  msgstr ""
570
 
571
- #: Models/Settings.php:250
572
  msgid "Import and Export global ThirstyAffiliates plugin settings from one site to another."
573
  msgstr ""
574
 
575
- #: Models/Settings.php:253
576
  msgid "Help"
577
  msgstr ""
578
 
579
- #: Models/Settings.php:254
580
  msgid "Links to knowledge base and other utilities."
581
  msgstr ""
582
 
583
- #: Models/Settings.php:263
584
  msgid "Default Link Insertion Type"
585
  msgstr ""
586
 
587
- #: Models/Settings.php:264
588
  msgid "Determines the default link type when inserting a link using the quick search."
589
  msgstr ""
590
 
591
- #: Models/Settings.php:268
592
  msgid "Link"
593
  msgstr ""
594
 
595
- #: Models/Settings.php:269
596
  msgid "Shortcode"
597
  msgstr ""
598
 
599
- #: Models/Settings.php:275
600
  msgid "Disable \"uncategorized\" category on save?"
601
  msgstr ""
602
 
603
- #: Models/Settings.php:276
604
  msgid "If links are including categories in the URL then by default ThirstyAffiliates will add an \"uncategorized\" category to apply to non-categorised links during save. If you disable this, it allows you to have some links with categories in the URL and some without."
605
  msgstr ""
606
 
607
- #: Models/Settings.php:282
608
  msgid "Disable buttons on the Visual editor?"
609
  msgstr ""
610
 
611
- #: Models/Settings.php:283
612
  msgid "Hide the ThirstyAffiliates buttons on the Visual editor."
613
  msgstr ""
614
 
615
- #: Models/Settings.php:289
616
  msgid "Disable buttons on the Text/Quicktags editor?"
617
  msgstr ""
618
 
619
- #: Models/Settings.php:290
620
  msgid "Hide the ThirstyAffiliates buttons on the Text editor."
621
  msgstr ""
622
 
623
- #: Models/Settings.php:296
624
  msgid "Trim stats older than:"
625
  msgstr ""
626
 
627
- #: Models/Settings.php:297
628
  msgid "months (Automatically clean the statistics database records older than a set point. Setting this to 0 will disable it)."
629
  msgstr ""
630
 
631
- #: Models/Settings.php:306
632
  msgid "Don't cache 301 redirects? (server side redirects)"
633
  msgstr ""
634
 
635
- #: Models/Settings.php:307
636
  msgid "By default, browsers caches the 301 redirects. Enabling this option will tell the browser not to cache 301 redirects. Be aware that it is still up to the browser if it will cache it or not."
637
  msgstr ""
638
 
639
- #: Models/Settings.php:313
640
- msgid "Enable Enhanced Javascript Redirect on Frontend"
641
  msgstr ""
642
 
643
- #: Models/Settings.php:314
644
- msgid "By default affiliate links are redirected on the server side. Enabling this will set all affiliate links to be redirected via javascript on your website's frontend. This will then improve the accuracy of the link performance report."
 
 
 
 
 
 
 
 
645
  msgstr ""
646
 
647
- #: Models/Settings.php:323
648
  msgid "Link Prefix"
649
  msgstr ""
650
 
651
- #: Models/Settings.php:324
652
  #, php-format
653
  msgid "The prefix that comes before your cloaked link's slug. <br>eg. %s/<strong>recommends</strong>/your-affiliate-link-name.<br><br><b>Warning :</b> Changing this setting after you've used links in a post could break those links. Be careful!"
654
  msgstr ""
655
 
656
- #: Models/Settings.php:352
657
  msgid "Custom Link Prefix"
658
  msgstr ""
659
 
660
- #: Models/Settings.php:353
661
  msgid "Enter your preferred link prefix."
662
  msgstr ""
663
 
664
- #: Models/Settings.php:359
665
  msgid "Link Category in URL?"
666
  msgstr ""
667
 
668
- #: Models/Settings.php:360
669
  #, php-format
670
  msgid "Shows the primary selected category in the url. eg. %s/recommends/<strong>link-category</strong>/your-affiliate-link-name.<br><br><b>Warning :</b> Changing this setting after you've used links in a post could break those links. Be careful!"
671
  msgstr ""
672
 
673
- #: Models/Settings.php:366
 
 
 
 
 
 
 
 
674
  msgid "Link Redirect Type (server side redirects)"
675
  msgstr ""
676
 
677
- #: Models/Settings.php:367
678
  msgid "This is the type of redirect ThirstyAffiliates will use to redirect the user to your affiliate link."
679
  msgstr ""
680
 
681
- #: Models/Settings.php:375
682
  msgid "Use no follow on links? (server side redirects)"
683
  msgstr ""
684
 
685
- #: Models/Settings.php:376
686
  msgid "Add the nofollow attribute to links so search engines don't index them."
687
  msgstr ""
688
 
689
- #: Models/Settings.php:385
690
  msgid "No follow categories (server side redirects)"
691
  msgstr ""
692
 
693
- #: Models/Settings.php:386
694
  msgid "The links assigned to the selected category will be set as \"no follow\"."
695
  msgstr ""
696
 
697
- #: Models/Settings.php:390 Models/Settings.php:412 Models/Settings.php:434
698
- #: Models/Settings.php:468
699
  msgid "Select category..."
700
  msgstr ""
701
 
702
- #: Models/Settings.php:397
703
  msgid "Open links in new window?"
704
  msgstr ""
705
 
706
- #: Models/Settings.php:398
707
  msgid "Make links open in a new browser tab by default."
708
  msgstr ""
709
 
710
- #: Models/Settings.php:407
711
  msgid "New window categories"
712
  msgstr ""
713
 
714
- #: Models/Settings.php:408
715
  msgid "The links assigned to the selected category will be set as \"new window\"."
716
  msgstr ""
717
 
718
- #: Models/Settings.php:419
719
  msgid "Pass query strings to destination url?"
720
  msgstr ""
721
 
722
- #: Models/Settings.php:420
723
  msgid "Enabling this option will pass all of the query strings present after the cloaked url to the destination url automatically when redirecting."
724
  msgstr ""
725
 
726
- #: Models/Settings.php:429
727
  msgid "Pass query strings categories"
728
  msgstr ""
729
 
730
- #: Models/Settings.php:430
731
  msgid "The links assigned to the selected category will be set as \"pass query strings\"."
732
  msgstr ""
733
 
734
- #: Models/Settings.php:441
735
  msgid "Additional rel attribute tags"
736
  msgstr ""
737
 
738
- #: Models/Settings.php:442
739
  msgid "Allows you to add extra tags into the rel= attribute when links are inserted."
740
  msgstr ""
741
 
742
- #: Models/Settings.php:448
743
  msgid "Disable ThirstyAffiliates CSS classes?"
744
  msgstr ""
745
 
746
- #: Models/Settings.php:449
747
  msgid "To help with styling a CSS class called \"thirstylink\" is added links on insertion.<br>Likewise the \"thirstylinkimg\" class is added to images when using the image insertion type. This option disables the addition these CSS classes."
748
  msgstr ""
749
 
750
- #: Models/Settings.php:455
751
  msgid "Disable title attribute on link insertion?"
752
  msgstr ""
753
 
754
- #: Models/Settings.php:456
755
  msgid "Links are automatically output with a title html attribute (by default this shows the title of the affiliate link).<br>This option disables the output of the title attribute on your links."
756
  msgstr ""
757
 
758
- #: Models/Settings.php:462
759
  msgid "Select Category to Uncloak"
760
  msgstr ""
761
 
762
- #: Models/Settings.php:463
763
  msgid "The links assigned to the selected category will be uncloaked."
764
  msgstr ""
765
 
766
- #: Models/Settings.php:477
767
  msgid "Statistics"
768
  msgstr ""
769
 
770
- #: Models/Settings.php:478
771
  msgid "When enabled, ThirstyAffiliates will collect click statistics information about visitors that click on your affiliate links. Also adds a new Reports section."
772
  msgstr ""
773
 
774
- #: Models/Settings.php:485
775
  msgid "Link Fixer"
776
  msgstr ""
777
 
778
- #: Models/Settings.php:486
779
  msgid "Link Fixer is a tiny piece of javascript code that runs on the frontend of your site to fix any outdated/broken affiliate links it detects. It's cache-friendly and runs after page load so it doesn't affect the rendering of content. Changed the settings on your site recently? Enabling Link Fixer means you don't need to update all your previously inserted affiliate links one by one – your visitors will never see an out of date affiliate link again."
780
  msgstr ""
781
 
782
- #: Models/Settings.php:493
783
  msgid "Uncloak Links"
784
  msgstr ""
785
 
786
- #: Models/Settings.php:494
787
  msgid "Uncloak Links is a feature to allow uncloaking of specific links on your site. It replaces the cloaked url with the actual destination url which is important for compatibility with some affiliate program with stricter terms (such as Amazon Associates). Once enabled, you will see a new Uncloak Link checkbox on the affiliate link edit screen. It also introduces a new setting under the Links tab for uncloaking whole categories.<br><br><b>Warning : </b>For this feature to work, the <strong>Link Fixer</strong> module needs to be turned on."
788
  msgstr ""
789
 
790
- #: Models/Settings.php:504
791
  msgid "Import Global Settings"
792
  msgstr ""
793
 
794
- #: Models/Settings.php:506
795
  msgid "Paste settings string here..."
796
  msgstr ""
797
 
798
- #: Models/Settings.php:511
799
  msgid "Export Global Settings"
800
  msgstr ""
801
 
802
- #: Models/Settings.php:520 Models/Settings.php:528
803
  msgid "Knowledge Base"
804
  msgstr ""
805
 
806
- #: Models/Settings.php:525
807
  msgid "Documentation"
808
  msgstr ""
809
 
810
- #: Models/Settings.php:529
811
  msgid "Guides, troubleshooting, FAQ and more."
812
  msgstr ""
813
 
814
- #: Models/Settings.php:534
815
  msgid "Our Blog"
816
  msgstr ""
817
 
818
- #: Models/Settings.php:537
819
  msgid "ThirstyAffiliates Blog"
820
  msgstr ""
821
 
822
- #: Models/Settings.php:538
823
  msgid "Learn & grow your affiliate marketing – covering increasing sales, generating traffic, optimising your affiliate marketing, interviews & case studies."
824
  msgstr ""
825
 
826
- #: Models/Settings.php:543
827
  msgid "Join the Community"
828
  msgstr ""
829
 
830
- #: Models/Settings.php:550
831
  msgid "Other Utilities"
832
  msgstr ""
833
 
834
- #: Models/Settings.php:555
835
  msgid "Migrate Old Data"
836
  msgstr ""
837
 
838
- #: Models/Settings.php:557
839
  msgid "Migrate old ThirstyAffiliates version 2 data to new version 3 data model."
840
  msgstr ""
841
 
842
- #: Models/Settings.php:682 Models/Settings.php:703
843
  msgid "ThirstyAffiliates Settings"
844
  msgstr ""
845
 
846
- #: Models/Settings.php:720
847
  msgid "Pro Features →"
848
  msgstr ""
849
 
850
- #: Models/Settings.php:846
851
  msgid "Save Changes"
852
  msgstr ""
853
 
854
- #: Models/Settings.php:1355
855
  msgid "Key"
856
  msgstr ""
857
 
858
- #: Models/Settings.php:1356
859
  msgid "Value"
860
  msgstr ""
861
 
862
- #: Models/Settings.php:1479
863
  msgid "Another application is currently processing the database. Please wait for this to complete."
864
  msgstr ""
865
 
866
- #: Models/Settings.php:1489
867
  msgid "Migrate"
868
  msgstr ""
869
 
870
- #: Models/Settings.php:1492
871
  msgid "Migrating data. Please wait..."
872
  msgstr ""
873
 
874
- #: Models/Settings.php:1523
875
  msgid "Like us on Facebook"
876
  msgstr ""
877
 
878
- #: Models/Settings.php:1527
879
  msgid "Follow us on Twitter"
880
  msgstr ""
881
 
882
- #: Models/Settings.php:1531
883
  msgid "Follow us on Linkedin"
884
  msgstr ""
885
 
886
- #: Models/Settings.php:1534
887
  msgid "Join Our Affiliate Program"
888
  msgstr ""
889
 
890
- #: Models/Settings.php:1535
891
  #, php-format
892
  msgid "(up to 30% commisions)"
893
  msgstr ""
894
 
895
- #: Models/Settings.php:1568
896
  msgid "Copy"
897
  msgstr ""
898
 
899
- #: Models/Settings.php:1605
900
  msgid "Import Settings"
901
  msgstr ""
902
 
903
- #: Models/Settings.php:1820
904
  msgid "Unauthorized operation. Only authorized accounts can access global plugin settings string"
905
  msgstr ""
906
 
907
- #: Models/Settings.php:1849
908
  msgid "Settings successfully imported"
909
  msgstr ""
910
 
911
- #: Models/Settings.php:1871
912
  msgid "Unauthorized operation. Only authorized accounts can import settings"
913
  msgstr ""
914
 
915
- #: Models/Settings.php:1876
916
  msgid "Invalid global settings string"
917
  msgstr ""
918
 
@@ -920,43 +945,43 @@ msgstr ""
920
  msgid "SHORTCODE ERROR: ThirstyAffiliates did not detect a valid link id, please check your short code!"
921
  msgstr ""
922
 
923
- #: Models/Stats_Reporting.php:366
924
  msgid "Selected affiliate link is invalid"
925
  msgstr ""
926
 
927
- #: Models/Stats_Reporting.php:490
928
  msgid "Link Overview"
929
  msgstr ""
930
 
931
- #: Models/Stats_Reporting.php:491
932
  msgid "Link Overview Report"
933
  msgstr ""
934
 
935
- #: Models/Stats_Reporting.php:492
936
  msgid "Total clicks on affiliate links over a given period."
937
  msgstr ""
938
 
939
- #: Models/Stats_Reporting.php:518
940
  msgid "ThirstyAffiliates Reports"
941
  msgstr ""
942
 
943
- #: Models/Stats_Reporting.php:519
944
  msgid "Reports"
945
  msgstr ""
946
 
947
- #: Models/Stats_Reporting.php:597
948
  msgid "Year"
949
  msgstr ""
950
 
951
- #: Models/Stats_Reporting.php:598
952
  msgid "Last Month"
953
  msgstr ""
954
 
955
- #: Models/Stats_Reporting.php:599
956
  msgid "This Month"
957
  msgstr ""
958
 
959
- #: Models/Stats_Reporting.php:600
960
  msgid "Last 7 Days"
961
  msgstr ""
962
 
2
  msgid ""
3
  msgstr ""
4
  "Project-Id-Version: ThirstyAffiliates\n"
5
+ "POT-Creation-Date: 2018-06-19 06:41+0800\n"
6
  "PO-Revision-Date: 2016-04-29 07:38+0800\n"
7
  "Last-Translator: \n"
8
  "Language-Team: Rymera Web Co <support@thirstyaffiliates.com>\n"
21
  "X-Poedit-SearchPathExcluded-2: js/lib\n"
22
  "X-Poedit-SearchPathExcluded-3: *node_modules*\n"
23
 
24
+ #: Helpers/Plugin_Constants.php:89
25
  msgid "301 Permanent"
26
  msgstr ""
27
 
28
+ #: Helpers/Plugin_Constants.php:90
29
  msgid "302 Temporary"
30
  msgstr ""
31
 
32
+ #: Helpers/Plugin_Constants.php:91
33
  msgid "307 Temporary (alternative)"
34
  msgstr ""
35
 
38
  msgstr ""
39
 
40
  #: Models/Affiliate_Link_Attachment.php:130
41
+ #: Models/Affiliate_Link_Attachment.php:200 Models/Affiliate_Links_CPT.php:898
42
+ #: Models/Affiliate_Links_CPT.php:923 Models/Guided_Tour.php:313
43
  #: Models/Link_Fixer.php:216 Models/Link_Fixer.php:218
44
  #: Models/Link_Picker.php:279 Models/Link_Picker.php:337
45
  #: Models/Link_Picker.php:457 Models/Marketing.php:175 Models/Marketing.php:300
46
+ #: Models/Marketing.php:445 Models/Settings.php:1846 Models/Settings.php:1894
47
+ #: Models/Stats_Reporting.php:398 Models/Stats_Reporting.php:444
48
  msgid "Invalid AJAX call"
49
  msgstr ""
50
 
51
  #: Models/Affiliate_Link_Attachment.php:132
52
+ #: Models/Affiliate_Link_Attachment.php:202 Models/Affiliate_Links_CPT.php:900
53
+ #: Models/Affiliate_Links_CPT.php:925 Models/Link_Picker.php:281
54
  #: Models/Link_Picker.php:339 Models/Link_Picker.php:459
55
+ #: Models/Marketing.php:302 Models/Stats_Reporting.php:400
56
+ #: Models/Stats_Reporting.php:446
57
  msgid "Missing required post data"
58
  msgstr ""
59
 
73
  msgid "Invalid attachment id to remove from an affiliate link"
74
  msgstr ""
75
 
76
+ #: Models/Affiliate_Links_CPT.php:199 Models/Affiliate_Links_CPT.php:203
77
+ #: Models/Affiliate_Links_CPT.php:215
78
  msgid "Affiliate Links"
79
  msgstr ""
80
 
81
+ #: Models/Affiliate_Links_CPT.php:200
82
  msgid "Affiliate Link"
83
  msgstr ""
84
 
85
+ #: Models/Affiliate_Links_CPT.php:201
86
  msgid "ThirstyAffiliates"
87
  msgstr ""
88
 
89
+ #: Models/Affiliate_Links_CPT.php:202
90
  msgid "Parent Affiliate Link"
91
  msgstr ""
92
 
93
+ #: Models/Affiliate_Links_CPT.php:204
94
  msgid "View Affiliate Link"
95
  msgstr ""
96
 
97
+ #: Models/Affiliate_Links_CPT.php:205
98
  msgid "Add Affiliate Link"
99
  msgstr ""
100
 
101
+ #: Models/Affiliate_Links_CPT.php:206
102
  msgid "New Affiliate Link"
103
  msgstr ""
104
 
105
+ #: Models/Affiliate_Links_CPT.php:207
106
  msgid "Edit Affiliate Link"
107
  msgstr ""
108
 
109
+ #: Models/Affiliate_Links_CPT.php:208
110
  msgid "Update Affiliate Link"
111
  msgstr ""
112
 
113
+ #: Models/Affiliate_Links_CPT.php:209
114
  msgid "Search Affiliate Links"
115
  msgstr ""
116
 
117
+ #: Models/Affiliate_Links_CPT.php:210
118
  msgid "No Affiliate Link found"
119
  msgstr ""
120
 
121
+ #: Models/Affiliate_Links_CPT.php:211
122
  msgid "No Affiliate Links found in Trash"
123
  msgstr ""
124
 
125
+ #: Models/Affiliate_Links_CPT.php:216
126
  msgid "ThirstyAffiliates affiliate links"
127
  msgstr ""
128
 
129
+ #: Models/Affiliate_Links_CPT.php:261 Models/Affiliate_Links_CPT.php:263
130
  #: views/linkpicker/quick-add-affiliate-link.php:72
131
  msgid "Link Categories"
132
  msgstr ""
133
 
134
+ #: Models/Affiliate_Links_CPT.php:262
135
  msgid "Link Category"
136
  msgstr ""
137
 
138
+ #: Models/Affiliate_Links_CPT.php:264
139
  msgid "All Categories"
140
  msgstr ""
141
 
142
+ #: Models/Affiliate_Links_CPT.php:265
143
  msgid "Parent Category"
144
  msgstr ""
145
 
146
+ #: Models/Affiliate_Links_CPT.php:266
147
  msgid "Parent Category:"
148
  msgstr ""
149
 
150
+ #: Models/Affiliate_Links_CPT.php:267
151
  msgid "New Category Name"
152
  msgstr ""
153
 
154
+ #: Models/Affiliate_Links_CPT.php:268
155
  msgid "Add New Category"
156
  msgstr ""
157
 
158
+ #: Models/Affiliate_Links_CPT.php:269
159
  msgid "Edit Category"
160
  msgstr ""
161
 
162
+ #: Models/Affiliate_Links_CPT.php:270
163
  msgid "Update Category"
164
  msgstr ""
165
 
166
+ #: Models/Affiliate_Links_CPT.php:271
167
  msgid "View Category"
168
  msgstr ""
169
 
170
+ #: Models/Affiliate_Links_CPT.php:272
171
  msgid "Separate items with commas"
172
  msgstr ""
173
 
174
+ #: Models/Affiliate_Links_CPT.php:273
175
  msgid "Add or remove items"
176
  msgstr ""
177
 
178
+ #: Models/Affiliate_Links_CPT.php:274
179
  msgid "Choose from the most used"
180
  msgstr ""
181
 
182
+ #: Models/Affiliate_Links_CPT.php:275
183
  msgid "Popular Categories"
184
  msgstr ""
185
 
186
+ #: Models/Affiliate_Links_CPT.php:276
187
  msgid "Search Categories"
188
  msgstr ""
189
 
190
+ #: Models/Affiliate_Links_CPT.php:277
191
  msgid "Not Found"
192
  msgstr ""
193
 
194
+ #: Models/Affiliate_Links_CPT.php:278
195
  msgid "No items"
196
  msgstr ""
197
 
198
+ #: Models/Affiliate_Links_CPT.php:279
199
  msgid "Category list"
200
  msgstr ""
201
 
202
+ #: Models/Affiliate_Links_CPT.php:280
203
  msgid "Category list navigation"
204
  msgstr ""
205
 
206
+ #: Models/Affiliate_Links_CPT.php:323
207
  msgid "Link ID:"
208
  msgstr ""
209
 
210
+ #: Models/Affiliate_Links_CPT.php:339
211
  msgid "URLs"
212
  msgstr ""
213
 
214
+ #: Models/Affiliate_Links_CPT.php:346
215
  msgid "Attach Images"
216
  msgstr ""
217
 
218
+ #: Models/Affiliate_Links_CPT.php:353
219
  msgid "Link Inserted Scanner"
220
  msgstr ""
221
 
222
+ #: Models/Affiliate_Links_CPT.php:363
223
  msgid "Save Affiliate Link"
224
  msgstr ""
225
 
226
+ #: Models/Affiliate_Links_CPT.php:370
227
  msgid "Link Options"
228
  msgstr ""
229
 
230
+ #: Models/Affiliate_Links_CPT.php:501
231
  msgid "Not yet scanned"
232
  msgstr ""
233
 
234
+ #: Models/Affiliate_Links_CPT.php:506 Models/Affiliate_Links_CPT.php:937
235
  msgid "Last scanned on:"
236
  msgstr ""
237
 
238
+ #: Models/Affiliate_Links_CPT.php:526
239
  msgid "No results found."
240
  msgstr ""
241
 
242
+ #: Models/Affiliate_Links_CPT.php:657
243
  msgid "Link ID"
244
  msgstr ""
245
 
246
+ #: Models/Affiliate_Links_CPT.php:658
247
  msgid "Redirect Type"
248
  msgstr ""
249
 
250
+ #: Models/Affiliate_Links_CPT.php:659
251
  msgid "Cloaked URL"
252
  msgstr ""
253
 
254
+ #: Models/Affiliate_Links_CPT.php:660
255
  msgid "Link Destination"
256
  msgstr ""
257
 
258
+ #: Models/Affiliate_Links_CPT.php:792
259
  msgid "Show Link Categories"
260
  msgstr ""
261
 
262
+ #: Models/Bootstrap.php:389 Models/Settings.php:738
263
  msgid "Settings"
264
  msgstr ""
265
 
266
+ #: Models/Bootstrap.php:426
267
+ msgid "xxSorry, you are not allowed to access this page."
268
+ msgstr ""
269
+
270
  #: Models/Guided_Tour.php:151
271
  msgid ""
272
  "<h3>Congratulations, you just activated ThirstyAffiliates!</h3>\n"
374
  msgid "No affiliate links found"
375
  msgstr ""
376
 
377
+ #: Models/Marketing.php:177 Models/Settings.php:1896
378
  msgid "Required parameter not passed"
379
  msgstr ""
380
 
461
  msgid "<b>ThirstyAffiliates is currently migrating your old affiliate link data to the new data model.<br>Please hold off making changes to your affiliate links. Please refresh the page and if this message has disappeared, the migration is complete.</b>"
462
  msgstr ""
463
 
464
+ #: Models/Rewrites_Redirection.php:377
465
+ #, php-format
466
+ msgid "<h1>Forbidden</h1><p>You don't have permission to access %s on this server.</p>"
467
+ msgstr ""
468
+
469
  #: Models/Script_Loader.php:145
470
  msgid "affiliate link"
471
  msgstr ""
526
  msgid "Start Tour"
527
  msgstr ""
528
 
529
+ #: Models/Settings.php:265 views/cpt/view-link-options-metabox.php:12
530
  #: views/cpt/view-link-options-metabox.php:24
531
  #: views/cpt/view-link-options-metabox.php:36
532
  #: views/cpt/view-link-options-metabox.php:49
535
  msgid "Yes"
536
  msgstr ""
537
 
538
+ #: Models/Settings.php:266 views/cpt/view-link-options-metabox.php:13
539
  #: views/cpt/view-link-options-metabox.php:25
540
  #: views/cpt/view-link-options-metabox.php:37
541
  #: views/cpt/view-link-options-metabox.php:50
544
  msgid "No"
545
  msgstr ""
546
 
547
+ #: Models/Settings.php:267
548
  msgid "Per category"
549
  msgstr ""
550
 
551
+ #: Models/Settings.php:273 views/reports/link-performance-report.php:39
552
  #: views/reports/link-performance-report.php:80
553
  msgid "General"
554
  msgstr ""
555
 
556
+ #: Models/Settings.php:274
557
  msgid "Settings that change the general behaviour of ThirstyAffiliates."
558
  msgstr ""
559
 
560
+ #: Models/Settings.php:277
561
  msgid "Link Appearance"
562
  msgstr ""
563
 
564
+ #: Models/Settings.php:278
565
  msgid "Settings that specifically affect the behaviour & appearance of your affiliate links."
566
  msgstr ""
567
 
568
+ #: Models/Settings.php:281
569
  msgid "Modules"
570
  msgstr ""
571
 
572
+ #: Models/Settings.php:282
573
  msgid "This section allows you to turn certain parts of ThirstyAffiliates on or off. Below are the individual modules and features of the plugin that can be controlled."
574
  msgstr ""
575
 
576
+ #: Models/Settings.php:285
577
  msgid "Import/Export"
578
  msgstr ""
579
 
580
+ #: Models/Settings.php:286
581
  msgid "Import and Export global ThirstyAffiliates plugin settings from one site to another."
582
  msgstr ""
583
 
584
+ #: Models/Settings.php:289
585
  msgid "Help"
586
  msgstr ""
587
 
588
+ #: Models/Settings.php:290
589
  msgid "Links to knowledge base and other utilities."
590
  msgstr ""
591
 
592
+ #: Models/Settings.php:299
593
  msgid "Default Link Insertion Type"
594
  msgstr ""
595
 
596
+ #: Models/Settings.php:300
597
  msgid "Determines the default link type when inserting a link using the quick search."
598
  msgstr ""
599
 
600
+ #: Models/Settings.php:304
601
  msgid "Link"
602
  msgstr ""
603
 
604
+ #: Models/Settings.php:305
605
  msgid "Shortcode"
606
  msgstr ""
607
 
608
+ #: Models/Settings.php:311
609
  msgid "Disable \"uncategorized\" category on save?"
610
  msgstr ""
611
 
612
+ #: Models/Settings.php:312
613
  msgid "If links are including categories in the URL then by default ThirstyAffiliates will add an \"uncategorized\" category to apply to non-categorised links during save. If you disable this, it allows you to have some links with categories in the URL and some without."
614
  msgstr ""
615
 
616
+ #: Models/Settings.php:318
617
  msgid "Disable buttons on the Visual editor?"
618
  msgstr ""
619
 
620
+ #: Models/Settings.php:319
621
  msgid "Hide the ThirstyAffiliates buttons on the Visual editor."
622
  msgstr ""
623
 
624
+ #: Models/Settings.php:325
625
  msgid "Disable buttons on the Text/Quicktags editor?"
626
  msgstr ""
627
 
628
+ #: Models/Settings.php:326
629
  msgid "Hide the ThirstyAffiliates buttons on the Text editor."
630
  msgstr ""
631
 
632
+ #: Models/Settings.php:332
633
  msgid "Trim stats older than:"
634
  msgstr ""
635
 
636
+ #: Models/Settings.php:333
637
  msgid "months (Automatically clean the statistics database records older than a set point. Setting this to 0 will disable it)."
638
  msgstr ""
639
 
640
+ #: Models/Settings.php:342
641
  msgid "Don't cache 301 redirects? (server side redirects)"
642
  msgstr ""
643
 
644
+ #: Models/Settings.php:343
645
  msgid "By default, browsers caches the 301 redirects. Enabling this option will tell the browser not to cache 301 redirects. Be aware that it is still up to the browser if it will cache it or not."
646
  msgstr ""
647
 
648
+ #: Models/Settings.php:349
649
+ msgid "Disable IP address collection"
650
  msgstr ""
651
 
652
+ #: Models/Settings.php:350
653
+ msgid "By default ThirstyAffiliates plugin collects visitor's IP address everytime they click an affiliate link as part of the statistics information. By checking this the IP address collection will be disabled, but other information will still be saved."
654
+ msgstr ""
655
+
656
+ #: Models/Settings.php:356
657
+ msgid "Blocked bots"
658
+ msgstr ""
659
+
660
+ #: Models/Settings.php:357
661
+ msgid "By default ThirstyAffiliates blocks bots accessing your affiliate links to give you a more appropriate data in the report. Select bots, or enter new ones to block."
662
  msgstr ""
663
 
664
+ #: Models/Settings.php:368
665
  msgid "Link Prefix"
666
  msgstr ""
667
 
668
+ #: Models/Settings.php:369
669
  #, php-format
670
  msgid "The prefix that comes before your cloaked link's slug. <br>eg. %s/<strong>recommends</strong>/your-affiliate-link-name.<br><br><b>Warning :</b> Changing this setting after you've used links in a post could break those links. Be careful!"
671
  msgstr ""
672
 
673
+ #: Models/Settings.php:397
674
  msgid "Custom Link Prefix"
675
  msgstr ""
676
 
677
+ #: Models/Settings.php:398
678
  msgid "Enter your preferred link prefix."
679
  msgstr ""
680
 
681
+ #: Models/Settings.php:404
682
  msgid "Link Category in URL?"
683
  msgstr ""
684
 
685
+ #: Models/Settings.php:405
686
  #, php-format
687
  msgid "Shows the primary selected category in the url. eg. %s/recommends/<strong>link-category</strong>/your-affiliate-link-name.<br><br><b>Warning :</b> Changing this setting after you've used links in a post could break those links. Be careful!"
688
  msgstr ""
689
 
690
+ #: Models/Settings.php:411
691
+ msgid "Enable Enhanced Javascript Redirect on Frontend"
692
+ msgstr ""
693
+
694
+ #: Models/Settings.php:412
695
+ msgid "By default affiliate links are redirected on the server side. Enabling this will set all affiliate links to be redirected via javascript on your website's frontend. This will then improve the accuracy of the link performance report."
696
+ msgstr ""
697
+
698
+ #: Models/Settings.php:418
699
  msgid "Link Redirect Type (server side redirects)"
700
  msgstr ""
701
 
702
+ #: Models/Settings.php:419
703
  msgid "This is the type of redirect ThirstyAffiliates will use to redirect the user to your affiliate link."
704
  msgstr ""
705
 
706
+ #: Models/Settings.php:427
707
  msgid "Use no follow on links? (server side redirects)"
708
  msgstr ""
709
 
710
+ #: Models/Settings.php:428
711
  msgid "Add the nofollow attribute to links so search engines don't index them."
712
  msgstr ""
713
 
714
+ #: Models/Settings.php:437
715
  msgid "No follow categories (server side redirects)"
716
  msgstr ""
717
 
718
+ #: Models/Settings.php:438
719
  msgid "The links assigned to the selected category will be set as \"no follow\"."
720
  msgstr ""
721
 
722
+ #: Models/Settings.php:442 Models/Settings.php:464 Models/Settings.php:486
723
+ #: Models/Settings.php:520
724
  msgid "Select category..."
725
  msgstr ""
726
 
727
+ #: Models/Settings.php:449
728
  msgid "Open links in new window?"
729
  msgstr ""
730
 
731
+ #: Models/Settings.php:450
732
  msgid "Make links open in a new browser tab by default."
733
  msgstr ""
734
 
735
+ #: Models/Settings.php:459
736
  msgid "New window categories"
737
  msgstr ""
738
 
739
+ #: Models/Settings.php:460
740
  msgid "The links assigned to the selected category will be set as \"new window\"."
741
  msgstr ""
742
 
743
+ #: Models/Settings.php:471
744
  msgid "Pass query strings to destination url?"
745
  msgstr ""
746
 
747
+ #: Models/Settings.php:472
748
  msgid "Enabling this option will pass all of the query strings present after the cloaked url to the destination url automatically when redirecting."
749
  msgstr ""
750
 
751
+ #: Models/Settings.php:481
752
  msgid "Pass query strings categories"
753
  msgstr ""
754
 
755
+ #: Models/Settings.php:482
756
  msgid "The links assigned to the selected category will be set as \"pass query strings\"."
757
  msgstr ""
758
 
759
+ #: Models/Settings.php:493
760
  msgid "Additional rel attribute tags"
761
  msgstr ""
762
 
763
+ #: Models/Settings.php:494
764
  msgid "Allows you to add extra tags into the rel= attribute when links are inserted."
765
  msgstr ""
766
 
767
+ #: Models/Settings.php:500
768
  msgid "Disable ThirstyAffiliates CSS classes?"
769
  msgstr ""
770
 
771
+ #: Models/Settings.php:501
772
  msgid "To help with styling a CSS class called \"thirstylink\" is added links on insertion.<br>Likewise the \"thirstylinkimg\" class is added to images when using the image insertion type. This option disables the addition these CSS classes."
773
  msgstr ""
774
 
775
+ #: Models/Settings.php:507
776
  msgid "Disable title attribute on link insertion?"
777
  msgstr ""
778
 
779
+ #: Models/Settings.php:508
780
  msgid "Links are automatically output with a title html attribute (by default this shows the title of the affiliate link).<br>This option disables the output of the title attribute on your links."
781
  msgstr ""
782
 
783
+ #: Models/Settings.php:514
784
  msgid "Select Category to Uncloak"
785
  msgstr ""
786
 
787
+ #: Models/Settings.php:515
788
  msgid "The links assigned to the selected category will be uncloaked."
789
  msgstr ""
790
 
791
+ #: Models/Settings.php:529
792
  msgid "Statistics"
793
  msgstr ""
794
 
795
+ #: Models/Settings.php:530
796
  msgid "When enabled, ThirstyAffiliates will collect click statistics information about visitors that click on your affiliate links. Also adds a new Reports section."
797
  msgstr ""
798
 
799
+ #: Models/Settings.php:537
800
  msgid "Link Fixer"
801
  msgstr ""
802
 
803
+ #: Models/Settings.php:538
804
  msgid "Link Fixer is a tiny piece of javascript code that runs on the frontend of your site to fix any outdated/broken affiliate links it detects. It's cache-friendly and runs after page load so it doesn't affect the rendering of content. Changed the settings on your site recently? Enabling Link Fixer means you don't need to update all your previously inserted affiliate links one by one – your visitors will never see an out of date affiliate link again."
805
  msgstr ""
806
 
807
+ #: Models/Settings.php:545
808
  msgid "Uncloak Links"
809
  msgstr ""
810
 
811
+ #: Models/Settings.php:546
812
  msgid "Uncloak Links is a feature to allow uncloaking of specific links on your site. It replaces the cloaked url with the actual destination url which is important for compatibility with some affiliate program with stricter terms (such as Amazon Associates). Once enabled, you will see a new Uncloak Link checkbox on the affiliate link edit screen. It also introduces a new setting under the Links tab for uncloaking whole categories.<br><br><b>Warning : </b>For this feature to work, the <strong>Link Fixer</strong> module needs to be turned on."
813
  msgstr ""
814
 
815
+ #: Models/Settings.php:556
816
  msgid "Import Global Settings"
817
  msgstr ""
818
 
819
+ #: Models/Settings.php:558
820
  msgid "Paste settings string here..."
821
  msgstr ""
822
 
823
+ #: Models/Settings.php:563
824
  msgid "Export Global Settings"
825
  msgstr ""
826
 
827
+ #: Models/Settings.php:572 Models/Settings.php:580
828
  msgid "Knowledge Base"
829
  msgstr ""
830
 
831
+ #: Models/Settings.php:577
832
  msgid "Documentation"
833
  msgstr ""
834
 
835
+ #: Models/Settings.php:581
836
  msgid "Guides, troubleshooting, FAQ and more."
837
  msgstr ""
838
 
839
+ #: Models/Settings.php:586
840
  msgid "Our Blog"
841
  msgstr ""
842
 
843
+ #: Models/Settings.php:589
844
  msgid "ThirstyAffiliates Blog"
845
  msgstr ""
846
 
847
+ #: Models/Settings.php:590
848
  msgid "Learn & grow your affiliate marketing – covering increasing sales, generating traffic, optimising your affiliate marketing, interviews & case studies."
849
  msgstr ""
850
 
851
+ #: Models/Settings.php:595
852
  msgid "Join the Community"
853
  msgstr ""
854
 
855
+ #: Models/Settings.php:602
856
  msgid "Other Utilities"
857
  msgstr ""
858
 
859
+ #: Models/Settings.php:607
860
  msgid "Migrate Old Data"
861
  msgstr ""
862
 
863
+ #: Models/Settings.php:609
864
  msgid "Migrate old ThirstyAffiliates version 2 data to new version 3 data model."
865
  msgstr ""
866
 
867
+ #: Models/Settings.php:737 Models/Settings.php:758
868
  msgid "ThirstyAffiliates Settings"
869
  msgstr ""
870
 
871
+ #: Models/Settings.php:775
872
  msgid "Pro Features →"
873
  msgstr ""
874
 
875
+ #: Models/Settings.php:901
876
  msgid "Save Changes"
877
  msgstr ""
878
 
879
+ #: Models/Settings.php:1410
880
  msgid "Key"
881
  msgstr ""
882
 
883
+ #: Models/Settings.php:1411
884
  msgid "Value"
885
  msgstr ""
886
 
887
+ #: Models/Settings.php:1534
888
  msgid "Another application is currently processing the database. Please wait for this to complete."
889
  msgstr ""
890
 
891
+ #: Models/Settings.php:1544
892
  msgid "Migrate"
893
  msgstr ""
894
 
895
+ #: Models/Settings.php:1547
896
  msgid "Migrating data. Please wait..."
897
  msgstr ""
898
 
899
+ #: Models/Settings.php:1578
900
  msgid "Like us on Facebook"
901
  msgstr ""
902
 
903
+ #: Models/Settings.php:1582
904
  msgid "Follow us on Twitter"
905
  msgstr ""
906
 
907
+ #: Models/Settings.php:1586
908
  msgid "Follow us on Linkedin"
909
  msgstr ""
910
 
911
+ #: Models/Settings.php:1589
912
  msgid "Join Our Affiliate Program"
913
  msgstr ""
914
 
915
+ #: Models/Settings.php:1590
916
  #, php-format
917
  msgid "(up to 30% commisions)"
918
  msgstr ""
919
 
920
+ #: Models/Settings.php:1623
921
  msgid "Copy"
922
  msgstr ""
923
 
924
+ #: Models/Settings.php:1660
925
  msgid "Import Settings"
926
  msgstr ""
927
 
928
+ #: Models/Settings.php:1875
929
  msgid "Unauthorized operation. Only authorized accounts can access global plugin settings string"
930
  msgstr ""
931
 
932
+ #: Models/Settings.php:1904
933
  msgid "Settings successfully imported"
934
  msgstr ""
935
 
936
+ #: Models/Settings.php:1926
937
  msgid "Unauthorized operation. Only authorized accounts can import settings"
938
  msgstr ""
939
 
940
+ #: Models/Settings.php:1931
941
  msgid "Invalid global settings string"
942
  msgstr ""
943
 
945
  msgid "SHORTCODE ERROR: ThirstyAffiliates did not detect a valid link id, please check your short code!"
946
  msgstr ""
947
 
948
+ #: Models/Stats_Reporting.php:414
949
  msgid "Selected affiliate link is invalid"
950
  msgstr ""
951
 
952
+ #: Models/Stats_Reporting.php:539
953
  msgid "Link Overview"
954
  msgstr ""
955
 
956
+ #: Models/Stats_Reporting.php:540
957
  msgid "Link Overview Report"
958
  msgstr ""
959
 
960
+ #: Models/Stats_Reporting.php:541
961
  msgid "Total clicks on affiliate links over a given period."
962
  msgstr ""
963
 
964
+ #: Models/Stats_Reporting.php:571
965
  msgid "ThirstyAffiliates Reports"
966
  msgstr ""
967
 
968
+ #: Models/Stats_Reporting.php:572
969
  msgid "Reports"
970
  msgstr ""
971
 
972
+ #: Models/Stats_Reporting.php:651
973
  msgid "Year"
974
  msgstr ""
975
 
976
+ #: Models/Stats_Reporting.php:652
977
  msgid "Last Month"
978
  msgstr ""
979
 
980
+ #: Models/Stats_Reporting.php:653
981
  msgid "This Month"
982
  msgstr ""
983
 
984
+ #: Models/Stats_Reporting.php:654
985
  msgid "Last 7 Days"
986
  msgstr ""
987
 
readme.txt CHANGED
@@ -4,8 +4,8 @@ Donate link:
4
  Tags: affiliate, link, affiliate link management, link cloaker, link redirect, shortlink, thirstyaffiliates, thirsty affiliates
5
  Requires at least: 3.4
6
  Requires PHP: 5.6
7
- Tested up to: 4.9.5
8
- Stable tag: 3.3.2
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -159,6 +159,17 @@ See our [Knowledge Base](https://thirstyaffiliates.com/knowledge-base/?utm_sourc
159
 
160
  == Changelog ==
161
 
 
 
 
 
 
 
 
 
 
 
 
162
  = 3.3.2 =
163
  * Bug Fix: WP 4.9.6: The post editor won't show TA buttons and shows a JS error
164
 
4
  Tags: affiliate, link, affiliate link management, link cloaker, link redirect, shortlink, thirstyaffiliates, thirsty affiliates
5
  Requires at least: 3.4
6
  Requires PHP: 5.6
7
+ Tested up to: 4.9.6
8
+ Stable tag: 3.3.3
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
159
 
160
  == Changelog ==
161
 
162
+ = 3.3.3 =
163
+ * Improvement: Block bots on stats recording process for non-apache servers
164
+ * Improvement: Remove report data query on page first load
165
+ * Improvement: Add settings for blocking bots
166
+ * Improvement: Ability to turn off IP address collection on stats (GDPR compliance)
167
+ * Improvement: Move "Enable Enhanced Javascript Redirect on Frontend" setting to Link Appearance tab
168
+ * Improvement: Code improvements
169
+ * Bug Fix: Improve reliability of link scanner
170
+ * Bug Fix: attachment page can be viewed with link prefix
171
+ * Bug Fix: Improve accuracy of link performance report
172
+
173
  = 3.3.2 =
174
  * Bug Fix: WP 4.9.6: The post editor won't show TA buttons and shows a JS error
175
 
thirstyaffiliates.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: ThirstyAffiliates
4
  * Plugin URI: http://thirstyaffiliates.com/
5
  * Description: ThirstyAffiliates is a revolution in affiliate link management. Collect, collate and store your affiliate links for use in your posts and pages.
6
- * Version: 3.3.2
7
  * Author: Rymera Web Co
8
  * Author URI: https://rymera.com.au/
9
  * Requires at least: 4.4.2
3
  * Plugin Name: ThirstyAffiliates
4
  * Plugin URI: http://thirstyaffiliates.com/
5
  * Description: ThirstyAffiliates is a revolution in affiliate link management. Collect, collate and store your affiliate links for use in your posts and pages.
6
+ * Version: 3.3.3
7
  * Author: Rymera Web Co
8
  * Author URI: https://rymera.com.au/
9
  * Requires at least: 4.4.2
views/reports/link-performance-report.php CHANGED
@@ -24,7 +24,7 @@
24
  </form>
25
  </li>
26
 
27
- <?php do_action( 'ta_stats_reporting_menu_items' , $data ); ?>
28
 
29
  </ul>
30
  </div>
@@ -37,7 +37,7 @@
37
  <ul class="chart-legend">
38
  <li style="border-color: #3498db">
39
  <?php _e( 'General' , 'thirstyaffiliates' ); ?>
40
- <em class="count"><?php echo number_format( $total_clicks ); ?></em>
41
  <span><?php _e( 'All links' , 'thirstyaffiliates' ); ?></span>
42
  </li>
43
  </ul>
@@ -75,16 +75,16 @@
75
  </div>
76
 
77
  <script type="text/javascript">
78
- var report_data = { 'click_counts' :<?php echo json_encode( $data ); ?>},
79
  report_details = {
80
  label : '<?php echo _e( 'General' , 'thirstyaffiliates' ); ?>',
81
  label : '<?php echo _e( 'All links' , 'thirstyaffiliates' ); ?>',
82
  timeformat : '<?php echo ( $range[ 'type' ] == 'year' ) ? '%b' : '%d %b'; ?>',
83
  minTickSize : [ 1 , "<?php echo ( $range[ 'type' ] == 'year' ) ? 'month' : 'day'; ?>" ],
84
  clicksLabel : '<?php _e( 'Clicks: ' , 'thirstyaffiliates' ); ?>',
85
- totalClicks : '<?php echo number_format( $total_clicks ); ?>'
86
  },
87
  main_chart;
88
  </script>
89
 
90
- <?php do_action( 'ta_after_link_performace_report' , $range , $data ); ?>
24
  </form>
25
  </li>
26
 
27
+ <?php do_action( 'ta_stats_reporting_menu_items' ); ?>
28
 
29
  </ul>
30
  </div>
37
  <ul class="chart-legend">
38
  <li style="border-color: #3498db">
39
  <?php _e( 'General' , 'thirstyaffiliates' ); ?>
40
+ <em class="count"></em>
41
  <span><?php _e( 'All links' , 'thirstyaffiliates' ); ?></span>
42
  </li>
43
  </ul>
75
  </div>
76
 
77
  <script type="text/javascript">
78
+ var report_data = { 'click_counts' :[] },
79
  report_details = {
80
  label : '<?php echo _e( 'General' , 'thirstyaffiliates' ); ?>',
81
  label : '<?php echo _e( 'All links' , 'thirstyaffiliates' ); ?>',
82
  timeformat : '<?php echo ( $range[ 'type' ] == 'year' ) ? '%b' : '%d %b'; ?>',
83
  minTickSize : [ 1 , "<?php echo ( $range[ 'type' ] == 'year' ) ? 'month' : 'day'; ?>" ],
84
  clicksLabel : '<?php _e( 'Clicks: ' , 'thirstyaffiliates' ); ?>',
85
+ totalClicks : ''
86
  },
87
  main_chart;
88
  </script>
89
 
90
+ <?php do_action( 'ta_after_link_performace_report' , $range ); ?>