Advanced Ads - Version 1.8.25

Version Description

  • updated labels and links for AdSense Page-Level ads and QuickStart since both are now combined as "Auto Ads"
  • added link to create new AdSense account
  • removed "Remove Widget ID" option. No longer needed after fixing a compatibility issue with Q2W3 Fixed Widget plugin
  • prepared for Pro feature to repeat an ad multiple times by injecting it into the content
Download this release

Release Info

Developer webzunft
Plugin Icon 128x128 Advanced Ads
Version 1.8.25
Comparing to
See all releases

Code changes from version 1.8.24 to 1.8.25

admin/includes/class-settings.php CHANGED
@@ -167,14 +167,6 @@ class Advanced_Ads_Admin_Settings {
167
  $hook,
168
  'advanced_ads_setting_section'
169
  );
170
- // remove id from widgets
171
- add_settings_field(
172
- 'remove-widget-id',
173
- __( 'Remove Widget ID', 'advanced-ads' ),
174
- array($this, 'render_settings_remove_widget_id'),
175
- $hook,
176
- 'advanced_ads_setting_section'
177
- );
178
  // allow editors to manage ads
179
  add_settings_field(
180
  'editors-manage-ads',
@@ -489,33 +481,6 @@ class Advanced_Ads_Admin_Settings {
489
  echo '<p class="description">'. __( 'Prefix of class or id attributes in the frontend. Change it if you don’t want <strong>ad blockers</strong> to mark these blocks as ads.<br/>You might need to <strong>rewrite css rules afterwards</strong>.', 'advanced-ads' ) .'</p>';
490
  }
491
 
492
- /**
493
- * render setting to remove the id from advanced ads widgets
494
- *
495
- * @since 1.6.8.2
496
- */
497
- public function render_settings_remove_widget_id(){
498
- $options = Advanced_Ads::get_instance()->options();
499
-
500
- // is true by default if no options where previously set
501
- if( ! isset($options['remove-widget-id']) && $options !== array() ){
502
- $remove = false;
503
- } elseif( $options === array() ){
504
- $remove = true;
505
- } else {
506
- $remove = true;
507
- }
508
-
509
- echo '<input id="advanced-ads-remove-widget-id" type="checkbox" ' . checked( $remove, true, false ) . ' name="'.ADVADS_SLUG.'[remove-widget-id]" />';
510
- echo '<p class="description">' . __( 'Remove the ID attribute from widgets in order to not make them an easy target of ad blockers.', 'advanced-ads' );
511
-
512
- if ( class_exists( 'q2w3_fixed_widget', false ) ) {
513
- echo '<br />' . __( 'If checked, the Advanced Ads Widget will not work with the fixed option of the <strong>Q2W3 Fixed Widget</strong> plugin.', 'advanced-ads' );
514
- }
515
-
516
- echo '</p>';
517
- }
518
-
519
  /**
520
  * render setting to allow editors to manage ads
521
  *
167
  $hook,
168
  'advanced_ads_setting_section'
169
  );
 
 
 
 
 
 
 
 
170
  // allow editors to manage ads
171
  add_settings_field(
172
  'editors-manage-ads',
481
  echo '<p class="description">'. __( 'Prefix of class or id attributes in the frontend. Change it if you don’t want <strong>ad blockers</strong> to mark these blocks as ads.<br/>You might need to <strong>rewrite css rules afterwards</strong>.', 'advanced-ads' ) .'</p>';
482
  }
483
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  /**
485
  * render setting to allow editors to manage ads
486
  *
advanced-ads.php CHANGED
@@ -5,20 +5,20 @@
5
  * @package Advanced_Ads
6
  * @author Thomas Maier <thomas.maier@webgilde.com>
7
  * @license GPL-2.0+
8
- * @link http://webgilde.com
9
  * @copyright 2013-2018 Thomas Maier, webgilde GmbH
10
  *
11
  * @wordpress-plugin
12
  * Plugin Name: Advanced Ads
13
  * Plugin URI: https://wpadvancedads.com
14
  * Description: Manage and optimize your ads in WordPress
15
- * Version: 1.8.24
16
  * Author: Thomas Maier
17
  * Author URI: https://wpadvancedads.com
18
  * Text Domain: advanced-ads
19
  * Domain Path: /languages
20
  * License: GPL-2.0+
21
- * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
22
  */
23
 
24
  // If this file is called directly, abort.
@@ -39,7 +39,7 @@ define( 'ADVADS_BASE_DIR', dirname( ADVADS_BASE ) ); // directory of the plugin
39
  // general and global slug, e.g. to store options in WP, textdomain
40
  define( 'ADVADS_SLUG', 'advanced-ads' );
41
  define( 'ADVADS_URL', 'https://wpadvancedads.com/' );
42
- define( 'ADVADS_VERSION', '1.8.24' );
43
 
44
  /*----------------------------------------------------------------------------*
45
  * Autoloading, modules and functions
5
  * @package Advanced_Ads
6
  * @author Thomas Maier <thomas.maier@webgilde.com>
7
  * @license GPL-2.0+
8
+ * @link https://webgilde.com
9
  * @copyright 2013-2018 Thomas Maier, webgilde GmbH
10
  *
11
  * @wordpress-plugin
12
  * Plugin Name: Advanced Ads
13
  * Plugin URI: https://wpadvancedads.com
14
  * Description: Manage and optimize your ads in WordPress
15
+ * Version: 1.8.25
16
  * Author: Thomas Maier
17
  * Author URI: https://wpadvancedads.com
18
  * Text Domain: advanced-ads
19
  * Domain Path: /languages
20
  * License: GPL-2.0+
21
+ * License URI: https://www.gnu.org/licenses/gpl-2.0.txt
22
  */
23
 
24
  // If this file is called directly, abort.
39
  // general and global slug, e.g. to store options in WP, textdomain
40
  define( 'ADVADS_SLUG', 'advanced-ads' );
41
  define( 'ADVADS_URL', 'https://wpadvancedads.com/' );
42
+ define( 'ADVADS_VERSION', '1.8.25' );
43
 
44
  /*----------------------------------------------------------------------------*
45
  * Autoloading, modules and functions
classes/ad_ajax_callbacks.php CHANGED
@@ -415,7 +415,7 @@ class Advanced_Ads_Ad_Ajax_Callbacks {
415
  }
416
 
417
  /**
418
- * Enable Adsense Page-level ads.
419
  */
420
  public function adsense_enable_pla(){
421
 
415
  }
416
 
417
  /**
418
+ * Enable Adsense Auto ads, previously "Page-Level ads"
419
  */
420
  public function adsense_enable_pla(){
421
 
classes/ad_placements.php CHANGED
@@ -337,12 +337,12 @@ class Advanced_Ads_Placements {
337
  *
338
  * @since 1.2.1
339
  * @param string $placement_id id of the placement
340
- * @param arr $options placement options
341
  * @param string $content
342
  * @return type
343
  * @link inspired by http://www.wpbeginner.com/wp-tutorials/how-to-insert-ads-within-your-post-content-in-wordpress/
344
  */
345
- public static function &inject_in_content($placement_id, $options, &$content) {
346
  if ( ! extension_loaded( 'dom' ) ) {
347
  return $content;
348
  }
@@ -382,30 +382,30 @@ class Advanced_Ads_Placements {
382
  }
383
 
384
  // parse arguments
385
- $tag = isset($options['tag']) ? $options['tag'] : 'p';
386
  $tag = preg_replace('/[^a-z0-9]/i', '', $tag); // simplify tag
387
 
388
  // allow more complex xPath expression
389
- $tag = apply_filters( 'advanced-ads-placement-content-injection-xpath', $tag, $options );
390
 
391
  if ( $tag === 'pwithoutimg' ) {
392
  $tag = 'p[not(descendant::img)]';
393
  }
394
 
395
- // only has before and after
396
- $before = isset($options['position']) && $options['position'] === 'before';
397
- $paragraph_id = isset($options['index']) ? $options['index'] : 1;
398
- $paragraph_id = max( 1, (int) $paragraph_id );
399
- $paragraph_select_from_bottom = isset($options['start_from_bottom']) && $options['start_from_bottom'];
400
-
401
  // select positions
402
  $xpath = new DOMXPath($dom);
403
  $items = $xpath->query('/html/body/' . $tag);
404
- $offset = null;
405
 
406
  $options = array(
407
  'allowEmpty' => false, // whether the tag can be empty to be counted
 
 
 
408
  );
 
 
 
 
409
  // if there are too few items at this level test nesting
410
  $options['itemLimit'] = $tag === 'p' ? 2 : 1;
411
 
@@ -444,64 +444,68 @@ class Advanced_Ads_Placements {
444
  }
445
  }
446
 
447
- $paragraph_count = count($paragraphs);
448
- if ($paragraph_count >= $paragraph_id) {
449
- $offset = $paragraph_select_from_bottom ? $paragraph_count - $paragraph_id : $paragraph_id - 1;
450
 
451
- // test ad is emtpy
452
- $adContent = Advanced_Ads_Select::get_instance()->get_ad_by_method( $placement_id, 'placement', $options );
453
- if ( trim( $adContent, $whitespaces ) === '' ) {
454
- return $content;
455
- }
456
 
457
- // convert HTML to XML!
458
- $adDom = new DOMDocument('1.0', $wpCharset);
459
- libxml_use_internal_errors(true);
460
- // replace `</` with `<\/` in ad content when placed within `document.write()` to prevent code from breaking
461
- // source for this regex: http://stackoverflow.com/questions/17852537/preg-replace-only-specific-part-of-string
462
- $adContent = preg_replace('#(document.write.+)</(.*)#', '$1<\/$2', $adContent); // escapes all closing html tags
463
- // $adContent = preg_replace('#(document.write.+)</sc(.*)#', '$1<\/sc$2', $adContent); // only escapes closing </script> tags
464
- // $adContent = preg_replace('#(document.write[^<^)]+)</sc(.*)#', '$1<\/sc$2', $adContent); // too restrict, doesn’t work when beginning <script> tag is in the same line
465
- $adDom->loadHtml('<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=' . $wpCharset . '" /><body>' . $adContent);
466
- // log errors
467
- if ( defined ( 'WP_DEBUG' ) && WP_DEBUG && current_user_can( 'advanced_ads_manage_options' ) ) {
468
- foreach( libxml_get_errors() as $_error ) {
469
- // continue, if there is '&' symbol, but not HTML entity
470
- if ( false === stripos( $_error->message, 'htmlParseEntityRef:' ) ) {
471
- Advanced_Ads::log( 'possible content injection error for placement "' . $placement_id . '": ' . print_r( $_error, true ) );
472
- }
473
  }
474
- }
475
-
476
- // inject
477
- $node = apply_filters( 'advanced-ads-placement-content-injection-node', $paragraphs[$offset], $tag, $before );
478
- if ($before) {
479
- $refNode = $node;
480
 
481
- foreach ( $adDom->getElementsByTagName( 'body' )->item( 0 )->childNodes as $importedNode ) {
482
- $importedNode = $dom->importNode( $importedNode, true );
483
- $refNode->parentNode->insertBefore( $importedNode, $refNode );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  }
485
- } else {
486
- // append before next node or as last child to body
487
- $refNode = $node->nextSibling;
488
- if (isset($refNode)) {
 
489
 
490
  foreach ( $adDom->getElementsByTagName( 'body' )->item( 0 )->childNodes as $importedNode ) {
491
  $importedNode = $dom->importNode( $importedNode, true );
492
  $refNode->parentNode->insertBefore( $importedNode, $refNode );
493
  }
494
-
495
  } else {
496
- // append to body; -TODO using here that we only select direct children of the body tag
497
- foreach ( $adDom->getElementsByTagName( 'body' )->item( 0 )->childNodes as $importedNode ) {
498
- $importedNode = $dom->importNode( $importedNode, true );
499
- $node->parentNode->appendChild( $importedNode );
 
 
 
 
 
 
 
 
 
 
 
500
  }
501
  }
502
- }
503
 
504
- libxml_use_internal_errors(false);
 
505
  /**
506
  * show a warning to ad admins in the Ad Health bar in the frontend, when
507
  *
@@ -515,7 +519,7 @@ class Advanced_Ads_Placements {
515
 
516
  // check if there are more elements without limitation
517
  $all_items = $xpath->query( '//' . $tag );
518
- if( $paragraph_id <= $all_items->length ){
519
  // add a warning to ad health
520
  add_filter( 'advanced-ads-ad-health-nodes', array( 'Advanced_Ads_Placements', 'add_ad_health_node' ) );
521
  }
337
  *
338
  * @since 1.2.1
339
  * @param string $placement_id id of the placement
340
+ * @param arr $placement_opts placement options
341
  * @param string $content
342
  * @return type
343
  * @link inspired by http://www.wpbeginner.com/wp-tutorials/how-to-insert-ads-within-your-post-content-in-wordpress/
344
  */
345
+ public static function &inject_in_content($placement_id, $placement_opts, &$content) {
346
  if ( ! extension_loaded( 'dom' ) ) {
347
  return $content;
348
  }
382
  }
383
 
384
  // parse arguments
385
+ $tag = isset($placement_opts['tag']) ? $placement_opts['tag'] : 'p';
386
  $tag = preg_replace('/[^a-z0-9]/i', '', $tag); // simplify tag
387
 
388
  // allow more complex xPath expression
389
+ $tag = apply_filters( 'advanced-ads-placement-content-injection-xpath', $tag, $placement_opts );
390
 
391
  if ( $tag === 'pwithoutimg' ) {
392
  $tag = 'p[not(descendant::img)]';
393
  }
394
 
 
 
 
 
 
 
395
  // select positions
396
  $xpath = new DOMXPath($dom);
397
  $items = $xpath->query('/html/body/' . $tag);
 
398
 
399
  $options = array(
400
  'allowEmpty' => false, // whether the tag can be empty to be counted
401
+ 'paragraph_select_from_bottom' => isset($placement_opts['start_from_bottom']) && $placement_opts['start_from_bottom'],
402
+ // only has before and after
403
+ 'before' => isset($placement_opts['position']) && $placement_opts['position'] === 'before'
404
  );
405
+
406
+ $options['paragraph_id'] = isset($placement_opts['index']) ? $placement_opts['index'] : 1;
407
+ $options['paragraph_id'] = max( 1, (int) $options['paragraph_id'] );
408
+
409
  // if there are too few items at this level test nesting
410
  $options['itemLimit'] = $tag === 'p' ? 2 : 1;
411
 
444
  }
445
  }
446
 
447
+ $options['paragraph_count'] = count($paragraphs);
 
 
448
 
449
+ if ($options['paragraph_count'] >= $options['paragraph_id']) {
450
+ $offset = $options['paragraph_select_from_bottom'] ? $options['paragraph_count'] - $options['paragraph_id'] : $options['paragraph_id'] - 1;
451
+ $offsets = apply_filters( 'advanced-ads-placement-content-offsets', array( $offset ), $options, $placement_opts );
 
 
452
 
453
+ foreach ( $offsets as $offset ) {
454
+ // test ad is emtpy
455
+ $adContent = Advanced_Ads_Select::get_instance()->get_ad_by_method( $placement_id, 'placement', $options );
456
+ if ( trim( $adContent, $whitespaces ) === '' ) {
457
+ return $content;
 
 
 
 
 
 
 
 
 
 
 
458
  }
 
 
 
 
 
 
459
 
460
+ // convert HTML to XML!
461
+ $adDom = new DOMDocument('1.0', $wpCharset);
462
+ libxml_use_internal_errors(true);
463
+ // replace `</` with `<\/` in ad content when placed within `document.write()` to prevent code from breaking
464
+ // source for this regex: http://stackoverflow.com/questions/17852537/preg-replace-only-specific-part-of-string
465
+ $adContent = preg_replace('#(document.write.+)</(.*)#', '$1<\/$2', $adContent); // escapes all closing html tags
466
+ // $adContent = preg_replace('#(document.write.+)</sc(.*)#', '$1<\/sc$2', $adContent); // only escapes closing </script> tags
467
+ // $adContent = preg_replace('#(document.write[^<^)]+)</sc(.*)#', '$1<\/sc$2', $adContent); // too restrict, doesn’t work when beginning <script> tag is in the same line
468
+ $adDom->loadHtml('<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=' . $wpCharset . '" /><body>' . $adContent);
469
+ // log errors
470
+ if ( defined ( 'WP_DEBUG' ) && WP_DEBUG && current_user_can( 'advanced_ads_manage_options' ) ) {
471
+ foreach( libxml_get_errors() as $_error ) {
472
+ // continue, if there is '&' symbol, but not HTML entity
473
+ if ( false === stripos( $_error->message, 'htmlParseEntityRef:' ) ) {
474
+ Advanced_Ads::log( 'possible content injection error for placement "' . $placement_id . '": ' . print_r( $_error, true ) );
475
+ }
476
+ }
477
  }
478
+
479
+ // inject
480
+ $node = apply_filters( 'advanced-ads-placement-content-injection-node', $paragraphs[$offset], $tag, $options['before'] );
481
+ if ( $options['before'] ) {
482
+ $refNode = $node;
483
 
484
  foreach ( $adDom->getElementsByTagName( 'body' )->item( 0 )->childNodes as $importedNode ) {
485
  $importedNode = $dom->importNode( $importedNode, true );
486
  $refNode->parentNode->insertBefore( $importedNode, $refNode );
487
  }
 
488
  } else {
489
+ // append before next node or as last child to body
490
+ $refNode = $node->nextSibling;
491
+ if (isset($refNode)) {
492
+
493
+ foreach ( $adDom->getElementsByTagName( 'body' )->item( 0 )->childNodes as $importedNode ) {
494
+ $importedNode = $dom->importNode( $importedNode, true );
495
+ $refNode->parentNode->insertBefore( $importedNode, $refNode );
496
+ }
497
+
498
+ } else {
499
+ // append to body; -TODO using here that we only select direct children of the body tag
500
+ foreach ( $adDom->getElementsByTagName( 'body' )->item( 0 )->childNodes as $importedNode ) {
501
+ $importedNode = $dom->importNode( $importedNode, true );
502
+ $node->parentNode->appendChild( $importedNode );
503
+ }
504
  }
505
  }
 
506
 
507
+ libxml_use_internal_errors(false);
508
+ }
509
  /**
510
  * show a warning to ad admins in the Ad Health bar in the frontend, when
511
  *
519
 
520
  // check if there are more elements without limitation
521
  $all_items = $xpath->query( '//' . $tag );
522
+ if( $options['paragraph_id'] <= $all_items->length ){
523
  // add a warning to ad health
524
  add_filter( 'advanced-ads-ad-health-nodes', array( 'Advanced_Ads_Placements', 'add_ad_health_node' ) );
525
  }
classes/checks.php CHANGED
@@ -163,9 +163,6 @@ class Advanced_Ads_Checks {
163
  if( class_exists( 'ITSEC_Core', false ) && defined ( 'AAP_VERSION' ) ){ // iThemes Security, but only if Pro is enabled
164
  $conflicting_plugins[] = 'iThemes Security';
165
  }
166
- if( class_exists('q2w3_fixed_widget', false) ){ // Q2W3 Fixed Widget
167
- $conflicting_plugins[] = 'Q2W3 Fixed Widget';
168
- }
169
 
170
  return $conflicting_plugins;
171
  }
163
  if( class_exists( 'ITSEC_Core', false ) && defined ( 'AAP_VERSION' ) ){ // iThemes Security, but only if Pro is enabled
164
  $conflicting_plugins[] = 'iThemes Security';
165
  }
 
 
 
166
 
167
  return $conflicting_plugins;
168
  }
classes/frontend_checks.php CHANGED
@@ -69,14 +69,14 @@ class Advanced_Ads_Frontend_Checks {
69
  )
70
  ) );*/
71
 
72
- // check if AdSense loads QuickStart ads
73
  // Hidden, will be shown using js.
74
  if( ! isset( $adsense_options['violation-warnings-disable'] ) ) {
75
  $nodes[] = array( 'type' => 2, 'data' => array(
76
  'parent' => 'advanced_ads_ad_health',
77
- 'id' => 'advanced_ads_quickstart_displayed',
78
  'title' => __( 'Random AdSense ads', 'advanced-ads' ),
79
- 'href' => ADVADS_URL . 'adsense-in-random-positions-quickstart/#utm_source=advancedads&utm_medium=link&utm_campaign=frontend-quickstart-ads',
80
  'meta' => array(
81
  'class' => 'hidden advanced_ads_ad_health_warning',
82
  'target' => '_blank'
@@ -455,25 +455,25 @@ class Advanced_Ads_Frontend_Checks {
455
  }
456
  };
457
 
458
- // highlight AdSense QuickStart ads 3 seconds after site loaded
459
  setTimeout( function(){
460
- advanced_ads_ready( advads_highlight_adsense_quickstart )
461
  }, 3000 );
462
- function advads_highlight_adsense_quickstart(){
463
  if ( ! window.jQuery ) {
464
  window.console && window.console.log( 'Advanced Ads: jQuery not found. Some Ad Health warnings will not be shown' );
465
  return;
466
  }
467
- var quickstart_ads = jQuery(document).find('.google-auto-placed');
468
- jQuery( '<p class="advads-quickstart-hint" style="background-color:#0085ba;color:#fff;font-size:0.8em;padding:5px;"><?php
469
- printf(__( 'This ad was automatically placed here by AdSense. <a href="%s" target="_blank" style="color:#fff;border-color:#fff;">Click here to learn more</a>.', 'advanced-ads' ), ADVADS_URL . 'adsense-in-random-positions/#utm_source=advanced-ads&utm_medium=link&utm_campaign=frontend-quickstart-ads' );
470
- ?></p>' ).prependTo( quickstart_ads );
471
- // show quickstart warning in Adhealth Bar if relevant
472
- if( quickstart_ads.length ){
473
- var advads_quickstart_link = document.querySelector( '#wp-admin-bar-advanced_ads_quickstart_displayed.hidden' );
474
- console.log( advads_quickstart_link );
475
- if ( advads_quickstart_link ) {
476
- advads_quickstart_link.className = advads_quickstart_link.className.replace( 'hidden', '' );
477
  }
478
  advanced_ads_frontend_checks.showCount();
479
  }
69
  )
70
  ) );*/
71
 
72
+ // check if AdSense loads Auto Ads ads
73
  // Hidden, will be shown using js.
74
  if( ! isset( $adsense_options['violation-warnings-disable'] ) ) {
75
  $nodes[] = array( 'type' => 2, 'data' => array(
76
  'parent' => 'advanced_ads_ad_health',
77
+ 'id' => 'advanced_ads_autoads_displayed',
78
  'title' => __( 'Random AdSense ads', 'advanced-ads' ),
79
+ 'href' => ADVADS_URL . 'adsense-in-random-positions-auto-ads/#utm_source=advancedads&utm_medium=link&utm_campaign=frontend-autoads-ads',
80
  'meta' => array(
81
  'class' => 'hidden advanced_ads_ad_health_warning',
82
  'target' => '_blank'
455
  }
456
  };
457
 
458
+ // highlight AdSense Auto Ads ads 3 seconds after site loaded
459
  setTimeout( function(){
460
+ advanced_ads_ready( advads_highlight_adsense_autoads )
461
  }, 3000 );
462
+ function advads_highlight_adsense_autoads(){
463
  if ( ! window.jQuery ) {
464
  window.console && window.console.log( 'Advanced Ads: jQuery not found. Some Ad Health warnings will not be shown' );
465
  return;
466
  }
467
+ var autoads_ads = jQuery(document).find('.google-auto-placed');
468
+ jQuery( '<p class="advads-autoads-hint" style="background-color:#0085ba;color:#fff;font-size:0.8em;padding:5px;"><?php
469
+ printf(__( 'This ad was automatically placed here by AdSense. <a href="%s" target="_blank" style="color:#fff;border-color:#fff;">Click here to learn more</a>.', 'advanced-ads' ), ADVADS_URL . 'adsense-in-random-positions-auto-ads/#utm_source=advanced-ads&utm_medium=link&utm_campaign=frontend-autoads-ads' );
470
+ ?></p>' ).prependTo( autoads_ads );
471
+ // show Auto Ads warning in Adhealth Bar if relevant
472
+ if( autoads_ads.length ){
473
+ var advads_autoads_link = document.querySelector( '#wp-admin-bar-advanced_ads_autoads_displayed.hidden' );
474
+ console.log( advads_autoads_link );
475
+ if ( advads_autoads_link ) {
476
+ advads_autoads_link.className = advads_autoads_link.className.replace( 'hidden', '' );
477
  }
478
  advanced_ads_frontend_checks.showCount();
479
  }
classes/plugin.php CHANGED
@@ -507,7 +507,7 @@ class Advanced_Ads_Plugin {
507
  $this->frontend_prefix = preg_match( '/[A-Za-z][A-Za-z0-9_]{4}/', $host, $result ) ? $result[0] . '-' : Advanced_Ads_Plugin::DEFAULT_FRONTEND_PREFIX;
508
  }
509
  } else {
510
- $this->frontend_prefix = $options['front-prefix'];
511
  }
512
  }
513
  return $this->frontend_prefix;
507
  $this->frontend_prefix = preg_match( '/[A-Za-z][A-Za-z0-9_]{4}/', $host, $result ) ? $result[0] . '-' : Advanced_Ads_Plugin::DEFAULT_FRONTEND_PREFIX;
508
  }
509
  } else {
510
+ $this->frontend_prefix = esc_attr( $options['front-prefix'] );
511
  }
512
  }
513
  return $this->frontend_prefix;
classes/widget.php CHANGED
@@ -24,6 +24,8 @@ class Advanced_Ads_Widget extends WP_Widget {
24
  $base_id = Advanced_Ads_Widget::get_base_id();
25
 
26
  parent::__construct( $base_id,'Advanced Ads', $widget_ops, $control_ops );
 
 
27
  }
28
 
29
  function widget($args, $instance) {
@@ -38,6 +40,8 @@ class Advanced_Ads_Widget extends WP_Widget {
38
  return;
39
  }
40
 
 
 
41
  echo $before_widget;
42
  if ( ! empty( $title ) ) {
43
  echo $before_title . $title . $after_title;
@@ -50,6 +54,12 @@ class Advanced_Ads_Widget extends WP_Widget {
50
  $instance = $old_instance;
51
  $instance['title'] = $new_instance['title'];
52
  $instance['item_id'] = $new_instance['item_id'];
 
 
 
 
 
 
53
  return $instance;
54
  }
55
 
@@ -176,4 +186,64 @@ class Advanced_Ads_Widget extends WP_Widget {
176
  return $prefix2 . 'widget';
177
  }
178
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  }
24
  $base_id = Advanced_Ads_Widget::get_base_id();
25
 
26
  parent::__construct( $base_id,'Advanced Ads', $widget_ops, $control_ops );
27
+
28
+ add_filter( 'q2w3-fixed-widgets', array( $this, 'q2w3_replace_frontend_id' ) );
29
  }
30
 
31
  function widget($args, $instance) {
40
  return;
41
  }
42
 
43
+ $before_widget = $this->maybe_replace_frontend_id( $before_widget, $instance );
44
+
45
  echo $before_widget;
46
  if ( ! empty( $title ) ) {
47
  echo $before_title . $title . $after_title;
54
  $instance = $old_instance;
55
  $instance['title'] = $new_instance['title'];
56
  $instance['item_id'] = $new_instance['item_id'];
57
+
58
+ // Allow to remove/replace id for new widgets and if it was allowed earlier.
59
+ if ( $old_instance === array() || ! empty( $old_instance['remove-widget-id'] ) ) {
60
+ $instance['remove-widget-id'] = true;
61
+ }
62
+ return $instance;
63
  return $instance;
64
  }
65
 
186
  return $prefix2 . 'widget';
187
  }
188
 
189
+ /**
190
+ * Get frontend widget id.
191
+ *
192
+ * @param int $number Unique ID number of the current widget instance.
193
+ * @return str
194
+ */
195
+ private function get_frontend_id( $number ) {
196
+ $prefix = Advanced_Ads_Plugin::get_instance()->get_frontend_prefix();
197
+ return $prefix . 'widget-' . $number;
198
+ }
199
+
200
+ /**
201
+ * Make it harder for ad blockers to block the widget.
202
+ *
203
+ * @param str $before_widget
204
+ * @param array $instance Settings for the current widget instance.
205
+ * @return str $before_widget
206
+ */
207
+ private function maybe_replace_frontend_id( $before_widget, $instance ) {
208
+ if ( ! empty( $instance['remove-widget-id'] ) ) {
209
+ $pattern = '#\sid=("|\')[^"\']+["\']#';
210
+ if ( ( defined( 'ADVANCED_ADS_SHOW_WIDGET_ID' ) && ADVANCED_ADS_SHOW_WIDGET_ID )
211
+ || ! empty( $instance['q2w3_fixed_widget'] )
212
+ ) {
213
+ // Replace id.
214
+ $number = ! empty( $this->number ) ? $this->number : '';
215
+ $before_widget = preg_replace( $pattern, ' id=$01' . $this->get_frontend_id( $number ) . '$01', $before_widget );
216
+ } else {
217
+ // Remove id.
218
+ $before_widget = preg_replace( $pattern, '', $before_widget );
219
+ }
220
+ }
221
+ return $before_widget;
222
+ }
223
+
224
+ /**
225
+ * Provide the 'Q2W3 Fixed Widget' plugin with the new frontend widget id.
226
+ *
227
+ * @param array $sidebars_widgets
228
+ * @return array $sidebars_widgets
229
+ */
230
+ public function q2w3_replace_frontend_id( $sidebars_widgets ) {
231
+ foreach ( $sidebars_widgets as $sidebar => $widgets ) {
232
+ foreach ( $widgets as $k => $widget ) {
233
+ $pos = strrpos( $widget, '-' );
234
+ $option_name = substr( $widget, 0, $pos );
235
+ $number = substr( $widget, $pos + 1 );
236
+
237
+ if ( $option_name === self::get_base_id() ) {
238
+ $widget_options = get_option('widget_' . $option_name);
239
+ if ( ! empty( $widget_options[ $number ]['remove-widget-id'] ) ) {
240
+ $sidebars_widgets[ $sidebar ][ $k ] = $this->get_frontend_id( $number );
241
+ }
242
+ }
243
+
244
+ }
245
+ }
246
+ return $sidebars_widgets;
247
+ }
248
+
249
  }
modules/gadsense/admin/admin.php CHANGED
@@ -7,6 +7,8 @@ class Advanced_Ads_AdSense_Admin {
7
  private static $instance = null;
8
  protected $notice = null;
9
  private $settings_page_hook = 'advanced-ads-adsense-settings-page';
 
 
10
 
11
  private function __construct() {
12
  $this->data = Advanced_Ads_AdSense_Data::get_instance();
@@ -121,9 +123,9 @@ class Advanced_Ads_AdSense_Admin {
121
 
122
  // get settings page hook
123
  $hook = $this->settings_page_hook;
124
-
125
  register_setting( ADVADS_SLUG . '-adsense', ADVADS_SLUG . '-adsense', array($this, 'sanitize_settings') );
126
-
127
  // add new section
128
  add_settings_section(
129
  'advanced_ads_adsense_setting_section',
@@ -139,7 +141,7 @@ class Advanced_Ads_AdSense_Admin {
139
  array($this, 'render_settings_adsense_id'),
140
  $hook,
141
  'advanced_ads_adsense_setting_section'
142
- );
143
 
144
  // add setting field for adsense limit
145
  add_settings_field(
@@ -150,10 +152,10 @@ class Advanced_Ads_AdSense_Admin {
150
  'advanced_ads_adsense_setting_section'
151
  );
152
 
153
- // activate page-level ads
154
  add_settings_field(
155
  'adsense-page-level',
156
- __( 'Activate Page-Level ads', 'advanced-ads' ),
157
  array($this, 'render_settings_adsense_page_level'),
158
  $hook,
159
  'advanced_ads_adsense_setting_section'
@@ -187,12 +189,6 @@ class Advanced_Ads_AdSense_Admin {
187
  */
188
  public function render_settings_section_callback(){
189
  // for whatever purpose there might come
190
- $adsense_id = $this->data->get_adsense_id();
191
- if( ! $adsense_id ){
192
- ?><p class="advads-error-message"><?php
193
- printf(__( 'Please enter your Publisher ID in order to use AdSense on your page. See the <a href="%s" target="_blank">manual</a> for more information.', 'advanced-ads' ), ADVADS_URL . 'manual/ad-types/adsense-ads/#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-adsense' );
194
- ?></p><?php
195
- }
196
  }
197
 
198
  /**
@@ -204,7 +200,16 @@ class Advanced_Ads_AdSense_Admin {
204
  $adsense_id = $this->data->get_adsense_id();
205
 
206
  ?><input type="text" name="<?php echo GADSENSE_OPT_NAME; ?>[adsense-id]" id="adsense-id" size="32" value="<?php echo $adsense_id; ?>" />
 
 
 
207
  <p class="description"><?php _e( 'Your AdSense Publisher ID <em>(pub-xxxxxxxxxxxxxx)</em>', 'advanced-ads' ) ?></p><?php
 
 
 
 
 
 
208
  }
209
 
210
  /**
@@ -238,9 +243,8 @@ class Advanced_Ads_AdSense_Admin {
238
  $page_level = $options['page-level-enabled'];
239
 
240
  ?><label><input type="checkbox" name="<?php echo GADSENSE_OPT_NAME; ?>[page-level-enabled]" value="1" <?php checked( $page_level ); ?> />
241
- <?php _e( 'Insert Page-Level ads code on all pages.', 'advanced-ads' ); ?></label>
242
- <p class="description"><?php _e( 'You still need to enable Page-Level ads in your AdSense account. See <a href="https://support.google.com/adsense/answer/6245304" target="_blank">AdSense Help</a> (requires AdSense-login) for more information.', 'advanced-ads' ); ?></p>
243
- <p class="description"><?php printf(__( 'Please notice that this code might also activate QuickStart ads. Please read <a href="%s" target="_blank">this article</a> if <strong>ads appear in random places</strong>.', 'advanced-ads' ), ADVADS_URL . 'adsense-in-random-positions-quickstart/#utm_source=advanced-ads&utm_medium=link&utm_campaign=backend-quickstart-ads' ); ?></p><?php
244
  }
245
 
246
  /**
@@ -254,7 +258,7 @@ class Advanced_Ads_AdSense_Admin {
254
 
255
  ?><label><input type="checkbox" name="<?php echo GADSENSE_OPT_NAME; ?>[violation-warnings-disable]" value="1" <?php checked( 1, $disable_violation_warnings ); ?> />
256
  <?php _e( 'Disable warnings about potential violations of the AdSense terms.', 'advanced-ads' ); ?></label>
257
- <p class="description"><?php printf(__( 'Our <a href="%s" target="_blank">Ad Health</a> feature monitors if AdSense is implemented correctly on your site. It also considers ads not managed with Advanced Ads. Enable this option to remove these checks', 'advanced-ads' ), ADVADS_URL . 'adsense-in-random-positions-quickstart/#utm_source=advanced-ads&utm_medium=link&utm_campaign=backend-quickstart-ads' ); ?></p><?php
258
  }
259
 
260
  /**
7
  private static $instance = null;
8
  protected $notice = null;
9
  private $settings_page_hook = 'advanced-ads-adsense-settings-page';
10
+
11
+ const ADSENSE_NEW_ACCOUNT_LINK = 'https://www.google.com/adsense/start/?utm_source=AdvancedAdsPlugIn&utm_medium=partnerships&utm_campaign=AdvancedAdsPartner';
12
 
13
  private function __construct() {
14
  $this->data = Advanced_Ads_AdSense_Data::get_instance();
123
 
124
  // get settings page hook
125
  $hook = $this->settings_page_hook;
126
+
127
  register_setting( ADVADS_SLUG . '-adsense', ADVADS_SLUG . '-adsense', array($this, 'sanitize_settings') );
128
+
129
  // add new section
130
  add_settings_section(
131
  'advanced_ads_adsense_setting_section',
141
  array($this, 'render_settings_adsense_id'),
142
  $hook,
143
  'advanced_ads_adsense_setting_section'
144
+ );
145
 
146
  // add setting field for adsense limit
147
  add_settings_field(
152
  'advanced_ads_adsense_setting_section'
153
  );
154
 
155
+ // activate AdSense verification code and Auto ads (previously Page-Level ads)
156
  add_settings_field(
157
  'adsense-page-level',
158
+ __( 'Verification code & Auto ads', 'advanced-ads' ),
159
  array($this, 'render_settings_adsense_page_level'),
160
  $hook,
161
  'advanced_ads_adsense_setting_section'
189
  */
190
  public function render_settings_section_callback(){
191
  // for whatever purpose there might come
 
 
 
 
 
 
192
  }
193
 
194
  /**
200
  $adsense_id = $this->data->get_adsense_id();
201
 
202
  ?><input type="text" name="<?php echo GADSENSE_OPT_NAME; ?>[adsense-id]" id="adsense-id" size="32" value="<?php echo $adsense_id; ?>" />
203
+ <?php if( empty( trim( $adsense_id ) ) ) :
204
+ ?><a class="button button-primary" target="_blank" href="<?php echo self::ADSENSE_NEW_ACCOUNT_LINK; ?>"><?php _e( 'Get a free AdSense account', 'advanced-ads' ); ?></a><?php
205
+ endif; ?>
206
  <p class="description"><?php _e( 'Your AdSense Publisher ID <em>(pub-xxxxxxxxxxxxxx)</em>', 'advanced-ads' ) ?></p><?php
207
+
208
+ if( ! $adsense_id ){
209
+ ?><p class="advads-error-message"><?php
210
+ printf(__( 'Please enter your Publisher ID in order to use AdSense on your page. See the <a href="%s" target="_blank">manual</a> for more information.', 'advanced-ads' ), ADVADS_URL . 'manual/ad-types/adsense-ads/#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-adsense' );
211
+ ?></p><?php
212
+ }
213
  }
214
 
215
  /**
243
  $page_level = $options['page-level-enabled'];
244
 
245
  ?><label><input type="checkbox" name="<?php echo GADSENSE_OPT_NAME; ?>[page-level-enabled]" value="1" <?php checked( $page_level ); ?> />
246
+ <?php _e( 'Insert the AdSense header code used for verification and the Auto Ads feature.', 'advanced-ads' ); ?></label>
247
+ <p class="description"><?php printf(__( 'This code might also activate Auto ads. Please read <a href="%s" target="_blank">this article</a> if <strong>ads appear in random places</strong>.', 'advanced-ads' ), ADVADS_URL . 'adsense-in-random-positions-auto-ads/#utm_source=advanced-ads&utm_medium=link&utm_campaign=backend-autoads-ads' ); ?></p><?php
 
248
  }
249
 
250
  /**
258
 
259
  ?><label><input type="checkbox" name="<?php echo GADSENSE_OPT_NAME; ?>[violation-warnings-disable]" value="1" <?php checked( 1, $disable_violation_warnings ); ?> />
260
  <?php _e( 'Disable warnings about potential violations of the AdSense terms.', 'advanced-ads' ); ?></label>
261
+ <p class="description"><?php printf(__( 'Our <a href="%s" target="_blank">Ad Health</a> feature monitors if AdSense is implemented correctly on your site. It also considers ads not managed with Advanced Ads. Enable this option to remove these checks', 'advanced-ads' ), ADVADS_URL . 'manual/ad-health/#utm_source=advanced-ads&utm_medium=link&utm_campaign=backend-autoads-ads' ); ?></p><?php
262
  }
263
 
264
  /**
modules/gadsense/admin/assets/js/new-ad.js CHANGED
@@ -271,7 +271,7 @@
271
  });
272
 
273
  /**
274
- * Show a message depending on whether Page-Level ads are enabled.
275
  */
276
  function showPageLevelAdMessage() {
277
  var $msg = $( '<p class="advads-success-message" />' ).appendTo ( '#pastecode-msg' );
271
  });
272
 
273
  /**
274
+ * Show a message depending on whether Auto ads are enabled.
275
  */
276
  function showPageLevelAdMessage() {
277
  var $msg = $( '<p class="advads-success-message" />' ).appendTo ( '#pastecode-msg' );
modules/gadsense/admin/views/adsense-ad-parameters.php CHANGED
@@ -19,7 +19,11 @@ $sizing_array = $db->get_responsive_sizing();
19
  ?>
20
  <input type="hidden" id="advads-ad-content-adsense" name="advanced_ad[content]" value="<?php echo esc_attr( $json_content ); ?>" />
21
  <input type="hidden" name="unit_id" id="unit_id" value="<?php echo esc_attr( $unit_id ); ?>" />
22
- <?php if ( $use_paste_code ) : ?>
 
 
 
 
23
  <div class="advads-adsense-code" <?php if( !empty( $unit_code ) ): echo 'style="display: none;"'; endif; ?>>
24
  <p class="description"><?php _e( 'Copy the ad code from your AdSense account, paste it into the area below and click on <em>Get details</em>.', 'advanced-ads' ); ?></p>
25
  <textarea rows="10" cols="40" class="advads-adsense-content"></textarea>
19
  ?>
20
  <input type="hidden" id="advads-ad-content-adsense" name="advanced_ad[content]" value="<?php echo esc_attr( $json_content ); ?>" />
21
  <input type="hidden" name="unit_id" id="unit_id" value="<?php echo esc_attr( $unit_id ); ?>" />
22
+ <?php if( empty( $pub_id ) ) :
23
+ ?><p><a class="button button-primary" target="_blank" href="<?php echo Advanced_Ads_AdSense_Admin::ADSENSE_NEW_ACCOUNT_LINK; ?>"><?php _e( 'Get a free AdSense account', 'advanced-ads' );
24
+ ?></a></p><?php
25
+ endif;
26
+ if ( $use_paste_code ) : ?>
27
  <div class="advads-adsense-code" <?php if( !empty( $unit_code ) ): echo 'style="display: none;"'; endif; ?>>
28
  <p class="description"><?php _e( 'Copy the ad code from your AdSense account, paste it into the area below and click on <em>Get details</em>.', 'advanced-ads' ); ?></p>
29
  <textarea rows="10" cols="40" class="advads-adsense-content"></textarea>
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: ads, ad manager, ad widget, ad rotation, adsense, advertise, advertisement
5
  Requires at least: 4.6
6
  Tested up to: 4.9
7
  Requires PHP: 5.2
8
- Stable tag: 1.8.24
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -100,7 +100,7 @@ Placements to insert ads in pre-defined positions in your theme and content. [Li
100
  * change type and sizes of an ad without going into your AdSense account
101
  * optional limit to 3 AdSense banners
102
  * hide AdSense advertisements on 404 pages by default (to comply with AdSense terms)
103
- * insert AdSense verification and AdSense Page-Level ads
104
  * Ad Health integration and AdSense violation checks
105
  * option to make the AdSense background transparent
106
  * place AdSense In-feed ads using the also free [In-feed add-on](https://wordpress.org/plugins/advanced-ads-adsense-in-feed/)
@@ -233,6 +233,13 @@ Yes. Advanced Ads is based on WordPress standards and therefore easily customiza
233
 
234
  == Changelog ==
235
 
 
 
 
 
 
 
 
236
  = 1.8.24 =
237
 
238
  * fixed minor conflict caused by Bridge theme
5
  Requires at least: 4.6
6
  Tested up to: 4.9
7
  Requires PHP: 5.2
8
+ Stable tag: 1.8.25
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
100
  * change type and sizes of an ad without going into your AdSense account
101
  * optional limit to 3 AdSense banners
102
  * hide AdSense advertisements on 404 pages by default (to comply with AdSense terms)
103
+ * insert AdSense verification and AdSense Auto Ads (previously called Page-Level ads and QuickStart)
104
  * Ad Health integration and AdSense violation checks
105
  * option to make the AdSense background transparent
106
  * place AdSense In-feed ads using the also free [In-feed add-on](https://wordpress.org/plugins/advanced-ads-adsense-in-feed/)
233
 
234
  == Changelog ==
235
 
236
+ = 1.8.25 =
237
+
238
+ * updated labels and links for AdSense Page-Level ads and QuickStart since both are now combined as "Auto Ads"
239
+ * added link to create new AdSense account
240
+ * removed "Remove Widget ID" option. No longer needed after fixing a compatibility issue with Q2W3 Fixed Widget plugin
241
+ * prepared for Pro feature to repeat an ad multiple times by injecting it into the content
242
+
243
  = 1.8.24 =
244
 
245
  * fixed minor conflict caused by Bridge theme