Advanced Ads - Version 1.19.0

Version Description

  • placements are now ordered by type on the Placements page. You can still choose ordering by name
  • the "custom" option of the Content placement now comes with a picker to select the position in the frontend
  • WPML: placements pages show ads according to the selected language
  • WPML: display the ad in the original language if a translated ad is missing unless the publisher chooses to hide it instead
  • prevented injection of ads into captions of "image" blocks
  • improved bot check
  • fixed layout of expiry data fields
  • fixed broken check for the Responsive add-on
Download this release

Release Info

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

Code changes from version 1.18.0 to 1.19.0

admin/assets/css/admin.css CHANGED
@@ -176,6 +176,7 @@ select + .advads-conditions-single { padding-left: 10px }
176
  .advads-option-list { overflow: hidden; }
177
  .advads-option-list > .label { display: block; float: left; width: 10em; padding: 10px; font-weight: bold; text-transform: capitalize; color: #444; text-align: left; font-size: 100%; }
178
  .advads-option-list > .label + div { display: block; float: left; padding: 10px; max-width: calc(100% - (10em + 40px)); }
 
179
  .advads-option-list > hr { clear: both; float: none; display: block; }
180
  .advads-option-list div[style*="display: none"] + hr { display: none; }
181
 
@@ -195,13 +196,13 @@ select + .advads-conditions-single { padding-left: 10px }
195
 
196
  .advads-debug-output legend { text-decoration: underline; cursor: pointer; }
197
 
198
- #advads-exp-timestampdiv { padding-top: 5px; line-height: 23px; }
199
- #advads-exp-timestampdiv p { margin: 8px 0 6px; }
200
- #advads-exp-timestampdiv input { border-width: 1px; border-style: solid; }
201
- #advads-exp-timestampdiv select { height: 21px; line-height: 1.1667; padding: 0; vertical-align: top; font-size: 12px; }
202
- #advads-exp-aa, #advads-exp-jj, #advads-exp-hh, #advads-exp-mn { padding: 1px; font-size: 12px; }
203
- #advads-exp-jj, #advads-exp-hh, #advads-exp-mn { width: 2em; }
204
- #advads-exp-aa { width: 3.4em; }
205
 
206
  #advads-url,
207
  #advads-image-url,
@@ -239,6 +240,15 @@ select + .advads-conditions-single { padding-left: 10px }
239
  #advads-support-callout > p { color: #0073aa; }
240
  #advads-support-callout a { text-decoration: none; }
241
 
 
 
 
 
 
 
 
 
 
242
  /**
243
  AD GROUP LIST
244
  */
@@ -291,6 +301,11 @@ fieldset.advads-group-add-ad { margin-top: 1em; }
291
  .advads-placements-table-options { text-align: right; }
292
  .advads-placements-table-options input[type="number"] { width: 4.5em; }
293
  .advads-placements-table ol { margin: 0.5em 0; list-style-position: inside; }
 
 
 
 
 
294
 
295
  /**
296
  GENERAL ELEMENTS
@@ -382,7 +397,7 @@ tr:hover .on-hover { display: block; }
382
  #advads-tabs .nav-tab-active { background: #fff; border-bottom: 0; margin-top: 1px; }
383
  .advads-tab { display: none; padding: 5px 15px; overflow: hidden; background-color: #fff; border: 1px solid #ccc; border-top: none; }
384
  .advads-tab input[type="checkbox"] { margin-right: 8px; }
385
- .advads-tab .form-table th, .advads-tab, .advads-tab .form-table td { padding-bottom: 30px; }
386
  .advads-tab.active { display: block; }
387
  .advads-license-activate-active { color: #46b450; }
388
  .advads-license-activate-error { color: #dc3232; }
@@ -447,6 +462,7 @@ tr:hover .on-hover { display: block; }
447
  .advads-success-message { color: green !important; }
448
  .advads-hidden { display: none; }
449
  .advads-loader { display: block; width: 43px; height: 11px; background: url(../img/loader.gif) no-repeat; }
 
450
 
451
  /* Image Ad */
452
  #advads_type_image_wp_media .media-sidebar .setting:not([data-setting="title"]):not([data-setting="alt"]),
@@ -565,4 +581,4 @@ tr.advads-clickable-row:hover{
565
 
566
  /* Set max-width for wide select elements */
567
  .advads-conditions-select-wrap { display: inline-block; max-width: 100%; }
568
- .advads-conditions-select-wrap select { width: 100%; }
176
  .advads-option-list { overflow: hidden; }
177
  .advads-option-list > .label { display: block; float: left; width: 10em; padding: 10px; font-weight: bold; text-transform: capitalize; color: #444; text-align: left; font-size: 100%; }
178
  .advads-option-list > .label + div { display: block; float: left; padding: 10px; max-width: calc(100% - (10em + 40px)); }
179
+ .advads-option-list > .label + div.hidden { display: none; }
180
  .advads-option-list > hr { clear: both; float: none; display: block; }
181
  .advads-option-list div[style*="display: none"] + hr { display: none; }
182
 
196
 
197
  .advads-debug-output legend { text-decoration: underline; cursor: pointer; }
198
 
199
+ .advads-timestamp { padding-top: 5px; line-height: 1.76923076; white-space: nowrap; }
200
+ .advads-timestamp p { margin: 8px 0 6px; }
201
+ .advads-timestamp input { text-align: center; }
202
+ .advads-timestamp select { font-size: 12px; }
203
+ .advads-timestamp .advads-jj, .advads-timestamp .advads-timestamp .advads-hh, .advads-timestamp .advads-mn { width: 2em; }
204
+ .advads-timestamp .advads-aa, .advads-timestamp .advads-jj, .advads-timestamp .advads-hh, .advads-timestamp .advads-mn { padding: 6px 1px; font-size: 12px; line-height: 1.16666666; }
205
+ .advads-timestamp .advads-aa { width: 3.4em; }
206
 
207
  #advads-url,
208
  #advads-image-url,
240
  #advads-support-callout > p { color: #0073aa; }
241
  #advads-support-callout a { text-decoration: none; }
242
 
243
+ /* Ad option tables */
244
+ .advads-ad-parameters-option-list-min-width input { width: 5em; border: none; text-align: right; }
245
+ /* hide the delete button of the first row */
246
+ .advads-ad-parameters-option-list tr:first-of-type .advads-tr-remove { display: none; }
247
+ /* todo: create a general rule */
248
+ .advads-option-buttons .dashicons { cursor: pointer; opacity: .5; }
249
+ .advads-option-buttons .dashicons:hover { opacity: 1; }
250
+ .advads-tr-remove:hover { color: #a00; }
251
+
252
  /**
253
  AD GROUP LIST
254
  */
301
  .advads-placements-table-options { text-align: right; }
302
  .advads-placements-table-options input[type="number"] { width: 4.5em; }
303
  .advads-placements-table ol { margin: 0.5em 0; list-style-position: inside; }
304
+ th.advads-placement-sortable { cursor: pointer; }
305
+ th.advads-placement-sortable a { display: block; overflow: hidden; }
306
+ .advads-placement-sorting-indicator { display: inline-block; visibility: hidden; width: 10px; height: 4px; }
307
+ .advads-placement-sorting-indicator:before { content: "\f142"; font: normal 20px/1 dashicons; speak: none; display: inline-block; padding: 0; top: 0; left: -1px; color: #444; position: relative; vertical-align: middle; text-decoration: none !important; color: #444; }
308
+ th.advads-placement-sorted .advads-placement-sorting-indicator, th:hover span.advads-placement-sorting-indicator, th:focus span.advads-placement-sorting-indicator { visibility: visible; }
309
 
310
  /**
311
  GENERAL ELEMENTS
397
  #advads-tabs .nav-tab-active { background: #fff; border-bottom: 0; margin-top: 1px; }
398
  .advads-tab { display: none; padding: 5px 15px; overflow: hidden; background-color: #fff; border: 1px solid #ccc; border-top: none; }
399
  .advads-tab input[type="checkbox"] { margin-right: 8px; }
400
+ .advads-tab .form-table th, .advads-tab, .advads-tab .form-table td { padding-bottom: 30px; vertical-align: top; }
401
  .advads-tab.active { display: block; }
402
  .advads-license-activate-active { color: #46b450; }
403
  .advads-license-activate-error { color: #dc3232; }
462
  .advads-success-message { color: green !important; }
463
  .advads-hidden { display: none; }
464
  .advads-loader { display: block; width: 43px; height: 11px; background: url(../img/loader.gif) no-repeat; }
465
+ .advads-loader.hidden { display: none; }
466
 
467
  /* Image Ad */
468
  #advads_type_image_wp_media .media-sidebar .setting:not([data-setting="title"]):not([data-setting="alt"]),
581
 
582
  /* Set max-width for wide select elements */
583
  .advads-conditions-select-wrap { display: inline-block; max-width: 100%; }
584
+ .advads-conditions-select-wrap select { width: 100%; }
admin/assets/img/placements/buddyboss-icon.png ADDED
Binary file
admin/assets/js/admin.js CHANGED
@@ -1064,9 +1064,11 @@ window.Advanced_Ads_Admin = window.Advanced_Ads_Admin || {
1064
  jQuery( '#advads-parameters-shortcodes-warning' ).hide()
1065
  }
1066
  },
1067
- toggle_placements_visibility: function ( elm ) {
1068
  var advadsplacementformrow = jQuery( elm ).next( '.advads-placements-advanced-options' )
1069
- if ( advadsplacementformrow.is( ':visible' ) ) {
 
 
1070
  advadsplacementformrow.hide()
1071
  // clear last edited id
1072
  jQuery( '#advads-last-edited-placement' ).val( '' )
@@ -1080,6 +1082,58 @@ window.Advanced_Ads_Admin = window.Advanced_Ads_Admin || {
1080
  tr.data( 'touched', true )
1081
  }
1082
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1083
  }
1084
  }
1085
 
@@ -1548,3 +1602,14 @@ class AdvancedAdsAdNetwork {
1548
  class AdvancedAdsExternalAdUnit {
1549
 
1550
  }
 
 
 
 
 
 
 
 
 
 
 
1064
  jQuery( '#advads-parameters-shortcodes-warning' ).hide()
1065
  }
1066
  },
1067
+ toggle_placements_visibility: function ( elm, state ) {
1068
  var advadsplacementformrow = jQuery( elm ).next( '.advads-placements-advanced-options' )
1069
+
1070
+ var hide = ( typeof state !== 'undefined' ) ? ! state : advadsplacementformrow.is( ':visible' );;
1071
+ if ( hide ) {
1072
  advadsplacementformrow.hide()
1073
  // clear last edited id
1074
  jQuery( '#advads-last-edited-placement' ).val( '' )
1082
  tr.data( 'touched', true )
1083
  }
1084
  }
1085
+ },
1086
+
1087
+ /**
1088
+ * get a cookie value
1089
+ *
1090
+ * @param {str} name of the cookie
1091
+ */
1092
+ get_cookie: function (name) {
1093
+ var i, x, y, ADVcookies = document.cookie.split( ";" );
1094
+ for (i = 0; i < ADVcookies.length; i++)
1095
+ {
1096
+ x = ADVcookies[i].substr( 0, ADVcookies[i].indexOf( "=" ) );
1097
+ y = ADVcookies[i].substr( ADVcookies[i].indexOf( "=" ) + 1 );
1098
+ x = x.replace( /^\s+|\s+$/g, "" );
1099
+ if (x === name)
1100
+ {
1101
+ return unescape( y );
1102
+ }
1103
+ }
1104
+ },
1105
+
1106
+ /**
1107
+ * set a cookie value
1108
+ *
1109
+ * @param {str} name of the cookie
1110
+ * @param {str} value of the cookie
1111
+ * @param {int} exdays days until cookie expires
1112
+ * set 0 to expire cookie immidiatelly
1113
+ * set null to expire cookie in the current session
1114
+ */
1115
+ set_cookie: function (name, value, exdays, path, domain, secure) {
1116
+ // days in seconds
1117
+ var expiry = ( exdays == null ) ? null : exdays * 24 * 60 * 60;
1118
+ this.set_cookie_sec( name, value, expiry, path, domain, secure );
1119
+ },
1120
+ /**
1121
+ * set a cookie with expiry given in seconds
1122
+ *
1123
+ * @param {str} name of the cookie
1124
+ * @param {str} value of the cookie
1125
+ * @param {int} expiry seconds until cookie expires
1126
+ * set 0 to expire cookie immidiatelly
1127
+ * set null to expire cookie in the current session
1128
+ */
1129
+ set_cookie_sec: function (name, value, expiry, path, domain, secure) {
1130
+ var exdate = new Date();
1131
+ exdate.setSeconds( exdate.getSeconds() + parseInt( expiry ) );
1132
+ document.cookie = name + "=" + escape( value ) +
1133
+ ((expiry == null) ? "" : "; expires=" + exdate.toUTCString()) +
1134
+ ((path == null) ? "; path=/" : "; path=" + path) +
1135
+ ((domain == null) ? "" : "; domain=" + domain) +
1136
+ ((secure == null) ? "" : "; secure");
1137
  }
1138
  }
1139
 
1602
  class AdvancedAdsExternalAdUnit {
1603
 
1604
  }
1605
+
1606
+ /**
1607
+ * todo: this looks like something we could use in general, but where to put it?
1608
+ */
1609
+ jQuery( document ).ready( function () {
1610
+ // delete an existing row by removing the parent tr tag
1611
+ // todo: this could be moved to a general file
1612
+ jQuery( document ).on( 'click', '.advads-tr-remove', function(){
1613
+ jQuery( this ).closest( 'tr' ).remove();
1614
+ });
1615
+ });
admin/class-advanced-ads-admin.php CHANGED
@@ -41,6 +41,13 @@ class Advanced_Ads_Admin {
41
  */
42
  protected $plugin_slug = '';
43
 
 
 
 
 
 
 
 
44
  /**
45
  * Initialize the plugin by loading admin scripts & styles and adding a
46
  * settings page and menu.
@@ -733,4 +740,34 @@ class Advanced_Ads_Admin {
733
 
734
  include ADVADS_BASE_PATH . 'admin/views/notices/starter-setup-success.php';
735
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
736
  }
41
  */
42
  protected $plugin_slug = '';
43
 
44
+ /**
45
+ * Admin settings.
46
+ *
47
+ * @var array
48
+ */
49
+ protected static $admin_settings = null;
50
+
51
  /**
52
  * Initialize the plugin by loading admin scripts & styles and adding a
53
  * settings page and menu.
740
 
741
  include ADVADS_BASE_PATH . 'admin/views/notices/starter-setup-success.php';
742
  }
743
+
744
+ /**
745
+ * Get admin settings of the current user.
746
+ *
747
+ * @return array
748
+ */
749
+ public static function get_admin_settings() {
750
+ if ( null === self::$admin_settings ) {
751
+ self::$admin_settings = get_user_meta( get_current_user_id(), 'advanced-ads-admin-settings', true );
752
+
753
+ if ( ! is_array( self::$admin_settings ) ) {
754
+ self::$admin_settings = array();
755
+ }
756
+ }
757
+ return self::$admin_settings;
758
+ }
759
+
760
+ /**
761
+ * Update admin settings of the current user.
762
+ *
763
+ * @param array $new_settings New admin settings.
764
+ */
765
+ public static function update_admin_setttings( $new_settings ) {
766
+ $current = self::get_admin_settings();
767
+
768
+ if ( $current !== $new_settings ) {
769
+ update_user_meta( get_current_user_id(), 'advanced-ads-admin-settings', $new_settings );
770
+ self::$admin_settings = $new_settings;
771
+ }
772
+ }
773
  }
admin/includes/ad-health-notices.php CHANGED
@@ -211,12 +211,12 @@ $advanced_ads_ad_health_notices = apply_filters(
211
  'type' => 'notice',
212
  'hide' => false,
213
  ),
214
- // BuddyPress installed.
215
  'buddypress_no_pro' => array(
216
  'text' => sprintf(
217
  // translators: %1$s is a plugin name, %2$s is the opening a tag and %3$s the closing one.
218
  __( 'Learn how to integrate %1$s with Advanced Ads %2$shere%3$s.', 'advanced-ads' ),
219
- '<strong>BuddyPress</strong>',
220
  '<a href="' . ADVADS_URL . 'ads-on-buddypress-pages/#utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-buddypress" target="_blank">',
221
  '</a>'
222
  ),
211
  'type' => 'notice',
212
  'hide' => false,
213
  ),
214
+ // BuddyPress or BuddyBoss installed.
215
  'buddypress_no_pro' => array(
216
  'text' => sprintf(
217
  // translators: %1$s is a plugin name, %2$s is the opening a tag and %3$s the closing one.
218
  __( 'Learn how to integrate %1$s with Advanced Ads %2$shere%3$s.', 'advanced-ads' ),
219
+ '<strong>BuddyPress & BuddyBoss</strong>',
220
  '<a href="' . ADVADS_URL . 'ads-on-buddypress-pages/#utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-buddypress" target="_blank">',
221
  '</a>'
222
  ),
admin/includes/class-admin-upgrades.php CHANGED
@@ -114,7 +114,7 @@ class Advanced_Ads_Admin_Upgrades {
114
  * AMP options for AdSense ads in the Ad Parameters on the ad edit page.
115
  */
116
  public function adsense_type_amp_options() {
117
- if ( ! defined( 'AAR_VERSION ' ) && Advanced_Ads_Checks::active_amp_plugin() ) {
118
  include ADVADS_BASE_PATH . 'admin/views/upgrades/adsense-amp.php';
119
  }
120
  }
114
  * AMP options for AdSense ads in the Ad Parameters on the ad edit page.
115
  */
116
  public function adsense_type_amp_options() {
117
+ if ( ! defined( 'AAR_VERSION' ) && Advanced_Ads_Checks::active_amp_plugin() ) {
118
  include ADVADS_BASE_PATH . 'admin/views/upgrades/adsense-amp.php';
119
  }
120
  }
admin/includes/class-licenses.php CHANGED
@@ -568,9 +568,9 @@ class Advanced_Ads_Admin_Licenses {
568
  /**
569
  * Add custom messages to plugin updater
570
  *
571
- * @param string $reply
572
- * @param string $package
573
- * @param string $updater
574
  *
575
  * @return string
576
  *
@@ -581,8 +581,11 @@ class Advanced_Ads_Admin_Licenses {
581
  if ( isset( $updater->skin->plugin ) ) {
582
  $plugin_file = $updater->skin->plugin;
583
  } elseif ( isset( $updater->skin->plugin_info['Name'] ) ) {
584
- $add_on = $this->get_installed_add_on_by_name( $updater->skin->plugin_info['Name'] );
585
- $plugin_file = plugin_basename( $add_on['path'] );
 
 
 
586
  }
587
 
588
  if ( isset( $plugin_file ) && $plugin_file ) {
568
  /**
569
  * Add custom messages to plugin updater
570
  *
571
+ * @param bool $reply Whether to bail without returning the package. Default false.
572
+ * @param string $package The package file name.
573
+ * @param string $updater The WP_Upgrader instance.
574
  *
575
  * @return string
576
  *
581
  if ( isset( $updater->skin->plugin ) ) {
582
  $plugin_file = $updater->skin->plugin;
583
  } elseif ( isset( $updater->skin->plugin_info['Name'] ) ) {
584
+ $add_on = $this->get_installed_add_on_by_name( $updater->skin->plugin_info['Name'] );
585
+ // $add_on['path'] should always be set with out official plugins but might be missing for some local and custom made.
586
+ if ( isset( $add_on['path'] ) ) {
587
+ $plugin_file = plugin_basename( $add_on['path'] );
588
+ }
589
  }
590
 
591
  if ( isset( $plugin_file ) && $plugin_file ) {
admin/includes/class-list-filters.php CHANGED
@@ -521,7 +521,7 @@ class Advanced_Ads_Ad_List_Filters {
521
  foreach ( $the_list as $post ) {
522
  if ( isset( $this->all_ads_options[ $post->ID ] ) ) {
523
  $option = $this->all_ads_options[ $post->ID ];
524
- if ( $option['expiry_date'] ) {
525
  $new_posts[] = $post;
526
  }
527
  }
521
  foreach ( $the_list as $post ) {
522
  if ( isset( $this->all_ads_options[ $post->ID ] ) ) {
523
  $option = $this->all_ads_options[ $post->ID ];
524
+ if ( ! empty( $option['expiry_date'] ) ) {
525
  $new_posts[] = $post;
526
  }
527
  }
admin/includes/class-menu.php CHANGED
@@ -245,6 +245,7 @@ class Advanced_Ads_Admin_Menu {
245
  $placements = Advanced_Ads::get_ad_placements_array(); // -TODO use model
246
  // load ads and groups for select field.
247
  $items = Advanced_Ads_Placements::items_for_select();
 
248
 
249
  // display view.
250
  include ADVADS_BASE_PATH . 'admin/views/placements.php';
@@ -337,4 +338,55 @@ class Advanced_Ads_Admin_Menu {
337
  }
338
  }
339
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  }
245
  $placements = Advanced_Ads::get_ad_placements_array(); // -TODO use model
246
  // load ads and groups for select field.
247
  $items = Advanced_Ads_Placements::items_for_select();
248
+ $orderby = $this->get_field_to_order_placement();
249
 
250
  // display view.
251
  include ADVADS_BASE_PATH . 'admin/views/placements.php';
338
  }
339
  }
340
 
341
+ /**
342
+ * Get the field to order placements.
343
+ *
344
+ * @return string
345
+ */
346
+ private function get_field_to_order_placement() {
347
+ $admin_settings = Advanced_Ads_Admin::get_admin_settings();
348
+
349
+ $default = isset( $admin_settings['placement-orderby'] ) ? $admin_settings['placement-orderby'] : 'type';
350
+ $current = isset( $_GET['orderby'] ) ? $_GET['orderby'] : $default; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
351
+
352
+ if ( ! in_array( $current, array( 'name', 'type' ) ) ) {
353
+ $current = 'type';
354
+ }
355
+
356
+ // Save default field, if it was changed.
357
+ $admin_settings['placement-orderby'] = $current;
358
+ Advanced_Ads_Admin::update_admin_setttings( $admin_settings );
359
+
360
+ return $current;
361
+ }
362
+
363
+ /**
364
+ * Get the URL where the user is redirected after activating the frontend picker for a "Content" placement.
365
+ *
366
+ * @since string URL.
367
+ */
368
+ private function get_url_for_content_placement_picker() {
369
+ $location = false;
370
+
371
+ if ( 'posts' === get_option( 'show_on_front' ) ) {
372
+ $recent_posts = wp_get_recent_posts(
373
+ array(
374
+ 'numberposts' => 1,
375
+ 'post_type' => 'post',
376
+ 'post_status' => 'publish',
377
+ ),
378
+ 'OBJECT'
379
+ );
380
+
381
+ if ( $recent_posts ) {
382
+ $location = get_permalink( $recent_posts[0] );
383
+ }
384
+ }
385
+
386
+ if ( ! $location ) {
387
+ $location = home_url();
388
+ }
389
+ return $location;
390
+ }
391
+
392
  }
admin/includes/class-overview-widgets.php CHANGED
@@ -490,14 +490,14 @@ endif;
490
  ?>
491
  </li><?php endif; /* bbPress */ ?>
492
  <?php
493
- if ( class_exists( 'BuddyPress', false ) ) :
494
  ?>
495
  <li>
496
  <?php
497
  printf(
498
  // translators: %s is the name of another plugin.
499
  wp_kses( __( 'integrates with <strong>%s</strong>', 'advanced-ads' ), array( 'strong' => array() ) ),
500
- 'BuddyPress'
501
  );
502
  ?>
503
  </li><?php endif; /* BuddyPress */ ?>
490
  ?>
491
  </li><?php endif; /* bbPress */ ?>
492
  <?php
493
+ if ( class_exists( 'BuddyPress', false ) ) : // BuddyPress or BuddyBoss
494
  ?>
495
  <li>
496
  <?php
497
  printf(
498
  // translators: %s is the name of another plugin.
499
  wp_kses( __( 'integrates with <strong>%s</strong>', 'advanced-ads' ), array( 'strong' => array() ) ),
500
+ defined( 'BP_PLATFORM_VERSION' ) ? 'BuddyBoss' : 'BuddyPress'
501
  );
502
  ?>
503
  </li><?php endif; /* BuddyPress */ ?>
admin/views/ad-parameters-metabox.php CHANGED
@@ -26,10 +26,18 @@ do_action( 'advanced-ads-ad-params-before', $ad, $types );
26
 
27
  $types_without_size = array( 'dummy' );
28
  $types_without_size = apply_filters( 'advanced-ads-types-without-size', $types_without_size );
 
29
  if ( ! in_array( $ad->type, $types_without_size ) ) {
30
  include ADVADS_BASE_PATH . 'admin/views/ad-parameters-size.php';
31
  };
32
  ?>
33
  </div>
34
  <?php
 
 
 
 
 
 
 
35
  do_action( 'advanced-ads-ad-params-after', $ad, $types );
26
 
27
  $types_without_size = array( 'dummy' );
28
  $types_without_size = apply_filters( 'advanced-ads-types-without-size', $types_without_size );
29
+ // todo: manage which ad types have a size in the ad type definition.
30
  if ( ! in_array( $ad->type, $types_without_size ) ) {
31
  include ADVADS_BASE_PATH . 'admin/views/ad-parameters-size.php';
32
  };
33
  ?>
34
  </div>
35
  <?php
36
+
37
+ // extend the parameters form by ad type
38
+ if ( isset( $types[ $ad->type ] ) ) {
39
+ do_action( "advanced-ads-ad-params-after-{$ad->type}", $ad, $types );
40
+ }
41
+
42
+ // extend the parameter form
43
  do_action( 'advanced-ads-ad-params-after', $ad, $types );
admin/views/ad-submitbox-meta.php CHANGED
@@ -12,41 +12,39 @@ $timezone_name = Advanced_Ads_Admin::timezone_get_name( Advanced_Ads_Admin::get_
12
  <br/>
13
  <div class="inner"<?php echo ( ! $enabled ) ? ' style="display:none;"' : ''; ?>>
14
  <?php
15
- $month = '<label><span class="screen-reader-text">' . __( 'Month', 'advanced-ads' ) . '</span><select id="advads-exp-mm" name="advanced_ad[expiry_date][month]"' . ">\n";
16
  for ( $i = 1; $i < 13; $i = ++$i ) {
17
- $month_num = zeroise( $i, 2 );
18
- $month .= "\t\t\t" . '<option value="' . $month_num . '" ' . selected( $curr_month, $month_num, false ) . '>';
19
- $month .= sprintf(
20
  // translators: %1$s is the month number, %2$s is the month shortname.
21
  _x( '%1$s-%2$s', '1: month number (01, 02, etc.), 2: month abbreviation', 'advanced-ads' ),
22
  $month_num,
23
  $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) )
24
  ) . "</option>\n";
25
  }
26
- $month .= '</select></label>';
27
 
28
- $day = '<label><span class="screen-reader-text">' . __( 'Day', 'advanced-ads' ) . '</span><input type="text" id="advads-exp-jj" name="advanced_ad[expiry_date][day]" value="' . $curr_day . '" size="2" maxlength="2" autocomplete="off" /></label>';
29
- $year = '<label><span class="screen-reader-text">' . __( 'Year', 'advanced-ads' ) . '</span><input type="text" id="advads-exp-aa" name="advanced_ad[expiry_date][year]" value="' . $curr_year . '" size="4" maxlength="4" autocomplete="off" /></label>';
30
- $hour = '<label><span class="screen-reader-text">' . __( 'Hour', 'advanced-ads' ) . '</span><input type="text" id="advads-exp-hh" name="advanced_ad[expiry_date][hour]" value="' . $curr_hour . '" size="2" maxlength="2" autocomplete="off" /></label>';
31
- $minute = '<label><span class="screen-reader-text">' . __( 'Minute', 'advanced-ads' ) . '</span><input type="text" id="advads-exp-mn" name="advanced_ad[expiry_date][minute]" value="' . $curr_minute . '" size="2" maxlength="2" autocomplete="off" /></label>';
32
 
33
  ?>
34
- <fieldset id="advads-exp-timestampdiv">
35
- <div class="timestamp-wrap">
36
  <?php
37
  // phpcs:disable
38
  printf(
39
  // translators: %1$s month, %2$s day, %3$s year, %4$s hour, %5$s minute.
40
  _x( '%1$s %2$s, %3$s @ %4$s %5$s', 'order of expiry date fields 1: month, 2: day, 3: year, 4: hour, 5: minute', 'advanced-ads' ),
41
- $month,
42
- $day,
43
- $year,
44
- $hour,
45
- $minute
46
  );
47
  // phpcs:enable
48
  ?>
49
- </div>
50
  </fieldset>
51
  (<?php echo esc_html( $timezone_name ); ?>)
52
  </div>
12
  <br/>
13
  <div class="inner"<?php echo ( ! $enabled ) ? ' style="display:none;"' : ''; ?>>
14
  <?php
15
+ $month_field = '<label><span class="screen-reader-text">' . __( 'Month', 'advanced-ads' ) . '</span><select class="advads-mm" name="advanced_ad[expiry_date][month]"' . ">\n";
16
  for ( $i = 1; $i < 13; $i = ++$i ) {
17
+ $month_num = zeroise( $i, 2 );
18
+ $month_field .= "\t\t\t" . '<option value="' . $month_num . '" ' . selected( $curr_month, $month_num, false ) . '>';
19
+ $month_field .= sprintf(
20
  // translators: %1$s is the month number, %2$s is the month shortname.
21
  _x( '%1$s-%2$s', '1: month number (01, 02, etc.), 2: month abbreviation', 'advanced-ads' ),
22
  $month_num,
23
  $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) )
24
  ) . "</option>\n";
25
  }
26
+ $month_field .= '</select></label>';
27
 
28
+ $day_field = '<label><span class="screen-reader-text">' . __( 'Day', 'advanced-ads' ) . '</span><input type="text" class="advads-jj" name="advanced_ad[expiry_date][day]" value="' . $curr_day . '" size="2" maxlength="2" autocomplete="off" /></label>';
29
+ $year_field = '<label><span class="screen-reader-text">' . __( 'Year', 'advanced-ads' ) . '</span><input type="text" class="advads-aa" name="advanced_ad[expiry_date][year]" value="' . $curr_year . '" size="4" maxlength="4" autocomplete="off" /></label>';
30
+ $hour_field = '<label><span class="screen-reader-text">' . __( 'Hour', 'advanced-ads' ) . '</span><input type="text" class="advads-hh" name="advanced_ad[expiry_date][hour]" value="' . $curr_hour . '" size="2" maxlength="2" autocomplete="off" /></label>';
31
+ $minute_field = '<label><span class="screen-reader-text">' . __( 'Minute', 'advanced-ads' ) . '</span><input type="text" class="advads-mn" name="advanced_ad[expiry_date][minute]" value="' . $curr_minute . '" size="2" maxlength="2" autocomplete="off" /></label>';
32
 
33
  ?>
34
+ <fieldset class="advads-timestamp">
 
35
  <?php
36
  // phpcs:disable
37
  printf(
38
  // translators: %1$s month, %2$s day, %3$s year, %4$s hour, %5$s minute.
39
  _x( '%1$s %2$s, %3$s @ %4$s %5$s', 'order of expiry date fields 1: month, 2: day, 3: year, 4: hour, 5: minute', 'advanced-ads' ),
40
+ $month_field,
41
+ $day_field,
42
+ $year_field,
43
+ $hour_field,
44
+ $minute_field
45
  );
46
  // phpcs:enable
47
  ?>
 
48
  </fieldset>
49
  (<?php echo esc_html( $timezone_name ); ?>)
50
  </div>
admin/views/frontend-picker-script.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script>
2
+ jQuery( document ).ready( function(){
3
+ // set element from frontend into placement input field
4
+ if( localStorage.getItem( 'advads_frontend_element' )){
5
+ var placement = localStorage.getItem( 'advads_frontend_picker' );
6
+ var id = 'advads-frontend-element-' + placement;
7
+ jQuery( '[id="' + id + '"]' ).find( '.advads-frontend-element' ).val( localStorage.getItem( 'advads_frontend_element' ) );
8
+
9
+ var action = localStorage.getItem( 'advads_frontend_action' );
10
+ if (typeof(action) !== 'undefined'){
11
+ var show_all_link = jQuery( 'a[data-placement="' + placement + '"]');
12
+ Advanced_Ads_Admin.toggle_placements_visibility( show_all_link, true );
13
+
14
+ // Auto-save the placement after selecting an element in the frontend.
15
+ var param = {
16
+ action: 'advads-update-frontend-element',
17
+ nonce: advadsglobal.ajax_nonce,
18
+ }
19
+ var $form = jQuery( '#advanced-ads-placements-form' );
20
+ var query = $form.find( '[id="single-placement-' + placement + '"]' ).find( 'input, select' )
21
+ .serialize() + '&' + jQuery.param( param );
22
+
23
+ $form.find( ':submit' ).attr( 'disabled', true );
24
+ jQuery.post( ajaxurl, query ).always( function() {
25
+ $form.find( ':submit' ).attr( 'disabled', false );
26
+ } );
27
+ }
28
+ localStorage.removeItem( 'advads_frontend_action' );
29
+ localStorage.removeItem( 'advads_frontend_element' );
30
+ localStorage.removeItem( 'advads_frontend_picker' );
31
+ localStorage.removeItem( 'advads_prev_url' );
32
+ localStorage.removeItem( 'advads_frontend_pathtype' );
33
+ localStorage.removeItem( 'advads_frontend_boundary' );
34
+ localStorage.removeItem( 'advads_frontend_blog_id' );
35
+ localStorage.removeItem( 'advads_frontend_starttime' );
36
+ window.Advanced_Ads_Admin.set_cookie( 'advads_frontend_picker', '', -1 );
37
+ }
38
+ jQuery('.advads-activate-frontend-picker').click(function( e ){
39
+ localStorage.setItem( 'advads_frontend_picker', jQuery( this ).data('placementid') );
40
+ localStorage.setItem( 'advads_frontend_action', jQuery( this ).data('action') );
41
+ localStorage.setItem( 'advads_prev_url', window.location );
42
+
43
+ localStorage.setItem( 'advads_frontend_pathtype', jQuery( this ).data('pathtype') );
44
+ localStorage.setItem( 'advads_frontend_boundary', jQuery( this ).data('boundary') );
45
+ localStorage.setItem( 'advads_frontend_blog_id', <?php echo get_current_blog_id(); ?> );
46
+ localStorage.setItem( 'advads_frontend_starttime', (new Date).getTime() );
47
+ window.Advanced_Ads_Admin.set_cookie( 'advads_frontend_picker', jQuery( this ).data('placementid'), null );
48
+
49
+ if ( jQuery( this ).data( 'boundary' ) ) {
50
+ /**
51
+ * The boundary is set for the "Content" placement.
52
+ * Perhaps ads through `the_content` are disabled on non-singular pages, so use a singular one.
53
+ */
54
+ window.location = "<?php echo $this->get_url_for_content_placement_picker(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>";
55
+ } else {
56
+ window.location = "<?php echo home_url(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>";
57
+ }
58
+ });
59
+ // allow to deactivate frontend picker
60
+ if ( localStorage.getItem( 'advads_frontend_picker' ) ) {
61
+ var id = 'advads-frontend-element-' + localStorage.getItem( 'advads_frontend_picker' );
62
+ jQuery( '[id="' + id + '"]' ).find( '.advads-deactivate-frontend-picker' ).show();
63
+ }
64
+ jQuery( '.advads-deactivate-frontend-picker' ).click( function( e ) {
65
+ localStorage.removeItem( 'advads_frontend_action' );
66
+ localStorage.removeItem( 'advads_frontend_element' );
67
+ localStorage.removeItem( 'advads_frontend_picker' );
68
+ localStorage.removeItem( 'advads_prev_url' );
69
+ localStorage.removeItem( 'advads_frontend_pathtype' );
70
+ localStorage.removeItem( 'advads_frontend_boundary' );
71
+ localStorage.removeItem( 'advads_frontend_blog_id' );
72
+ localStorage.removeItem( 'advads_frontend_starttime' );
73
+ window.Advanced_Ads_Admin.set_cookie( 'advads_frontend_picker', '', -1 );
74
+ jQuery('.advads-deactivate-frontend-picker').hide();
75
+ });
76
+ });
77
+ </script>
admin/views/placements-content-index.php CHANGED
@@ -36,11 +36,16 @@
36
  ><?php echo esc_html( $_tag ); ?></option>
37
  <?php endforeach; ?>
38
  </select>
39
- <input name="advads[placements][<?php echo esc_attr( $_placement_slug ); ?>][options][xpath]"
40
- class="advads-placements-content-custom-xpath<?php echo 'custom' !== $option_tag ? ' hidden' : ''; ?>"
41
- type="text"
42
- value="<?php echo esc_html( $option_xpath ); ?>"
43
- placeholder="<?php esc_html_e( 'use xpath, e.g. `p[not(parent::blockquote)]`', 'advanced-ads' ); ?>"/>
 
 
 
 
 
44
 
45
  <p><label><input type="checkbox" name="advads[placements][<?php echo esc_attr( $_placement_slug ); ?>][options][start_from_bottom]" value="1"
46
  <?php
36
  ><?php echo esc_html( $_tag ); ?></option>
37
  <?php endforeach; ?>
38
  </select>
39
+
40
+ <div id="advads-frontend-element-<?php echo esc_attr( $_placement_slug ); ?>" class="advads-placements-content-custom-xpath<?php echo 'custom' !== $option_tag ? ' hidden' : ''; ?>">
41
+ <input name="advads[placements][<?php echo esc_attr( $_placement_slug ); ?>][options][xpath]"
42
+ class="advads-frontend-element "
43
+ type="text"
44
+ value="<?php echo esc_html( $option_xpath ); ?>"
45
+ placeholder="<?php esc_html_e( 'use xpath, e.g. `p[not(parent::blockquote)]`', 'advanced-ads' ); ?>"/>
46
+ <button style="display:none; color: red;" type="button" class="advads-deactivate-frontend-picker button "><?php echo esc_html_x( 'stop selection', 'frontend picker', 'advanced-ads' ); ?></button>
47
+ <button type="button" class="advads-activate-frontend-picker button " data-placementid="<?php echo esc_attr( $_placement_slug ); ?>" data-pathtype="xpath" data-boundary="true"><?php esc_html_e( 'select position', 'advanced-ads' ); ?></button>
48
+ </div>
49
 
50
  <p><label><input type="checkbox" name="advads[placements][<?php echo esc_attr( $_placement_slug ); ?>][options][start_from_bottom]" value="1"
51
  <?php
admin/views/placements-item.php CHANGED
@@ -4,6 +4,8 @@
4
  *
5
  * @var string $_placement_slug slug of the current placement.
6
  * @var array $_placement information of the current placement.
 
 
7
  */
8
  ?>
9
  <select id="advads-placements-item-<?php echo esc_attr( $_placement_slug ); ?>" name="advads[placements][<?php echo esc_attr( $_placement_slug ); ?>][item]">
@@ -22,11 +24,20 @@
22
  <?php endif; ?>
23
  <?php if ( isset( $items['ads'] ) ) : ?>
24
  <optgroup label="<?php esc_html_e( 'Ads', 'advanced-ads' ); ?>">
25
- <?php foreach ( $items['ads'] as $_item_id => $_item_title ) : ?>
 
 
26
  <option value="<?php echo esc_attr( $_item_id ); ?>"
27
  <?php
28
- if ( isset( $_placement['item'] ) ) {
29
- selected( $_item_id, $_placement['item'] ); }
 
 
 
 
 
 
 
30
  ?>
31
  ><?php echo esc_html( $_item_title ); ?></option>
32
  <?php endforeach; ?>
@@ -35,20 +46,38 @@
35
  </select>
36
  <?php
37
  // link to item.
38
- if ( isset( $_placement['item'] ) ) :
39
- $currently_linked_item = explode( '_', $_placement['item'] );
40
- $link_to_item = false;
41
- switch ( $currently_linked_item[0] ) :
42
  case 'ad':
43
- $link_to_item = get_edit_post_link( $currently_linked_item[1] );
 
 
 
 
 
 
44
  break;
45
  case 'group':
46
- $link_to_item = admin_url( 'admin.php?page=advanced-ads-groups&advads-last-edited-group=' . $currently_linked_item[1] );
47
  break;
48
  endswitch;
49
- if ( $link_to_item ) :
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  ?>
51
- <a href="<?php echo esc_url( $link_to_item ); ?>"><span class="dashicons dashicons-external"></span></span></a>
52
  <?php
53
- endif;
54
  endif;
4
  *
5
  * @var string $_placement_slug slug of the current placement.
6
  * @var array $_placement information of the current placement.
7
+ * @var string|null $placement_item_type type of the item currently selected for the placement
8
+ * @var string|null $placement_item_id ID of the item currently selected for the placement
9
  */
10
  ?>
11
  <select id="advads-placements-item-<?php echo esc_attr( $_placement_slug ); ?>" name="advads[placements][<?php echo esc_attr( $_placement_slug ); ?>][item]">
24
  <?php endif; ?>
25
  <?php if ( isset( $items['ads'] ) ) : ?>
26
  <optgroup label="<?php esc_html_e( 'Ads', 'advanced-ads' ); ?>">
27
+ <?php
28
+ foreach ( $items['ads'] as $_item_id => $_item_title ) :
29
+ ?>
30
  <option value="<?php echo esc_attr( $_item_id ); ?>"
31
  <?php
32
+ if ( $placement_item_id ) {
33
+ /**
34
+ * Select the translated version of an ad if set up with WPML.
35
+ *
36
+ * @source https://wpml.org/wpml-hook/wpml_object_id/
37
+ */
38
+ $translated_item_id = 'ad_' . apply_filters( 'wpml_object_id', $placement_item_id, 'advanced_ads', true );
39
+
40
+ selected( $_item_id, $translated_item_id ); }
41
  ?>
42
  ><?php echo esc_html( $_item_title ); ?></option>
43
  <?php endforeach; ?>
46
  </select>
47
  <?php
48
  // link to item.
49
+ if ( $placement_item_type ) :
50
+ $link_to_item = false;
51
+ switch ( $placement_item_type ) :
 
52
  case 'ad':
53
+ /**
54
+ * Deliver the translated version of an ad if set up with WPML.
55
+ *
56
+ * @source https://wpml.org/wpml-hook/wpml_object_id/
57
+ */
58
+ $placement_item_id = apply_filters( 'wpml_object_id', $placement_item_id, 'advanced_ads' );
59
+ $link_to_item = get_edit_post_link( $placement_item_id );
60
  break;
61
  case 'group':
62
+ $link_to_item = admin_url( 'admin.php?page=advanced-ads-groups&advads-last-edited-group=' . $placement_item_id );
63
  break;
64
  endswitch;
65
+ if ( $link_to_item ) {
66
+ ?>
67
+ <a href="<?php echo esc_url( $link_to_item ); ?>"><span class="dashicons dashicons-external"></span></span></a>
68
+ <?php
69
+ } elseif ( 'ad' === $placement_item_type && defined( 'ICL_LANGUAGE_NAME' ) ) {
70
+ // translation missing notice
71
+ ?>
72
+ <p>
73
+ <?php
74
+ printf(
75
+ // translators: %s is the name of a language in English
76
+ esc_html__( 'The ad is not translated into %s', 'advanced-ads' ),
77
+ esc_html( ICL_LANGUAGE_NAME )
78
+ );
79
  ?>
80
+ </p>
81
  <?php
82
+ }
83
  endif;
admin/views/placements.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * The view for the placements page
4
  *
@@ -52,20 +53,61 @@ if ( isset( $placements ) && is_array( $placements ) && count( $placements ) ) :
52
  ?>
53
  <h2><?php esc_html_e( 'Placements', 'advanced-ads' ); ?></h2>
54
  <form method="POST" action="" id="advanced-ads-placements-form">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  <table class="widefat advads-placements-table striped">
56
  <thead>
57
  <tr>
58
- <th><?php esc_html_e( 'Type', 'advanced-ads' ); ?></th>
59
- <th><?php esc_html_e( 'Name', 'advanced-ads' ); ?></th>
60
- <th><?php esc_html_e( 'Options', 'advanced-ads' ); ?></th>
61
- <?php do_action( 'advanced-ads-placements-list-column-header' ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  <th></th>
63
  </tr>
64
  </thead>
65
  <tbody>
66
  <?php
67
- // order by slug.
68
- ksort( $placements );
 
69
  foreach ( $placements as $_placement_slug => $_placement ) :
70
  $type_missing = false;
71
  if ( isset( $_placement['type'] ) && ! isset( $placement_types[ $_placement['type'] ] ) ) {
@@ -136,6 +178,12 @@ if ( isset( $placements ) && is_array( $placements ) && count( $placements ) ) :
136
 
137
  <?php
138
  ob_start();
 
 
 
 
 
 
139
  include ADVADS_BASE_PATH . 'admin/views/placements-item.php';
140
  $item_option_content = ob_get_clean();
141
 
@@ -150,6 +198,12 @@ if ( isset( $placements ) && is_array( $placements ) && count( $placements ) ) :
150
  case 'post_content':
151
  $option_index = isset( $_placement['options']['index'] ) ? absint( max( 1, (int) $_placement['options']['index'] ) ) : 1;
152
  $option_tag = isset( $_placement['options']['tag'] ) ? $_placement['options']['tag'] : 'p';
 
 
 
 
 
 
153
  $option_xpath = isset( $_placement['options']['xpath'] ) ? stripslashes( $_placement['options']['xpath'] ) : '';
154
  $positions = array(
155
  'after' => __( 'after', 'advanced-ads' ),
@@ -314,6 +368,7 @@ endif;
314
  <input type="hidden" name="advads-last-edited-placement" id="advads-last-edited-placement" value="0"/>
315
  </form>
316
  <?php
 
317
  do_action( 'advanced-ads-placements-list-after', $placements );
318
  endif;
319
 
1
  <?php
2
+ defined( 'ABSPATH' ) || exit;
3
  /**
4
  * The view for the placements page
5
  *
53
  ?>
54
  <h2><?php esc_html_e( 'Placements', 'advanced-ads' ); ?></h2>
55
  <form method="POST" action="" id="advanced-ads-placements-form">
56
+
57
+ <?php
58
+ $columns = array(
59
+ array(
60
+ 'key' => 'type',
61
+ 'display_name' => esc_html__( 'Type', 'advanced-ads' ),
62
+ 'sortable' => true,
63
+ ),
64
+ array(
65
+ 'key' => 'name',
66
+ 'display_name' => esc_html__( 'Name', 'advanced-ads' ),
67
+ 'sortable' => true,
68
+ ),
69
+ array(
70
+ 'key' => 'options',
71
+ 'display_name' => esc_html__( 'Options', 'advanced-ads' ),
72
+ ),
73
+ );
74
+ ?>
75
  <table class="widefat advads-placements-table striped">
76
  <thead>
77
  <tr>
78
+ <?php
79
+ foreach ( $columns as $column ) {
80
+ $class = '';
81
+ $column_display_name = $column['display_name'];
82
+
83
+ if ( ! empty( $column['sortable'] ) ) {
84
+ $column_display_name = $column_display_name
85
+ . '<span class="advads-placement-sorting-indicator"></span>';
86
+
87
+ if ( $orderby === $column['key'] ) {
88
+ $class = 'class="advads-placement-sorted"';
89
+ } else {
90
+ $class = 'class="advads-placement-sortable"';
91
+
92
+ $column_display_name = '<a href="' . esc_url( add_query_arg( array( 'orderby' => $column['key'] ) ) ) . '">'
93
+ . $column_display_name
94
+ . '</a>';
95
+ }
96
+ }
97
+
98
+ echo "<th $class>$column_display_name</th>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
99
+ }
100
+
101
+ do_action( 'advanced-ads-placements-list-column-header' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
102
+ ?>
103
  <th></th>
104
  </tr>
105
  </thead>
106
  <tbody>
107
  <?php
108
+ // Sort placements.
109
+ $placements = Advanced_Ads_Placements::sort( $placements, $orderby );
110
+
111
  foreach ( $placements as $_placement_slug => $_placement ) :
112
  $type_missing = false;
113
  if ( isset( $_placement['type'] ) && ! isset( $placement_types[ $_placement['type'] ] ) ) {
178
 
179
  <?php
180
  ob_start();
181
+
182
+ // get the currently selected item
183
+ $placement_item_array = explode( '_', $_placement['item'] );
184
+ $placement_item_type = is_array( $placement_item_array ) && isset( $placement_item_array[0] ) ? $placement_item_array[0] : null;
185
+ $placement_item_id = is_array( $placement_item_array ) && isset( $placement_item_array[1] ) ? $placement_item_array[1] : null;
186
+
187
  include ADVADS_BASE_PATH . 'admin/views/placements-item.php';
188
  $item_option_content = ob_get_clean();
189
 
198
  case 'post_content':
199
  $option_index = isset( $_placement['options']['index'] ) ? absint( max( 1, (int) $_placement['options']['index'] ) ) : 1;
200
  $option_tag = isset( $_placement['options']['tag'] ) ? $_placement['options']['tag'] : 'p';
201
+
202
+ // Automatically select the 'custom' option.
203
+ if ( ! empty( $_COOKIE['advads_frontend_picker'] ) ) {
204
+ $option_tag = ( $_COOKIE['advads_frontend_picker'] === $_placement_slug ) ? 'custom' : $option_tag;
205
+ }
206
+
207
  $option_xpath = isset( $_placement['options']['xpath'] ) ? stripslashes( $_placement['options']['xpath'] ) : '';
208
  $positions = array(
209
  'after' => __( 'after', 'advanced-ads' ),
368
  <input type="hidden" name="advads-last-edited-placement" id="advads-last-edited-placement" value="0"/>
369
  </form>
370
  <?php
371
+ include ADVADS_BASE_PATH . 'admin/views/frontend-picker-script.php';
372
  do_action( 'advanced-ads-placements-list-after', $placements );
373
  endif;
374
 
admin/views/settings/license/section.php CHANGED
@@ -23,7 +23,7 @@ printf(
23
  ),
24
  )
25
  ),
26
- esc_url( ADVADS_URL . 'manual-category/purchase-licenses/#utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-licenses' )
27
  );
28
  ?>
29
  </p>
23
  ),
24
  )
25
  ),
26
+ esc_url( ADVADS_URL . 'manual/purchase-licenses/#utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-licenses' )
27
  );
28
  ?>
29
  </p>
admin/views/support.php CHANGED
@@ -7,7 +7,7 @@
7
  <h2><?php esc_html_e( 'Possible Issues', 'advanced-ads' ); ?></h2>
8
  <ul>
9
  <li><a href="<?php echo esc_url( ADVADS_URL ); ?>manual/ads-not-showing-up/#utm_source=advanced-ads&utm_medium=link&utm_campaign=support"><?php esc_html_e( 'Ads not showing up', 'advanced-ads' ); ?></a></li>
10
- <li><a href="<?php echo esc_url( ADVADS_URL ); ?>manual-category/purchase-licenses/#utm_source=advanced-ads&utm_medium=link&utm_campaign=support"><?php esc_html_e( 'Purchase & Licenses', 'advanced-ads' ); ?></a></li>
11
  <li><a href="<?php echo esc_url( ADVADS_URL ); ?>manual-category/troubleshooting/#utm_source=advanced-ads&utm_medium=link&utm_campaign=support"><?php esc_html_e( 'General Issues', 'advanced-ads' ); ?></a></li>
12
  <li><a href="<?php echo esc_url( ADVADS_URL ); ?>manual-category/add-on-issues/#utm_source=advanced-ads&utm_medium=link&utm_campaign=support"><?php esc_html_e( 'Issues with Add-Ons', 'advanced-ads' ); ?></a></li>
13
  </ul>
7
  <h2><?php esc_html_e( 'Possible Issues', 'advanced-ads' ); ?></h2>
8
  <ul>
9
  <li><a href="<?php echo esc_url( ADVADS_URL ); ?>manual/ads-not-showing-up/#utm_source=advanced-ads&utm_medium=link&utm_campaign=support"><?php esc_html_e( 'Ads not showing up', 'advanced-ads' ); ?></a></li>
10
+ <li><a href="<?php echo esc_url( ADVADS_URL ); ?>manual/purchase-licenses/#utm_source=advanced-ads&utm_medium=link&utm_campaign=support"><?php esc_html_e( 'Purchase & Licenses', 'advanced-ads' ); ?></a></li>
11
  <li><a href="<?php echo esc_url( ADVADS_URL ); ?>manual-category/troubleshooting/#utm_source=advanced-ads&utm_medium=link&utm_campaign=support"><?php esc_html_e( 'General Issues', 'advanced-ads' ); ?></a></li>
12
  <li><a href="<?php echo esc_url( ADVADS_URL ); ?>manual-category/add-on-issues/#utm_source=advanced-ads&utm_medium=link&utm_campaign=support"><?php esc_html_e( 'Issues with Add-Ons', 'advanced-ads' ); ?></a></li>
13
  </ul>
admin/views/upgrades/pro-placements.php CHANGED
@@ -37,8 +37,14 @@ $pro_placements = array(
37
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/background.png',
38
  ),
39
  );
40
- // BuddyPress.
41
- if ( class_exists( 'BuddyPress', false ) ) {
 
 
 
 
 
 
42
  $pro_placements['buddypress'] = array(
43
  'title' => __( 'BuddyPress Content', 'advanced-ads' ),
44
  'description' => __( 'Display ads on BuddyPress related pages.', 'advanced-ads' ),
37
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/background.png',
38
  ),
39
  );
40
+ // BuddyBoss & BuddyPress.
41
+ if ( defined( 'BP_PLATFORM_VERSION' ) ) { // BuddyBoss
42
+ $pro_placements['buddypress'] = array(
43
+ 'title' => __( 'BuddyBoss Content', 'advanced-ads' ),
44
+ 'description' => __( 'Display ads on BuddyBoss related pages.', 'advanced-ads' ),
45
+ 'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/buddyboss-icon.png',
46
+ );
47
+ } elseif ( class_exists( 'BuddyPress', false ) ) { // BuddyPress
48
  $pro_placements['buddypress'] = array(
49
  'title' => __( 'BuddyPress Content', 'advanced-ads' ),
50
  'description' => __( 'Display ads on BuddyPress related pages.', 'advanced-ads' ),
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.18.0
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.18.0' );
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.19.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.19.0' );
43
 
44
  // Autoloading, modules and functions.
45
 
classes/ad-model.php CHANGED
@@ -1,5 +1,8 @@
1
  <?php
2
 
 
 
 
3
  class Advanced_Ads_Model {
4
 
5
  /**
@@ -142,7 +145,11 @@ class Advanced_Ads_Model {
142
  * @param array $ad_placements array with placements.
143
  */
144
  public function update_ad_placements_array( $ad_placements ) {
 
145
  update_option( 'advads-ads-placements', $ad_placements );
146
  $this->ad_placements = $ad_placements;
147
  }
 
 
 
148
  }
1
  <?php
2
 
3
+ /**
4
+ * Advanced Ads Model
5
+ */
6
  class Advanced_Ads_Model {
7
 
8
  /**
145
  * @param array $ad_placements array with placements.
146
  */
147
  public function update_ad_placements_array( $ad_placements ) {
148
+ $ad_placements = Advanced_Ads_Placements::sort( $ad_placements, 'type' );
149
  update_option( 'advads-ads-placements', $ad_placements );
150
  $this->ad_placements = $ad_placements;
151
  }
152
+
153
+
154
+
155
  }
classes/ad.php CHANGED
@@ -587,6 +587,9 @@ class Advanced_Ads_Ad {
587
  // sanitize container ID option.
588
  $options['output']['wrapper-id'] = isset( $options['output']['wrapper-id'] ) ? sanitize_key( $options['output']['wrapper-id'] ) : '';
589
 
 
 
 
590
  // filter to manipulate options or add more to be saved.
591
  $options = apply_filters( 'advanced-ads-save-options', $options, $this );
592
 
@@ -620,7 +623,7 @@ class Advanced_Ads_Ad {
620
  $content = $this->content;
621
 
622
  // load ad type specific parameter filter
623
- // @todo this is just a hotfix for type_obj not set, yet the cause is still unknown.
624
  if ( is_object( $this->type_obj ) ) {
625
  $content = $this->type_obj->sanitize_content( $content );
626
  }
@@ -631,18 +634,26 @@ class Advanced_Ads_Ad {
631
  }
632
 
633
  /**
634
- * Native filter for ad parameters before being saved
 
635
  *
636
- * @return array $parameters sanitized parameters.
 
637
  */
638
- public function prepare_parameters_to_save() {
 
 
 
 
 
 
 
 
 
639
 
640
- $parameters = $this->parameters;
641
- // load ad type specific parameter filter.
642
- $parameters = $this->type_obj->sanitize_parameters( $parameters );
643
 
644
- // apply native WP filter for content fields.
645
- return $parameters;
646
  }
647
 
648
  /**
587
  // sanitize container ID option.
588
  $options['output']['wrapper-id'] = isset( $options['output']['wrapper-id'] ) ? sanitize_key( $options['output']['wrapper-id'] ) : '';
589
 
590
+ // sanitize options before saving
591
+ $options = $this->prepare_options_to_save( $options );
592
+
593
  // filter to manipulate options or add more to be saved.
594
  $options = apply_filters( 'advanced-ads-save-options', $options, $this );
595
 
623
  $content = $this->content;
624
 
625
  // load ad type specific parameter filter
626
+ // @todo this is just a hotfix for type_obj not set, yet the cause is still unknown. Likely when the ad is first saved
627
  if ( is_object( $this->type_obj ) ) {
628
  $content = $this->type_obj->sanitize_content( $content );
629
  }
634
  }
635
 
636
  /**
637
+ * Sanitize ad options before being saved
638
+ * allows some ad types to sanitize certain values
639
  *
640
+ * @param array $options ad options.
641
+ * @return array sanitized options.
642
  */
643
+ public function prepare_options_to_save( $options ) {
644
+
645
+ // load ad type specific sanitize function.
646
+ // we need to load the ad type object if not set (e.g., when the ad is saved for the first time)
647
+ if ( ! is_object( $this->type_obj ) || ! $this->type_obj->ID ) {
648
+ $types = Advanced_Ads::get_instance()->ad_types;
649
+ if ( isset( $types[ $this->type ] ) ) {
650
+ $this->type_obj = $types[ $this->type ];
651
+ }
652
+ }
653
 
654
+ $options = $this->type_obj->sanitize_options( $options );
 
 
655
 
656
+ return $options;
 
657
  }
658
 
659
  /**
classes/ad_ajax_callbacks.php CHANGED
@@ -43,6 +43,7 @@ class Advanced_Ads_Ad_Ajax_Callbacks {
43
  add_action( 'wp_ajax_advads-ad-health-notice-hide', array( $this, 'ad_health_notice_hide' ) );
44
  add_action( 'wp_ajax_advads-ad-health-notice-unignore', array( $this, 'ad_health_notice_unignore' ) );
45
  add_action( 'wp_ajax_advads-ad-health-notice-solved', array( $this, 'ad_health_notice_solved' ) );
 
46
 
47
  }
48
 
@@ -62,7 +63,8 @@ class Advanced_Ads_Ad_Ajax_Callbacks {
62
  $type_string = $_REQUEST['ad_type'];
63
  $ad_id = absint( $_REQUEST['ad_id'] );
64
  if ( empty( $ad_id ) ) {
65
- die(); }
 
66
 
67
  $ad = new Advanced_Ads_Ad( $ad_id );
68
 
@@ -75,6 +77,16 @@ class Advanced_Ads_Ad_Ajax_Callbacks {
75
  if ( ! in_array( $type_string, $types_without_size ) ) {
76
  include ADVADS_BASE_PATH . 'admin/views/ad-parameters-size.php';
77
  }
 
 
 
 
 
 
 
 
 
 
78
  }
79
 
80
  die();
@@ -518,4 +530,21 @@ class Advanced_Ads_Ad_Ajax_Callbacks {
518
  Advanced_Ads_Ad_Health_Notices::get_instance()->unignore();
519
  die();
520
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
521
  }
43
  add_action( 'wp_ajax_advads-ad-health-notice-hide', array( $this, 'ad_health_notice_hide' ) );
44
  add_action( 'wp_ajax_advads-ad-health-notice-unignore', array( $this, 'ad_health_notice_unignore' ) );
45
  add_action( 'wp_ajax_advads-ad-health-notice-solved', array( $this, 'ad_health_notice_solved' ) );
46
+ add_action( 'wp_ajax_advads-update-frontend-element', array( $this, 'update_frontend_element' ) );
47
 
48
  }
49
 
63
  $type_string = $_REQUEST['ad_type'];
64
  $ad_id = absint( $_REQUEST['ad_id'] );
65
  if ( empty( $ad_id ) ) {
66
+ die();
67
+ }
68
 
69
  $ad = new Advanced_Ads_Ad( $ad_id );
70
 
77
  if ( ! in_array( $type_string, $types_without_size ) ) {
78
  include ADVADS_BASE_PATH . 'admin/views/ad-parameters-size.php';
79
  }
80
+
81
+ // set the ad type attribute if empty
82
+ if ( ! isset( $ad->type ) ) {
83
+ $ad->type = $type_string;
84
+ }
85
+
86
+ // extend the AJAX-loaded parameters form by ad type
87
+ if ( isset( $types[ $type_string ] ) ) {
88
+ do_action( "advanced-ads-ad-params-after-{$type_string}", $ad, $types );
89
+ }
90
  }
91
 
92
  die();
530
  Advanced_Ads_Ad_Health_Notices::get_instance()->unignore();
531
  die();
532
  }
533
+
534
+ /**
535
+ * After the user has selected a new frontend element, update the corresponding placement.
536
+ */
537
+ public function update_frontend_element() {
538
+ check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
539
+
540
+ if ( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_manage_placements' ) ) ) {
541
+ return;
542
+ }
543
+
544
+ if ( isset( $_POST['advads']['placements'] ) ) {
545
+ Advanced_Ads_Placements::save_placements( $_POST['advads']['placements'] );
546
+ }
547
+
548
+ exit();
549
+ }
550
  }
classes/ad_placements.php CHANGED
@@ -46,6 +46,7 @@ class Advanced_Ads_Placements {
46
  'title' => __( 'Manual Placement', 'advanced-ads' ),
47
  'description' => __( 'Manual placement to use as function or shortcode.', 'advanced-ads' ),
48
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/manual.png',
 
49
  'options' => array(
50
  'show_position' => true,
51
  'show_lazy_load' => true,
@@ -56,17 +57,20 @@ class Advanced_Ads_Placements {
56
  'title' => __( 'Header Code', 'advanced-ads' ),
57
  'description' => __( 'Injected in Header (before closing &lt;/head&gt; Tag, often not visible).', 'advanced-ads' ),
58
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/header.png',
 
59
  ),
60
  'footer' => array(
61
  'title' => __( 'Footer Code', 'advanced-ads' ),
62
  'description' => __( 'Injected in Footer (before closing &lt;/body&gt; Tag).', 'advanced-ads' ),
63
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/footer.png',
 
64
  'options' => array( 'amp' => true ),
65
  ),
66
  'post_top' => array(
67
  'title' => __( 'Before Content', 'advanced-ads' ),
68
  'description' => __( 'Injected before the post content.', 'advanced-ads' ),
69
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-before.png',
 
70
  'options' => array(
71
  'show_position' => true,
72
  'show_lazy_load' => true,
@@ -78,6 +82,7 @@ class Advanced_Ads_Placements {
78
  'title' => __( 'After Content', 'advanced-ads' ),
79
  'description' => __( 'Injected after the post content.', 'advanced-ads' ),
80
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-after.png',
 
81
  'options' => array(
82
  'show_position' => true,
83
  'show_lazy_load' => true,
@@ -89,6 +94,7 @@ class Advanced_Ads_Placements {
89
  'title' => __( 'Content', 'advanced-ads' ),
90
  'description' => __( 'Injected into the content. You can choose the paragraph after which the ad content is displayed.', 'advanced-ads' ),
91
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-within.png',
 
92
  'options' => array(
93
  'show_position' => true,
94
  'show_lazy_load' => true,
@@ -100,6 +106,7 @@ class Advanced_Ads_Placements {
100
  'title' => __( 'Sidebar Widget', 'advanced-ads' ),
101
  'description' => __( 'Create a sidebar widget with an ad. Can be placed and used like any other widget.', 'advanced-ads' ),
102
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/widget.png',
 
103
  'options' => array(
104
  'show_lazy_load' => true,
105
  'amp' => true,
@@ -391,11 +398,16 @@ class Advanced_Ads_Placements {
391
 
392
  /**
393
  * Deliver the translated version of an ad if set up with WPML.
 
394
  *
395
  * @source https://wpml.org/wpml-hook/wpml_object_id/
 
 
396
  */
397
- $_item[1] = apply_filters( 'wpml_object_id', $_item[1], 'advanced_ads', true );
398
-
 
 
399
  break;
400
 
401
  case Advanced_Ads_Select::PLACEMENT:
@@ -501,8 +513,17 @@ class Advanced_Ads_Placements {
501
  $tag = 'p[not(descendant::img) and not(parent::blockquote)]';
502
  break;
503
  case 'img':
504
- // prevent injection of ads next to images in tables.
505
- $tag = 'img[not(ancestor::table)]';
 
 
 
 
 
 
 
 
 
506
  break;
507
  // any headline. By default h2, h3, and h4
508
  case 'headlines':
@@ -1173,6 +1194,64 @@ class Advanced_Ads_Placements {
1173
  return '//*[' . implode( ' or ', $query ) . ']';
1174
  }
1175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1176
 
1177
  }
1178
 
46
  'title' => __( 'Manual Placement', 'advanced-ads' ),
47
  'description' => __( 'Manual placement to use as function or shortcode.', 'advanced-ads' ),
48
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/manual.png',
49
+ 'order' => 80,
50
  'options' => array(
51
  'show_position' => true,
52
  'show_lazy_load' => true,
57
  'title' => __( 'Header Code', 'advanced-ads' ),
58
  'description' => __( 'Injected in Header (before closing &lt;/head&gt; Tag, often not visible).', 'advanced-ads' ),
59
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/header.png',
60
+ 'order' => 3,
61
  ),
62
  'footer' => array(
63
  'title' => __( 'Footer Code', 'advanced-ads' ),
64
  'description' => __( 'Injected in Footer (before closing &lt;/body&gt; Tag).', 'advanced-ads' ),
65
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/footer.png',
66
+ 'order' => 95,
67
  'options' => array( 'amp' => true ),
68
  ),
69
  'post_top' => array(
70
  'title' => __( 'Before Content', 'advanced-ads' ),
71
  'description' => __( 'Injected before the post content.', 'advanced-ads' ),
72
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-before.png',
73
+ 'order' => 20,
74
  'options' => array(
75
  'show_position' => true,
76
  'show_lazy_load' => true,
82
  'title' => __( 'After Content', 'advanced-ads' ),
83
  'description' => __( 'Injected after the post content.', 'advanced-ads' ),
84
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-after.png',
85
+ 'order' => 35,
86
  'options' => array(
87
  'show_position' => true,
88
  'show_lazy_load' => true,
94
  'title' => __( 'Content', 'advanced-ads' ),
95
  'description' => __( 'Injected into the content. You can choose the paragraph after which the ad content is displayed.', 'advanced-ads' ),
96
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-within.png',
97
+ 'order' => 21,
98
  'options' => array(
99
  'show_position' => true,
100
  'show_lazy_load' => true,
106
  'title' => __( 'Sidebar Widget', 'advanced-ads' ),
107
  'description' => __( 'Create a sidebar widget with an ad. Can be placed and used like any other widget.', 'advanced-ads' ),
108
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/widget.png',
109
+ 'order' => 50,
110
  'options' => array(
111
  'show_lazy_load' => true,
112
  'amp' => true,
398
 
399
  /**
400
  * Deliver the translated version of an ad if set up with WPML.
401
+ * If an ad is not translated, show the ad in the original language when this is the selected option in the WPML settings.
402
  *
403
  * @source https://wpml.org/wpml-hook/wpml_object_id/
404
+ * @source https://wpml.org/forums/topic/backend-custom-post-types-page-overview-with-translation-options/
405
+ *
406
  */
407
+ if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
408
+ global $sitepress;
409
+ $_item[1] = apply_filters( 'wpml_object_id', $_item[1], 'advanced_ads', $sitepress->is_display_as_translated_post_type( 'advanced_ads' ) );
410
+ }
411
  break;
412
 
413
  case Advanced_Ads_Select::PLACEMENT:
513
  $tag = 'p[not(descendant::img) and not(parent::blockquote)]';
514
  break;
515
  case 'img':
516
+ /*
517
+ * Handle: 1) "img" tags 2) "image" block 3) "gallery" block 4) "gallery shortcode" 5) "wp_caption" shortcode
518
+ * Handle the gallery created by the block or the shortcode as one image.
519
+ * Prevent injection of ads next to images in tables.
520
+ */
521
+ // Default shortcodes, including non-HTML5 versions.
522
+ $shortcodes = "@class and (
523
+ contains(concat(' ', normalize-space(@class), ' '), ' gallery-size') or
524
+ contains(concat(' ', normalize-space(@class), ' '), ' wp-caption ') )";
525
+ $tag = "*[self::img or self::figure or self::div[$shortcodes]]
526
+ [not(ancestor::table or ancestor::figure or ancestor::div[$shortcodes])]";
527
  break;
528
  // any headline. By default h2, h3, and h4
529
  case 'headlines':
1194
  return '//*[' . implode( ' or ', $query ) . ']';
1195
  }
1196
 
1197
+ /**
1198
+ * Sort placements
1199
+ *
1200
+ * @param array $placements Existing placements.
1201
+ * @param string $orderby The field to order by. Accept `name` or `type`.
1202
+ * @return array $placements Sorted placements.
1203
+ */
1204
+ public static function sort( $placements, $orderby = 'name' ) {
1205
+ if ( ! is_array( $placements ) ) {
1206
+ return array();
1207
+ }
1208
+ if ( 'name' === $orderby ) {
1209
+ ksort( $placements );
1210
+ return $placements;
1211
+ }
1212
+ uasort( $placements, array( 'Advanced_Ads_Placements', 'sort_by_type_callback' ) );
1213
+ return $placements;
1214
+
1215
+ }
1216
+
1217
+ /**
1218
+ * Callback to sort placements by type.
1219
+ *
1220
+ * @param array $f First placement.
1221
+ * @param array $s Second placement.
1222
+ * @return int 0 If placements are equal, -1 if the first should come first, 1 otherwise.
1223
+ */
1224
+ private static function sort_by_type_callback( $f, $s ) {
1225
+ // A placement with the "Words Between Ads" option set to non-zero gets injected after others
1226
+ // because it reads existing ads.
1227
+ if ( ! empty( $f['options']['words_between_repeats'] ) xor ! empty( $s['options']['words_between_repeats'] ) ) {
1228
+ return ! empty( $f['options']['words_between_repeats'] ) ? 1 : -1;
1229
+ }
1230
+
1231
+ $types = self::get_placement_types();
1232
+
1233
+ $f_o = ( isset( $f['type'] ) && isset( $types[ $f['type'] ]['order'] ) ) ? $types[ $f['type'] ]['order'] : 100;
1234
+ $s_o = ( isset( $s['type'] ) && isset( $types[ $s['type'] ]['order'] ) ) ? $types[ $s['type'] ]['order'] : 100;
1235
+
1236
+ if ( $f_o === $s_o ) {
1237
+ // Sort by index.
1238
+ if ( 'post_content' === $f['type'] && isset( $f['options']['index'] ) && isset( $s['options']['index'] )
1239
+ && $f['options']['index'] !== $s['options']['index'] ) {
1240
+ return ( $f['options']['index'] < $s['options']['index'] ) ? -1 : 1;
1241
+ }
1242
+
1243
+ // Sort by name.
1244
+ if ( isset( $f['name'] ) && isset( $s['name'] ) ) {
1245
+ return 0 > strcmp( $f['name'], $s['name'] ) ? -1 : 1;
1246
+ }
1247
+ return 0;
1248
+ }
1249
+
1250
+ // Sort by order.
1251
+ return ( $f_o < $s_o ) ? -1 : 1;
1252
+
1253
+ }
1254
+
1255
 
1256
  }
1257
 
classes/ad_type_abstract.php CHANGED
@@ -74,15 +74,14 @@ class Advanced_Ads_Ad_Type_Abstract {
74
  }
75
 
76
  /**
77
- * Sanitize ad parameters on save
78
  *
79
- * @param arr $parameters array with ad parameters
80
- * @return arr $parameters sanitized ad parameters
81
  * @since 1.0.0
82
  */
83
- public function sanitize_parameters($parameters = array()){
84
- // no specific filter for content ad parameters, because there are no
85
- return $parameters;
86
  }
87
 
88
  /**
74
  }
75
 
76
  /**
77
+ * Sanitize ad options on save
78
  *
79
+ * @param array $options all ad options.
80
+ * @return array sanitized ad options.
81
  * @since 1.0.0
82
  */
83
+ public function sanitize_options( $options = array() ) {
84
+ return $options;
 
85
  }
86
 
87
  /**
classes/compatibility.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
-
 
 
3
  class Advanced_Ads_Compatibility {
4
 
5
  /**
@@ -23,7 +25,7 @@ class Advanced_Ads_Compatibility {
23
  }
24
  // WPML.
25
  add_filter( 'wpml_admin_language_switcher_active_languages', array( $this, 'wpml_language_switcher' ) );
26
- // Wordpress SEO by Yoast.
27
  add_filter( 'wpseo_sitemap_entry', array( $this, 'wordpress_seo_noindex_ad_attachments' ), 10, 3 );
28
  // Add shortcode for MailPoet.
29
  add_filter( 'mailpoet_newsletter_shortcode', array( $this, 'mailpoet_ad_shortcode' ), 10, 5 );
@@ -92,16 +94,13 @@ class Advanced_Ads_Compatibility {
92
  return array();
93
  }
94
  break;
95
- // always show all languages on Placements page.
96
- case 'advanced-ads_page_advanced-ads-placements':
97
- return array();
98
  }
99
 
100
  return $active_languages;
101
  }
102
 
103
  /**
104
- * Wordpress SEO: remove attachments attached to ads from `/attachment-sitemap.xml`.
105
  *
106
  * @param array $url Array of URL parts.
107
  * @param string $type URL type.
@@ -115,10 +114,12 @@ class Advanced_Ads_Compatibility {
115
 
116
  static $ad_ids = null;
117
  if ( null === $ad_ids ) {
118
- $ad_ids = Advanced_Ads::get_instance()->get_model()->get_ads( array(
119
- 'post_status' => 'any',
120
- 'fields' => 'ids'
121
- ) );
 
 
122
  }
123
 
124
  if ( isset( $post->post_parent ) && in_array( $post->post_parent, $ad_ids, true ) ) {
@@ -133,15 +134,15 @@ class Advanced_Ads_Compatibility {
133
  * e.g., [custom:ad:123] to display ad with the ID 123
134
  * [custom:ad_group:345] to display ad group with the ID 345
135
  *
136
- * @param string $shortcode
137
- * @param $newsletter unused
138
- * @param $subscriber unused
139
- * @param $queue unused
140
- * @param $newsletter_body unused
141
  *
142
  * @return string
143
  */
144
- function mailpoet_ad_shortcode( $shortcode, $newsletter, $subscriber, $queue, $newsletter_body ) {
145
  // display an ad group.
146
  if ( 0 === strpos( $shortcode, '[custom:ad_group:' ) ) {
147
  // get ad group ID.
1
  <?php
2
+ /**
3
+ * Compatibility fixes with other plugins.
4
+ */
5
  class Advanced_Ads_Compatibility {
6
 
7
  /**
25
  }
26
  // WPML.
27
  add_filter( 'wpml_admin_language_switcher_active_languages', array( $this, 'wpml_language_switcher' ) );
28
+ // WordPress SEO by Yoast.
29
  add_filter( 'wpseo_sitemap_entry', array( $this, 'wordpress_seo_noindex_ad_attachments' ), 10, 3 );
30
  // Add shortcode for MailPoet.
31
  add_filter( 'mailpoet_newsletter_shortcode', array( $this, 'mailpoet_ad_shortcode' ), 10, 5 );
94
  return array();
95
  }
96
  break;
 
 
 
97
  }
98
 
99
  return $active_languages;
100
  }
101
 
102
  /**
103
+ * WordPress SEO: remove attachments attached to ads from `/attachment-sitemap.xml`.
104
  *
105
  * @param array $url Array of URL parts.
106
  * @param string $type URL type.
114
 
115
  static $ad_ids = null;
116
  if ( null === $ad_ids ) {
117
+ $ad_ids = Advanced_Ads::get_instance()->get_model()->get_ads(
118
+ array(
119
+ 'post_status' => 'any',
120
+ 'fields' => 'ids',
121
+ )
122
+ );
123
  }
124
 
125
  if ( isset( $post->post_parent ) && in_array( $post->post_parent, $ad_ids, true ) ) {
134
  * e.g., [custom:ad:123] to display ad with the ID 123
135
  * [custom:ad_group:345] to display ad group with the ID 345
136
  *
137
+ * @param string $shortcode shortcode that placed the ad.
138
+ * @param mixed $newsletter unused.
139
+ * @param mixed $subscriber unused.
140
+ * @param mixed $queue unused.
141
+ * @param string $newsletter_body unused.
142
  *
143
  * @return string
144
  */
145
+ public function mailpoet_ad_shortcode( $shortcode, $newsletter, $subscriber, $queue, $newsletter_body ) {
146
  // display an ad group.
147
  if ( 0 === strpos( $shortcode, '[custom:ad_group:' ) ) {
148
  // get ad group ID.
classes/display-conditions.php CHANGED
@@ -1011,7 +1011,7 @@ class Advanced_Ads_Display_Conditions {
1011
  $query = $ad_options['wp_the_query'];
1012
  $post_id = isset( $ad_options['post']['id'] ) ? $ad_options['post']['id'] : null;
1013
 
1014
- // ixes page id on BuddyPress pages.
1015
  if ( 0 === $post_id && class_exists( 'BuddyPress' ) && function_exists( 'bp_current_component' ) ) {
1016
  $component = bp_current_component();
1017
  $bp_pages = get_option( 'bp-pages' );
1011
  $query = $ad_options['wp_the_query'];
1012
  $post_id = isset( $ad_options['post']['id'] ) ? $ad_options['post']['id'] : null;
1013
 
1014
+ // fixes page id on BuddyPress pages.
1015
  if ( 0 === $post_id && class_exists( 'BuddyPress' ) && function_exists( 'bp_current_component' ) ) {
1016
  $component = bp_current_component();
1017
  $bp_pages = get_option( 'bp-pages' );
classes/frontend_checks.php CHANGED
@@ -98,7 +98,7 @@ class Advanced_Ads_Frontend_Checks {
98
  'parent' => 'advanced_ads_ad_health',
99
  'id' => 'advanced_ads_autoads_displayed',
100
  'title' => __( 'Random AdSense ads', 'advanced-ads' ),
101
- 'href' => ADVADS_URL . 'adsense-in-random-positions-auto-ads/#utm_source=advancedads&utm_medium=link&utm_campaign=frontend-autoads-ads',
102
  'meta' => array(
103
  'class' => 'hidden',
104
  'target' => '_blank'
@@ -488,8 +488,8 @@ class Advanced_Ads_Frontend_Checks {
488
  */
489
  public function footer_checks() {
490
  ob_start();
491
- ?><!-- Advanced Ads: <?php _e( 'the following code is used for automatic error detection and only visible to admins', 'advanced-ads' ); ?>-->
492
- <style>.hidden { display: none; }
493
  #wp-admin-bar-advanced_ads_ad_health-default a:after { content: "\25BA"; margin-left: .5em; font-size: smaller; }
494
  #wp-admin-bar-advanced_ads_ad_health-default .advanced_ads_ad_health_highlight_ads div:before { content: "\f177"; margin-right: .2em; line-height: 1em; padding: 0.2em 0 0; color: inherit; }
495
  #wp-admin-bar-advanced_ads_ad_health-default .advanced_ads_ad_health_highlight_ads div:hover { color: #00b9eb; cursor: pointer; }
@@ -816,7 +816,7 @@ class Advanced_Ads_Frontend_Checks {
816
  '<span class="advads-close advads-smiley advads-smiley-positive" title="<?php esc_attr_e( 'This is fine', 'advanced-ads' ); ?>"><i class="eye eye1"></i><i class="eye eye2"></i><i class="mouth"></i></span>' +
817
  '<span class="advads-choice-negative advads-smiley" title="<?php esc_attr_e( 'I expected something else', 'advanced-ads' ); ?>"><i class="eye eye1"></i><i class="eye eye2"></i><i class="mouth"></i></span>' +
818
  '</div>' +
819
- '<p class="advads-notice-var1"><?php esc_attr_e( 'PS: this is a one-time check from your friendly Advanced Ads plugin. It is only visible to you.', 'advanced-ads' ); ?></p>';
820
  break;
821
  case 'auto-ads-with-ads-help' :
822
  content = '<p style="text-align: center;"><?php esc_attr_e( 'Just click on your problem to learn more from our knowledge base.', 'advanced-ads' ); ?></p>' +
98
  'parent' => 'advanced_ads_ad_health',
99
  'id' => 'advanced_ads_autoads_displayed',
100
  'title' => __( 'Random AdSense ads', 'advanced-ads' ),
101
+ 'href' => ADVADS_URL . 'adsense-in-random-positions-auto-ads/#utm_source=advanced-ads&utm_medium=link&utm_campaign=frontend-autoads-ads',
102
  'meta' => array(
103
  'class' => 'hidden',
104
  'target' => '_blank'
488
  */
489
  public function footer_checks() {
490
  ob_start();
491
+ ?><!-- Advanced Ads: <?php esc_html_e( 'the following code is used for automatic error detection and only visible to admins', 'advanced-ads' ); ?>-->
492
+ <style>#wp-admin-bar-advanced_ads_ad_health .hidden { display: none; }
493
  #wp-admin-bar-advanced_ads_ad_health-default a:after { content: "\25BA"; margin-left: .5em; font-size: smaller; }
494
  #wp-admin-bar-advanced_ads_ad_health-default .advanced_ads_ad_health_highlight_ads div:before { content: "\f177"; margin-right: .2em; line-height: 1em; padding: 0.2em 0 0; color: inherit; }
495
  #wp-admin-bar-advanced_ads_ad_health-default .advanced_ads_ad_health_highlight_ads div:hover { color: #00b9eb; cursor: pointer; }
816
  '<span class="advads-close advads-smiley advads-smiley-positive" title="<?php esc_attr_e( 'This is fine', 'advanced-ads' ); ?>"><i class="eye eye1"></i><i class="eye eye2"></i><i class="mouth"></i></span>' +
817
  '<span class="advads-choice-negative advads-smiley" title="<?php esc_attr_e( 'I expected something else', 'advanced-ads' ); ?>"><i class="eye eye1"></i><i class="eye eye2"></i><i class="mouth"></i></span>' +
818
  '</div>' +
819
+ '<p class="advads-notice-var1"><?php esc_attr_e( 'PS: This is a one-time check from your friendly Advanced Ads plugin. It is only visible to you.', 'advanced-ads' ); ?></p>';
820
  break;
821
  case 'auto-ads-with-ads-help' :
822
  content = '<p style="text-align: center;"><?php esc_attr_e( 'Just click on your problem to learn more from our knowledge base.', 'advanced-ads' ); ?></p>' +
classes/plugin.php CHANGED
@@ -162,8 +162,13 @@ class Advanced_Ads_Plugin {
162
  // wp_enqueue_script( $this->get_plugin_slug() . '-plugin-script', plugins_url('assets/js/public.js', __FILE__), array('jquery'), ADVADS_VERSION);
163
  $options = $this->options();
164
  $activated_js = apply_filters( 'advanced-ads-activate-advanced-js', isset( $options['advanced-js'] ) );
165
- if ( $activated_js ) {
166
- wp_enqueue_script( $this->get_plugin_slug() . '-advanced-js', ADVADS_BASE_URL . 'public/assets/js/advanced.js', array( 'jquery' ), ADVADS_VERSION );
 
 
 
 
 
167
  }
168
  }
169
 
162
  // wp_enqueue_script( $this->get_plugin_slug() . '-plugin-script', plugins_url('assets/js/public.js', __FILE__), array('jquery'), ADVADS_VERSION);
163
  $options = $this->options();
164
  $activated_js = apply_filters( 'advanced-ads-activate-advanced-js', isset( $options['advanced-js'] ) );
165
+
166
+ if ( $activated_js || ! empty( $_COOKIE['advads_frontend_picker'] ) ) {
167
+ wp_enqueue_script( $this->get_plugin_slug() . '-advanced-js', ADVADS_BASE_URL . 'public/assets/js/advanced.js', array( 'jquery' ), ADVADS_VERSION, false );
168
+ $data = array(
169
+ 'blog_id' => get_current_blog_id(),
170
+ );
171
+ wp_localize_script( $this->get_plugin_slug() . '-advanced-js', 'advanced_ads_data', $data );
172
  }
173
  }
174
 
includes/load_modules.php CHANGED
@@ -1,17 +1,23 @@
1
  <?php
2
 
 
 
 
3
  final class Advanced_Ads_ModuleLoader {
4
 
5
  protected static $loader;
6
  protected static $textdomains = array();
7
  protected static $modules = array();
8
 
 
 
 
 
 
9
  public static function getLoader()
10
  {
11
- if ( null === self::$loader ) {
12
- self::$loader = file_exists(ADVADS_BASE_PATH . 'vendor/autoload.php')
13
- ? require_once ADVADS_BASE_PATH . 'vendor/autoload.php'
14
- : require_once ADVADS_BASE_PATH . 'lib/autoload.php';
15
  }
16
 
17
  return self::$loader;
1
  <?php
2
 
3
+ /**
4
+ * Class Advanced_Ads_ModuleLoader
5
+ */
6
  final class Advanced_Ads_ModuleLoader {
7
 
8
  protected static $loader;
9
  protected static $textdomains = array();
10
  protected static $modules = array();
11
 
12
+ /**
13
+ * Get the Composer autoloader.
14
+ *
15
+ * @return \AdvancedAds\Autoload\ClassLoader
16
+ */
17
  public static function getLoader()
18
  {
19
+ if ( is_null( self::$loader ) ) {
20
+ self::$loader = require_once ADVADS_BASE_PATH . 'lib/autoload.php';
 
 
21
  }
22
 
23
  return self::$loader;
languages/advanced-ads.pot CHANGED
@@ -2,14 +2,14 @@
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.18.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: 2020-06-10T08:01:44+00: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"
@@ -32,7 +32,7 @@ msgstr ""
32
  msgid "Thomas Maier, Advanced Ads GmbH"
33
  msgstr ""
34
 
35
- #: admin/class-advanced-ads-admin.php:216
36
  #: classes/display-conditions.php:290
37
  #: classes/visitor-conditions.php:311
38
  #: modules/gadsense/admin/views/external-ads-links.php:17
@@ -41,70 +41,70 @@ msgstr ""
41
  msgid "or"
42
  msgstr ""
43
 
44
- #: admin/class-advanced-ads-admin.php:217
45
  #: classes/display-conditions.php:290
46
  #: classes/visitor-conditions.php:311
47
  msgid "and"
48
  msgstr ""
49
 
50
- #: admin/class-advanced-ads-admin.php:218
51
  msgid "After which paragraph?"
52
  msgstr ""
53
 
54
- #: admin/class-advanced-ads-admin.php:220
55
  msgid "Today"
56
  msgstr ""
57
 
58
- #: admin/class-advanced-ads-admin.php:221
59
  msgid "Yesterday"
60
  msgstr ""
61
 
62
- #: admin/class-advanced-ads-admin.php:222
63
  msgid "This Month"
64
  msgstr ""
65
 
66
  #. translators: 1: The number of days.
67
- #: admin/class-advanced-ads-admin.php:224
68
  msgid "Last %1$d days"
69
  msgstr ""
70
 
71
- #: admin/class-advanced-ads-admin.php:227
72
  msgid "All"
73
  msgstr ""
74
 
75
- #: admin/class-advanced-ads-admin.php:228
76
  msgid "There were no results returned for this ad. Please make sure it is active, generating impressions and double check your ad parameters."
77
  msgstr ""
78
 
79
- #: admin/class-advanced-ads-admin.php:229
80
  #: modules/gadsense/admin/views/external-ads-list.php:33
81
  msgid "Show inactive ads"
82
  msgstr ""
83
 
84
- #: admin/class-advanced-ads-admin.php:230
85
  msgid "Hide inactive ads"
86
  msgstr ""
87
 
88
  #. translators: time zone name.
89
- #: admin/class-advanced-ads-admin.php:344
90
  msgid "time of %s"
91
  msgstr ""
92
 
93
- #: admin/class-advanced-ads-admin.php:415
94
  #: admin/includes/class-menu.php:156
95
  #: admin/includes/class-menu.php:159
96
  #: admin/views/settings.php:29
97
  msgid "Support"
98
  msgstr ""
99
 
100
- #: admin/class-advanced-ads-admin.php:419
101
  #: admin/includes/class-overview-widgets.php:71
102
  msgid "Add-Ons"
103
  msgstr ""
104
 
105
  #. translators: %s is the URL to add a new review, https://wordpress.org/support/plugin/advanced-ads/reviews/#new-post
106
  #. translators: %s is a URL.
107
- #: admin/class-advanced-ads-admin.php:690
108
  #: admin/includes/class-overview-widgets.php:194
109
  msgid "Thank the developer with a &#9733;&#9733;&#9733;&#9733;&#9733; review on <a href=\"%s\" target=\"_blank\">wordpress.org</a>"
110
  msgstr ""
@@ -122,7 +122,7 @@ msgstr ""
122
  #. translators: %s is a list of PHP extensions.
123
  #. translators: %s is a name of a module.
124
  #: admin/includes/ad-health-notices.php:54
125
- #: admin/views/placements.php:179
126
  msgid "Missing PHP extensions could cause issues. Please ask your hosting provider to enable them: %s"
127
  msgstr ""
128
 
@@ -317,7 +317,7 @@ msgstr ""
317
  #: modules/import-export/classes/import.php:146
318
  #: modules/import-export/classes/import.php:186
319
  #: modules/import-export/classes/import.php:564
320
- #: public/class-advanced-ads.php:740
321
  msgid "Edit"
322
  msgstr ""
323
 
@@ -514,11 +514,11 @@ msgstr ""
514
  msgid "License couldn’t be deactivated. Please try again later."
515
  msgstr ""
516
 
517
- #: admin/includes/class-licenses.php:596
518
  msgid "Download failed. <a href=\"%s\">Click here to try another method</a>."
519
  msgstr ""
520
 
521
- #: admin/includes/class-licenses.php:598
522
  msgid "Download failed. <a href=\"%s\" target=\"_blank\">Click here to learn why</a>."
523
  msgstr ""
524
 
@@ -549,23 +549,23 @@ msgstr ""
549
  #: admin/views/ad-group-list-form-row.php:91
550
  #: admin/views/ad-group-list-header.php:16
551
  #: admin/views/placement-form.php:88
552
- #: admin/views/placements-item.php:24
553
  #: classes/widget.php:129
554
  #: modules/gutenberg/includes/class-gutenberg.php:79
555
  #: modules/import-export/views/page.php:23
556
- #: public/class-advanced-ads.php:736
557
  msgid "Ads"
558
  msgstr ""
559
 
560
  #: admin/includes/class-menu.php:112
561
- #: public/class-advanced-ads.php:739
562
  msgid "Add New Ad"
563
  msgstr ""
564
 
565
  #: admin/includes/class-menu.php:113
566
  #: admin/views/ad-group-list-ads.php:36
567
- #: public/class-advanced-ads.php:738
568
- #: public/class-advanced-ads.php:742
569
  msgid "New Ad"
570
  msgstr ""
571
 
@@ -583,7 +583,7 @@ msgstr ""
583
 
584
  #: admin/includes/class-menu.php:132
585
  #: admin/includes/class-shortcode-creator.php:115
586
- #: admin/views/placements.php:53
587
  #: classes/widget.php:115
588
  #: modules/gutenberg/includes/class-gutenberg.php:81
589
  #: modules/import-export/views/page.php:25
@@ -604,12 +604,12 @@ msgstr ""
604
  msgid "Licenses"
605
  msgstr ""
606
 
607
- #: admin/includes/class-menu.php:282
608
- #: admin/includes/class-menu.php:307
609
  msgid "Sorry, you are not allowed to access this feature."
610
  msgstr ""
611
 
612
- #: admin/includes/class-menu.php:294
613
  msgid "You attempted to edit an ad group that doesn&#8217;t exist. Perhaps it was deleted?"
614
  msgstr ""
615
 
@@ -632,13 +632,13 @@ msgid "Layout / Output"
632
  msgstr ""
633
 
634
  #: admin/includes/class-meta-box.php:104
635
- #: admin/views/placements.php:219
636
  #: classes/ad-debug.php:152
637
  msgid "Display Conditions"
638
  msgstr ""
639
 
640
  #: admin/includes/class-meta-box.php:112
641
- #: admin/views/placements.php:228
642
  #: classes/ad-debug.php:239
643
  msgid "Visitor Conditions"
644
  msgstr ""
@@ -937,7 +937,7 @@ msgid "Priority of content injection filter"
937
  msgstr ""
938
 
939
  #: admin/includes/class-settings.php:163
940
- #: classes/ad_placements.php:996
941
  msgid "Disable level limitation"
942
  msgstr ""
943
 
@@ -1007,7 +1007,7 @@ msgstr ""
1007
 
1008
  #: admin/includes/class-shortcode-creator.php:108
1009
  #: admin/views/placement-form.php:81
1010
- #: admin/views/placements-item.php:12
1011
  #: classes/widget.php:122
1012
  #: modules/gutenberg/includes/class-gutenberg.php:80
1013
  msgid "Ad Groups"
@@ -1162,7 +1162,7 @@ msgstr ""
1162
  #: classes/ad-debug.php:118
1163
  #: classes/ad-debug.php:167
1164
  #: classes/ad-debug.php:169
1165
- #: public/class-advanced-ads.php:737
1166
  msgid "Ad"
1167
  msgstr ""
1168
 
@@ -1176,7 +1176,7 @@ msgid "add"
1176
  msgstr ""
1177
 
1178
  #: admin/views/ad-group-list-form-row.php:31
1179
- #: admin/views/placements.php:59
1180
  #: modules/gadsense/admin/views/external-ads-list.php:45
1181
  #: modules/gadsense/admin/views/external-ads-list.php:55
1182
  #: modules/privacy/admin/views/setting-consent-method.php:9
@@ -1184,7 +1184,7 @@ msgid "Name"
1184
  msgstr ""
1185
 
1186
  #: admin/views/ad-group-list-form-row.php:56
1187
- #: admin/views/placements.php:58
1188
  #: modules/gadsense/admin/views/adsense-ad-parameters.php:105
1189
  msgid "Type"
1190
  msgstr ""
@@ -1213,7 +1213,7 @@ msgstr ""
1213
 
1214
  #: admin/views/ad-group-list-row.php:22
1215
  #: admin/views/ad-info.php:7
1216
- #: admin/views/placements.php:126
1217
  msgid "shortcode"
1218
  msgstr ""
1219
 
@@ -1370,7 +1370,7 @@ msgstr ""
1370
  #: admin/views/placements-ad-label-position.php:13
1371
  #: admin/views/placements-ad-label.php:9
1372
  #: admin/views/placements-ad-label.php:11
1373
- #: admin/views/placements.php:108
1374
  #: modules/gadsense/includes/class-network-adsense.php:324
1375
  msgid "default"
1376
  msgstr ""
@@ -1504,7 +1504,7 @@ msgid "Minute"
1504
  msgstr ""
1505
 
1506
  #. translators: %1$s month, %2$s day, %3$s year, %4$s hour, %5$s minute.
1507
- #: admin/views/ad-submitbox-meta.php:40
1508
  msgctxt "order of expiry date fields 1: month, 2: day, 3: year, 4: hour, 5: minute"
1509
  msgid "%1$s %2$s, %3$s @ %4$s %5$s"
1510
  msgstr ""
@@ -1804,7 +1804,7 @@ msgid "The ad or group that should be displayed."
1804
  msgstr ""
1805
 
1806
  #: admin/views/placement-form.php:79
1807
- #: admin/views/placements-item.php:10
1808
  msgid "--not selected--"
1809
  msgstr ""
1810
 
@@ -1854,17 +1854,17 @@ msgid "New placement"
1854
  msgstr ""
1855
 
1856
  #: admin/views/placement-injection-top.php:79
1857
- #: classes/ad_placements.php:67
1858
  msgid "Before Content"
1859
  msgstr ""
1860
 
1861
  #: admin/views/placement-injection-top.php:80
1862
- #: classes/ad_placements.php:89
1863
  msgid "Content"
1864
  msgstr ""
1865
 
1866
  #: admin/views/placement-injection-top.php:81
1867
- #: classes/ad_placements.php:78
1868
  msgid "After Content"
1869
  msgstr ""
1870
 
@@ -1942,127 +1942,141 @@ msgstr ""
1942
  msgid "disabled"
1943
  msgstr ""
1944
 
1945
- #: admin/views/placements-content-index.php:43
1946
  msgid "use xpath, e.g. `p[not(parent::blockquote)]`"
1947
  msgstr ""
1948
 
1949
- #: admin/views/placements-content-index.php:50
 
 
 
 
 
 
 
 
 
1950
  msgid "start counting from bottom"
1951
  msgstr ""
1952
 
1953
- #: admin/views/placements.php:12
 
 
 
 
 
1954
  msgid "Couldn’t create the new placement. Please check your form field and whether the name is already in use."
1955
  msgstr ""
1956
 
1957
- #: admin/views/placements.php:16
1958
  msgid "Placements updated"
1959
  msgstr ""
1960
 
1961
- #: admin/views/placements.php:22
1962
- #: admin/views/placements.php:307
1963
  msgid "Create a new placement"
1964
  msgstr ""
1965
 
1966
- #: admin/views/placements.php:23
1967
- #: admin/views/placements.php:309
1968
  msgid "New Placement"
1969
  msgstr ""
1970
 
1971
- #: admin/views/placements.php:28
1972
  msgid "Placements are physically places in your theme and posts. You can use them if you plan to change ads and ad groups on the same place without the need to change your templates."
1973
  msgstr ""
1974
 
1975
  #. translators: %s is a URL.
1976
- #: admin/views/placements.php:34
1977
  msgid "See also the manual for more information on <a href=\"%s\">placements</a>."
1978
  msgstr ""
1979
 
1980
- #: admin/views/placements.php:60
1981
  #: modules/import-export/views/page.php:26
1982
  msgid "Options"
1983
  msgstr ""
1984
 
1985
  #. translators: %s is the name of a placement.
1986
- #: admin/views/placements.php:87
1987
  msgid "Placement type \"%s\" is missing and was reset to \"default\".<br/>Please check if the responsible add-on is activated."
1988
  msgstr ""
1989
 
1990
- #: admin/views/placements.php:117
1991
  msgid "show usage"
1992
  msgstr ""
1993
 
1994
- #: admin/views/placements.php:129
1995
  msgid "template (PHP)"
1996
  msgstr ""
1997
 
1998
- #: admin/views/placements.php:144
1999
  msgid "Item"
2000
  msgstr ""
2001
 
2002
- #: admin/views/placements.php:155
2003
  msgid "after"
2004
  msgstr ""
2005
 
2006
- #: admin/views/placements.php:156
2007
  msgid "before"
2008
  msgstr ""
2009
 
2010
- #: admin/views/placements.php:169
2011
  msgid "position"
2012
  msgstr ""
2013
 
2014
- #: admin/views/placements.php:175
2015
  msgid "Important Notice"
2016
  msgstr ""
2017
 
2018
- #: admin/views/placements.php:208
2019
  msgid "ad label"
2020
  msgstr ""
2021
 
2022
- #: admin/views/placements.php:221
2023
  msgid "Use display conditions for placements."
2024
  msgstr ""
2025
 
2026
- #: admin/views/placements.php:222
2027
- #: admin/views/placements.php:231
2028
  msgid "The free version provides conditions on the ad edit page."
2029
  msgstr ""
2030
 
2031
- #: admin/views/placements.php:230
2032
  msgid "Use visitor conditions for placements."
2033
  msgstr ""
2034
 
2035
- #: admin/views/placements.php:237
2036
  msgid "Minimum Content Length"
2037
  msgstr ""
2038
 
2039
- #: admin/views/placements.php:239
2040
  msgid "Minimum length of content before automatically injected ads are allowed in them."
2041
  msgstr ""
2042
 
2043
- #: admin/views/placements.php:245
2044
  msgid "Words Between Ads"
2045
  msgstr ""
2046
 
2047
- #: admin/views/placements.php:247
2048
  msgid "A minimum amount of words between automatically injected ads."
2049
  msgstr ""
2050
 
2051
- #: admin/views/placements.php:257
2052
  msgid "show all options"
2053
  msgstr ""
2054
 
2055
  #. translators: %s is a URL.
2056
- #: admin/views/placements.php:278
2057
  msgid "Tutorial: <a href=\"%s\" target=\"_blank\">How to place visible ads in the header of your website</a>."
2058
  msgstr ""
2059
 
2060
- #: admin/views/placements.php:298
2061
  msgctxt "checkbox to remove placement"
2062
  msgid "delete"
2063
  msgstr ""
2064
 
2065
- #: admin/views/placements.php:305
2066
  msgid "Save Placements"
2067
  msgstr ""
2068
 
@@ -2369,18 +2383,26 @@ msgid "Background of the website behind the main wrapper."
2369
  msgstr ""
2370
 
2371
  #: admin/views/upgrades/pro-placements.php:43
2372
- msgid "BuddyPress Content"
2373
  msgstr ""
2374
 
2375
  #: admin/views/upgrades/pro-placements.php:44
 
 
 
 
 
 
 
 
2376
  msgid "Display ads on BuddyPress related pages."
2377
  msgstr ""
2378
 
2379
- #: admin/views/upgrades/pro-placements.php:51
2380
  msgid "bbPress Content"
2381
  msgstr ""
2382
 
2383
- #: admin/views/upgrades/pro-placements.php:52
2384
  msgid "Display ads in content created with bbPress."
2385
  msgstr ""
2386
 
@@ -2462,7 +2484,7 @@ msgid "main query"
2462
  msgstr ""
2463
 
2464
  #: classes/ad-debug.php:121
2465
- #: public/class-advanced-ads.php:701
2466
  msgctxt "ad group singular name"
2467
  msgid "Ad Group"
2468
  msgstr ""
@@ -2478,7 +2500,7 @@ msgid "Learn more about AdSense account issues %1$shere%2$s."
2478
  msgstr ""
2479
 
2480
  #. translators: %s is a URL.
2481
- #: classes/ad_ajax_callbacks.php:246
2482
  msgid "An error occurred. Please use <a href=\"%s\" target=\"_blank\">this form</a> to sign up."
2483
  msgstr ""
2484
 
@@ -2490,113 +2512,113 @@ msgstr ""
2490
  msgid "Manual placement to use as function or shortcode."
2491
  msgstr ""
2492
 
2493
- #: classes/ad_placements.php:56
2494
  msgid "Header Code"
2495
  msgstr ""
2496
 
2497
- #: classes/ad_placements.php:57
2498
  msgid "Injected in Header (before closing &lt;/head&gt; Tag, often not visible)."
2499
  msgstr ""
2500
 
2501
- #: classes/ad_placements.php:61
2502
  msgid "Footer Code"
2503
  msgstr ""
2504
 
2505
- #: classes/ad_placements.php:62
2506
  msgid "Injected in Footer (before closing &lt;/body&gt; Tag)."
2507
  msgstr ""
2508
 
2509
- #: classes/ad_placements.php:68
2510
  msgid "Injected before the post content."
2511
  msgstr ""
2512
 
2513
- #: classes/ad_placements.php:79
2514
  msgid "Injected after the post content."
2515
  msgstr ""
2516
 
2517
- #: classes/ad_placements.php:90
2518
  msgid "Injected into the content. You can choose the paragraph after which the ad content is displayed."
2519
  msgstr ""
2520
 
2521
- #: classes/ad_placements.php:100
2522
  msgid "Sidebar Widget"
2523
  msgstr ""
2524
 
2525
- #: classes/ad_placements.php:101
2526
  msgid "Create a sidebar widget with an ad. Can be placed and used like any other widget."
2527
  msgstr ""
2528
 
2529
  #. translators: %s is an html tag.
2530
- #: classes/ad_placements.php:292
2531
  msgid "paragraph (%s)"
2532
  msgstr ""
2533
 
2534
  #. translators: %s is an html tag.
2535
- #: classes/ad_placements.php:294
2536
  msgid "paragraph without image (%s)"
2537
  msgstr ""
2538
 
2539
  #. translators: %s is an html tag.
2540
- #: classes/ad_placements.php:296
2541
  msgid "headline 2 (%s)"
2542
  msgstr ""
2543
 
2544
  #. translators: %s is an html tag.
2545
- #: classes/ad_placements.php:298
2546
  msgid "headline 3 (%s)"
2547
  msgstr ""
2548
 
2549
  #. translators: %s is an html tag.
2550
- #: classes/ad_placements.php:300
2551
  msgid "headline 4 (%s)"
2552
  msgstr ""
2553
 
2554
  #. translators: %s is an html tag.
2555
- #: classes/ad_placements.php:302
2556
  msgid "any headline (%s)"
2557
  msgstr ""
2558
 
2559
  #. translators: %s is an html tag.
2560
- #: classes/ad_placements.php:304
2561
  msgid "image (%s)"
2562
  msgstr ""
2563
 
2564
  #. translators: %s is an html tag.
2565
- #: classes/ad_placements.php:306
2566
  msgid "table (%s)"
2567
  msgstr ""
2568
 
2569
  #. translators: %s is an html tag.
2570
- #: classes/ad_placements.php:308
2571
  msgid "list item (%s)"
2572
  msgstr ""
2573
 
2574
  #. translators: %s is an html tag.
2575
- #: classes/ad_placements.php:310
2576
  msgid "quote (%s)"
2577
  msgstr ""
2578
 
2579
  #. translators: %s is an html tag.
2580
- #: classes/ad_placements.php:312
2581
  msgid "iframe (%s)"
2582
  msgstr ""
2583
 
2584
  #. translators: %s is an html tag.
2585
- #: classes/ad_placements.php:314
2586
  msgid "container (%s)"
2587
  msgstr ""
2588
 
2589
- #: classes/ad_placements.php:316
2590
  msgid "any element"
2591
  msgstr ""
2592
 
2593
- #: classes/ad_placements.php:318
2594
  msgctxt "for the \"custom\" content placement option"
2595
  msgid "custom"
2596
  msgstr ""
2597
 
2598
  #. translators: %s stands for the name of the "Disable level limitation" option and automatically translated as well
2599
- #: classes/ad_placements.php:995
2600
  msgid "Set <em>%s</em> to show more ads"
2601
  msgstr ""
2602
 
@@ -3020,6 +3042,7 @@ msgid "Something is off"
3020
  msgstr ""
3021
 
3022
  #: classes/frontend_checks.php:804
 
3023
  msgid "PS: This is a one-time check from your friendly Advanced Ads plugin. It is only visible to you."
3024
  msgstr ""
3025
 
@@ -3035,10 +3058,6 @@ msgstr ""
3035
  msgid "I expected something else"
3036
  msgstr ""
3037
 
3038
- #: classes/frontend_checks.php:819
3039
- msgid "PS: this is a one-time check from your friendly Advanced Ads plugin. It is only visible to you."
3040
- msgstr ""
3041
-
3042
  #: classes/frontend_checks.php:822
3043
  #: classes/frontend_checks.php:830
3044
  msgid "Just click on your problem to learn more from our knowledge base."
@@ -3959,7 +3978,7 @@ msgid "When you click the button below Advanced Ads will create an XML file for
3959
  msgstr ""
3960
 
3961
  #: modules/import-export/views/page.php:24
3962
- #: public/class-advanced-ads.php:710
3963
  msgid "Groups"
3964
  msgstr ""
3965
 
@@ -4044,76 +4063,76 @@ msgstr ""
4044
  msgid "Advanced Ads Error: %s"
4045
  msgstr ""
4046
 
4047
- #: public/class-advanced-ads.php:700
4048
  msgctxt "ad group general name"
4049
  msgid "Ad Groups & Rotations"
4050
  msgstr ""
4051
 
4052
- #: public/class-advanced-ads.php:702
4053
  msgid "Search Ad Groups"
4054
  msgstr ""
4055
 
4056
- #: public/class-advanced-ads.php:703
4057
  msgid "All Ad Groups"
4058
  msgstr ""
4059
 
4060
- #: public/class-advanced-ads.php:704
4061
  msgid "Parent Ad Groups"
4062
  msgstr ""
4063
 
4064
- #: public/class-advanced-ads.php:705
4065
  msgid "Parent Ad Groups:"
4066
  msgstr ""
4067
 
4068
- #: public/class-advanced-ads.php:706
4069
  msgid "Edit Ad Group"
4070
  msgstr ""
4071
 
4072
- #: public/class-advanced-ads.php:707
4073
  msgid "Update Ad Group"
4074
  msgstr ""
4075
 
4076
- #: public/class-advanced-ads.php:708
4077
  msgid "Add New Ad Group"
4078
  msgstr ""
4079
 
4080
- #: public/class-advanced-ads.php:709
4081
  msgid "New Ad Groups Name"
4082
  msgstr ""
4083
 
4084
- #: public/class-advanced-ads.php:711
4085
  msgid "No Ad Group found"
4086
  msgstr ""
4087
 
4088
- #: public/class-advanced-ads.php:741
4089
  msgid "Edit Ad"
4090
  msgstr ""
4091
 
4092
- #: public/class-advanced-ads.php:743
4093
  msgid "View"
4094
  msgstr ""
4095
 
4096
- #: public/class-advanced-ads.php:744
4097
  msgid "View the Ad"
4098
  msgstr ""
4099
 
4100
- #: public/class-advanced-ads.php:745
4101
  msgid "Search Ads"
4102
  msgstr ""
4103
 
4104
- #: public/class-advanced-ads.php:746
4105
  msgid "No Ads found"
4106
  msgstr ""
4107
 
4108
- #: public/class-advanced-ads.php:747
4109
  msgid "No Ads found in Trash"
4110
  msgstr ""
4111
 
4112
- #: public/class-advanced-ads.php:748
4113
  msgid "Parent Ad"
4114
  msgstr ""
4115
 
4116
- #: public/class-advanced-ads.php:887
4117
  msgctxt "label above ads"
4118
  msgid "Advertisements"
4119
  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.19.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: 2020-08-05T08:31:33+00: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"
32
  msgid "Thomas Maier, Advanced Ads GmbH"
33
  msgstr ""
34
 
35
+ #: admin/class-advanced-ads-admin.php:223
36
  #: classes/display-conditions.php:290
37
  #: classes/visitor-conditions.php:311
38
  #: modules/gadsense/admin/views/external-ads-links.php:17
41
  msgid "or"
42
  msgstr ""
43
 
44
+ #: admin/class-advanced-ads-admin.php:224
45
  #: classes/display-conditions.php:290
46
  #: classes/visitor-conditions.php:311
47
  msgid "and"
48
  msgstr ""
49
 
50
+ #: admin/class-advanced-ads-admin.php:225
51
  msgid "After which paragraph?"
52
  msgstr ""
53
 
54
+ #: admin/class-advanced-ads-admin.php:227
55
  msgid "Today"
56
  msgstr ""
57
 
58
+ #: admin/class-advanced-ads-admin.php:228
59
  msgid "Yesterday"
60
  msgstr ""
61
 
62
+ #: admin/class-advanced-ads-admin.php:229
63
  msgid "This Month"
64
  msgstr ""
65
 
66
  #. translators: 1: The number of days.
67
+ #: admin/class-advanced-ads-admin.php:231
68
  msgid "Last %1$d days"
69
  msgstr ""
70
 
71
+ #: admin/class-advanced-ads-admin.php:234
72
  msgid "All"
73
  msgstr ""
74
 
75
+ #: admin/class-advanced-ads-admin.php:235
76
  msgid "There were no results returned for this ad. Please make sure it is active, generating impressions and double check your ad parameters."
77
  msgstr ""
78
 
79
+ #: admin/class-advanced-ads-admin.php:236
80
  #: modules/gadsense/admin/views/external-ads-list.php:33
81
  msgid "Show inactive ads"
82
  msgstr ""
83
 
84
+ #: admin/class-advanced-ads-admin.php:237
85
  msgid "Hide inactive ads"
86
  msgstr ""
87
 
88
  #. translators: time zone name.
89
+ #: admin/class-advanced-ads-admin.php:351
90
  msgid "time of %s"
91
  msgstr ""
92
 
93
+ #: admin/class-advanced-ads-admin.php:422
94
  #: admin/includes/class-menu.php:156
95
  #: admin/includes/class-menu.php:159
96
  #: admin/views/settings.php:29
97
  msgid "Support"
98
  msgstr ""
99
 
100
+ #: admin/class-advanced-ads-admin.php:426
101
  #: admin/includes/class-overview-widgets.php:71
102
  msgid "Add-Ons"
103
  msgstr ""
104
 
105
  #. translators: %s is the URL to add a new review, https://wordpress.org/support/plugin/advanced-ads/reviews/#new-post
106
  #. translators: %s is a URL.
107
+ #: admin/class-advanced-ads-admin.php:697
108
  #: admin/includes/class-overview-widgets.php:194
109
  msgid "Thank the developer with a &#9733;&#9733;&#9733;&#9733;&#9733; review on <a href=\"%s\" target=\"_blank\">wordpress.org</a>"
110
  msgstr ""
122
  #. translators: %s is a list of PHP extensions.
123
  #. translators: %s is a name of a module.
124
  #: admin/includes/ad-health-notices.php:54
125
+ #: admin/views/placements.php:233
126
  msgid "Missing PHP extensions could cause issues. Please ask your hosting provider to enable them: %s"
127
  msgstr ""
128
 
317
  #: modules/import-export/classes/import.php:146
318
  #: modules/import-export/classes/import.php:186
319
  #: modules/import-export/classes/import.php:564
320
+ #: public/class-advanced-ads.php:743
321
  msgid "Edit"
322
  msgstr ""
323
 
514
  msgid "License couldn’t be deactivated. Please try again later."
515
  msgstr ""
516
 
517
+ #: admin/includes/class-licenses.php:599
518
  msgid "Download failed. <a href=\"%s\">Click here to try another method</a>."
519
  msgstr ""
520
 
521
+ #: admin/includes/class-licenses.php:601
522
  msgid "Download failed. <a href=\"%s\" target=\"_blank\">Click here to learn why</a>."
523
  msgstr ""
524
 
549
  #: admin/views/ad-group-list-form-row.php:91
550
  #: admin/views/ad-group-list-header.php:16
551
  #: admin/views/placement-form.php:88
552
+ #: admin/views/placements-item.php:26
553
  #: classes/widget.php:129
554
  #: modules/gutenberg/includes/class-gutenberg.php:79
555
  #: modules/import-export/views/page.php:23
556
+ #: public/class-advanced-ads.php:739
557
  msgid "Ads"
558
  msgstr ""
559
 
560
  #: admin/includes/class-menu.php:112
561
+ #: public/class-advanced-ads.php:742
562
  msgid "Add New Ad"
563
  msgstr ""
564
 
565
  #: admin/includes/class-menu.php:113
566
  #: admin/views/ad-group-list-ads.php:36
567
+ #: public/class-advanced-ads.php:741
568
+ #: public/class-advanced-ads.php:745
569
  msgid "New Ad"
570
  msgstr ""
571
 
583
 
584
  #: admin/includes/class-menu.php:132
585
  #: admin/includes/class-shortcode-creator.php:115
586
+ #: admin/views/placements.php:54
587
  #: classes/widget.php:115
588
  #: modules/gutenberg/includes/class-gutenberg.php:81
589
  #: modules/import-export/views/page.php:25
604
  msgid "Licenses"
605
  msgstr ""
606
 
607
+ #: admin/includes/class-menu.php:283
608
+ #: admin/includes/class-menu.php:308
609
  msgid "Sorry, you are not allowed to access this feature."
610
  msgstr ""
611
 
612
+ #: admin/includes/class-menu.php:295
613
  msgid "You attempted to edit an ad group that doesn&#8217;t exist. Perhaps it was deleted?"
614
  msgstr ""
615
 
632
  msgstr ""
633
 
634
  #: admin/includes/class-meta-box.php:104
635
+ #: admin/views/placements.php:273
636
  #: classes/ad-debug.php:152
637
  msgid "Display Conditions"
638
  msgstr ""
639
 
640
  #: admin/includes/class-meta-box.php:112
641
+ #: admin/views/placements.php:282
642
  #: classes/ad-debug.php:239
643
  msgid "Visitor Conditions"
644
  msgstr ""
937
  msgstr ""
938
 
939
  #: admin/includes/class-settings.php:163
940
+ #: classes/ad_placements.php:1017
941
  msgid "Disable level limitation"
942
  msgstr ""
943
 
1007
 
1008
  #: admin/includes/class-shortcode-creator.php:108
1009
  #: admin/views/placement-form.php:81
1010
+ #: admin/views/placements-item.php:14
1011
  #: classes/widget.php:122
1012
  #: modules/gutenberg/includes/class-gutenberg.php:80
1013
  msgid "Ad Groups"
1162
  #: classes/ad-debug.php:118
1163
  #: classes/ad-debug.php:167
1164
  #: classes/ad-debug.php:169
1165
+ #: public/class-advanced-ads.php:740
1166
  msgid "Ad"
1167
  msgstr ""
1168
 
1176
  msgstr ""
1177
 
1178
  #: admin/views/ad-group-list-form-row.php:31
1179
+ #: admin/views/placements.php:66
1180
  #: modules/gadsense/admin/views/external-ads-list.php:45
1181
  #: modules/gadsense/admin/views/external-ads-list.php:55
1182
  #: modules/privacy/admin/views/setting-consent-method.php:9
1184
  msgstr ""
1185
 
1186
  #: admin/views/ad-group-list-form-row.php:56
1187
+ #: admin/views/placements.php:61
1188
  #: modules/gadsense/admin/views/adsense-ad-parameters.php:105
1189
  msgid "Type"
1190
  msgstr ""
1213
 
1214
  #: admin/views/ad-group-list-row.php:22
1215
  #: admin/views/ad-info.php:7
1216
+ #: admin/views/placements.php:168
1217
  msgid "shortcode"
1218
  msgstr ""
1219
 
1370
  #: admin/views/placements-ad-label-position.php:13
1371
  #: admin/views/placements-ad-label.php:9
1372
  #: admin/views/placements-ad-label.php:11
1373
+ #: admin/views/placements.php:150
1374
  #: modules/gadsense/includes/class-network-adsense.php:324
1375
  msgid "default"
1376
  msgstr ""
1504
  msgstr ""
1505
 
1506
  #. translators: %1$s month, %2$s day, %3$s year, %4$s hour, %5$s minute.
1507
+ #: admin/views/ad-submitbox-meta.php:39
1508
  msgctxt "order of expiry date fields 1: month, 2: day, 3: year, 4: hour, 5: minute"
1509
  msgid "%1$s %2$s, %3$s @ %4$s %5$s"
1510
  msgstr ""
1804
  msgstr ""
1805
 
1806
  #: admin/views/placement-form.php:79
1807
+ #: admin/views/placements-item.php:12
1808
  msgid "--not selected--"
1809
  msgstr ""
1810
 
1854
  msgstr ""
1855
 
1856
  #: admin/views/placement-injection-top.php:79
1857
+ #: classes/ad_placements.php:70
1858
  msgid "Before Content"
1859
  msgstr ""
1860
 
1861
  #: admin/views/placement-injection-top.php:80
1862
+ #: classes/ad_placements.php:94
1863
  msgid "Content"
1864
  msgstr ""
1865
 
1866
  #: admin/views/placement-injection-top.php:81
1867
+ #: classes/ad_placements.php:82
1868
  msgid "After Content"
1869
  msgstr ""
1870
 
1942
  msgid "disabled"
1943
  msgstr ""
1944
 
1945
+ #: admin/views/placements-content-index.php:45
1946
  msgid "use xpath, e.g. `p[not(parent::blockquote)]`"
1947
  msgstr ""
1948
 
1949
+ #: admin/views/placements-content-index.php:46
1950
+ msgctxt "frontend picker"
1951
+ msgid "stop selection"
1952
+ msgstr ""
1953
+
1954
+ #: admin/views/placements-content-index.php:47
1955
+ msgid "select position"
1956
+ msgstr ""
1957
+
1958
+ #: admin/views/placements-content-index.php:55
1959
  msgid "start counting from bottom"
1960
  msgstr ""
1961
 
1962
+ #. translators: %s is the name of a language in English
1963
+ #: admin/views/placements-item.php:76
1964
+ msgid "The ad is not translated into %s"
1965
+ msgstr ""
1966
+
1967
+ #: admin/views/placements.php:13
1968
  msgid "Couldn’t create the new placement. Please check your form field and whether the name is already in use."
1969
  msgstr ""
1970
 
1971
+ #: admin/views/placements.php:17
1972
  msgid "Placements updated"
1973
  msgstr ""
1974
 
1975
+ #: admin/views/placements.php:23
1976
+ #: admin/views/placements.php:361
1977
  msgid "Create a new placement"
1978
  msgstr ""
1979
 
1980
+ #: admin/views/placements.php:24
1981
+ #: admin/views/placements.php:363
1982
  msgid "New Placement"
1983
  msgstr ""
1984
 
1985
+ #: admin/views/placements.php:29
1986
  msgid "Placements are physically places in your theme and posts. You can use them if you plan to change ads and ad groups on the same place without the need to change your templates."
1987
  msgstr ""
1988
 
1989
  #. translators: %s is a URL.
1990
+ #: admin/views/placements.php:35
1991
  msgid "See also the manual for more information on <a href=\"%s\">placements</a>."
1992
  msgstr ""
1993
 
1994
+ #: admin/views/placements.php:71
1995
  #: modules/import-export/views/page.php:26
1996
  msgid "Options"
1997
  msgstr ""
1998
 
1999
  #. translators: %s is the name of a placement.
2000
+ #: admin/views/placements.php:129
2001
  msgid "Placement type \"%s\" is missing and was reset to \"default\".<br/>Please check if the responsible add-on is activated."
2002
  msgstr ""
2003
 
2004
+ #: admin/views/placements.php:159
2005
  msgid "show usage"
2006
  msgstr ""
2007
 
2008
+ #: admin/views/placements.php:171
2009
  msgid "template (PHP)"
2010
  msgstr ""
2011
 
2012
+ #: admin/views/placements.php:192
2013
  msgid "Item"
2014
  msgstr ""
2015
 
2016
+ #: admin/views/placements.php:209
2017
  msgid "after"
2018
  msgstr ""
2019
 
2020
+ #: admin/views/placements.php:210
2021
  msgid "before"
2022
  msgstr ""
2023
 
2024
+ #: admin/views/placements.php:223
2025
  msgid "position"
2026
  msgstr ""
2027
 
2028
+ #: admin/views/placements.php:229
2029
  msgid "Important Notice"
2030
  msgstr ""
2031
 
2032
+ #: admin/views/placements.php:262
2033
  msgid "ad label"
2034
  msgstr ""
2035
 
2036
+ #: admin/views/placements.php:275
2037
  msgid "Use display conditions for placements."
2038
  msgstr ""
2039
 
2040
+ #: admin/views/placements.php:276
2041
+ #: admin/views/placements.php:285
2042
  msgid "The free version provides conditions on the ad edit page."
2043
  msgstr ""
2044
 
2045
+ #: admin/views/placements.php:284
2046
  msgid "Use visitor conditions for placements."
2047
  msgstr ""
2048
 
2049
+ #: admin/views/placements.php:291
2050
  msgid "Minimum Content Length"
2051
  msgstr ""
2052
 
2053
+ #: admin/views/placements.php:293
2054
  msgid "Minimum length of content before automatically injected ads are allowed in them."
2055
  msgstr ""
2056
 
2057
+ #: admin/views/placements.php:299
2058
  msgid "Words Between Ads"
2059
  msgstr ""
2060
 
2061
+ #: admin/views/placements.php:301
2062
  msgid "A minimum amount of words between automatically injected ads."
2063
  msgstr ""
2064
 
2065
+ #: admin/views/placements.php:311
2066
  msgid "show all options"
2067
  msgstr ""
2068
 
2069
  #. translators: %s is a URL.
2070
+ #: admin/views/placements.php:332
2071
  msgid "Tutorial: <a href=\"%s\" target=\"_blank\">How to place visible ads in the header of your website</a>."
2072
  msgstr ""
2073
 
2074
+ #: admin/views/placements.php:352
2075
  msgctxt "checkbox to remove placement"
2076
  msgid "delete"
2077
  msgstr ""
2078
 
2079
+ #: admin/views/placements.php:359
2080
  msgid "Save Placements"
2081
  msgstr ""
2082
 
2383
  msgstr ""
2384
 
2385
  #: admin/views/upgrades/pro-placements.php:43
2386
+ msgid "BuddyBoss Content"
2387
  msgstr ""
2388
 
2389
  #: admin/views/upgrades/pro-placements.php:44
2390
+ msgid "Display ads on BuddyBoss related pages."
2391
+ msgstr ""
2392
+
2393
+ #: admin/views/upgrades/pro-placements.php:49
2394
+ msgid "BuddyPress Content"
2395
+ msgstr ""
2396
+
2397
+ #: admin/views/upgrades/pro-placements.php:50
2398
  msgid "Display ads on BuddyPress related pages."
2399
  msgstr ""
2400
 
2401
+ #: admin/views/upgrades/pro-placements.php:57
2402
  msgid "bbPress Content"
2403
  msgstr ""
2404
 
2405
+ #: admin/views/upgrades/pro-placements.php:58
2406
  msgid "Display ads in content created with bbPress."
2407
  msgstr ""
2408
 
2484
  msgstr ""
2485
 
2486
  #: classes/ad-debug.php:121
2487
+ #: public/class-advanced-ads.php:704
2488
  msgctxt "ad group singular name"
2489
  msgid "Ad Group"
2490
  msgstr ""
2500
  msgstr ""
2501
 
2502
  #. translators: %s is a URL.
2503
+ #: classes/ad_ajax_callbacks.php:258
2504
  msgid "An error occurred. Please use <a href=\"%s\" target=\"_blank\">this form</a> to sign up."
2505
  msgstr ""
2506
 
2512
  msgid "Manual placement to use as function or shortcode."
2513
  msgstr ""
2514
 
2515
+ #: classes/ad_placements.php:57
2516
  msgid "Header Code"
2517
  msgstr ""
2518
 
2519
+ #: classes/ad_placements.php:58
2520
  msgid "Injected in Header (before closing &lt;/head&gt; Tag, often not visible)."
2521
  msgstr ""
2522
 
2523
+ #: classes/ad_placements.php:63
2524
  msgid "Footer Code"
2525
  msgstr ""
2526
 
2527
+ #: classes/ad_placements.php:64
2528
  msgid "Injected in Footer (before closing &lt;/body&gt; Tag)."
2529
  msgstr ""
2530
 
2531
+ #: classes/ad_placements.php:71
2532
  msgid "Injected before the post content."
2533
  msgstr ""
2534
 
2535
+ #: classes/ad_placements.php:83
2536
  msgid "Injected after the post content."
2537
  msgstr ""
2538
 
2539
+ #: classes/ad_placements.php:95
2540
  msgid "Injected into the content. You can choose the paragraph after which the ad content is displayed."
2541
  msgstr ""
2542
 
2543
+ #: classes/ad_placements.php:106
2544
  msgid "Sidebar Widget"
2545
  msgstr ""
2546
 
2547
+ #: classes/ad_placements.php:107
2548
  msgid "Create a sidebar widget with an ad. Can be placed and used like any other widget."
2549
  msgstr ""
2550
 
2551
  #. translators: %s is an html tag.
2552
+ #: classes/ad_placements.php:299
2553
  msgid "paragraph (%s)"
2554
  msgstr ""
2555
 
2556
  #. translators: %s is an html tag.
2557
+ #: classes/ad_placements.php:301
2558
  msgid "paragraph without image (%s)"
2559
  msgstr ""
2560
 
2561
  #. translators: %s is an html tag.
2562
+ #: classes/ad_placements.php:303
2563
  msgid "headline 2 (%s)"
2564
  msgstr ""
2565
 
2566
  #. translators: %s is an html tag.
2567
+ #: classes/ad_placements.php:305
2568
  msgid "headline 3 (%s)"
2569
  msgstr ""
2570
 
2571
  #. translators: %s is an html tag.
2572
+ #: classes/ad_placements.php:307
2573
  msgid "headline 4 (%s)"
2574
  msgstr ""
2575
 
2576
  #. translators: %s is an html tag.
2577
+ #: classes/ad_placements.php:309
2578
  msgid "any headline (%s)"
2579
  msgstr ""
2580
 
2581
  #. translators: %s is an html tag.
2582
+ #: classes/ad_placements.php:311
2583
  msgid "image (%s)"
2584
  msgstr ""
2585
 
2586
  #. translators: %s is an html tag.
2587
+ #: classes/ad_placements.php:313
2588
  msgid "table (%s)"
2589
  msgstr ""
2590
 
2591
  #. translators: %s is an html tag.
2592
+ #: classes/ad_placements.php:315
2593
  msgid "list item (%s)"
2594
  msgstr ""
2595
 
2596
  #. translators: %s is an html tag.
2597
+ #: classes/ad_placements.php:317
2598
  msgid "quote (%s)"
2599
  msgstr ""
2600
 
2601
  #. translators: %s is an html tag.
2602
+ #: classes/ad_placements.php:319
2603
  msgid "iframe (%s)"
2604
  msgstr ""
2605
 
2606
  #. translators: %s is an html tag.
2607
+ #: classes/ad_placements.php:321
2608
  msgid "container (%s)"
2609
  msgstr ""
2610
 
2611
+ #: classes/ad_placements.php:323
2612
  msgid "any element"
2613
  msgstr ""
2614
 
2615
+ #: classes/ad_placements.php:325
2616
  msgctxt "for the \"custom\" content placement option"
2617
  msgid "custom"
2618
  msgstr ""
2619
 
2620
  #. translators: %s stands for the name of the "Disable level limitation" option and automatically translated as well
2621
+ #: classes/ad_placements.php:1016
2622
  msgid "Set <em>%s</em> to show more ads"
2623
  msgstr ""
2624
 
3042
  msgstr ""
3043
 
3044
  #: classes/frontend_checks.php:804
3045
+ #: classes/frontend_checks.php:819
3046
  msgid "PS: This is a one-time check from your friendly Advanced Ads plugin. It is only visible to you."
3047
  msgstr ""
3048
 
3058
  msgid "I expected something else"
3059
  msgstr ""
3060
 
 
 
 
 
3061
  #: classes/frontend_checks.php:822
3062
  #: classes/frontend_checks.php:830
3063
  msgid "Just click on your problem to learn more from our knowledge base."
3978
  msgstr ""
3979
 
3980
  #: modules/import-export/views/page.php:24
3981
+ #: public/class-advanced-ads.php:713
3982
  msgid "Groups"
3983
  msgstr ""
3984
 
4063
  msgid "Advanced Ads Error: %s"
4064
  msgstr ""
4065
 
4066
+ #: public/class-advanced-ads.php:703
4067
  msgctxt "ad group general name"
4068
  msgid "Ad Groups & Rotations"
4069
  msgstr ""
4070
 
4071
+ #: public/class-advanced-ads.php:705
4072
  msgid "Search Ad Groups"
4073
  msgstr ""
4074
 
4075
+ #: public/class-advanced-ads.php:706
4076
  msgid "All Ad Groups"
4077
  msgstr ""
4078
 
4079
+ #: public/class-advanced-ads.php:707
4080
  msgid "Parent Ad Groups"
4081
  msgstr ""
4082
 
4083
+ #: public/class-advanced-ads.php:708
4084
  msgid "Parent Ad Groups:"
4085
  msgstr ""
4086
 
4087
+ #: public/class-advanced-ads.php:709
4088
  msgid "Edit Ad Group"
4089
  msgstr ""
4090
 
4091
+ #: public/class-advanced-ads.php:710
4092
  msgid "Update Ad Group"
4093
  msgstr ""
4094
 
4095
+ #: public/class-advanced-ads.php:711
4096
  msgid "Add New Ad Group"
4097
  msgstr ""
4098
 
4099
+ #: public/class-advanced-ads.php:712
4100
  msgid "New Ad Groups Name"
4101
  msgstr ""
4102
 
4103
+ #: public/class-advanced-ads.php:714
4104
  msgid "No Ad Group found"
4105
  msgstr ""
4106
 
4107
+ #: public/class-advanced-ads.php:744
4108
  msgid "Edit Ad"
4109
  msgstr ""
4110
 
4111
+ #: public/class-advanced-ads.php:746
4112
  msgid "View"
4113
  msgstr ""
4114
 
4115
+ #: public/class-advanced-ads.php:747
4116
  msgid "View the Ad"
4117
  msgstr ""
4118
 
4119
+ #: public/class-advanced-ads.php:748
4120
  msgid "Search Ads"
4121
  msgstr ""
4122
 
4123
+ #: public/class-advanced-ads.php:749
4124
  msgid "No Ads found"
4125
  msgstr ""
4126
 
4127
+ #: public/class-advanced-ads.php:750
4128
  msgid "No Ads found in Trash"
4129
  msgstr ""
4130
 
4131
+ #: public/class-advanced-ads.php:751
4132
  msgid "Parent Ad"
4133
  msgstr ""
4134
 
4135
+ #: public/class-advanced-ads.php:890
4136
  msgctxt "label above ads"
4137
  msgid "Advertisements"
4138
  msgstr ""
public/assets/js/advanced.js CHANGED
@@ -1 +1 @@
1
- advads={supports_localstorage:function(){"use strict";try{if(!window||window.localStorage===undefined){return false}window.localStorage.setItem("x","x");window.localStorage.removeItem("x");return true}catch(e){return false}},max_per_session:function(name,max){var num=1;if(max===undefined||parseInt(max)===0){max=1}if(this.cookie_exists(name)){if(this.get_cookie(name)>=max){return true}num=num+parseInt(this.get_cookie(name))}this.set_cookie(name,num);return false},count_up:function(name,exdays){var num=1;if(this.cookie_exists(name)){num=num+parseInt(this.get_cookie(name))}this.set_cookie(name,num)},set_cookie_exists:function(name){if(get_cookie(name)){return true}set_cookie(name,"",0);return false},get_cookie:function(name){var i,x,y,ADVcookies=document.cookie.split(";");for(i=0;i<ADVcookies.length;i++){x=ADVcookies[i].substr(0,ADVcookies[i].indexOf("="));y=ADVcookies[i].substr(ADVcookies[i].indexOf("=")+1);x=x.replace(/^\s+|\s+$/g,"");if(x===name){return unescape(y)}}},set_cookie:function(name,value,exdays,path,domain,secure){var expiry=exdays==null?null:exdays*24*60*60;this.set_cookie_sec(name,value,expiry,path,domain,secure)},set_cookie_sec:function(name,value,expiry,path,domain,secure){var exdate=new Date;exdate.setSeconds(exdate.getSeconds()+parseInt(expiry));document.cookie=name+"="+escape(value)+(expiry==null?"":"; expires="+exdate.toUTCString())+(path==null?"; path=/":"; path="+path)+(domain==null?"":"; domain="+domain)+(secure==null?"":"; secure")},cookie_exists:function(name){var c_value=this.get_cookie(name);if(c_value!==null&&c_value!==""&&c_value!==undefined){return true}return false},move:function(element,target,options){var el=jQuery(element);var target_string=target;if(typeof options==="undefined"){options={}}if(typeof options.css==="undefined"){options.css={}}if(typeof options.method==="undefined"){options.method="prependTo"}if(target===""&&typeof options.target!=="undefined"){switch(options.target){case"wrapper":var offset="left";if(typeof options.offset!=="undefined"){offset=options.offset}target=this.find_wrapper(element,offset);break}}if(typeof options.moveintohidden==="undefined"){target=jQuery(target).filter(":visible")}else{target=jQuery(target)}if(target.length>1){console.log("Advanced Ads: element '"+target_string+"' found "+target.length+" times.")}switch(options.method){case"insertBefore":el.insertBefore(target);break;case"insertAfter":el.insertAfter(target);break;case"appendTo":el.appendTo(target);break;case"prependTo":el.prependTo(target);break;default:el.prependTo(target)}},set_parent_relative:function(element,options){var options=typeof options!=="undefined"?options:{};var el=jQuery(element);var parent=el.parent();if(options.use_grandparent){parent=parent.parent()}if(parent.css("position")==="static"||parent.css("position")===""){parent.css("position","relative")}},fix_element:function(element,options){var options=typeof options!=="undefined"?options:{};var el=jQuery(element);if(options.use_grandparent){this.set_parent_relative(el.parent())}else{this.set_parent_relative(el)}if(options.is_invisible){el.show()}var topoffset=parseInt(el.offset().top);var leftoffset=parseInt(el.offset().left);if(options.is_invisible){el.hide()}if("left"===options.offset){var rightoffset=jQuery(window).width()-leftoffset-el.outerWidth();el.css("position","fixed").css("top",topoffset+"px").css("right",rightoffset+"px").css("left","")}else{el.css("position","fixed").css("top",topoffset+"px").css("left",leftoffset+"px").css("right","")}},find_wrapper:function(element,offset){var returnValue;jQuery("body").children().each(function(key,value){if(value.id!==element.substring(1)){var checkedelement=jQuery(value);if(offset==="right"&&checkedelement.offset().left+jQuery(checkedelement).width()<jQuery(window).width()||offset==="left"&&checkedelement.offset().left>0){if(checkedelement.css("position")==="static"||checkedelement.css("position")===""){checkedelement.css("position","relative")}returnValue=value;return false}}});return returnValue},center_fixed_element:function(element){var el=jQuery(element);var left=jQuery(window).width()/2-parseInt(el.css("width"))/2;el.css("left",left+"px")},center_vertically:function(element){var el=jQuery(element);var left=jQuery(window).height()/2-parseInt(el.css("height"))/2;if(el.css("position")!=="fixed"){left-=topoffset=parseInt(el.offset().top)}el.css("top",left+"px")},close:function(element){var wrapper=jQuery(element);wrapper.remove()},wait_for_images:function($el,ready_callback){var loaded_count=0;var srcs=[];$el.find('img[src][src!=""]').each(function(){srcs.push(this.src)});if(srcs.length===0){ready_callback.call($el)}jQuery.each(srcs,function(i,src){var image=new Image;image.src=src;var events="load error";jQuery(image).one(events,function me(event){jQuery(this).off(events,me);loaded_count++;if(loaded_count==srcs.length){ready_callback.call($el[0]);return false}})})},privacy:{get_state:function(){if(!window.advads_options||!window.advads_options.privacy){return"not_needed"}var options=window.advads_options.privacy;if(!options.enabled){return"not_needed"}var method=options["consent-method"]?options["consent-method"]:"0";switch(method){case"0":return"not_needed";break;case"custom":if(options["custom-cookie-value"===undefined]||options["custom-cookie-value"]===undefined){return"not_needed"}var found=advads.get_cookie(options["custom-cookie-name"]);if(typeof found!=="string"){return"unknown"}if(options["custom-cookie-value"]===""&&found===""||options["custom-cookie-value"]!==""&&found.indexOf(options["custom-cookie-value"])!==-1){return"accepted"}return"unknown";break;default:return advads.cookie_exists(method)?"accepted":"unknown"}},is_adsense_npa_enabled:function(){if(!window.advads_options||!window.advads_options.privacy){return true}var options=window.advads_options.privacy;return!!options["show-non-personalized-adsense"]}}};jQuery(document).ready(function(){if(advads.supports_localstorage()&&localStorage.getItem("advads_frontend_picker")){var advads_picker_cur,advads_picker_overlay=jQuery("<div id='advads-picker-overlay'>"),advads_picker_no=[document.body,document.documentElement,document];advads_picker_overlay.css({position:"absolute",border:"solid 2px #428bca",backgroundColor:"rgba(66,139,202,0.5)",boxSizing:"border-box",zIndex:1e6,pointerEvents:"none"}).prependTo("body");jQuery(document).mousemove(function(e){if(e.target===advads_picker_cur){return}if(~advads_picker_no.indexOf(e.target)){advads_picker_cur=null;advads_picker_overlay.hide();return}var target=jQuery(e.target),offset=target.offset(),width=target.outerWidth(),height=target.outerHeight();advads_picker_cur=e.target;advads_picker_overlay.css({top:offset.top,left:offset.left,width:width,height:height}).show();console.log(jQuery(advads_picker_cur).getPath())});jQuery(document).click(function(e){var path=jQuery(advads_picker_cur).getPath();localStorage.setItem("advads_frontend_element",path);window.location=localStorage.getItem("advads_prev_url")})}});jQuery.fn.extend({getPath:function(path,depth){if(typeof path==="undefined")path="";if(typeof depth==="undefined")depth=0;if(this.is("html")){return"html > "+path}else if(3===depth){return path}var cur=this.get(0).nodeName.toLowerCase();var el_id=this.attr("id"),el_class=this.attr("class");depth=depth+1;if(typeof el_id!=="undefined"&&!/\d/.test(el_id)){cur+="#"+el_id}else if(typeof el_class!=="undefined"){el_class=el_class.split(/[\s\n]+/);el_class=jQuery.grep(el_class,function(element,index){return!/\d/.test(element)});if(el_class.length){cur+="."+el_class.slice(0,2).join(".")}}if(this.siblings(cur).length){cur+=":eq("+this.siblings(cur).addBack().not("#advads-picker-overlay").index(this)+")"}if(path===""){return this.parent().getPath(cur,depth)}else{return this.parent().getPath(cur+" > "+path,depth)}}});
1
+ advads={supports_localstorage:function(){"use strict";try{if(!window||window.localStorage===undefined){return false}window.localStorage.setItem("x","x");window.localStorage.removeItem("x");return true}catch(e){return false}},max_per_session:function(name,max){var num=1;if(max===undefined||parseInt(max)===0){max=1}if(this.cookie_exists(name)){if(this.get_cookie(name)>=max){return true}num=num+parseInt(this.get_cookie(name))}this.set_cookie(name,num);return false},count_up:function(name,exdays){var num=1;if(this.cookie_exists(name)){num=num+parseInt(this.get_cookie(name))}this.set_cookie(name,num)},set_cookie_exists:function(name){if(get_cookie(name)){return true}set_cookie(name,"",0);return false},get_cookie:function(name){var i,x,y,ADVcookies=document.cookie.split(";");for(i=0;i<ADVcookies.length;i++){x=ADVcookies[i].substr(0,ADVcookies[i].indexOf("="));y=ADVcookies[i].substr(ADVcookies[i].indexOf("=")+1);x=x.replace(/^\s+|\s+$/g,"");if(x===name){return unescape(y)}}},set_cookie:function(name,value,exdays,path,domain,secure){var expiry=exdays==null?null:exdays*24*60*60;this.set_cookie_sec(name,value,expiry,path,domain,secure)},set_cookie_sec:function(name,value,expiry,path,domain,secure){var exdate=new Date;exdate.setSeconds(exdate.getSeconds()+parseInt(expiry));document.cookie=name+"="+escape(value)+(expiry==null?"":"; expires="+exdate.toUTCString())+(path==null?"; path=/":"; path="+path)+(domain==null?"":"; domain="+domain)+(secure==null?"":"; secure")},cookie_exists:function(name){var c_value=this.get_cookie(name);if(c_value!==null&&c_value!==""&&c_value!==undefined){return true}return false},move:function(element,target,options){var el=jQuery(element);var target_string=target;if(typeof options==="undefined"){options={}}if(typeof options.css==="undefined"){options.css={}}if(typeof options.method==="undefined"){options.method="prependTo"}if(target===""&&typeof options.target!=="undefined"){switch(options.target){case"wrapper":var offset="left";if(typeof options.offset!=="undefined"){offset=options.offset}target=this.find_wrapper(element,offset);break}}if(typeof options.moveintohidden==="undefined"){target=jQuery(target).filter(":visible")}else{target=jQuery(target)}if(target.length>1){console.log("Advanced Ads: element '"+target_string+"' found "+target.length+" times.")}switch(options.method){case"insertBefore":el.insertBefore(target);break;case"insertAfter":el.insertAfter(target);break;case"appendTo":el.appendTo(target);break;case"prependTo":el.prependTo(target);break;default:el.prependTo(target)}},set_parent_relative:function(element,options){var options=typeof options!=="undefined"?options:{};var el=jQuery(element);var parent=el.parent();if(options.use_grandparent){parent=parent.parent()}if(parent.css("position")==="static"||parent.css("position")===""){parent.css("position","relative")}},fix_element:function(element,options){var options=typeof options!=="undefined"?options:{};var el=jQuery(element);if(options.use_grandparent){this.set_parent_relative(el.parent())}else{this.set_parent_relative(el)}if(options.is_invisible){el.show()}var topoffset=parseInt(el.offset().top);var leftoffset=parseInt(el.offset().left);if(options.is_invisible){el.hide()}if("left"===options.offset){var rightoffset=jQuery(window).width()-leftoffset-el.outerWidth();el.css("position","fixed").css("top",topoffset+"px").css("right",rightoffset+"px").css("left","")}else{el.css("position","fixed").css("top",topoffset+"px").css("left",leftoffset+"px").css("right","")}},find_wrapper:function(element,offset){var returnValue;jQuery("body").children().each(function(key,value){if(value.id!==element.substring(1)){var checkedelement=jQuery(value);if(offset==="right"&&checkedelement.offset().left+jQuery(checkedelement).width()<jQuery(window).width()||offset==="left"&&checkedelement.offset().left>0){if(checkedelement.css("position")==="static"||checkedelement.css("position")===""){checkedelement.css("position","relative")}returnValue=value;return false}}});return returnValue},center_fixed_element:function(element){var el=jQuery(element);var left=jQuery(window).width()/2-parseInt(el.css("width"))/2;el.css("left",left+"px")},center_vertically:function(element){var el=jQuery(element);var left=jQuery(window).height()/2-parseInt(el.css("height"))/2;if(el.css("position")!=="fixed"){left-=topoffset=parseInt(el.offset().top)}el.css("top",left+"px")},close:function(element){var wrapper=jQuery(element);wrapper.remove()},wait_for_images:function($el,ready_callback){var loaded_count=0;var srcs=[];$el.find('img[src][src!=""]').each(function(){srcs.push(this.src)});if(srcs.length===0){ready_callback.call($el)}jQuery.each(srcs,function(i,src){var image=new Image;image.src=src;var events="load error";jQuery(image).one(events,function me(event){jQuery(this).off(events,me);loaded_count++;if(loaded_count==srcs.length){ready_callback.call($el[0]);return false}})})},privacy:{get_state:function(){if(!window.advads_options||!window.advads_options.privacy){return"not_needed"}var options=window.advads_options.privacy;if(!options.enabled){return"not_needed"}var method=options["consent-method"]?options["consent-method"]:"0";switch(method){case"0":return"not_needed";break;case"custom":if(options["custom-cookie-value"===undefined]||options["custom-cookie-value"]===undefined){return"not_needed"}var found=advads.get_cookie(options["custom-cookie-name"]);if(typeof found!=="string"){return"unknown"}if(options["custom-cookie-value"]===""&&found===""||options["custom-cookie-value"]!==""&&found.indexOf(options["custom-cookie-value"])!==-1){return"accepted"}return"unknown";break;default:return advads.cookie_exists(method)?"accepted":"unknown"}},is_adsense_npa_enabled:function(){if(!window.advads_options||!window.advads_options.privacy){return true}var options=window.advads_options.privacy;return!!options["show-non-personalized-adsense"]}}};jQuery(document).ready(function(){function is_enabled(){if(!advads.supports_localstorage()||!localStorage.getItem("advads_frontend_picker")){return false}if(window.advanced_ads_data&&advanced_ads_data.blog_id&&localStorage.getItem("advads_frontend_blog_id")&&advanced_ads_data.blog_id!==localStorage.getItem("advads_frontend_blog_id")){return false}if(localStorage.getItem("advads_frontend_starttime")&&parseInt(localStorage.getItem("advads_frontend_starttime"),10)<(new Date).getTime()-45*60*1e3){localStorage.removeItem("advads_frontend_action");localStorage.removeItem("advads_frontend_element");localStorage.removeItem("advads_frontend_picker");localStorage.removeItem("advads_prev_url");localStorage.removeItem("advads_frontend_pathtype");localStorage.removeItem("advads_frontend_boundary");localStorage.removeItem("advads_frontend_blog_id");localStorage.removeItem("advads_frontend_starttime");advads.set_cookie("advads_frontend_picker","",-1);return false}return true}if(is_enabled()){var advads_picker_cur,advads_picker_overlay=jQuery("<div id='advads-picker-overlay'>"),advads_picker_no=[document.body,document.documentElement,document];advads_picker_overlay.css({position:"absolute",border:"solid 2px #428bca",backgroundColor:"rgba(66,139,202,0.5)",boxSizing:"border-box",zIndex:1e6,pointerEvents:"none"}).prependTo("body");if("true"===localStorage.getItem("advads_frontend_boundary")){jQuery("body").css("cursor","not-allowed")}window.advads.is_boundary_reached=function(advads_picker_cur){if("true"!==localStorage.getItem("advads_frontend_boundary")){return false}$advads_picker_cur=jQuery(advads_picker_cur);var $boundary_helpers=jQuery(".advads-frontend-picker-boundary-helper");$boundaries=$boundary_helpers.parent();$boundaries.css("cursor","pointer");return $advads_picker_cur.is($boundaries)||!$advads_picker_cur.closest($boundaries).length};if("xpath"===localStorage.getItem("advads_frontend_pathtype")){var fn="getXPath"}else{var fn="getPath"}jQuery(document).mousemove(function(e){if(e.target===advads_picker_cur){return}if(~advads_picker_no.indexOf(e.target)){advads_picker_cur=null;advads_picker_overlay.hide();return}var target=jQuery(e.target),offset=target.offset(),width=target.outerWidth(),height=target.outerHeight();advads_picker_cur=e.target;var path=jQuery(advads_picker_cur)[fn]();if(!path){return}console.log(path);advads_picker_overlay.css({top:offset.top,left:offset.left,width:width,height:height}).show()});jQuery(document).click(function(e){var path=jQuery(advads_picker_cur)[fn]();if(advads.is_boundary_reached(advads_picker_cur)){return}localStorage.setItem("advads_frontend_element",path);window.location=localStorage.getItem("advads_prev_url")})}});jQuery.fn.extend({getPath:function(path,depth){if(typeof path==="undefined")path="";if(typeof depth==="undefined")depth=0;if(this.is("html")){return"html > "+path}else if(3===depth){return path}var cur=this.get(0).nodeName.toLowerCase();var el_id=this.attr("id"),el_class=this.attr("class");depth=depth+1;if(typeof el_id!=="undefined"&&!/\d/.test(el_id)){cur+="#"+el_id}else if(typeof el_class!=="undefined"){el_class=el_class.split(/[\s\n]+/);el_class=jQuery.grep(el_class,function(element,index){return!/\d/.test(element)});if(el_class.length){cur+="."+el_class.slice(0,2).join(".")}}if(this.siblings(cur).length){cur+=":eq("+this.siblings(cur).addBack().not("#advads-picker-overlay").index(this)+")"}if(path===""){return this.parent().getPath(cur,depth)}else{return this.parent().getPath(cur+" > "+path,depth)}},getXPath:function(path,depth){if(typeof path==="undefined")path="";if(typeof depth==="undefined")depth=0;if(this.is("body")||3===depth){return path}if(advads.is_boundary_reached(this)){return path}var tag=this.get(0).nodeName.toLowerCase();var cur=tag;var el_id=this.attr("id"),el_class=this.attr("class");var classes=[];if(typeof el_id!=="undefined"&&!/\d/.test(el_id)){return cur+'[@id and id="'+el_id+'"]/'+path}else if(typeof el_class!=="undefined"){el_class=el_class.split(/[\s\n]+/);el_class=jQuery.grep(el_class,function(element,index){return!/\d/.test(element)});if(el_class.length){depth=depth+1;var classes=el_class.slice(0,2);var xpath_classes=[];for(var i=0;i<classes.length;i++){xpath_classes.push('(@class and contains(concat(" ", normalize-space(@class), " "), " '+classes[i]+' "))')}cur+="["+xpath_classes.join(" and ")+"]"}}if(classes.length){var $siblings=this.siblings(tag+"."+classes.join("."))}else{var $siblings=this.siblings(tag)}if($siblings.length){var index=$siblings.addBack().not("#advads-picker-overlay").index(this);cur+="["+index+"]"}if(path===""){return this.parent().getXPath(cur,depth)}else{return this.parent().getXPath(cur+"/"+path,depth)}}});
public/assets/js/advanced.orig.js CHANGED
@@ -425,13 +425,82 @@ advads = {
425
  };
426
  // highlight elements in frontend, if local storage variable is set
427
  jQuery(document).ready(function(){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
  // only trigger if local storage is available
429
- if( advads.supports_localstorage() && localStorage.getItem('advads_frontend_picker') ) {
430
  var advads_picker_cur, advads_picker_overlay = jQuery("<div id='advads-picker-overlay'>"),
431
  advads_picker_no = [document.body, document.documentElement, document];
432
  advads_picker_overlay.css({position: 'absolute', border: 'solid 2px #428bca',
433
  backgroundColor: 'rgba(66,139,202,0.5)', boxSizing: 'border-box',
434
  zIndex: 1000000, pointerEvents: 'none'}).prependTo('body');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
  jQuery(document).mousemove(function(e) {
436
  if (e.target === advads_picker_cur) {
437
  return;
@@ -450,22 +519,32 @@ jQuery(document).ready(function(){
450
 
451
  advads_picker_cur = e.target;
452
 
 
 
 
 
 
 
 
 
 
453
  advads_picker_overlay.css({
454
  top: offset.top,
455
  left: offset.left,
456
  width: width,
457
  height: height
458
  }).show();
459
- // log path
460
- console.log( jQuery( advads_picker_cur ).getPath());
461
 
462
  });
463
  // save on click
464
  jQuery(document).click(function(e) {
465
- //console.log( advads_picker_cur );
466
- var path = jQuery( advads_picker_cur ).getPath();
 
 
 
 
467
  localStorage.setItem( 'advads_frontend_element', path );
468
- // console.log( jQuery( advads_picker_cur ).getPath() );
469
  window.location = localStorage.getItem('advads_prev_url');
470
  });
471
  };
@@ -527,5 +606,75 @@ jQuery.fn.extend({
527
  } else {
528
  return this.parent().getPath( cur + ' > ' + path, depth );
529
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
530
  }
531
  });
425
  };
426
  // highlight elements in frontend, if local storage variable is set
427
  jQuery(document).ready(function(){
428
+
429
+ function is_enabled() {
430
+ if ( ! advads.supports_localstorage() || ! localStorage.getItem('advads_frontend_picker') ) {
431
+ return false;
432
+ }
433
+
434
+ // Check if the frontend picker was started on the current blog.
435
+ if ( window.advanced_ads_data && advanced_ads_data.blog_id
436
+ && localStorage.getItem( 'advads_frontend_blog_id' )
437
+ && advanced_ads_data.blog_id !== localStorage.getItem( 'advads_frontend_blog_id' ) ) {
438
+ return false;
439
+ }
440
+
441
+
442
+ // Deactivate the frontend picker if it was started more than 45 minutes ago.
443
+ if ( localStorage.getItem( 'advads_frontend_starttime' )
444
+ && parseInt( localStorage.getItem( 'advads_frontend_starttime' ), 10 ) < ( new Date().getTime() ) - 45 * 60 * 1000 ) {
445
+ localStorage.removeItem( 'advads_frontend_action' );
446
+ localStorage.removeItem( 'advads_frontend_element' );
447
+ localStorage.removeItem( 'advads_frontend_picker' );
448
+ localStorage.removeItem( 'advads_prev_url' );
449
+ localStorage.removeItem( 'advads_frontend_pathtype' );
450
+ localStorage.removeItem( 'advads_frontend_boundary' );
451
+ localStorage.removeItem( 'advads_frontend_blog_id' );
452
+ localStorage.removeItem( 'advads_frontend_starttime' );
453
+ advads.set_cookie( 'advads_frontend_picker', '', -1 );
454
+ return false;
455
+ }
456
+
457
+ return true;
458
+ }
459
+
460
  // only trigger if local storage is available
461
+ if ( is_enabled() ) {
462
  var advads_picker_cur, advads_picker_overlay = jQuery("<div id='advads-picker-overlay'>"),
463
  advads_picker_no = [document.body, document.documentElement, document];
464
  advads_picker_overlay.css({position: 'absolute', border: 'solid 2px #428bca',
465
  backgroundColor: 'rgba(66,139,202,0.5)', boxSizing: 'border-box',
466
  zIndex: 1000000, pointerEvents: 'none'}).prependTo('body');
467
+
468
+ if ( 'true' === localStorage.getItem( 'advads_frontend_boundary' ) ) {
469
+ jQuery( 'body' ).css( 'cursor', 'not-allowed' );
470
+ }
471
+
472
+ /**
473
+ * Check if we can traverse up the dom tree.
474
+ *
475
+ * We cannot use event delegation because:
476
+ * - the content can be loaded via AJAX dynamically
477
+ * - we cannot wrap the content in a `div` that represents post boundary
478
+ * because that may prevent css rules from working
479
+ *
480
+ * @param HTMLElement The current element.
481
+ * return bool
482
+ */
483
+ window.advads.is_boundary_reached = function( advads_picker_cur ) {
484
+ if ( 'true' !== localStorage.getItem( 'advads_frontend_boundary' ) ) {
485
+ return false;
486
+ }
487
+ $advads_picker_cur = jQuery( advads_picker_cur );
488
+ // A boundary helper is the `ins` element inside of the post content
489
+ // that is used to determine the post boundary (where the content starts and ends).
490
+ var $boundary_helpers = jQuery( '.advads-frontend-picker-boundary-helper' );
491
+
492
+ $boundaries = $boundary_helpers.parent();
493
+ $boundaries.css( 'cursor', 'pointer' );
494
+ return $advads_picker_cur.is( $boundaries ) || ! $advads_picker_cur.closest( $boundaries ).length;
495
+ }
496
+
497
+ if ( 'xpath' === localStorage.getItem( 'advads_frontend_pathtype' ) ) {
498
+ var fn = 'getXPath';
499
+ } else {
500
+ var fn = 'getPath';
501
+ }
502
+
503
+
504
  jQuery(document).mousemove(function(e) {
505
  if (e.target === advads_picker_cur) {
506
  return;
519
 
520
  advads_picker_cur = e.target;
521
 
522
+ var path = jQuery( advads_picker_cur )[fn]();
523
+ if ( ! path ) {
524
+ // A click outside of the boundary.
525
+ // @see `is_boundary_reached`.
526
+ return;
527
+ }
528
+ //log path
529
+ console.log( path);
530
+
531
  advads_picker_overlay.css({
532
  top: offset.top,
533
  left: offset.left,
534
  width: width,
535
  height: height
536
  }).show();
 
 
537
 
538
  });
539
  // save on click
540
  jQuery(document).click(function(e) {
541
+ var path = jQuery( advads_picker_cur )[fn]();
542
+
543
+ if ( advads.is_boundary_reached( advads_picker_cur )) {
544
+ return;
545
+ }
546
+
547
  localStorage.setItem( 'advads_frontend_element', path );
 
548
  window.location = localStorage.getItem('advads_prev_url');
549
  });
550
  };
606
  } else {
607
  return this.parent().getPath( cur + ' > ' + path, depth );
608
  }
609
+ },
610
+
611
+ /**
612
+ * Get XPath.
613
+ */
614
+ getXPath: function( path, depth ) {
615
+ // The first time this function is called, path won't be defined.
616
+ if ( typeof path === 'undefined' ) path = '';
617
+ if ( typeof depth === 'undefined' ) depth = 0;
618
+
619
+ // If this element is <html> we've reached the end of the path.
620
+ // also end after 2 elements
621
+ if ( this.is('body') || 3 === depth){
622
+ return path;
623
+ }
624
+
625
+ if ( advads.is_boundary_reached( this )) {
626
+ return path;
627
+ }
628
+
629
+ // Add the element name.
630
+ var tag = this.get(0).nodeName.toLowerCase();
631
+ var cur = tag;
632
+
633
+ // Determine the IDs and path.
634
+ var el_id = this.attr('id'),
635
+ el_class = this.attr('class');
636
+ var classes = [];
637
+
638
+ // Add the #id if there is one. Ignore ID with number.
639
+ if ( typeof el_id !== 'undefined' && ! /\d/.test( el_id ) ) {
640
+ return cur + '[@id and id="' + el_id + '"]/' + path;
641
+ } else if ( typeof el_class !== 'undefined' ){
642
+ // Add classes if there is no id.
643
+ el_class = el_class.split( /[\s\n]+/ );
644
+ // Skip classes with numbers.
645
+ el_class = jQuery.grep( el_class, function( element, index ) {
646
+ return ! /\d/.test( element )
647
+ });
648
+ // Add 2 classes.
649
+ if ( el_class.length ) {
650
+ depth = depth + 1;
651
+ var classes = el_class.slice( 0, 2 );
652
+
653
+ var xpath_classes = [];
654
+ for ( var i = 0; i < classes.length; i++ ) {
655
+ xpath_classes.push( '(@class and contains(concat(" ", normalize-space(@class), " "), " ' + classes[ i ] + ' "))');
656
+ }
657
+ cur += '[' + xpath_classes.join( ' and ' ) + ']';
658
+ }
659
+ }
660
+
661
+ // Add index if this element is not unique among its siblings.
662
+ if ( classes.length ) {
663
+ var $siblings = this.siblings( tag + '.' + classes.join( '.' ) );
664
+ } else {
665
+ var $siblings = this.siblings( tag );
666
+ }
667
+
668
+ if ( $siblings.length ) {
669
+ var index = $siblings.addBack().not( '#advads-picker-overlay' ).index( this );
670
+ cur += '[' + index + ']';
671
+ }
672
+
673
+ // Recurse up the DOM.
674
+ if( path === '' ){
675
+ return this.parent().getXPath( cur, depth );
676
+ } else {
677
+ return this.parent().getXPath( cur + '/' + path, depth );
678
+ }
679
  }
680
  });
public/class-advanced-ads.php CHANGED
@@ -79,7 +79,7 @@ class Advanced_Ads {
79
  *
80
  * @var array list of bots
81
  */
82
- protected $bots = array( 'bot', 'spider', 'crawler', 'scraper', 'parser', '008', 'Accoona-AI-Agent', 'ADmantX', 'alexa', 'appie', 'Apple-PubSub', 'Arachmo', 'Ask Jeeves', 'avira\.com', 'B-l-i-t-z-B-O-T', 'boitho\.com-dc', 'BUbiNG', 'Cerberian Drtrs', 'Charlotte', 'cosmos', 'Covario IDS', 'curl', 'Datanyze', 'DataparkSearch', 'DDG-Android', 'Ecosia', 'expo9', 'facebookexternalhit', 'Feedfetcher-Google', 'FindLinks', 'Firefly', 'froogle', 'Genieo', 'heritrix', 'Holmes', 'htdig', 'https://developers\.google\.com', 'ia_archiver', 'ichiro', 'igdeSpyder', 'InfoSeek', 'inktomi', 'Kraken', 'L\.webis', 'Larbin', 'Linguee', 'LinkWalker', 'looksmart', 'lwp-trivial', 'mabontland', 'Mnogosearch', 'mogimogi', 'Morning Paper', 'MVAClient', 'NationalDirectory', 'NetResearchServer', 'NewsGator', 'NG-Search', 'Nusearch', 'NutchCVS', 'Nymesis', 'oegp', 'Orbiter', 'Peew', 'Pompos', 'PostPost', 'proximic', 'PycURL', 'Qseero', 'rabaz', 'Radian6', 'Reeder', 'savetheworldheritage', 'SBIder', 'Scooter', 'ScoutJet', 'Scrubby', 'SearchSight', 'semanticdiscovery', 'Sensis', 'ShopWiki', 'silk', 'Snappy', 'Spade', 'Sqworm', 'StackRambler', 'TechnoratiSnoop', 'TECNOSEEK', 'Teoma', 'Thumbnail\.CZ', 'TinEye', 'truwoGPS', 'updated', 'Vagabondo', 'voltron', 'Vortex', 'voyager', 'VYU2', 'WebBug', 'webcollage', 'WebIndex', 'Websquash\.com', 'WeSEE:Ads', 'wf84', 'Wget', 'WomlpeFactory', 'WordPress', 'yacy', 'Yahoo! Slurp', 'Yahoo! Slurp China', 'YahooSeeker', 'YahooSeeker-Testing', 'YandexBot', 'YandexMedia', 'YandexBlogs', 'YandexNews', 'YandexCalendar', 'YandexImages', 'Yeti', 'yoogliFetchAgent', 'Zao', 'ZyBorg', 'okhttp', 'ips-agent', 'ltx71', 'Optimizer', 'Daum', 'Qwantify' );
83
 
84
  /**
85
  * Loaded instance of Advanced_Ads_Model
@@ -532,6 +532,12 @@ class Advanced_Ads {
532
  }
533
  }
534
 
 
 
 
 
 
 
535
  return $content;
536
  }
537
 
@@ -605,8 +611,8 @@ class Advanced_Ads {
605
  /**
606
  * Check if the current user agent is given or a bot
607
  *
608
- * @since 1.4.9
609
  * @return bool true if the current user agent is empty or a bot.
 
610
  */
611
  public function is_bot() {
612
  // show ads on AMP version also for bots in order to allow Google (and maybe others) to cache the page.
@@ -614,19 +620,16 @@ class Advanced_Ads {
614
  return false;
615
  }
616
 
617
- $bots = apply_filters( 'advanced-ads-bots', $this->bots );
618
-
619
- $bots = implode( '|', $bots );
620
- $bots = preg_replace( '@[^-_;/|\][ :.!a-z0-9]@i', '', $bots );
621
- $regex = "@$bots@i";
622
-
623
- if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && '' !== $_SERVER['HTTP_USER_AGENT'] ) {
624
- $agent = sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) );
625
-
626
- return preg_match( $regex, $agent ) === 1;
627
  }
628
 
629
- return true;
 
 
 
 
 
630
  }
631
 
632
  /**
79
  *
80
  * @var array list of bots
81
  */
82
+ protected $bots = array( 'bot', 'spider', 'crawler', 'scraper', 'parser', '008', 'Accoona-AI-Agent', 'ADmantX', 'alexa', 'appie', 'Apple-PubSub', 'Arachmo', 'Ask Jeeves', 'avira\.com', 'B-l-i-t-z-B-O-T', 'boitho\.com-dc', 'BUbiNG', 'Cerberian Drtrs', 'Charlotte', 'cosmos', 'Covario IDS', 'curl', 'Datanyze', 'DataparkSearch', 'Dataprovider\.com', 'DDG-Android', 'Ecosia', 'expo9', 'facebookexternalhit', 'Feedfetcher-Google', 'FindLinks', 'Firefly', 'froogle', 'Genieo', 'heritrix', 'Holmes', 'htdig', 'https://developers\.google\.com', 'ia_archiver', 'ichiro', 'igdeSpyder', 'InfoSeek', 'inktomi', 'Kraken', 'L\.webis', 'Larbin', 'Linguee', 'LinkWalker', 'looksmart', 'lwp-trivial', 'mabontland', 'Mnogosearch', 'mogimogi', 'Morning Paper', 'MVAClient', 'NationalDirectory', 'NetResearchServer', 'NewsGator', 'NG-Search', 'Nusearch', 'NutchCVS', 'Nymesis', 'oegp', 'Orbiter', 'Peew', 'Pompos', 'PostPost', 'proximic', 'PycURL', 'Qseero', 'rabaz', 'Radian6', 'Reeder', 'savetheworldheritage', 'SBIder', 'Scooter', 'ScoutJet', 'Scrubby', 'SearchSight', 'semanticdiscovery', 'Sensis', 'ShopWiki', 'silk', 'Snappy', 'Spade', 'Sqworm', 'StackRambler', 'TechnoratiSnoop', 'TECNOSEEK', 'Teoma', 'Thumbnail\.CZ', 'TinEye', 'truwoGPS', 'updated', 'Vagabondo', 'voltron', 'Vortex', 'voyager', 'VYU2', 'WebBug', 'webcollage', 'WebIndex', 'Websquash\.com', 'WeSEE:Ads', 'wf84', 'Wget', 'WomlpeFactory', 'WordPress', 'yacy', 'Yahoo! Slurp', 'Yahoo! Slurp China', 'YahooSeeker', 'YahooSeeker-Testing', 'YandexBot', 'YandexMedia', 'YandexBlogs', 'YandexNews', 'YandexCalendar', 'YandexImages', 'Yeti', 'yoogliFetchAgent', 'Zao', 'ZyBorg', 'okhttp', 'ips-agent', 'ltx71', 'Optimizer', 'Daum', 'Qwantify' );
83
 
84
  /**
85
  * Loaded instance of Advanced_Ads_Model
532
  }
533
  }
534
 
535
+ if ( ! empty( $_COOKIE['advads_frontend_picker'] ) ) {
536
+ // Make possible to know where the content starts and ends.
537
+ $content = '<ins style="display: none;" class="advads-frontend-picker-boundary-helper"></ins>
538
+ ' . $content;
539
+ }
540
+
541
  return $content;
542
  }
543
 
611
  /**
612
  * Check if the current user agent is given or a bot
613
  *
 
614
  * @return bool true if the current user agent is empty or a bot.
615
+ * @since 1.4.9
616
  */
617
  public function is_bot() {
618
  // show ads on AMP version also for bots in order to allow Google (and maybe others) to cache the page.
620
  return false;
621
  }
622
 
623
+ if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
624
+ return true;
 
 
 
 
 
 
 
 
625
  }
626
 
627
+ $bots = apply_filters( 'advanced-ads-bots', $this->bots );
628
+ $bots = implode( '|', $bots );
629
+ // Make sure delimiters in regex are escaped.
630
+ $bots = preg_replace( '/(.*?)(?<!\\\)' . preg_quote( '/', '/' ) . '(.*?)/', '$1\\/$2', $bots );
631
+
632
+ return preg_match( sprintf( '/%s/i', $bots ), wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) );
633
  }
634
 
635
  /**
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: ads, ad manager, ad rotation, adsense, banner
4
  Requires at least: 4.6
5
  Tested up to: 5.4
6
  Requires PHP: 5.6
7
- Stable tag: 1.18.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -141,8 +141,6 @@ Like j4ckson185, there are thousands of happy AdSense users:
141
  * generates ads.txt with custom content
142
  * adds the content for AdSense to the ads.txt automatically
143
 
144
- (available with WordPress 5.1)
145
-
146
  https://vimeo.com/299410390
147
 
148
  = ad blocker =
@@ -172,6 +170,19 @@ Localizations: Czech, Dutch, English, French, German, Italian, Japanese, Norwegi
172
 
173
  If you have problems with Advanced Ads, please reach out to [our support](https://wordpress.org/support/plugin/advanced-ads).
174
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  == Installation ==
176
 
177
  How to install the plugin and get it working?
@@ -265,10 +276,6 @@ Just use their shortcodes in our "Rich Media" ad type to combine both features.
265
  Works with AdRotate, Ad Inserter, Ad Injection, Quick AdSense, Quick AdSense Reloaded (WPQUADS), Simple Ads Manager, and other plugins.
266
  Advanced Ads can be used along Google Site Kit or replace it if you need more control over your ad setup.
267
 
268
- = Can I use Flash ads? =
269
-
270
- There is a dedicated Flash ad type in [Pro](https://wpadvancedads.com/add-ons/advanced-ads-pro/).
271
-
272
  = Is the plugin compatible with page builders? =
273
 
274
  Yes. It works out of the box with all site builders that allow shortcodes or widgets, like Elementor, SiteOrigin, Beaver Builder, WPBakery Page Builder (formerly Visual Composer), [Nimble Page Builder](https://wordpress.org/plugins/nimble-builder/), and others.
@@ -288,7 +295,7 @@ Advanced Ads can create that file automatically with the correct information for
288
 
289
  = I am a developer. Can I customize the plugin? =
290
 
291
- Yes. Advanced Ads is built on WordPress standards and therefore easily customizable using either WordPress hooks or the ones we defined [here](https://wpadvancedads.com/codex/).
292
 
293
  == Screenshots ==
294
 
@@ -305,6 +312,17 @@ Yes. Advanced Ads is built on WordPress standards and therefore easily customiza
305
 
306
  == Changelog ==
307
 
 
 
 
 
 
 
 
 
 
 
 
308
  = 1.18.0 =
309
 
310
  * inject ads automatically based on div, table, quotes, iframe, and other HTML tags
@@ -415,4 +433,4 @@ Yes. Advanced Ads is built on WordPress standards and therefore easily customiza
415
  * fixed missing index issue on 404 pages for logged-in admins
416
  * fixed AJAX/PHP error 403 on Settings page
417
  * fixed layout issue that happened when "If>So Dynamic Content" plugin was active
418
- * prevented Ad label from taking height of fixed sized AdSense ads
4
  Requires at least: 4.6
5
  Tested up to: 5.4
6
  Requires PHP: 5.6
7
+ Stable tag: 1.19.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
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 =
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
+
175
+ Advanced Ads integrates with plenty of other plugins:
176
+
177
+ - MailPoet - [How to integrate Advanced Ads in MailPoet Newsletters](https://wpadvancedads.com/mailpoet-newsletters/)
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
+
186
  == Installation ==
187
 
188
  How to install the plugin and get it working?
276
  Works with AdRotate, Ad Inserter, Ad Injection, Quick AdSense, Quick AdSense Reloaded (WPQUADS), Simple Ads Manager, and other plugins.
277
  Advanced Ads can be used along Google Site Kit or replace it if you need more control over your ad setup.
278
 
 
 
 
 
279
  = Is the plugin compatible with page builders? =
280
 
281
  Yes. It works out of the box with all site builders that allow shortcodes or widgets, like Elementor, SiteOrigin, Beaver Builder, WPBakery Page Builder (formerly Visual Composer), [Nimble Page Builder](https://wordpress.org/plugins/nimble-builder/), and others.
295
 
296
  = I am a developer. Can I customize the plugin? =
297
 
298
+ Yes. You can use plenty of [hooks](https://wpadvancedads.com/codex/) to customize Advanced Ads.
299
 
300
  == Screenshots ==
301
 
312
 
313
  == Changelog ==
314
 
315
+ = 1.19.0 =
316
+
317
+ - placements are now ordered by type on the Placements page. You can still choose ordering by name
318
+ - the "custom" option of the Content placement now comes with a picker to select the position in the frontend
319
+ - WPML: placements pages show ads according to the selected language
320
+ - WPML: display the ad in the original language if a translated ad is missing unless the publisher chooses to hide it instead
321
+ - prevented injection of ads into captions of "image" blocks
322
+ - improved bot check
323
+ - fixed layout of expiry data fields
324
+ - fixed broken check for the Responsive add-on
325
+
326
  = 1.18.0 =
327
 
328
  * inject ads automatically based on div, table, quotes, iframe, and other HTML tags
433
  * fixed missing index issue on 404 pages for logged-in admins
434
  * fixed AJAX/PHP error 403 on Settings page
435
  * fixed layout issue that happened when "If>So Dynamic Content" plugin was active
436
+ * prevented Ad label from taking height of fixed sized AdSense ads