ThirstyAffiliates Affiliate Link Manager - Version 3.9.2

Version Description

  • Feature: Add X-Robots-Tag header to nofollow links
  • Improvement: Add indexes to the plugin database columns
  • Bug Fix: Fatal error activating the plugin on some WP timezones
  • Bug Fix: Reports only showing results for 10 links
Download this release

Release Info

Developer caseproof
Plugin Icon 128x128 ThirstyAffiliates Affiliate Link Manager
Version 3.9.2
Comparing to
See all releases

Code changes from version 3.9.1 to 3.9.2

Helpers/Helper_Functions.php CHANGED
@@ -141,10 +141,7 @@ class Helper_Functions {
141
  /**
142
  * Returns the timezone string for a site, even if it's set to a UTC offset
143
  *
144
- * Adapted from http://www.php.net/manual/en/function.timezone-name-from-abbr.php#89155
145
- *
146
- * Reference:
147
- * http://www.skyverge.com/blog/down-the-rabbit-hole-wordpress-and-timezones/
148
  *
149
  * @since 3.0.0
150
  * @access public
@@ -153,29 +150,43 @@ class Helper_Functions {
153
  */
154
  public function get_site_current_timezone() {
155
 
156
- // if site timezone string exists, return it
157
- if ( $timezone = get_option( 'timezone_string' ) )
158
- return $timezone;
 
 
 
 
 
 
 
 
 
 
159
 
160
- // get UTC offset, if it isn't set then return UTC
161
- if ( 0 === ( $utc_offset = get_option( 'gmt_offset', 0 ) ) )
162
- return 'UTC';
 
163
 
164
- return $this->convert_utc_offset_to_timezone( $utc_offset );
165
 
166
  }
167
 
168
  /**
169
- * Conver UTC offset to timezone.
170
  *
171
  * @since 1.2.0
172
  * @access public
 
173
  *
174
  * @param float|int|string $utc_offset UTC offset.
175
  * @return string valid PHP timezone string
176
  */
177
  public function convert_utc_offset_to_timezone( $utc_offset ) {
178
 
 
 
179
  // adjust UTC offset from hours to seconds
180
  $utc_offset *= 3600;
181
 
@@ -327,6 +338,11 @@ class Helper_Functions {
327
  'post__not_in' => $exclude
328
  );
329
 
 
 
 
 
 
330
  if ( $category ) {
331
 
332
  $args[ 'tax_query' ] = array(
141
  /**
142
  * Returns the timezone string for a site, even if it's set to a UTC offset
143
  *
144
+ * Duplicate of wp_timezone_string() for WP <5.3.
 
 
 
145
  *
146
  * @since 3.0.0
147
  * @access public
150
  */
151
  public function get_site_current_timezone() {
152
 
153
+ if ( function_exists( 'wp_timezone_string' ) ) {
154
+ return wp_timezone_string();
155
+ }
156
+
157
+ $timezone_string = get_option( 'timezone_string' );
158
+
159
+ if ( $timezone_string ) {
160
+ return $timezone_string;
161
+ }
162
+
163
+ $offset = (float) get_option( 'gmt_offset' );
164
+ $hours = (int) $offset;
165
+ $minutes = ( $offset - $hours );
166
 
167
+ $sign = ( $offset < 0 ) ? '-' : '+';
168
+ $abs_hour = abs( $hours );
169
+ $abs_mins = abs( $minutes * 60 );
170
+ $tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins );
171
 
172
+ return $tz_offset;
173
 
174
  }
175
 
176
  /**
177
+ * Convert UTC offset to timezone.
178
  *
179
  * @since 1.2.0
180
  * @access public
181
+ * @deprecated 3.9.2
182
  *
183
  * @param float|int|string $utc_offset UTC offset.
184
  * @return string valid PHP timezone string
185
  */
186
  public function convert_utc_offset_to_timezone( $utc_offset ) {
187
 
188
+ _deprecated_function( 'ThirstyAffiliates\Helpers\Helper_Functions::convert_utc_offset_to_timezone', '3.9.2');
189
+
190
  // adjust UTC offset from hours to seconds
191
  $utc_offset *= 3600;
192
 
338
  'post__not_in' => $exclude
339
  );
340
 
341
+ if ( $paged == -1 ) {
342
+ $args['posts_per_page'] = -1;
343
+ unset( $args['paged'] );
344
+ }
345
+
346
  if ( $category ) {
347
 
348
  $args[ 'tax_query' ] = array(
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.9.1';
31
  const TEXT_DOMAIN = 'thirstyaffiliates';
32
  const THEME_TEMPLATE_PATH = 'thirstyaffiliates';
33
  const META_DATA_PREFIX = '_ta_';
27
  // Plugin configuration constants
28
  const TOKEN = 'ta';
29
  const INSTALLED_VERSION = 'ta_installed_version';
30
+ const VERSION = '3.9.2';
31
  const TEXT_DOMAIN = 'thirstyaffiliates';
32
  const THEME_TEMPLATE_PATH = 'thirstyaffiliates';
33
  const META_DATA_PREFIX = '_ta_';
Models/Affiliate_Links_CPT.php CHANGED
@@ -949,7 +949,8 @@ class Affiliate_Links_CPT implements Model_Interface , Initiable_Interface {
949
  $thirstylink = $this->get_thirstylink_post( $link_id );
950
  $inserted_to = $thirstylink->scan_where_links_inserted();
951
  $timezone = new \DateTimeZone( $this->_helper_functions->get_site_current_timezone() );
952
- $last_scanned = \DateTime::createFromFormat( 'Y-m-d G:i:s' , get_post_meta( $link_id , Plugin_Constants::META_DATA_PREFIX . 'scanned_inserted' , true ) , $timezone );
 
953
 
954
  $response = array(
955
  'status' => 'success',
949
  $thirstylink = $this->get_thirstylink_post( $link_id );
950
  $inserted_to = $thirstylink->scan_where_links_inserted();
951
  $timezone = new \DateTimeZone( $this->_helper_functions->get_site_current_timezone() );
952
+ $last_scanned = \DateTime::createFromFormat( 'Y-m-d G:i:s' , get_post_meta( $link_id , Plugin_Constants::META_DATA_PREFIX . 'scanned_inserted' , true ) );
953
+ $last_scanned->setTimezone($timezone);
954
 
955
  $response = array(
956
  'status' => 'success',
Models/Bootstrap.php CHANGED
@@ -345,7 +345,7 @@ class Bootstrap implements Model_Interface {
345
 
346
  global $wpdb;
347
 
348
- if ( get_option( 'ta_database_tables_created' ) === 'yes' )
349
  return;
350
 
351
  $link_click_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
@@ -357,7 +357,9 @@ class Bootstrap implements Model_Interface {
357
  id bigint(20) NOT NULL AUTO_INCREMENT,
358
  link_id bigint(20) NOT NULL,
359
  date_clicked datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
360
- PRIMARY KEY (id)
 
 
361
  ) $charset_collate;\n";
362
 
363
  // link clicks meta db sql command
@@ -366,13 +368,15 @@ class Bootstrap implements Model_Interface {
366
  click_id bigint(20) NOT NULL,
367
  meta_key varchar(255) NULL,
368
  meta_value longtext NULL,
369
- PRIMARY KEY (id)
 
 
370
  ) $charset_collate;";
371
 
372
  require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
373
  dbDelta( $sql );
374
 
375
- update_option( 'ta_database_tables_created' , 'yes' );
376
  }
377
 
378
  /**
@@ -394,7 +398,7 @@ class Bootstrap implements Model_Interface {
394
 
395
  /**
396
  * Control admin interface visibility.
397
- *
398
  * @since 3.3.2
399
  * @access public
400
  */
@@ -420,11 +424,11 @@ class Bootstrap implements Model_Interface {
420
  else
421
  $capability = $current_interface;
422
 
423
- if ( $current_tab === 'ta_import_export_settings' )
424
  $capability = 'manage_options';
425
 
426
  // get error message.
427
- $error_message = apply_filters( 'ta_admin_interface_error_message' , __( "Sorry, you are not allowed to access this page." , 'thirstyaffiliates' ) , $screen_id , $current_tab , $capability , $current_interface );
428
 
429
  // kill page display error message if current user does not have capability.
430
  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' ) ) )
@@ -433,14 +437,14 @@ class Bootstrap implements Model_Interface {
433
 
434
  /**
435
  * Control admin menu items visibility.
436
- *
437
  * @since 3.3.2
438
  * @access public
439
  */
440
  public function admin_menu_items_visibilty() {
441
 
442
  global $submenu;
443
-
444
  $menu_slug = 'edit.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
445
  $menu_items = apply_filters( 'ta_menu_items' , array() );
446
  $main_cap = null;
@@ -448,14 +452,14 @@ class Bootstrap implements Model_Interface {
448
  if ( ! is_array( $menu_items ) || empty( $menu_items ) ) return;
449
 
450
  foreach ( $menu_items as $submenu_slug => $capability ) {
451
-
452
  if ( $submenu_slug == $menu_slug ) {
453
  $main_cap = $capability;
454
  continue;
455
  }
456
 
457
  if ( $capability && ! current_user_can( $capability ) )
458
- remove_submenu_page( $menu_slug , esc_attr( $submenu_slug ) );
459
  }
460
 
461
  $menu_count = isset( $submenu[ $menu_slug ] ) ? count( $submenu[ $menu_slug ] ) : 0;
@@ -472,8 +476,8 @@ class Bootstrap implements Model_Interface {
472
  */
473
  public function initialize() {
474
 
475
- // Execute activation codebase if not yet executed on plugin activation ( Mostly due to plugin dependencies )
476
- if ( get_option( 'ta_activation_code_triggered' , false ) !== 'yes' ) {
477
 
478
  if ( ! function_exists( 'is_plugin_active_for_network' ) )
479
  require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
345
 
346
  global $wpdb;
347
 
348
+ if ( get_option( 'ta_database_tables_created' ) === Plugin_Constants::VERSION )
349
  return;
350
 
351
  $link_click_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
357
  id bigint(20) NOT NULL AUTO_INCREMENT,
358
  link_id bigint(20) NOT NULL,
359
  date_clicked datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
360
+ PRIMARY KEY (id),
361
+ KEY link_id (link_id),
362
+ KEY date_clicked (date_clicked)
363
  ) $charset_collate;\n";
364
 
365
  // link clicks meta db sql command
368
  click_id bigint(20) NOT NULL,
369
  meta_key varchar(255) NULL,
370
  meta_value longtext NULL,
371
+ PRIMARY KEY (id),
372
+ KEY click_id (click_id),
373
+ KEY meta_key (meta_key(191))
374
  ) $charset_collate;";
375
 
376
  require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
377
  dbDelta( $sql );
378
 
379
+ update_option( 'ta_database_tables_created' , Plugin_Constants::VERSION );
380
  }
381
 
382
  /**
398
 
399
  /**
400
  * Control admin interface visibility.
401
+ *
402
  * @since 3.3.2
403
  * @access public
404
  */
424
  else
425
  $capability = $current_interface;
426
 
427
+ if ( $current_tab === 'ta_import_export_settings' )
428
  $capability = 'manage_options';
429
 
430
  // get error message.
431
+ $error_message = apply_filters( 'ta_admin_interface_error_message' , __( "Sorry, you are not allowed to access this page." , 'thirstyaffiliates' ) , $screen_id , $current_tab , $capability , $current_interface );
432
 
433
  // kill page display error message if current user does not have capability.
434
  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' ) ) )
437
 
438
  /**
439
  * Control admin menu items visibility.
440
+ *
441
  * @since 3.3.2
442
  * @access public
443
  */
444
  public function admin_menu_items_visibilty() {
445
 
446
  global $submenu;
447
+
448
  $menu_slug = 'edit.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
449
  $menu_items = apply_filters( 'ta_menu_items' , array() );
450
  $main_cap = null;
452
  if ( ! is_array( $menu_items ) || empty( $menu_items ) ) return;
453
 
454
  foreach ( $menu_items as $submenu_slug => $capability ) {
455
+
456
  if ( $submenu_slug == $menu_slug ) {
457
  $main_cap = $capability;
458
  continue;
459
  }
460
 
461
  if ( $capability && ! current_user_can( $capability ) )
462
+ remove_submenu_page( $menu_slug , esc_attr( $submenu_slug ) );
463
  }
464
 
465
  $menu_count = isset( $submenu[ $menu_slug ] ) ? count( $submenu[ $menu_slug ] ) : 0;
476
  */
477
  public function initialize() {
478
 
479
+ // Execute activation codebase if not yet executed on plugin activation or if this is a new version
480
+ if ( get_option( 'ta_activation_code_triggered' , false ) !== 'yes' || get_option( Plugin_Constants::INSTALLED_VERSION ) !== Plugin_Constants::VERSION ) {
481
 
482
  if ( ! function_exists( 'is_plugin_active_for_network' ) )
483
  require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
Models/Rewrites_Redirection.php CHANGED
@@ -213,7 +213,7 @@ 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
- * @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() {
@@ -224,7 +224,7 @@ class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface
224
 
225
  if ( is_object( $post ) && $post->post_type === 'attachment' && $this->validate_cloaked_url() )
226
  $wp_query->set_404();
227
-
228
  return;
229
  }
230
 
@@ -255,6 +255,10 @@ class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface
255
  header( 'Expires: Thu, 01 Jan 1970 00:00:00 GMT' );
256
  }
257
 
 
 
 
 
258
  wp_redirect( $redirect_url , intval( $redirect_type ) );
259
  exit;
260
  }
@@ -338,7 +342,7 @@ class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface
338
  // prepend block bots rules in the htaccess content.
339
  $htaccess = $block_bots . $htaccess;
340
  }
341
-
342
  file_put_contents( $this->_constants->HTACCESS_FILE() , $htaccess );
343
  }
344
 
@@ -365,7 +369,7 @@ class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface
365
 
366
  /**
367
  * Block bots access to affiliate links for non-apache servers.
368
- *
369
  * @since 3.3.3
370
  * @since 3.3.7 We only block bots when the ta_enable_bot_crawl_blocker_script setting option is set to "yes".
371
  * @access public
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() {
224
 
225
  if ( is_object( $post ) && $post->post_type === 'attachment' && $this->validate_cloaked_url() )
226
  $wp_query->set_404();
227
+
228
  return;
229
  }
230
 
255
  header( 'Expires: Thu, 01 Jan 1970 00:00:00 GMT' );
256
  }
257
 
258
+ if ( $thirstylink->is( 'no_follow' ) ) {
259
+ header( 'X-Robots-Tag: noindex, nofollow' );
260
+ }
261
+
262
  wp_redirect( $redirect_url , intval( $redirect_type ) );
263
  exit;
264
  }
342
  // prepend block bots rules in the htaccess content.
343
  $htaccess = $block_bots . $htaccess;
344
  }
345
+
346
  file_put_contents( $this->_constants->HTACCESS_FILE() , $htaccess );
347
  }
348
 
369
 
370
  /**
371
  * Block bots access to affiliate links for non-apache servers.
372
+ *
373
  * @since 3.3.3
374
  * @since 3.3.7 We only block bots when the ta_enable_bot_crawl_blocker_script setting option is set to "yes".
375
  * @access public
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: 5.0
6
  Requires PHP: 5.6
7
- Tested up to: 5.3
8
- Stable tag: 3.9.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -159,6 +159,12 @@ See our [Knowledge Base](https://thirstyaffiliates.com/knowledge-base/?utm_sourc
159
 
160
  == Changelog ==
161
 
 
 
 
 
 
 
162
  = 3.9.1 =
163
  * Bug Fix: Incorrect client IP retrieved from HTTP_X_FORWARDED_FOR header
164
  * Bug Fix: External images not working in TA Image block
4
  Tags: affiliate, link, affiliate link management, link cloaker, link redirect, shortlink, thirstyaffiliates, thirsty affiliates
5
  Requires at least: 5.0
6
  Requires PHP: 5.6
7
+ Tested up to: 5.4
8
+ Stable tag: 3.9.2
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
159
 
160
  == Changelog ==
161
 
162
+ = 3.9.2 =
163
+ * Feature: Add X-Robots-Tag header to nofollow links
164
+ * Improvement: Add indexes to the plugin database columns
165
+ * Bug Fix: Fatal error activating the plugin on some WP timezones
166
+ * Bug Fix: Reports only showing results for 10 links
167
+
168
  = 3.9.1 =
169
  * Bug Fix: Incorrect client IP retrieved from HTTP_X_FORWARDED_FOR header
170
  * Bug Fix: External images not working in TA Image block
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.9.1
7
  * Author: Caseproof
8
  * Author URI: https://caseproof.com/
9
  * Requires at least: 4.5
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.9.2
7
  * Author: Caseproof
8
  * Author URI: https://caseproof.com/
9
  * Requires at least: 4.5
views/cpt/view-link-options-metabox.php CHANGED
@@ -31,7 +31,7 @@ wp_nonce_field( 'thirsty_affiliates_cpt_nonce', '_thirstyaffiliates_nonce' ); ?>
31
  <?php _e( 'Pass query string to destination url?' , 'thirstyaffiliates' ); ?>
32
  <span class="tooltip" data-tip="<?php esc_attr_e( 'Passes the query strings present after the cloaked url automatically to the destination url when redirecting.' , 'thirstyaffiliates' ); ?>"></span>
33
  </label>
34
- <select id="ta_new_window" name="ta_pass_query_str">
35
  <option value="global" <?php selected( $thirstylink->get_prop( 'pass_query_str' ) , 'global' ); ?>><?php echo sprintf( __( 'Global (%s)' , 'thirstyaffiliates' ) , $global_pass_query_str ); ?></option>
36
  <option value="yes" <?php selected( $thirstylink->get_prop( 'pass_query_str' ) , 'yes' ); ?>><?php _e( 'Yes' , 'thirstyaffiliates' ); ?></option>
37
  <option value="no" <?php selected( $thirstylink->get_prop( 'pass_query_str' ) , 'no' ); ?>><?php _e( 'No' , 'thirstyaffiliates' ); ?></option>
31
  <?php _e( 'Pass query string to destination url?' , 'thirstyaffiliates' ); ?>
32
  <span class="tooltip" data-tip="<?php esc_attr_e( 'Passes the query strings present after the cloaked url automatically to the destination url when redirecting.' , 'thirstyaffiliates' ); ?>"></span>
33
  </label>
34
+ <select id="ta_pass_query_str" name="ta_pass_query_str">
35
  <option value="global" <?php selected( $thirstylink->get_prop( 'pass_query_str' ) , 'global' ); ?>><?php echo sprintf( __( 'Global (%s)' , 'thirstyaffiliates' ) , $global_pass_query_str ); ?></option>
36
  <option value="yes" <?php selected( $thirstylink->get_prop( 'pass_query_str' ) , 'yes' ); ?>><?php _e( 'Yes' , 'thirstyaffiliates' ); ?></option>
37
  <option value="no" <?php selected( $thirstylink->get_prop( 'pass_query_str' ) , 'no' ); ?>><?php _e( 'No' , 'thirstyaffiliates' ); ?></option>