Advanced Ads - Version 1.26.0

Version Description

  • overwrite existing options when importing new options
  • add possibility to export privacy, ads.txt and Google AdSense options
  • remove duplicate inline styles for placements with passive cache-busting and activated TCF 2.0 privacy option
  • adjust the Advanced Ads block layout to the default WordPress block layout
  • add migration from Advanced Ads widget to Advanced Ads block
  • fix saving of additional CSS class in Advanced Ads block
  • make placement deletion confirmation dialogue translatable
  • add WebP as allowed image media type for exports
Download this release

Release Info

Developer advancedads
Plugin Icon 128x128 Advanced Ads
Version 1.26.0
Comparing to
See all releases

Code changes from version 1.25.1 to 1.26.0

admin/assets/js/admin.js CHANGED
@@ -189,7 +189,7 @@ jQuery( document ).ready( function ( $ ) {
189
 
190
  jQuery( '.advads-delete-tag' ).each( function () {
191
  jQuery( this ).on( 'click', function () {
192
- var r = confirm( 'Wirklich löschen?' );
193
  if ( r === true ) {
194
  var row = jQuery( this ).parents( '.advanced-ads-placement-row' );
195
  row.find( '.advads-placements-item-delete' ).prop( 'checked', true );
@@ -240,29 +240,6 @@ jQuery( document ).ready( function ( $ ) {
240
  $( '.advads-output-wrapper-id-error' ).addClass( 'advads-error-message' ).css( 'display', 'block' )
241
  }
242
  } )
243
- /**
244
- * Automatically open all options and show usage link when this is the placement linked in the URL
245
- * also highlight the box with an effect for a short time.
246
- * Use attribute selector to avoid the need to escape the selector.
247
- */
248
- function sanitize( string ) {
249
- var map = {
250
- '&': '&',
251
- '<': '&lt;',
252
- '>': '&gt;',
253
- '"': '&quot;',
254
- '\'': '&#x27;',
255
- '/': '&#x2F;'
256
- };
257
- return string.replace( /[&<>"'/]/ig, function ( match ) {
258
- return map[match];
259
- } );
260
- }
261
-
262
- var single_placement_slug = '#' + sanitize( window.location.hash.substr( 1 ) );
263
- if ( jQuery( single_placement_slug ).length ) {
264
- jQuery( single_placement_slug ).find( '.advads-toggle-link + div, .advads-usage' ).show();
265
- }
266
 
267
  // group page: add ad to group
268
  $( '.advads-group-add-ad button' ).on( 'click', function () {
189
 
190
  jQuery( '.advads-delete-tag' ).each( function () {
191
  jQuery( this ).on( 'click', function () {
192
+ var r = confirm( window.advadstxt.delete_placement_confirmation );
193
  if ( r === true ) {
194
  var row = jQuery( this ).parents( '.advanced-ads-placement-row' );
195
  row.find( '.advads-placements-item-delete' ).prop( 'checked', true );
240
  $( '.advads-output-wrapper-id-error' ).addClass( 'advads-error-message' ).css( 'display', 'block' )
241
  }
242
  } )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
  // group page: add ad to group
245
  $( '.advads-group-add-ad button' ).on( 'click', function () {
admin/class-advanced-ads-admin.php CHANGED
@@ -213,22 +213,23 @@ class Advanced_Ads_Admin {
213
 
214
  // register admin.js translations.
215
  $translation_array = array(
216
- 'condition_or' => __( 'or', 'advanced-ads' ),
217
- 'condition_and' => __( 'and', 'advanced-ads' ),
218
- 'after_paragraph_promt' => __( 'After which paragraph?', 'advanced-ads' ),
219
- 'page_level_ads_enabled' => $auto_ads_strings['enabled'],
220
- 'today' => __( 'Today', 'advanced-ads' ),
221
- 'yesterday' => __( 'Yesterday', 'advanced-ads' ),
222
- 'this_month' => __( 'This Month', 'advanced-ads' ),
223
  /* translators: 1: The number of days. */
224
- 'last_n_days' => __( 'Last %1$d days', 'advanced-ads' ),
225
  /* translators: 1: An error message. */
226
- 'error_message' => __( 'An error occurred: %1$s' ),
227
- 'all' => __( 'All', 'advanced-ads' ),
228
- 'no_results' => __( 'There were no results returned for this ad. Please make sure it is active, generating impressions and double check your ad parameters.', 'advanced-ads' ),
229
- 'show_inactive_ads' => __( 'Show inactive ads', 'advanced-ads' ),
230
- 'hide_inactive_ads' => __( 'Hide inactive ads', 'advanced-ads' ),
231
- 'display_conditions_form_name' => Advanced_Ads_Display_Conditions::FORM_NAME, // not meant for translation.
 
232
  );
233
 
234
  wp_localize_script( $this->plugin_slug . '-admin-script', 'advadstxt', $translation_array );
213
 
214
  // register admin.js translations.
215
  $translation_array = array(
216
+ 'condition_or' => __( 'or', 'advanced-ads' ),
217
+ 'condition_and' => __( 'and', 'advanced-ads' ),
218
+ 'after_paragraph_promt' => __( 'After which paragraph?', 'advanced-ads' ),
219
+ 'page_level_ads_enabled' => $auto_ads_strings['enabled'],
220
+ 'today' => __( 'Today', 'advanced-ads' ),
221
+ 'yesterday' => __( 'Yesterday', 'advanced-ads' ),
222
+ 'this_month' => __( 'This Month', 'advanced-ads' ),
223
  /* translators: 1: The number of days. */
224
+ 'last_n_days' => __( 'Last %1$d days', 'advanced-ads' ),
225
  /* translators: 1: An error message. */
226
+ 'error_message' => __( 'An error occurred: %1$s' ),
227
+ 'all' => __( 'All', 'advanced-ads' ),
228
+ 'no_results' => __( 'There were no results returned for this ad. Please make sure it is active, generating impressions and double check your ad parameters.', 'advanced-ads' ),
229
+ 'show_inactive_ads' => __( 'Show inactive ads', 'advanced-ads' ),
230
+ 'hide_inactive_ads' => __( 'Hide inactive ads', 'advanced-ads' ),
231
+ 'display_conditions_form_name' => Advanced_Ads_Display_Conditions::FORM_NAME, // not meant for translation.
232
+ 'delete_placement_confirmation' => __( 'Permanently delete this placement?', 'advanced-ads' ),
233
  );
234
 
235
  wp_localize_script( $this->plugin_slug . '-admin-script', 'advadstxt', $translation_array );
admin/includes/class-licenses.php CHANGED
@@ -205,9 +205,16 @@ class Advanced_Ads_Admin_Licenses {
205
  'item_name_mismatch' => __( 'This is not the correct key for this add-on.', 'advanced-ads' ),
206
  'no_activations_left' => __( 'There are no activations left.', 'advanced-ads' )
207
  . '&nbsp;'
208
- . sprintf( // translators: %1$s is a starting link tag, %2$s is the closing one.
 
209
  __( 'You can manage activations in %1$syour account%2$s.', 'advanced-ads' ),
210
- '<a href="' . ADVADS_URL . 'account/" target="_blank">',
 
 
 
 
 
 
211
  '</a>'
212
  ),
213
  );
205
  'item_name_mismatch' => __( 'This is not the correct key for this add-on.', 'advanced-ads' ),
206
  'no_activations_left' => __( 'There are no activations left.', 'advanced-ads' )
207
  . '&nbsp;'
208
+ . sprintf(
209
+ /* translators: %1$s is a starting link tag, %2$s is the closing one. */
210
  __( 'You can manage activations in %1$syour account%2$s.', 'advanced-ads' ),
211
+ '<a href="' . ADVADS_URL . 'account/#utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-licenses-activations-left" target="_blank">',
212
+ '</a>'
213
+ ) . '&nbsp;'
214
+ . sprintf(
215
+ /* translators: %1$s is a starting link tag, %2$s is the closing one. */
216
+ __( '%1$sUpgrade%2$s for more activations.', 'advanced-ads' ),
217
+ '<a href="' . ADVADS_URL . 'account/upgrades/#utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-licenses-activations-left" target="_blank">',
218
  '</a>'
219
  ),
220
  );
admin/includes/class-settings.php CHANGED
@@ -588,13 +588,14 @@ class Advanced_Ads_Admin_Settings {
588
  $editor_role->remove_cap( 'advanced_ads_place_ads' );
589
  }
590
 
591
- // we need 3 states: ! isset, 1, 0.
592
- $options['disabled-ads']['feed'] = isset( $options['disabled-ads']['feed'] ) ? 1 : 0;
593
 
594
  if ( isset( $options['content-injection-everywhere'] ) ) {
595
- if ( 0 == $options['content-injection-everywhere'] ) {
596
  unset( $options['content-injection-everywhere'] );
597
- } elseif ( $options['content-injection-everywhere'] <= - 1 ) {
 
598
  $options['content-injection-everywhere'] = 'true';
599
  } else {
600
  $options['content-injection-everywhere'] = absint( $options['content-injection-everywhere'] );
588
  $editor_role->remove_cap( 'advanced_ads_place_ads' );
589
  }
590
 
591
+ // we need 3 states: ! empty, 1, 0.
592
+ $options['disabled-ads']['feed'] = ! empty( $options['disabled-ads']['feed'] ) ? 1 : 0;
593
 
594
  if ( isset( $options['content-injection-everywhere'] ) ) {
595
+ if ( '0' === $options['content-injection-everywhere'] ) {
596
  unset( $options['content-injection-everywhere'] );
597
+ } elseif ( $options['content-injection-everywhere'] === 'true' || $options['content-injection-everywhere'] <= - 1 ) {
598
+ // Note: the option may be already set 'true' during import.
599
  $options['content-injection-everywhere'] = 'true';
600
  } else {
601
  $options['content-injection-everywhere'] = absint( $options['content-injection-everywhere'] );
admin/views/placements.php CHANGED
@@ -411,10 +411,12 @@ $quick_actions['delete'] = '<a style="cursor: pointer;" class="advads-delete-tag
411
  ?>
412
  </p>
413
  <?php endif; ?>
414
- <div class="advads-placements-show-options">
415
- <a href="#modal-<?php echo esc_attr( $_placement_slug ); ?>" style="cursor: pointer;"
416
- data-placement="<?php echo esc_attr( $_placement_slug ); ?>"><?php esc_html_e( 'show all options', 'advanced-ads' ); ?></a>
417
- </div>
 
 
418
  </td>
419
  <td class="advads-placement-conditions">
420
  <?php if ( ! empty( $_placement['options']['placement_conditions']['display'] ) ) : ?>
411
  ?>
412
  </p>
413
  <?php endif; ?>
414
+ <?php if ( $advanced_options ) : ?>
415
+ <div class="advads-placements-show-options">
416
+ <a href="#modal-<?php echo esc_attr( $_placement_slug ); ?>" style="cursor: pointer;"
417
+ data-placement="<?php echo esc_attr( $_placement_slug ); ?>"><?php esc_html_e( 'show all options', 'advanced-ads' ); ?></a>
418
+ </div>
419
+ <?php endif; ?>
420
  </td>
421
  <td class="advads-placement-conditions">
422
  <?php if ( ! empty( $_placement['options']['placement_conditions']['display'] ) ) : ?>
advanced-ads.php CHANGED
@@ -12,7 +12,7 @@
12
  * Plugin Name: Advanced Ads
13
  * Plugin URI: https://wpadvancedads.com
14
  * Description: Manage and optimize your ads in WordPress
15
- * Version: 1.25.1
16
  * Author: Thomas Maier, Advanced Ads GmbH
17
  * Author URI: https://wpadvancedads.com
18
  * Text Domain: advanced-ads
@@ -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.
40
  define( 'ADVADS_SLUG', 'advanced-ads' );
41
  define( 'ADVADS_URL', 'https://wpadvancedads.com/' );
42
- define( 'ADVADS_VERSION', '1.25.1' );
43
 
44
  // Autoloading, modules and functions.
45
 
12
  * Plugin Name: Advanced Ads
13
  * Plugin URI: https://wpadvancedads.com
14
  * Description: Manage and optimize your ads in WordPress
15
+ * Version: 1.26.0
16
  * Author: Thomas Maier, Advanced Ads GmbH
17
  * Author URI: https://wpadvancedads.com
18
  * Text Domain: advanced-ads
39
  // general and global slug, e.g. to store options in WP.
40
  define( 'ADVADS_SLUG', 'advanced-ads' );
41
  define( 'ADVADS_URL', 'https://wpadvancedads.com/' );
42
+ define( 'ADVADS_VERSION', '1.26.0' );
43
 
44
  // Autoloading, modules and functions.
45
 
classes/inline-css.php CHANGED
@@ -67,7 +67,8 @@ class Advanced_Ads_Inline_Css {
67
  $inline_css = $ad->options( 'inline-css' );
68
 
69
  if (
70
- empty( $inline_css )
 
71
  || strpos( $output, '<div class="tcf-container"' ) === 0
72
  ) {
73
  return $output;
67
  $inline_css = $ad->options( 'inline-css' );
68
 
69
  if (
70
+ ! $ad->global_output
71
+ || empty( $inline_css )
72
  || strpos( $output, '<div class="tcf-container"' ) === 0
73
  ) {
74
  return $output;
classes/widget.php CHANGED
@@ -14,6 +14,14 @@
14
  */
15
  class Advanced_Ads_Widget extends WP_Widget {
16
 
 
 
 
 
 
 
 
 
17
  /**
18
  * Advanced_Ads_Widget constructor.
19
  */
@@ -22,8 +30,9 @@ class Advanced_Ads_Widget extends WP_Widget {
22
  $classname = $prefix . 'widget';
23
 
24
  $widget_ops = array(
25
- 'classname' => $classname,
26
- 'description' => __( 'Display Ads and Ad Groups.', 'advanced-ads' ),
 
27
  );
28
  $control_ops = array();
29
  $base_id = self::get_base_id();
@@ -276,6 +285,9 @@ class Advanced_Ads_Widget extends WP_Widget {
276
  public function q2w3_replace_frontend_id( $sidebars_widgets ) {
277
  foreach ( $sidebars_widgets as $sidebar => $widgets ) {
278
  foreach ( $widgets as $k => $widget ) {
 
 
 
279
  $pos = strrpos( $widget, '-' );
280
  $option_name = substr( $widget, 0, $pos );
281
  $number = substr( $widget, $pos + 1 );
@@ -283,7 +295,8 @@ class Advanced_Ads_Widget extends WP_Widget {
283
  if ( self::get_base_id() === $option_name ) {
284
  $widget_options = get_option( 'widget_' . $option_name );
285
  if ( ! empty( $widget_options[ $number ]['remove-widget-id'] ) ) {
286
- $sidebars_widgets[ $sidebar ][ $k ] = $this->get_frontend_id( $number );
 
287
  }
288
  }
289
  }
14
  */
15
  class Advanced_Ads_Widget extends WP_Widget {
16
 
17
+ /**
18
+ * Allows the REST API to see the widgets instance.
19
+ *
20
+ * @deprecated deprecated since WordPress version 5.8
21
+ * @var bool
22
+ */
23
+ public $show_instance_in_rest = true;
24
+
25
  /**
26
  * Advanced_Ads_Widget constructor.
27
  */
30
  $classname = $prefix . 'widget';
31
 
32
  $widget_ops = array(
33
+ 'classname' => $classname,
34
+ 'show_instance_in_rest' => true,
35
+ 'description' => __( 'Display Ads and Ad Groups.', 'advanced-ads' ),
36
  );
37
  $control_ops = array();
38
  $base_id = self::get_base_id();
285
  public function q2w3_replace_frontend_id( $sidebars_widgets ) {
286
  foreach ( $sidebars_widgets as $sidebar => $widgets ) {
287
  foreach ( $widgets as $k => $widget ) {
288
+ // after Fixed Widget 5.3.0, the widget option includes '#'. It didn’t before. We store the information since we need it later again.
289
+ $has_hash = strpos( $widget, '#' ) !== false;
290
+ $widget = str_replace( '#', '', $widget );
291
  $pos = strrpos( $widget, '-' );
292
  $option_name = substr( $widget, 0, $pos );
293
  $number = substr( $widget, $pos + 1 );
295
  if ( self::get_base_id() === $option_name ) {
296
  $widget_options = get_option( 'widget_' . $option_name );
297
  if ( ! empty( $widget_options[ $number ]['remove-widget-id'] ) ) {
298
+ // add a hash if the widget had one before. See comment above
299
+ $sidebars_widgets[ $sidebar ][ $k ] = $has_hash ? ( '#' . $this->get_frontend_id( $number ) ) : $this->get_frontend_id( $number );
300
  }
301
  }
302
  }
languages/advanced-ads.pot CHANGED
@@ -2,20 +2,20 @@
2
  # This file is distributed under the same license as the Advanced Ads plugin.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Advanced Ads 1.25.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/advanced-ads/\n"
7
  "Last-Translator: Thomas Maier <post@webzunft.de>\n"
8
  "Language-Team: webgilde <support@wpadvancedads.com>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "POT-Creation-Date: 2021-07-01T14:50:38+02:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: advanced-ads\n"
16
 
17
  #. Plugin Name of the plugin
18
- #: modules/gutenberg/includes/class-gutenberg.php:78
19
  msgid "Advanced Ads"
20
  msgstr ""
21
 
@@ -85,21 +85,25 @@ msgstr ""
85
  msgid "Hide inactive ads"
86
  msgstr ""
87
 
88
- #: admin/class-advanced-ads-admin.php:390
 
 
 
 
89
  #: admin/includes/class-menu.php:156
90
  #: admin/includes/class-menu.php:159
91
  #: admin/views/settings.php:29
92
  msgid "Support"
93
  msgstr ""
94
 
95
- #: admin/class-advanced-ads-admin.php:394
96
  #: admin/includes/class-overview-widgets.php:72
97
  msgid "Add-Ons"
98
  msgstr ""
99
 
100
  #. translators: %s is the URL to add a new review, https://wordpress.org/support/plugin/advanced-ads/reviews/#new-post
101
  #. translators: %s is a URL.
102
- #: admin/class-advanced-ads-admin.php:665
103
  #: admin/includes/class-overview-widgets.php:191
104
  msgid "Thank the developer with a &#9733;&#9733;&#9733;&#9733;&#9733; review on <a href=\"%s\" target=\"_blank\">wordpress.org</a>"
105
  msgstr ""
@@ -304,9 +308,9 @@ msgstr ""
304
 
305
  #: admin/includes/class-ad-groups-list.php:339
306
  #: admin/views/placements.php:274
307
- #: modules/import-export/classes/import.php:150
308
- #: modules/import-export/classes/import.php:190
309
- #: modules/import-export/classes/import.php:579
310
  #: public/class-advanced-ads.php:792
311
  msgid "Edit"
312
  msgstr ""
@@ -484,34 +488,39 @@ msgid "There are no activations left."
484
  msgstr ""
485
 
486
  #. translators: %1$s is a starting link tag, %2$s is the closing one.
487
- #: admin/includes/class-licenses.php:209
488
  msgid "You can manage activations in %1$syour account%2$s."
489
  msgstr ""
490
 
 
 
 
 
 
491
  #. translators: %s is a string containing information about the issue.
492
- #: admin/includes/class-licenses.php:223
493
  msgid "License is invalid. Reason: %s"
494
  msgstr ""
495
 
496
  #. translators: %s is a list of server information like IP address. Just keep it as is.
497
- #: admin/includes/class-licenses.php:263
498
  msgid "Your request was blocked by our firewall. Please send us the following information to unblock you: %s."
499
  msgstr ""
500
 
501
- #: admin/includes/class-licenses.php:325
502
  msgid "Error while trying to disable the license. Please contact support."
503
  msgstr ""
504
 
505
- #: admin/includes/class-licenses.php:360
506
- #: admin/includes/class-licenses.php:383
507
  msgid "License couldn’t be deactivated. Please try again later."
508
  msgstr ""
509
 
510
- #: admin/includes/class-licenses.php:617
511
  msgid "Download failed. <a href=\"%s\">Click here to try another method</a>."
512
  msgstr ""
513
 
514
- #: admin/includes/class-licenses.php:619
515
  msgid "Download failed. <a href=\"%s\" target=\"_blank\">Click here to learn why</a>."
516
  msgstr ""
517
 
@@ -543,8 +552,8 @@ msgstr ""
543
  #: admin/views/ad-group-list-header.php:16
544
  #: admin/views/placement-form.php:88
545
  #: admin/views/placements-item.php:26
546
- #: classes/widget.php:129
547
- #: modules/gutenberg/includes/class-gutenberg.php:79
548
  #: modules/import-export/views/page.php:23
549
  #: public/class-advanced-ads.php:788
550
  msgid "Ads"
@@ -577,8 +586,8 @@ msgstr ""
577
  #: admin/includes/class-menu.php:132
578
  #: admin/includes/class-shortcode-creator.php:198
579
  #: admin/views/placements.php:57
580
- #: classes/widget.php:115
581
- #: modules/gutenberg/includes/class-gutenberg.php:81
582
  #: modules/import-export/views/page.php:25
583
  msgid "Placements"
584
  msgstr ""
@@ -626,14 +635,14 @@ msgstr ""
626
 
627
  #: admin/includes/class-meta-box.php:104
628
  #: admin/views/placements.php:183
629
- #: admin/views/placements.php:421
630
  #: classes/ad-debug.php:152
631
  msgid "Display Conditions"
632
  msgstr ""
633
 
634
  #: admin/includes/class-meta-box.php:112
635
  #: admin/views/placements.php:192
636
- #: admin/views/placements.php:429
637
  #: classes/ad-debug.php:239
638
  msgid "Visitor Conditions"
639
  msgstr ""
@@ -998,16 +1007,16 @@ msgid "Advertisements"
998
  msgstr ""
999
 
1000
  #: admin/includes/class-shortcode-creator.php:182
1001
- #: classes/widget.php:113
1002
- #: modules/gutenberg/includes/class-gutenberg.php:77
1003
  msgid "--empty--"
1004
  msgstr ""
1005
 
1006
  #: admin/includes/class-shortcode-creator.php:191
1007
  #: admin/views/placement-form.php:81
1008
  #: admin/views/placements-item.php:14
1009
- #: classes/widget.php:122
1010
- #: modules/gutenberg/includes/class-gutenberg.php:80
1011
  msgid "Ad Groups"
1012
  msgstr ""
1013
 
@@ -1977,12 +1986,12 @@ msgid "Placements updated"
1977
  msgstr ""
1978
 
1979
  #: admin/views/placements.php:25
1980
- #: admin/views/placements.php:457
1981
  msgid "Create a new placement"
1982
  msgstr ""
1983
 
1984
  #: admin/views/placements.php:26
1985
- #: admin/views/placements.php:459
1986
  msgid "New Placement"
1987
  msgstr ""
1988
 
@@ -2083,20 +2092,20 @@ msgstr ""
2083
  msgid "Tutorial: <a href=\"%s\" target=\"_blank\">How to place visible ads in the header of your website</a>."
2084
  msgstr ""
2085
 
2086
- #: admin/views/placements.php:416
2087
  msgid "show all options"
2088
  msgstr ""
2089
 
2090
- #: admin/views/placements.php:438
2091
  msgid "edit conditions"
2092
  msgstr ""
2093
 
2094
- #: admin/views/placements.php:448
2095
  msgctxt "checkbox to remove placement"
2096
  msgid "delete"
2097
  msgstr ""
2098
 
2099
- #: admin/views/placements.php:455
2100
  msgid "Save Placements"
2101
  msgstr ""
2102
 
@@ -3198,11 +3207,11 @@ msgstr ""
3198
  msgid "browser width"
3199
  msgstr ""
3200
 
3201
- #: classes/widget.php:26
3202
  msgid "Display Ads and Ad Groups."
3203
  msgstr ""
3204
 
3205
- #: classes/widget.php:107
3206
  msgid "Title:"
3207
  msgstr ""
3208
 
@@ -3230,39 +3239,39 @@ msgstr ""
3230
  msgid "Individual Posts, Pages and Public Post Types"
3231
  msgstr ""
3232
 
3233
- #: modules/ad-blocker/admin/admin.php:98
3234
  msgid "Ad blocker fix"
3235
  msgstr ""
3236
 
3237
- #: modules/ad-blocker/admin/admin.php:152
3238
  #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:381
3239
  msgid "Unable to connect to the filesystem. Please confirm your credentials."
3240
  msgstr ""
3241
 
3242
- #: modules/ad-blocker/admin/admin.php:167
3243
  msgid "The asset folder was rebuilt successfully"
3244
  msgstr ""
3245
 
3246
- #: modules/ad-blocker/admin/admin.php:228
3247
  msgid "There is no writable upload folder"
3248
  msgstr ""
3249
 
3250
- #: modules/ad-blocker/admin/admin.php:257
3251
  msgid "Unable to rename \"%s\" directory"
3252
  msgstr ""
3253
 
3254
- #: modules/ad-blocker/admin/admin.php:273
3255
- #: modules/ad-blocker/admin/admin.php:286
3256
- #: modules/ad-blocker/admin/admin.php:303
3257
  msgid "Unable to copy assets to the \"%s\" directory"
3258
  msgstr ""
3259
 
3260
- #: modules/ad-blocker/admin/admin.php:336
3261
- #: modules/ad-blocker/admin/admin.php:421
3262
  msgid "We do not have direct write access to the \"%s\" directory"
3263
  msgstr ""
3264
 
3265
- #: modules/ad-blocker/admin/admin.php:432
3266
  msgid "Unable to copy files to %s"
3267
  msgstr ""
3268
 
@@ -3918,86 +3927,85 @@ msgstr ""
3918
  msgid "Please enter XML content"
3919
  msgstr ""
3920
 
3921
- #: modules/import-export/classes/import.php:151
3922
- #: modules/import-export/classes/import.php:580
3923
  msgid "New attachment created <em>%s</em> %s"
3924
  msgstr ""
3925
 
3926
- #: modules/import-export/classes/import.php:183
3927
  msgid "Failed to import <em>%s</em>"
3928
  msgstr ""
3929
 
3930
- #: modules/import-export/classes/import.php:191
3931
  msgid "New ad created: <em>%s</em> %s"
3932
  msgstr ""
3933
 
3934
- #: modules/import-export/classes/import.php:234
3935
  msgid "Assigned terms: <em>%s</em>, to post: <em>%s</em>"
3936
  msgstr ""
3937
 
3938
- #: modules/import-export/classes/import.php:296
3939
  msgid "New group created, id: <em>%s</em>, name: <em>%s</em>"
3940
  msgstr ""
3941
 
3942
- #: modules/import-export/classes/import.php:298
3943
  msgid "Failed to import taxonomy: <em>%s</em>, term: <em>%s</em>"
3944
  msgstr ""
3945
 
3946
- #: modules/import-export/classes/import.php:363
3947
  msgid "Placement <em>%s</em> created"
3948
  msgstr ""
3949
 
3950
- #: modules/import-export/classes/import.php:491
 
3951
  msgid "Option was updated: <em>%s</em>"
3952
  msgstr ""
3953
 
3954
- #: modules/import-export/classes/import.php:494
3955
- msgid "Option already exists: <em>%s</em>"
3956
- msgstr ""
3957
-
3958
- #: modules/import-export/classes/import.php:516
3959
  msgid "Failed to create import directory <em>%s</em>"
3960
  msgstr ""
3961
 
3962
- #: modules/import-export/classes/import.php:521
3963
  msgid "Import directory is not writable: <em>%s</em>"
3964
  msgstr ""
3965
 
3966
- #: modules/import-export/classes/import.php:529
3967
  msgid "File is empty, uploads are disabled or post_max_size is smaller than upload_max_filesize in php.ini"
3968
  msgstr ""
3969
 
3970
- #: modules/import-export/classes/import.php:539
3971
  msgid "Failed to upload file, error: <em>%s</em>"
3972
  msgstr ""
3973
 
3974
- #: modules/import-export/classes/import.php:544
3975
  msgid "File is empty."
3976
  msgstr ""
3977
 
3978
- #: modules/import-export/classes/import.php:549
3979
  msgid "The file could not be created: <em>%s</em>. This is probably a permissions problem"
3980
  msgstr ""
3981
 
3982
- #: modules/import-export/classes/import.php:622
3983
  msgid "Invalid filetype <em>%s</em>"
3984
  msgstr ""
3985
 
3986
- #: modules/import-export/classes/import.php:627
3987
- #: modules/import-export/classes/import.php:634
3988
- #: modules/import-export/classes/import.php:642
3989
- #: modules/import-export/classes/import.php:657
 
3990
  msgid "Error getting remote image <em>%s</em>"
3991
  msgstr ""
3992
 
3993
- #: modules/import-export/classes/import.php:651
3994
  msgid "Zero size file downloaded <em>%s</em>"
3995
  msgstr ""
3996
 
 
3997
  #: modules/import-export/classes/XmlEncoder.php:61
3998
  #: modules/import-export/classes/XmlEncoder.php:64
3999
- #: modules/import-export/classes/XmlEncoder.php:191
4000
- #: modules/import-export/classes/XmlEncoder.php:194
4001
  msgid "The %s extension(s) is not loaded"
4002
  msgstr ""
4003
 
@@ -4011,12 +4019,12 @@ msgctxt "import_export"
4011
  msgid "An unexpected value could not be serialized: %s"
4012
  msgstr ""
4013
 
4014
- #: modules/import-export/classes/XmlEncoder.php:199
4015
  msgctxt "import_export"
4016
  msgid "Invalid XML data, it can not be empty"
4017
  msgstr ""
4018
 
4019
- #: modules/import-export/classes/XmlEncoder.php:221
4020
  msgctxt "import_export"
4021
  msgid "XML error: %s"
4022
  msgstr ""
2
  # This file is distributed under the same license as the Advanced Ads plugin.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Advanced Ads 1.26.0\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/advanced-ads/\n"
7
  "Last-Translator: Thomas Maier <post@webzunft.de>\n"
8
  "Language-Team: webgilde <support@wpadvancedads.com>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2021-07-21T10:55:09+02:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: advanced-ads\n"
16
 
17
  #. Plugin Name of the plugin
18
+ #: modules/gutenberg/includes/class-gutenberg.php:88
19
  msgid "Advanced Ads"
20
  msgstr ""
21
 
85
  msgid "Hide inactive ads"
86
  msgstr ""
87
 
88
+ #: admin/class-advanced-ads-admin.php:232
89
+ msgid "Permanently delete this placement?"
90
+ msgstr ""
91
+
92
+ #: admin/class-advanced-ads-admin.php:391
93
  #: admin/includes/class-menu.php:156
94
  #: admin/includes/class-menu.php:159
95
  #: admin/views/settings.php:29
96
  msgid "Support"
97
  msgstr ""
98
 
99
+ #: admin/class-advanced-ads-admin.php:395
100
  #: admin/includes/class-overview-widgets.php:72
101
  msgid "Add-Ons"
102
  msgstr ""
103
 
104
  #. translators: %s is the URL to add a new review, https://wordpress.org/support/plugin/advanced-ads/reviews/#new-post
105
  #. translators: %s is a URL.
106
+ #: admin/class-advanced-ads-admin.php:666
107
  #: admin/includes/class-overview-widgets.php:191
108
  msgid "Thank the developer with a &#9733;&#9733;&#9733;&#9733;&#9733; review on <a href=\"%s\" target=\"_blank\">wordpress.org</a>"
109
  msgstr ""
308
 
309
  #: admin/includes/class-ad-groups-list.php:339
310
  #: admin/views/placements.php:274
311
+ #: modules/import-export/classes/import.php:153
312
+ #: modules/import-export/classes/import.php:193
313
+ #: modules/import-export/classes/import.php:595
314
  #: public/class-advanced-ads.php:792
315
  msgid "Edit"
316
  msgstr ""
488
  msgstr ""
489
 
490
  #. translators: %1$s is a starting link tag, %2$s is the closing one.
491
+ #: admin/includes/class-licenses.php:210
492
  msgid "You can manage activations in %1$syour account%2$s."
493
  msgstr ""
494
 
495
+ #. translators: %1$s is a starting link tag, %2$s is the closing one.
496
+ #: admin/includes/class-licenses.php:216
497
+ msgid "%1$sUpgrade%2$s for more activations."
498
+ msgstr ""
499
+
500
  #. translators: %s is a string containing information about the issue.
501
+ #: admin/includes/class-licenses.php:230
502
  msgid "License is invalid. Reason: %s"
503
  msgstr ""
504
 
505
  #. translators: %s is a list of server information like IP address. Just keep it as is.
506
+ #: admin/includes/class-licenses.php:270
507
  msgid "Your request was blocked by our firewall. Please send us the following information to unblock you: %s."
508
  msgstr ""
509
 
510
+ #: admin/includes/class-licenses.php:332
511
  msgid "Error while trying to disable the license. Please contact support."
512
  msgstr ""
513
 
514
+ #: admin/includes/class-licenses.php:367
515
+ #: admin/includes/class-licenses.php:390
516
  msgid "License couldn’t be deactivated. Please try again later."
517
  msgstr ""
518
 
519
+ #: admin/includes/class-licenses.php:624
520
  msgid "Download failed. <a href=\"%s\">Click here to try another method</a>."
521
  msgstr ""
522
 
523
+ #: admin/includes/class-licenses.php:626
524
  msgid "Download failed. <a href=\"%s\" target=\"_blank\">Click here to learn why</a>."
525
  msgstr ""
526
 
552
  #: admin/views/ad-group-list-header.php:16
553
  #: admin/views/placement-form.php:88
554
  #: admin/views/placements-item.php:26
555
+ #: classes/widget.php:138
556
+ #: modules/gutenberg/includes/class-gutenberg.php:89
557
  #: modules/import-export/views/page.php:23
558
  #: public/class-advanced-ads.php:788
559
  msgid "Ads"
586
  #: admin/includes/class-menu.php:132
587
  #: admin/includes/class-shortcode-creator.php:198
588
  #: admin/views/placements.php:57
589
+ #: classes/widget.php:124
590
+ #: modules/gutenberg/includes/class-gutenberg.php:91
591
  #: modules/import-export/views/page.php:25
592
  msgid "Placements"
593
  msgstr ""
635
 
636
  #: admin/includes/class-meta-box.php:104
637
  #: admin/views/placements.php:183
638
+ #: admin/views/placements.php:423
639
  #: classes/ad-debug.php:152
640
  msgid "Display Conditions"
641
  msgstr ""
642
 
643
  #: admin/includes/class-meta-box.php:112
644
  #: admin/views/placements.php:192
645
+ #: admin/views/placements.php:431
646
  #: classes/ad-debug.php:239
647
  msgid "Visitor Conditions"
648
  msgstr ""
1007
  msgstr ""
1008
 
1009
  #: admin/includes/class-shortcode-creator.php:182
1010
+ #: classes/widget.php:122
1011
+ #: modules/gutenberg/includes/class-gutenberg.php:87
1012
  msgid "--empty--"
1013
  msgstr ""
1014
 
1015
  #: admin/includes/class-shortcode-creator.php:191
1016
  #: admin/views/placement-form.php:81
1017
  #: admin/views/placements-item.php:14
1018
+ #: classes/widget.php:131
1019
+ #: modules/gutenberg/includes/class-gutenberg.php:90
1020
  msgid "Ad Groups"
1021
  msgstr ""
1022
 
1986
  msgstr ""
1987
 
1988
  #: admin/views/placements.php:25
1989
+ #: admin/views/placements.php:459
1990
  msgid "Create a new placement"
1991
  msgstr ""
1992
 
1993
  #: admin/views/placements.php:26
1994
+ #: admin/views/placements.php:461
1995
  msgid "New Placement"
1996
  msgstr ""
1997
 
2092
  msgid "Tutorial: <a href=\"%s\" target=\"_blank\">How to place visible ads in the header of your website</a>."
2093
  msgstr ""
2094
 
2095
+ #: admin/views/placements.php:417
2096
  msgid "show all options"
2097
  msgstr ""
2098
 
2099
+ #: admin/views/placements.php:440
2100
  msgid "edit conditions"
2101
  msgstr ""
2102
 
2103
+ #: admin/views/placements.php:450
2104
  msgctxt "checkbox to remove placement"
2105
  msgid "delete"
2106
  msgstr ""
2107
 
2108
+ #: admin/views/placements.php:457
2109
  msgid "Save Placements"
2110
  msgstr ""
2111
 
3207
  msgid "browser width"
3208
  msgstr ""
3209
 
3210
+ #: classes/widget.php:35
3211
  msgid "Display Ads and Ad Groups."
3212
  msgstr ""
3213
 
3214
+ #: classes/widget.php:116
3215
  msgid "Title:"
3216
  msgstr ""
3217
 
3239
  msgid "Individual Posts, Pages and Public Post Types"
3240
  msgstr ""
3241
 
3242
+ #: modules/ad-blocker/admin/admin.php:96
3243
  msgid "Ad blocker fix"
3244
  msgstr ""
3245
 
3246
+ #: modules/ad-blocker/admin/admin.php:150
3247
  #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:381
3248
  msgid "Unable to connect to the filesystem. Please confirm your credentials."
3249
  msgstr ""
3250
 
3251
+ #: modules/ad-blocker/admin/admin.php:165
3252
  msgid "The asset folder was rebuilt successfully"
3253
  msgstr ""
3254
 
3255
+ #: modules/ad-blocker/admin/admin.php:206
3256
  msgid "There is no writable upload folder"
3257
  msgstr ""
3258
 
3259
+ #: modules/ad-blocker/admin/admin.php:238
3260
  msgid "Unable to rename \"%s\" directory"
3261
  msgstr ""
3262
 
3263
+ #: modules/ad-blocker/admin/admin.php:254
3264
+ #: modules/ad-blocker/admin/admin.php:267
3265
+ #: modules/ad-blocker/admin/admin.php:284
3266
  msgid "Unable to copy assets to the \"%s\" directory"
3267
  msgstr ""
3268
 
3269
+ #: modules/ad-blocker/admin/admin.php:317
3270
+ #: modules/ad-blocker/admin/admin.php:402
3271
  msgid "We do not have direct write access to the \"%s\" directory"
3272
  msgstr ""
3273
 
3274
+ #: modules/ad-blocker/admin/admin.php:413
3275
  msgid "Unable to copy files to %s"
3276
  msgstr ""
3277
 
3927
  msgid "Please enter XML content"
3928
  msgstr ""
3929
 
3930
+ #: modules/import-export/classes/import.php:154
3931
+ #: modules/import-export/classes/import.php:596
3932
  msgid "New attachment created <em>%s</em> %s"
3933
  msgstr ""
3934
 
3935
+ #: modules/import-export/classes/import.php:186
3936
  msgid "Failed to import <em>%s</em>"
3937
  msgstr ""
3938
 
3939
+ #: modules/import-export/classes/import.php:194
3940
  msgid "New ad created: <em>%s</em> %s"
3941
  msgstr ""
3942
 
3943
+ #: modules/import-export/classes/import.php:237
3944
  msgid "Assigned terms: <em>%s</em>, to post: <em>%s</em>"
3945
  msgstr ""
3946
 
3947
+ #: modules/import-export/classes/import.php:299
3948
  msgid "New group created, id: <em>%s</em>, name: <em>%s</em>"
3949
  msgstr ""
3950
 
3951
+ #: modules/import-export/classes/import.php:301
3952
  msgid "Failed to import taxonomy: <em>%s</em>, term: <em>%s</em>"
3953
  msgstr ""
3954
 
3955
+ #: modules/import-export/classes/import.php:366
3956
  msgid "Placement <em>%s</em> created"
3957
  msgstr ""
3958
 
3959
+ #. translators: %s: Option name.
3960
+ #: modules/import-export/classes/import.php:510
3961
  msgid "Option was updated: <em>%s</em>"
3962
  msgstr ""
3963
 
3964
+ #: modules/import-export/classes/import.php:532
 
 
 
 
3965
  msgid "Failed to create import directory <em>%s</em>"
3966
  msgstr ""
3967
 
3968
+ #: modules/import-export/classes/import.php:537
3969
  msgid "Import directory is not writable: <em>%s</em>"
3970
  msgstr ""
3971
 
3972
+ #: modules/import-export/classes/import.php:545
3973
  msgid "File is empty, uploads are disabled or post_max_size is smaller than upload_max_filesize in php.ini"
3974
  msgstr ""
3975
 
3976
+ #: modules/import-export/classes/import.php:555
3977
  msgid "Failed to upload file, error: <em>%s</em>"
3978
  msgstr ""
3979
 
3980
+ #: modules/import-export/classes/import.php:560
3981
  msgid "File is empty."
3982
  msgstr ""
3983
 
3984
+ #: modules/import-export/classes/import.php:565
3985
  msgid "The file could not be created: <em>%s</em>. This is probably a permissions problem"
3986
  msgstr ""
3987
 
3988
+ #: modules/import-export/classes/import.php:638
3989
  msgid "Invalid filetype <em>%s</em>"
3990
  msgstr ""
3991
 
3992
+ #. translators: 1: image url
3993
+ #: modules/import-export/classes/import.php:643
3994
+ #: modules/import-export/classes/import.php:650
3995
+ #: modules/import-export/classes/import.php:658
3996
+ #: modules/import-export/classes/import.php:684
3997
  msgid "Error getting remote image <em>%s</em>"
3998
  msgstr ""
3999
 
4000
+ #: modules/import-export/classes/import.php:667
4001
  msgid "Zero size file downloaded <em>%s</em>"
4002
  msgstr ""
4003
 
4004
+ #. translators: %s: A name of not loaded extension.
4005
  #: modules/import-export/classes/XmlEncoder.php:61
4006
  #: modules/import-export/classes/XmlEncoder.php:64
4007
+ #: modules/import-export/classes/XmlEncoder.php:201
4008
+ #: modules/import-export/classes/XmlEncoder.php:205
4009
  msgid "The %s extension(s) is not loaded"
4010
  msgstr ""
4011
 
4019
  msgid "An unexpected value could not be serialized: %s"
4020
  msgstr ""
4021
 
4022
+ #: modules/import-export/classes/XmlEncoder.php:210
4023
  msgctxt "import_export"
4024
  msgid "Invalid XML data, it can not be empty"
4025
  msgstr ""
4026
 
4027
+ #: modules/import-export/classes/XmlEncoder.php:242
4028
  msgctxt "import_export"
4029
  msgid "XML error: %s"
4030
  msgstr ""
modules/ad-blocker/admin/admin.php CHANGED
@@ -65,8 +65,6 @@ class Advanced_Ads_Ad_Blocker_Admin {
65
  // add rebuild asset form
66
  add_filter( 'advanced-ads-settings-tab-after-form', array( $this, 'add_asset_rebuild_form_wrap' ) );
67
 
68
- add_filter( "pre_update_option_" . ADVADS_AB_SLUG, array( $this, 'sanitize_settings' ), 10, 2 );
69
-
70
  add_action( 'admin_init', array( $this, 'process_auto_update' ) );
71
 
72
  $this->error_messages = new WP_Error();
@@ -194,30 +192,10 @@ class Advanced_Ads_Ad_Blocker_Admin {
194
  }
195
 
196
  /**
197
- * Catch the update options before it's submitted to the database
198
- *
199
- * @param array $new_options new values that need to be saved
200
- * @param array $old_options old values saved in database
201
- * @return array - options to save
202
- */
203
- public function sanitize_settings( $new_options, $old_options ) {
204
- if ( is_array( $new_options ) ) {
205
- $this->options = array_merge( $this->options, $new_options );
206
- // Error, disable the ad-blocker script
207
- if ( ! isset( $new_options['module_can_work'] ) ) {
208
- unset( $this->options['module_can_work'] );
209
- }
210
- }
211
-
212
- return $this->options;
213
- }
214
-
215
-
216
- /**
217
- * Creates dummy plugin and return new options, that need to be stored in database
218
  *
219
- * @param array $form_post_fields options, POST data sent by user
220
- * @return array $new_options - options, that need to be stored in database
221
  */
222
  public function create_dummy_plugin( $form_post_fields = array() ) {
223
  global $wp_filesystem;
@@ -230,7 +208,10 @@ class Advanced_Ads_Ad_Blocker_Admin {
230
  return false;
231
  }
232
 
233
- $new_options = $new_options_error = array();
 
 
 
234
  // $new_options_error does not have the 'module_can_work' key - ad-blocker script will be inactive and the asset folder will be rebuilt next time
235
  $new_options['module_can_work'] = true;
236
 
@@ -265,7 +246,7 @@ class Advanced_Ads_Ad_Blocker_Admin {
265
  $is_rebuild_needed = count( $this->get_assets() );
266
 
267
  // we have an error while the method is being executed
268
- update_option( ADVADS_AB_SLUG, $new_options_error );
269
 
270
  if ( $is_rebuild_needed ) {
271
  $lookup_table = $this->copy_assets( $new_options['folder_name'], $need_assign_new_name );
@@ -279,7 +260,7 @@ class Advanced_Ads_Ad_Blocker_Admin {
279
 
280
  } else {
281
  // we have an error while the method is being executed
282
- update_option( ADVADS_AB_SLUG, $new_options_error );
283
  // old folder does not exist, let's create it
284
  $lookup_table = $this->copy_assets( $new_options['folder_name'] );
285
  if ( ! $lookup_table ) {
@@ -296,7 +277,7 @@ class Advanced_Ads_Ad_Blocker_Admin {
296
  // Create a unique folder name
297
  $new_options['folder_name'] = $new_options_error['folder_name'] = $new_folder_name;
298
  // we have an error while the method is being executed
299
- update_option( ADVADS_AB_SLUG, $new_options_error );
300
  // Copy the assets
301
  $lookup_table = $this->copy_assets( $new_options['folder_name'] );
302
  if ( ! $lookup_table ) {
@@ -307,7 +288,7 @@ class Advanced_Ads_Ad_Blocker_Admin {
307
  $new_options['lookup_table'] = $lookup_table;
308
  }
309
  // successful result, save options and rewrite previous error options
310
- update_option( ADVADS_AB_SLUG, $new_options);
311
  Advanced_Ads_Ad_Health_Notices::get_instance()->remove( 'assets_expired' );
312
  }
313
 
@@ -514,7 +495,7 @@ class Advanced_Ads_Ad_Blocker_Admin {
514
  // we can not update assets automatically. The user should visit the setting page and update assets manually
515
  // disable module and show notice
516
  unset( $this->options['module_can_work'] );
517
- update_option( ADVADS_AB_SLUG, $this->options);
518
  return;
519
  }
520
 
65
  // add rebuild asset form
66
  add_filter( 'advanced-ads-settings-tab-after-form', array( $this, 'add_asset_rebuild_form_wrap' ) );
67
 
 
 
68
  add_action( 'admin_init', array( $this, 'process_auto_update' ) );
69
 
70
  $this->error_messages = new WP_Error();
192
  }
193
 
194
  /**
195
+ * Creates dummy plugin and return new options, that need to be stored in database.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  *
197
+ * @param array $form_post_fields options, POST data sent by user.
198
+ * @return array $new_options - options, that need to be stored in database.
199
  */
200
  public function create_dummy_plugin( $form_post_fields = array() ) {
201
  global $wp_filesystem;
208
  return false;
209
  }
210
 
211
+ $new_options = array(
212
+ 'lookup_table' => isset( $this->options['lookup_table'] ) ? $this->options['lookup_table'] : array(),
213
+ );
214
+ $new_options_error = $new_options;
215
  // $new_options_error does not have the 'module_can_work' key - ad-blocker script will be inactive and the asset folder will be rebuilt next time
216
  $new_options['module_can_work'] = true;
217
 
246
  $is_rebuild_needed = count( $this->get_assets() );
247
 
248
  // we have an error while the method is being executed
249
+ Advanced_Ads_Ad_Blocker::get_instance()->update_options( $new_options_error );
250
 
251
  if ( $is_rebuild_needed ) {
252
  $lookup_table = $this->copy_assets( $new_options['folder_name'], $need_assign_new_name );
260
 
261
  } else {
262
  // we have an error while the method is being executed
263
+ Advanced_Ads_Ad_Blocker::get_instance()->update_options( $new_options_error );
264
  // old folder does not exist, let's create it
265
  $lookup_table = $this->copy_assets( $new_options['folder_name'] );
266
  if ( ! $lookup_table ) {
277
  // Create a unique folder name
278
  $new_options['folder_name'] = $new_options_error['folder_name'] = $new_folder_name;
279
  // we have an error while the method is being executed
280
+ Advanced_Ads_Ad_Blocker::get_instance()->update_options( $new_options_error );
281
  // Copy the assets
282
  $lookup_table = $this->copy_assets( $new_options['folder_name'] );
283
  if ( ! $lookup_table ) {
288
  $new_options['lookup_table'] = $lookup_table;
289
  }
290
  // successful result, save options and rewrite previous error options
291
+ Advanced_Ads_Ad_Blocker::get_instance()->update_options( $new_options );
292
  Advanced_Ads_Ad_Health_Notices::get_instance()->remove( 'assets_expired' );
293
  }
294
 
495
  // we can not update assets automatically. The user should visit the setting page and update assets manually
496
  // disable module and show notice
497
  unset( $this->options['module_can_work'] );
498
+ Advanced_Ads_Ad_Blocker::get_instance()->update_options( $this->options );
499
  return;
500
  }
501
 
modules/ad-blocker/classes/plugin.php CHANGED
@@ -1,6 +1,8 @@
1
  <?php
2
- class Advanced_Ads_Ad_Blocker
3
- {
 
 
4
  /**
5
  * Singleton instance of the plugin
6
  *
@@ -140,4 +142,27 @@ class Advanced_Ads_Ad_Blocker
140
  }
141
  return $this->options;
142
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  }
1
  <?php
2
+ /**
3
+ * Ad blocker frontend functionality.
4
+ */
5
+ class Advanced_Ads_Ad_Blocker {
6
  /**
7
  * Singleton instance of the plugin
8
  *
142
  }
143
  return $this->options;
144
  }
145
+
146
+ /**
147
+ * Update module options.
148
+ *
149
+ * @param array $new_options New options.
150
+ */
151
+ public function update_options( $new_options ) {
152
+ if ( ! is_array( $new_options ) ) {
153
+ return;
154
+ }
155
+
156
+ update_option( ADVADS_AB_SLUG, $new_options );
157
+
158
+ // We do not save the following keys to the database.
159
+ if ( isset( $this->options['use-adblocker'] ) ) {
160
+ $new_options['use-adblocker'] = $this->options['use-adblocker'];
161
+ }
162
+ if ( isset( $this->options['upload_dir'] ) ) {
163
+ $new_options['upload_dir'] = $this->options['upload_dir'];
164
+ }
165
+
166
+ $this->options = $new_options;
167
+ }
168
  }
modules/gutenberg/includes/class-gutenberg.php CHANGED
@@ -1,11 +1,14 @@
1
  <?php
2
 
 
 
 
3
  class Advanced_Ads_Gutenberg {
4
 
5
  private static $instance;
6
-
7
  private static $css_class;
8
-
9
  private function __construct() {
10
  add_action( 'init', array( $this, 'init' ) );
11
  add_action( 'enqueue_block_editor_assets', array( $this, 'register_scripts' ) );
@@ -19,13 +22,20 @@ class Advanced_Ads_Gutenberg {
19
  // no Gutenberg, Abort
20
  return;
21
  }
22
-
23
  register_block_type( 'advads/gblock', array(
24
  'editor_script' => ADVADS_BASE . '/gutenberg-ad',
25
  'render_callback' => array( $this, 'render_ad_selector' ),
26
  ) );
 
 
 
 
 
 
 
27
  }
28
-
29
  /**
30
  * Register back end scripts
31
  */
@@ -34,7 +44,7 @@ class Advanced_Ads_Gutenberg {
34
  // no Gutenberg, Abort
35
  return;
36
  }
37
-
38
  wp_register_script(
39
  ADVADS_BASE . '/gutenberg-ad',
40
  ADVADS_BASE_URL . 'modules/gutenberg/js/advanced-ads.block.js',
@@ -42,37 +52,37 @@ class Advanced_Ads_Gutenberg {
42
  );
43
 
44
  $model = Advanced_Ads::get_instance()->get_model();
45
-
46
  $all_ads = Advanced_Ads::get_ads( array( 'post_status' => array( 'publish' ), 'orderby' => 'title', 'order' => 'ASC' ) );
47
  $all_groups = $model->get_ad_groups();
48
  $all_placements = Advanced_Ads::get_ad_placements_array();
49
-
50
  $ads = array();
51
  $groups = array();
52
  $placements = array();
53
-
54
  foreach ( $all_ads as $ad ) {
55
  $ads[] = array( 'id' => $ad->ID, 'title' => $ad->post_title );
56
  }
57
-
58
  foreach ( $all_groups as $gr ) {
59
  $groups[] = array( 'id' => $gr->term_id, 'name' => $gr->name );
60
  }
61
-
62
  if ( is_array( $all_placements ) ) {
63
  ksort( $all_placements );
64
  }
65
-
66
  foreach( $all_placements as $key => $value ) {
67
  if ( 'sidebar_widget' == $value['type'] ) {
68
  $placements[] = array( 'id' => $key, 'name' => $value['name'] );
69
  }
70
  }
71
-
72
  if ( empty( $placements ) ) {
73
  $placements = false;
74
  }
75
-
76
  $i18n = array(
77
  '--empty--' => __( '--empty--', 'advanced-ads' ),
78
  'advads' => __( 'Advanced Ads', 'advanced-ads' ),
@@ -80,7 +90,7 @@ class Advanced_Ads_Gutenberg {
80
  'adGroups' => __( 'Ad Groups', 'advanced-ads' ),
81
  'placements' => __( 'Placements', 'advanced-ads' ),
82
  );
83
-
84
  $inline_script = wp_json_encode(
85
  array(
86
  'ads' => $ads,
@@ -94,62 +104,62 @@ class Advanced_Ads_Gutenberg {
94
  'i18n' => $i18n
95
  )
96
  );
97
-
98
  // put the inline code with the global variable right before the block's JS file
99
  wp_add_inline_script( ADVADS_BASE . '/gutenberg-ad', 'var advadsGutenberg = ' . $inline_script, 'before' );
100
  wp_enqueue_script( ADVADS_BASE . '/gutenberg-ad' );
101
  }
102
-
103
  /**
104
- * Server side rendering for single ad block
105
  */
106
  public static function render_ad_selector( $attr ) {
107
  ob_start();
108
-
109
  if ( !isset( $attr['itemID'] ) ) {
110
  ob_end_clean();
111
  return '';
112
  }
113
-
114
  // the item is an ad
115
  if ( 0 === strpos( $attr['itemID'], 'ad_' ) ) {
116
-
117
  $id = substr( $attr['itemID'], 3 );
118
-
119
  // add CSS classes to the wrapper via filter
120
  if ( isset( $attr['className'] ) ) {
121
  echo get_ad( absint( $id ), array( 'output' => array( 'class' => explode( ' ', $attr['className'] ) ) ) );
122
  } else {
123
  the_ad( absint( $id ) );
124
  }
125
-
126
  } elseif ( 0 === strpos( $attr['itemID'], 'group_' ) ) {
127
-
128
  $id = substr( $attr['itemID'], 6 );
129
-
130
  if ( isset( $attr['className'] ) ) {
131
  echo get_ad_group( $id, array( 'output' => array( 'class' => explode( ' ', $attr['className'] ) ) ) );
132
  } else {
133
  the_ad_group( $id );
134
  }
135
-
136
  } elseif ( 0 === strpos( $attr['itemID'], 'place_' ) ) {
137
-
138
  $id = substr( $attr['itemID'], 6 );
139
-
140
  if ( isset( $attr['className'] ) ) {
141
  echo get_ad_placement( $id, array( 'output' => array( 'class' => explode( ' ', $attr['className'] ) ) ) );
142
  } else {
143
  the_ad_placement( $id );
144
  }
145
-
146
  }
147
-
148
  return ob_get_clean();
149
  }
150
-
151
  /**
152
- * Return the unique instance
153
  */
154
  public static function get_instance() {
155
  if ( null == self::$instance ) {
1
  <?php
2
 
3
+ /**
4
+ * Class Advanced_Ads_Gutenberg
5
+ */
6
  class Advanced_Ads_Gutenberg {
7
 
8
  private static $instance;
9
+
10
  private static $css_class;
11
+
12
  private function __construct() {
13
  add_action( 'init', array( $this, 'init' ) );
14
  add_action( 'enqueue_block_editor_assets', array( $this, 'register_scripts' ) );
22
  // no Gutenberg, Abort
23
  return;
24
  }
25
+
26
  register_block_type( 'advads/gblock', array(
27
  'editor_script' => ADVADS_BASE . '/gutenberg-ad',
28
  'render_callback' => array( $this, 'render_ad_selector' ),
29
  ) );
30
+
31
+ // Removes legacy widget from legacy widget block.
32
+ add_filter( 'widget_types_to_hide_from_legacy_widget_block', function() {
33
+ $widget_types[] = 'advads_ad_widget';
34
+
35
+ return $widget_types;
36
+ } );
37
  }
38
+
39
  /**
40
  * Register back end scripts
41
  */
44
  // no Gutenberg, Abort
45
  return;
46
  }
47
+
48
  wp_register_script(
49
  ADVADS_BASE . '/gutenberg-ad',
50
  ADVADS_BASE_URL . 'modules/gutenberg/js/advanced-ads.block.js',
52
  );
53
 
54
  $model = Advanced_Ads::get_instance()->get_model();
55
+
56
  $all_ads = Advanced_Ads::get_ads( array( 'post_status' => array( 'publish' ), 'orderby' => 'title', 'order' => 'ASC' ) );
57
  $all_groups = $model->get_ad_groups();
58
  $all_placements = Advanced_Ads::get_ad_placements_array();
59
+
60
  $ads = array();
61
  $groups = array();
62
  $placements = array();
63
+
64
  foreach ( $all_ads as $ad ) {
65
  $ads[] = array( 'id' => $ad->ID, 'title' => $ad->post_title );
66
  }
67
+
68
  foreach ( $all_groups as $gr ) {
69
  $groups[] = array( 'id' => $gr->term_id, 'name' => $gr->name );
70
  }
71
+
72
  if ( is_array( $all_placements ) ) {
73
  ksort( $all_placements );
74
  }
75
+
76
  foreach( $all_placements as $key => $value ) {
77
  if ( 'sidebar_widget' == $value['type'] ) {
78
  $placements[] = array( 'id' => $key, 'name' => $value['name'] );
79
  }
80
  }
81
+
82
  if ( empty( $placements ) ) {
83
  $placements = false;
84
  }
85
+
86
  $i18n = array(
87
  '--empty--' => __( '--empty--', 'advanced-ads' ),
88
  'advads' => __( 'Advanced Ads', 'advanced-ads' ),
90
  'adGroups' => __( 'Ad Groups', 'advanced-ads' ),
91
  'placements' => __( 'Placements', 'advanced-ads' ),
92
  );
93
+
94
  $inline_script = wp_json_encode(
95
  array(
96
  'ads' => $ads,
104
  'i18n' => $i18n
105
  )
106
  );
107
+
108
  // put the inline code with the global variable right before the block's JS file
109
  wp_add_inline_script( ADVADS_BASE . '/gutenberg-ad', 'var advadsGutenberg = ' . $inline_script, 'before' );
110
  wp_enqueue_script( ADVADS_BASE . '/gutenberg-ad' );
111
  }
112
+
113
  /**
114
+ * Server side rendering for single ad block
115
  */
116
  public static function render_ad_selector( $attr ) {
117
  ob_start();
118
+
119
  if ( !isset( $attr['itemID'] ) ) {
120
  ob_end_clean();
121
  return '';
122
  }
123
+
124
  // the item is an ad
125
  if ( 0 === strpos( $attr['itemID'], 'ad_' ) ) {
126
+
127
  $id = substr( $attr['itemID'], 3 );
128
+
129
  // add CSS classes to the wrapper via filter
130
  if ( isset( $attr['className'] ) ) {
131
  echo get_ad( absint( $id ), array( 'output' => array( 'class' => explode( ' ', $attr['className'] ) ) ) );
132
  } else {
133
  the_ad( absint( $id ) );
134
  }
135
+
136
  } elseif ( 0 === strpos( $attr['itemID'], 'group_' ) ) {
137
+
138
  $id = substr( $attr['itemID'], 6 );
139
+
140
  if ( isset( $attr['className'] ) ) {
141
  echo get_ad_group( $id, array( 'output' => array( 'class' => explode( ' ', $attr['className'] ) ) ) );
142
  } else {
143
  the_ad_group( $id );
144
  }
145
+
146
  } elseif ( 0 === strpos( $attr['itemID'], 'place_' ) ) {
147
+
148
  $id = substr( $attr['itemID'], 6 );
149
+
150
  if ( isset( $attr['className'] ) ) {
151
  echo get_ad_placement( $id, array( 'output' => array( 'class' => explode( ' ', $attr['className'] ) ) ) );
152
  } else {
153
  the_ad_placement( $id );
154
  }
155
+
156
  }
157
+
158
  return ob_get_clean();
159
  }
160
+
161
  /**
162
+ * Return the unique instance
163
  */
164
  public static function get_instance() {
165
  if ( null == self::$instance ) {
modules/gutenberg/js/advanced-ads.block.js CHANGED
@@ -48,6 +48,9 @@
48
  category: 'common',
49
 
50
  attributes: {
 
 
 
51
  itemID: {
52
  type: 'string',
53
  },
@@ -109,10 +112,7 @@
109
  args.push( el( 'optgroup', {label: advadsGutenberg.i18n['ads']}, ads ) );
110
 
111
  // add a <label /> first and style it.
112
- children.push( el( 'label', {style:{fontWeight:'bold',display:'block'}}, advadsGutenberg.i18n.advads ) );
113
-
114
- // then add the <select /> input with its own children
115
- children.push( el.apply( null, args ) );
116
 
117
  if ( itemID && advadsGutenberg.i18n['--empty--'] != itemID ) {
118
 
@@ -128,23 +128,28 @@
128
 
129
  children.push(
130
  el(
131
- 'a',
132
- {
133
- class: 'dashicons dashicons-external',
134
- style: {
135
- 'vetical-align': 'middle',
136
- margin: 5,
137
- 'border-bottom': 'none'
138
- },
139
- href: url,
140
- target: '_blank',
141
- }
 
 
 
 
142
  )
143
  );
144
-
 
145
  }
146
  // return the complete form
147
- return el( 'form', { onSubmit: setItemID }, children );
148
 
149
  },
150
 
@@ -153,6 +158,37 @@
153
  return null;
154
  },
155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  } );
157
 
158
  })(window.wp);
48
  category: 'common',
49
 
50
  attributes: {
51
+ className: {
52
+ type: 'string',
53
+ },
54
  itemID: {
55
  type: 'string',
56
  },
112
  args.push( el( 'optgroup', {label: advadsGutenberg.i18n['ads']}, ads ) );
113
 
114
  // add a <label /> first and style it.
115
+ children.push( el( 'div', {className: 'components-placeholder__label'}, advadsIconEl, el( 'label', {style: {display: 'block'}}, advadsGutenberg.i18n.advads ) ) );
 
 
 
116
 
117
  if ( itemID && advadsGutenberg.i18n['--empty--'] != itemID ) {
118
 
128
 
129
  children.push(
130
  el(
131
+ 'div',
132
+ {className: 'components-placeholder__fieldset'},
133
+ // then add the <select /> input with its own children
134
+ el.apply( null, args ),
135
+ el(
136
+ 'a',
137
+ {
138
+ class: 'dashicons dashicons-external',
139
+ style: {
140
+ margin: 5
141
+ },
142
+ href: url,
143
+ target: '_blank'
144
+ }
145
+ )
146
  )
147
  );
148
+ } else {
149
+ children.push( el.apply( null, args ) );
150
  }
151
  // return the complete form
152
+ return el( 'form', { className: 'components-placeholder is-large', onSubmit: setItemID }, children );
153
 
154
  },
155
 
158
  return null;
159
  },
160
 
161
+ // Transforms legacy widget to Advanced Ads block.
162
+ transforms: {
163
+ from: [{
164
+ type: 'block',
165
+ blocks: ['core/legacy-widget'],
166
+ isMatch: function ( attributes ) {
167
+ if ( ! attributes.instance || ! attributes.instance.raw ) {
168
+ // Can't transform if raw instance is not shown in REST API.
169
+ return false;
170
+ }
171
+ return attributes.idBase === 'advads_ad_widget';
172
+ },
173
+ transform: function ( attributes ) {
174
+ var instance = attributes.instance.raw;
175
+ var transformedBlock = wp.blocks.createBlock( 'advads/gblock', {
176
+ name: instance.name,
177
+ itemID: instance.item_id
178
+ } );
179
+ if ( ! instance.title ) {
180
+ return transformedBlock;
181
+ }
182
+ return [
183
+ wp.blocks.createBlock( 'core/heading', {
184
+ content: instance.title
185
+ } ),
186
+ transformedBlock
187
+ ];
188
+ }
189
+ }]
190
+ }
191
+
192
  } );
193
 
194
  })(window.wp);
modules/import-export/classes/XmlEncoder.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- /*
3
  * Encodes XML data.
4
  *
5
  * Based on code from the Symfony package
@@ -186,21 +186,39 @@ class Advanced_Ads_XmlEncoder
186
  return $name && false === strpos($name, ' ') && preg_match('#^[\pL_][\pL0-9._:-]*$#ui', $name);
187
  }
188
 
189
- public function decode($data) {
190
- if ( ! extension_loaded( 'simplexml' ) ) {
191
- throw new Exception( sprintf( __( 'The %s extension(s) is not loaded', 'advanced-ads' ), 'simplexml' ) );
192
- }
193
- if ( ! extension_loaded( 'dom' ) ) {
194
- throw new Exception( sprintf( __( 'The %s extension(s) is not loaded', 'advanced-ads' ), 'dom' ) );
195
- }
 
 
 
 
 
 
 
 
 
 
 
196
 
197
 
198
  if ('' === trim($data)) {
199
  throw new UnexpectedValueException( _x( 'Invalid XML data, it can not be empty', 'import_export', 'advanced-ads' ) );
200
  }
201
 
202
- $internalErrors = libxml_use_internal_errors(true);
203
- $disableEntities = libxml_disable_entity_loader(true);
 
 
 
 
 
 
 
204
  libxml_clear_errors();
205
 
206
  $dom = new DOMDocument();
@@ -212,8 +230,11 @@ class Advanced_Ads_XmlEncoder
212
 
213
  $dom->loadXML($data, LIBXML_NONET | LIBXML_NOBLANKS);
214
 
215
- libxml_use_internal_errors($internalErrors);
216
- libxml_disable_entity_loader($disableEntities);
 
 
 
217
 
218
  if ($error = libxml_get_last_error()) {
219
  libxml_clear_errors();
1
  <?php
2
+ /**
3
  * Encodes XML data.
4
  *
5
  * Based on code from the Symfony package
186
  return $name && false === strpos($name, ' ') && preg_match('#^[\pL_][\pL0-9._:-]*$#ui', $name);
187
  }
188
 
189
+ /**
190
+ * Decode XML data.
191
+ *
192
+ * @throws Exception If an extension is lt loaded.
193
+ * @throws UnexpectedValueException If XML data is invalid.
194
+ *
195
+ * @param string $data XML data.
196
+ * @return array Decoded XML data.
197
+ */
198
+ public function decode( $data ) {
199
+ if ( ! extension_loaded( 'simplexml' ) ) {
200
+ /* translators: %s: A name of not loaded extension. */
201
+ throw new Exception( sprintf( __( 'The %s extension(s) is not loaded', 'advanced-ads' ), 'simplexml' ) );
202
+ }
203
+ if ( ! extension_loaded( 'dom' ) ) {
204
+ /* translators: %s: A name of not loaded extension. */
205
+ throw new Exception( sprintf( __( 'The %s extension(s) is not loaded', 'advanced-ads' ), 'dom' ) );
206
+ }
207
 
208
 
209
  if ('' === trim($data)) {
210
  throw new UnexpectedValueException( _x( 'Invalid XML data, it can not be empty', 'import_export', 'advanced-ads' ) );
211
  }
212
 
213
+ $internal_errors = libxml_use_internal_errors( true );
214
+
215
+ if ( PHP_VERSION_ID < 80000 ) {
216
+ // This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading
217
+ // is disabled by default, so this function is no longer needed to protect against XXE attacks.
218
+ // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.libxml_disable_entity_loaderDeprecated
219
+ $disable_entities = libxml_disable_entity_loader( true );
220
+ }
221
+
222
  libxml_clear_errors();
223
 
224
  $dom = new DOMDocument();
230
 
231
  $dom->loadXML($data, LIBXML_NONET | LIBXML_NOBLANKS);
232
 
233
+ libxml_use_internal_errors( $internal_errors );
234
+
235
+ if ( PHP_VERSION_ID < 80000 && isset( $disable_entities ) ) {
236
+ libxml_disable_entity_loader( $disable_entities );
237
+ }
238
 
239
  if ($error = libxml_get_last_error()) {
240
  libxml_clear_errors();
modules/import-export/classes/export.php CHANGED
@@ -1,4 +1,7 @@
1
  <?php
 
 
 
2
  class Advanced_Ads_Export {
3
  /**
4
  * @var Advanced_Ads_Export
@@ -47,7 +50,9 @@ class Advanced_Ads_Export {
47
  }
48
 
49
  /**
50
- * Generate XML file
 
 
51
  */
52
  private function process( array $content ) {
53
  global $wpdb;
@@ -78,10 +83,13 @@ class Advanced_Ads_Export {
78
 
79
  $posts = $wpdb->get_results( $wpdb->prepare( "SELECT $export_fields FROM {$wpdb->posts} where post_type = '%s' and post_status not in ('trash', 'auto-draft')", Advanced_Ads::POST_TYPE_SLUG ), ARRAY_A );
80
 
 
 
 
 
81
  foreach ( $posts as $k => $post ) {
82
  if ( ! empty( $post['post_content'] ) ) {
83
  // wrap images in <advads_import_img></advads_import_img> tags
84
- $search = '/' . preg_quote( home_url(), '/' ) . '(\S+?)\.(jpg|jpeg|gif|png)/i';
85
  $post['post_content'] = preg_replace( $search, '<advads_import_img>\\0</advads_import_img>', $post['post_content'] );
86
  }
87
 
@@ -163,11 +171,18 @@ class Advanced_Ads_Export {
163
  $export['placements'] = array_values( $placements );
164
  }
165
 
166
- if ( in_array( 'options', $content ) ) {
167
- $export['options'] = apply_filters( 'advanced-ads-export-options', array (
168
- ADVADS_SLUG => Advanced_Ads::get_instance()->options(),
169
- ADVADS_SLUG . '-internal' => Advanced_Ads::get_instance()->internal_options(),
170
- ) );
 
 
 
 
 
 
 
171
  }
172
 
173
  do_action_ref_array( 'advanced-ads-export', array( $content, &$export ) );
@@ -182,7 +197,7 @@ class Advanced_Ads_Export {
182
 
183
  try {
184
  $encoded = Advanced_Ads_XmlEncoder::get_instance()->encode( $export, array( 'encoding' => get_option( 'blog_charset' ) ) );
185
-
186
  header( 'Content-Description: File Transfer' );
187
  header( 'Content-Disposition: attachment; filename=' . $filename );
188
  header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
@@ -205,4 +220,4 @@ class Advanced_Ads_Export {
205
  public function get_messages(){
206
  return $this->messages;
207
  }
208
- }
1
  <?php
2
+ /**
3
+ * Export functionality.
4
+ */
5
  class Advanced_Ads_Export {
6
  /**
7
  * @var Advanced_Ads_Export
50
  }
51
 
52
  /**
53
+ * Generate XML file.
54
+ *
55
+ * @param array $content Types of content to be exported.
56
  */
57
  private function process( array $content ) {
58
  global $wpdb;
83
 
84
  $posts = $wpdb->get_results( $wpdb->prepare( "SELECT $export_fields FROM {$wpdb->posts} where post_type = '%s' and post_status not in ('trash', 'auto-draft')", Advanced_Ads::POST_TYPE_SLUG ), ARRAY_A );
85
 
86
+ $mime_types = array_filter( get_allowed_mime_types(), function( $mime_type ) {
87
+ return preg_match( '/image\//', $mime_type );
88
+ } );
89
+ $search = '/' . preg_quote( home_url(), '/' ) . '(\S+?)\.(' . implode( '|', array_keys( $mime_types ) ) . ')/i';
90
  foreach ( $posts as $k => $post ) {
91
  if ( ! empty( $post['post_content'] ) ) {
92
  // wrap images in <advads_import_img></advads_import_img> tags
 
93
  $post['post_content'] = preg_replace( $search, '<advads_import_img>\\0</advads_import_img>', $post['post_content'] );
94
  }
95
 
171
  $export['placements'] = array_values( $placements );
172
  }
173
 
174
+ if ( in_array( 'options', $content, true ) ) {
175
+ /**
176
+ * Filters the list of options to be exported.
177
+ *
178
+ * @param $options An array of options
179
+ */
180
+ $export['options'] = array_filter( apply_filters( 'advanced-ads-export-options', array(
181
+ ADVADS_SLUG => get_option( ADVADS_SLUG ),
182
+ GADSENSE_OPT_NAME => get_option( GADSENSE_OPT_NAME ),
183
+ Advanced_Ads_Privacy::OPTION_KEY => get_option( Advanced_Ads_Privacy::OPTION_KEY ),
184
+ Advanced_Ads_Ads_Txt_Strategy::OPTION => get_option( Advanced_Ads_Ads_Txt_Strategy::OPTION ),
185
+ ) ) );
186
  }
187
 
188
  do_action_ref_array( 'advanced-ads-export', array( $content, &$export ) );
197
 
198
  try {
199
  $encoded = Advanced_Ads_XmlEncoder::get_instance()->encode( $export, array( 'encoding' => get_option( 'blog_charset' ) ) );
200
+
201
  header( 'Content-Description: File Transfer' );
202
  header( 'Content-Disposition: attachment; filename=' . $filename );
203
  header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
220
  public function get_messages(){
221
  return $this->messages;
222
  }
223
+ }
modules/import-export/classes/import.php CHANGED
@@ -71,7 +71,8 @@ class Advanced_Ads_Import {
71
  return;
72
  }
73
  // see wp_magic_quotes()
74
- $this->import( stripslashes( $_POST['xml_textarea'] ) );
 
75
  break;
76
  case 'xml_file':
77
  if ( $this->handle_upload() ) {
@@ -86,12 +87,14 @@ class Advanced_Ads_Import {
86
  /**
87
  * The main controller for the actual import stage
88
  *
89
- * @param string $xml_content
90
  */
91
  public function import( &$xml_content ) {
92
  @set_time_limit( 0 );
93
  @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
94
 
 
 
95
  if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
96
  error_log( 'source XML:' );
97
  error_log( $xml_content );
@@ -475,24 +478,37 @@ class Advanced_Ads_Import {
475
  }
476
 
477
  /**
478
- * Create new options based on import information
479
  *
480
- * @param array $decoded decoded XML
481
  */
482
  private function import_options( &$decoded ) {
483
  if ( isset( $decoded['options'] ) && is_array( $decoded['options'] ) ) {
484
- foreach ( $decoded['options'] as $option_name => $option ) {
485
- // ignore options not belonging to advanced ads
486
- if ( 0 !== strpos( $option_name, 'advads-' ) && 0 !== strpos( $option_name, 'advanced-ads' ) ) {
 
 
 
 
 
487
  continue;
488
  }
489
 
490
- if( ! get_option( $option_name ) ) {
491
- $this->messages[] = array( 'error', sprintf(__( 'Option was updated: <em>%s</em>', 'advanced-ads' ), $option_name ) );
492
- update_option( $option_name, maybe_unserialize( $option ) );
493
- } else {
494
- $this->messages[] = array( 'error', sprintf(__( 'Option already exists: <em>%s</em>', 'advanced-ads' ), $option_name ) );
 
 
495
  }
 
 
 
 
 
 
496
  }
497
  }
498
  }
@@ -608,7 +624,7 @@ class Advanced_Ads_Import {
608
  /**
609
  * Upload image from URL and create attachment
610
  *
611
- * @param string $image_url
612
  * @return array with indices: post_id, attachment_url, false on failure
613
  */
614
  private function upload_image_from_url( $image_url ) {
@@ -652,9 +668,21 @@ class Advanced_Ads_Import {
652
  return false;
653
  }
654
 
655
- if ( ! ( $fileinfo = @getimagesize( $upload['file'] ) ) || ! in_array( $fileinfo[2], array( IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF ) ) ) {
 
 
 
 
 
 
 
 
 
 
656
  @unlink( $upload['file'] );
657
- $this->messages[] = array( 'error', sprintf( __( 'Error getting remote image <em>%s</em>', 'advanced-ads' ), $image_url ) );
 
 
658
  return false;
659
  }
660
 
71
  return;
72
  }
73
  // see wp_magic_quotes()
74
+ $content = stripslashes( $_POST['xml_textarea'] );
75
+ $this->import( $content );
76
  break;
77
  case 'xml_file':
78
  if ( $this->handle_upload() ) {
87
  /**
88
  * The main controller for the actual import stage
89
  *
90
+ * @param string $xml_content XML content to import.
91
  */
92
  public function import( &$xml_content ) {
93
  @set_time_limit( 0 );
94
  @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
95
 
96
+ $xml_content = trim( $xml_content );
97
+
98
  if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
99
  error_log( 'source XML:' );
100
  error_log( $xml_content );
478
  }
479
 
480
  /**
481
+ * Create new options based on import information.
482
  *
483
+ * @param array $decoded decoded XML.
484
  */
485
  private function import_options( &$decoded ) {
486
  if ( isset( $decoded['options'] ) && is_array( $decoded['options'] ) ) {
487
+ foreach ( $decoded['options'] as $option_name => $imported_option ) {
488
+ // Ignore options not belonging to advanced ads.
489
+ if (
490
+ 0 !== strpos( $option_name, 'advads-' )
491
+ && 0 !== strpos( $option_name, 'advads_' )
492
+ && 0 !== strpos( $option_name, 'advanced-ads' )
493
+ && 0 !== strpos( $option_name, 'advanced_ads' )
494
+ ) {
495
  continue;
496
  }
497
 
498
+ $existing_option = get_option( $option_name, array() );
499
+
500
+ if ( ! is_array( $imported_option ) ) {
501
+ $imported_option = array();
502
+ }
503
+ if ( ! is_array( $existing_option ) ) {
504
+ $existing_option = array();
505
  }
506
+
507
+ $option_to_import = array_merge( $existing_option, $imported_option );
508
+
509
+ /* translators: %s: Option name. */
510
+ $this->messages[] = array( 'update', sprintf( __( 'Option was updated: <em>%s</em>', 'advanced-ads' ), $option_name ) );
511
+ update_option( $option_name, maybe_unserialize( $option_to_import ) );
512
  }
513
  }
514
  }
624
  /**
625
  * Upload image from URL and create attachment
626
  *
627
+ * @param string $image_url Image url.
628
  * @return array with indices: post_id, attachment_url, false on failure
629
  */
630
  private function upload_image_from_url( $image_url ) {
668
  return false;
669
  }
670
 
671
+ /**
672
+ * Get allowed image mime types.
673
+ *
674
+ * @var string Single mime type.
675
+ */
676
+ $mime_types = array_filter( get_allowed_mime_types(), function( $mime_type ) {
677
+ return preg_match( '/image\//', $mime_type );
678
+ } );
679
+ $fileinfo = @getimagesize( $upload['file'] );
680
+
681
+ if ( ! $fileinfo || ! in_array( $fileinfo['mime'], $mime_types, true ) ) {
682
  @unlink( $upload['file'] );
683
+ /* translators: 1: image url */
684
+ $this->messages[] = array( 'error', sprintf( __( 'Error getting remote image <em>%s</em>', 'advanced-ads' ), $image_url ) );
685
+
686
  return false;
687
  }
688
 
modules/import-export/views/page.php CHANGED
@@ -20,10 +20,10 @@ class_exists( 'Advanced_Ads', false ) || exit();
20
  <fieldset>
21
  <input type="hidden" name="action" value="export" />
22
  <?php wp_nonce_field( 'advads-export' ); ?>
23
- <p><label><input type="checkbox" name="content[]" value="ads" checked="checked" /> <?php _e( 'Ads', 'advanced-ads' ); ?></label></p>
24
- <p><label><input type="checkbox" name="content[]" value="groups" checked="checked" /> <?php _e( 'Groups', 'advanced-ads' ); ?></label></p>
25
- <p><label><input type="checkbox" name="content[]" value="placements" checked="checked" /> <?php _e( 'Placements', 'advanced-ads' ); ?></label></p>
26
- <p><label><input type="checkbox" name="content[]" value="options" checked="checked" /> <?php _e( 'Options', 'advanced-ads' ); ?></label></p>
27
  </fieldset>
28
  <?php submit_button( __( 'Download Export File', 'advanced-ads' ) ); ?>
29
  </form>
20
  <fieldset>
21
  <input type="hidden" name="action" value="export" />
22
  <?php wp_nonce_field( 'advads-export' ); ?>
23
+ <p><label><input type="checkbox" name="content[]" value="ads" checked="checked" /> <?php esc_html_e( 'Ads', 'advanced-ads' ); ?></label></p>
24
+ <p><label><input type="checkbox" name="content[]" value="groups" checked="checked" /> <?php esc_html_e( 'Groups', 'advanced-ads' ); ?></label></p>
25
+ <p><label><input type="checkbox" name="content[]" value="placements" checked="checked" /> <?php esc_html_e( 'Placements', 'advanced-ads' ); ?></label></p>
26
+ <p><label><input type="checkbox" name="content[]" value="options" /> <?php esc_html_e( 'Options', 'advanced-ads' ); ?></label></p>
27
  </fieldset>
28
  <?php submit_button( __( 'Download Export File', 'advanced-ads' ) ); ?>
29
  </form>
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: webzunft, advancedads
3
  Tags: ads, ad manager, ad rotation, adsense, banner
4
  Requires at least: 4.9
5
- Tested up to: 5.7
6
  Requires PHP: 5.6
7
- Stable tag: 1.25.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -14,14 +14,14 @@ Manage and optimize all ad types. Support for Google AdSense Auto ads, Amazon, i
14
 
15
  Are you looking for a simple ad manager plugin? These are the top arguments to use Advanced Ads:
16
 
17
- * approved in 10 years of Publishing and Ad Optimization
18
- * works with all ad types and networks, including Google AdSense, Google Ad Manager (DFP), Amazon ads, or media.net
19
- * Google AdSense Partner
20
  * most features to test and optimize ads
21
  * unlimited ad units
22
  * ads.txt support
23
- * dedicated Gutenberg block for ads
24
- * the only solution with *Ad Health* integration and Google AdSense violation checks
 
25
  * best rated [free support](https://wordpress.org/support/plugin/advanced-ads)
26
 
27
  This is what our users are saying about Advanced Ads:
@@ -42,24 +42,24 @@ Advanced Ads allowed us to grow from 0 to 100 MM monthly ad impressions. Benefit
42
  * schedule ads and set start time and expiration date
43
  * target ads by content and user groups
44
  * inject ads into posts and pages automatically without coding
45
- * sell ads on your website automatically with the [Selling Ads add-on](https://wpadvancedads.com/add-ons/selling-ads/)
46
 
47
  = ad types =
48
 
49
  choose between different ad types that enable you to:
50
 
51
- * insert ads content and banners from all ad and affiliate networks (e.g., Google AdSense, Amazon, BuySellAds, Google Ad Manager, DoubleClick (DFP), Ezoic, media.net, Booking.com, Tradedoubler, Awin, Getyourguide, The Moneytizer...)
52
- * dedicated support for all types of Google AdSense ads, including text and diplay ads, native ads (In-article, In-feed, matched content), link units (standard and responsive), Auto ads, and Auto ads for AMP
53
  * display images and image banners
54
  * create content-rich ads with the WordPress TinyMCE editor
55
- * create Amazon ads with the Rich Content ad type and the [Amazon Associates Link Builder](https://wordpress.org/plugins/amazon-associates-link-builder/) or insert contextual Amazon Native Shopping Ads
56
  * inject HTML, CSS, Javascript or PHP code
57
  * use shortcodes within ads (to also deliver advertisements from another ad plugin like Ad Inserter, AdRotate, Quick AdSense, WP Bannerize, or the Google AdSense Plugin WP QUADS)
58
 
59
  = display ads for WP =
60
 
 
61
  * use functions to display ads in template files
62
- * use shortcodes to place them manually in post content
63
  * show ads in the sidebar and in widgets
64
  * disable all ads on specific pages
65
  * display multiple ads (ad blocks)
@@ -100,7 +100,7 @@ Placements to insert ads in pre-defined positions in your theme and content. [Li
100
  * ads at the top or bottom of the post content
101
  * ads before closing `</head>` tag
102
  * ads in the footer
103
- * test placements against each other with [Pro](https://wpadvancedads.com/add-ons/advanced-ads-pro/)
104
  * many more ad positions with [add-ons](https://wpadvancedads.com/add-ons/)
105
  * automatic insertion of any kind of code into header or footer, not only advertising
106
 
@@ -119,18 +119,20 @@ Amazing features of the most powerful and easy Google AdSense plugin.
119
  * pull ad units directly from your Google AdSense account
120
  * show AdSense revenue in WP Admin
121
  * change settings of your Google AdSense ads directly from your WordPress backend
122
- * supports all Google AdSense ad types, including Google AdSense display ads, link units, native ads like In-feed ads, In-article ads, matched content ads, Google AdSense Auto ads, and Google AdSense Auto ads for AMP
123
- * change type and sizes of an ad without going into your Google AdSense account
124
  * hide Google AdSense advertisements on 404 pages by default (to comply with Google AdSense terms)
125
- * insert Google AdSense code for verification and AdSense Auto Ads (previously called Page-Level ads and QuickStart)
126
  * enable AdSense Auto ads on AMP
127
  * easy Ad Health integration and Google AdSense violation checks
128
- * option to make the Google AdSense background transparent
129
  * place Google AdSense In-feed ads using the also free [In-feed add-on](https://wordpress.org/plugins/advanced-ads-adsense-in-feed/)
130
- * assistant for exact sizes of responsive Google AdSense code with the [Responsive add-on](https://wpadvancedads.com/add-ons/responsive-ads/)
131
  * convert Google AdSense ads into AMP ads automatically with the [Responsive add-on](https://wpadvancedads.com/add-ons/responsive-ads/)
132
  * ads.txt generated with the correct AdSense information automatically
133
- * works along Google Site Kit or can replace if it you want to [control your ad placements](https://wpadvancedads.com/place-adsense-ad-unit-manually/)
 
 
134
 
135
  Like j4ckson185, there are thousands of happy AdSense users:
136
 
@@ -138,14 +140,14 @@ Like j4ckson185, there are thousands of happy AdSense users:
138
 
139
  = ads.txt =
140
 
141
- * generates ads.txt with custom content
142
  * adds the content for AdSense to the ads.txt automatically
143
 
144
- https://vimeo.com/299410390
145
 
146
  = ad blocker =
147
 
148
- * basic features to prevent ad units from being removed by AdBlock and others
149
  * prevent ad blockers from breaking sites where plugin scripts are running
150
  * ad blocking detection: show alternative content to ad block users with [Pro](https://wpadvancedads.com/add-ons/advanced-ads-pro/) and improve the monetization of your website
151
 
@@ -153,22 +155,24 @@ Learn more on the [plugin homepage](https://wpadvancedads.com).
153
 
154
  Thank you for motivating us with your [positive review](https://wordpress.org/support/plugin/advanced-ads/reviews/?rate=5#new-post).
155
 
156
- Localizations: Arabic, Chinese, Czech, Dutch, English, French, German, Hungarian, Italian, Japanese, Norwegian, Polish, Portuguese, Russian, Slovak, Spanish, Turkish, Vietnamese
157
 
158
  > <strong>Add-Ons</strong>
159
  >
160
  > * all add-ons include priority email support
161
- > * [Advanced Ads Pro](https://wpadvancedads.com/add-ons/advanced-ads-pro/) – powerful tools for ad optimizations: cache-busting, more placements, lazy load, ad blocker module, click fraud, and more
162
- > * [Tracking](https://wpadvancedads.com/add-ons/tracking/) – ad tracking and statistics
163
- > * [Responsive Ads](https://wpadvancedads.com/add-ons/responsive-ads/) – create mobile ads or ads for specific browser sizes and ads on AMP
164
- > * [Google Ad Manager Integration](https://wpadvancedads.com/add-ons/google-ad-manager/) – a quick and error-free way to load ad units from GAM / DFP account without touching any ad codes
165
- > * [Geo Targeting](https://wpadvancedads.com/add-ons/geo-targeting/) – display ads based on geo location of the visitor
166
  > * [Sticky Ads](https://wpadvancedads.com/add-ons/sticky-ads/) – increase click rates with fixed, sticky, and anchor ads
 
167
  > * [PopUp and Layer Ads](https://wpadvancedads.com/add-ons/popup-and-layer-ads/) – display ads and other content in layers and popups
168
  > * [Selling Ads](https://wpadvancedads.com/add-ons/selling-ads/) - allows you to sell ads on your website fully automated, including payments and advertiser profiles.
169
- > * [Slider](https://wpadvancedads.com/add-ons/slider/) – create a simple slider from your ads
170
 
171
- If you have problems with Advanced Ads, please reach out to [our support](https://wordpress.org/support/plugin/advanced-ads).
 
172
 
173
  = Integrations =
174
 
@@ -178,11 +182,12 @@ Advanced Ads integrates with plenty of other plugins:
178
  - WPML – [Showing different ads per language with WPML](https://wpadvancedads.com/translating-ads-wpml/)
179
  - WPBakery Page Builder – [Displaying Ads with WPBakery Page Builder (formerly Visual Composer)](https://wpadvancedads.com/visual-composer-ads/)
180
  - Genesis – [Genesis Ads add-on](https://wpadvancedads.com/add-ons/genesis-ads/)
181
- - BuddyPress & BuddyBoss – [How to add ads on BuddyPress pages](https://wpadvancedads.com/ads-on-buddypress-pages/)
 
182
  - bbPress – [How to show ads on bbPress pages?](https://wpadvancedads.com/ads-in-bbpress/)
183
- - Cookie Consent, Borlabs Cookies, Complianz and other content manager – [How to show ads based on visitors’ consent](https://wpadvancedads.com/manual/ad-cookie-consent/)
184
  - Paid Memberships Pro – [How to manage ads on membership sites running Paid Memberships Pro](https://wpadvancedads.com/paid-memberships-pro/)
185
- - IAB TCF 2.0 consent – hide ads until users give their consent. Integrating with any CMP, Quantcast Choices, iubenda, Google Funding Choices, cookiebot, etc.
186
 
187
  == Installation ==
188
 
@@ -239,7 +244,7 @@ You can learn more about how Advanced Ads and its add-ons handles data and priva
239
 
240
  = Which ad networks are supported? =
241
 
242
- Advanced Ads is compatible with all ad networks and banners from affiliate programs like Google AdSense, Chitika, Clickbank, Amazon, and also Google Ad Manager (Google Double Click, DFP), media.net.
243
 
244
  You can also use it to insert additional ad network tags into header or footer of your site without coding.
245
 
@@ -317,6 +322,17 @@ Yes. You can use plenty of [hooks](https://wpadvancedads.com/codex/) to customiz
317
 
318
  == Changelog ==
319
 
 
 
 
 
 
 
 
 
 
 
 
320
  = 1.25.1 =
321
 
322
  - fixed a bug that prevented removing placement conditions
2
  Contributors: webzunft, advancedads
3
  Tags: ads, ad manager, ad rotation, adsense, banner
4
  Requires at least: 4.9
5
+ Tested up to: 5.8
6
  Requires PHP: 5.6
7
+ Stable tag: 1.26.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
14
 
15
  Are you looking for a simple ad manager plugin? These are the top arguments to use Advanced Ads:
16
 
17
+ * approved in publishing and ad optimization since 2009
18
+ * works with all ad types and networks, including Google AdSense, Google Ad Manager (formerly Google DoubleClick for Publishers, DFP), Amazon ads, or media.net ads
 
19
  * most features to test and optimize ads
20
  * unlimited ad units
21
  * ads.txt support
22
+ * dedicated ad block for the block editor
23
+ * Google AdSense Partner, who implements all technical changes early and in 100% compliance with the Google AdSense policies
24
+ * the only advertising solution with *Ad Health* integration and Google AdSense violation checks
25
  * best rated [free support](https://wordpress.org/support/plugin/advanced-ads)
26
 
27
  This is what our users are saying about Advanced Ads:
42
  * schedule ads and set start time and expiration date
43
  * target ads by content and user groups
44
  * inject ads into posts and pages automatically without coding
 
45
 
46
  = ad types =
47
 
48
  choose between different ad types that enable you to:
49
 
50
+ * insert ads and banners from all ad and affiliate networks (e.g., Google AdSense, Amazon, BuySellAds, Google Ad Manager (formerly Google DoubleClick for Publishers, DFP), Ezoic, media.net, Booking.com, Tradedoubler, Awin, Getyourguide, The Moneytizer, Infolinks...)
51
+ * dedicated support for all types of Google AdSense ads, including text and display ads, native ads (In-article, In-feed, matched content), Auto ads, and Auto ads for AMP
52
  * display images and image banners
53
  * create content-rich ads with the WordPress TinyMCE editor
54
+ * insert contextual Amazon Native Shopping Ads
55
  * inject HTML, CSS, Javascript or PHP code
56
  * use shortcodes within ads (to also deliver advertisements from another ad plugin like Ad Inserter, AdRotate, Quick AdSense, WP Bannerize, or the Google AdSense Plugin WP QUADS)
57
 
58
  = display ads for WP =
59
 
60
+ * auto-inject ads via placements
61
  * use functions to display ads in template files
62
+ * use shortcodes to place ads manually in post content
63
  * show ads in the sidebar and in widgets
64
  * disable all ads on specific pages
65
  * display multiple ads (ad blocks)
100
  * ads at the top or bottom of the post content
101
  * ads before closing `</head>` tag
102
  * ads in the footer
103
+ * test placements against each other with [Pro](https://wpadvancedads.com/add-ons/advanced-ads-pro/) (A/B testing)
104
  * many more ad positions with [add-ons](https://wpadvancedads.com/add-ons/)
105
  * automatic insertion of any kind of code into header or footer, not only advertising
106
 
119
  * pull ad units directly from your Google AdSense account
120
  * show AdSense revenue in WP Admin
121
  * change settings of your Google AdSense ads directly from your WordPress backend
122
+ * supports all Google AdSense ad types, including Google AdSense display ads, native ads like In-feed ads, In-article ads, matched content ads, Google AdSense Auto ads, and Google AdSense Auto ads for AMP
123
+ * change type and sizes of AdSense ads without going into your Google AdSense account
124
  * hide Google AdSense advertisements on 404 pages by default (to comply with Google AdSense terms)
125
+ * insert Google AdSense code for verification and AdSense Auto Ads
126
  * enable AdSense Auto ads on AMP
127
  * easy Ad Health integration and Google AdSense violation checks
128
+ * option to remove the Google AdSense background color
129
  * place Google AdSense In-feed ads using the also free [In-feed add-on](https://wordpress.org/plugins/advanced-ads-adsense-in-feed/)
130
+ * assistant for exact sizes of responsive Google AdSense ads with the [Responsive add-on](https://wpadvancedads.com/add-ons/responsive-ads/)
131
  * convert Google AdSense ads into AMP ads automatically with the [Responsive add-on](https://wpadvancedads.com/add-ons/responsive-ads/)
132
  * ads.txt generated with the correct AdSense information automatically
133
+ * works along with Google Site Kit or can replace it if you want to [control your ad placements](https://wpadvancedads.com/place-adsense-ad-unit-manually/)
134
+
135
+ https://vimeo.com/577120971
136
 
137
  Like j4ckson185, there are thousands of happy AdSense users:
138
 
140
 
141
  = ads.txt =
142
 
143
+ * generates an ads.txt with custom content
144
  * adds the content for AdSense to the ads.txt automatically
145
 
146
+ https://vimeo.com/577170591
147
 
148
  = ad blocker =
149
 
150
+ * basic features to prevent ads from being removed by AdBlock and other ad blockers
151
  * prevent ad blockers from breaking sites where plugin scripts are running
152
  * ad blocking detection: show alternative content to ad block users with [Pro](https://wpadvancedads.com/add-ons/advanced-ads-pro/) and improve the monetization of your website
153
 
155
 
156
  Thank you for motivating us with your [positive review](https://wordpress.org/support/plugin/advanced-ads/reviews/?rate=5#new-post).
157
 
158
+ Localizations: Arabic, Chinese, Czech, Danish, Dutch, English, French, German, Hungarian, Italian, Japanese, Norwegian, Polish, Portuguese, Russian, Slovak, Spanish, Turkish, Vietnamese
159
 
160
  > <strong>Add-Ons</strong>
161
  >
162
  > * all add-ons include priority email support
163
+ > * [Advanced Ads Pro](https://wpadvancedads.com/add-ons/advanced-ads-pro/) – powerful tools for ad optimizations: cache-busting, more placements, lazy loading, ad blocker module, click fraud protection, and many more
164
+ > * [Tracking](https://wpadvancedads.com/add-ons/tracking/) – track ad impressions and ad clicks with local methods or Google Analytics
165
+ > * [Responsive Ads](https://wpadvancedads.com/add-ons/responsive-ads/) – target ads to specific browser sizes and create ads for AMP
166
+ > * [Google Ad Manager Integration](https://wpadvancedads.com/add-ons/google-ad-manager/) – a quick and error-free way to load ad units from your Google Ad Manager (formerly Google DoubleClick for Publishers, DFP) account without touching any ad codes
167
+ > * [Geo Targeting](https://wpadvancedads.com/add-ons/geo-targeting/) – display ads based on the geo location of the visitor
168
  > * [Sticky Ads](https://wpadvancedads.com/add-ons/sticky-ads/) – increase click rates with fixed, sticky, and anchor ads
169
+ > * [Fixed Widget for WordPress](https://wordpress.org/plugins/q2w3-fixed-widget/) – turn sidebar widgets into performant fixed sticky ads
170
  > * [PopUp and Layer Ads](https://wpadvancedads.com/add-ons/popup-and-layer-ads/) – display ads and other content in layers and popups
171
  > * [Selling Ads](https://wpadvancedads.com/add-ons/selling-ads/) - allows you to sell ads on your website fully automated, including payments and advertiser profiles.
172
+ > * [Ad Slider](https://wpadvancedads.com/add-ons/slider/) – create a simple slider from your ads
173
 
174
+ If you have problems with Advanced Ads, please reach out to [our support](https://wordpress.org/support/plugin/advanced-ads) or open a [new topic](https://wordpress.org/support/plugin/advanced-ads/#new-topic-0) in our forums on wordpress.org
175
+ .
176
 
177
  = Integrations =
178
 
182
  - WPML – [Showing different ads per language with WPML](https://wpadvancedads.com/translating-ads-wpml/)
183
  - WPBakery Page Builder – [Displaying Ads with WPBakery Page Builder (formerly Visual Composer)](https://wpadvancedads.com/visual-composer-ads/)
184
  - Genesis – [Genesis Ads add-on](https://wpadvancedads.com/add-ons/genesis-ads/)
185
+ - BuddyBoss – [How to integrate ads into BuddyBoss](https://wpadvancedads.com/manual/buddyboss-ads/)
186
+ - BuddyPress – [How to add ads on BuddyPress pages](https://wpadvancedads.com/ads-on-buddypress-pages/)
187
  - bbPress – [How to show ads on bbPress pages?](https://wpadvancedads.com/ads-in-bbpress/)
188
+ - Cookie Consent, Borlabs Cookies, Complianz, GDPR Cookie Consent, and other content manager – [How to show ads based on visitors’ consent](https://wpadvancedads.com/manual/ad-cookie-consent/)
189
  - Paid Memberships Pro – [How to manage ads on membership sites running Paid Memberships Pro](https://wpadvancedads.com/paid-memberships-pro/)
190
+ - [IAB TCF 2.0 consent](https://wpadvancedads.com/manual/tcf-consent-wordpress/) – hide ads until users give their consent. Integrating with any CMP, Quantcast Choices, iubenda, Google Funding Choices, cookiebot, etc.
191
 
192
  == Installation ==
193
 
244
 
245
  = Which ad networks are supported? =
246
 
247
+ Advanced Ads is compatible with all ad networks and banners from affiliate programs like Google AdSense, Chitika, Clickbank, Amazon, and also Google Ad Manager (formerly Google DoubleClick for Publishers, DFP), media.net.
248
 
249
  You can also use it to insert additional ad network tags into header or footer of your site without coding.
250
 
322
 
323
  == Changelog ==
324
 
325
+ = 1.26.0 =
326
+
327
+ - overwrite existing options when importing new options
328
+ - add possibility to export privacy, ads.txt and Google AdSense options
329
+ - remove duplicate inline styles for placements with passive cache-busting and activated TCF 2.0 privacy option
330
+ - adjust the Advanced Ads block layout to the default WordPress block layout
331
+ - add migration from Advanced Ads widget to Advanced Ads block
332
+ - fix saving of additional CSS class in Advanced Ads block
333
+ - make placement deletion confirmation dialogue translatable
334
+ - add WebP as allowed image media type for exports
335
+
336
  = 1.25.1 =
337
 
338
  - fixed a bug that prevented removing placement conditions