Advanced Ads - Version 1.35.0

Version Description

(August 9, 2022) =

  • Improvement: remove frontend picker functionality from the frontend advanced.js JavaScript file
  • Improvement: save the Advanced Ads version as postmeta when saving an ad
  • Fix: make AdSense ad unit list ordering case-insensitive
  • Fix: hide widget types that should not be offered by the Legacy Widget block
  • Fix: respect unfiltered_html capabilities and constant for plain text ads
Download this release

Release Info

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

Code changes from version 1.34.0 to 1.35.0

admin/assets/css/admin.css CHANGED
@@ -139,7 +139,7 @@ h2.hndle .advads-hndlelinks a + a, #advads_overview_adsense_stats .advads-hndlel
139
  .advads-conditions-table > tbody > tr { background: #eee; }
140
  .advads-conditions-table > tbody > tr > td:last-child { padding-right: 10px; }
141
  .advads-conditions-table tr:first-child.advads-conditions-connector { display: none; }
142
- .advads-conditions-connector { text-align: center; }
143
  .advads-conditions-table > tbody > .advads-conditions-connector-and { background: none; }
144
  .advads-conditions-connector label {
145
  text-transform: uppercase;
@@ -162,6 +162,11 @@ select + .advads-conditions-single { display: inline-flex; flex-wrap: wrap; alig
162
  #advads-ad-display-conditions .advads-condition-line-wrap select {
163
  margin-right: 20px;
164
  }
 
 
 
 
 
165
  .advads-conditions-single.disabled { display: none; opacity: .5; }
166
  .advads-conditions-table .advads-conditions-single.advads-buttonset label {
167
  margin: 0.5em 0.5em 0.5em 0;
@@ -219,6 +224,10 @@ select + .advads-conditions-single { display: inline-flex; flex-wrap: wrap; alig
219
  gap: 10px;
220
  }
221
 
 
 
 
 
222
  #ad-display-box .advads-conditions-terms-show-search { height: 22px; line-height: 22px; font-weight: bold; font-size: 1.5em; }
223
  .advads-conditions-terms-search { display: none; }
224
  .post-type-advanced_ads #ad-parameters-box .advads-ad-parameters-spinner { display: block; float: none; }
@@ -365,8 +374,8 @@ fieldset.advads-group-add-ad { margin-top: 1em; }
365
  .advads-placements-table td { margin: 0; padding: 20px 10px; text-align: left; vertical-align: top; }
366
  .advads-placements-table img { height: 70px; margin-bottom: 5px; }
367
  .advads-placements-table .usage-modal-link { cursor: pointer; }
368
- .advads-placements-table .advads-usage { margin-bottom: 20px; }
369
- .advads-placements-table .advads-usage input { width: 100%; }
370
  .advads-placements-table-options { text-align: right; }
371
  .advads-placements-table-options input[type="number"] { width: 4.5em; }
372
  .advads-placements-table ol { margin: 0.5em 0; list-style-position: inside; }
@@ -695,6 +704,12 @@ body.rtl #mapi-archived-ads { left: 78px; right:auto; }
695
  position: sticky;
696
  bottom: 0;
697
  }
 
 
 
 
 
 
698
  @keyframes advads-modal-animatetop {
699
  from {
700
  top: -300px;
@@ -828,7 +843,8 @@ li:hover > .advads-help:before {
828
 
829
  /* WP Admin notifications branded for Advanced Ads */
830
  .advads-notice,
831
- .post-type-advanced_ads .notice {
 
832
  border-left-color: #1B183A;
833
  }
834
  .wp-core-ui .notice.advads-notice .button, .wp-core-ui .notice.advads-notice p button {
139
  .advads-conditions-table > tbody > tr { background: #eee; }
140
  .advads-conditions-table > tbody > tr > td:last-child { padding-right: 10px; }
141
  .advads-conditions-table tr:first-child.advads-conditions-connector { display: none; }
142
+ .advads-conditions-table .advads-conditions-connector td { text-align: center; }
143
  .advads-conditions-table > tbody > .advads-conditions-connector-and { background: none; }
144
  .advads-conditions-connector label {
145
  text-transform: uppercase;
162
  #advads-ad-display-conditions .advads-condition-line-wrap select {
163
  margin-right: 20px;
164
  }
165
+
166
+ .advads-conditions-new select {
167
+ text-transform: capitalize;
168
+ }
169
+
170
  .advads-conditions-single.disabled { display: none; opacity: .5; }
171
  .advads-conditions-table .advads-conditions-single.advads-buttonset label {
172
  margin: 0.5em 0.5em 0.5em 0;
224
  gap: 10px;
225
  }
226
 
227
+ .advads-conditions-table .advads-conditions-table-width-100 {
228
+ width: 100%;
229
+ }
230
+
231
  #ad-display-box .advads-conditions-terms-show-search { height: 22px; line-height: 22px; font-weight: bold; font-size: 1.5em; }
232
  .advads-conditions-terms-search { display: none; }
233
  .post-type-advanced_ads #ad-parameters-box .advads-ad-parameters-spinner { display: block; float: none; }
374
  .advads-placements-table td { margin: 0; padding: 20px 10px; text-align: left; vertical-align: top; }
375
  .advads-placements-table img { height: 70px; margin-bottom: 5px; }
376
  .advads-placements-table .usage-modal-link { cursor: pointer; }
377
+ .advads-placements-table .advads-usage, .adgroups .advads-usage { margin-bottom: 20px; }
378
+ .advads-placements-table .advads-usage input, .adgroups .advads-usage input { width: 100%; }
379
  .advads-placements-table-options { text-align: right; }
380
  .advads-placements-table-options input[type="number"] { width: 4.5em; }
381
  .advads-placements-table ol { margin: 0.5em 0; list-style-position: inside; }
704
  position: sticky;
705
  bottom: 0;
706
  }
707
+
708
+ .advads-modal h2, .advads-modal h3 {
709
+ font-size: 1.3em;
710
+ margin: 1em 0;
711
+ }
712
+
713
  @keyframes advads-modal-animatetop {
714
  from {
715
  top: -300px;
843
 
844
  /* WP Admin notifications branded for Advanced Ads */
845
  .advads-notice,
846
+ .post-type-advanced_ads .notice,
847
+ .advanced-ads_page_advanced-ads-placements .notice {
848
  border-left-color: #1B183A;
849
  }
850
  .wp-core-ui .notice.advads-notice .button, .wp-core-ui .notice.advads-notice p button {
admin/assets/js/admin.js CHANGED
@@ -113,20 +113,30 @@ jQuery( document ).ready( function ( $ ) {
113
 
114
  // display ad groups form
115
  $( '#advads-ad-group-list a.edit, #advads-ad-group-list a.row-title' ).on( 'click', function ( e ) {
116
- e.preventDefault();
117
- var advadsgroupformrow = $(this).parents('.advads-group-row').next('.advads-ad-group-form');
118
- if (advadsgroupformrow.is(':visible')) {
119
- advadsgroupformrow.addClass('hidden');
120
- // clear last edited id
121
- $('#advads-last-edited-group').val('');
122
- } else {
123
- advadsgroupformrow.removeClass('hidden');
124
- var group_id = advadsgroupformrow.find('.advads-group-id').val()
125
- $('#advads-last-edited-group').val(group_id);
126
- // remember that we opened that one
127
- advadsgroupformrow.data('touched', true);
128
- }
129
- });
 
 
 
 
 
 
 
 
 
 
130
  // display ad groups usage
131
  $( '#advads-ad-group-list a.usage' ).on( 'click', function ( e ) {
132
  e.preventDefault();
@@ -1058,18 +1068,19 @@ window.Advanced_Ads_Admin = window.Advanced_Ads_Admin || {
1058
  check_ad_source: function () {
1059
  var text = Advanced_Ads_Admin.get_ad_source_editor_text()
1060
  // allow php is enabled.
 
 
 
 
 
 
1061
  if ( jQuery( '#advads-parameters-php' ).prop( 'checked' ) ) {
1062
  // ad content has opening php tag.
1063
- if ( ! /<\?php/.test( text ) ) {
1064
- jQuery( '#advads-parameters-php-warning' ).show();
1065
- jQuery( '#advads-allow-php-warning' ).hide();
1066
  } else {
1067
- jQuery( '#advads-parameters-php-warning' ).hide();
1068
- jQuery( '#advads-allow-php-warning' ).show();
1069
  }
1070
- } else {
1071
- jQuery( '#advads-parameters-php-warning' ).hide();
1072
- jQuery( '#advads-allow-php-warning' ).hide();
1073
  }
1074
  // execute shortcodes is enabled.
1075
  if ( jQuery( '#advads-parameters-shortcodes' ).prop( 'checked' ) && ! /\[[^\]]+\]/.test( text ) ) {
@@ -1079,6 +1090,22 @@ window.Advanced_Ads_Admin = window.Advanced_Ads_Admin || {
1079
  }
1080
  },
1081
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1082
  /**
1083
  * Toggle placement advanced options.
1084
  *
113
 
114
  // display ad groups form
115
  $( '#advads-ad-group-list a.edit, #advads-ad-group-list a.row-title' ).on( 'click', function ( e ) {
116
+ e.preventDefault();
117
+ var advadsgroupformrow = $( this ).parents( '.advads-group-row' ).next( '.advads-ad-group-form' );
118
+ if ( advadsgroupformrow.is( ':visible' ) ) {
119
+ advadsgroupformrow.addClass( 'hidden' );
120
+ advadsgroupformrow.prev( '.advads-group-row' ).find( '.advads-ad-group-list-ads a.edit' ).show();
121
+ // clear last edited id
122
+ $( '#advads-last-edited-group' ).val( '' );
123
+ } else {
124
+ advadsgroupformrow.removeClass( 'hidden' );
125
+ advadsgroupformrow.prev( '.advads-group-row' ).find( '.advads-ad-group-list-ads a.edit' ).hide();
126
+ var selectField = advadsgroupformrow.find( 'select.advads-group-add-ad-list-ads' );
127
+ if ( jQuery( this ).hasClass( 'advads-add-ads' ) ) {
128
+ selectField.focus();
129
+ jQuery( 'html, body' ).animate( {
130
+ scrollTop: selectField.offset().top
131
+ }, 1000 );
132
+ }
133
+
134
+ var group_id = advadsgroupformrow.find( '.advads-group-id' ).val();
135
+ $( '#advads-last-edited-group' ).val( group_id );
136
+ // remember that we opened that one
137
+ advadsgroupformrow.data( 'touched', true );
138
+ }
139
+ } );
140
  // display ad groups usage
141
  $( '#advads-ad-group-list a.usage' ).on( 'click', function ( e ) {
142
  e.preventDefault();
1068
  check_ad_source: function () {
1069
  var text = Advanced_Ads_Admin.get_ad_source_editor_text()
1070
  // allow php is enabled.
1071
+ const phpWarning = jQuery( '#advads-parameters-php-warning' );
1072
+ const allowPhpWarning = jQuery( '#advads-allow-php-warning' );
1073
+
1074
+ phpWarning.hide();
1075
+ allowPhpWarning.hide();
1076
+
1077
  if ( jQuery( '#advads-parameters-php' ).prop( 'checked' ) ) {
1078
  // ad content has opening php tag.
1079
+ if ( /<\?(?:php|=)/.test( text ) ) {
1080
+ allowPhpWarning.show();
 
1081
  } else {
1082
+ phpWarning.show();
 
1083
  }
 
 
 
1084
  }
1085
  // execute shortcodes is enabled.
1086
  if ( jQuery( '#advads-parameters-shortcodes' ).prop( 'checked' ) && ! /\[[^\]]+\]/.test( text ) ) {
1090
  }
1091
  },
1092
 
1093
+ /**
1094
+ * Change the user id to the current user and save the post.
1095
+ *
1096
+ * @param {int} user_id
1097
+ */
1098
+ reassign_ad: function ( user_id ) {
1099
+ let $authorBox = jQuery( '#post_author_override' );
1100
+ if ( ! $authorBox.length ) {
1101
+ $authorBox = jQuery( '#post_author' );
1102
+ }
1103
+
1104
+ $authorBox.val( user_id ).queue( () => {
1105
+ jQuery( '#post' ).submit();
1106
+ } );
1107
+ },
1108
+
1109
  /**
1110
  * Toggle placement advanced options.
1111
  *
admin/class-advanced-ads-admin.php CHANGED
@@ -131,6 +131,7 @@ class Advanced_Ads_Admin {
131
  Advanced_Ads_Admin_Menu::get_instance();
132
  Advanced_Ads_Admin_Ad_Type::get_instance();
133
  Advanced_Ads_Admin_Settings::get_instance();
 
134
  new Advanced_Ads_Admin_Upgrades();
135
  }
136
 
131
  Advanced_Ads_Admin_Menu::get_instance();
132
  Advanced_Ads_Admin_Ad_Type::get_instance();
133
  Advanced_Ads_Admin_Settings::get_instance();
134
+ Advanced_Ads_Ad_Authors::get_instance();
135
  new Advanced_Ads_Admin_Upgrades();
136
  }
137
 
admin/includes/ad-authors.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Control Ad Authors.
5
+ */
6
+ class Advanced_Ads_Ad_Authors {
7
+ /**
8
+ * Singleton instance of this class.
9
+ *
10
+ * @var Advanced_Ads_Ad_Authors
11
+ */
12
+ private static $instance;
13
+
14
+ /**
15
+ * Attach callbacks to hooks and filters.
16
+ */
17
+ private function __construct() {
18
+ add_filter( 'wp_dropdown_users_args', array( $this, 'filter_ad_authors' ) );
19
+ add_action( 'pre_post_update', array( $this, 'sanitize_author_saving' ), 10, 2 );
20
+ add_filter( 'map_meta_cap', array( $this, 'filter_editable_posts' ), 10, 4 );
21
+ }
22
+
23
+ /**
24
+ * Singleton.
25
+ *
26
+ * @return Advanced_Ads_Ad_Authors
27
+ */
28
+ public static function get_instance() {
29
+ if ( self::$instance === null ) {
30
+ self::$instance = new self();
31
+ }
32
+
33
+ return self::$instance;
34
+ }
35
+
36
+ /**
37
+ * Ensure that users cannot assign ads to users with unfiltered_html if they don't have the capability themselves.
38
+ *
39
+ * @param array $query_args WP_User_Query args.
40
+ *
41
+ * @return array
42
+ */
43
+ public function filter_ad_authors( $query_args ) {
44
+ if ( get_current_screen()->post_type !== Advanced_Ads::POST_TYPE_SLUG ) {
45
+ return $query_args;
46
+ }
47
+
48
+ if ( is_multisite() ) {
49
+ return $this->multisite_filter_ad_authors( $query_args );
50
+ }
51
+
52
+ $user_roles_to_display = array_filter( wp_roles()->role_objects, static function( WP_Role $role ) {
53
+ return ! $role->has_cap( 'unfiltered_html' ) && $role->has_cap( 'advanced_ads_edit_ads' );
54
+ } );
55
+
56
+ $query_args['role__in'] = wp_list_pluck( $user_roles_to_display, 'name' );
57
+
58
+ return $query_args;
59
+ }
60
+
61
+ /**
62
+ * Ensure that users cannot assign ads to users who have more rights on multisite.
63
+ *
64
+ * @param array $query_args WP_User_Query args.
65
+ *
66
+ * @return array
67
+ */
68
+ private function multisite_filter_ad_authors( $query_args ) {
69
+ if ( is_super_admin() ) {
70
+ return $query_args;
71
+ }
72
+
73
+ $options = Advanced_Ads::get_instance()->options();
74
+ $allowed_roles = isset( $options['allow-unfiltered-html'] ) ? $options['allow-unfiltered-html'] : array();
75
+
76
+ // if the current user can unfiltered_html, return the default args.
77
+ if ( ! empty( array_intersect( wp_get_current_user()->roles, $allowed_roles ) ) ) {
78
+ return $query_args;
79
+ }
80
+
81
+ // if the current user can't use unfiltered_html, they should not be able to assign the ad to a user that can.
82
+ $user_roles_to_display = array_filter( wp_roles()->role_objects, static function( WP_Role $role ) use ( $allowed_roles ) {
83
+ return ! in_array( $role->name, $allowed_roles, true ) && $role->has_cap( 'advanced_ads_edit_ads' );
84
+ } );
85
+
86
+ $query_args['role__in'] = wp_list_pluck( $user_roles_to_display, 'name' );
87
+ // exclude super-admins from the author dropdown.
88
+ $query_args['exclude'] = array_map( static function( $login ) {
89
+ return get_user_by( 'login', $login )->ID;
90
+ }, get_super_admins() );
91
+
92
+ return $query_args;
93
+ }
94
+
95
+ /**
96
+ * Prevent users from editing the form data and assign ads to users they're not allowed to.
97
+ * Wp_die() if tampering detected.
98
+ *
99
+ * @param int $post_id The current post id.
100
+ * @param array $data The post data to be saved.
101
+ *
102
+ * @return void
103
+ */
104
+ public function sanitize_author_saving( $post_id, $data ) {
105
+ if ( get_post_type( $post_id ) !== Advanced_Ads::POST_TYPE_SLUG ) {
106
+ return;
107
+ }
108
+
109
+ if ( (int) $data['post_author'] === get_current_user_id() ) {
110
+ return;
111
+ }
112
+
113
+ $user_query = new WP_User_Query( $this->filter_ad_authors( array( 'fields' => 'ID' ) ) );
114
+ if ( ! in_array( (int) $data['post_author'], array_map( 'intval', $user_query->get_results() ), true ) ) {
115
+ wp_die( esc_html__( 'Sorry, you\'re not allowed to assign this user.', 'advanced-ads' ) );
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Prevent users from editing posts of users with more rights than themselves.
121
+ *
122
+ * @param array $caps Needed capabilities.
123
+ * @param string $cap Requested capability.
124
+ * @param int $user_id The user_id for the cap check.
125
+ * @param array $args Arguments array for checking primitive capabilities.
126
+ *
127
+ * @return array
128
+ */
129
+ public function filter_editable_posts( $caps, $cap, $user_id, $args ) {
130
+ if ( $cap !== 'advanced_ads_edit_ads' || empty( $args ) ) {
131
+ return $caps;
132
+ }
133
+
134
+ $post_id = (int) $args[0];
135
+ if ( empty( $post_id ) ) {
136
+ return $caps;
137
+ }
138
+
139
+ $ad = new Advanced_Ads_Ad( $post_id );
140
+ if ( $ad->type !== 'plain' ) {
141
+ return $caps;
142
+ }
143
+
144
+ $author_id = (int) get_post_field( 'post_author', $post_id );
145
+ $user_query = new WP_User_Query( $this->filter_ad_authors( array( 'fields' => 'ID' ) ) );
146
+ if ( ! in_array( $author_id, array_map( 'intval', $user_query->get_results() ), true ) ) {
147
+ $caps[] = 'do_not_allow';
148
+ }
149
+
150
+ return $caps;
151
+ }
152
+ }
admin/includes/class-ad-groups-list.php CHANGED
@@ -233,7 +233,7 @@ class Advanced_Ads_Groups_List {
233
  } else {
234
  esc_html_e( 'No ads assigned', 'advanced-ads' );
235
  ?>
236
- <br/><a class="edit">+ <?php esc_html_e( 'Add some', 'advanced-ads' ); ?></a>
237
  <?php
238
  }
239
  // Restore original Post Data.
@@ -356,7 +356,7 @@ class Advanced_Ads_Groups_List {
356
  $actions = array();
357
  if ( current_user_can( $tax->cap->edit_terms ) ) {
358
  $actions['edit'] = '<a class="edit">' . __( 'Edit', 'advanced-ads' ) . '</a>';
359
- $actions['usage'] = '<a class="usage">' . __( 'Usage', 'advanced-ads' ) . '</a>';
360
  }
361
 
362
  if ( current_user_can( $tax->cap->delete_terms ) ) {
233
  } else {
234
  esc_html_e( 'No ads assigned', 'advanced-ads' );
235
  ?>
236
+ <br/><a class="edit advads-add-ads">+ <?php esc_html_e( 'Add some', 'advanced-ads' ); ?></a>
237
  <?php
238
  }
239
  // Restore original Post Data.
356
  $actions = array();
357
  if ( current_user_can( $tax->cap->edit_terms ) ) {
358
  $actions['edit'] = '<a class="edit">' . __( 'Edit', 'advanced-ads' ) . '</a>';
359
+ $actions['usage'] = '<a href="#modal-' . esc_attr( $group->id ) . '-usage" class="usage-modal-link">' . esc_html__( 'show usage', 'advanced-ads' ) . '</a>';
360
  }
361
 
362
  if ( current_user_can( $tax->cap->delete_terms ) ) {
admin/includes/class-ad-network-ad-unit.php CHANGED
@@ -90,10 +90,10 @@ class Advanced_Ads_Ad_Network_Ad_Unit {
90
  return 1;
91
  }
92
 
93
- return strcmp( $a->name, $b->name );
94
  }
95
  );
96
 
97
  return $ad_units;
98
  }
99
- }
90
  return 1;
91
  }
92
 
93
+ return strcasecmp( $a->name, $b->name );
94
  }
95
  );
96
 
97
  return $ad_units;
98
  }
99
+ }
admin/includes/class-settings.php CHANGED
@@ -222,6 +222,19 @@ class Advanced_Ads_Admin_Settings {
222
  $hook,
223
  'advanced_ads_setting_section'
224
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  // ad label.
226
  add_settings_field(
227
  'add-custom-label',
@@ -547,6 +560,27 @@ class Advanced_Ads_Admin_Settings {
547
  require ADVADS_BASE_PATH . '/admin/views/settings/general/editors-manage-ads.php';
548
  }
549
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
550
  /**
551
  * Render setting to add an "Advertisement" label before ads
552
  */
222
  $hook,
223
  'advanced_ads_setting_section'
224
  );
225
+
226
+ // add unfiltered_html option to multisites
227
+ if ( is_multisite() && current_user_can( 'unfiltered_html' ) ) {
228
+ add_settings_field(
229
+ 'allow-unfiltered-html',
230
+ /* translators: unfiltered_html */
231
+ sprintf( __( 'Add the %s capability to user roles on multisite', 'advanced-ads' ), '<code>unfiltered_html</code>' ),
232
+ array( $this, 'renders_settings_allow_unfiltered_html' ),
233
+ $hook,
234
+ 'advanced_ads_setting_section'
235
+ );
236
+ }
237
+
238
  // ad label.
239
  add_settings_field(
240
  'add-custom-label',
560
  require ADVADS_BASE_PATH . '/admin/views/settings/general/editors-manage-ads.php';
561
  }
562
 
563
+ /**
564
+ * Prepare the template for multisite allow unfiltered_html settings.
565
+ *
566
+ * @return void
567
+ */
568
+ public function renders_settings_allow_unfiltered_html() {
569
+ $options = Advanced_Ads::get_instance()->options();
570
+ $user_roles_to_display = array_filter( wp_roles()->role_objects, static function( WP_Role $role ) {
571
+ return $role->has_cap( 'advanced_ads_edit_ads' );
572
+ } );
573
+ if ( empty( $user_roles_to_display ) ) {
574
+ return;
575
+ }
576
+ if ( ! isset( $options['allow-unfiltered-html'] ) ) {
577
+ $options['allow-unfiltered-html'] = array();
578
+ }
579
+ $allowed_roles = $options['allow-unfiltered-html'];
580
+
581
+ require ADVADS_BASE_PATH . '/admin/views/settings/general/allow-unfiltered-html.php';
582
+ }
583
+
584
  /**
585
  * Render setting to add an "Advertisement" label before ads
586
  */
admin/views/ad-group-list-row.php CHANGED
@@ -8,9 +8,9 @@
8
  * @link https://wpadvancedads.com
9
  * @copyright since 2013 Thomas Maier, Advanced Ads GmbH
10
  *
11
- * @var Advanced_Ads_Group $group ad group object.
 
12
  */
13
-
14
  ?><tr class="advads-group-row">
15
  <td>
16
  <strong><a class="row-title" href="#"><?php echo esc_html( $group->name ); ?></a></strong>
@@ -18,14 +18,21 @@
18
  // escaping done by the function.
19
  // phpcs:ignore
20
  echo $this->render_action_links( $group ); ?>
21
- <div class="hidden advads-usage">
22
- <label><?php esc_attr_e( 'shortcode', 'advanced-ads' ); ?>
23
- <code><input type="text" onclick="this.select();" style="width: 200px;" value='[the_ad_group id="<?php echo absint( $group->id ); ?>"]'/></code>
24
- </label><br/>
25
- <label><?php esc_attr_e( 'template', 'advanced-ads' ); ?>
26
- <code><input type="text" onclick="this.select();" value="the_ad_group(<?php echo absint( $group->id ); ?>);"/></code>
27
- </label>
 
 
28
  </div>
 
 
 
 
 
29
  </td>
30
  <td>
31
  <ul><?php $_type = isset( $this->types[ $group->type ]['title'] ) ? $this->types[ $group->type ]['title'] : 'default'; ?>
8
  * @link https://wpadvancedads.com
9
  * @copyright since 2013 Thomas Maier, Advanced Ads GmbH
10
  *
11
+ * @var Advanced_Ads_Group $group ad group object.
12
+ * @var Advanced_Ads_Groups_List $this Groups list table object.
13
  */
 
14
  ?><tr class="advads-group-row">
15
  <td>
16
  <strong><a class="row-title" href="#"><?php echo esc_html( $group->name ); ?></a></strong>
18
  // escaping done by the function.
19
  // phpcs:ignore
20
  echo $this->render_action_links( $group ); ?>
21
+ <?php
22
+ $modal_slug = esc_attr( $group->id . '-usage' );
23
+ ob_start();
24
+ ?>
25
+ <div class="advads-usage">
26
+ <h2><?php esc_attr_e( 'shortcode', 'advanced-ads' ); ?></h2>
27
+ <code><input type="text" onclick="this.select();" value='[the_ad_group id="<?php echo absint( $group->id ); ?>"]' readonly /></code>
28
+ <h2><?php esc_html_e( 'template (PHP)', 'advanced-ads' ); ?></h2>
29
+ <code><input type="text" onclick="this.select();" value="the_ad_group(<?php echo absint( $group->id ); ?>);" readonly /></code>
30
  </div>
31
+ <?php
32
+ $modal_content = ob_get_clean();
33
+ $modal_title = esc_html__( 'Usage', 'advanced-ads' );
34
+ include ADVADS_BASE_PATH . 'admin/views/modal.php';
35
+ ?>
36
  </td>
37
  <td>
38
  <ul><?php $_type = isset( $this->types[ $group->type ]['title'] ) ? $this->types[ $group->type ]['title'] : 'default'; ?>
admin/views/placements-ad-label-position.php CHANGED
@@ -7,7 +7,6 @@
7
  * @var bool $_clearfix value of the position clearfix option.
8
  */
9
  ?>
10
- <br/><br/><p><?php esc_html_e( 'Position', 'advanced-ads' ); ?></p>
11
  <label title="<?php esc_html_e( 'default', 'advanced-ads' ); ?>">
12
  <input type="radio" name="advads[placements][<?php echo esc_attr( $_placement_slug ); ?>][options][placement_position]" value="" <?php checked( $_position, 'default' ); ?>/>
13
  <?php esc_html_e( 'default', 'advanced-ads' ); ?>
7
  * @var bool $_clearfix value of the position clearfix option.
8
  */
9
  ?>
 
10
  <label title="<?php esc_html_e( 'default', 'advanced-ads' ); ?>">
11
  <input type="radio" name="advads[placements][<?php echo esc_attr( $_placement_slug ); ?>][options][placement_position]" value="" <?php checked( $_position, 'default' ); ?>/>
12
  <?php esc_html_e( 'default', 'advanced-ads' ); ?>
admin/views/placements.php CHANGED
@@ -16,9 +16,9 @@ $quick_actions['delete'] = '<a style="cursor: pointer;" class="advads-delete-tag
16
  if ( isset( $_GET['message'] ) ) :
17
  if ( $_GET['message'] === 'error' ) :
18
  ?>
19
- <div id="message" class="error inline"><p><?php esc_html_e( 'Couldn’t create the new placement. Please check your form field and whether the name is already in use.', 'advanced-ads' ); ?></p></div>
20
  <?php elseif ( $_GET['message'] === 'updated' ) : ?>
21
- <div id="message" class="updated inline"><p><?php esc_html_e( 'Placements updated', 'advanced-ads' ); ?></p></div>
22
  <?php endif; ?>
23
  <?php endif; ?>
24
  <p class="description"><?php esc_html_e( '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.', 'advanced-ads' ); ?></p>
@@ -145,9 +145,6 @@ $quick_actions['delete'] = '<a style="cursor: pointer;" class="advads-delete-tag
145
 
146
  ob_start();
147
  include ADVADS_BASE_PATH . 'admin/views/placements-ad-label.php';
148
- if ( ! empty( $placement_types[ $_placement['type'] ]['options']['show_position'] ) ) :
149
- include ADVADS_BASE_PATH . 'admin/views/placements-ad-label-position.php';
150
- endif;
151
  $option_content = ob_get_clean();
152
 
153
  Advanced_Ads_Admin_Options::render_option(
@@ -157,6 +154,17 @@ $quick_actions['delete'] = '<a style="cursor: pointer;" class="advads-delete-tag
157
  );
158
  }
159
 
 
 
 
 
 
 
 
 
 
 
 
160
  // Renders inline css option.
161
  ob_start();
162
  include ADVADS_BASE_PATH . 'admin/views/placements-inline-css.php';
@@ -302,10 +310,10 @@ $quick_actions['delete'] = '<a style="cursor: pointer;" class="advads-delete-tag
302
  <div class="advads-usage">
303
  <h2><?php esc_html_e( 'shortcode', 'advanced-ads' ); ?></h2>
304
  <code><input type="text" onclick="this.select();"
305
- value='[the_ad_placement id="<?php echo esc_attr( $_placement_slug ); ?>"]'/></code>
306
  <h2><?php esc_html_e( 'template (PHP)', 'advanced-ads' ); ?></h2>
307
  <code><input type="text" onclick="this.select();"
308
- value="if( function_exists('the_ad_placement') ) { the_ad_placement('<?php echo esc_attr( $_placement_slug ); ?>'); }"/></code>
309
  </div>
310
  </div>
311
  <div class="advads-modal-footer">
16
  if ( isset( $_GET['message'] ) ) :
17
  if ( $_GET['message'] === 'error' ) :
18
  ?>
19
+ <div id="message" class="notice notice-error advads-admin-notice inline"><p><?php esc_html_e( 'Couldn’t create the new placement. Please check your form field and whether the name is already in use.', 'advanced-ads' ); ?></p></div>
20
  <?php elseif ( $_GET['message'] === 'updated' ) : ?>
21
+ <div id="message" class="notice updated advads-admin-notice inline"><p><?php esc_html_e( 'Placements updated', 'advanced-ads' ); ?></p></div>
22
  <?php endif; ?>
23
  <?php endif; ?>
24
  <p class="description"><?php esc_html_e( '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.', 'advanced-ads' ); ?></p>
145
 
146
  ob_start();
147
  include ADVADS_BASE_PATH . 'admin/views/placements-ad-label.php';
 
 
 
148
  $option_content = ob_get_clean();
149
 
150
  Advanced_Ads_Admin_Options::render_option(
154
  );
155
  }
156
 
157
+ if ( ! empty( $placement_types[ $_placement['type'] ]['options']['show_position'] ) ) :
158
+ ob_start();
159
+ include ADVADS_BASE_PATH . 'admin/views/placements-ad-label-position.php';
160
+ $option_content = ob_get_clean();
161
+ Advanced_Ads_Admin_Options::render_option(
162
+ 'placement-position',
163
+ __( 'Position', 'advanced-ads' ),
164
+ $option_content
165
+ );
166
+ endif;
167
+
168
  // Renders inline css option.
169
  ob_start();
170
  include ADVADS_BASE_PATH . 'admin/views/placements-inline-css.php';
310
  <div class="advads-usage">
311
  <h2><?php esc_html_e( 'shortcode', 'advanced-ads' ); ?></h2>
312
  <code><input type="text" onclick="this.select();"
313
+ value='[the_ad_placement id="<?php echo esc_attr( $_placement_slug ); ?>"]' readonly/></code>
314
  <h2><?php esc_html_e( 'template (PHP)', 'advanced-ads' ); ?></h2>
315
  <code><input type="text" onclick="this.select();"
316
+ value="if( function_exists('the_ad_placement') ) { the_ad_placement('<?php echo esc_attr( $_placement_slug ); ?>'); }" readonly/></code>
317
  </div>
318
  </div>
319
  <div class="advads-modal-footer">
admin/views/settings/general/allow-unfiltered-html.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template for allow unfiltered_html for user roles on multisites.
4
+ *
5
+ * @var WP_Role[] $user_roles_to_display Array of user roles that are allowed to edit ads.
6
+ * @var array $allowed_roles Array of user role names that are allowed to use unfiltered_html on ads.
7
+ */
8
+ ?>
9
+ <fieldset>
10
+ <legend><?php esc_html_e( 'Allow unfiltered HTML for these user roles:', 'advanced-ads' ); ?></legend>
11
+ <?php foreach ( $user_roles_to_display as $user_role ) : ?>
12
+ <p>
13
+ <input
14
+ type="checkbox"
15
+ id="<?php echo esc_attr( $user_role->name ); ?>"
16
+ name="<?php echo esc_attr( ADVADS_SLUG ); ?>[allow-unfiltered-html][]"
17
+ value="<?php echo esc_attr( $user_role->name ); ?>"
18
+ <?php checked( in_array( $user_role->name, $allowed_roles, true ) ); ?>
19
+ >
20
+ <label for="<?php echo esc_attr( $user_role->name ); ?>"><?php echo esc_html( $user_role->name ); ?></label>
21
+ </p>
22
+ <?php endforeach; ?>
23
+ </fieldset>
24
+ <p class="description">
25
+ <?php esc_html_e( 'Enabling this option for untrusted users may cause them to publish malicious or poorly formatted code in their ads and can be a potential security risk. You should carefully consider which user roles you grant this capability.', 'advanced-ads' ); ?>
26
+ </p>
advanced-ads.php CHANGED
@@ -6,13 +6,13 @@
6
  * @author Thomas Maier <support@wpadvancedads.com>
7
  * @license GPL-2.0+
8
  * @link https://wpadvancedads.com
9
- * @copyright 2013-2020 Thomas Maier, Advanced Ads GmbH
10
  *
11
  * @wordpress-plugin
12
  * Plugin Name: Advanced Ads
13
  * Plugin URI: https://wpadvancedads.com
14
  * Description: Manage and optimize your ads in WordPress
15
- * Version: 1.34.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.34.0' );
43
 
44
  // Autoloading, modules and functions.
45
 
6
  * @author Thomas Maier <support@wpadvancedads.com>
7
  * @license GPL-2.0+
8
  * @link https://wpadvancedads.com
9
+ * @copyright since 2013 Thomas Maier, Advanced Ads GmbH
10
  *
11
  * @wordpress-plugin
12
  * Plugin Name: Advanced Ads
13
  * Plugin URI: https://wpadvancedads.com
14
  * Description: Manage and optimize your ads in WordPress
15
+ * Version: 1.35.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.35.0' );
43
 
44
  // Autoloading, modules and functions.
45
 
classes/ad.php CHANGED
@@ -597,6 +597,9 @@ class Advanced_Ads_Ad {
597
  $options['expiry_date'] = $this->expiry_date;
598
  $options['description'] = $this->description;
599
 
 
 
 
600
  // sanitize container ID option.
601
  $options['output']['wrapper-id'] = isset( $options['output']['wrapper-id'] ) ? sanitize_key( $options['output']['wrapper-id'] ) : '';
602
 
597
  $options['expiry_date'] = $this->expiry_date;
598
  $options['description'] = $this->description;
599
 
600
+ // save the plugin version, with every ad save.
601
+ $options['last_save_version'] = ADVADS_VERSION;
602
+
603
  // sanitize container ID option.
604
  $options['output']['wrapper-id'] = isset( $options['output']['wrapper-id'] ) ? sanitize_key( $options['output']['wrapper-id'] ) : '';
605
 
classes/ad_type_plain.php CHANGED
@@ -197,7 +197,15 @@ class Advanced_Ads_Ad_Type_Plain extends Advanced_Ads_Ad_Type_Abstract {
197
  }
198
  }
199
 
200
- return $this->kses_ad( $content );
 
 
 
 
 
 
 
 
201
  }
202
 
203
  /**
@@ -219,19 +227,23 @@ class Advanced_Ads_Ad_Type_Plain extends Advanced_Ads_Ad_Type_Abstract {
219
  * @return void
220
  */
221
  protected function error_unfiltered_html( Advanced_Ads_Ad $ad ) {
222
- $author_id = (int) get_post_field( 'post_author', $ad->id );
 
223
 
224
- if ( ! ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) ) {
225
  return;
226
  }
227
 
228
  ?>
229
  <p class="advads-notice-inline advads-error">
230
  <?php
231
- if ( $author_id === get_current_user_id() ) {
232
  esc_html_e( 'You do not have sufficient permissions to include all HTML tags.', 'advanced-ads' );
233
  } else {
234
  esc_html_e( 'The creator of the ad does not have sufficient permissions to include all HTML tags.', 'advanced-ads' );
 
 
 
235
  }
236
  ?>
237
  <a href="<?php echo esc_url( ADVADS_URL ) . '/manual/ad-types/#Plain_Text_and_Code'; ?>" target="_blank" rel="noopener">
@@ -245,12 +257,51 @@ class Advanced_Ads_Ad_Type_Plain extends Advanced_Ads_Ad_Type_Abstract {
245
  * Check if the ad content needs filtering.
246
  *
247
  * @param string $content The parsed ad content.
 
248
  *
249
  * @return string
250
  */
251
  protected function kses_ad( $content ) {
252
- return defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML
253
- ? wp_kses( $content, wp_kses_allowed_html( 'post' ) )
254
- : $content;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  }
256
  }
197
  }
198
  }
199
 
200
+ return (
201
+ (
202
+ ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) ||
203
+ ! $this->author_can_unfiltered_html( (int) get_post_field( 'post_author', $ad->id ) )
204
+ )
205
+ && version_compare( $ad->options( 'last_save_version', '0' ), '1.35.0', 'ge' )
206
+ )
207
+ ? wp_kses( $content, wp_kses_allowed_html( 'post' ) )
208
+ : $content;
209
  }
210
 
211
  /**
227
  * @return void
228
  */
229
  protected function error_unfiltered_html( Advanced_Ads_Ad $ad ) {
230
+ $author_id = (int) get_post_field( 'post_author', $ad->id );
231
+ $current_user_id = get_current_user_id();
232
 
233
+ if ($this->author_can_unfiltered_html($author_id)) {
234
  return;
235
  }
236
 
237
  ?>
238
  <p class="advads-notice-inline advads-error">
239
  <?php
240
+ if ( $author_id === $current_user_id ) {
241
  esc_html_e( 'You do not have sufficient permissions to include all HTML tags.', 'advanced-ads' );
242
  } else {
243
  esc_html_e( 'The creator of the ad does not have sufficient permissions to include all HTML tags.', 'advanced-ads' );
244
+ if ( current_user_can( 'unfiltered_html' ) && $this->user_has_role_on_site() ) {
245
+ printf( '<button type="button" onclick="(()=>Advanced_Ads_Admin.reassign_ad(%d))();" class="button button-primary">%s</button>', $current_user_id, esc_html__( 'Assign ad to me', 'advanced-ads' ) );
246
+ }
247
  }
248
  ?>
249
  <a href="<?php echo esc_url( ADVADS_URL ) . '/manual/ad-types/#Plain_Text_and_Code'; ?>" target="_blank" rel="noopener">
257
  * Check if the ad content needs filtering.
258
  *
259
  * @param string $content The parsed ad content.
260
+ * @deprecated
261
  *
262
  * @return string
263
  */
264
  protected function kses_ad( $content ) {
265
+ return $content;
266
+ }
267
+
268
+ /**
269
+ * Check if the author of the ad can use unfiltered_html.
270
+ *
271
+ * @param int $author_id User ID of the ad author.
272
+ *
273
+ * @return bool
274
+ */
275
+ private function author_can_unfiltered_html( $author_id ) {
276
+ if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) {
277
+ return false;
278
+ }
279
+
280
+ $unfiltered_allowed = user_can( $author_id, 'unfiltered_html' );
281
+ if ( $unfiltered_allowed || ! is_multisite() ) {
282
+ return $unfiltered_allowed;
283
+ }
284
+
285
+ $options = Advanced_Ads::get_instance()->options();
286
+ if ( ! isset( $options['allow-unfiltered-html'] ) ) {
287
+ $options['allow-unfiltered-html'] = array();
288
+ }
289
+ $allowed_roles = $options['allow-unfiltered-html'];
290
+ $user = get_user_by( 'id', $author_id );
291
+
292
+ return ! empty( array_intersect( $user->roles, $allowed_roles ) );
293
+ }
294
+
295
+ /**
296
+ * Check if the current user has a role on this site.
297
+ *
298
+ * @return bool
299
+ */
300
+ private function user_has_role_on_site() {
301
+ return in_array(
302
+ get_current_blog_id(),
303
+ wp_list_pluck( get_blogs_of_user( get_current_user_id() ), 'userblog_id' ),
304
+ true
305
+ );
306
  }
307
  }
classes/plugin.php CHANGED
@@ -199,6 +199,18 @@ class Advanced_Ads_Plugin {
199
  if ( $activated_js || ! empty( $_COOKIE['advads_frontend_picker'] ) ) {
200
  wp_enqueue_script( $this->get_plugin_slug() . '-advanced-js' );
201
  }
 
 
 
 
 
 
 
 
 
 
 
 
202
  }
203
 
204
  /**
199
  if ( $activated_js || ! empty( $_COOKIE['advads_frontend_picker'] ) ) {
200
  wp_enqueue_script( $this->get_plugin_slug() . '-advanced-js' );
201
  }
202
+
203
+ wp_register_script(
204
+ $this->get_plugin_slug() . '-frontend-picker',
205
+ sprintf( '%spublic/assets/js/frontend-picker%s.js', ADVADS_BASE_URL, defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ),
206
+ array( 'jquery', $this->get_plugin_slug() . '-advanced-js' ),
207
+ ADVADS_VERSION,
208
+ false
209
+ );
210
+
211
+ if ( ! empty( $_COOKIE['advads_frontend_picker'] ) ) {
212
+ wp_enqueue_script( $this->get_plugin_slug() . '-frontend-picker' );
213
+ }
214
  }
215
 
216
  /**
languages/advanced-ads.pot CHANGED
@@ -2,20 +2,20 @@
2
  # This file is distributed under the GPL-2.0+.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Advanced Ads 1.34.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: 2022-05-24T08:25:52+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.6.0\n"
15
  "X-Domain: advanced-ads\n"
16
 
17
  #. Plugin Name of the plugin
18
- #: modules/gutenberg/includes/class-gutenberg.php:85
19
  msgid "Advanced Ads"
20
  msgstr ""
21
 
@@ -32,7 +32,7 @@ msgstr ""
32
  msgid "Thomas Maier, Advanced Ads GmbH"
33
  msgstr ""
34
 
35
- #: admin/class-advanced-ads-admin.php:214
36
  #: classes/display-conditions.php:317
37
  #: classes/visitor-conditions.php:311
38
  #: modules/gadsense/admin/views/external-ads-links.php:17
@@ -41,99 +41,103 @@ msgstr ""
41
  msgid "or"
42
  msgstr ""
43
 
44
- #: admin/class-advanced-ads-admin.php:215
45
  #: classes/display-conditions.php:317
46
  #: classes/visitor-conditions.php:311
47
  msgid "and"
48
  msgstr ""
49
 
50
- #: admin/class-advanced-ads-admin.php:216
51
  msgid "After which paragraph?"
52
  msgstr ""
53
 
54
- #: admin/class-advanced-ads-admin.php:218
55
  #: modules/gadsense/includes/class-adsense-report.php:159
56
  msgid "Today"
57
  msgstr ""
58
 
59
- #: admin/class-advanced-ads-admin.php:219
60
  #: modules/gadsense/includes/class-adsense-report.php:160
61
  msgid "Yesterday"
62
  msgstr ""
63
 
64
- #: admin/class-advanced-ads-admin.php:220
65
  #: modules/gadsense/includes/class-adsense-report.php:163
66
  msgid "This Month"
67
  msgstr ""
68
 
69
  #. translators: 1: The number of days.
70
- #: admin/class-advanced-ads-admin.php:222
71
  #: modules/gadsense/includes/class-adsense-report.php:162
72
  #: modules/gadsense/includes/class-adsense-report.php:165
73
  msgid "Last %1$d days"
74
  msgstr ""
75
 
76
- #: admin/class-advanced-ads-admin.php:225
77
  #: modules/gadsense/admin/views/adsense-report.php:24
78
  msgid "All"
79
  msgstr ""
80
 
81
- #: admin/class-advanced-ads-admin.php:226
82
  msgid "There were no results returned for this ad. Please make sure it is active, generating impressions and double check your ad parameters."
83
  msgstr ""
84
 
85
- #: admin/class-advanced-ads-admin.php:227
86
  msgid "Show inactive ads"
87
  msgstr ""
88
 
89
- #: admin/class-advanced-ads-admin.php:228
90
  msgid "Hide inactive ads"
91
  msgstr ""
92
 
93
- #: admin/class-advanced-ads-admin.php:230
94
  msgid "Permanently delete this placement?"
95
  msgstr ""
96
 
97
- #: admin/class-advanced-ads-admin.php:393
98
  #: admin/includes/class-menu.php:166
99
  #: admin/includes/class-menu.php:169
100
  #: admin/views/settings.php:29
101
  msgid "Support"
102
  msgstr ""
103
 
104
- #: admin/class-advanced-ads-admin.php:398
105
  #: admin/includes/class-overview-widgets.php:72
106
  msgid "Add-Ons"
107
  msgstr ""
108
 
109
- #: admin/class-advanced-ads-admin.php:400
110
  msgid "See Pro Features"
111
  msgstr ""
112
 
113
  #. translators: %s is the URL to add a new review, https://wordpress.org/support/plugin/advanced-ads/reviews/#new-post
114
  #. translators: %s is a URL.
115
- #: admin/class-advanced-ads-admin.php:674
116
  #: admin/includes/class-overview-widgets.php:191
117
  msgid "Thank the developer with a &#9733;&#9733;&#9733;&#9733;&#9733; review on <a href=\"%s\" target=\"_blank\">wordpress.org</a>"
118
  msgstr ""
119
 
120
- #: admin/class-advanced-ads-admin.php:757
121
  msgid "Your Ads"
122
  msgstr ""
123
 
124
- #: admin/class-advanced-ads-admin.php:760
125
  msgid "Your Groups"
126
  msgstr ""
127
 
128
- #: admin/class-advanced-ads-admin.php:763
129
  msgid "Your Placements"
130
  msgstr ""
131
 
132
- #: admin/class-advanced-ads-admin.php:766
133
  #: admin/includes/class-menu.php:150
134
  msgid "Advanced Ads Settings"
135
  msgstr ""
136
 
 
 
 
 
137
  #. translators: %1$s is a version number.
138
  #: admin/includes/ad-health-notices.php:32
139
  msgid "Your <strong>PHP version (%1$s) is too low</strong>. Advanced Ads is built for PHP %2$s and higher. It might work, but updating PHP is highly recommended. Please ask your hosting provider for more information."
@@ -147,7 +151,7 @@ msgstr ""
147
  #. translators: %s is a list of PHP extensions.
148
  #. Translators: %s is a name of a module.
149
  #: admin/includes/ad-health-notices.php:54
150
- #: admin/views/placements.php:381
151
  msgid "Missing PHP extensions could cause issues. Please ask your hosting provider to enable them: %s"
152
  msgstr ""
153
 
@@ -331,7 +335,7 @@ msgid "Display ads with the highest ad weight first"
331
  msgstr ""
332
 
333
  #: admin/includes/class-ad-groups-list.php:358
334
- #: admin/views/placements.php:268
335
  #: modules/import-export/classes/import.php:153
336
  #: modules/import-export/classes/import.php:193
337
  #: modules/import-export/classes/import.php:595
@@ -340,8 +344,8 @@ msgid "Edit"
340
  msgstr ""
341
 
342
  #: admin/includes/class-ad-groups-list.php:359
343
- #: admin/views/placements.php:299
344
- msgid "Usage"
345
  msgstr ""
346
 
347
  #: admin/includes/class-ad-groups-list.php:368
@@ -591,7 +595,7 @@ msgstr ""
591
  #: admin/views/placement-form.php:90
592
  #: admin/views/placements-item.php:26
593
  #: classes/widget.php:136
594
- #: modules/gutenberg/includes/class-gutenberg.php:86
595
  #: modules/import-export/views/page.php:23
596
  #: public/class-advanced-ads.php:794
597
  msgid "Ads"
@@ -625,7 +629,7 @@ msgstr ""
625
  #: admin/includes/class-menu.php:142
626
  #: admin/includes/class-shortcode-creator.php:226
627
  #: classes/widget.php:122
628
- #: modules/gutenberg/includes/class-gutenberg.php:88
629
  #: modules/import-export/views/page.php:25
630
  msgid "Placements"
631
  msgstr ""
@@ -636,7 +640,7 @@ msgstr ""
636
 
637
  #: admin/includes/class-menu.php:186
638
  #: admin/includes/class-menu.php:190
639
- #: admin/includes/class-settings.php:298
640
  msgid "Licenses"
641
  msgstr ""
642
 
@@ -668,15 +672,15 @@ msgid "Layout / Output"
668
  msgstr ""
669
 
670
  #: admin/includes/class-meta-box.php:104
671
- #: admin/views/placements.php:176
672
- #: admin/views/placements.php:422
673
  #: classes/ad-debug.php:152
674
  msgid "Display Conditions"
675
  msgstr ""
676
 
677
  #: admin/includes/class-meta-box.php:112
678
- #: admin/views/placements.php:185
679
- #: admin/views/placements.php:430
680
  #: classes/ad-debug.php:239
681
  msgid "Visitor Conditions"
682
  msgstr ""
@@ -697,7 +701,7 @@ msgstr ""
697
  #: admin/views/ad-output-metabox.php:65
698
  #: admin/views/header.php:47
699
  #: admin/views/settings/general/custom-label.php:10
700
- #: classes/ad_type_plain.php:238
701
  #: modules/ads-txt/admin/views/setting-create.php:12
702
  #: modules/privacy/admin/views/setting-general.php:34
703
  msgid "Manual"
@@ -1003,43 +1007,48 @@ msgstr ""
1003
  msgid "Allow editors to manage ads"
1004
  msgstr ""
1005
 
1006
- #: admin/includes/class-settings.php:228
 
 
 
 
 
1007
  msgid "Ad label"
1008
  msgstr ""
1009
 
1010
- #: admin/includes/class-settings.php:237
1011
  msgid "Open links in a new window"
1012
  msgstr ""
1013
 
1014
- #: admin/includes/class-settings.php:245
1015
  msgid "Use advanced JavaScript"
1016
  msgstr ""
1017
 
1018
- #: admin/includes/class-settings.php:255
1019
  msgid "Delete data on uninstall"
1020
  msgstr ""
1021
 
1022
- #: admin/includes/class-settings.php:317
1023
  msgid "Pro"
1024
  msgstr ""
1025
 
1026
- #: admin/includes/class-settings.php:335
1027
  #: admin/views/upgrades/tracking.php:2
1028
  msgid "Tracking"
1029
  msgstr ""
1030
 
1031
- #: admin/includes/class-settings.php:381
1032
  msgid "Are you missing something?"
1033
  msgstr ""
1034
 
1035
- #: admin/includes/class-settings.php:557
1036
  msgctxt "label before ads"
1037
  msgid "Advertisements"
1038
  msgstr ""
1039
 
1040
  #: admin/includes/class-shortcode-creator.php:210
1041
  #: classes/widget.php:120
1042
- #: modules/gutenberg/includes/class-gutenberg.php:84
1043
  msgid "--empty--"
1044
  msgstr ""
1045
 
@@ -1047,7 +1056,7 @@ msgstr ""
1047
  #: admin/views/placement-form.php:83
1048
  #: admin/views/placements-item.php:14
1049
  #: classes/widget.php:129
1050
- #: modules/gutenberg/includes/class-gutenberg.php:87
1051
  msgid "Ad Groups"
1052
  msgstr ""
1053
 
@@ -1193,7 +1202,7 @@ msgid "Update"
1193
  msgstr ""
1194
 
1195
  #: admin/views/ad-group-list-ads.php:20
1196
- #: admin/views/placements.php:340
1197
  #: classes/ad-debug.php:118
1198
  #: classes/ad-debug.php:167
1199
  #: classes/ad-debug.php:169
@@ -1219,7 +1228,7 @@ msgstr ""
1219
 
1220
  #: admin/views/ad-group-list-form-row.php:56
1221
  #: admin/views/placements.php:56
1222
- #: admin/views/placements.php:250
1223
  #: modules/gadsense/admin/views/adsense-ad-parameters.php:105
1224
  msgid "Type"
1225
  msgstr ""
@@ -1246,23 +1255,29 @@ msgstr ""
1246
  msgid "Details"
1247
  msgstr ""
1248
 
1249
- #: admin/views/ad-group-list-row.php:22
1250
  #: admin/views/ad-info.php:7
1251
- #: admin/views/placements.php:303
1252
  msgid "shortcode"
1253
  msgstr ""
1254
 
1255
- #: admin/views/ad-group-list-row.php:25
1256
- msgid "template"
 
 
 
 
 
 
1257
  msgstr ""
1258
 
1259
  #. translators: %s is the name of a group type
1260
- #: admin/views/ad-group-list-row.php:37
1261
  msgid "Type: %s"
1262
  msgstr ""
1263
 
1264
  #. translators: %s is the ID of an ad group
1265
- #: admin/views/ad-group-list-row.php:45
1266
  msgid "ID: %s"
1267
  msgstr ""
1268
 
@@ -1391,7 +1406,7 @@ msgid "Everything connected to the ads layout and output."
1391
  msgstr ""
1392
 
1393
  #: admin/views/ad-output-metabox.php:14
1394
- #: admin/views/placements-ad-label-position.php:10
1395
  msgid "Position"
1396
  msgstr ""
1397
 
@@ -1400,30 +1415,30 @@ msgid "- default -"
1400
  msgstr ""
1401
 
1402
  #: admin/views/ad-output-metabox.php:18
1403
- #: admin/views/placements-ad-label-position.php:11
1404
- #: admin/views/placements-ad-label-position.php:13
1405
  #: admin/views/placements-ad-label.php:9
1406
  #: admin/views/placements-ad-label.php:11
1407
- #: admin/views/placements.php:262
1408
  #: modules/gadsense/includes/class-network-adsense.php:321
1409
  msgid "default"
1410
  msgstr ""
1411
 
1412
  #: admin/views/ad-output-metabox.php:19
1413
- #: admin/views/placements-ad-label-position.php:15
1414
- #: admin/views/placements-ad-label-position.php:17
1415
  msgid "left"
1416
  msgstr ""
1417
 
1418
  #: admin/views/ad-output-metabox.php:22
1419
- #: admin/views/placements-ad-label-position.php:18
1420
- #: admin/views/placements-ad-label-position.php:20
1421
  msgid "center"
1422
  msgstr ""
1423
 
1424
  #: admin/views/ad-output-metabox.php:25
1425
- #: admin/views/placements-ad-label-position.php:21
1426
- #: admin/views/placements-ad-label-position.php:23
1427
  msgid "right"
1428
  msgstr ""
1429
 
@@ -1741,12 +1756,12 @@ msgid "New Ad Group"
1741
  msgstr ""
1742
 
1743
  #: admin/views/header.php:35
1744
- #: admin/views/placements.php:458
1745
  msgid "Create a new placement"
1746
  msgstr ""
1747
 
1748
  #: admin/views/header.php:35
1749
- #: admin/views/placements.php:460
1750
  msgid "New Placement"
1751
  msgstr ""
1752
 
@@ -1756,14 +1771,14 @@ msgstr ""
1756
 
1757
  #: admin/views/modal.php:36
1758
  #: admin/views/modal.php:37
1759
- #: admin/views/placements.php:313
1760
- #: admin/views/placements.php:314
1761
  msgid "Close"
1762
  msgstr ""
1763
 
1764
  #. Translators: 1: "Options", 2: the name of a placement.
1765
  #: admin/views/modal.php:39
1766
- #: admin/views/placements.php:224
1767
  msgid "Close and save"
1768
  msgstr ""
1769
 
@@ -1985,7 +2000,7 @@ msgstr ""
1985
  msgid "Learn more about your choices to display an ad in the <a href=\"%s\" target=\"_blank\">manual</a>."
1986
  msgstr ""
1987
 
1988
- #: admin/views/placements-ad-label-position.php:27
1989
  msgid "Check this if you don’t want the following elements to float around the ad. (adds a placement_clearfix)"
1990
  msgstr ""
1991
 
@@ -2058,101 +2073,93 @@ msgstr ""
2058
  msgid "filter by name"
2059
  msgstr ""
2060
 
2061
- #: admin/views/placements.php:131
2062
- msgid "show usage"
2063
- msgstr ""
2064
-
2065
- #: admin/views/placements.php:155
2066
  msgid "ad label"
2067
  msgstr ""
2068
 
2069
- #: admin/views/placements.php:167
2070
  msgid "Inline CSS"
2071
  msgstr ""
2072
 
2073
- #: admin/views/placements.php:178
2074
  msgid "Use display conditions for placements."
2075
  msgstr ""
2076
 
2077
- #: admin/views/placements.php:179
2078
- #: admin/views/placements.php:188
2079
  msgid "The free version provides conditions on the ad edit page."
2080
  msgstr ""
2081
 
2082
- #: admin/views/placements.php:187
2083
  msgid "Use visitor conditions for placements."
2084
  msgstr ""
2085
 
2086
- #: admin/views/placements.php:194
2087
  msgid "Minimum Content Length"
2088
  msgstr ""
2089
 
2090
- #: admin/views/placements.php:196
2091
  msgid "Minimum length of content before automatically injected ads are allowed in them."
2092
  msgstr ""
2093
 
2094
- #: admin/views/placements.php:202
2095
  msgid "Words Between Ads"
2096
  msgstr ""
2097
 
2098
- #: admin/views/placements.php:204
2099
  msgid "A minimum amount of words between automatically injected ads."
2100
  msgstr ""
2101
 
2102
  #. Translators: 1: "Options", 2: the name of a placement.
2103
- #: admin/views/placements.php:223
2104
  #: modules/import-export/views/page.php:26
2105
  msgid "Options"
2106
  msgstr ""
2107
 
2108
  #. Translators: %s is the name of a placement.
2109
- #: admin/views/placements.php:235
2110
  msgid "Placement type \"%s\" is missing and was reset to \"default\".<br/>Please check if the responsible add-on is activated."
2111
  msgstr ""
2112
 
2113
- #: admin/views/placements.php:306
2114
- msgid "template (PHP)"
2115
- msgstr ""
2116
-
2117
- #: admin/views/placements.php:341
2118
  msgid "Group"
2119
  msgstr ""
2120
 
2121
- #: admin/views/placements.php:357
2122
  msgid "after"
2123
  msgstr ""
2124
 
2125
- #: admin/views/placements.php:358
2126
  msgid "before"
2127
  msgstr ""
2128
 
2129
- #: admin/views/placements.php:371
2130
  msgid "position"
2131
  msgstr ""
2132
 
2133
- #: admin/views/placements.php:377
2134
  msgid "Important Notice"
2135
  msgstr ""
2136
 
2137
  #. Translators: %s is a URL.
2138
- #: admin/views/placements.php:400
2139
  msgid "Tutorial: <a href=\"%s\" target=\"_blank\">How to place visible ads in the header of your website</a>."
2140
  msgstr ""
2141
 
2142
- #: admin/views/placements.php:416
2143
  msgid "show all options"
2144
  msgstr ""
2145
 
2146
- #: admin/views/placements.php:439
2147
  msgid "edit conditions"
2148
  msgstr ""
2149
 
2150
- #: admin/views/placements.php:449
2151
  msgctxt "checkbox to remove placement"
2152
  msgid "delete"
2153
  msgstr ""
2154
 
2155
- #: admin/views/placements.php:456
2156
  msgid "Save Placements"
2157
  msgstr ""
2158
 
@@ -2227,6 +2234,14 @@ msgstr ""
2227
  msgid "Enable advanced JavaScript functions (<a href=\"%s\" target=\"_blank\">here</a>). Some features and add-ons might override this setting if they need features from this file."
2228
  msgstr ""
2229
 
 
 
 
 
 
 
 
 
2230
  #: admin/views/settings/general/block-bots.php:5
2231
  #: classes/frontend_checks.php:123
2232
  msgid "You look like a bot"
@@ -2804,14 +2819,18 @@ msgstr ""
2804
  msgid "No shortcode detected in your code."
2805
  msgstr ""
2806
 
2807
- #: classes/ad_type_plain.php:232
2808
  msgid "You do not have sufficient permissions to include all HTML tags."
2809
  msgstr ""
2810
 
2811
- #: classes/ad_type_plain.php:234
2812
  msgid "The creator of the ad does not have sufficient permissions to include all HTML tags."
2813
  msgstr ""
2814
 
 
 
 
 
2815
  #: classes/display-conditions.php:89
2816
  msgid "post type"
2817
  msgstr ""
2
  # This file is distributed under the GPL-2.0+.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Advanced Ads 1.35.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: 2022-08-09T08:21:22+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.6.0\n"
15
  "X-Domain: advanced-ads\n"
16
 
17
  #. Plugin Name of the plugin
18
+ #: modules/gutenberg/includes/class-gutenberg.php:90
19
  msgid "Advanced Ads"
20
  msgstr ""
21
 
32
  msgid "Thomas Maier, Advanced Ads GmbH"
33
  msgstr ""
34
 
35
+ #: admin/class-advanced-ads-admin.php:215
36
  #: classes/display-conditions.php:317
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:216
45
  #: classes/display-conditions.php:317
46
  #: classes/visitor-conditions.php:311
47
  msgid "and"
48
  msgstr ""
49
 
50
+ #: admin/class-advanced-ads-admin.php:217
51
  msgid "After which paragraph?"
52
  msgstr ""
53
 
54
+ #: admin/class-advanced-ads-admin.php:219
55
  #: modules/gadsense/includes/class-adsense-report.php:159
56
  msgid "Today"
57
  msgstr ""
58
 
59
+ #: admin/class-advanced-ads-admin.php:220
60
  #: modules/gadsense/includes/class-adsense-report.php:160
61
  msgid "Yesterday"
62
  msgstr ""
63
 
64
+ #: admin/class-advanced-ads-admin.php:221
65
  #: modules/gadsense/includes/class-adsense-report.php:163
66
  msgid "This Month"
67
  msgstr ""
68
 
69
  #. translators: 1: The number of days.
70
+ #: admin/class-advanced-ads-admin.php:223
71
  #: modules/gadsense/includes/class-adsense-report.php:162
72
  #: modules/gadsense/includes/class-adsense-report.php:165
73
  msgid "Last %1$d days"
74
  msgstr ""
75
 
76
+ #: admin/class-advanced-ads-admin.php:226
77
  #: modules/gadsense/admin/views/adsense-report.php:24
78
  msgid "All"
79
  msgstr ""
80
 
81
+ #: admin/class-advanced-ads-admin.php:227
82
  msgid "There were no results returned for this ad. Please make sure it is active, generating impressions and double check your ad parameters."
83
  msgstr ""
84
 
85
+ #: admin/class-advanced-ads-admin.php:228
86
  msgid "Show inactive ads"
87
  msgstr ""
88
 
89
+ #: admin/class-advanced-ads-admin.php:229
90
  msgid "Hide inactive ads"
91
  msgstr ""
92
 
93
+ #: admin/class-advanced-ads-admin.php:231
94
  msgid "Permanently delete this placement?"
95
  msgstr ""
96
 
97
+ #: admin/class-advanced-ads-admin.php:394
98
  #: admin/includes/class-menu.php:166
99
  #: admin/includes/class-menu.php:169
100
  #: admin/views/settings.php:29
101
  msgid "Support"
102
  msgstr ""
103
 
104
+ #: admin/class-advanced-ads-admin.php:399
105
  #: admin/includes/class-overview-widgets.php:72
106
  msgid "Add-Ons"
107
  msgstr ""
108
 
109
+ #: admin/class-advanced-ads-admin.php:401
110
  msgid "See Pro Features"
111
  msgstr ""
112
 
113
  #. translators: %s is the URL to add a new review, https://wordpress.org/support/plugin/advanced-ads/reviews/#new-post
114
  #. translators: %s is a URL.
115
+ #: admin/class-advanced-ads-admin.php:675
116
  #: admin/includes/class-overview-widgets.php:191
117
  msgid "Thank the developer with a &#9733;&#9733;&#9733;&#9733;&#9733; review on <a href=\"%s\" target=\"_blank\">wordpress.org</a>"
118
  msgstr ""
119
 
120
+ #: admin/class-advanced-ads-admin.php:758
121
  msgid "Your Ads"
122
  msgstr ""
123
 
124
+ #: admin/class-advanced-ads-admin.php:761
125
  msgid "Your Groups"
126
  msgstr ""
127
 
128
+ #: admin/class-advanced-ads-admin.php:764
129
  msgid "Your Placements"
130
  msgstr ""
131
 
132
+ #: admin/class-advanced-ads-admin.php:767
133
  #: admin/includes/class-menu.php:150
134
  msgid "Advanced Ads Settings"
135
  msgstr ""
136
 
137
+ #: admin/includes/ad-authors.php:115
138
+ msgid "Sorry, you're not allowed to assign this user."
139
+ msgstr ""
140
+
141
  #. translators: %1$s is a version number.
142
  #: admin/includes/ad-health-notices.php:32
143
  msgid "Your <strong>PHP version (%1$s) is too low</strong>. Advanced Ads is built for PHP %2$s and higher. It might work, but updating PHP is highly recommended. Please ask your hosting provider for more information."
151
  #. translators: %s is a list of PHP extensions.
152
  #. Translators: %s is a name of a module.
153
  #: admin/includes/ad-health-notices.php:54
154
+ #: admin/views/placements.php:389
155
  msgid "Missing PHP extensions could cause issues. Please ask your hosting provider to enable them: %s"
156
  msgstr ""
157
 
335
  msgstr ""
336
 
337
  #: admin/includes/class-ad-groups-list.php:358
338
+ #: admin/views/placements.php:276
339
  #: modules/import-export/classes/import.php:153
340
  #: modules/import-export/classes/import.php:193
341
  #: modules/import-export/classes/import.php:595
344
  msgstr ""
345
 
346
  #: admin/includes/class-ad-groups-list.php:359
347
+ #: admin/views/placements.php:131
348
+ msgid "show usage"
349
  msgstr ""
350
 
351
  #: admin/includes/class-ad-groups-list.php:368
595
  #: admin/views/placement-form.php:90
596
  #: admin/views/placements-item.php:26
597
  #: classes/widget.php:136
598
+ #: modules/gutenberg/includes/class-gutenberg.php:91
599
  #: modules/import-export/views/page.php:23
600
  #: public/class-advanced-ads.php:794
601
  msgid "Ads"
629
  #: admin/includes/class-menu.php:142
630
  #: admin/includes/class-shortcode-creator.php:226
631
  #: classes/widget.php:122
632
+ #: modules/gutenberg/includes/class-gutenberg.php:93
633
  #: modules/import-export/views/page.php:25
634
  msgid "Placements"
635
  msgstr ""
640
 
641
  #: admin/includes/class-menu.php:186
642
  #: admin/includes/class-menu.php:190
643
+ #: admin/includes/class-settings.php:311
644
  msgid "Licenses"
645
  msgstr ""
646
 
672
  msgstr ""
673
 
674
  #: admin/includes/class-meta-box.php:104
675
+ #: admin/views/placements.php:184
676
+ #: admin/views/placements.php:430
677
  #: classes/ad-debug.php:152
678
  msgid "Display Conditions"
679
  msgstr ""
680
 
681
  #: admin/includes/class-meta-box.php:112
682
+ #: admin/views/placements.php:193
683
+ #: admin/views/placements.php:438
684
  #: classes/ad-debug.php:239
685
  msgid "Visitor Conditions"
686
  msgstr ""
701
  #: admin/views/ad-output-metabox.php:65
702
  #: admin/views/header.php:47
703
  #: admin/views/settings/general/custom-label.php:10
704
+ #: classes/ad_type_plain.php:250
705
  #: modules/ads-txt/admin/views/setting-create.php:12
706
  #: modules/privacy/admin/views/setting-general.php:34
707
  msgid "Manual"
1007
  msgid "Allow editors to manage ads"
1008
  msgstr ""
1009
 
1010
+ #. translators: unfiltered_html
1011
+ #: admin/includes/class-settings.php:231
1012
+ msgid "Add the %s capability to user roles on multisite"
1013
+ msgstr ""
1014
+
1015
+ #: admin/includes/class-settings.php:241
1016
  msgid "Ad label"
1017
  msgstr ""
1018
 
1019
+ #: admin/includes/class-settings.php:250
1020
  msgid "Open links in a new window"
1021
  msgstr ""
1022
 
1023
+ #: admin/includes/class-settings.php:258
1024
  msgid "Use advanced JavaScript"
1025
  msgstr ""
1026
 
1027
+ #: admin/includes/class-settings.php:268
1028
  msgid "Delete data on uninstall"
1029
  msgstr ""
1030
 
1031
+ #: admin/includes/class-settings.php:330
1032
  msgid "Pro"
1033
  msgstr ""
1034
 
1035
+ #: admin/includes/class-settings.php:348
1036
  #: admin/views/upgrades/tracking.php:2
1037
  msgid "Tracking"
1038
  msgstr ""
1039
 
1040
+ #: admin/includes/class-settings.php:394
1041
  msgid "Are you missing something?"
1042
  msgstr ""
1043
 
1044
+ #: admin/includes/class-settings.php:591
1045
  msgctxt "label before ads"
1046
  msgid "Advertisements"
1047
  msgstr ""
1048
 
1049
  #: admin/includes/class-shortcode-creator.php:210
1050
  #: classes/widget.php:120
1051
+ #: modules/gutenberg/includes/class-gutenberg.php:89
1052
  msgid "--empty--"
1053
  msgstr ""
1054
 
1056
  #: admin/views/placement-form.php:83
1057
  #: admin/views/placements-item.php:14
1058
  #: classes/widget.php:129
1059
+ #: modules/gutenberg/includes/class-gutenberg.php:92
1060
  msgid "Ad Groups"
1061
  msgstr ""
1062
 
1202
  msgstr ""
1203
 
1204
  #: admin/views/ad-group-list-ads.php:20
1205
+ #: admin/views/placements.php:348
1206
  #: classes/ad-debug.php:118
1207
  #: classes/ad-debug.php:167
1208
  #: classes/ad-debug.php:169
1228
 
1229
  #: admin/views/ad-group-list-form-row.php:56
1230
  #: admin/views/placements.php:56
1231
+ #: admin/views/placements.php:258
1232
  #: modules/gadsense/admin/views/adsense-ad-parameters.php:105
1233
  msgid "Type"
1234
  msgstr ""
1255
  msgid "Details"
1256
  msgstr ""
1257
 
1258
+ #: admin/views/ad-group-list-row.php:26
1259
  #: admin/views/ad-info.php:7
1260
+ #: admin/views/placements.php:311
1261
  msgid "shortcode"
1262
  msgstr ""
1263
 
1264
+ #: admin/views/ad-group-list-row.php:28
1265
+ #: admin/views/placements.php:314
1266
+ msgid "template (PHP)"
1267
+ msgstr ""
1268
+
1269
+ #: admin/views/ad-group-list-row.php:33
1270
+ #: admin/views/placements.php:307
1271
+ msgid "Usage"
1272
  msgstr ""
1273
 
1274
  #. translators: %s is the name of a group type
1275
+ #: admin/views/ad-group-list-row.php:44
1276
  msgid "Type: %s"
1277
  msgstr ""
1278
 
1279
  #. translators: %s is the ID of an ad group
1280
+ #: admin/views/ad-group-list-row.php:52
1281
  msgid "ID: %s"
1282
  msgstr ""
1283
 
1406
  msgstr ""
1407
 
1408
  #: admin/views/ad-output-metabox.php:14
1409
+ #: admin/views/placements.php:163
1410
  msgid "Position"
1411
  msgstr ""
1412
 
1415
  msgstr ""
1416
 
1417
  #: admin/views/ad-output-metabox.php:18
1418
+ #: admin/views/placements-ad-label-position.php:10
1419
+ #: admin/views/placements-ad-label-position.php:12
1420
  #: admin/views/placements-ad-label.php:9
1421
  #: admin/views/placements-ad-label.php:11
1422
+ #: admin/views/placements.php:270
1423
  #: modules/gadsense/includes/class-network-adsense.php:321
1424
  msgid "default"
1425
  msgstr ""
1426
 
1427
  #: admin/views/ad-output-metabox.php:19
1428
+ #: admin/views/placements-ad-label-position.php:14
1429
+ #: admin/views/placements-ad-label-position.php:16
1430
  msgid "left"
1431
  msgstr ""
1432
 
1433
  #: admin/views/ad-output-metabox.php:22
1434
+ #: admin/views/placements-ad-label-position.php:17
1435
+ #: admin/views/placements-ad-label-position.php:19
1436
  msgid "center"
1437
  msgstr ""
1438
 
1439
  #: admin/views/ad-output-metabox.php:25
1440
+ #: admin/views/placements-ad-label-position.php:20
1441
+ #: admin/views/placements-ad-label-position.php:22
1442
  msgid "right"
1443
  msgstr ""
1444
 
1756
  msgstr ""
1757
 
1758
  #: admin/views/header.php:35
1759
+ #: admin/views/placements.php:466
1760
  msgid "Create a new placement"
1761
  msgstr ""
1762
 
1763
  #: admin/views/header.php:35
1764
+ #: admin/views/placements.php:468
1765
  msgid "New Placement"
1766
  msgstr ""
1767
 
1771
 
1772
  #: admin/views/modal.php:36
1773
  #: admin/views/modal.php:37
1774
+ #: admin/views/placements.php:321
1775
+ #: admin/views/placements.php:322
1776
  msgid "Close"
1777
  msgstr ""
1778
 
1779
  #. Translators: 1: "Options", 2: the name of a placement.
1780
  #: admin/views/modal.php:39
1781
+ #: admin/views/placements.php:232
1782
  msgid "Close and save"
1783
  msgstr ""
1784
 
2000
  msgid "Learn more about your choices to display an ad in the <a href=\"%s\" target=\"_blank\">manual</a>."
2001
  msgstr ""
2002
 
2003
+ #: admin/views/placements-ad-label-position.php:26
2004
  msgid "Check this if you don’t want the following elements to float around the ad. (adds a placement_clearfix)"
2005
  msgstr ""
2006
 
2073
  msgid "filter by name"
2074
  msgstr ""
2075
 
2076
+ #: admin/views/placements.php:152
 
 
 
 
2077
  msgid "ad label"
2078
  msgstr ""
2079
 
2080
+ #: admin/views/placements.php:175
2081
  msgid "Inline CSS"
2082
  msgstr ""
2083
 
2084
+ #: admin/views/placements.php:186
2085
  msgid "Use display conditions for placements."
2086
  msgstr ""
2087
 
2088
+ #: admin/views/placements.php:187
2089
+ #: admin/views/placements.php:196
2090
  msgid "The free version provides conditions on the ad edit page."
2091
  msgstr ""
2092
 
2093
+ #: admin/views/placements.php:195
2094
  msgid "Use visitor conditions for placements."
2095
  msgstr ""
2096
 
2097
+ #: admin/views/placements.php:202
2098
  msgid "Minimum Content Length"
2099
  msgstr ""
2100
 
2101
+ #: admin/views/placements.php:204
2102
  msgid "Minimum length of content before automatically injected ads are allowed in them."
2103
  msgstr ""
2104
 
2105
+ #: admin/views/placements.php:210
2106
  msgid "Words Between Ads"
2107
  msgstr ""
2108
 
2109
+ #: admin/views/placements.php:212
2110
  msgid "A minimum amount of words between automatically injected ads."
2111
  msgstr ""
2112
 
2113
  #. Translators: 1: "Options", 2: the name of a placement.
2114
+ #: admin/views/placements.php:231
2115
  #: modules/import-export/views/page.php:26
2116
  msgid "Options"
2117
  msgstr ""
2118
 
2119
  #. Translators: %s is the name of a placement.
2120
+ #: admin/views/placements.php:243
2121
  msgid "Placement type \"%s\" is missing and was reset to \"default\".<br/>Please check if the responsible add-on is activated."
2122
  msgstr ""
2123
 
2124
+ #: admin/views/placements.php:349
 
 
 
 
2125
  msgid "Group"
2126
  msgstr ""
2127
 
2128
+ #: admin/views/placements.php:365
2129
  msgid "after"
2130
  msgstr ""
2131
 
2132
+ #: admin/views/placements.php:366
2133
  msgid "before"
2134
  msgstr ""
2135
 
2136
+ #: admin/views/placements.php:379
2137
  msgid "position"
2138
  msgstr ""
2139
 
2140
+ #: admin/views/placements.php:385
2141
  msgid "Important Notice"
2142
  msgstr ""
2143
 
2144
  #. Translators: %s is a URL.
2145
+ #: admin/views/placements.php:408
2146
  msgid "Tutorial: <a href=\"%s\" target=\"_blank\">How to place visible ads in the header of your website</a>."
2147
  msgstr ""
2148
 
2149
+ #: admin/views/placements.php:424
2150
  msgid "show all options"
2151
  msgstr ""
2152
 
2153
+ #: admin/views/placements.php:447
2154
  msgid "edit conditions"
2155
  msgstr ""
2156
 
2157
+ #: admin/views/placements.php:457
2158
  msgctxt "checkbox to remove placement"
2159
  msgid "delete"
2160
  msgstr ""
2161
 
2162
+ #: admin/views/placements.php:464
2163
  msgid "Save Placements"
2164
  msgstr ""
2165
 
2234
  msgid "Enable advanced JavaScript functions (<a href=\"%s\" target=\"_blank\">here</a>). Some features and add-ons might override this setting if they need features from this file."
2235
  msgstr ""
2236
 
2237
+ #: admin/views/settings/general/allow-unfiltered-html.php:10
2238
+ msgid "Allow unfiltered HTML for these user roles:"
2239
+ msgstr ""
2240
+
2241
+ #: admin/views/settings/general/allow-unfiltered-html.php:25
2242
+ msgid "Enabling this option for untrusted users may cause them to publish malicious or poorly formatted code in their ads and can be a potential security risk. You should carefully consider which user roles you grant this capability."
2243
+ msgstr ""
2244
+
2245
  #: admin/views/settings/general/block-bots.php:5
2246
  #: classes/frontend_checks.php:123
2247
  msgid "You look like a bot"
2819
  msgid "No shortcode detected in your code."
2820
  msgstr ""
2821
 
2822
+ #: classes/ad_type_plain.php:241
2823
  msgid "You do not have sufficient permissions to include all HTML tags."
2824
  msgstr ""
2825
 
2826
+ #: classes/ad_type_plain.php:243
2827
  msgid "The creator of the ad does not have sufficient permissions to include all HTML tags."
2828
  msgstr ""
2829
 
2830
+ #: classes/ad_type_plain.php:245
2831
+ msgid "Assign ad to me"
2832
+ msgstr ""
2833
+
2834
  #: classes/display-conditions.php:89
2835
  msgid "post type"
2836
  msgstr ""
lib/composer/autoload_classmap.php CHANGED
@@ -11,6 +11,7 @@ return array(
11
  'Advanced_Ads' => $baseDir . '/public/class-advanced-ads.php',
12
  'Advanced_Ads_Ad' => $baseDir . '/classes/ad.php',
13
  'Advanced_Ads_Ad_Ajax_Callbacks' => $baseDir . '/classes/ad_ajax_callbacks.php',
 
14
  'Advanced_Ads_Ad_Debug' => $baseDir . '/classes/ad-debug.php',
15
  'Advanced_Ads_Ad_Expiration' => $baseDir . '/classes/ad-expiration.php',
16
  'Advanced_Ads_Ad_Health_Notices' => $baseDir . '/classes/ad-health-notices.php',
11
  'Advanced_Ads' => $baseDir . '/public/class-advanced-ads.php',
12
  'Advanced_Ads_Ad' => $baseDir . '/classes/ad.php',
13
  'Advanced_Ads_Ad_Ajax_Callbacks' => $baseDir . '/classes/ad_ajax_callbacks.php',
14
+ 'Advanced_Ads_Ad_Authors' => $baseDir . '/admin/includes/ad-authors.php',
15
  'Advanced_Ads_Ad_Debug' => $baseDir . '/classes/ad-debug.php',
16
  'Advanced_Ads_Ad_Expiration' => $baseDir . '/classes/ad-expiration.php',
17
  'Advanced_Ads_Ad_Health_Notices' => $baseDir . '/classes/ad-health-notices.php',
lib/composer/autoload_static.php CHANGED
@@ -12,6 +12,7 @@ class ComposerStaticInit_advanced_ads
12
  'Advanced_Ads' => __DIR__ . '/../..' . '/public/class-advanced-ads.php',
13
  'Advanced_Ads_Ad' => __DIR__ . '/../..' . '/classes/ad.php',
14
  'Advanced_Ads_Ad_Ajax_Callbacks' => __DIR__ . '/../..' . '/classes/ad_ajax_callbacks.php',
 
15
  'Advanced_Ads_Ad_Debug' => __DIR__ . '/../..' . '/classes/ad-debug.php',
16
  'Advanced_Ads_Ad_Expiration' => __DIR__ . '/../..' . '/classes/ad-expiration.php',
17
  'Advanced_Ads_Ad_Health_Notices' => __DIR__ . '/../..' . '/classes/ad-health-notices.php',
12
  'Advanced_Ads' => __DIR__ . '/../..' . '/public/class-advanced-ads.php',
13
  'Advanced_Ads_Ad' => __DIR__ . '/../..' . '/classes/ad.php',
14
  'Advanced_Ads_Ad_Ajax_Callbacks' => __DIR__ . '/../..' . '/classes/ad_ajax_callbacks.php',
15
+ 'Advanced_Ads_Ad_Authors' => __DIR__ . '/../..' . '/admin/includes/ad-authors.php',
16
  'Advanced_Ads_Ad_Debug' => __DIR__ . '/../..' . '/classes/ad-debug.php',
17
  'Advanced_Ads_Ad_Expiration' => __DIR__ . '/../..' . '/classes/ad-expiration.php',
18
  'Advanced_Ads_Ad_Health_Notices' => __DIR__ . '/../..' . '/classes/ad-health-notices.php',
modules/gutenberg/includes/class-gutenberg.php CHANGED
@@ -28,8 +28,13 @@ class Advanced_Ads_Gutenberg {
28
  'render_callback' => array( $this, 'render_ad_selector' ),
29
  ) );
30
 
31
- // Removes legacy widget from legacy widget block.
32
- add_filter( 'widget_types_to_hide_from_legacy_widget_block', function() {
 
 
 
 
 
33
  $widget_types[] = 'advads_ad_widget';
34
 
35
  return $widget_types;
28
  'render_callback' => array( $this, 'render_ad_selector' ),
29
  ) );
30
 
31
+ /**
32
+ * Removes legacy widget from legacy widget block.
33
+ *
34
+ * @param string[] $widget_types An array of excluded widget-type IDs.
35
+ * @return array
36
+ */
37
+ add_filter( 'widget_types_to_hide_from_legacy_widget_block', function( $widget_types ) {
38
  $widget_types[] = 'advads_ad_widget';
39
 
40
  return $widget_types;
public/assets/js/advanced.js CHANGED
@@ -671,269 +671,3 @@ document.addEventListener( 'advanced_ads_privacy', function ( event ) {
671
  document.querySelectorAll( 'script[type="text/plain"][data-tcf="waiting-for-consent"]' ).forEach( advads.privacy.decode_ad );
672
  } );
673
 
674
- // highlight elements in frontend, if local storage variable is set
675
- jQuery( document ).ready( function () {
676
-
677
- function is_enabled() {
678
- if ( ! advads.supports_localstorage() || ! localStorage.getItem( 'advads_frontend_picker' ) ) {
679
- return false;
680
- }
681
-
682
- // Check if the frontend picker was started on the current blog.
683
- if ( window.advads_options.blog_id
684
- && localStorage.getItem( 'advads_frontend_blog_id' )
685
- && window.advads_options.blog_id !== localStorage.getItem( 'advads_frontend_blog_id' ) ) {
686
- return false;
687
- }
688
-
689
- // Deactivate the frontend picker if it was started more than 45 minutes ago.
690
- if ( localStorage.getItem( 'advads_frontend_starttime' )
691
- && parseInt( localStorage.getItem( 'advads_frontend_starttime' ), 10 ) < (
692
- new Date().getTime()
693
- ) - 45 * 60 * 1000 ) {
694
- localStorage.removeItem( 'advads_frontend_action' );
695
- localStorage.removeItem( 'advads_frontend_element' );
696
- localStorage.removeItem( 'advads_frontend_picker' );
697
- localStorage.removeItem( 'advads_prev_url' );
698
- localStorage.removeItem( 'advads_frontend_pathtype' );
699
- localStorage.removeItem( 'advads_frontend_boundary' );
700
- localStorage.removeItem( 'advads_frontend_blog_id' );
701
- localStorage.removeItem( 'advads_frontend_starttime' );
702
- advads.set_cookie( 'advads_frontend_picker', '', - 1 );
703
- return false;
704
- }
705
-
706
- return true;
707
- }
708
-
709
- // only trigger if local storage is available
710
- if ( is_enabled() ) {
711
- var advads_picker_cur, advads_picker_overlay = jQuery( "<div id='advads-picker-overlay'>" ),
712
- advads_picker_no = [document.body, document.documentElement, document];
713
- advads_picker_overlay.css( {
714
- position: 'absolute', border: 'solid 2px #428bca',
715
- backgroundColor: 'rgba(66,139,202,0.5)', boxSizing: 'border-box',
716
- zIndex: 1000000, pointerEvents: 'none'
717
- } ).prependTo( 'body' );
718
-
719
- if ( 'true' === localStorage.getItem( 'advads_frontend_boundary' ) ) {
720
- jQuery( 'body' ).css( 'cursor', 'not-allowed' );
721
- }
722
-
723
- /**
724
- * Check if we can traverse up the dom tree.
725
- *
726
- * We cannot use event delegation because:
727
- * - the content can be loaded via AJAX dynamically
728
- * - we cannot wrap the content in a `div` that represents post boundary
729
- * because that may prevent css rules from working
730
- *
731
- * @param HTMLElement The current element.
732
- * return bool
733
- */
734
- window.advads.is_boundary_reached = function ( advads_picker_cur ) {
735
- if ( 'true' !== localStorage.getItem( 'advads_frontend_boundary' ) ) {
736
- return false;
737
- }
738
- $advads_picker_cur = jQuery( advads_picker_cur );
739
- // A boundary helper is the `ins` element inside of the post content
740
- // that is used to determine the post boundary (where the content starts and ends).
741
- var $boundary_helpers = jQuery( '.advads-frontend-picker-boundary-helper' );
742
-
743
- $boundaries = $boundary_helpers.parent();
744
- $boundaries.css( 'cursor', 'pointer' );
745
- return $advads_picker_cur.is( $boundaries ) || ! $advads_picker_cur.closest( $boundaries ).length;
746
- }
747
-
748
- if ( 'xpath' === localStorage.getItem( 'advads_frontend_pathtype' ) ) {
749
- var fn = 'getXPath';
750
- } else {
751
- var fn = 'getPath';
752
- }
753
-
754
- jQuery( document ).mousemove( function ( e ) {
755
- if ( e.target === advads_picker_cur ) {
756
- return;
757
- }
758
-
759
- if ( ~ advads_picker_no.indexOf( e.target ) ) {
760
- advads_picker_cur = null;
761
- advads_picker_overlay.hide();
762
- return;
763
- }
764
-
765
- var target = jQuery( e.target ),
766
- offset = target.offset(),
767
- width = target.outerWidth(),
768
- height = target.outerHeight();
769
-
770
- advads_picker_cur = e.target;
771
-
772
- var path = jQuery( advads_picker_cur )[fn]();
773
- if ( ! path ) {
774
- // A click outside of the boundary.
775
- // @see `is_boundary_reached`.
776
- return;
777
- }
778
- //log path
779
- console.log( path );
780
-
781
- advads_picker_overlay.css( {
782
- top: offset.top,
783
- left: offset.left,
784
- width: width,
785
- height: height
786
- } ).show();
787
-
788
- } );
789
- // save on click
790
- jQuery( document ).click( function ( e ) {
791
- var path = jQuery( advads_picker_cur )[fn]();
792
-
793
- if ( advads.is_boundary_reached( advads_picker_cur ) ) {
794
- return;
795
- }
796
-
797
- localStorage.setItem( 'advads_frontend_element', path );
798
- window.location = localStorage.getItem( 'advads_prev_url' );
799
- } );
800
- }
801
- ;
802
- } );
803
- /*
804
- derrived from jQuery-GetPath v0.01, by Dave Cardwell. (2007-04-27)
805
- http://davecardwell.co.uk/javascript/jquery/plugins/jquery-getpath/
806
- Usage:
807
- var path = $('#foo').getPath();
808
- */
809
-
810
- jQuery.fn.extend( {
811
- getPath: function ( path, depth ) {
812
- // The first time this function is called, path won't be defined.
813
- if ( typeof path === 'undefined' ) {
814
- path = '';
815
- }
816
- if ( typeof depth === 'undefined' ) {
817
- depth = 0;
818
- }
819
-
820
- // If this element is <html> we've reached the end of the path.
821
- // also end after 2 elements
822
- if ( this.is( 'html' ) ) {
823
- return 'html > ' + path;
824
- } else if ( 3 === depth ) {
825
- return path;
826
- }
827
-
828
- // Add the element name.
829
- var cur = this.get( 0 ).nodeName.toLowerCase();
830
-
831
- // Determine the IDs and path.
832
- var el_id = this.attr( 'id' ),
833
- el_class = this.attr( 'class' );
834
-
835
- depth = depth + 1;
836
-
837
- // Add the #id if there is one. Ignore ID with number.
838
- if ( typeof el_id !== 'undefined' && ! /\d/.test( el_id ) ) {
839
- cur += '#' + el_id;
840
- } else if ( typeof el_class !== 'undefined' ) {
841
- // Add classes if there is no id.
842
- el_class = el_class.split( /[\s\n]+/ );
843
- // Skip classes with numbers.
844
- el_class = jQuery.grep( el_class, function ( element, index ) {
845
- return ! /\d/.test( element )
846
- } );
847
- // Add 2 classes.
848
- if ( el_class.length ) {
849
- cur += '.' + el_class.slice( 0, 2 ).join( '.' );
850
- }
851
- }
852
-
853
- // add index if this element is not unique among its siblings
854
- if ( this.siblings( cur ).length ) {
855
- cur += ":eq(" + this.siblings( cur ).addBack().not( '#advads-picker-overlay' ).index( this ) + ")";
856
- }
857
-
858
- // Recurse up the DOM.
859
- if ( path === '' ) {
860
- return this.parent().getPath( cur, depth );
861
- } else {
862
- return this.parent().getPath( cur + ' > ' + path, depth );
863
- }
864
- },
865
-
866
- /**
867
- * Get XPath.
868
- */
869
- getXPath: function ( path, depth ) {
870
- // The first time this function is called, path won't be defined.
871
- if ( typeof path === 'undefined' ) {
872
- path = '';
873
- }
874
- if ( typeof depth === 'undefined' ) {
875
- depth = 0;
876
- }
877
-
878
- // If this element is <html> we've reached the end of the path.
879
- // also end after 2 elements
880
- if ( this.is( 'body' ) || 3 === depth ) {
881
- return path;
882
- }
883
-
884
- if ( advads.is_boundary_reached( this ) ) {
885
- return path;
886
- }
887
-
888
- // Add the element name.
889
- var tag = this.get( 0 ).nodeName.toLowerCase();
890
- var cur = tag;
891
-
892
- // Determine the IDs and path.
893
- var el_id = this.attr( 'id' ),
894
- el_class = this.attr( 'class' );
895
- var classes = [];
896
-
897
- // Add the #id if there is one. Ignore ID with number.
898
- if ( typeof el_id !== 'undefined' && ! /\d/.test( el_id ) ) {
899
- return cur + '[@id and id="' + el_id + '"]/' + path;
900
- } else if ( typeof el_class !== 'undefined' ) {
901
- // Add classes if there is no id.
902
- el_class = el_class.split( /[\s\n]+/ );
903
- // Skip classes with numbers.
904
- el_class = jQuery.grep( el_class, function ( element, index ) {
905
- return ! /\d/.test( element )
906
- } );
907
- // Add 2 classes.
908
- if ( el_class.length ) {
909
- depth = depth + 1;
910
- var classes = el_class.slice( 0, 2 );
911
-
912
- var xpath_classes = [];
913
- for ( var i = 0; i < classes.length; i ++ ) {
914
- xpath_classes.push( '(@class and contains(concat(" ", normalize-space(@class), " "), " ' + classes[i] + ' "))' );
915
- }
916
- cur += '[' + xpath_classes.join( ' and ' ) + ']';
917
- }
918
- }
919
-
920
- // Add index if this element is not unique among its siblings.
921
- if ( classes.length ) {
922
- var $siblings = this.siblings( tag + '.' + classes.join( '.' ) );
923
- } else {
924
- var $siblings = this.siblings( tag );
925
- }
926
-
927
- if ( $siblings.length ) {
928
- var index = $siblings.addBack().not( '#advads-picker-overlay' ).index( this );
929
- cur += '[' + index + ']';
930
- }
931
-
932
- // Recurse up the DOM.
933
- if ( path === '' ) {
934
- return this.parent().getXPath( cur, depth );
935
- } else {
936
- return this.parent().getXPath( cur + '/' + path, depth );
937
- }
938
- }
939
- } );
671
  document.querySelectorAll( 'script[type="text/plain"][data-tcf="waiting-for-consent"]' ).forEach( advads.privacy.decode_ad );
672
  } );
673
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/assets/js/advanced.min.js CHANGED
@@ -1 +1 @@
1
- !function(){if("function"!=typeof window.CustomEvent){window.CustomEvent=function(e,t){t=t||{bubbles:!1,cancelable:!1,detail:null};var a=document.createEvent("CustomEvent");return a.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),a}}function e(){var e,t=this.parentNode,a=arguments.length;if(t)for(a||t.removeChild(this);a--;)"object"!=typeof(e=arguments[a])?e=this.ownerDocument.createTextNode(e):e.parentNode&&e.parentNode.removeChild(e),a?t.insertBefore(e,this.nextSibling):t.replaceChild(e,this)}Element.prototype.replaceWith||(Element.prototype.replaceWith=e),CharacterData.prototype.replaceWith||(CharacterData.prototype.replaceWith=e),DocumentType.prototype.replaceWith||(DocumentType.prototype.replaceWith=e),window.NodeList&&!NodeList.prototype.forEach&&(NodeList.prototype.forEach=function(e,t){var a,o=this.length;for(t=t||window,a=0;a<o;a++)e.call(t,this[a],a,this)})}(),advads={supports_localstorage:function(){"use strict";try{return!(!window||void 0===window.localStorage)&&(window.localStorage.setItem("x","x"),window.localStorage.removeItem("x"),!0)}catch(e){return!1}},max_per_session:function(e,t){var a=1;if(void 0!==t&&0!==parseInt(t)||(t=1),this.cookie_exists(e)){if(this.get_cookie(e)>=t)return!0;a+=parseInt(this.get_cookie(e))}return this.set_cookie(e,a),!1},count_up:function(e,t){var a=1;this.cookie_exists(e)&&(a+=parseInt(this.get_cookie(e))),this.set_cookie(e,a)},set_cookie_exists:function(e){return!!get_cookie(e)||(set_cookie(e,"",0),!1)},get_cookie:function(e){var t,a,o,n=document.cookie.split(";");for(t=0;t<n.length;t++)if(a=n[t].substr(0,n[t].indexOf("=")),o=n[t].substr(n[t].indexOf("=")+1),(a=a.replace(/^\s+|\s+$/g,""))===e)return unescape(o)},set_cookie:function(e,t,a,o,n,i){var r=null==a?null:24*a*60*60;this.set_cookie_sec(e,t,r,o,n,i)},set_cookie_sec:function(e,t,a,o,n,i){var r=new Date;r.setSeconds(r.getSeconds()+parseInt(a)),document.cookie=e+"="+escape(t)+(null==a?"":"; expires="+r.toUTCString())+(null==o?"; path=/":"; path="+o)+(null==n?"":"; domain="+n)+(null==i?"":"; secure")},cookie_exists:function(e){var t=this.get_cookie(e);return null!==t&&""!==t&&void 0!==t},move:function(e,t,a){var o=jQuery(e);if(void 0===a&&(a={}),void 0===a.css&&(a.css={}),void 0===a.method&&(a.method="prependTo"),""===t&&void 0!==a.target)switch(a.target){case"wrapper":var n="left";void 0!==a.offset&&(n=a.offset),t=this.find_wrapper(e,n)}switch((t=void 0===a.moveintohidden?jQuery(t).filter(":visible"):jQuery(t)).length>1&&t.length,a.method){case"insertBefore":o.insertBefore(t);break;case"insertAfter":o.insertAfter(t);break;case"appendTo":o.appendTo(t);break;case"prependTo":o.prependTo(t);break;default:o.prependTo(t)}},set_parent_relative:function(e,t){t=void 0!==t?t:{};var a=jQuery(e).parent();t.use_grandparent&&(a=a.parent()),"static"!==a.css("position")&&""!==a.css("position")||a.css("position","relative")},fix_element:function(e,t){t=void 0!==t?t:{};var a=jQuery(e);t.use_grandparent?this.set_parent_relative(a.parent()):this.set_parent_relative(a),t.is_invisible&&a.show();var o=parseInt(a.offset().top),n=parseInt(a.offset().left);if(t.is_invisible&&a.hide(),"left"===t.offset){var i=jQuery(window).width()-n-a.outerWidth();a.css("position","fixed").css("top",o+"px").css("right",i+"px").css("left","")}else a.css("position","fixed").css("top",o+"px").css("left",n+"px").css("right","")},find_wrapper:function(e,t){var a;return jQuery("body").children().each((function(o,n){if(n.id!==e.substring(1)){var i=jQuery(n);if("right"===t&&i.offset().left+jQuery(i).width()<jQuery(window).width()||"left"===t&&i.offset().left>0)return"static"!==i.css("position")&&""!==i.css("position")||i.css("position","relative"),a=n,!1}})),a},center_fixed_element:function(e){var t=jQuery(e),a=jQuery(window).width()/2-parseInt(t.css("width"))/2;t.css("left",a+"px")},center_vertically:function(e){var t=jQuery(e),a=jQuery(window).height()/2-parseInt(t.css("height"))/2;"fixed"!==t.css("position")&&(a-=topoffset=parseInt(t.offset().top)),t.css("top",a+"px")},close:function(e){jQuery(e).remove()},wait_for_images:function(e,t){var a=0,o=[];e.find('img[src][src!=""]').each((function(){o.push(this.src)})),0===o.length&&t.call(e),jQuery.each(o,(function(n,i){var r=new Image;r.src=i;var s="load error";jQuery(r).one(s,(function n(i){if(jQuery(this).off(s,n),++a==o.length)return t.call(e[0]),!1}))}))},privacy:{state:"unknown",state_executed:!1,get_state:function(){if("unknown"!==window.advads_options.privacy.state)return advads.privacy.state_executed||(advads.privacy.state_executed=!0,advads.privacy.dispatch_event(window.advads_options.privacy.state,!1)),advads.privacy.state;if("custom"===window.advads_options.privacy["consent-method"]){var e=new RegExp(window.advads_options.privacy["custom-cookie-name"]+"=.*?"+window.advads_options.privacy["custom-cookie-value"]+"[^;]*");advads.privacy.state_executed||(advads.privacy.state_executed=!0,advads.privacy.dispatch_event(null!==document.cookie.match(e)?"accepted":"unknown",!0))}advads.privacy.state_executed=!0;var t=0,a=setInterval((function(){switch(600==++t&&clearInterval(a),window.advads_options.privacy["consent-method"]){case"custom":null!==document.cookie.match(e)&&(clearInterval(a),"accepted"!==advads.privacy.state&&advads.privacy.dispatch_event("accepted",!0));break;case"iab_tcf_20":if(void 0===window.__tcfapi)return;clearInterval(a),window.__tcfapi("addEventListener",2,(function(e,t){if(t&&("tcloaded"===e.eventStatus||"useractioncomplete"===e.eventStatus||null===e.eventStatus&&void 0!==window.googlefc&&(void 0!==e.purpose||!e.gdprApplies))){var a="useractioncomplete"===e.eventStatus;if(!e.gdprApplies)return void("not_needed"!==advads.privacy.state&&advads.privacy.dispatch_event("not_needed",a));if(e.purpose.consents[1])return void("accepted"!==advads.privacy.state&&advads.privacy.dispatch_event("accepted",a));"rejected"!==advads.privacy.state&&advads.privacy.dispatch_event("rejected",a)}}))}}),100);return advads.privacy.state},is_adsense_npa_enabled:function(){return!window.advads_options||!window.advads_options.privacy||!(!window.advads_options.privacy["show-non-personalized-adsense"]||"custom"!==window.advads_options.privacy["consent-method"])},dispatch_event:function(e,t){var a=advads.privacy.state;advads.privacy.state=e,window.advanced_ads_ready_queue.push((function(){document.dispatchEvent(new CustomEvent("advanced_ads_privacy",{detail:{state:e,previousState:a,userAction:t}}))}))},is_ad_decoded:function(e){return null===document.querySelector('script[data-tcf="waiting-for-consent"][data-id="'+e+'"]')},decode_ad:function(e,t){t="boolean"!=typeof t||t;var a=decodeURIComponent(Array.prototype.map.call(atob(e.textContent),(function(e){return"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)})).join(""));if(!t)return a;e.replaceWith(document.createRange().createContextualFragment(a))}}},window.advanced_ads_ready_queue.push(advads.privacy.get_state),document.addEventListener("advanced_ads_privacy",(function(e){"accepted"!==e.detail.state&&"not_needed"!==e.detail.state||e.detail.userAction||"loading"===document.readyState||document.querySelectorAll('script[type="text/plain"][data-tcf="waiting-for-consent"]').forEach(advads.privacy.decode_ad)})),jQuery(document).ready((function(){if(!(!advads.supports_localstorage()||!localStorage.getItem("advads_frontend_picker")||window.advads_options.blog_id&&localStorage.getItem("advads_frontend_blog_id")&&window.advads_options.blog_id!==localStorage.getItem("advads_frontend_blog_id")||localStorage.getItem("advads_frontend_starttime")&&parseInt(localStorage.getItem("advads_frontend_starttime"),10)<(new Date).getTime()-27e5&&(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),1))){var e,t=jQuery("<div id='advads-picker-overlay'>"),a=[document.body,document.documentElement,document];if(t.css({position:"absolute",border:"solid 2px #428bca",backgroundColor:"rgba(66,139,202,0.5)",boxSizing:"border-box",zIndex:1e6,pointerEvents:"none"}).prependTo("body"),"true"===localStorage.getItem("advads_frontend_boundary")&&jQuery("body").css("cursor","not-allowed"),window.advads.is_boundary_reached=function(e){if("true"!==localStorage.getItem("advads_frontend_boundary"))return!1;$advads_picker_cur=jQuery(e);var t=jQuery(".advads-frontend-picker-boundary-helper");return $boundaries=t.parent(),$boundaries.css("cursor","pointer"),$advads_picker_cur.is($boundaries)||!$advads_picker_cur.closest($boundaries).length},"xpath"===localStorage.getItem("advads_frontend_pathtype"))var o="getXPath";else o="getPath";jQuery(document).mousemove((function(n){if(n.target!==e){if(~a.indexOf(n.target))return e=null,void t.hide();var i=jQuery(n.target),r=i.offset(),s=i.outerWidth(),d=i.outerHeight();e=n.target;var c=jQuery(e)[o]();c&&t.css({top:r.top,left:r.left,width:s,height:d}).show()}})),jQuery(document).click((function(t){var a=jQuery(e)[o]();advads.is_boundary_reached(e)||(localStorage.setItem("advads_frontend_element",a),window.location=localStorage.getItem("advads_prev_url"))}))}})),jQuery.fn.extend({getPath:function(e,t){if(void 0===e&&(e=""),void 0===t&&(t=0),this.is("html"))return"html > "+e;if(3===t)return e;var a=this.get(0).nodeName.toLowerCase(),o=this.attr("id"),n=this.attr("class");return t+=1,void 0===o||/\d/.test(o)?void 0!==n&&(n=n.split(/[\s\n]+/),(n=jQuery.grep(n,(function(e,t){return!/\d/.test(e)}))).length&&(a+="."+n.slice(0,2).join("."))):a+="#"+o,this.siblings(a).length&&(a+=":eq("+this.siblings(a).addBack().not("#advads-picker-overlay").index(this)+")"),""===e?this.parent().getPath(a,t):this.parent().getPath(a+" > "+e,t)},getXPath:function(e,t){if(void 0===e&&(e=""),void 0===t&&(t=0),this.is("body")||3===t)return e;if(advads.is_boundary_reached(this))return e;var a=this.get(0).nodeName.toLowerCase(),o=a,n=this.attr("id"),i=this.attr("class"),r=[];if(void 0!==n&&!/\d/.test(n))return o+'[@id and id="'+n+'"]/'+e;if(void 0!==i&&(i=i.split(/[\s\n]+/),(i=jQuery.grep(i,(function(e,t){return!/\d/.test(e)}))).length)){t+=1;r=i.slice(0,2);for(var s=[],d=0;d<r.length;d++)s.push('(@class and contains(concat(" ", normalize-space(@class), " "), " '+r[d]+' "))');o+="["+s.join(" and ")+"]"}if(r.length)var c=this.siblings(a+"."+r.join("."));else c=this.siblings(a);c.length&&(o+="["+c.addBack().not("#advads-picker-overlay").index(this)+"]");return""===e?this.parent().getXPath(o,t):this.parent().getXPath(o+"/"+e,t)}});
1
+ !function(){if("function"!=typeof window.CustomEvent){window.CustomEvent=function(e,t){t=t||{bubbles:!1,cancelable:!1,detail:null};var a=document.createEvent("CustomEvent");return a.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),a}}function e(){var e,t=this.parentNode,a=arguments.length;if(t)for(a||t.removeChild(this);a--;)"object"!=typeof(e=arguments[a])?e=this.ownerDocument.createTextNode(e):e.parentNode&&e.parentNode.removeChild(e),a?t.insertBefore(e,this.nextSibling):t.replaceChild(e,this)}Element.prototype.replaceWith||(Element.prototype.replaceWith=e),CharacterData.prototype.replaceWith||(CharacterData.prototype.replaceWith=e),DocumentType.prototype.replaceWith||(DocumentType.prototype.replaceWith=e),window.NodeList&&!NodeList.prototype.forEach&&(NodeList.prototype.forEach=function(e,t){var a,o=this.length;for(t=t||window,a=0;a<o;a++)e.call(t,this[a],a,this)})}(),advads={supports_localstorage:function(){"use strict";try{return!(!window||void 0===window.localStorage)&&(window.localStorage.setItem("x","x"),window.localStorage.removeItem("x"),!0)}catch(e){return!1}},max_per_session:function(e,t){var a=1;if(void 0!==t&&0!==parseInt(t)||(t=1),this.cookie_exists(e)){if(this.get_cookie(e)>=t)return!0;a+=parseInt(this.get_cookie(e))}return this.set_cookie(e,a),!1},count_up:function(e,t){var a=1;this.cookie_exists(e)&&(a+=parseInt(this.get_cookie(e))),this.set_cookie(e,a)},set_cookie_exists:function(e){return!!get_cookie(e)||(set_cookie(e,"",0),!1)},get_cookie:function(e){var t,a,o,i=document.cookie.split(";");for(t=0;t<i.length;t++)if(a=i[t].substr(0,i[t].indexOf("=")),o=i[t].substr(i[t].indexOf("=")+1),(a=a.replace(/^\s+|\s+$/g,""))===e)return unescape(o)},set_cookie:function(e,t,a,o,i,n){var s=null==a?null:24*a*60*60;this.set_cookie_sec(e,t,s,o,i,n)},set_cookie_sec:function(e,t,a,o,i,n){var s=new Date;s.setSeconds(s.getSeconds()+parseInt(a)),document.cookie=e+"="+escape(t)+(null==a?"":"; expires="+s.toUTCString())+(null==o?"; path=/":"; path="+o)+(null==i?"":"; domain="+i)+(null==n?"":"; secure")},cookie_exists:function(e){var t=this.get_cookie(e);return null!==t&&""!==t&&void 0!==t},move:function(e,t,a){var o=jQuery(e);if(void 0===a&&(a={}),void 0===a.css&&(a.css={}),void 0===a.method&&(a.method="prependTo"),""===t&&void 0!==a.target)switch(a.target){case"wrapper":var i="left";void 0!==a.offset&&(i=a.offset),t=this.find_wrapper(e,i)}switch((t=void 0===a.moveintohidden?jQuery(t).filter(":visible"):jQuery(t)).length>1&&t.length,a.method){case"insertBefore":o.insertBefore(t);break;case"insertAfter":o.insertAfter(t);break;case"appendTo":o.appendTo(t);break;case"prependTo":o.prependTo(t);break;default:o.prependTo(t)}},set_parent_relative:function(e,t){t=void 0!==t?t:{};var a=jQuery(e).parent();t.use_grandparent&&(a=a.parent()),"static"!==a.css("position")&&""!==a.css("position")||a.css("position","relative")},fix_element:function(e,t){t=void 0!==t?t:{};var a=jQuery(e);t.use_grandparent?this.set_parent_relative(a.parent()):this.set_parent_relative(a),t.is_invisible&&a.show();var o=parseInt(a.offset().top),i=parseInt(a.offset().left);if(t.is_invisible&&a.hide(),"left"===t.offset){var n=jQuery(window).width()-i-a.outerWidth();a.css("position","fixed").css("top",o+"px").css("right",n+"px").css("left","")}else a.css("position","fixed").css("top",o+"px").css("left",i+"px").css("right","")},find_wrapper:function(e,t){var a;return jQuery("body").children().each((function(o,i){if(i.id!==e.substring(1)){var n=jQuery(i);if("right"===t&&n.offset().left+jQuery(n).width()<jQuery(window).width()||"left"===t&&n.offset().left>0)return"static"!==n.css("position")&&""!==n.css("position")||n.css("position","relative"),a=i,!1}})),a},center_fixed_element:function(e){var t=jQuery(e),a=jQuery(window).width()/2-parseInt(t.css("width"))/2;t.css("left",a+"px")},center_vertically:function(e){var t=jQuery(e),a=jQuery(window).height()/2-parseInt(t.css("height"))/2;"fixed"!==t.css("position")&&(a-=topoffset=parseInt(t.offset().top)),t.css("top",a+"px")},close:function(e){jQuery(e).remove()},wait_for_images:function(e,t){var a=0,o=[];e.find('img[src][src!=""]').each((function(){o.push(this.src)})),0===o.length&&t.call(e),jQuery.each(o,(function(i,n){var s=new Image;s.src=n;var r="load error";jQuery(s).one(r,(function i(n){if(jQuery(this).off(r,i),++a==o.length)return t.call(e[0]),!1}))}))},privacy:{state:"unknown",state_executed:!1,get_state:function(){if("unknown"!==window.advads_options.privacy.state)return advads.privacy.state_executed||(advads.privacy.state_executed=!0,advads.privacy.dispatch_event(window.advads_options.privacy.state,!1)),advads.privacy.state;if("custom"===window.advads_options.privacy["consent-method"]){var e=new RegExp(window.advads_options.privacy["custom-cookie-name"]+"=.*?"+window.advads_options.privacy["custom-cookie-value"]+"[^;]*");advads.privacy.state_executed||(advads.privacy.state_executed=!0,advads.privacy.dispatch_event(null!==document.cookie.match(e)?"accepted":"unknown",!0))}advads.privacy.state_executed=!0;var t=0,a=setInterval((function(){switch(600==++t&&clearInterval(a),window.advads_options.privacy["consent-method"]){case"custom":null!==document.cookie.match(e)&&(clearInterval(a),"accepted"!==advads.privacy.state&&advads.privacy.dispatch_event("accepted",!0));break;case"iab_tcf_20":if(void 0===window.__tcfapi)return;clearInterval(a),window.__tcfapi("addEventListener",2,(function(e,t){if(t&&("tcloaded"===e.eventStatus||"useractioncomplete"===e.eventStatus||null===e.eventStatus&&void 0!==window.googlefc&&(void 0!==e.purpose||!e.gdprApplies))){var a="useractioncomplete"===e.eventStatus;if(!e.gdprApplies)return void("not_needed"!==advads.privacy.state&&advads.privacy.dispatch_event("not_needed",a));if(e.purpose.consents[1])return void("accepted"!==advads.privacy.state&&advads.privacy.dispatch_event("accepted",a));"rejected"!==advads.privacy.state&&advads.privacy.dispatch_event("rejected",a)}}))}}),100);return advads.privacy.state},is_adsense_npa_enabled:function(){return!window.advads_options||!window.advads_options.privacy||!(!window.advads_options.privacy["show-non-personalized-adsense"]||"custom"!==window.advads_options.privacy["consent-method"])},dispatch_event:function(e,t){var a=advads.privacy.state;advads.privacy.state=e,window.advanced_ads_ready_queue.push((function(){document.dispatchEvent(new CustomEvent("advanced_ads_privacy",{detail:{state:e,previousState:a,userAction:t}}))}))},is_ad_decoded:function(e){return null===document.querySelector('script[data-tcf="waiting-for-consent"][data-id="'+e+'"]')},decode_ad:function(e,t){t="boolean"!=typeof t||t;var a=decodeURIComponent(Array.prototype.map.call(atob(e.textContent),(function(e){return"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)})).join(""));if(!t)return a;e.replaceWith(document.createRange().createContextualFragment(a))}}},window.advanced_ads_ready_queue.push(advads.privacy.get_state),document.addEventListener("advanced_ads_privacy",(function(e){"accepted"!==e.detail.state&&"not_needed"!==e.detail.state||e.detail.userAction||"loading"===document.readyState||document.querySelectorAll('script[type="text/plain"][data-tcf="waiting-for-consent"]').forEach(advads.privacy.decode_ad)}));
public/assets/js/frontend-picker.js ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Highlight elements in frontend, if local storage variable is set.
2
+ jQuery( document ).ready( function () {
3
+
4
+ function is_enabled() {
5
+ if ( ! advads.supports_localstorage() || ! localStorage.getItem( 'advads_frontend_picker' ) ) {
6
+ return false;
7
+ }
8
+
9
+ // Check if the frontend picker was started on the current blog.
10
+ if ( window.advads_options.blog_id
11
+ && localStorage.getItem( 'advads_frontend_blog_id' )
12
+ && window.advads_options.blog_id !== localStorage.getItem( 'advads_frontend_blog_id' ) ) {
13
+ return false;
14
+ }
15
+
16
+ // Deactivate the frontend picker if it was started more than 45 minutes ago.
17
+ if ( localStorage.getItem( 'advads_frontend_starttime' )
18
+ && parseInt( localStorage.getItem( 'advads_frontend_starttime' ), 10 ) < (
19
+ new Date().getTime()
20
+ ) - 45 * 60 * 1000 ) {
21
+ localStorage.removeItem( 'advads_frontend_action' );
22
+ localStorage.removeItem( 'advads_frontend_element' );
23
+ localStorage.removeItem( 'advads_frontend_picker' );
24
+ localStorage.removeItem( 'advads_prev_url' );
25
+ localStorage.removeItem( 'advads_frontend_pathtype' );
26
+ localStorage.removeItem( 'advads_frontend_boundary' );
27
+ localStorage.removeItem( 'advads_frontend_blog_id' );
28
+ localStorage.removeItem( 'advads_frontend_starttime' );
29
+ advads.set_cookie( 'advads_frontend_picker', '', - 1 );
30
+ return false;
31
+ }
32
+
33
+ return true;
34
+ }
35
+
36
+ // only trigger if local storage is available
37
+ if ( is_enabled() ) {
38
+ var advads_picker_cur, advads_picker_overlay = jQuery( "<div id='advads-picker-overlay'>" ),
39
+ advads_picker_no = [document.body, document.documentElement, document];
40
+ advads_picker_overlay.css( {
41
+ position: 'absolute', border: 'solid 2px #428bca',
42
+ backgroundColor: 'rgba(66,139,202,0.5)', boxSizing: 'border-box',
43
+ zIndex: 1000000, pointerEvents: 'none'
44
+ } ).prependTo( 'body' );
45
+
46
+ if ( 'true' === localStorage.getItem( 'advads_frontend_boundary' ) ) {
47
+ jQuery( 'body' ).css( 'cursor', 'not-allowed' );
48
+ }
49
+
50
+ /**
51
+ * Check if we can traverse up the dom tree.
52
+ *
53
+ * We cannot use event delegation because:
54
+ * - the content can be loaded via AJAX dynamically
55
+ * - we cannot wrap the content in a `div` that represents post boundary
56
+ * because that may prevent css rules from working
57
+ *
58
+ * @param HTMLElement The current element.
59
+ * return bool
60
+ */
61
+ window.advads.is_boundary_reached = function ( advads_picker_cur ) {
62
+ if ( 'true' !== localStorage.getItem( 'advads_frontend_boundary' ) ) {
63
+ return false;
64
+ }
65
+ $advads_picker_cur = jQuery( advads_picker_cur );
66
+ // A boundary helper is the `ins` element inside of the post content
67
+ // that is used to determine the post boundary (where the content starts and ends).
68
+ var $boundary_helpers = jQuery( '.advads-frontend-picker-boundary-helper' );
69
+
70
+ $boundaries = $boundary_helpers.parent();
71
+ $boundaries.css( 'cursor', 'pointer' );
72
+ return $advads_picker_cur.is( $boundaries ) || ! $advads_picker_cur.closest( $boundaries ).length;
73
+ }
74
+
75
+ if ( 'xpath' === localStorage.getItem( 'advads_frontend_pathtype' ) ) {
76
+ var fn = 'getXPath';
77
+ } else {
78
+ var fn = 'getPath';
79
+ }
80
+
81
+ jQuery( document ).mousemove( function ( e ) {
82
+ if ( e.target === advads_picker_cur ) {
83
+ return;
84
+ }
85
+
86
+ if ( ~ advads_picker_no.indexOf( e.target ) ) {
87
+ advads_picker_cur = null;
88
+ advads_picker_overlay.hide();
89
+ return;
90
+ }
91
+
92
+ var target = jQuery( e.target ),
93
+ offset = target.offset(),
94
+ width = target.outerWidth(),
95
+ height = target.outerHeight();
96
+
97
+ advads_picker_cur = e.target;
98
+
99
+ var path = jQuery( advads_picker_cur )[fn]();
100
+ if ( ! path ) {
101
+ // A click outside of the boundary.
102
+ // @see `is_boundary_reached`.
103
+ return;
104
+ }
105
+ // log path
106
+ console.log( path );
107
+
108
+ advads_picker_overlay.css( {
109
+ top: offset.top,
110
+ left: offset.left,
111
+ width: width,
112
+ height: height
113
+ } ).show();
114
+
115
+ } );
116
+ // save on click
117
+ jQuery( document ).click( function ( e ) {
118
+ var path = jQuery( advads_picker_cur )[fn]();
119
+
120
+ if ( advads.is_boundary_reached( advads_picker_cur ) ) {
121
+ return;
122
+ }
123
+
124
+ localStorage.setItem( 'advads_frontend_element', path );
125
+ window.location = localStorage.getItem( 'advads_prev_url' );
126
+ } );
127
+ };
128
+ } );
129
+
130
+ /*
131
+ Derrived from jQuery-GetPath v0.01, by Dave Cardwell. (2007-04-27)
132
+ http://davecardwell.co.uk/javascript/jquery/plugins/jquery-getpath/
133
+ Usage:
134
+ var path = $('#foo').getPath();
135
+ */
136
+ jQuery.fn.extend( {
137
+ getPath: function ( path, depth ) {
138
+ // The first time this function is called, path won't be defined.
139
+ if ( typeof path === 'undefined' ) {
140
+ path = '';
141
+ }
142
+ if ( typeof depth === 'undefined' ) {
143
+ depth = 0;
144
+ }
145
+
146
+ // If this element is <html> we've reached the end of the path.
147
+ // also end after 2 elements
148
+ if ( this.is( 'html' ) ) {
149
+ return 'html > ' + path;
150
+ } else if ( 3 === depth ) {
151
+ return path;
152
+ }
153
+
154
+ // Add the element name.
155
+ var cur = this.get( 0 ).nodeName.toLowerCase();
156
+
157
+ // Determine the IDs and path.
158
+ var el_id = this.attr( 'id' ),
159
+ el_class = this.attr( 'class' );
160
+
161
+ depth = depth + 1;
162
+
163
+ // Add the #id if there is one. Ignore ID with number.
164
+ if ( typeof el_id !== 'undefined' && ! /\d/.test( el_id ) ) {
165
+ cur += '#' + el_id;
166
+ } else if ( typeof el_class !== 'undefined' ) {
167
+ // Add classes if there is no id.
168
+ el_class = el_class.split( /[\s\n]+/ );
169
+ // Skip classes with numbers.
170
+ el_class = jQuery.grep( el_class, function ( element, index ) {
171
+ return ! /\d/.test( element )
172
+ } );
173
+ // Add 2 classes.
174
+ if ( el_class.length ) {
175
+ cur += '.' + el_class.slice( 0, 2 ).join( '.' );
176
+ }
177
+ }
178
+
179
+ // add index if this element is not unique among its siblings
180
+ if ( this.siblings( cur ).length ) {
181
+ cur += ":eq(" + this.siblings( cur ).addBack().not( '#advads-picker-overlay' ).index( this ) + ")";
182
+ }
183
+
184
+ // Recurse up the DOM.
185
+ if ( path === '' ) {
186
+ return this.parent().getPath( cur, depth );
187
+ } else {
188
+ return this.parent().getPath( cur + ' > ' + path, depth );
189
+ }
190
+ },
191
+
192
+ /**
193
+ * Get XPath.
194
+ */
195
+ getXPath: function ( path, depth ) {
196
+ // The first time this function is called, path won't be defined.
197
+ if ( typeof path === 'undefined' ) {
198
+ path = '';
199
+ }
200
+ if ( typeof depth === 'undefined' ) {
201
+ depth = 0;
202
+ }
203
+
204
+ // If this element is <html> we've reached the end of the path.
205
+ // also end after 2 elements
206
+ if ( this.is( 'body' ) || 3 === depth ) {
207
+ return path;
208
+ }
209
+
210
+ if ( advads.is_boundary_reached( this ) ) {
211
+ return path;
212
+ }
213
+
214
+ // Add the element name.
215
+ var tag = this.get( 0 ).nodeName.toLowerCase();
216
+ var cur = tag;
217
+
218
+ // Determine the IDs and path.
219
+ var el_id = this.attr( 'id' ),
220
+ el_class = this.attr( 'class' );
221
+ var classes = [];
222
+
223
+ // Add the #id if there is one. Ignore ID with number.
224
+ if ( typeof el_id !== 'undefined' && ! /\d/.test( el_id ) ) {
225
+ return cur + '[@id and id="' + el_id + '"]/' + path;
226
+ } else if ( typeof el_class !== 'undefined' ) {
227
+ // Add classes if there is no id.
228
+ el_class = el_class.split( /[\s\n]+/ );
229
+ // Skip classes with numbers.
230
+ el_class = jQuery.grep( el_class, function ( element, index ) {
231
+ return ! /\d/.test( element )
232
+ } );
233
+ // Add 2 classes.
234
+ if ( el_class.length ) {
235
+ depth = depth + 1;
236
+ var classes = el_class.slice( 0, 2 );
237
+
238
+ var xpath_classes = [];
239
+ for ( var i = 0, l = classes.length; i < l; i ++ ) {
240
+ xpath_classes.push( '(@class and contains(concat(" ", normalize-space(@class), " "), " ' + classes[i] + ' "))' );
241
+ }
242
+ cur += '[' + xpath_classes.join( ' and ' ) + ']';
243
+ }
244
+ }
245
+
246
+ // Add index if this element is not unique among its siblings.
247
+ if ( classes.length ) {
248
+ var $siblings = this.siblings( tag + '.' + classes.join( '.' ) );
249
+ } else {
250
+ var $siblings = this.siblings( tag );
251
+ }
252
+
253
+ if ( $siblings.length ) {
254
+ var index = $siblings.addBack().not( '#advads-picker-overlay' ).index( this );
255
+ cur += '[' + index + ']';
256
+ }
257
+
258
+ // Recurse up the DOM.
259
+ if ( path === '' ) {
260
+ return this.parent().getXPath( cur, depth );
261
+ } else {
262
+ return this.parent().getXPath( cur + '/' + path, depth );
263
+ }
264
+ }
265
+ } );
public/assets/js/frontend-picker.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready((function(){if(!(!advads.supports_localstorage()||!localStorage.getItem("advads_frontend_picker")||window.advads_options.blog_id&&localStorage.getItem("advads_frontend_blog_id")&&window.advads_options.blog_id!==localStorage.getItem("advads_frontend_blog_id")||localStorage.getItem("advads_frontend_starttime")&&parseInt(localStorage.getItem("advads_frontend_starttime"),10)<(new Date).getTime()-27e5&&(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),1))){var e,t=jQuery("<div id='advads-picker-overlay'>"),a=[document.body,document.documentElement,document];if(t.css({position:"absolute",border:"solid 2px #428bca",backgroundColor:"rgba(66,139,202,0.5)",boxSizing:"border-box",zIndex:1e6,pointerEvents:"none"}).prependTo("body"),"true"===localStorage.getItem("advads_frontend_boundary")&&jQuery("body").css("cursor","not-allowed"),window.advads.is_boundary_reached=function(e){if("true"!==localStorage.getItem("advads_frontend_boundary"))return!1;$advads_picker_cur=jQuery(e);var t=jQuery(".advads-frontend-picker-boundary-helper");return $boundaries=t.parent(),$boundaries.css("cursor","pointer"),$advads_picker_cur.is($boundaries)||!$advads_picker_cur.closest($boundaries).length},"xpath"===localStorage.getItem("advads_frontend_pathtype"))var r="getXPath";else r="getPath";jQuery(document).mousemove((function(o){if(o.target!==e){if(~a.indexOf(o.target))return e=null,void t.hide();var d=jQuery(o.target),n=d.offset(),i=d.outerWidth(),s=d.outerHeight();e=o.target;var l=jQuery(e)[r]();l&&t.css({top:n.top,left:n.left,width:i,height:s}).show()}})),jQuery(document).click((function(t){var a=jQuery(e)[r]();advads.is_boundary_reached(e)||(localStorage.setItem("advads_frontend_element",a),window.location=localStorage.getItem("advads_prev_url"))}))}})),jQuery.fn.extend({getPath:function(e,t){if(void 0===e&&(e=""),void 0===t&&(t=0),this.is("html"))return"html > "+e;if(3===t)return e;var a=this.get(0).nodeName.toLowerCase(),r=this.attr("id"),o=this.attr("class");return t+=1,void 0===r||/\d/.test(r)?void 0!==o&&(o=o.split(/[\s\n]+/),(o=jQuery.grep(o,(function(e,t){return!/\d/.test(e)}))).length&&(a+="."+o.slice(0,2).join("."))):a+="#"+r,this.siblings(a).length&&(a+=":eq("+this.siblings(a).addBack().not("#advads-picker-overlay").index(this)+")"),""===e?this.parent().getPath(a,t):this.parent().getPath(a+" > "+e,t)},getXPath:function(e,t){if(void 0===e&&(e=""),void 0===t&&(t=0),this.is("body")||3===t)return e;if(advads.is_boundary_reached(this))return e;var a=this.get(0).nodeName.toLowerCase(),r=a,o=this.attr("id"),d=this.attr("class"),n=[];if(void 0!==o&&!/\d/.test(o))return r+'[@id and id="'+o+'"]/'+e;if(void 0!==d&&(d=d.split(/[\s\n]+/),(d=jQuery.grep(d,(function(e,t){return!/\d/.test(e)}))).length)){t+=1;for(var i=[],s=0,l=(n=d.slice(0,2)).length;s<l;s++)i.push('(@class and contains(concat(" ", normalize-space(@class), " "), " '+n[s]+' "))');r+="["+i.join(" and ")+"]"}if(n.length)var c=this.siblings(a+"."+n.join("."));else c=this.siblings(a);c.length&&(r+="["+c.addBack().not("#advads-picker-overlay").index(this)+"]");return""===e?this.parent().getXPath(r,t):this.parent().getXPath(r+"/"+e,t)}});
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: ads, adsense, amp, ads.txt, ad rotations, ad blocker, amazon, banner, clic
4
  Requires at least: 4.9
5
  Tested up to: 6.0
6
  Requires PHP: 5.6
7
- Stable tag: 1.34.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -193,6 +193,7 @@ Advanced Ads integrates with plenty of other plugins:
193
  - Genesis – [Genesis Ads add-on](https://wpadvancedads.com/add-ons/genesis-ads/)
194
  - MailPoet - [How to integrate Advanced Ads in MailPoet Newsletters](https://wpadvancedads.com/mailpoet-newsletters/)
195
  - Paid Memberships Pro – [How to manage ads on membership sites running Paid Memberships Pro](https://wpadvancedads.com/paid-memberships-pro/)
 
196
  - [IAB TCF 2.0 consent](https://wpadvancedads.com/manual/tcf-consent-wordpress/) – hide ads until users give their consent. Integrating with any CMP, Quantcast Choices, iubenda, Google Funding Choices, cookiebot, etc.
197
  - WPBakery Page Builder – [Displaying Ads with WPBakery Page Builder](https://wpadvancedads.com/visual-composer-ads/)
198
  - WPML – [Showing different ads per language with WPML](https://wpadvancedads.com/translating-ads-wpml/)
@@ -334,6 +335,14 @@ Yes. You can use plenty of [hooks](https://wpadvancedads.com/codex/) to customiz
334
 
335
  == Changelog ==
336
 
 
 
 
 
 
 
 
 
337
  = 1.34.0 (May 24, 2022) =
338
 
339
  - Improvement: add a nofollow attribute to the manual link in the ad debug output
4
  Requires at least: 4.9
5
  Tested up to: 6.0
6
  Requires PHP: 5.6
7
+ Stable tag: 1.35.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
193
  - Genesis – [Genesis Ads add-on](https://wpadvancedads.com/add-ons/genesis-ads/)
194
  - MailPoet - [How to integrate Advanced Ads in MailPoet Newsletters](https://wpadvancedads.com/mailpoet-newsletters/)
195
  - Paid Memberships Pro – [How to manage ads on membership sites running Paid Memberships Pro](https://wpadvancedads.com/paid-memberships-pro/)
196
+ - Polylang - [How to target ads to multiple languages in Polylang](https://wpadvancedads.com/polylang/)
197
  - [IAB TCF 2.0 consent](https://wpadvancedads.com/manual/tcf-consent-wordpress/) – hide ads until users give their consent. Integrating with any CMP, Quantcast Choices, iubenda, Google Funding Choices, cookiebot, etc.
198
  - WPBakery Page Builder – [Displaying Ads with WPBakery Page Builder](https://wpadvancedads.com/visual-composer-ads/)
199
  - WPML – [Showing different ads per language with WPML](https://wpadvancedads.com/translating-ads-wpml/)
335
 
336
  == Changelog ==
337
 
338
+ = 1.35.0 (August 9, 2022) =
339
+
340
+ - Improvement: remove frontend picker functionality from the frontend `advanced.js` JavaScript file
341
+ - Improvement: save the Advanced Ads version as postmeta when saving an ad
342
+ - Fix: make AdSense ad unit list ordering case-insensitive
343
+ - Fix: hide widget types that should not be offered by the Legacy Widget block
344
+ - Fix: respect unfiltered_html capabilities and constant for plain text ads
345
+
346
  = 1.34.0 (May 24, 2022) =
347
 
348
  - Improvement: add a nofollow attribute to the manual link in the ad debug output