Advanced Ads - Version 1.15

Version Description

  • please enable the new content injection method under Advanced Ads > Settings > General > Content Injection > Use new injection logic
  • rewritten content injection to prevent HTML markup modifications
  • rewritten code for Display and Visitor Condition form fields on ad edit pages
  • allow to replace existing ads.txt file with the option provided by Advanced Ads
  • prevented duplicated SQL query when a group contains no ads
  • added warning for WP AutoTerms plugin, which prevents ads from showing on category archive pages
Download this release

Release Info

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

Code changes from version 1.14.11 to 1.15

Files changed (53) hide show
  1. admin/assets/css/admin.css +8 -1
  2. admin/assets/img/starter-setup-button.png +0 -0
  3. admin/assets/js/admin.js +876 -998
  4. admin/assets/js/conditions.js +285 -0
  5. admin/assets/xml/starter-setup.xml +74 -0
  6. admin/class-advanced-ads-admin.php +126 -59
  7. admin/includes/class-ad-type.php +5 -6
  8. admin/includes/class-meta-box.php +2 -2
  9. admin/includes/class-notices.php +18 -20
  10. admin/includes/class-options.php +4 -4
  11. admin/includes/class-settings.php +25 -0
  12. admin/includes/notices.php +4 -15
  13. admin/views/ad-display-metabox.php +0 -217
  14. admin/views/ad-visitor-metabox.php +0 -207
  15. admin/views/conditions/ad-display-metabox.php +52 -0
  16. admin/views/conditions/ad-visitor-metabox.php +43 -0
  17. admin/views/conditions/condition-author.php +34 -0
  18. admin/views/conditions/condition-device.php +10 -0
  19. admin/views/conditions/condition-is-or-not.php +10 -0
  20. admin/views/conditions/condition-number.php +7 -0
  21. admin/views/conditions/condition-operator.php +4 -0
  22. admin/views/conditions/condition-string.php +6 -0
  23. admin/views/conditions/conditions-form.php +38 -0
  24. admin/views/conditions/display-conditions-form-top.php +6 -0
  25. admin/views/conditions/display-conditions-list.php +74 -0
  26. admin/views/conditions/visitor-conditions-form-top.php +15 -0
  27. admin/views/conditions/visitor-conditions-list.php +41 -0
  28. admin/views/notices/starter-setup-success.php +12 -0
  29. admin/views/notices/welcome-panel.php +70 -25
  30. advanced-ads.php +2 -2
  31. classes/EDD_SL_Plugin_Updater.php +1 -1
  32. classes/ad-ajax.php +2 -1
  33. classes/ad.php +17 -0
  34. classes/ad_ajax_callbacks.php +6 -4
  35. classes/ad_group.php +1 -1
  36. classes/ad_placements.php +276 -46
  37. classes/ad_type_dummy.php +2 -2
  38. classes/checks.php +7 -4
  39. classes/display-conditions.php +1103 -929
  40. classes/plugin.php +39 -30
  41. classes/visitor-conditions.php +302 -216
  42. languages/advanced-ads.pot +512 -452
  43. modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php +121 -7
  44. modules/ads-txt/admin/views/setting-additional-content.php +2 -2
  45. modules/ads-txt/config.php +1 -0
  46. modules/ads-txt/includes/class-advanced-ads-ads-txt-real-file.php +97 -0
  47. modules/ads-txt/includes/class-advanced-ads-ads-txt-strategy.php +24 -0
  48. modules/ads-txt/main.php +16 -8
  49. modules/ads-txt/public/class-advanced-ads-ads-txt-public.php +17 -7
  50. modules/gadsense/admin/admin.php +1 -1
  51. modules/gadsense/admin/views/external-ads-adsense.php +1 -0
  52. modules/gadsense/public/templates/page-level.php +4 -6
  53. readme.txt +16 -9
admin/assets/css/admin.css CHANGED
@@ -126,7 +126,7 @@ h2.hndle .advads-hndlelinks a + a, #advads_overview_adsense_stats .advads-hndlel
126
  .post-type-advanced_ads .advads-conditions-table .advanced-ads-display-condition-set label { float: left; margin-right: -1px; }
127
  .post-type-advanced_ads .advads-conditions-table .ui-widget { font-size: inherit; }
128
  #advads-visitor-conditions-new select,
129
- #advads-display-conditions-new select { text-transform: capitalize; }
130
  .advads-display-conditions-remove + h5 { display: inline-block; margin-top: 0; margin-left: 1em; }
131
  select + .advads-conditions-single { display: inline-block; }
132
  .advads-conditions-table { border-collapse: collapse; width: 100%; max-width: 850px; }
@@ -323,6 +323,7 @@ tr:hover .on-hover { display: block; }
323
  #aa-welcome-panel .aa-welcome-panel-column:first-child { width: 36%; }
324
  #aa-welcome-panel .aa-welcome-panel-column ul { margin: 0.8em 1em 1em 0; }
325
  #aa-welcome-panel .aa-welcome-panel-column li { line-height: 16px; list-style-type: none; padding: 0 0 8px; }
 
326
  .aa-welcome-panel-column p { margin-top: 7px; color: #444; }
327
  .aa-welcome-panel-column .button { margin-left: 0; }
328
 
@@ -440,6 +441,12 @@ tr:hover .on-hover { display: block; }
440
  /* Filesystem */
441
  #advanced-ads-rfc-dialog .cancel-button { display: inline; }
442
 
 
 
 
 
 
 
443
  /* Fix Safari autofill: https://stackoverflow.com/questions/38663578/how-to-hide-autofill-safari-icon-in-input-field */
444
  .post-type-advanced_ads input::-webkit-contacts-auto-fill-button {
445
  visibility: hidden;
126
  .post-type-advanced_ads .advads-conditions-table .advanced-ads-display-condition-set label { float: left; margin-right: -1px; }
127
  .post-type-advanced_ads .advads-conditions-table .ui-widget { font-size: inherit; }
128
  #advads-visitor-conditions-new select,
129
+ .advads-conditions-new select { text-transform: capitalize; }
130
  .advads-display-conditions-remove + h5 { display: inline-block; margin-top: 0; margin-left: 1em; }
131
  select + .advads-conditions-single { display: inline-block; }
132
  .advads-conditions-table { border-collapse: collapse; width: 100%; max-width: 850px; }
323
  #aa-welcome-panel .aa-welcome-panel-column:first-child { width: 36%; }
324
  #aa-welcome-panel .aa-welcome-panel-column ul { margin: 0.8em 1em 1em 0; }
325
  #aa-welcome-panel .aa-welcome-panel-column li { line-height: 16px; list-style-type: none; padding: 0 0 8px; }
326
+ #aa-welcome-panel .aa-welcome-panel-starter-setup p { max-width: 300px; }
327
  .aa-welcome-panel-column p { margin-top: 7px; color: #444; }
328
  .aa-welcome-panel-column .button { margin-left: 0; }
329
 
441
  /* Filesystem */
442
  #advanced-ads-rfc-dialog .cancel-button { display: inline; }
443
 
444
+ /* ads.txt */
445
+ .advads-ads-txt-updated { border-left: 4px solid green; padding-left: 4px; }
446
+ .advads-error-message.advads-ads-txt-updated { border-color: red; }
447
+ #advads-ads-txt-notices li { padding-top: 1em; }
448
+ #advads-ads-txt-notices li:nth-child(even) { background-color: #f9f9f9; }
449
+
450
  /* Fix Safari autofill: https://stackoverflow.com/questions/38663578/how-to-hide-autofill-safari-icon-in-input-field */
451
  .post-type-advanced_ads input::-webkit-contacts-auto-fill-button {
452
  visibility: hidden;
admin/assets/img/starter-setup-button.png ADDED
Binary file
admin/assets/js/admin.js CHANGED
@@ -1,9 +1,9 @@
1
- jQuery( document ).ready(function ($) {
2
- function advads_load_ad_type_parameter_metabox(ad_type) {
3
- jQuery( '#advanced-ad-type input' ).prop( 'disabled', true );
4
- $( '#advanced-ads-tinymce-wrapper' ).hide();
5
- $( '#advanced-ads-ad-parameters' ).html( '<span class="spinner advads-ad-parameters-spinner advads-spinner"></span>' );
6
- $.ajax({
7
  type: 'POST',
8
  url: ajaxurl,
9
  data: {
@@ -12,546 +12,442 @@ jQuery( document ).ready(function ($) {
12
  'ad_id': $( '#post_ID' ).val(),
13
  'nonce': advadsglobal.ajax_nonce
14
  },
15
- success: function (data, textStatus, XMLHttpRequest) {
16
- // toggle main content field
17
- if (data) {
18
- $( '#advanced-ads-ad-parameters' ).html( data ).trigger( 'paramloaded' );
19
- advads_maybe_textarea_to_tinymce( ad_type );
20
  }
21
  },
22
- error: function (MLHttpRequest, textStatus, errorThrown) {
23
- $( '#advanced-ads-ad-parameters' ).html( errorThrown );
24
  }
25
- }).always( function ( MLHttpRequest, textStatus, errorThrown ) {
26
- jQuery( '#advanced-ad-type input').prop( 'disabled', false );
27
- });
28
- };
29
-
30
- $( document ).on( 'click', '#switch-to-adsense-type', function( ev ) {
31
- ev.preventDefault();
32
- AdvancedAdsAdmin.AdImporter.adsenseCode = Advanced_Ads_Admin.get_ad_source_editor_text();
33
- $( '#advanced-ad-type-adsense' ).trigger( 'click' );
34
- $( this ).closest( 'li' ).addClass( 'hidden' );
35
- } );
36
-
37
- $( document ).on('change', '#advanced-ad-type input', function () {
38
  var ad_type = $( this ).val()
39
- advads_load_ad_type_parameter_metabox( ad_type );
40
- });
41
 
42
  // trigger for ad injection after ad creation
43
- $( '#advads-ad-injection-box .advads-ad-injection-button' ).on( 'click', function(){
44
  var placement_type = this.dataset.placementType, // create new placement
45
- placement_slug = this.dataset.placementSlug, // use existing placement
46
- options = {};
47
 
48
- if ( ! placement_type && ! placement_slug ) { return; }
49
 
50
  // create new placement
51
  if ( placement_type ) {
52
- // for content injection
53
- if ( 'post_content' === placement_type ) {
54
- var paragraph = prompt( advadstxt.after_paragraph_promt, 1);
55
  if ( paragraph !== null ) {
56
- options.index = parseInt( paragraph, 10 );
57
  }
58
- }
59
- }
60
- $( '#advads-ad-injection-box .advads-loader' ).show();
61
- $( '#advads-ad-injection-box-placements' ).hide();
62
- $( 'body').animate({ scrollTop: $( '#advads-ad-injection-box' ).offset().top -40 }, 1, 'linear' );
63
-
64
- $.ajax({
65
- type: 'POST',
66
- url: ajaxurl,
67
- data: {
68
- action: 'advads-ad-injection-content',
69
- placement_type: placement_type,
70
- placement_slug: placement_slug,
71
- ad_id: $( '#post_ID' ).val(),
72
- options: options,
73
- nonce: advadsglobal.ajax_nonce
74
- },
75
- success: function (r, textStatus, XMLHttpRequest) {
76
- if ( ! r ) {
77
- $( '#advads-ad-injection-box' ).html( 'an error occured' );
78
- return;
79
  }
80
-
81
- $( '#advads-ad-injection-box *' ).hide();
82
- // append anchor to placement message
83
- $( '#advads-ad-injection-message-placement-created .advads-placement-link' ).attr( 'href', $( '#advads-ad-injection-message-placement-created a' ).attr( 'href' ) + r );
84
- $( '#advads-ad-injection-message-placement-created, #advads-ad-injection-message-placement-created *' ).show();
85
- },
86
- error: function (MLHttpRequest, textStatus, errorThrown) {
87
- $( '#advads-ad-injection-box' ).html( errorThrown );
88
  }
89
- }).always( function ( MLHttpRequest, textStatus, errorThrown ) {
90
- // jQuery( '#advanced-ad-type input').prop( 'disabled', false );
91
- });
92
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
  // activate general buttons
95
  if ( $.fn.advads_buttonset ) {
96
- $( '.advads-buttonset' ).advads_buttonset();
97
  }
98
  // activate accordions
99
  if ( $.fn.accordion ) {
100
- $( ".advads-accordion" ).accordion({
101
- active: false,
102
- collapsible: true,
103
- });
104
  }
105
 
106
- $( document ).on('click', '.advads-conditions-terms-buttons .button', function (e) {
107
- $( this ).remove();
108
- });
109
- // display input field to search for terms
110
- $( document ).on('click', '.advads-conditions-terms-show-search', function (e) {
111
- e.preventDefault();
112
- // display input field
113
- $( this ).siblings( '.advads-conditions-terms-search' ).show().focus();
114
- // register autocomplete
115
- advads_register_terms_autocomplete( $( this ).siblings( '.advads-conditions-terms-search' ) );
116
- $( this ).next( 'br' ).show();
117
- $( this ).hide();
118
- });
119
- // function for autocomplete
120
- function advads_register_terms_autocomplete( self ){
121
- self.autocomplete({
122
- source: function(request, callback){
123
- // var searchField = request.term;
124
- advads_term_search( self, callback );
125
- },
126
- minLength: 1,
127
- select: function( event, ui ) {
128
- // append new line with input fields
129
- $( '<label class="button ui-state-active">' + ui.item.label + '<input type="hidden" name="' + self.data('inputName') + '" value="' + ui.item.value + '"></label>' ).appendTo( self.siblings( '.advads-conditions-terms-buttons' ) );
130
-
131
- // show / hide other elements
132
- // $( '.advads-display-conditions-individual-post' ).hide();
133
- // $( '.advads-conditions-postids-list .show-search a' ).show();
134
- },
135
- close: function( event, ui ) {
136
- self.val( '' );
137
- }
138
- });
139
- }
140
- // display input field to search for post, page, etc.
141
- $( document ).on( 'click', '.advads-conditions-postids-show-search', function (e) {
142
- e.preventDefault();
143
- // display input field
144
- $( this).next().find( '.advads-display-conditions-individual-post' ).show();
145
- //$( '.advads-conditions-postids-search-line .description' ).hide();
146
- $( this ).hide();
147
- });
148
- // register autocomplete to display condition individual posts
149
- $( document ).on( "focus", ".advads-display-conditions-individual-post", function(e) {
150
- var self = this;
151
- if ( !$(this).data("autocomplete") ) { // If the autocomplete wasn't called yet:
152
- $( this ).autocomplete({
153
- source: function(request, callback){
154
- var searchParam = request.term;
155
- advads_post_search( searchParam, callback );
156
- },
157
- minLength: 1,
158
- select: function( event, ui ) {
159
- // append new line with input fields
160
- var newline = $( '<label class="button ui-state-active">' + ui.item.label + '</label>' );
161
- $( '<input type="hidden" name="' + self.dataset.fieldName + '[value][]" value="' + ui.item.value + '"/>' ).appendTo( newline );
162
- newline.insertBefore( $( self ).parent( '.advads-conditions-postids-search-line' ) );
163
- },
164
- close: function( event, ui ) {
165
- $( self ).val( '' );
166
- },
167
- })
168
- .autocomplete().data("ui-autocomplete")._renderItem = function( ul, item ) {
169
- ul.addClass( "advads-conditions-postids-autocomplete-suggestions" );
170
- return $( "<li></li>" )
171
- .append( "<span class='left'>" + item.label + "</span>&nbsp;<span class='right'>" + item.info + "</span>" )
172
- .appendTo( ul );
173
- };
174
- };
175
- });
176
-
177
- // remove individual posts from the display conditions post list
178
- $( document ).on('click', '.advads-conditions-postid-buttons .button', function(e){
179
- $( this ).remove();
180
- });
181
- // display/hide error message if no option was selected
182
- // is also called on every click
183
- function advads_display_condition_option_not_selected(){
184
- $( '.advads-conditions-not-selected' ).each(function(){
185
- if( $( this ).siblings('input:checked').length ){
186
- $( this ).hide();
187
- } else {
188
- $( this ).show();
189
- }
190
- });
191
- }
192
- advads_display_condition_option_not_selected();
193
- // update error messages when an item is clicked
194
- $( document ).on( 'click', '.advads-conditions-terms-buttons input[type="checkbox"], .advads-conditions-single input[type="checkbox"]', function(){
195
- // needs a slight delay until the buttons are updated
196
- window.setTimeout( advads_display_condition_option_not_selected, 200 );
197
- });
198
- // activate and toggle conditions connector option
199
- $('.advads-conditions-connector input').advads_button();
200
- // dynamically change label
201
- $(document).on('click', '.advads-conditions-connector input', function(){
202
- if( $( this ).is(':checked' ) ){
203
- $( this ).advads_button( "option", "label", advadstxt.condition_or );
204
- $( this ).parents( '.advads-conditions-connector' ).addClass('advads-conditions-connector-or').removeClass('advads-conditions-connector-and');
205
- } else {
206
- $( this ).advads_button( "option", "label", advadstxt.condition_and );
207
- $( this ).parents( '.advads-conditions-connector' ).addClass('advads-conditions-connector-and').removeClass('advads-conditions-connector-or');
208
- }
209
- });
210
- // remove a line with a display or visitor condition
211
- $(document).on('click', '.advads-conditions-remove', function(){
212
- $(this).parents('.advads-conditions-table tr').prev('tr').remove();
213
- $(this).parents('.advads-conditions-table tr').remove();
214
- });
215
 
216
  // display new ad group form
217
- $( '#advads-new-ad-group-link' ).click(function(e){
218
- e.preventDefault();
219
- $( '#advads-new-group-form' ).show().find('input[type="text"]').focus();
220
- });
221
 
222
  // display ad groups form
223
- $( '#advads-ad-group-list a.edit, #advads-ad-group-list a.row-title' ).click(function(e){
224
- e.preventDefault();
225
- var advadsgroupformrow = $( this ).parents( '.advads-group-row' ).next( '.advads-ad-group-form' );
226
- if(advadsgroupformrow.is( ':visible' )){
227
- advadsgroupformrow.hide();
228
  // clear last edited id
229
- $('#advads-last-edited-group').val('');
230
  } else {
231
- advadsgroupformrow.show();
232
- var group_id = advadsgroupformrow.find('.advads-group-id').val();
233
- $('#advads-last-edited-group').val( group_id );
234
  // remember that we opened that one
235
- advadsgroupformrow.data('touched', true);
236
  }
237
- });
238
  // display ad groups usage
239
- $( '#advads-ad-group-list a.usage' ).click(function(e){
240
- e.preventDefault();
241
- var usagediv = $( this ).parents( '.advads-group-row' ).find( '.advads-usage' );
242
- if(usagediv.is( ':visible' )){
243
- usagediv.hide();
244
  } else {
245
- usagediv.show();
246
  }
247
- });
248
  // handle the submission of the groups form
249
- $ ('form#advads-form-groups').submit(function(){
250
- var grouprows = jQuery( 'tr.advads-ad-group-form' );
251
- jQuery( 'tr.advads-ad-group-form' ).each(function(k,v){
252
- v = jQuery(v);
253
- if (! v.data('touched')){
254
- v.remove();
255
  }
256
- });
257
- });
258
  // display placement settings form
259
- $( '.advads-placements-table a.advads-placement-options-link' ).click(function(e){
260
- e.preventDefault();
261
- Advanced_Ads_Admin.toggle_placements_visibility(this);
262
- });
263
  // display manual placement usage
264
- $( '.advads-placements-table .usage-link' ).click(function(e){
265
- e.preventDefault();
266
- var usagediv = $( this ).parents( 'tr' ).find( '.advads-usage' );
267
- if(usagediv.is( ':visible' )){
268
- usagediv.hide();
269
  } else {
270
- usagediv.show();
271
  }
272
- });
273
  // show warning if Container ID option contains invalid characters
274
- $( '#advads-output-wrapper-id' ).keyup( function(){
275
- var id_value = $( this ).val();
276
- if( /^[a-z-0-9]*$/.test( id_value ) ){
277
- $( '.advads-output-wrapper-id-error' ).removeClass( 'advads-error-message' );
278
- } else {
279
- $( '.advads-output-wrapper-id-error' ).addClass( 'advads-error-message' ).css( 'display', 'block' );
280
- }
281
- });
282
  /**
283
- * automatically open all options and show usage link when this is the placement linked in the URL
284
  * also highlight the box with an effect for a short time
285
  */
286
- if( jQuery( window.location.hash ).length ){
287
- jQuery( window.location.hash ).find( '.advads-toggle-link + div, .advads-usage' ).show();
288
 
289
  }
290
 
291
  // group page: add ad to group
292
- $( '.advads-group-add-ad button' ).click( function() {
293
  var $settings_row = $( this ).closest( '.advads-ad-group-form' ),
294
- $ad = $settings_row.find( '.advads-group-add-ad-list-ads option:selected' )
295
- $weight_selector = $settings_row.find( '.advads-group-add-ad-list-weights' ).last(),
296
- $ad_table = $settings_row.find( '.advads-group-ads tbody' );
297
  // add new row if does not already exist
298
- if ( $ad.length && $weight_selector.length && ! $ad_table.find( '[name="' + $ad.val() + '"]' ).length ) {
299
  $ad_table.append(
300
  $( '<tr></tr>' ).append(
301
  $( '<td></td>' ).html( $ad.text() ),
302
  $( '<td></td>' ).append( $weight_selector.clone().val( $weight_selector.val() ).prop( 'name', $ad.val() ) ),
303
  '<td><button type="button" class="advads-remove-ad-from-group button">x</button></td>'
304
  )
305
- );
306
  }
307
- });
308
  // group page: remove ad from group
309
- $( '#advads-ad-group-list' ).on( 'click', '.advads-remove-ad-from-group', function() {
310
- var $ad_row = $( this ).closest( 'tr' );
311
 
312
  if ( $ad_row.data( 'ad-id' ) ) {
313
  // save the ad id, it is needed when this ad is not included in any other group
314
  $( '#advads-ad-group-list form' ).append(
315
- '<input type="hidden" name="advads-groups-removed-ads[]" value="' + $ad_row.data( 'ad-id' ) + '">'
316
- + '<input type="hidden" name="advads-groups-removed-ads-gid[]" value="' + $ad_row.data( 'group-id' ) + '">'
317
- );
318
  }
319
- $ad_row.remove();
320
- });
321
  // group page: handle switching of group types based on a class derrived from that type
322
- $('.advads-ad-group-type input').click(function(){
323
- advads_show_group_options( $( this ) );
324
- });
325
- function advads_show_group_options( el ){
 
326
  // first, hide all options except title and type
327
  // iterate through all elements
328
- el.each( function(){
329
- var _this = jQuery( this );
330
- _this.parents('.advads-ad-group-form').find('.advads-option:not(.static)').hide();
331
- var current_type = _this.val();
332
 
333
  // now, show only the ones corresponding with the group type
334
- _this.parents('.advads-ad-group-form').find( '.advads-group-type-' + current_type ).show();
335
- });
336
  }
 
337
  // set default group options for earch group
338
 
339
- advads_show_group_options( $( '.advads-ad-group-type input:checked' ) );
340
  // group page: hide ads if more than 4 – than only show 3
341
- $('.advads-ad-group-list-ads').each( function(){
342
- if( 5 <= $(this).find('li').length ){
343
- $(this).find('li:gt(2)').hide();
344
- };
345
- });
 
346
  // show more than 3 ads when clicked on a link
347
- $('.advads-group-ads-list-show-more').click( function(){
348
- jQuery( this ).hide().parents('.advads-ad-group-list-ads').find('li').show();
349
- });
350
 
351
  /**
352
  * SETTINGS PAGE
353
  */
354
 
355
  // automatically copy the first entered license key into all other empty fields
356
- $('.advads-settings-tab-main-form .advads-license-key').blur( function(){
357
- // get number of license fields
358
-
359
- var license_key = $(this).val();
360
 
361
- if( "" === license_key ){
362
- return;
363
- }
364
 
365
- var license_fields = $('.advads-settings-tab-main-form .advads-license-key');
366
- var license_fields_without_value = [];
 
367
 
368
- // count license fields without value
369
- license_fields.each( function( i, el ){
370
- if( "" === $( el ).val() ){
371
- license_fields_without_value.push( el );
372
- }
373
- } );
374
 
375
- // if there is only one field filled then take its content (probably a license key) and add it into the other fields
376
- if( license_fields.length === ( license_fields_without_value.length + 1 ) ){
377
- $.each( license_fields_without_value, function( i, el ) {
378
- $( el ).val( license_key );
379
- } );
380
- }
381
 
 
 
 
 
 
 
382
 
383
- });
384
 
385
  // activate licenses
386
- $('.advads-license-activate').click(function(){
387
-
388
- var button = $(this);
389
-
390
- if( ! this.dataset.addon ) { return }
391
-
392
- advads_disable_license_buttons( true );
393
-
394
- var query = {
395
- action: 'advads-activate-license',
396
- addon: this.dataset.addon,
397
- pluginname: this.dataset.pluginname,
398
- optionslug: this.dataset.optionslug,
399
- license: $(this).parents('td').find('.advads-license-key').val(),
400
- security: $('#advads-licenses-ajax-referrer').val()
401
- };
402
-
403
- // show loader
404
- $( '<span class="spinner advads-spinner"></span>' ).insertAfter( button );
405
-
406
- // send and close message
407
- $.post(ajaxurl, query, function (r) {
408
- // remove spinner
409
- $('span.spinner').remove();
410
- var parent = button.parents('td');
411
-
412
- if( r === '1' ){
413
- parent.find('.advads-license-activate-error').remove();
414
- parent.find('.advads-license-deactivate').show();
415
- button.fadeOut();
416
- parent.find('.advads-license-activate-active').fadeIn();
417
- parent.find('input').prop('readonly', 'readonly');
418
- advads_disable_license_buttons( false );
419
- } else if( r === 'ex' ){
420
- var input = parent.find('input.advads-license-key');
421
- var link = parent.find('a.advads-renewal-link');
422
- if (input && link){
423
- var license_key = input.val();
424
- var href = link.prop('href');
425
- link.prop('href', href.replace("%LICENSE_KEY%", license_key));
426
- }
427
- parent.find('.advads-license-activate-error').remove();
428
- parent.find('.advads-license-expired-error').show();
429
- advads_disable_license_buttons( false );
430
- } else {
431
- parent.find('.advads-license-activate-error').show().text( r );
432
- advads_disable_license_buttons( false );
433
  }
434
- });
435
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
 
437
  // deactivate licenses
438
- $('.advads-license-deactivate').click(function(){
439
-
440
- var button = $(this);
441
-
442
- if( ! this.dataset.addon ) { return }
443
-
444
- advads_disable_license_buttons( true );
445
-
446
- var query = {
447
- action: 'advads-deactivate-license',
448
- addon: this.dataset.addon,
449
- pluginname: this.dataset.pluginname,
450
- optionslug: this.dataset.optionslug,
451
- security: $('#advads-licenses-ajax-referrer').val()
452
- };
453
-
454
- // show loader
455
- $( '<span class="spinner advads-spinner"></span>' ).insertAfter( button );
456
-
457
- // send and close message
458
- $.post(ajaxurl, query, function (r) {
459
- // remove spinner
460
- $('span.spinner').remove();
461
-
462
- if( r === '1' ){
463
- button.siblings('.advads-license-activate-error').hide();
464
- button.siblings('.advads-license-activate-active').hide();
465
- button.siblings('.advads-license-activate').show();
466
- button.siblings('input').prop('readonly', false);
467
- button.fadeOut();
468
- advads_disable_license_buttons( false );
469
- } else if( r === 'ex' ){
470
- button.siblings('.advads-license-activate-error').hide();
471
- button.siblings('.advads-license-activate-active').hide();
472
- button.siblings('.advads-license-expired-error').show();
473
- button.siblings('input').prop('readonly', false);
474
- button.fadeOut();
475
- advads_disable_license_buttons( false );
476
- } else {
477
- console.log( r );
478
- button.siblings('.advads-license-activate-error').show().html( r );
479
- button.siblings('.advads-license-activate-active').hide();
480
- advads_disable_license_buttons( false );
481
  }
482
- });
483
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
 
485
  // toggle license buttons – disable or not
486
- function advads_disable_license_buttons( disable = true ) {
487
- var buttons = $('button.advads-license-activate, button.advads-license-deactivate'); // all activation buttons
488
- // disable all buttons to prevent issues when users try to enable multiple licenses at the same time
489
- if (disable) {
490
- buttons.attr('disabled', 'disabled');
491
- } else {
492
- buttons.removeAttr( 'disabled' );
493
- }
494
- }
495
 
496
  /**
497
- * PLACEMENTS
498
- */
499
- // show image tooltips
500
  if ( $.fn.advads_tooltip ) {
501
- $( ".advads-placements-new-form .advads-placement-type" ).advads_tooltip({
502
- items: "label",
503
- content: function() {
504
- return $( this ).parents('.advads-placement-type').find( '.advads-placement-description' ).html();
505
  }
506
- });
507
  }
508
-
509
  // keep track of placements that were changed
510
- $( 'form#advanced-ads-placements-form input, #advanced-ads-placements-form select' ).on( 'change', function(){
511
- var tr = $( this ).closest( 'tr.advanced-ads-placement-row' );
512
- if (tr){
513
- tr.data('touched', true);
514
  }
515
- });
516
-
517
  // some special form elements overwrite the jquery listeners (or render them unusable in some strange way)
518
  // to counter that and make it more robust in general, we now listen for mouseover events, that will
519
  // only occur, when the settings of a placement are expanded (let's just assume this means editing)
520
- $( 'form#advanced-ads-placements-form .advads-placements-advanced-options' ).on( 'mouseover' , function(){
521
- var tr = $( this ).closest( 'tr.advanced-ads-placement-row' );
522
- if (tr){
523
- tr.data('touched', true);
524
  }
525
- });
526
-
527
  // on submit remove placements that were untouched
528
- $ ('form#advanced-ads-placements-form').submit(function(){
529
- var grouprows = jQuery( 'form#advanced-ads-placements-form tr.advanced-ads-placement-row' );
530
- jQuery( 'form#advanced-ads-placements-form tr.advanced-ads-placement-row' ).each(function(k,v){
531
- v = jQuery(v);
532
- if (! v.data('touched')){
533
- v.find( 'input, select' ).each(function(k2,v2){
534
- v2 = jQuery(v2);
535
- v2.prop("disabled", true);
536
- });
537
  }
538
- });
539
- });
540
 
541
  /**
542
- * Image ad uploader
543
- */
544
- $('body').on('click', '.advads_image_upload', function(e) {
545
 
546
- e.preventDefault();
547
 
548
- var button = $(this);
549
 
550
  // If the media frame already exists, reopen it.
551
  if ( file_frame ) {
552
  // file_frame.uploader.uploader.param( 'post_id', set_to_post_id );
553
- file_frame.open();
554
- return;
555
  }
556
 
557
  // Create the media frame.
@@ -565,227 +461,153 @@ jQuery( document ).ready(function ($) {
565
  type: 'image'
566
  },
567
  multiple: false // only allow one file to be selected
568
- } );
569
 
570
  // When an image is selected, run a callback.
571
- file_frame.on( 'select', function() {
572
 
573
- var selection = file_frame.state().get('selection');
574
- selection.each( function( attachment, index ) {
575
- attachment = attachment.toJSON();
576
  if ( 0 === index ) {
577
  // place first attachment in field
578
- $( '#advads-image-id' ).val( attachment.id );
579
- $( '#advanced-ads-ad-parameters-size input[name="advanced_ad[width]"]' ).val( attachment.width );
580
- $( '#advanced-ads-ad-parameters-size input[name="advanced_ad[height]"]' ).val( attachment.height );
581
  // update image preview
582
- var new_image = '<img width="'+ attachment.width +'" height="'+ attachment.height +
583
- '" title="'+ attachment.title +'" alt="'+ attachment.alt +'" src="'+ attachment.url +'"/>';
584
- $('#advads-image-preview').html( new_image );
585
- $('#advads-image-edit-link').attr( 'href', attachment.editLink );
586
  // process "reserve this space" checkbox
587
- $( '#advanced-ads-ad-parameters-size input[type=number]:first' ).change();
588
  }
589
- });
590
- });
591
 
592
  // Finally, open the modal
593
- file_frame.open();
594
- });
595
 
596
  // WP 3.5+ uploader
597
- var file_frame;
598
- window.formfield = '';
599
 
600
  // adblocker related code
601
- $( '#advanced-ads-use-adblocker' ).change( function() {
602
- advads_toggle_box( this, '#advads-adblocker-wrapper' );
603
- });
604
 
605
  // processing of the rebuild asset form and the FTP/SSH credentials form
606
- var $advads_adblocker_wrapper = $( '#advads-adblocker-wrapper' );
607
- $advads_adblocker_wrapper.find( 'input[type="submit"]' ).prop( 'disabled', false );
608
- $advads_adblocker_wrapper.on( 'submit', 'form', function( event ) {
609
- event.preventDefault();
610
- var $form = $( '#advanced-ads-rebuild-assets-form' );
611
- $form.prev( '.error' ).remove();
612
- $form.find( 'input[type="submit"]' ).prop( 'disabled', true ).after( '<span class="spinner advads-spinner"></span>' );
613
 
614
  var args = {
615
  data: {
616
  action: 'advads-adblock-rebuild-assets',
617
  nonce: advadsglobal.ajax_nonce,
618
  },
619
- done: function( data, textStatus, jqXHR ) {
620
- var $advads_adblocker_wrapper = $( '#advads-adblocker-wrapper' );
621
- $advads_adblocker_wrapper.html( data );
622
  },
623
- fail: function( jqXHR, textStatus, errorThrown ) {
624
- $form.before( '<div class="error"><p>' + textStatus + ': ' + errorThrown + '</p></div>' );
625
- $form.find( 'input[type="submit"]' ).prop( 'disabled', false ).next( '.advads-spinner' ).remove();
626
  },
627
- on_modal_close: function() {
628
- var $form = $( '#advanced-ads-rebuild-assets-form' );
629
- $form.find( 'input[type="submit"]' ).prop( 'disabled', false ).next( '.advads-spinner' ).remove();
630
  }
631
  }
632
 
633
- $.each( $form.serializeArray(), function( i, o ) {
634
- args.data[ o.name ] = o.value;
635
- });
636
 
637
- advanced_ads_admin.filesystem.ajax( args );
638
- });
639
 
640
  // process "reserve this space" checkbox
641
- $( '#advanced-ads-ad-parameters' ).on( 'change', '#advanced-ads-ad-parameters-size input[type=number]', function() {
642
- if ( $( '#advanced-ads-ad-parameters-size input[type=number]' ).filter( function() {
643
- return parseInt( this.value, 10 ) > 0;
644
- }).length === 2 ) {
645
- $( '#advads-wrapper-add-sizes' ).prop( 'disabled', false );
646
  } else {
647
- $( '#advads-wrapper-add-sizes' ).prop( 'disabled', true ).prop( 'checked', false );
648
  }
649
- });
650
  // process "reserve this space" checkbox - ad type changed
651
- $( '#advanced-ads-ad-parameters' ).on( 'paramloaded', function() {
652
- $( '#advanced-ads-ad-parameters-size input[type=number]:first' ).change();
653
- })
654
  // process "reserve this space" checkbox - on load
655
- $( '#advanced-ads-ad-parameters-size input[type=number]:first' ).change();
656
-
657
  // move meta box markup to hndle headline
658
- $('.advads-hndlelinks').each(function(){
659
- $(this).removeClass('hidden');
660
- $(this).appendTo( $(this).parent('.inside').siblings('h2.hndle') );
661
- });
662
  // open tutorial link when clicked on it
663
- $('.advads-video-link').click(function( el ){
664
- el.preventDefault();
665
- var video_container = $(this).parents('h2').siblings('.inside').find('.advads-video-link-container');
666
- video_container.html( video_container.data('videolink') );
667
- });
668
  // open inline tutorial link when clicked on it
669
- $('.advads-video-link-inline').click(function( el ){
670
- el.preventDefault();
671
- var video_container = $(this).parents('div').siblings('.advads-video-link-container');
672
- video_container.html( video_container.data('videolink') );
673
- });
674
  // switch import type
675
- jQuery( '.advads_import_type' ).change( function() {
676
  if ( this.value === 'xml_content' ) {
677
- jQuery( '#advads_xml_file' ).hide();
678
- jQuery( '#advads_xml_content' ).show();
679
  } else {
680
- jQuery( '#advads_xml_file' ).show();
681
- jQuery( '#advads_xml_content' ).hide();
682
  }
683
- });
684
 
685
  // Find Adsense Auto Ads inside ad content.
686
- var ad_content = jQuery('textarea[name=advanced_ad\\[content\\]]').html();
687
  if ( ad_content && ad_content.indexOf( 'enable_page_level_ads' ) !== -1 ) {
688
- advads_show_adsense_auto_ads_warning();
689
  }
690
 
691
-
692
  //advads_ads_txt_check_third_party();
693
- advads_ads_txt_find_issues();
694
-
695
- jQuery( '.advanced-ads-adsense-dashboard' ).each( function(key,elm) {
696
- Advanced_Ads_Adsense_Helper.process_dashboard(elm);
697
- });
698
- });
699
 
 
 
 
 
700
 
701
  /**
702
- * store the action hash in settings form action
703
  * thanks for Yoast SEO for this idea
704
  */
705
- function advads_set_tab_hashes() {
706
  // iterate through forms
707
- jQuery( '#advads-tabs' ).find( 'a' ).each(function () {
708
- var id = jQuery( this ).attr( 'id' ).replace( '-tab', '' );
709
- var optiontab = jQuery( '#' + id );
710
 
711
- var form = optiontab.children( '.advads-settings-tab-main-form' );
712
  if ( form.length ) {
713
- var currentUrl = form.attr( 'action' ).split( '#' )[ 0 ];
714
- form.attr( 'action', currentUrl + jQuery( this ).attr( 'href' ) );
715
- }
716
- });
717
- }
718
-
719
- /**
720
- * callback for term search autocomplete
721
- *
722
- * @param {type} search term
723
- * @param {type} callback
724
- * @returns {obj} json object with labels and values
725
- */
726
- function advads_term_search(field, callback) {
727
-
728
- // return ['post', 'poster'];
729
- var query = {
730
- action: 'advads-terms-search',
731
- nonce: advadsglobal.ajax_nonce
732
- };
733
-
734
- query.search = field.val();
735
- query.tax = field.data('tagName');
736
-
737
- var querying = true;
738
-
739
- var results = {};
740
- jQuery.post(ajaxurl, query, function (r) {
741
- querying = false;
742
- var results = [];
743
- if(r){
744
- r.map(function(element, index){
745
- results[index] = {
746
- value: element.term_id,
747
- label: element.name
748
- };
749
- });
750
  }
751
- callback( results );
752
- }, 'json');
753
- }
754
-
755
- /**
756
- * callback for post search autocomplete
757
- *
758
- * @param {str} searchParam
759
- * @param {type} callback
760
- * @returns {obj} json object with labels and values
761
- */
762
- function advads_post_search( searchParam, callback ) {
763
-
764
- // return ['post', 'poster'];
765
- var query = {
766
- action: 'advads-post-search',
767
- _ajax_linking_nonce: jQuery( '#_ajax_linking_nonce' ).val(),
768
- 'search': searchParam,
769
- nonce: advadsglobal.ajax_nonce
770
- };
771
-
772
- var querying = true;
773
-
774
- var results = {};
775
- jQuery.post(ajaxurl, query, function (r) {
776
- querying = false;
777
- var results = [];
778
- if(r){
779
- r.map(function(element, index){
780
- results[index] = {
781
- label: element.title,
782
- value: element.ID,
783
- info: element.info
784
- };
785
- });
786
- }
787
- callback( results );
788
- }, 'json');
789
  }
790
 
791
  /**
@@ -793,11 +615,11 @@ function advads_post_search( searchParam, callback ) {
793
  *
794
  * @param selector jQuery selector
795
  */
796
- function advads_scroll_to_element( selector ) {
797
- var height_of_admin_bar = jQuery( '#wpadminbar').height();
798
- jQuery( 'html, body' ).animate({
799
- scrollTop: jQuery( selector ).offset().top - height_of_admin_bar
800
- }, 1000);
801
  }
802
 
803
  /**
@@ -805,8 +627,8 @@ function advads_scroll_to_element( selector ) {
805
  *
806
  * @param selector jquery selector
807
  */
808
- function advads_toggle(selector) {
809
- jQuery( selector ).slideToggle();
810
  }
811
 
812
  /**
@@ -814,11 +636,11 @@ function advads_toggle(selector) {
814
  *
815
  * @param selector jquery selector
816
  */
817
- function advads_toggle_box(e, selector) {
818
- if (jQuery( e ).is( ':checked' )) {
819
- jQuery( selector ).slideDown();
820
  } else {
821
- jQuery( selector ).slideUp();
822
  }
823
  }
824
 
@@ -828,81 +650,81 @@ function advads_toggle_box(e, selector) {
828
  *
829
  * @param selector jquery selector
830
  */
831
- function advads_toggle_box_enable(e, selector) {
832
- if (jQuery( e ).is( ':checked' )) {
833
- jQuery( selector ).find( 'input' ).removeAttr( 'disabled', '' );
834
  } else {
835
- jQuery( selector ).find( 'input' ).attr( 'disabled', 'disabled' );
836
  }
837
  }
838
 
839
  /**
840
  * validate placement form on submit
841
  */
842
- function advads_validate_placement_form(){
843
  // check if placement type was selected
844
- if( ! jQuery('.advads-placement-type input:checked').length){
845
- jQuery('.advads-placement-type-error').show();
846
- return false;
847
  } else {
848
- jQuery('.advads-placement-type-error').hide();
849
  }
850
  // check if placement name was entered
851
- if( jQuery('.advads-new-placement-name').val() == '' ){
852
- jQuery('.advads-placement-name-error').show();
853
- return false;
854
  } else {
855
- jQuery('.advads-placement-name-error').hide();
856
  }
857
- return true;
858
  }
859
 
860
  /**
861
  * replace textarea with TinyMCE editor for Rich Content ad type
862
  */
863
- function advads_maybe_textarea_to_tinymce( ad_type ) {
864
  var textarea = jQuery( '#advads-ad-content-plain' ),
865
- textarea_html = textarea.val(),
866
- tinymce_id = 'advanced-ads-tinymce',
867
- tinymce_id_ws = jQuery( '#' + tinymce_id ),
868
- tinymce_wrapper_div = jQuery ( '#advanced-ads-tinymce-wrapper' );
869
 
870
  if ( ad_type !== 'content' ) {
871
- tinymce_id_ws.prop('name', tinymce_id );
872
- tinymce_wrapper_div.hide();
873
- return false;
874
  }
875
 
876
  if ( typeof tinyMCE === 'object' && tinyMCE.get( tinymce_id ) !== null ) {
877
  // visual mode
878
  if ( textarea_html ) {
879
  // see BeforeSetContent in the wp-includes\js\tinymce\plugins\wordpress\plugin.js
880
- var wp = window.wp,
881
- hasWpautop = ( wp && wp.editor && wp.editor.autop && tinyMCE.get( tinymce_id ).getParam( 'wpautop', true ) );
882
  if ( hasWpautop ) {
883
- textarea_html = wp.editor.autop( textarea_html );
884
  }
885
- tinyMCE.get( tinymce_id ).setContent( textarea_html );
886
  }
887
- textarea.remove();
888
- tinymce_id_ws.prop('name', textarea.prop( 'name' ) );
889
- tinymce_wrapper_div.show();
890
  } else if ( tinymce_id_ws.length ) {
891
  // text mode
892
- tinymce_id_ws.val( textarea_html );
893
- textarea.remove();
894
- tinymce_id_ws.prop('name', textarea.prop( 'name' ) );
895
- tinymce_wrapper_div.show();
896
  }
897
  }
898
 
899
  /**
900
  * Show a message depending on whether Adsense Auto ads are enabled.
901
  */
902
- function advads_show_adsense_auto_ads_warning() {
903
- $msg = jQuery( '.advads-auto-ad-in-ad-content' ).show();
904
- $msg.on( 'click', 'button', function() {
905
- $msg.hide();
906
  jQuery.ajax( {
907
  type: 'POST',
908
  url: ajaxurl,
@@ -910,70 +732,130 @@ function advads_show_adsense_auto_ads_warning() {
910
  action: 'advads-adsense-enable-pla',
911
  nonce: advadsglobal.ajax_nonce
912
  },
913
- } ).done(function( data ) {
914
- $msg.show().html( advadstxt.page_level_ads_enabled );
915
- } ).fail(function( jqXHR, textStatus ) {
916
- $msg.show();
917
- } );
918
- });
919
  }
920
 
921
  /**
922
  * Check if a third-party ads.txt file exists.
923
  */
924
- function advads_ads_txt_find_issues() {
925
- var $wrapper = jQuery( '#advads-ads-txt-notice-wrapper' );
926
- var $refresh = jQuery( '#advads-ads-txt-notice-refresh' );
 
 
 
 
 
 
 
 
 
 
 
 
 
927
 
928
  if ( ! $wrapper.length ) {
929
- return;
930
  }
931
 
932
  if ( ! $wrapper.find( 'ul' ).length ) {
933
- load();
 
934
  }
935
 
936
- $refresh.click( function() {
937
- load();
938
- } );
939
 
940
- function load() {
941
- $wrapper.empty().append( jQuery( '<span class="spinner advads-spinner"></span>' ) );
942
- $refresh.hide();
 
 
 
 
 
 
 
 
 
 
 
 
943
 
944
  jQuery.ajax( {
945
  type: 'POST',
946
  url: ajaxurl,
947
- dataType: 'html',
948
  data: {
949
  action: 'advads-ads-txt',
950
- nonce: advadsglobal.ajax_nonce
 
951
  },
952
- } ).done(function( response ) {
953
- $wrapper.html( response );
954
- $refresh.show();
955
- } ).fail(function( jqXHR ) {
956
- $wrapper.html( '<p class="advads-error-message">'
957
- + jQuery( '#advads-ads-txt-notice-error' ).text().replace( '%s', parseInt( jqXHR.status, 10 ) ),
958
- + '</p>'
959
- );
960
- $refresh.show();
961
- } );
962
  }
963
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
964
  }
965
 
966
- jQuery.fn.advads_tooltip = function() {
967
- return _advads_apply_jqueryui_widget.call( this, 'tooltip', ['tooltip'], arguments );
968
- };
969
 
970
- jQuery.fn.advads_button = function() {
971
- return _advads_apply_jqueryui_widget.call( this, 'button', ['button'], arguments );
972
- };
973
 
974
- jQuery.fn.advads_buttonset = function() {
975
- return _advads_apply_jqueryui_widget.call( this, 'buttonset', ['button', 'buttonset'], arguments );
976
- };
977
 
978
  /**
979
  * Apply jQueryUI widget.
@@ -982,25 +864,25 @@ jQuery.fn.advads_buttonset = function() {
982
  * @param arr revoke Names of Twitter Bootstrap widgets to revoke.
983
  * @param arguments_ mixed Widget arguments.
984
  */
985
- function _advads_apply_jqueryui_widget( name, revoke, args ) {
986
- var can_apply = true;
987
 
988
- jQuery.each( revoke, function( _index, _name ) {
989
  if ( jQuery.fn[ _name ].noConflict ) {
990
  // Revoke Twitter Bootstrap, assign jQuery UI.
991
- jQuery.fn[ _name ].noConflict();
992
  }
993
- can_apply = _advads_can_apply_jqueryui_widget( _name );
994
- });
995
 
996
  if ( ! can_apply ) {
997
  // The culprit is not Bootstrap, we haven't been able to assign jQuery UI.
998
- jQuery( '.advads-jqueryui-error').show();
999
- return;
1000
  }
1001
 
1002
- var r = this[ name ].apply( this, args );
1003
- return r;
1004
  }
1005
 
1006
  /**
@@ -1009,18 +891,18 @@ function _advads_apply_jqueryui_widget( name, revoke, args ) {
1009
  * @param name Widget name.
1010
  * @return bool
1011
  */
1012
- var _advads_can_apply_jqueryui_widget = ( function( name ) {
1013
- var r = {};
1014
  return function ( name ) {
1015
  if ( ! r.hasOwnProperty( name ) ) {
1016
- var needle = 'prior to initialization;'; // A string from jquery-ui source code.
1017
- r[ name ] = jQuery.fn[ name ].toString().indexOf( needle ) !== -1;
1018
  }
1019
- return r[ name ];
1020
- };
1021
- })();
1022
 
1023
- window.advanced_ads_admin = window.advanced_ads_admin || {};
1024
  advanced_ads_admin.filesystem = {
1025
  /**
1026
  * Holds the current job while the user writes data in the 'Connection Information' modal.
@@ -1032,37 +914,37 @@ advanced_ads_admin.filesystem = {
1032
  /**
1033
  * Toggle the 'Connection Information' modal.
1034
  */
1035
- _requestForCredentialsModalToggle: function() {
1036
- this.$filesystemModal.toggle();
1037
- jQuery( 'body' ).toggleClass( 'modal-open' );
1038
  },
1039
 
1040
- _init: function() {
1041
- this._init = function() {}
1042
- var self = this;
1043
 
1044
- self.$filesystemModal = jQuery( '#advanced-ads-rfc-dialog' );
1045
  /**
1046
  * Sends saved job.
1047
  */
1048
- self.$filesystemModal.on( 'submit', 'form', function( event ) {
1049
- event.preventDefault();
1050
 
1051
- self.ajax( self._locked_job, true );
1052
  self._requestForCredentialsModalToggle()
1053
- } );
1054
 
1055
  /**
1056
  * Closes the request credentials modal when clicking the 'Cancel' button.
1057
  */
1058
- self.$filesystemModal.on( 'click', '[data-js-action="close"]', function() {
1059
  if ( jQuery.isPlainObject( self._locked_job ) && self._locked_job.on_modal_close ) {
1060
- self._locked_job.on_modal_close();
1061
  }
1062
 
1063
- self._locked_job = false;
1064
- self._requestForCredentialsModalToggle();
1065
- } );
1066
  },
1067
 
1068
  /**
@@ -1071,275 +953,274 @@ advanced_ads_admin.filesystem = {
1071
  * @param {object} args
1072
  * @param {bool} skip_modal
1073
  */
1074
- ajax: function( args, skip_modal ) {
1075
- this._init();
1076
 
1077
  if ( ! skip_modal && this.$filesystemModal.length > 0 ) {
1078
- this._requestForCredentialsModalToggle();
1079
- this.$filesystemModal.find( 'input:enabled:first' ).focus();
1080
 
1081
  // Do not send request.
1082
- this._locked_job = args;
1083
- return;
1084
  }
1085
 
1086
  var options = {
1087
  method: 'POST',
1088
  url: window.ajaxurl,
1089
  data: {
1090
- username: jQuery( '#username' ).val(),
1091
- password: jQuery( '#password' ).val(),
1092
- hostname: jQuery( '#hostname' ).val(),
1093
  connection_type: jQuery( 'input[name="connection_type"]:checked' ).val(),
1094
- public_key: jQuery( '#public_key' ).val(),
1095
- private_key: jQuery( '#private_key' ).val(),
1096
- _fs_nonce: jQuery( '#_fs_nonce' ).val()
1097
 
1098
  }
1099
- };
1100
 
1101
- options.data = jQuery.extend( options.data, args.data );
1102
- var request = jQuery.ajax( options );
 
 
 
 
1103
 
1104
  if ( args.done ) {
1105
- request.done( args.done );
1106
  }
1107
 
1108
  if ( args.fail ) {
1109
- request.fail( args.fail );
1110
  }
1111
  }
1112
  }
1113
 
1114
  window.Advanced_Ads_Admin = window.Advanced_Ads_Admin || {
1115
- init_ad_source_editor: function(){
1116
-
1117
  },
1118
- get_ad_source_editor_text: function(){
1119
- var text = undefined;
1120
- if (Advanced_Ads_Admin.editor){
1121
- if (Advanced_Ads_Admin.editor.codemirror){
1122
- text = Advanced_Ads_Admin.editor.codemirror.getValue();
1123
- }
1124
- }
1125
- if (! text){
1126
- var ta = jQuery('#advads-ad-content-plain');
1127
- if (ta) text = ta.val();
1128
- }
1129
- return text;
1130
  },
1131
- set_ad_source_editor_text: function(text){
1132
- if (Advanced_Ads_Admin.editor && Advanced_Ads_Admin.editor.codemirror){
1133
- Advanced_Ads_Admin.editor.codemirror.setValue(text);
1134
- }
1135
- else {
1136
- jQuery('#advads-ad-content-plain').val(text);
1137
- }
1138
  },
1139
- check_ad_source: function(){
1140
- var text = Advanced_Ads_Admin.get_ad_source_editor_text();
1141
- var enabled_php = jQuery('#advads-parameters-php').prop('checked');
1142
- var enabled_sc = jQuery('#advads-parameters-shortcodes').prop('checked');
1143
- if (enabled_php && ! /\<\?php/.test(text)){
1144
- jQuery('#advads-parameters-php-warning').show();
1145
- }
1146
- else{
1147
- jQuery('#advads-parameters-php-warning').hide();
1148
- }
1149
- if (enabled_sc && ! /\[[^\]]+\]/.test(text)){
1150
- jQuery('#advads-parameters-shortcodes-warning').show();
1151
- }
1152
- else{
1153
- jQuery('#advads-parameters-shortcodes-warning').hide();
1154
- }
1155
- },
1156
- toggle_placements_visibility: function(elm){
1157
- var advadsplacementformrow = jQuery( elm ).next( '.advads-placements-advanced-options' );
1158
- if( advadsplacementformrow.is( ':visible' ) ){
1159
- advadsplacementformrow.hide();
1160
  // clear last edited id
1161
- jQuery('#advads-last-edited-placement').val('');
1162
  } else {
1163
- var placement_id = jQuery( elm ).parents( '.advads-placements-table-options' ).find('.advads-placement-slug').val();
1164
- advadsplacementformrow.show();
1165
- jQuery('#advads-last-edited-placement').val( placement_id );
1166
  // some special elements (color picker) may not be detected with jquery
1167
- var tr = jQuery( elm ).closest( 'tr.advanced-ads-placement-row' );
1168
- if (tr){
1169
- tr.data('touched', true);
1170
  }
1171
  }
1172
- }
1173
- };
1174
-
1175
 
1176
- if (! window.AdvancedAdsAdmin) window.AdvancedAdsAdmin = {};
1177
- if (! window.AdvancedAdsAdmin.AdImporter) window.AdvancedAdsAdmin.AdImporter = {
1178
  /**
1179
  * will highlight the currently selected ads in the list
1180
  * @param hideInactive when true will hide inactive ad units
1181
  * @returns the selector of the selected row or false if no row was selected.
1182
  */
1183
- highlightSelectedRowInExternalAdsList: function(hideInactive){
1184
- if (typeof(hideInactive) == 'undefined') hideInactive = AdvancedAdsAdmin.AdImporter.adNetwork.hideIdle;
1185
- const tbody = jQuery( '#mapi-table-wrap tbody' );
1186
- const btn = jQuery('#mapi-toggle-idle');
1187
 
1188
  // count the ad units to determine if there's a need for the overflow class (scrolling)
1189
  const nbUnits = hideInactive
1190
  ? jQuery( '#mapi-table-wrap tbody tr[data-active=1]' ).length
1191
- : jQuery( '#mapi-table-wrap tbody tr' ).length;
1192
- if (nbUnits > 8) jQuery( '#mapi-table-wrap' ).addClass('overflow');
1193
- else jQuery( '#mapi-table-wrap' ).removeClass('overflow');
1194
 
1195
  // hide inactive ads, but always show the selected one (if any)
1196
- if (hideInactive) {
1197
- btn.removeClass('dashicons-hidden');
1198
- btn.addClass('dashicons-visibility');
1199
- btn.attr('title', advadstxt.show_inactive_ads);
1200
- tbody.find('tr[data-slotid]').each(function (k, v) {
1201
- v = jQuery(v);
1202
- if (v.data("active")) v.show();
1203
- else v.hide();
1204
- });
1205
- }
1206
- else{
1207
- btn.removeClass('dashicons-visibility');
1208
- btn.addClass('dashicons-hidden');
1209
- btn.attr('title', advadstxt.hide_inactive_ads);
1210
- tbody.find('tr[data-slotid]').show();
1211
  }
1212
 
1213
- const selectedRow = AdvancedAdsAdmin.AdImporter.getSelectedRow();
1214
- tbody.find( 'tr' ).removeClass( 'selected' );
1215
- if (selectedRow){
1216
  //make sure, it is visible before applying the zebra stripes
1217
- selectedRow.show();
1218
  }
1219
 
1220
  // make the table's rows striped.
1221
- const visible = tbody.find( 'tr:visible' );
1222
- visible.filter( ':odd' ).css('background-color', '#FFFFFF');
1223
- visible.filter( ':even' ).css('background-color', '#F9F9F9');
1224
 
1225
  // highlight the selected row
1226
- if (selectedRow){
1227
  // highlight the selected row
1228
- selectedRow.css('background-color', '');
1229
- selectedRow.addClass( 'selected' );
1230
  }
1231
- return selectedRow || false;
1232
  },
1233
- getSelectedRow(){
1234
- const selectedId = AdvancedAdsAdmin.AdImporter.adNetwork.getSelectedId();
1235
- const tbody = jQuery( '#mapi-table-wrap tbody' );
1236
 
1237
- if (selectedId){
1238
- const selectedRows = tbody.find( 'tr[data-slotid="' + selectedId + '"]' );
1239
  if ( selectedRows.length ) {
1240
- return selectedRows;
1241
  }
1242
  }
1243
- return null;
1244
  },
1245
- openExternalAdsList: function(){
1246
- const network = AdvancedAdsAdmin.AdImporter.adNetwork;
1247
- network.openSelector();
1248
 
1249
- jQuery( '#mapi-insert-code' ).css( 'display', 'inline' );
1250
- jQuery( '#mapi-open-selector' ).css( 'display', 'none' );
1251
- jQuery( '#mapi-close-selector-link' ).css( 'display', 'inline' );
1252
- jQuery( '.advads-adsense-code' ).css( 'display', 'none' );
1253
- jQuery( '#remote-ad-unsupported-ad-type' ).css( 'display', 'none' );
1254
 
1255
- AdvancedAdsAdmin.AdImporter.highlightSelectedRowInExternalAdsList(network.hideIdle);
1256
 
1257
- var SNT = network.getCustomInputs();
1258
- SNT.css( 'display', 'none' );
1259
 
1260
- jQuery( '#mapi-wrap' ).css( 'display', 'block' );
1261
 
1262
- if (! network.fetchedExternalAds){
1263
- network.fetchedExternalAds = true;
1264
- const nbUnits = jQuery( '#mapi-table-wrap tbody tr[data-slotid]' ).length;
1265
- if (nbUnits == 0) {
1266
  //usually we start with a preloaded list.
1267
  //only reload, when the count is zero (true for new accounts).
1268
- AdvancedAdsAdmin.AdImporter.refreshAds();
1269
  }
1270
  }
1271
- AdvancedAdsAdmin.AdImporter.resizeAdListHeader();
1272
- },
1273
  /**
1274
  * will be called every time the ad type is changed.
1275
  * required for onBlur detection
1276
  */
1277
- onChangedAdType: function(){
1278
- if (AdvancedAdsAdmin.AdImporter.adNetwork){
1279
- AdvancedAdsAdmin.AdImporter.adNetwork.onBlur();
1280
- AdvancedAdsAdmin.AdImporter.adNetwork = null;
1281
  }
1282
  },
1283
- setup: function (adNetwork) {
1284
- AdvancedAdsAdmin.AdImporter.adNetwork = adNetwork;
1285
- adNetwork.onSelected();
1286
- if (AdvancedAdsAdmin.AdImporter.isSetup) {
1287
- AdvancedAdsAdmin.AdImporter.highlightSelectedRowInExternalAdsList();
1288
- return;
1289
  }
1290
- AdvancedAdsAdmin.AdImporter.isSetup = true;
1291
 
1292
- jQuery( document ).on( 'click', '.prevent-default', function( ev ) { ev.preventDefault() } );
1293
 
1294
  // handle clicks for the "insert new ... code" anchor
1295
- jQuery( document ).on('click', '#mapi-insert-code', function(e){
1296
- e.preventDefault();
1297
- jQuery( '.advads-adsense-code' ).show();
1298
- jQuery( '#mapi-open-selector' ).css( 'display', 'inline' );
1299
- jQuery( '#mapi-close-selector-link' ).css( 'display', 'inline' );
1300
- jQuery( '#mapi-wrap' ).css( 'display', 'none' );
1301
- var SNT = AdvancedAdsAdmin.AdImporter.adNetwork.getCustomInputs();
1302
- SNT.css( 'display', 'none' );
1303
- jQuery( this ).hide();
1304
- });
1305
 
1306
  // handle clicks for the "get ad code from your linked account" anchor
1307
- jQuery( document ).on( 'click', '#mapi-open-selector a', function(){
1308
- AdvancedAdsAdmin.AdImporter.openExternalAdsList();
1309
- });
1310
 
1311
  // the close button of the ad unit list
1312
- jQuery( document ).on( 'click', '#mapi-close-selector,#mapi-close-selector-link', function(){
1313
- AdvancedAdsAdmin.AdImporter.manualSetup();
1314
- } );
1315
 
1316
  //the individual rows of the ad units may contain elements with the mapiaction class
1317
- jQuery( document ).on( 'click', '.mapiaction', function( ev ) {
1318
- var action = jQuery( this ).attr( 'data-mapiaction' );
1319
  switch ( action ) {
1320
  case 'updateList':
1321
- AdvancedAdsAdmin.AdImporter.refreshAds();
1322
- break;
1323
  case 'getCode':
1324
  if ( jQuery( this ).hasClass( 'disabled' ) ) {
1325
- break;
1326
  }
1327
- var slotId = jQuery( this ).attr( 'data-slotid' );
1328
- AdvancedAdsAdmin.AdImporter.adNetwork.selectAdFromList(slotId);
1329
- break;
1330
  case 'updateCode':
1331
- var slotId = jQuery( this ).attr( 'data-slotid' );
1332
- AdvancedAdsAdmin.AdImporter.adNetwork.updateAdFromList(slotId);
1333
- break;
1334
  case 'toggleidle':
1335
- AdvancedAdsAdmin.AdImporter.adNetwork.hideIdle = !AdvancedAdsAdmin.AdImporter.adNetwork.hideIdle;
1336
- AdvancedAdsAdmin.AdImporter.toggleIdleAds( AdvancedAdsAdmin.AdImporter.adNetwork.hideIdle );
1337
- break;
1338
  default:
1339
  }
1340
- } );
1341
 
1342
- AdvancedAdsAdmin.AdImporter.adNetwork.onDomReady();
1343
  // AdvancedAdsAdmin.AdImporter.openExternalAdsList();
1344
 
1345
  },
@@ -1348,62 +1229,60 @@ if (! window.AdvancedAdsAdmin.AdImporter) window.AdvancedAdsAdmin.AdImporter = {
1348
  * call this method to display the manual setup (if available for the current ad network)
1349
  * this method is an equivalent to the close ad list button.
1350
  */
1351
- manualSetup(){
1352
- jQuery( '#mapi-open-selector,.advads-adsense-show-code' ).css( 'display', 'inline' );
1353
- jQuery( '#mapi-insert-code' ).css( 'display', 'inline' );
1354
- jQuery( '#mapi-close-selector-link' ).css( 'display', 'none' );
1355
- jQuery( '#mapi-wrap' ).css( 'display', 'none' );
1356
-
1357
- var SNT = AdvancedAdsAdmin.AdImporter.adNetwork.getCustomInputs();
1358
- SNT.css( 'display', 'block' );
1359
- AdvancedAdsAdmin.AdImporter.adNetwork.onManualSetup();
1360
  },
1361
 
1362
- setRemoteErrorMessage(msg){
1363
- if (! msg) jQuery('#remote-ad-code-msg').empty();
1364
- else jQuery('#remote-ad-code-msg').html(msg);
1365
  },
1366
 
1367
  // another legacy method
1368
- resizeAdListHeader: function() {
1369
- var th = jQuery( '#mapi-list-header span' );
1370
- var tb = jQuery( '#mapi-table-wrap tbody tr:visible' );
1371
- var w = [];
1372
 
1373
- tb.first().find( 'td' ).each(function(){
1374
- w.push( jQuery( this ).width() );
1375
- });
1376
 
1377
- th.each(function(i){
1378
  if ( i != w.length - 1 ) {
1379
- jQuery( this ).width( w[i] );
1380
  }
1381
- });
1382
  },
1383
 
1384
-
1385
-
1386
  /**
1387
  * legacy method
1388
  */
1389
- closeAdSelector: function() {
1390
  // close the ad unit selector
1391
- setTimeout(function(){
1392
- jQuery( '#mapi-wrap' ).animate(
1393
  { height: 0, },
1394
  360,
1395
- function(){
1396
- jQuery( '#mapi-open-selector,.advads-adsense-show-code' ).css( 'display', 'inline' );
1397
- jQuery( '#mapi-close-selector-link' ).css( 'display', 'none' );
1398
- jQuery( '#mapi-wrap' ).css({
1399
  display: 'none',
1400
  height: 'auto',
1401
- });
1402
- const SNT = AdvancedAdsAdmin.AdImporter.adNetwork.getCustomInputs();
1403
- SNT.css( 'display', 'block' );
1404
  }
1405
- );
1406
- }, 80);
1407
 
1408
  },
1409
 
@@ -1411,20 +1290,20 @@ if (! window.AdvancedAdsAdmin.AdImporter) window.AdvancedAdsAdmin.AdImporter = {
1411
  * legacy method
1412
  * updates the UI, (call if the selected unit is supported)
1413
  */
1414
- unitIsNotSupported: function( slotID ) {
1415
- jQuery( '#remote-ad-unsupported-ad-type' ).css( 'display', 'block' );
1416
- AdsenseMAPI.unsupportedUnits[slotID] = 1;
1417
- jQuery( 'i[data-mapiaction="getCode"][data-slotid="' + slotID + '"]' ).addClass( 'disabled' );
1418
- jQuery( 'tr[data-slotid="' + slotID + '"] .unitcode > span' ).addClass( 'unsupported' );
1419
  if ( ! jQuery( 'tr[data-slotid="' + slotID + '"] .unittype a' ).length ) {
1420
- var td = jQuery( 'tr[data-slotid="' + slotID + '"] .unittype' );
1421
- var content = td.text();
1422
- td.html( '<a target="_blank" href="' + AdsenseMAPI.unsupportedLink + '" data-type="' + content + '">' + AdsenseMAPI.unsupportedText + '</a>' );
1423
  }
1424
  if ( ! jQuery( 'tr[data-slotid="' + slotID + '"] .unitsize a' ).length ) {
1425
- var td = jQuery( 'tr[data-slotid="' + slotID + '"] .unitsize' );
1426
- var content = td.text();
1427
- td.html( '<a target="_blank" href="' + AdsenseMAPI.unsupportedLink + '" data-size="' + content + '">' + AdsenseMAPI.unsupportedText + '</a>' );
1428
  }
1429
 
1430
  },
@@ -1433,22 +1312,22 @@ if (! window.AdvancedAdsAdmin.AdImporter) window.AdvancedAdsAdmin.AdImporter = {
1433
  * legacy method
1434
  * updates the UI, (call if the selected unit is NOT supported)
1435
  */
1436
- unitIsSupported: function( slotID ) {
1437
- jQuery( '#remote-ad-unsupported-ad-type' ).css( 'display', 'none' );
1438
- if ( 'undefined' != typeof AdsenseMAPI.unsupportedUnits[slotID] ) {
1439
- delete AdsenseMAPI.unsupportedUnits[slotID];
1440
  }
1441
- jQuery( 'i[data-mapiaction="getCode"][data-slotid="' + slotID + '"]' ).removeClass( 'disabled' );
1442
- jQuery( 'tr[data-slotid="' + slotID + '"] .unitcode > span' ).removeClass( 'unsupported' );
1443
  if ( jQuery( 'tr[data-slotid="' + slotID + '"] .unittype a' ).length ) {
1444
- var td = jQuery( 'tr[data-slotid="' + slotID + '"] .unittype' );
1445
- var content = jQuery( 'tr[data-slotid="' + slotID + '"] .unittype a' ).attr( 'data-type' );
1446
- td.text( content );
1447
  }
1448
  if ( jQuery( 'tr[data-slotid="' + slotID + '"] .unitsize a' ).length ) {
1449
- var td = jQuery( 'tr[data-slotid="' + slotID + '"] .unitsize' );
1450
- var content = jQuery( 'tr[data-slotid="' + slotID + '"] .unitsize a' ).attr( 'data-size' );
1451
- td.text( content );
1452
  }
1453
  },
1454
 
@@ -1456,48 +1335,48 @@ if (! window.AdvancedAdsAdmin.AdImporter) window.AdvancedAdsAdmin.AdImporter = {
1456
  * legacy method
1457
  * updates the UI, (call if the selected unit is NOT supported)
1458
  */
1459
- emptyMapiSelector: function( msg ) {
1460
- const nag = '<div class="notice notice-error" style="font-size:1.1em;padding:.6em 1em;font-weight:bold;">' + msg + '</div>';
1461
- jQuery( '#mapi-loading-overlay' ).css( 'display', 'none' );
1462
- jQuery( '#mapi-wrap' ).html( jQuery( nag ) );
1463
  },
1464
 
1465
  /**
1466
  * legacy method
1467
  */
1468
- refreshAds: function() {
1469
- const adNetwork = AdvancedAdsAdmin.AdImporter.adNetwork;
1470
- jQuery( '#mapi-loading-overlay' ).css( 'display', 'block' );
1471
- jQuery.ajax({
1472
  type: 'post',
1473
  url: ajaxurl,
1474
  data: adNetwork.getRefreshAdsParameters(),
1475
- success: function(response,status,XHR){
1476
  if ( 'undefined' != typeof response.html ) {
1477
- jQuery( '#mapi-wrap' ).replaceWith( jQuery( response.html ) );
1478
- AdvancedAdsAdmin.AdImporter.openExternalAdsList();
1479
  } else if ( 'undefined' != typeof response.msg ) {
1480
- AdvancedAdsAdmin.AdImporter.emptyMapiSelector( response.msg );
1481
  }
1482
  if ( 'undefined' != typeof response.raw ) {
1483
- console.log( response.raw );
1484
  }
1485
- jQuery( '#mapi-loading-overlay' ).css( 'display', 'none' );
1486
  },
1487
- error: function(request,status,err){
1488
- jQuery( '#mapi-loading-overlay' ).css( 'display', 'none' );
1489
  },
1490
- });
1491
 
1492
  },
1493
 
1494
  toggleIdleAds: function ( hide ) {
1495
  if ( 'undefined' == typeof hide ) {
1496
- hide = true;
1497
  }
1498
- AdvancedAdsAdmin.AdImporter.highlightSelectedRowInExternalAdsList(hide);
1499
  }
1500
- };
1501
 
1502
  /**
1503
  * The "abstract" base class for handling external ad units
@@ -1513,52 +1392,52 @@ if (! window.AdvancedAdsAdmin.AdImporter) window.AdvancedAdsAdmin.AdImporter = {
1513
  * hideIdle Remembers, wheter idle ads should be displayed in the list;
1514
  * fetchedExternalAds Remembers if the external ads list has already been loaded to prevent unneccesary requests
1515
  */
1516
- class AdvancedAdsAdNetwork{
1517
  /**
1518
  * @param id string representing the id of this network. has to match the identifier of the PHP class
1519
  */
1520
- constructor(id){
1521
- this.id = id;
1522
- this.units = [];
1523
- this.vars = window[id + 'AdvancedAdsJS'];
1524
- this.hideIdle = true;
1525
- this.fetchedExternalAds = false;
1526
  }
1527
 
1528
  /**
1529
  * will be called when an ad network is selected (ad type in edit ad)
1530
  */
1531
- onSelected(){
1532
- console.error("Please override onSelected.");
1533
  }
1534
 
1535
  /**
1536
  * will be called when an ad network deselected (ad type in edit ad)
1537
  */
1538
- onBlur(){
1539
- console.error("Please override onBlur.");
1540
  }
1541
 
1542
  /**
1543
  * opens the selector list containing the external ad units
1544
  */
1545
- openSelector(){
1546
- console.error("Please override openSelector.");
1547
  }
1548
 
1549
  /**
1550
  * returns the network specific id of the currently selected ad unit
1551
  */
1552
- getSelectedId(){
1553
- console.error("Please override getSelectedId.");
1554
  }
1555
 
1556
  /**
1557
  * will be called when an external ad unit has been selected from the selector list
1558
  * @param slotId string the external ad unit id
1559
  */
1560
- selectAdFromList(slotId){
1561
- console.error("Please override selectAdFromList.");
1562
  }
1563
 
1564
  /**
@@ -1566,41 +1445,40 @@ class AdvancedAdsAdNetwork{
1566
  * TODO: decide wheter to remove this method. not required anymore - the button was removed.
1567
  * @param slotId string the external ad unit id
1568
  */
1569
- updateAdFromList(slotId){
1570
- console.error("Please override updateAdFromList.");
1571
  }
1572
 
1573
-
1574
  /**
1575
  * return the POST params that you want to send to the server when requesting a refresh of the external ad units
1576
  * (like nonce and action and everything else that is required)
1577
  */
1578
- getRefreshAdsParameters(){
1579
- console.error("Please override getRefreshAdsParameters.");
1580
  }
1581
 
1582
  /**
1583
  * return the jquery objects for all the custom html elements of this ad type
1584
  */
1585
- getCustomInputs(){
1586
- console.error("Please override getCustomInputs.");
1587
  }
1588
 
1589
  /**
1590
  * what to do when the DOM is ready
1591
  */
1592
- onDomReady(){
1593
- console.error("Please override onDomReady.");
1594
  }
1595
 
1596
  /**
1597
  * when you need custom behaviour for ad networks that support manual setup of ad units, override this method
1598
  */
1599
- onManualSetup(){
1600
  //no console logging. this is optional
1601
  }
1602
  }
1603
 
1604
- class AdvancedAdsExternalAdUnit{
1605
 
1606
  }
1
+ jQuery( document ).ready( function ( $ ) {
2
+ function advads_load_ad_type_parameter_metabox ( ad_type ) {
3
+ jQuery( '#advanced-ad-type input' ).prop( 'disabled', true )
4
+ $( '#advanced-ads-tinymce-wrapper' ).hide()
5
+ $( '#advanced-ads-ad-parameters' ).html( '<span class="spinner advads-ad-parameters-spinner advads-spinner"></span>' )
6
+ $.ajax( {
7
  type: 'POST',
8
  url: ajaxurl,
9
  data: {
12
  'ad_id': $( '#post_ID' ).val(),
13
  'nonce': advadsglobal.ajax_nonce
14
  },
15
+ success: function ( data, textStatus, XMLHttpRequest ) {
16
+ // toggle main content field.
17
+ if ( data ) {
18
+ $( '#advanced-ads-ad-parameters' ).html( data ).trigger( 'paramloaded' )
19
+ advads_maybe_textarea_to_tinymce( ad_type )
20
  }
21
  },
22
+ error: function ( MLHttpRequest, textStatus, errorThrown ) {
23
+ $( '#advanced-ads-ad-parameters' ).html( errorThrown )
24
  }
25
+ } ).always( function ( MLHttpRequest, textStatus, errorThrown ) {
26
+ jQuery( '#advanced-ad-type input' ).prop( 'disabled', false )
27
+ } )
28
+ }
29
+
30
+ $( document ).on( 'click', '#switch-to-adsense-type', function ( ev ) {
31
+ ev.preventDefault()
32
+ AdvancedAdsAdmin.AdImporter.adsenseCode = Advanced_Ads_Admin.get_ad_source_editor_text()
33
+ $( '#advanced-ad-type-adsense' ).trigger( 'click' )
34
+ $( this ).closest( 'li' ).addClass( 'hidden' )
35
+ } )
36
+
37
+ $( document ).on( 'change', '#advanced-ad-type input', function () {
38
  var ad_type = $( this ).val()
39
+ advads_load_ad_type_parameter_metabox( ad_type )
40
+ } )
41
 
42
  // trigger for ad injection after ad creation
43
+ $( '#advads-ad-injection-box .advads-ad-injection-button' ).on( 'click', function () {
44
  var placement_type = this.dataset.placementType, // create new placement
45
+ placement_slug = this.dataset.placementSlug, // use existing placement
46
+ options = {}
47
 
48
+ if ( ! placement_type && ! placement_slug ) { return }
49
 
50
  // create new placement
51
  if ( placement_type ) {
52
+ // for content injection
53
+ if ( 'post_content' === placement_type ) {
54
+ var paragraph = prompt( advadstxt.after_paragraph_promt, 1 )
55
  if ( paragraph !== null ) {
56
+ options.index = parseInt( paragraph, 10 )
57
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  }
 
 
 
 
 
 
 
 
59
  }
60
+ $( '#advads-ad-injection-box .advads-loader' ).show()
61
+ $( '#advads-ad-injection-box-placements' ).hide()
62
+ $( 'body' ).animate( { scrollTop: $( '#advads-ad-injection-box' ).offset().top - 40 }, 1, 'linear' )
63
+
64
+ $.ajax( {
65
+ type: 'POST',
66
+ url: ajaxurl,
67
+ data: {
68
+ action: 'advads-ad-injection-content',
69
+ placement_type: placement_type,
70
+ placement_slug: placement_slug,
71
+ ad_id: $( '#post_ID' ).val(),
72
+ options: options,
73
+ nonce: advadsglobal.ajax_nonce
74
+ },
75
+ success: function ( r, textStatus, XMLHttpRequest ) {
76
+ if ( ! r ) {
77
+ $( '#advads-ad-injection-box' ).html( 'an error occured' )
78
+ return
79
+ }
80
+
81
+ $( '#advads-ad-injection-box *' ).hide()
82
+ // append anchor to placement message
83
+ $( '#advads-ad-injection-message-placement-created .advads-placement-link' ).attr( 'href', $( '#advads-ad-injection-message-placement-created a' ).attr( 'href' ) + r )
84
+ $( '#advads-ad-injection-message-placement-created, #advads-ad-injection-message-placement-created *' ).show()
85
+ },
86
+ error: function ( MLHttpRequest, textStatus, errorThrown ) {
87
+ $( '#advads-ad-injection-box' ).html( errorThrown )
88
+ }
89
+ } ).always( function ( MLHttpRequest, textStatus, errorThrown ) {
90
+ // jQuery( '#advanced-ad-type input').prop( 'disabled', false );
91
+ } )
92
+ } )
93
 
94
  // activate general buttons
95
  if ( $.fn.advads_buttonset ) {
96
+ $( '.advads-buttonset' ).advads_buttonset()
97
  }
98
  // activate accordions
99
  if ( $.fn.accordion ) {
100
+ $( '.advads-accordion' ).accordion( {
101
+ active: false,
102
+ collapsible: true,
103
+ } )
104
  }
105
 
106
+ /**
107
+ * Logic for ad groups
108
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
  // display new ad group form
111
+ $( '#advads-new-ad-group-link' ).click( function ( e ) {
112
+ e.preventDefault()
113
+ $( '#advads-new-group-form' ).show().find( 'input[type="text"]' ).focus()
114
+ } )
115
 
116
  // display ad groups form
117
+ $( '#advads-ad-group-list a.edit, #advads-ad-group-list a.row-title' ).click( function ( e ) {
118
+ e.preventDefault()
119
+ var advadsgroupformrow = $( this ).parents( '.advads-group-row' ).next( '.advads-ad-group-form' )
120
+ if ( advadsgroupformrow.is( ':visible' ) ) {
121
+ advadsgroupformrow.hide()
122
  // clear last edited id
123
+ $( '#advads-last-edited-group' ).val( '' )
124
  } else {
125
+ advadsgroupformrow.show()
126
+ var group_id = advadsgroupformrow.find( '.advads-group-id' ).val()
127
+ $( '#advads-last-edited-group' ).val( group_id )
128
  // remember that we opened that one
129
+ advadsgroupformrow.data( 'touched', true )
130
  }
131
+ } )
132
  // display ad groups usage
133
+ $( '#advads-ad-group-list a.usage' ).click( function ( e ) {
134
+ e.preventDefault()
135
+ var usagediv = $( this ).parents( '.advads-group-row' ).find( '.advads-usage' )
136
+ if ( usagediv.is( ':visible' ) ) {
137
+ usagediv.hide()
138
  } else {
139
+ usagediv.show()
140
  }
141
+ } )
142
  // handle the submission of the groups form
143
+ $( 'form#advads-form-groups' ).submit( function () {
144
+ var grouprows = jQuery( 'tr.advads-ad-group-form' )
145
+ jQuery( 'tr.advads-ad-group-form' ).each( function ( k, v ) {
146
+ v = jQuery( v )
147
+ if ( ! v.data( 'touched' ) ) {
148
+ v.remove()
149
  }
150
+ } )
151
+ } )
152
  // display placement settings form
153
+ $( '.advads-placements-table a.advads-placement-options-link' ).click( function ( e ) {
154
+ e.preventDefault()
155
+ Advanced_Ads_Admin.toggle_placements_visibility( this )
156
+ } )
157
  // display manual placement usage
158
+ $( '.advads-placements-table .usage-link' ).click( function ( e ) {
159
+ e.preventDefault()
160
+ var usagediv = $( this ).parents( 'tr' ).find( '.advads-usage' )
161
+ if ( usagediv.is( ':visible' ) ) {
162
+ usagediv.hide()
163
  } else {
164
+ usagediv.show()
165
  }
166
+ } )
167
  // show warning if Container ID option contains invalid characters
168
+ $( '#advads-output-wrapper-id' ).keyup( function () {
169
+ var id_value = $( this ).val()
170
+ if ( /^[a-z-0-9]*$/.test( id_value ) ) {
171
+ $( '.advads-output-wrapper-id-error' ).removeClass( 'advads-error-message' )
172
+ } else {
173
+ $( '.advads-output-wrapper-id-error' ).addClass( 'advads-error-message' ).css( 'display', 'block' )
174
+ }
175
+ } )
176
  /**
177
+ * Automatically open all options and show usage link when this is the placement linked in the URL
178
  * also highlight the box with an effect for a short time
179
  */
180
+ if ( jQuery( window.location.hash ).length ) {
181
+ jQuery( window.location.hash ).find( '.advads-toggle-link + div, .advads-usage' ).show()
182
 
183
  }
184
 
185
  // group page: add ad to group
186
+ $( '.advads-group-add-ad button' ).click( function () {
187
  var $settings_row = $( this ).closest( '.advads-ad-group-form' ),
188
+ $ad = $settings_row.find( '.advads-group-add-ad-list-ads option:selected' )
189
+ $weight_selector = $settings_row.find( '.advads-group-add-ad-list-weights' ).last(),
190
+ $ad_table = $settings_row.find( '.advads-group-ads tbody' )
191
  // add new row if does not already exist
192
+ if ( $ad.length && $weight_selector.length && ! $ad_table.find( '[name="' + $ad.val() + '"]' ).length ) {
193
  $ad_table.append(
194
  $( '<tr></tr>' ).append(
195
  $( '<td></td>' ).html( $ad.text() ),
196
  $( '<td></td>' ).append( $weight_selector.clone().val( $weight_selector.val() ).prop( 'name', $ad.val() ) ),
197
  '<td><button type="button" class="advads-remove-ad-from-group button">x</button></td>'
198
  )
199
+ )
200
  }
201
+ } )
202
  // group page: remove ad from group
203
+ $( '#advads-ad-group-list' ).on( 'click', '.advads-remove-ad-from-group', function () {
204
+ var $ad_row = $( this ).closest( 'tr' )
205
 
206
  if ( $ad_row.data( 'ad-id' ) ) {
207
  // save the ad id, it is needed when this ad is not included in any other group
208
  $( '#advads-ad-group-list form' ).append(
209
+ '<input type="hidden" name="advads-groups-removed-ads[]" value="' + $ad_row.data( 'ad-id' ) + '">'
210
+ + '<input type="hidden" name="advads-groups-removed-ads-gid[]" value="' + $ad_row.data( 'group-id' ) + '">'
211
+ )
212
  }
213
+ $ad_row.remove()
214
+ } )
215
  // group page: handle switching of group types based on a class derrived from that type
216
+ $( '.advads-ad-group-type input' ).click( function () {
217
+ advads_show_group_options( $( this ) )
218
+ } )
219
+
220
+ function advads_show_group_options ( el ) {
221
  // first, hide all options except title and type
222
  // iterate through all elements
223
+ el.each( function () {
224
+ var _this = jQuery( this )
225
+ _this.parents( '.advads-ad-group-form' ).find( '.advads-option:not(.static)' ).hide()
226
+ var current_type = _this.val()
227
 
228
  // now, show only the ones corresponding with the group type
229
+ _this.parents( '.advads-ad-group-form' ).find( '.advads-group-type-' + current_type ).show()
230
+ } )
231
  }
232
+
233
  // set default group options for earch group
234
 
235
+ advads_show_group_options( $( '.advads-ad-group-type input:checked' ) )
236
  // group page: hide ads if more than 4 – than only show 3
237
+ $( '.advads-ad-group-list-ads' ).each( function () {
238
+ if ( 5 <= $( this ).find( 'li' ).length ) {
239
+ $( this ).find( 'li:gt(2)' ).hide()
240
+ }
241
+
242
+ } )
243
  // show more than 3 ads when clicked on a link
244
+ $( '.advads-group-ads-list-show-more' ).click( function () {
245
+ jQuery( this ).hide().parents( '.advads-ad-group-list-ads' ).find( 'li' ).show()
246
+ } )
247
 
248
  /**
249
  * SETTINGS PAGE
250
  */
251
 
252
  // automatically copy the first entered license key into all other empty fields
253
+ $( '.advads-settings-tab-main-form .advads-license-key' ).blur( function () {
254
+ // get number of license fields
 
 
255
 
256
+ var license_key = $( this ).val()
 
 
257
 
258
+ if ( '' === license_key ) {
259
+ return
260
+ }
261
 
262
+ var license_fields = $( '.advads-settings-tab-main-form .advads-license-key' )
263
+ var license_fields_without_value = []
 
 
 
 
264
 
265
+ // count license fields without value
266
+ license_fields.each( function ( i, el ) {
267
+ if ( '' === $( el ).val() ) {
268
+ license_fields_without_value.push( el )
269
+ }
270
+ } )
271
 
272
+ // if there is only one field filled then take its content (probably a license key) and add it into the other fields
273
+ if ( license_fields.length === (license_fields_without_value.length + 1) ) {
274
+ $.each( license_fields_without_value, function ( i, el ) {
275
+ $( el ).val( license_key )
276
+ } )
277
+ }
278
 
279
+ } )
280
 
281
  // activate licenses
282
+ $( '.advads-license-activate' ).click( function () {
283
+
284
+ var button = $( this )
285
+
286
+ if ( ! this.dataset.addon ) { return }
287
+
288
+ advads_disable_license_buttons( true )
289
+
290
+ var query = {
291
+ action: 'advads-activate-license',
292
+ addon: this.dataset.addon,
293
+ pluginname: this.dataset.pluginname,
294
+ optionslug: this.dataset.optionslug,
295
+ license: $( this ).parents( 'td' ).find( '.advads-license-key' ).val(),
296
+ security: $( '#advads-licenses-ajax-referrer' ).val()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
  }
298
+
299
+ // show loader
300
+ $( '<span class="spinner advads-spinner"></span>' ).insertAfter( button )
301
+
302
+ // send and close message
303
+ $.post( ajaxurl, query, function ( r ) {
304
+ // remove spinner
305
+ $( 'span.spinner' ).remove()
306
+ var parent = button.parents( 'td' )
307
+
308
+ if ( r === '1' ) {
309
+ parent.find( '.advads-license-activate-error' ).remove()
310
+ parent.find( '.advads-license-deactivate' ).show()
311
+ button.fadeOut()
312
+ parent.find( '.advads-license-activate-active' ).fadeIn()
313
+ parent.find( 'input' ).prop( 'readonly', 'readonly' )
314
+ advads_disable_license_buttons( false )
315
+ } else if ( r === 'ex' ) {
316
+ var input = parent.find( 'input.advads-license-key' )
317
+ var link = parent.find( 'a.advads-renewal-link' )
318
+ if ( input && link ) {
319
+ var license_key = input.val()
320
+ var href = link.prop( 'href' )
321
+ link.prop( 'href', href.replace( '%LICENSE_KEY%', license_key ) )
322
+ }
323
+ parent.find( '.advads-license-activate-error' ).remove()
324
+ parent.find( '.advads-license-expired-error' ).show()
325
+ advads_disable_license_buttons( false )
326
+ } else {
327
+ parent.find( '.advads-license-activate-error' ).show().text( r )
328
+ advads_disable_license_buttons( false )
329
+ }
330
+ } )
331
+ } )
332
 
333
  // deactivate licenses
334
+ $( '.advads-license-deactivate' ).click( function () {
335
+
336
+ var button = $( this )
337
+
338
+ if ( ! this.dataset.addon ) { return }
339
+
340
+ advads_disable_license_buttons( true )
341
+
342
+ var query = {
343
+ action: 'advads-deactivate-license',
344
+ addon: this.dataset.addon,
345
+ pluginname: this.dataset.pluginname,
346
+ optionslug: this.dataset.optionslug,
347
+ security: $( '#advads-licenses-ajax-referrer' ).val()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
  }
349
+
350
+ // show loader
351
+ $( '<span class="spinner advads-spinner"></span>' ).insertAfter( button )
352
+
353
+ // send and close message
354
+ $.post( ajaxurl, query, function ( r ) {
355
+ // remove spinner
356
+ $( 'span.spinner' ).remove()
357
+
358
+ if ( r === '1' ) {
359
+ button.siblings( '.advads-license-activate-error' ).hide()
360
+ button.siblings( '.advads-license-activate-active' ).hide()
361
+ button.siblings( '.advads-license-activate' ).show()
362
+ button.siblings( 'input' ).prop( 'readonly', false )
363
+ button.fadeOut()
364
+ advads_disable_license_buttons( false )
365
+ } else if ( r === 'ex' ) {
366
+ button.siblings( '.advads-license-activate-error' ).hide()
367
+ button.siblings( '.advads-license-activate-active' ).hide()
368
+ button.siblings( '.advads-license-expired-error' ).show()
369
+ button.siblings( 'input' ).prop( 'readonly', false )
370
+ button.fadeOut()
371
+ advads_disable_license_buttons( false )
372
+ } else {
373
+ console.log( r )
374
+ button.siblings( '.advads-license-activate-error' ).show().html( r )
375
+ button.siblings( '.advads-license-activate-active' ).hide()
376
+ advads_disable_license_buttons( false )
377
+ }
378
+ } )
379
+ } )
380
 
381
  // toggle license buttons – disable or not
382
+ function advads_disable_license_buttons ( disable = true ) {
383
+ var buttons = $( 'button.advads-license-activate, button.advads-license-deactivate' ) // all activation buttons
384
+ // disable all buttons to prevent issues when users try to enable multiple licenses at the same time
385
+ if ( disable ) {
386
+ buttons.attr( 'disabled', 'disabled' )
387
+ } else {
388
+ buttons.removeAttr( 'disabled' )
389
+ }
390
+ }
391
 
392
  /**
393
+ * PLACEMENTS
394
+ */
395
+ // show image tooltips
396
  if ( $.fn.advads_tooltip ) {
397
+ $( '.advads-placements-new-form .advads-placement-type' ).advads_tooltip( {
398
+ items: 'label',
399
+ content: function () {
400
+ return $( this ).parents( '.advads-placement-type' ).find( '.advads-placement-description' ).html()
401
  }
402
+ } )
403
  }
404
+
405
  // keep track of placements that were changed
406
+ $( 'form#advanced-ads-placements-form input, #advanced-ads-placements-form select' ).on( 'change', function () {
407
+ var tr = $( this ).closest( 'tr.advanced-ads-placement-row' )
408
+ if ( tr ) {
409
+ tr.data( 'touched', true )
410
  }
411
+ } )
412
+
413
  // some special form elements overwrite the jquery listeners (or render them unusable in some strange way)
414
  // to counter that and make it more robust in general, we now listen for mouseover events, that will
415
  // only occur, when the settings of a placement are expanded (let's just assume this means editing)
416
+ $( 'form#advanced-ads-placements-form .advads-placements-advanced-options' ).on( 'mouseover', function () {
417
+ var tr = $( this ).closest( 'tr.advanced-ads-placement-row' )
418
+ if ( tr ) {
419
+ tr.data( 'touched', true )
420
  }
421
+ } )
422
+
423
  // on submit remove placements that were untouched
424
+ $( 'form#advanced-ads-placements-form' ).submit( function () {
425
+ var grouprows = jQuery( 'form#advanced-ads-placements-form tr.advanced-ads-placement-row' )
426
+ jQuery( 'form#advanced-ads-placements-form tr.advanced-ads-placement-row' ).each( function ( k, v ) {
427
+ v = jQuery( v )
428
+ if ( ! v.data( 'touched' ) ) {
429
+ v.find( 'input, select' ).each( function ( k2, v2 ) {
430
+ v2 = jQuery( v2 )
431
+ v2.prop( 'disabled', true )
432
+ } )
433
  }
434
+ } )
435
+ } )
436
 
437
  /**
438
+ * Image ad uploader
439
+ */
440
+ $( 'body' ).on( 'click', '.advads_image_upload', function ( e ) {
441
 
442
+ e.preventDefault()
443
 
444
+ var button = $( this )
445
 
446
  // If the media frame already exists, reopen it.
447
  if ( file_frame ) {
448
  // file_frame.uploader.uploader.param( 'post_id', set_to_post_id );
449
+ file_frame.open()
450
+ return
451
  }
452
 
453
  // Create the media frame.
461
  type: 'image'
462
  },
463
  multiple: false // only allow one file to be selected
464
+ } )
465
 
466
  // When an image is selected, run a callback.
467
+ file_frame.on( 'select', function () {
468
 
469
+ var selection = file_frame.state().get( 'selection' )
470
+ selection.each( function ( attachment, index ) {
471
+ attachment = attachment.toJSON()
472
  if ( 0 === index ) {
473
  // place first attachment in field
474
+ $( '#advads-image-id' ).val( attachment.id )
475
+ $( '#advanced-ads-ad-parameters-size input[name="advanced_ad[width]"]' ).val( attachment.width )
476
+ $( '#advanced-ads-ad-parameters-size input[name="advanced_ad[height]"]' ).val( attachment.height )
477
  // update image preview
478
+ var new_image = '<img width="' + attachment.width + '" height="' + attachment.height +
479
+ '" title="' + attachment.title + '" alt="' + attachment.alt + '" src="' + attachment.url + '"/>'
480
+ $( '#advads-image-preview' ).html( new_image )
481
+ $( '#advads-image-edit-link' ).attr( 'href', attachment.editLink )
482
  // process "reserve this space" checkbox
483
+ $( '#advanced-ads-ad-parameters-size input[type=number]:first' ).change()
484
  }
485
+ } )
486
+ } )
487
 
488
  // Finally, open the modal
489
+ file_frame.open()
490
+ } )
491
 
492
  // WP 3.5+ uploader
493
+ var file_frame
494
+ window.formfield = ''
495
 
496
  // adblocker related code
497
+ $( '#advanced-ads-use-adblocker' ).change( function () {
498
+ advads_toggle_box( this, '#advads-adblocker-wrapper' )
499
+ } )
500
 
501
  // processing of the rebuild asset form and the FTP/SSH credentials form
502
+ var $advads_adblocker_wrapper = $( '#advads-adblocker-wrapper' )
503
+ $advads_adblocker_wrapper.find( 'input[type="submit"]' ).prop( 'disabled', false )
504
+ $advads_adblocker_wrapper.on( 'submit', 'form', function ( event ) {
505
+ event.preventDefault()
506
+ var $form = $( '#advanced-ads-rebuild-assets-form' )
507
+ $form.prev( '.error' ).remove()
508
+ $form.find( 'input[type="submit"]' ).prop( 'disabled', true ).after( '<span class="spinner advads-spinner"></span>' )
509
 
510
  var args = {
511
  data: {
512
  action: 'advads-adblock-rebuild-assets',
513
  nonce: advadsglobal.ajax_nonce,
514
  },
515
+ done: function ( data, textStatus, jqXHR ) {
516
+ var $advads_adblocker_wrapper = $( '#advads-adblocker-wrapper' )
517
+ $advads_adblocker_wrapper.html( data )
518
  },
519
+ fail: function ( jqXHR, textStatus, errorThrown ) {
520
+ $form.before( '<div class="error"><p>' + textStatus + ': ' + errorThrown + '</p></div>' )
521
+ $form.find( 'input[type="submit"]' ).prop( 'disabled', false ).next( '.advads-spinner' ).remove()
522
  },
523
+ on_modal_close: function () {
524
+ var $form = $( '#advanced-ads-rebuild-assets-form' )
525
+ $form.find( 'input[type="submit"]' ).prop( 'disabled', false ).next( '.advads-spinner' ).remove()
526
  }
527
  }
528
 
529
+ $.each( $form.serializeArray(), function ( i, o ) {
530
+ args.data[ o.name ] = o.value
531
+ } )
532
 
533
+ advanced_ads_admin.filesystem.ajax( args )
534
+ } )
535
 
536
  // process "reserve this space" checkbox
537
+ $( '#advanced-ads-ad-parameters' ).on( 'change', '#advanced-ads-ad-parameters-size input[type=number]', function () {
538
+ if ( $( '#advanced-ads-ad-parameters-size input[type=number]' ).filter( function () {
539
+ return parseInt( this.value, 10 ) > 0
540
+ } ).length === 2 ) {
541
+ $( '#advads-wrapper-add-sizes' ).prop( 'disabled', false )
542
  } else {
543
+ $( '#advads-wrapper-add-sizes' ).prop( 'disabled', true ).prop( 'checked', false )
544
  }
545
+ } )
546
  // process "reserve this space" checkbox - ad type changed
547
+ $( '#advanced-ads-ad-parameters' ).on( 'paramloaded', function () {
548
+ $( '#advanced-ads-ad-parameters-size input[type=number]:first' ).change()
549
+ } )
550
  // process "reserve this space" checkbox - on load
551
+ $( '#advanced-ads-ad-parameters-size input[type=number]:first' ).change()
552
+
553
  // move meta box markup to hndle headline
554
+ $( '.advads-hndlelinks' ).each( function () {
555
+ $( this ).removeClass( 'hidden' )
556
+ $( this ).appendTo( $( this ).parent( '.inside' ).siblings( 'h2.hndle' ) )
557
+ } )
558
  // open tutorial link when clicked on it
559
+ $( '.advads-video-link' ).click( function ( el ) {
560
+ el.preventDefault()
561
+ var video_container = $( this ).parents( 'h2' ).siblings( '.inside' ).find( '.advads-video-link-container' )
562
+ video_container.html( video_container.data( 'videolink' ) )
563
+ } )
564
  // open inline tutorial link when clicked on it
565
+ $( '.advads-video-link-inline' ).click( function ( el ) {
566
+ el.preventDefault()
567
+ var video_container = $( this ).parents( 'div' ).siblings( '.advads-video-link-container' )
568
+ video_container.html( video_container.data( 'videolink' ) )
569
+ } )
570
  // switch import type
571
+ jQuery( '.advads_import_type' ).change( function () {
572
  if ( this.value === 'xml_content' ) {
573
+ jQuery( '#advads_xml_file' ).hide()
574
+ jQuery( '#advads_xml_content' ).show()
575
  } else {
576
+ jQuery( '#advads_xml_file' ).show()
577
+ jQuery( '#advads_xml_content' ).hide()
578
  }
579
+ } )
580
 
581
  // Find Adsense Auto Ads inside ad content.
582
+ var ad_content = jQuery( 'textarea[name=advanced_ad\\[content\\]]' ).html()
583
  if ( ad_content && ad_content.indexOf( 'enable_page_level_ads' ) !== -1 ) {
584
+ advads_show_adsense_auto_ads_warning()
585
  }
586
 
 
587
  //advads_ads_txt_check_third_party();
588
+ advads_ads_txt_find_issues()
 
 
 
 
 
589
 
590
+ jQuery( '.advanced-ads-adsense-dashboard' ).each( function ( key, elm ) {
591
+ Advanced_Ads_Adsense_Helper.process_dashboard( elm )
592
+ } )
593
+ } )
594
 
595
  /**
596
+ * Store the action hash in settings form action
597
  * thanks for Yoast SEO for this idea
598
  */
599
+ function advads_set_tab_hashes () {
600
  // iterate through forms
601
+ jQuery( '#advads-tabs' ).find( 'a' ).each( function () {
602
+ var id = jQuery( this ).attr( 'id' ).replace( '-tab', '' )
603
+ var optiontab = jQuery( '#' + id )
604
 
605
+ var form = optiontab.children( '.advads-settings-tab-main-form' )
606
  if ( form.length ) {
607
+ var currentUrl = form.attr( 'action' ).split( '#' )[ 0 ]
608
+ form.attr( 'action', currentUrl + jQuery( this ).attr( 'href' ) )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
609
  }
610
+ } )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
611
  }
612
 
613
  /**
615
  *
616
  * @param selector jQuery selector
617
  */
618
+ function advads_scroll_to_element ( selector ) {
619
+ var height_of_admin_bar = jQuery( '#wpadminbar' ).height()
620
+ jQuery( 'html, body' ).animate( {
621
+ scrollTop: jQuery( selector ).offset().top - height_of_admin_bar
622
+ }, 1000 )
623
  }
624
 
625
  /**
627
  *
628
  * @param selector jquery selector
629
  */
630
+ function advads_toggle ( selector ) {
631
+ jQuery( selector ).slideToggle()
632
  }
633
 
634
  /**
636
  *
637
  * @param selector jquery selector
638
  */
639
+ function advads_toggle_box ( e, selector ) {
640
+ if ( jQuery( e ).is( ':checked' ) ) {
641
+ jQuery( selector ).slideDown()
642
  } else {
643
+ jQuery( selector ).slideUp()
644
  }
645
  }
646
 
650
  *
651
  * @param selector jquery selector
652
  */
653
+ function advads_toggle_box_enable ( e, selector ) {
654
+ if ( jQuery( e ).is( ':checked' ) ) {
655
+ jQuery( selector ).find( 'input' ).removeAttr( 'disabled', '' )
656
  } else {
657
+ jQuery( selector ).find( 'input' ).attr( 'disabled', 'disabled' )
658
  }
659
  }
660
 
661
  /**
662
  * validate placement form on submit
663
  */
664
+ function advads_validate_placement_form () {
665
  // check if placement type was selected
666
+ if ( ! jQuery( '.advads-placement-type input:checked' ).length ) {
667
+ jQuery( '.advads-placement-type-error' ).show()
668
+ return false
669
  } else {
670
+ jQuery( '.advads-placement-type-error' ).hide()
671
  }
672
  // check if placement name was entered
673
+ if ( jQuery( '.advads-new-placement-name' ).val() == '' ) {
674
+ jQuery( '.advads-placement-name-error' ).show()
675
+ return false
676
  } else {
677
+ jQuery( '.advads-placement-name-error' ).hide()
678
  }
679
+ return true
680
  }
681
 
682
  /**
683
  * replace textarea with TinyMCE editor for Rich Content ad type
684
  */
685
+ function advads_maybe_textarea_to_tinymce ( ad_type ) {
686
  var textarea = jQuery( '#advads-ad-content-plain' ),
687
+ textarea_html = textarea.val(),
688
+ tinymce_id = 'advanced-ads-tinymce',
689
+ tinymce_id_ws = jQuery( '#' + tinymce_id ),
690
+ tinymce_wrapper_div = jQuery( '#advanced-ads-tinymce-wrapper' )
691
 
692
  if ( ad_type !== 'content' ) {
693
+ tinymce_id_ws.prop( 'name', tinymce_id )
694
+ tinymce_wrapper_div.hide()
695
+ return false
696
  }
697
 
698
  if ( typeof tinyMCE === 'object' && tinyMCE.get( tinymce_id ) !== null ) {
699
  // visual mode
700
  if ( textarea_html ) {
701
  // see BeforeSetContent in the wp-includes\js\tinymce\plugins\wordpress\plugin.js
702
+ var wp = window.wp,
703
+ hasWpautop = (wp && wp.editor && wp.editor.autop && tinyMCE.get( tinymce_id ).getParam( 'wpautop', true ))
704
  if ( hasWpautop ) {
705
+ textarea_html = wp.editor.autop( textarea_html )
706
  }
707
+ tinyMCE.get( tinymce_id ).setContent( textarea_html )
708
  }
709
+ textarea.remove()
710
+ tinymce_id_ws.prop( 'name', textarea.prop( 'name' ) )
711
+ tinymce_wrapper_div.show()
712
  } else if ( tinymce_id_ws.length ) {
713
  // text mode
714
+ tinymce_id_ws.val( textarea_html )
715
+ textarea.remove()
716
+ tinymce_id_ws.prop( 'name', textarea.prop( 'name' ) )
717
+ tinymce_wrapper_div.show()
718
  }
719
  }
720
 
721
  /**
722
  * Show a message depending on whether Adsense Auto ads are enabled.
723
  */
724
+ function advads_show_adsense_auto_ads_warning () {
725
+ $msg = jQuery( '.advads-auto-ad-in-ad-content' ).show()
726
+ $msg.on( 'click', 'button', function () {
727
+ $msg.hide()
728
  jQuery.ajax( {
729
  type: 'POST',
730
  url: ajaxurl,
732
  action: 'advads-adsense-enable-pla',
733
  nonce: advadsglobal.ajax_nonce
734
  },
735
+ } ).done( function ( data ) {
736
+ $msg.show().html( advadstxt.page_level_ads_enabled )
737
+ } ).fail( function ( jqXHR, textStatus ) {
738
+ $msg.show()
739
+ } )
740
+ } )
741
  }
742
 
743
  /**
744
  * Check if a third-party ads.txt file exists.
745
  */
746
+ function advads_ads_txt_find_issues () {
747
+ var $wrapper = jQuery( '#advads-ads-txt-notice-wrapper' )
748
+ var $refresh = jQuery( '#advads-ads-txt-notice-refresh' )
749
+ var $actions = jQuery( '.advads-ads-txt-action' )
750
+
751
+ /**
752
+ * Toggle the visibility of the spinner.
753
+ *
754
+ * @param {Bool} state True to show, False to hide.
755
+ */
756
+ function set_loading ( state ) {
757
+ $actions.toggle( ! state )
758
+ if ( state ) {
759
+ $wrapper.html( '<span class="spinner advads-spinner"></span>' )
760
+ }
761
+ }
762
 
763
  if ( ! $wrapper.length ) {
764
+ return
765
  }
766
 
767
  if ( ! $wrapper.find( 'ul' ).length ) {
768
+ // There are no notices. Fetch them using ajax.
769
+ load( 'get_notices' )
770
  }
771
 
772
+ $refresh.click( function () {
773
+ load( 'get_notices' )
774
+ } )
775
 
776
+ function done ( response ) {
777
+ $wrapper.html( response.notices )
778
+ set_loading( false )
779
+ }
780
+
781
+ function fail ( jqXHR ) {
782
+ $wrapper.html( '<p class="advads-error-message">'
783
+ + jQuery( '#advads-ads-txt-notice-error' ).text().replace( '%s', parseInt( jqXHR.status, 10 ) ),
784
+ +'</p>'
785
+ )
786
+ set_loading( false )
787
+ }
788
+
789
+ function load ( type ) {
790
+ set_loading( true )
791
 
792
  jQuery.ajax( {
793
  type: 'POST',
794
  url: ajaxurl,
 
795
  data: {
796
  action: 'advads-ads-txt',
797
+ nonce: advadsglobal.ajax_nonce,
798
+ type,
799
  },
800
+ } ).done( done ).fail( fail )
 
 
 
 
 
 
 
 
 
801
  }
802
 
803
+ jQuery( document ).on( 'click', '#advads-ads-txt-remove-real', function ( event ) {
804
+ event.preventDefault()
805
+
806
+ var args = {
807
+ data: {
808
+ action: 'advads-ads-txt',
809
+ nonce: advadsglobal.ajax_nonce,
810
+ type: 'remove_real_file',
811
+ },
812
+ done: function ( response ) {
813
+ if ( response.additional_content ) {
814
+ jQuery( '#advads-ads-txt-additional-content' ).val( response.additional_content )
815
+ }
816
+ done( response )
817
+ },
818
+ fail: fail,
819
+ before_send: function () {
820
+ set_loading( true )
821
+ },
822
+ }
823
+
824
+ advanced_ads_admin.filesystem.ajax( args )
825
+ } )
826
+
827
+ jQuery( document ).on( 'click', '#advads-ads-txt-create-real', function ( event ) {
828
+ event.preventDefault()
829
+
830
+ var args = {
831
+ data: {
832
+ action: 'advads-ads-txt',
833
+ nonce: advadsglobal.ajax_nonce,
834
+ type: 'create_real_file',
835
+ },
836
+ done: done,
837
+ fail: fail,
838
+ before_send: function () {
839
+ set_loading( true )
840
+ },
841
+ }
842
+
843
+ advanced_ads_admin.filesystem.ajax( args )
844
+ } )
845
+
846
  }
847
 
848
+ jQuery.fn.advads_tooltip = function () {
849
+ return _advads_apply_jqueryui_widget.call( this, 'tooltip', [ 'tooltip' ], arguments )
850
+ }
851
 
852
+ jQuery.fn.advads_button = function () {
853
+ return _advads_apply_jqueryui_widget.call( this, 'button', [ 'button' ], arguments )
854
+ }
855
 
856
+ jQuery.fn.advads_buttonset = function () {
857
+ return _advads_apply_jqueryui_widget.call( this, 'buttonset', [ 'button', 'buttonset' ], arguments )
858
+ }
859
 
860
  /**
861
  * Apply jQueryUI widget.
864
  * @param arr revoke Names of Twitter Bootstrap widgets to revoke.
865
  * @param arguments_ mixed Widget arguments.
866
  */
867
+ function _advads_apply_jqueryui_widget ( name, revoke, args ) {
868
+ var can_apply = true
869
 
870
+ jQuery.each( revoke, function ( _index, _name ) {
871
  if ( jQuery.fn[ _name ].noConflict ) {
872
  // Revoke Twitter Bootstrap, assign jQuery UI.
873
+ jQuery.fn[ _name ].noConflict()
874
  }
875
+ can_apply = _advads_can_apply_jqueryui_widget( _name )
876
+ } )
877
 
878
  if ( ! can_apply ) {
879
  // The culprit is not Bootstrap, we haven't been able to assign jQuery UI.
880
+ jQuery( '.advads-jqueryui-error' ).show()
881
+ return
882
  }
883
 
884
+ var r = this[ name ].apply( this, args )
885
+ return r
886
  }
887
 
888
  /**
891
  * @param name Widget name.
892
  * @return bool
893
  */
894
+ var _advads_can_apply_jqueryui_widget = (function ( name ) {
895
+ var r = {}
896
  return function ( name ) {
897
  if ( ! r.hasOwnProperty( name ) ) {
898
+ var needle = 'prior to initialization;' // A string from jquery-ui source code.
899
+ r[ name ] = jQuery.fn[ name ].toString().indexOf( needle ) !== -1
900
  }
901
+ return r[ name ]
902
+ }
903
+ })()
904
 
905
+ window.advanced_ads_admin = window.advanced_ads_admin || {}
906
  advanced_ads_admin.filesystem = {
907
  /**
908
  * Holds the current job while the user writes data in the 'Connection Information' modal.
914
  /**
915
  * Toggle the 'Connection Information' modal.
916
  */
917
+ _requestForCredentialsModalToggle: function () {
918
+ this.$filesystemModal.toggle()
919
+ jQuery( 'body' ).toggleClass( 'modal-open' )
920
  },
921
 
922
+ _init: function () {
923
+ this._init = function () {}
924
+ var self = this
925
 
926
+ self.$filesystemModal = jQuery( '#advanced-ads-rfc-dialog' )
927
  /**
928
  * Sends saved job.
929
  */
930
+ self.$filesystemModal.on( 'submit', 'form', function ( event ) {
931
+ event.preventDefault()
932
 
933
+ self.ajax( self._locked_job, true )
934
  self._requestForCredentialsModalToggle()
935
+ } )
936
 
937
  /**
938
  * Closes the request credentials modal when clicking the 'Cancel' button.
939
  */
940
+ self.$filesystemModal.on( 'click', '[data-js-action="close"]', function () {
941
  if ( jQuery.isPlainObject( self._locked_job ) && self._locked_job.on_modal_close ) {
942
+ self._locked_job.on_modal_close()
943
  }
944
 
945
+ self._locked_job = false
946
+ self._requestForCredentialsModalToggle()
947
+ } )
948
  },
949
 
950
  /**
953
  * @param {object} args
954
  * @param {bool} skip_modal
955
  */
956
+ ajax: function ( args, skip_modal ) {
957
+ this._init()
958
 
959
  if ( ! skip_modal && this.$filesystemModal.length > 0 ) {
960
+ this._requestForCredentialsModalToggle()
961
+ this.$filesystemModal.find( 'input:enabled:first' ).focus()
962
 
963
  // Do not send request.
964
+ this._locked_job = args
965
+ return
966
  }
967
 
968
  var options = {
969
  method: 'POST',
970
  url: window.ajaxurl,
971
  data: {
972
+ username: jQuery( '#username' ).val(),
973
+ password: jQuery( '#password' ).val(),
974
+ hostname: jQuery( '#hostname' ).val(),
975
  connection_type: jQuery( 'input[name="connection_type"]:checked' ).val(),
976
+ public_key: jQuery( '#public_key' ).val(),
977
+ private_key: jQuery( '#private_key' ).val(),
978
+ _fs_nonce: jQuery( '#_fs_nonce' ).val()
979
 
980
  }
981
+ }
982
 
983
+ if ( args.before_send ) {
984
+ args.before_send()
985
+ }
986
+
987
+ options.data = jQuery.extend( options.data, args.data )
988
+ var request = jQuery.ajax( options )
989
 
990
  if ( args.done ) {
991
+ request.done( args.done )
992
  }
993
 
994
  if ( args.fail ) {
995
+ request.fail( args.fail )
996
  }
997
  }
998
  }
999
 
1000
  window.Advanced_Ads_Admin = window.Advanced_Ads_Admin || {
1001
+ init_ad_source_editor: function () {
1002
+
1003
  },
1004
+ get_ad_source_editor_text: function () {
1005
+ var text = undefined
1006
+ if ( Advanced_Ads_Admin.editor ) {
1007
+ if ( Advanced_Ads_Admin.editor.codemirror ) {
1008
+ text = Advanced_Ads_Admin.editor.codemirror.getValue()
1009
+ }
1010
+ }
1011
+ if ( ! text ) {
1012
+ var ta = jQuery( '#advads-ad-content-plain' )
1013
+ if ( ta ) text = ta.val()
1014
+ }
1015
+ return text
1016
  },
1017
+ set_ad_source_editor_text: function ( text ) {
1018
+ if ( Advanced_Ads_Admin.editor && Advanced_Ads_Admin.editor.codemirror ) {
1019
+ Advanced_Ads_Admin.editor.codemirror.setValue( text )
1020
+ } else {
1021
+ jQuery( '#advads-ad-content-plain' ).val( text )
1022
+ }
 
1023
  },
1024
+ check_ad_source: function () {
1025
+ var text = Advanced_Ads_Admin.get_ad_source_editor_text()
1026
+ var enabled_php = jQuery( '#advads-parameters-php' ).prop( 'checked' )
1027
+ var enabled_sc = jQuery( '#advads-parameters-shortcodes' ).prop( 'checked' )
1028
+ if ( enabled_php && ! /\<\?php/.test( text ) ) {
1029
+ jQuery( '#advads-parameters-php-warning' ).show()
1030
+ } else {
1031
+ jQuery( '#advads-parameters-php-warning' ).hide()
1032
+ }
1033
+ if ( enabled_sc && ! /\[[^\]]+\]/.test( text ) ) {
1034
+ jQuery( '#advads-parameters-shortcodes-warning' ).show()
1035
+ } else {
1036
+ jQuery( '#advads-parameters-shortcodes-warning' ).hide()
1037
+ }
1038
+ },
1039
+ toggle_placements_visibility: function ( elm ) {
1040
+ var advadsplacementformrow = jQuery( elm ).next( '.advads-placements-advanced-options' )
1041
+ if ( advadsplacementformrow.is( ':visible' ) ) {
1042
+ advadsplacementformrow.hide()
 
 
1043
  // clear last edited id
1044
+ jQuery( '#advads-last-edited-placement' ).val( '' )
1045
  } else {
1046
+ var placement_id = jQuery( elm ).parents( '.advads-placements-table-options' ).find( '.advads-placement-slug' ).val()
1047
+ advadsplacementformrow.show()
1048
+ jQuery( '#advads-last-edited-placement' ).val( placement_id )
1049
  // some special elements (color picker) may not be detected with jquery
1050
+ var tr = jQuery( elm ).closest( 'tr.advanced-ads-placement-row' )
1051
+ if ( tr ) {
1052
+ tr.data( 'touched', true )
1053
  }
1054
  }
1055
+ }
1056
+ }
 
1057
 
1058
+ if ( ! window.AdvancedAdsAdmin ) window.AdvancedAdsAdmin = {}
1059
+ if ( ! window.AdvancedAdsAdmin.AdImporter ) window.AdvancedAdsAdmin.AdImporter = {
1060
  /**
1061
  * will highlight the currently selected ads in the list
1062
  * @param hideInactive when true will hide inactive ad units
1063
  * @returns the selector of the selected row or false if no row was selected.
1064
  */
1065
+ highlightSelectedRowInExternalAdsList: function ( hideInactive ) {
1066
+ if ( typeof (hideInactive) == 'undefined' ) hideInactive = AdvancedAdsAdmin.AdImporter.adNetwork.hideIdle
1067
+ const tbody = jQuery( '#mapi-table-wrap tbody' )
1068
+ const btn = jQuery( '#mapi-toggle-idle' )
1069
 
1070
  // count the ad units to determine if there's a need for the overflow class (scrolling)
1071
  const nbUnits = hideInactive
1072
  ? jQuery( '#mapi-table-wrap tbody tr[data-active=1]' ).length
1073
+ : jQuery( '#mapi-table-wrap tbody tr' ).length
1074
+ if ( nbUnits > 8 ) jQuery( '#mapi-table-wrap' ).addClass( 'overflow' )
1075
+ else jQuery( '#mapi-table-wrap' ).removeClass( 'overflow' )
1076
 
1077
  // hide inactive ads, but always show the selected one (if any)
1078
+ if ( hideInactive ) {
1079
+ btn.removeClass( 'dashicons-hidden' )
1080
+ btn.addClass( 'dashicons-visibility' )
1081
+ btn.attr( 'title', advadstxt.show_inactive_ads )
1082
+ tbody.find( 'tr[data-slotid]' ).each( function ( k, v ) {
1083
+ v = jQuery( v )
1084
+ if ( v.data( 'active' ) ) v.show()
1085
+ else v.hide()
1086
+ } )
1087
+ } else {
1088
+ btn.removeClass( 'dashicons-visibility' )
1089
+ btn.addClass( 'dashicons-hidden' )
1090
+ btn.attr( 'title', advadstxt.hide_inactive_ads )
1091
+ tbody.find( 'tr[data-slotid]' ).show()
 
1092
  }
1093
 
1094
+ const selectedRow = AdvancedAdsAdmin.AdImporter.getSelectedRow()
1095
+ tbody.find( 'tr' ).removeClass( 'selected' )
1096
+ if ( selectedRow ) {
1097
  //make sure, it is visible before applying the zebra stripes
1098
+ selectedRow.show()
1099
  }
1100
 
1101
  // make the table's rows striped.
1102
+ const visible = tbody.find( 'tr:visible' )
1103
+ visible.filter( ':odd' ).css( 'background-color', '#FFFFFF' )
1104
+ visible.filter( ':even' ).css( 'background-color', '#F9F9F9' )
1105
 
1106
  // highlight the selected row
1107
+ if ( selectedRow ) {
1108
  // highlight the selected row
1109
+ selectedRow.css( 'background-color', '' )
1110
+ selectedRow.addClass( 'selected' )
1111
  }
1112
+ return selectedRow || false
1113
  },
1114
+ getSelectedRow () {
1115
+ const selectedId = AdvancedAdsAdmin.AdImporter.adNetwork.getSelectedId()
1116
+ const tbody = jQuery( '#mapi-table-wrap tbody' )
1117
 
1118
+ if ( selectedId ) {
1119
+ const selectedRows = tbody.find( 'tr[data-slotid="' + selectedId + '"]' )
1120
  if ( selectedRows.length ) {
1121
+ return selectedRows
1122
  }
1123
  }
1124
+ return null
1125
  },
1126
+ openExternalAdsList: function () {
1127
+ const network = AdvancedAdsAdmin.AdImporter.adNetwork
1128
+ network.openSelector()
1129
 
1130
+ jQuery( '#mapi-insert-code' ).css( 'display', 'inline' )
1131
+ jQuery( '#mapi-open-selector' ).css( 'display', 'none' )
1132
+ jQuery( '#mapi-close-selector-link' ).css( 'display', 'inline' )
1133
+ jQuery( '.advads-adsense-code' ).css( 'display', 'none' )
1134
+ jQuery( '#remote-ad-unsupported-ad-type' ).css( 'display', 'none' )
1135
 
1136
+ AdvancedAdsAdmin.AdImporter.highlightSelectedRowInExternalAdsList( network.hideIdle )
1137
 
1138
+ var SNT = network.getCustomInputs()
1139
+ SNT.css( 'display', 'none' )
1140
 
1141
+ jQuery( '#mapi-wrap' ).css( 'display', 'block' )
1142
 
1143
+ if ( ! network.fetchedExternalAds ) {
1144
+ network.fetchedExternalAds = true
1145
+ const nbUnits = jQuery( '#mapi-table-wrap tbody tr[data-slotid]' ).length
1146
+ if ( nbUnits == 0 ) {
1147
  //usually we start with a preloaded list.
1148
  //only reload, when the count is zero (true for new accounts).
1149
+ AdvancedAdsAdmin.AdImporter.refreshAds()
1150
  }
1151
  }
1152
+ AdvancedAdsAdmin.AdImporter.resizeAdListHeader()
1153
+ },
1154
  /**
1155
  * will be called every time the ad type is changed.
1156
  * required for onBlur detection
1157
  */
1158
+ onChangedAdType: function () {
1159
+ if ( AdvancedAdsAdmin.AdImporter.adNetwork ) {
1160
+ AdvancedAdsAdmin.AdImporter.adNetwork.onBlur()
1161
+ AdvancedAdsAdmin.AdImporter.adNetwork = null
1162
  }
1163
  },
1164
+ setup: function ( adNetwork ) {
1165
+ AdvancedAdsAdmin.AdImporter.adNetwork = adNetwork
1166
+ adNetwork.onSelected()
1167
+ if ( AdvancedAdsAdmin.AdImporter.isSetup ) {
1168
+ AdvancedAdsAdmin.AdImporter.highlightSelectedRowInExternalAdsList()
1169
+ return
1170
  }
1171
+ AdvancedAdsAdmin.AdImporter.isSetup = true
1172
 
1173
+ jQuery( document ).on( 'click', '.prevent-default', function ( ev ) { ev.preventDefault() } )
1174
 
1175
  // handle clicks for the "insert new ... code" anchor
1176
+ jQuery( document ).on( 'click', '#mapi-insert-code', function ( e ) {
1177
+ e.preventDefault()
1178
+ jQuery( '.advads-adsense-code' ).show()
1179
+ jQuery( '#mapi-open-selector' ).css( 'display', 'inline' )
1180
+ jQuery( '#mapi-close-selector-link' ).css( 'display', 'inline' )
1181
+ jQuery( '#mapi-wrap' ).css( 'display', 'none' )
1182
+ var SNT = AdvancedAdsAdmin.AdImporter.adNetwork.getCustomInputs()
1183
+ SNT.css( 'display', 'none' )
1184
+ jQuery( this ).hide()
1185
+ } )
1186
 
1187
  // handle clicks for the "get ad code from your linked account" anchor
1188
+ jQuery( document ).on( 'click', '#mapi-open-selector a', function () {
1189
+ AdvancedAdsAdmin.AdImporter.openExternalAdsList()
1190
+ } )
1191
 
1192
  // the close button of the ad unit list
1193
+ jQuery( document ).on( 'click', '#mapi-close-selector,#mapi-close-selector-link', function () {
1194
+ AdvancedAdsAdmin.AdImporter.manualSetup()
1195
+ } )
1196
 
1197
  //the individual rows of the ad units may contain elements with the mapiaction class
1198
+ jQuery( document ).on( 'click', '.mapiaction', function ( ev ) {
1199
+ var action = jQuery( this ).attr( 'data-mapiaction' )
1200
  switch ( action ) {
1201
  case 'updateList':
1202
+ AdvancedAdsAdmin.AdImporter.refreshAds()
1203
+ break
1204
  case 'getCode':
1205
  if ( jQuery( this ).hasClass( 'disabled' ) ) {
1206
+ break
1207
  }
1208
+ var slotId = jQuery( this ).attr( 'data-slotid' )
1209
+ AdvancedAdsAdmin.AdImporter.adNetwork.selectAdFromList( slotId )
1210
+ break
1211
  case 'updateCode':
1212
+ var slotId = jQuery( this ).attr( 'data-slotid' )
1213
+ AdvancedAdsAdmin.AdImporter.adNetwork.updateAdFromList( slotId )
1214
+ break
1215
  case 'toggleidle':
1216
+ AdvancedAdsAdmin.AdImporter.adNetwork.hideIdle = ! AdvancedAdsAdmin.AdImporter.adNetwork.hideIdle
1217
+ AdvancedAdsAdmin.AdImporter.toggleIdleAds( AdvancedAdsAdmin.AdImporter.adNetwork.hideIdle )
1218
+ break
1219
  default:
1220
  }
1221
+ } )
1222
 
1223
+ AdvancedAdsAdmin.AdImporter.adNetwork.onDomReady()
1224
  // AdvancedAdsAdmin.AdImporter.openExternalAdsList();
1225
 
1226
  },
1229
  * call this method to display the manual setup (if available for the current ad network)
1230
  * this method is an equivalent to the close ad list button.
1231
  */
1232
+ manualSetup () {
1233
+ jQuery( '#mapi-open-selector,.advads-adsense-show-code' ).css( 'display', 'inline' )
1234
+ jQuery( '#mapi-insert-code' ).css( 'display', 'inline' )
1235
+ jQuery( '#mapi-close-selector-link' ).css( 'display', 'none' )
1236
+ jQuery( '#mapi-wrap' ).css( 'display', 'none' )
1237
+
1238
+ var SNT = AdvancedAdsAdmin.AdImporter.adNetwork.getCustomInputs()
1239
+ SNT.css( 'display', 'block' )
1240
+ AdvancedAdsAdmin.AdImporter.adNetwork.onManualSetup()
1241
  },
1242
 
1243
+ setRemoteErrorMessage ( msg ) {
1244
+ if ( ! msg ) jQuery( '#remote-ad-code-msg' ).empty()
1245
+ else jQuery( '#remote-ad-code-msg' ).html( msg )
1246
  },
1247
 
1248
  // another legacy method
1249
+ resizeAdListHeader: function () {
1250
+ var th = jQuery( '#mapi-list-header span' )
1251
+ var tb = jQuery( '#mapi-table-wrap tbody tr:visible' )
1252
+ var w = []
1253
 
1254
+ tb.first().find( 'td' ).each( function () {
1255
+ w.push( jQuery( this ).width() )
1256
+ } )
1257
 
1258
+ th.each( function ( i ) {
1259
  if ( i != w.length - 1 ) {
1260
+ jQuery( this ).width( w[ i ] )
1261
  }
1262
+ } )
1263
  },
1264
 
 
 
1265
  /**
1266
  * legacy method
1267
  */
1268
+ closeAdSelector: function () {
1269
  // close the ad unit selector
1270
+ setTimeout( function () {
1271
+ jQuery( '#mapi-wrap' ).animate(
1272
  { height: 0, },
1273
  360,
1274
+ function () {
1275
+ jQuery( '#mapi-open-selector,.advads-adsense-show-code' ).css( 'display', 'inline' )
1276
+ jQuery( '#mapi-close-selector-link' ).css( 'display', 'none' )
1277
+ jQuery( '#mapi-wrap' ).css( {
1278
  display: 'none',
1279
  height: 'auto',
1280
+ } )
1281
+ const SNT = AdvancedAdsAdmin.AdImporter.adNetwork.getCustomInputs()
1282
+ SNT.css( 'display', 'block' )
1283
  }
1284
+ )
1285
+ }, 80 )
1286
 
1287
  },
1288
 
1290
  * legacy method
1291
  * updates the UI, (call if the selected unit is supported)
1292
  */
1293
+ unitIsNotSupported: function ( slotID ) {
1294
+ jQuery( '#remote-ad-unsupported-ad-type' ).css( 'display', 'block' )
1295
+ AdsenseMAPI.unsupportedUnits[ slotID ] = 1
1296
+ jQuery( 'i[data-mapiaction="getCode"][data-slotid="' + slotID + '"]' ).addClass( 'disabled' )
1297
+ jQuery( 'tr[data-slotid="' + slotID + '"] .unitcode > span' ).addClass( 'unsupported' )
1298
  if ( ! jQuery( 'tr[data-slotid="' + slotID + '"] .unittype a' ).length ) {
1299
+ var td = jQuery( 'tr[data-slotid="' + slotID + '"] .unittype' )
1300
+ var content = td.text()
1301
+ td.html( '<a target="_blank" href="' + AdsenseMAPI.unsupportedLink + '" data-type="' + content + '">' + AdsenseMAPI.unsupportedText + '</a>' )
1302
  }
1303
  if ( ! jQuery( 'tr[data-slotid="' + slotID + '"] .unitsize a' ).length ) {
1304
+ var td = jQuery( 'tr[data-slotid="' + slotID + '"] .unitsize' )
1305
+ var content = td.text()
1306
+ td.html( '<a target="_blank" href="' + AdsenseMAPI.unsupportedLink + '" data-size="' + content + '">' + AdsenseMAPI.unsupportedText + '</a>' )
1307
  }
1308
 
1309
  },
1312
  * legacy method
1313
  * updates the UI, (call if the selected unit is NOT supported)
1314
  */
1315
+ unitIsSupported: function ( slotID ) {
1316
+ jQuery( '#remote-ad-unsupported-ad-type' ).css( 'display', 'none' )
1317
+ if ( 'undefined' != typeof AdsenseMAPI.unsupportedUnits[ slotID ] ) {
1318
+ delete AdsenseMAPI.unsupportedUnits[ slotID ]
1319
  }
1320
+ jQuery( 'i[data-mapiaction="getCode"][data-slotid="' + slotID + '"]' ).removeClass( 'disabled' )
1321
+ jQuery( 'tr[data-slotid="' + slotID + '"] .unitcode > span' ).removeClass( 'unsupported' )
1322
  if ( jQuery( 'tr[data-slotid="' + slotID + '"] .unittype a' ).length ) {
1323
+ var td = jQuery( 'tr[data-slotid="' + slotID + '"] .unittype' )
1324
+ var content = jQuery( 'tr[data-slotid="' + slotID + '"] .unittype a' ).attr( 'data-type' )
1325
+ td.text( content )
1326
  }
1327
  if ( jQuery( 'tr[data-slotid="' + slotID + '"] .unitsize a' ).length ) {
1328
+ var td = jQuery( 'tr[data-slotid="' + slotID + '"] .unitsize' )
1329
+ var content = jQuery( 'tr[data-slotid="' + slotID + '"] .unitsize a' ).attr( 'data-size' )
1330
+ td.text( content )
1331
  }
1332
  },
1333
 
1335
  * legacy method
1336
  * updates the UI, (call if the selected unit is NOT supported)
1337
  */
1338
+ emptyMapiSelector: function ( msg ) {
1339
+ const nag = '<div class="notice notice-error" style="font-size:1.1em;padding:.6em 1em;font-weight:bold;">' + msg + '</div>'
1340
+ jQuery( '#mapi-loading-overlay' ).css( 'display', 'none' )
1341
+ jQuery( '#mapi-wrap' ).html( jQuery( nag ) )
1342
  },
1343
 
1344
  /**
1345
  * legacy method
1346
  */
1347
+ refreshAds: function () {
1348
+ const adNetwork = AdvancedAdsAdmin.AdImporter.adNetwork
1349
+ jQuery( '#mapi-loading-overlay' ).css( 'display', 'block' )
1350
+ jQuery.ajax( {
1351
  type: 'post',
1352
  url: ajaxurl,
1353
  data: adNetwork.getRefreshAdsParameters(),
1354
+ success: function ( response, status, XHR ) {
1355
  if ( 'undefined' != typeof response.html ) {
1356
+ jQuery( '#mapi-wrap' ).replaceWith( jQuery( response.html ) )
1357
+ AdvancedAdsAdmin.AdImporter.openExternalAdsList()
1358
  } else if ( 'undefined' != typeof response.msg ) {
1359
+ AdvancedAdsAdmin.AdImporter.emptyMapiSelector( response.msg )
1360
  }
1361
  if ( 'undefined' != typeof response.raw ) {
1362
+ console.log( response.raw )
1363
  }
1364
+ jQuery( '#mapi-loading-overlay' ).css( 'display', 'none' )
1365
  },
1366
+ error: function ( request, status, err ) {
1367
+ jQuery( '#mapi-loading-overlay' ).css( 'display', 'none' )
1368
  },
1369
+ } )
1370
 
1371
  },
1372
 
1373
  toggleIdleAds: function ( hide ) {
1374
  if ( 'undefined' == typeof hide ) {
1375
+ hide = true
1376
  }
1377
+ AdvancedAdsAdmin.AdImporter.highlightSelectedRowInExternalAdsList( hide )
1378
  }
1379
+ }
1380
 
1381
  /**
1382
  * The "abstract" base class for handling external ad units
1392
  * hideIdle Remembers, wheter idle ads should be displayed in the list;
1393
  * fetchedExternalAds Remembers if the external ads list has already been loaded to prevent unneccesary requests
1394
  */
1395
+ class AdvancedAdsAdNetwork {
1396
  /**
1397
  * @param id string representing the id of this network. has to match the identifier of the PHP class
1398
  */
1399
+ constructor ( id ) {
1400
+ this.id = id
1401
+ this.units = []
1402
+ this.vars = window[ id + 'AdvancedAdsJS' ]
1403
+ this.hideIdle = true
1404
+ this.fetchedExternalAds = false
1405
  }
1406
 
1407
  /**
1408
  * will be called when an ad network is selected (ad type in edit ad)
1409
  */
1410
+ onSelected () {
1411
+ console.error( 'Please override onSelected.' )
1412
  }
1413
 
1414
  /**
1415
  * will be called when an ad network deselected (ad type in edit ad)
1416
  */
1417
+ onBlur () {
1418
+ console.error( 'Please override onBlur.' )
1419
  }
1420
 
1421
  /**
1422
  * opens the selector list containing the external ad units
1423
  */
1424
+ openSelector () {
1425
+ console.error( 'Please override openSelector.' )
1426
  }
1427
 
1428
  /**
1429
  * returns the network specific id of the currently selected ad unit
1430
  */
1431
+ getSelectedId () {
1432
+ console.error( 'Please override getSelectedId.' )
1433
  }
1434
 
1435
  /**
1436
  * will be called when an external ad unit has been selected from the selector list
1437
  * @param slotId string the external ad unit id
1438
  */
1439
+ selectAdFromList ( slotId ) {
1440
+ console.error( 'Please override selectAdFromList.' )
1441
  }
1442
 
1443
  /**
1445
  * TODO: decide wheter to remove this method. not required anymore - the button was removed.
1446
  * @param slotId string the external ad unit id
1447
  */
1448
+ updateAdFromList ( slotId ) {
1449
+ console.error( 'Please override updateAdFromList.' )
1450
  }
1451
 
 
1452
  /**
1453
  * return the POST params that you want to send to the server when requesting a refresh of the external ad units
1454
  * (like nonce and action and everything else that is required)
1455
  */
1456
+ getRefreshAdsParameters () {
1457
+ console.error( 'Please override getRefreshAdsParameters.' )
1458
  }
1459
 
1460
  /**
1461
  * return the jquery objects for all the custom html elements of this ad type
1462
  */
1463
+ getCustomInputs () {
1464
+ console.error( 'Please override getCustomInputs.' )
1465
  }
1466
 
1467
  /**
1468
  * what to do when the DOM is ready
1469
  */
1470
+ onDomReady () {
1471
+ console.error( 'Please override onDomReady.' )
1472
  }
1473
 
1474
  /**
1475
  * when you need custom behaviour for ad networks that support manual setup of ad units, override this method
1476
  */
1477
+ onManualSetup () {
1478
  //no console logging. this is optional
1479
  }
1480
  }
1481
 
1482
+ class AdvancedAdsExternalAdUnit {
1483
 
1484
  }
admin/assets/js/conditions.js ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Logic for Display and Visitor Conditions forms
3
+ */
4
+
5
+ jQuery( document ).ready(
6
+ function ( $ ) {
7
+ /**
8
+ * Pressing the button to add a new condition to the list of conditions
9
+ */
10
+ $( '.advads-conditions-new button' ).click(
11
+ function () {
12
+ // get the form fieldset and values.
13
+ var condition_form_container = $( this ).parents( 'fieldset' )
14
+ var condition_type = condition_form_container.find( '.advads-conditions-new select' ).val()
15
+ var condition_title = condition_form_container.find( '.advads-conditions-new select option:selected' ).text()
16
+ var condition_index = parseInt( condition_form_container.find( '.advads-conditions-index' ).val() )
17
+ var condition_list_target_ID = condition_form_container.data( 'condition-list-target' ) // ID of the container into which the new condition is loaded.
18
+ var condition_list_target = $( '#' + condition_list_target_ID ) // container into which the new condition is loaded.
19
+ var conditions_form_name = condition_form_container.data( 'condition-form-name' ) // name prefix for the form.
20
+ var conditions_connector_default = condition_form_container.data( 'condition-connector-default' ) // default connector option.
21
+ var conditions_action = condition_form_container.data( 'condition-action' ) // action to which to send the AJAX call to.
22
+ if ( ! condition_type || '' == condition_type ) {
23
+ return
24
+ }
25
+ condition_form_container.find( '.advads-loader' ).show() // show loader.
26
+ condition_form_container.find( 'button' ).hide() // hide add button.
27
+ $.ajax(
28
+ {
29
+ type: 'POST',
30
+ url: ajaxurl,
31
+ data: {
32
+ action: conditions_action,
33
+ type: condition_type,
34
+ index: condition_index,
35
+ form_name: conditions_form_name,
36
+ nonce: advadsglobal.ajax_nonce
37
+ },
38
+ success: function ( r, textStatus, XMLHttpRequest ) {
39
+ // add.
40
+ if ( r ) {
41
+ if ( 'or' === conditions_connector_default ) {
42
+ // as used for display conditions.
43
+ var connector = '<input style="display:none;" type="checkbox" name="' + conditions_form_name + '[' + condition_index + '][connector]" checked="checked" value="or" id="advads-conditions-' + condition_list_target_ID + '-' + condition_index + '-connector"><label for="advads-conditions-' + condition_list_target_ID + '-' + condition_index + '-connector">' + advadstxt.condition_or + '</label>'
44
+ var newline = '<tr class="advads-conditions-connector advads-conditions-connector-or"><td colspan="3">' + connector + '</td></tr><tr><td class="advads-conditions-type" data-condition-type="' + condition_type + '">' + condition_title + '</td><td>' + r + '</td><td><button type="button" class="advads-conditions-remove button">x</button></td></tr>'
45
+ } else {
46
+ // as used for visitor conditions.
47
+ var connector = '<input type="checkbox" name="' + conditions_form_name + '[' + condition_index + '][connector]" value="or" id="advads-conditions-' + condition_list_target_ID + '-' + condition_index + '-connector"><label for="advads-conditions-' + condition_list_target_ID + '-' + condition_index + '-connector">' + advadstxt.condition_and + '</label>'
48
+ var newline = '<tr class="advads-conditions-connector advads-conditions-connector-and"><td colspan="3">' + connector + '</td></tr><tr><td class="advads-conditions-type" data-condition-type="' + condition_type + '">' + condition_title + '</td><td>' + r + '</td><td><button type="button" class="advads-conditions-remove button">x</button></td></tr>'
49
+ }
50
+ condition_list_target.find( 'tbody' ).append( newline )
51
+ if ( jQuery.fn.advads_buttonset ) {
52
+ condition_list_target.find( 'tbody .advads-conditions-single.advads-buttonset' ).advads_buttonset()
53
+ }
54
+ if ( jQuery.fn.advads_button ) {
55
+ condition_list_target.find( 'tbody .advads-conditions-connector input' ).advads_button()
56
+ }
57
+ // increase count.
58
+ condition_index++
59
+ condition_form_container.find( '.advads-conditions-index' ).val( condition_index )
60
+ // reset select.
61
+ condition_form_container.find( '.advads-conditions-new select' )[ 0 ].selectedIndex = 0
62
+ }
63
+ },
64
+ error: function ( MLHttpRequest, textStatus, errorThrown ) {
65
+ condition_form_container.find( '.advads-conditions-new' ).append( errorThrown )
66
+ },
67
+ complete: function ( MLHttpRequest, textStatus ) {
68
+ condition_form_container.find( '.advads-conditions-new .advads-loader' ).hide() // hide loader.
69
+ condition_form_container.find( '.advads-conditions-new button' ).show() // display add button.
70
+ }
71
+ }
72
+ )
73
+ }
74
+ )
75
+ // disable term in the term list of the appropriate condition by just clicking on it.
76
+ $( document ).on( 'click', '.advads-conditions-terms-buttons .button', function ( e ) {
77
+ $( this ).remove()
78
+ }
79
+ )
80
+ // display input field to search for terms.
81
+ $( document ).on( 'click', '.advads-conditions-terms-show-search', function ( e ) {
82
+ e.preventDefault()
83
+ // display input field.
84
+ $( this ).siblings( '.advads-conditions-terms-search' ).show().focus()
85
+ // register autocomplete.
86
+ advads_register_terms_autocomplete( $( this ).siblings( '.advads-conditions-terms-search' ) )
87
+ $( this ).next( 'br' ).show()
88
+ $( this ).hide()
89
+ }
90
+ )
91
+
92
+ // function for autocomplete.
93
+ function advads_register_terms_autocomplete ( self ) {
94
+ self.autocomplete(
95
+ {
96
+ source: function ( request, callback ) {
97
+ // var searchField = request.term;
98
+ advads_term_search( self, callback )
99
+ },
100
+ minLength: 1,
101
+ select: function ( event, ui ) {
102
+ // append new line with input fields.
103
+ $( '<label class="button ui-state-active">' + ui.item.label + '<input type="hidden" name="' + self.data( 'inputName' ) + '" value="' + ui.item.value + '"></label>' ).appendTo( self.siblings( '.advads-conditions-terms-buttons' ) )
104
+
105
+ // show / hide other elements
106
+ // $( '.advads-display-conditions-individual-post' ).hide();
107
+ // $( '.advads-conditions-postids-list .show-search a' ).show();
108
+ },
109
+ close: function ( event, ui ) {
110
+ self.val( '' )
111
+ }
112
+ }
113
+ )
114
+ }
115
+
116
+ // display input field to search for post, page, etc.
117
+ $( document ).on( 'click', '.advads-conditions-postids-show-search', function ( e ) {
118
+ e.preventDefault()
119
+ // display input field.
120
+ $( this ).next().find( '.advads-display-conditions-individual-post' ).show()
121
+ //$( '.advads-conditions-postids-search-line .description' ).hide();
122
+ $( this ).hide()
123
+ }
124
+ )
125
+ // register autocomplete to display condition individual posts.
126
+ $( document ).on( 'focus', '.advads-display-conditions-individual-post', function ( e ) {
127
+ var self = this
128
+ if ( ! $( this ).data( 'autocomplete' ) ) { // If the autocomplete wasn't called yet:
129
+ $( this ).autocomplete(
130
+ {
131
+ source: function ( request, callback ) {
132
+ var searchParam = request.term
133
+ advads_post_search( searchParam, callback )
134
+ },
135
+ minLength: 1,
136
+ select: function ( event, ui ) {
137
+ // append new line with input fields
138
+ var newline = $( '<label class="button ui-state-active">' + ui.item.label + '</label>' )
139
+ $( '<input type="hidden" name="' + self.dataset.fieldName + '[value][]" value="' + ui.item.value + '"/>' ).appendTo( newline )
140
+ newline.insertBefore( $( self ).parent( '.advads-conditions-postids-search-line' ) )
141
+ },
142
+ close: function ( event, ui ) {
143
+ $( self ).val( '' )
144
+ },
145
+ } ).autocomplete().data( 'ui-autocomplete' )._renderItem = function ( ul, item ) {
146
+ ul.addClass( 'advads-conditions-postids-autocomplete-suggestions' )
147
+ return $( '<li></li>' ).append( '<span class=\'left\'>' + item.label + '</span>&nbsp;<span class=\'right\'>' + item.info + '</span>' ).appendTo( ul )
148
+ }
149
+ }
150
+ }
151
+ )
152
+ // remove individual posts from the display conditions post list.
153
+ $( document ).on(
154
+ 'click',
155
+ '.advads-conditions-postid-buttons .button',
156
+ function ( e ) {
157
+ $( this ).remove()
158
+ }
159
+ )
160
+ // display/hide error message if no option was selected
161
+ // is also called on every click.
162
+ function advads_display_condition_option_not_selected () {
163
+ $( '.advads-conditions-not-selected' ).each(
164
+ function () {
165
+ if ( $( this ).siblings( 'input:checked' ).length ) {
166
+ $( this ).hide()
167
+ } else {
168
+ $( this ).show()
169
+ }
170
+ }
171
+ )
172
+ }
173
+
174
+ advads_display_condition_option_not_selected()
175
+
176
+ // update error messages when an item is clicked.
177
+ $( document ).on( 'click', '.advads-conditions-terms-buttons input[type="checkbox"], .advads-conditions-single input[type="checkbox"]', function () {
178
+ // needs a slight delay until the buttons are updated.
179
+ window.setTimeout( advads_display_condition_option_not_selected, 200 )
180
+ }
181
+ )
182
+ // activate and toggle conditions connector option.
183
+ $( '.advads-conditions-connector input' ).advads_button()
184
+
185
+ // dynamically change label.
186
+ $( document ).on( 'click', '.advads-conditions-connector input', function () {
187
+ if ( $( this ).is( ':checked' ) ) {
188
+ $( this ).advads_button( 'option', 'label', advadstxt.condition_or )
189
+ $( this ).parents( '.advads-conditions-connector' ).addClass( 'advads-conditions-connector-or' ).removeClass( 'advads-conditions-connector-and' )
190
+ } else {
191
+ $( this ).advads_button( 'option', 'label', advadstxt.condition_and )
192
+ $( this ).parents( '.advads-conditions-connector' ).addClass( 'advads-conditions-connector-and' ).removeClass( 'advads-conditions-connector-or' )
193
+ }
194
+ }
195
+ )
196
+ // remove a line with a display or visitor condition.
197
+ $( document ).on( 'click', '.advads-conditions-remove', function () {
198
+ $( this ).parents( '.advads-conditions-table tr' ).prev( 'tr' ).remove()
199
+ $( this ).parents( '.advads-conditions-table tr' ).remove()
200
+ }
201
+ )
202
+ }
203
+ )
204
+
205
+ /**
206
+ * Callback for term search autocomplete
207
+ *
208
+ * @param {type} search term
209
+ * @param {type} callback
210
+ * @returns {obj} json object with labels and values
211
+ */
212
+ function advads_term_search ( field, callback ) {
213
+
214
+ // return ['post', 'poster'];
215
+ var query = {
216
+ action: 'advads-terms-search',
217
+ nonce: advadsglobal.ajax_nonce
218
+ }
219
+
220
+ query.search = field.val()
221
+ query.tax = field.data( 'tagName' )
222
+
223
+ var querying = true
224
+
225
+ var results = {}
226
+ jQuery.post( ajaxurl, query,
227
+ function ( r ) {
228
+ querying = false
229
+ var results = []
230
+ if ( r ) {
231
+ r.map(
232
+ function ( element, index ) {
233
+ results[ index ] = {
234
+ value: element.term_id,
235
+ label: element.name
236
+ }
237
+ }
238
+ )
239
+ }
240
+ callback( results )
241
+ },
242
+ 'json'
243
+ )
244
+ }
245
+
246
+ /**
247
+ * Callback for post search autocomplete
248
+ *
249
+ * @param {str} searchParam
250
+ * @param {type} callback
251
+ * @returns {obj} json object with labels and values
252
+ */
253
+ function advads_post_search ( searchParam, callback ) {
254
+
255
+ // return ['post', 'poster'];
256
+ var query = {
257
+ action: 'advads-post-search',
258
+ _ajax_linking_nonce: jQuery( '#_ajax_linking_nonce' ).val(),
259
+ 'search': searchParam,
260
+ nonce: advadsglobal.ajax_nonce
261
+ }
262
+
263
+ var querying = true
264
+
265
+ var results = {}
266
+ jQuery.post( ajaxurl, query,
267
+ function ( r ) {
268
+ querying = false
269
+ var results = []
270
+ if ( r ) {
271
+ r.map(
272
+ function ( element, index ) {
273
+ results[ index ] = {
274
+ label: element.title,
275
+ value: element.ID,
276
+ info: element.info
277
+ }
278
+ }
279
+ )
280
+ }
281
+ callback( results )
282
+ },
283
+ 'json'
284
+ )
285
+ }
admin/assets/xml/starter-setup.xml ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <advads-export>
3
+ <ads type="array">
4
+ <item key="0" type="array">
5
+ <ID type="string">1</ID>
6
+ <post_content type="string">
7
+ <![CDATA[<div style="width: 100%; height: 90px; background: #15A2E1; color: #fff; line-height: 90px; text-align: center; ">Example Ad #1 (only visible for logged-in visitors)</div>]]></post_content>
8
+ <post_title type="string">Example Ad #1 (only for logged-in visitors)</post_title>
9
+ <post_status type="string">publish</post_status>
10
+ <meta_input type="array">
11
+ <advanced_ads_ad_options type="array">
12
+ <visitor type="array"/>
13
+ <visitors type="array">
14
+ <item key="0" type="array">
15
+ <type type="string">loggedin</type>
16
+ <operator type="string">is</operator>
17
+ </item>
18
+ </visitors>
19
+ <output type="array">
20
+ <allow_php type="string">0</allow_php>
21
+ </output>
22
+ <type type="string">plain</type>
23
+ <width type="numeric">0</width>
24
+ <height type="numeric">0</height>
25
+ </advanced_ads_ad_options>
26
+ </meta_input>
27
+ </item>
28
+ <item key="1" type="array">
29
+ <ID type="string">2</ID>
30
+ <post_content type="string">
31
+ <![CDATA[<div style="width: 100%; height: 90px; background: #04B404; color: #fff; line-height: 90px; text-align: center; ">Example Ad #2 (only visible for logged-in visitors)</div>]]></post_content>
32
+ <post_title type="string">Example Ad #2 (only for logged-in visitors)</post_title>
33
+ <post_status type="string">publish</post_status>
34
+ <meta_input type="array">
35
+ <advanced_ads_ad_options type="array">
36
+ <visitor type="array"/>
37
+ <visitors type="array">
38
+ <item key="0" type="array">
39
+ <type type="string">loggedin</type>
40
+ <operator type="string">is</operator>
41
+ </item>
42
+ </visitors>
43
+ <output type="array">
44
+ <allow_php type="string">0</allow_php>
45
+ </output>
46
+ <type type="string">plain</type>
47
+ <width type="numeric">0</width>
48
+ <height type="numeric">0</height>
49
+ </advanced_ads_ad_options>
50
+ </meta_input>
51
+ </item>
52
+ </ads>
53
+ <placements type="array">
54
+ <item key="0" type="array">
55
+ <type type="string">post_top</type>
56
+ <name type="string">Before Content Placement</name>
57
+ <item type="string">ad_1</item>
58
+ <key type="string">before-content-placement</key>
59
+ </item>
60
+ <item key="1" type="array">
61
+ <type type="string">post_content</type>
62
+ <name type="string">Content Placement after 3rd Paragraph</name>
63
+ <item type="string">ad_2</item>
64
+ <options type="array">
65
+ <position type="string">after</position>
66
+ <index type="numeric">3</index>
67
+ <tag type="string">p</tag>
68
+ <ad_label type="string">default</ad_label>
69
+ <placement_position type="string"/>
70
+ </options>
71
+ <key type="string">content-placement-after-3rd-paragraph</key>
72
+ </item>
73
+ </placements>
74
+ </advads-export>
admin/class-advanced-ads-admin.php CHANGED
@@ -7,7 +7,7 @@
7
  * @license GPL-2.0+
8
  * @link https://wpadvancedads.com
9
  * @copyright since 2013 Thomas Maier, webgilde GmbH
10
- *
11
  * Plugin class. This class should ideally be used to work with the
12
  * administrative side of the WordPress site.
13
  */
@@ -69,22 +69,28 @@ class Advanced_Ads_Admin {
69
  /**
70
  * License handling legacy code after moving license handling code to Advanced_Ads_Admin_Licenses
71
  *
72
- * @param string $addon slug of the add-on.
73
- * @param string $plugin_name name of the add-on.
74
- * @param string $options_slug slug of the options the plugin is saving in the options table.
 
 
75
  * @since version 1.7.16 (early January 2017)
 
76
  */
77
  public function deactivate_license( $addon = '', $plugin_name = '', $options_slug = '' ) {
78
- return Advanced_Ads_Admin_Licenses::get_instance()->deactivate_license( $addon, $plugin_name, $options_slug ); }
 
79
 
80
  /**
81
  * Get license status.
82
  *
83
- * @param string $slug slug of the add-on.
 
84
  * @return string license status
85
  */
86
  public function get_license_status( $slug = '' ) {
87
- return Advanced_Ads_Admin_Licenses::get_instance()->get_license_status( $slug ); }
 
88
 
89
  /**
90
  * Actions and filter available after all plugins are initialized.
@@ -108,9 +114,9 @@ class Advanced_Ads_Admin {
108
 
109
  // add Advanced Ads admin notices
110
  // removes admin notices from other plugins
111
- // `in_admin_header` is the last hook to run before àdmin_notices` according to https://codex.wordpress.org/Plugin_API/Action_Reference
112
  add_action( 'in_admin_header', array( $this, 'register_admin_notices' ) );
113
-
114
  // add links to plugin page.
115
  add_filter( 'plugin_action_links_' . ADVADS_BASE, array( $this, 'add_plugin_links' ) );
116
 
@@ -122,6 +128,9 @@ class Advanced_Ads_Admin {
122
 
123
  add_action( 'plugins_api_result', array( $this, 'recommend_suitable_add_ons' ), 11, 3 );
124
 
 
 
 
125
  Advanced_Ads_Admin_Meta_Boxes::get_instance();
126
  Advanced_Ads_Admin_Menu::get_instance();
127
  Advanced_Ads_Admin_Ad_Type::get_instance();
@@ -142,9 +151,9 @@ class Advanced_Ads_Admin {
142
  /**
143
  * Return an instance of this class.
144
  *
 
145
  * @since 1.0.0
146
  *
147
- * @return object A single instance of this class.
148
  */
149
  public static function get_instance() {
150
  // If the single instance hasn't been set, set it now.
@@ -202,9 +211,10 @@ class Advanced_Ads_Admin {
202
  'ajax_nonce' => wp_create_nonce( 'advanced-ads-admin-ajax-nonce' ),
203
  );
204
  wp_localize_script( $this->plugin_slug . '-admin-global-script', 'advadsglobal', $params );
205
-
206
  if ( self::screen_belongs_to_advanced_ads() ) {
207
  wp_register_script( $this->plugin_slug . '-admin-script', plugins_url( 'assets/js/admin.js', __FILE__ ), array( 'jquery', 'jquery-ui-autocomplete', 'jquery-ui-button' ), ADVADS_VERSION, false );
 
208
  wp_register_script( $this->plugin_slug . '-wizard-script', plugins_url( 'assets/js/wizard.js', __FILE__ ), array( 'jquery' ), ADVADS_VERSION, false );
209
 
210
  // jquery ui.
@@ -219,26 +229,28 @@ class Advanced_Ads_Admin {
219
 
220
  // register admin.js translations.
221
  $translation_array = array(
222
- 'condition_or' => __( 'or', 'advanced-ads' ),
223
- 'condition_and' => __( 'and', 'advanced-ads' ),
224
- 'after_paragraph_promt' => __( 'After which paragraph?', 'advanced-ads' ),
225
- 'page_level_ads_enabled' => $auto_ads_strings['enabled'],
226
- 'today' => __( 'Today', 'advanced-ads'),
227
- 'yesterday' => __( 'Yesterday', 'advanced-ads'),
228
- 'this_month' => __( 'This Month', 'advanced-ads'),
229
  /* translators: 1: The number of days. */
230
- 'last_n_days' => __( 'Last %1$d days', 'advanced-ads'),
231
  /* translators: 1: An error message. */
232
- 'error_message' => __( 'An error occurred: %1$s'),
233
- 'all' => __( 'All', 'advanced-ads'),
234
- 'no_results' => __( 'There were no results returned for this ad. Please make sure it is active, generating impressions and double check your ad parameters.', 'advanced-ads'),
235
- 'show_inactive_ads' => __( 'Show inactive ads' , 'advanced-ads' ),
236
- 'hide_inactive_ads' => __( 'Hide inactive ads' , 'advanced-ads' )
 
237
  );
238
 
239
  wp_localize_script( $this->plugin_slug . '-admin-script', 'advadstxt', $translation_array );
240
 
241
  wp_enqueue_script( $this->plugin_slug . '-admin-script' );
 
242
  wp_enqueue_script( $this->plugin_slug . '-wizard-script' );
243
  }
244
 
@@ -257,11 +269,11 @@ class Advanced_Ads_Admin {
257
  /**
258
  * Check if the current screen belongs to Advanced Ads
259
  *
260
- * @since 1.6.6
261
  * @return bool true if screen belongs to Advanced Ads
 
262
  */
263
  public static function screen_belongs_to_advanced_ads() {
264
-
265
  if ( ! function_exists( 'get_current_screen' ) ) {
266
  return false;
267
  }
@@ -270,7 +282,7 @@ class Advanced_Ads_Admin {
270
  if ( ! isset( $screen->id ) ) {
271
  return false;
272
  }
273
-
274
  $advads_pages = apply_filters(
275
  'advanced-ads-dashboard-screens', array(
276
  'advanced-ads_page_advanced-ads-groups', // ad groups.
@@ -280,7 +292,7 @@ class Advanced_Ads_Admin {
280
  'advanced-ads_page_advanced-ads-settings', // settings.
281
  'toplevel_page_advanced-ads', // overview.
282
  'admin_page_advanced-ads-debug', // debug.
283
- // 'advanced-ads_page_advanced-ads-support', // support.
284
  'admin_page_advanced-ads-import-export', // import & export.
285
  )
286
  );
@@ -299,7 +311,7 @@ class Advanced_Ads_Admin {
299
  */
300
  public function current_action() {
301
  $request = wp_unslash( $_REQUEST );
302
- if ( isset( $request['action'] ) && -1 !== $request['action'] ) {
303
  return $request['action'];
304
  }
305
 
@@ -322,17 +334,18 @@ class Advanced_Ads_Admin {
322
 
323
  $gmt = '';
324
  if ( $gmt_offset ) {
325
- $gmt .= $sign . zeroise( $int, 2 ) . ':' . zeroise( 60 * $frac, 2 );
326
  $time_zone = date_create( '2017-10-01T12:00:00' . $gmt )->getTimezone();
327
  }
328
  }
 
329
  return $time_zone;
330
  }
331
 
332
  /**
333
  * Get literal expression of timezone
334
  *
335
- * @param DateTimeZone $date_time_zone the DateTimeZone object to get literal value from.
336
  */
337
  public static function timezone_get_name( $date_time_zone ) {
338
  if ( $date_time_zone instanceof DateTimeZone ) {
@@ -346,17 +359,19 @@ class Advanced_Ads_Admin {
346
  // translators: time zone name.
347
  $time_zone = sprintf( __( 'time of %s', 'advanced-ads' ), $time_zone );
348
  }
 
349
  return $time_zone;
350
  }
 
351
  return 'UTC+0';
352
  }
353
-
354
  /**
355
  * Registers Advanced Ads admin notices
356
  * prevents other notices from showing up on our own pages
357
  */
358
- public function register_admin_notices(){
359
-
360
  /**
361
  * remove all registered admin_notices from AA screens
362
  * - we need to use this or some users have half or more of their viewports cluttered with unrelated notices
@@ -364,7 +379,7 @@ class Advanced_Ads_Admin {
364
  if ( $this->screen_belongs_to_advanced_ads() ) {
365
  remove_all_actions( 'admin_notices' );
366
  }
367
-
368
  // register our own notices
369
  add_action( 'admin_notices', array( $this, 'admin_notices' ) );
370
  }
@@ -383,25 +398,31 @@ class Advanced_Ads_Admin {
383
  }
384
  }
385
 
 
 
 
 
 
386
  // register our own notices on Advanced Ads pages, except from the overview page where they should appear in the notices section.
387
  $screen = get_current_screen();
388
  if ( class_exists( 'Advanced_Ads_Admin_Notices' )
389
- && current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads' ) )
390
- && ( ! isset( $screen->id ) || 'toplevel_page_advanced-ads' !== $screen->id ) ) {
391
  $this->notices = Advanced_Ads_Admin_Notices::get_instance()->notices;
392
  Advanced_Ads_Admin_Notices::get_instance()->display_notices();
393
 
394
  // allow other Advanced Ads plugins to show admin notices at this late stage.
395
- do_action( 'advanced-ads-admin-notices');
396
  }
397
  }
398
 
399
  /**
400
  * Add links to the plugins list
401
  *
402
- * @since 1.6.14
403
  * @param arr $links array of links for the plugins, adapted when the current plugin is found.
 
404
  * @return array $links
 
405
  */
406
  public function add_plugin_links( $links ) {
407
 
@@ -478,26 +499,26 @@ class Advanced_Ads_Admin {
478
  $from = isset( $form['advanced_ads_disable_from'] ) ? $form['advanced_ads_disable_from'] : '';
479
  // the user clicked on the "don’t disable" button or if an address is given in the form then use that one.
480
  if ( isset( $form['advanced_ads_disable_reason'] )
481
- && 'get help' === $form['advanced_ads_disable_reason']
482
- && ! empty( $form['advanced_ads_disable_reply_email'] ) ) {
483
- $email = isset( $form['advanced_ads_disable_reply_email'] ) ? trim( $form['advanced_ads_disable_reply_email'] ) : $current_user->email;
484
- $current_user = wp_get_current_user();
485
- $name = ( $current_user instanceof WP_User ) ? $current_user->user_nicename : '';
486
- $from = $name . ' <' . $email . '>';
487
- $is_german = ( preg_match( '/\.de$/', $from ) || "de_" === substr( get_locale(), 0, 3 ) || "de_" === substr( get_user_locale(), 0, 3 ) );
488
  if ( isset( $form['advanced_ads_disable_text'][0] )
489
- && trim( $form['advanced_ads_disable_text'][0] ) !== '' ) { // is a text given then ask for help.
490
  // send German text
491
- if( $is_german ){
492
- $text .= "\n\n Hilfe ist auf dem Weg.";
493
  } else {
494
- $text .= "\n\n Help is on its way.";
495
  }
496
  } else { // if no text is given, just reply.
497
- if( $is_german ){
498
- $text .= "\n\n Vielen Dank für das Feedback.";
499
  } else {
500
- $text .= "\n\n Thank you for your feedback.";
501
  }
502
  }
503
  }
@@ -520,6 +541,7 @@ class Advanced_Ads_Admin {
520
  * Configure TinyMCE to allow unsafe link target.
521
  *
522
  * @param boolean $mce_init the tinyMce initialization array.
 
523
  * @return boolean
524
  */
525
  public function tinymce_allow_unsafe_link_target( $mce_init ) {
@@ -542,12 +564,14 @@ class Advanced_Ads_Admin {
542
  *
543
  * @param array $a array to be compared.
544
  * @param array $b array to be compared.
 
545
  * @since 1.8.12
546
  */
547
  public static function sort_condition_array_by_label( $a, $b ) {
548
  if ( ! isset( $a['label'] ) || ! isset( $b['label'] ) ) {
549
  return;
550
  }
 
551
  return strcmp( strtolower( $a['label'] ), strtolower( $b['label'] ) );
552
  }
553
 
@@ -556,7 +580,7 @@ class Advanced_Ads_Admin {
556
  *
557
  * @param object $result original result object.
558
  * @param unknown $action action.
559
- * @param object $args additional arguments.
560
  */
561
  public function recommend_suitable_add_ons( $result, $action, $args ) {
562
  if ( empty( $args->browse ) ) {
@@ -573,7 +597,7 @@ class Advanced_Ads_Admin {
573
 
574
  // Recommend AdSense In-Feed add-on.
575
  if ( ! is_plugin_active( 'advanced-ads-adsense-in-feed/advanced-ads-in-feed.php' )
576
- && ! is_plugin_active_for_network( 'advanced-ads-adsense-in-feed/advanced-ads-in-feed.php' ) ) {
577
 
578
  // Grab all slugs from the api results.
579
  $result_slugs = wp_list_pluck( $result->plugins, 'slug' );
@@ -604,8 +628,8 @@ class Advanced_Ads_Admin {
604
 
605
  // Recommend Genesis Ads add-on.
606
  if ( defined( 'PARENT_THEME_NAME' ) && 'Genesis' === PARENT_THEME_NAME
607
- && ! is_plugin_active( 'advanced-ads-genesis/genesis-ads.php' )
608
- && ! is_plugin_active_for_network( 'advanced-ads-genesis/genesis-ads.php' ) ) {
609
 
610
  // Grab all slugs from the api results.
611
  $result_slugs = wp_list_pluck( $result->plugins, 'slug' );
@@ -636,8 +660,8 @@ class Advanced_Ads_Admin {
636
 
637
  // Recommend WP Bakery (former Visual Composer) add-on.
638
  if ( defined( 'WPB_VC_VERSION' )
639
- && ! is_plugin_active( 'ads-for-visual-composer/advanced-ads-vc.php' )
640
- && ! is_plugin_active_for_network( 'ads-for-visual-composer/advanced-ads-vc.php' ) ) {
641
 
642
  // Grab all slugs from the api results.
643
  $result_slugs = wp_list_pluck( $result->plugins, 'slug' );
@@ -683,7 +707,50 @@ class Advanced_Ads_Admin {
683
  return sprintf( __( 'Thank the developer with a &#9733;&#9733;&#9733;&#9733;&#9733; review on <a href="%s" target="_blank">wordpress.org</a>', 'advanced-ads' ), 'https://wordpress.org/support/plugin/advanced-ads/reviews/#new-post' );
684
 
685
  }
 
686
  return $default_text;
687
  }
688
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
689
  }
7
  * @license GPL-2.0+
8
  * @link https://wpadvancedads.com
9
  * @copyright since 2013 Thomas Maier, webgilde GmbH
10
+ *
11
  * Plugin class. This class should ideally be used to work with the
12
  * administrative side of the WordPress site.
13
  */
69
  /**
70
  * License handling legacy code after moving license handling code to Advanced_Ads_Admin_Licenses
71
  *
72
+ * @param string $addon slug of the add-on.
73
+ * @param string $plugin_name name of the add-on.
74
+ * @param string $options_slug slug of the options the plugin is saving in the options table.
75
+ *
76
+ * @return mixed 1 on success or string with error message.
77
  * @since version 1.7.16 (early January 2017)
78
+ *
79
  */
80
  public function deactivate_license( $addon = '', $plugin_name = '', $options_slug = '' ) {
81
+ return Advanced_Ads_Admin_Licenses::get_instance()->deactivate_license( $addon, $plugin_name, $options_slug );
82
+ }
83
 
84
  /**
85
  * Get license status.
86
  *
87
+ * @param string $slug slug of the add-on.
88
+ *
89
  * @return string license status
90
  */
91
  public function get_license_status( $slug = '' ) {
92
+ return Advanced_Ads_Admin_Licenses::get_instance()->get_license_status( $slug );
93
+ }
94
 
95
  /**
96
  * Actions and filter available after all plugins are initialized.
114
 
115
  // add Advanced Ads admin notices
116
  // removes admin notices from other plugins
117
+ // `in_admin_header` is the last hook to run before àdmin_notices` according to https://codex.wordpress.org/Plugin_API/Action_Reference.
118
  add_action( 'in_admin_header', array( $this, 'register_admin_notices' ) );
119
+
120
  // add links to plugin page.
121
  add_filter( 'plugin_action_links_' . ADVADS_BASE, array( $this, 'add_plugin_links' ) );
122
 
128
 
129
  add_action( 'plugins_api_result', array( $this, 'recommend_suitable_add_ons' ), 11, 3 );
130
 
131
+ // register dynamic action to load a starter setup.
132
+ add_action( 'admin_action_advanced_ads_starter_setup', array( $this, 'import_starter_setup' ) );
133
+
134
  Advanced_Ads_Admin_Meta_Boxes::get_instance();
135
  Advanced_Ads_Admin_Menu::get_instance();
136
  Advanced_Ads_Admin_Ad_Type::get_instance();
151
  /**
152
  * Return an instance of this class.
153
  *
154
+ * @return object A single instance of this class.
155
  * @since 1.0.0
156
  *
 
157
  */
158
  public static function get_instance() {
159
  // If the single instance hasn't been set, set it now.
211
  'ajax_nonce' => wp_create_nonce( 'advanced-ads-admin-ajax-nonce' ),
212
  );
213
  wp_localize_script( $this->plugin_slug . '-admin-global-script', 'advadsglobal', $params );
214
+
215
  if ( self::screen_belongs_to_advanced_ads() ) {
216
  wp_register_script( $this->plugin_slug . '-admin-script', plugins_url( 'assets/js/admin.js', __FILE__ ), array( 'jquery', 'jquery-ui-autocomplete', 'jquery-ui-button' ), ADVADS_VERSION, false );
217
+ wp_register_script( $this->plugin_slug . '-conditions-script', plugins_url( 'assets/js/conditions.js', __FILE__ ), array( 'jquery', 'jquery-ui-autocomplete', 'jquery-ui-button' ), ADVADS_VERSION, false );
218
  wp_register_script( $this->plugin_slug . '-wizard-script', plugins_url( 'assets/js/wizard.js', __FILE__ ), array( 'jquery' ), ADVADS_VERSION, false );
219
 
220
  // jquery ui.
229
 
230
  // register admin.js translations.
231
  $translation_array = array(
232
+ 'condition_or' => __( 'or', 'advanced-ads' ),
233
+ 'condition_and' => __( 'and', 'advanced-ads' ),
234
+ 'after_paragraph_promt' => __( 'After which paragraph?', 'advanced-ads' ),
235
+ 'page_level_ads_enabled' => $auto_ads_strings['enabled'],
236
+ 'today' => __( 'Today', 'advanced-ads' ),
237
+ 'yesterday' => __( 'Yesterday', 'advanced-ads' ),
238
+ 'this_month' => __( 'This Month', 'advanced-ads' ),
239
  /* translators: 1: The number of days. */
240
+ 'last_n_days' => __( 'Last %1$d days', 'advanced-ads' ),
241
  /* translators: 1: An error message. */
242
+ 'error_message' => __( 'An error occurred: %1$s' ),
243
+ 'all' => __( 'All', 'advanced-ads' ),
244
+ 'no_results' => __( 'There were no results returned for this ad. Please make sure it is active, generating impressions and double check your ad parameters.', 'advanced-ads' ),
245
+ 'show_inactive_ads' => __( 'Show inactive ads', 'advanced-ads' ),
246
+ 'hide_inactive_ads' => __( 'Hide inactive ads', 'advanced-ads' ),
247
+ 'display_conditions_form_name' => Advanced_Ads_Display_Conditions::FORM_NAME, // not meant for translation.
248
  );
249
 
250
  wp_localize_script( $this->plugin_slug . '-admin-script', 'advadstxt', $translation_array );
251
 
252
  wp_enqueue_script( $this->plugin_slug . '-admin-script' );
253
+ wp_enqueue_script( $this->plugin_slug . '-conditions-script' );
254
  wp_enqueue_script( $this->plugin_slug . '-wizard-script' );
255
  }
256
 
269
  /**
270
  * Check if the current screen belongs to Advanced Ads
271
  *
 
272
  * @return bool true if screen belongs to Advanced Ads
273
+ * @since 1.6.6
274
  */
275
  public static function screen_belongs_to_advanced_ads() {
276
+
277
  if ( ! function_exists( 'get_current_screen' ) ) {
278
  return false;
279
  }
282
  if ( ! isset( $screen->id ) ) {
283
  return false;
284
  }
285
+
286
  $advads_pages = apply_filters(
287
  'advanced-ads-dashboard-screens', array(
288
  'advanced-ads_page_advanced-ads-groups', // ad groups.
292
  'advanced-ads_page_advanced-ads-settings', // settings.
293
  'toplevel_page_advanced-ads', // overview.
294
  'admin_page_advanced-ads-debug', // debug.
295
+ // 'advanced-ads_page_advanced-ads-support', // support.
296
  'admin_page_advanced-ads-import-export', // import & export.
297
  )
298
  );
311
  */
312
  public function current_action() {
313
  $request = wp_unslash( $_REQUEST );
314
+ if ( isset( $request['action'] ) && - 1 !== $request['action'] ) {
315
  return $request['action'];
316
  }
317
 
334
 
335
  $gmt = '';
336
  if ( $gmt_offset ) {
337
+ $gmt .= $sign . zeroise( $int, 2 ) . ':' . zeroise( 60 * $frac, 2 );
338
  $time_zone = date_create( '2017-10-01T12:00:00' . $gmt )->getTimezone();
339
  }
340
  }
341
+
342
  return $time_zone;
343
  }
344
 
345
  /**
346
  * Get literal expression of timezone
347
  *
348
+ * @param DateTimeZone $date_time_zone the DateTimeZone object to get literal value from.
349
  */
350
  public static function timezone_get_name( $date_time_zone ) {
351
  if ( $date_time_zone instanceof DateTimeZone ) {
359
  // translators: time zone name.
360
  $time_zone = sprintf( __( 'time of %s', 'advanced-ads' ), $time_zone );
361
  }
362
+
363
  return $time_zone;
364
  }
365
+
366
  return 'UTC+0';
367
  }
368
+
369
  /**
370
  * Registers Advanced Ads admin notices
371
  * prevents other notices from showing up on our own pages
372
  */
373
+ public function register_admin_notices() {
374
+
375
  /**
376
  * remove all registered admin_notices from AA screens
377
  * - we need to use this or some users have half or more of their viewports cluttered with unrelated notices
379
  if ( $this->screen_belongs_to_advanced_ads() ) {
380
  remove_all_actions( 'admin_notices' );
381
  }
382
+
383
  // register our own notices
384
  add_action( 'admin_notices', array( $this, 'admin_notices' ) );
385
  }
398
  }
399
  }
400
 
401
+ // Show success notice after starter setup was imported. Registered here because it will be visible only once.
402
+ if ( isset( $_GET['message'] ) && 'advanced-ads-starter-setup-success' === $_GET['message'] ) {
403
+ add_action( 'advanced-ads-admin-notices', array( $this, 'starter_setup_success_message' ) );
404
+ }
405
+
406
  // register our own notices on Advanced Ads pages, except from the overview page where they should appear in the notices section.
407
  $screen = get_current_screen();
408
  if ( class_exists( 'Advanced_Ads_Admin_Notices' )
409
+ && current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads' ) )
410
+ && ( ! isset( $screen->id ) || 'toplevel_page_advanced-ads' !== $screen->id ) ) {
411
  $this->notices = Advanced_Ads_Admin_Notices::get_instance()->notices;
412
  Advanced_Ads_Admin_Notices::get_instance()->display_notices();
413
 
414
  // allow other Advanced Ads plugins to show admin notices at this late stage.
415
+ do_action( 'advanced-ads-admin-notices' );
416
  }
417
  }
418
 
419
  /**
420
  * Add links to the plugins list
421
  *
 
422
  * @param arr $links array of links for the plugins, adapted when the current plugin is found.
423
+ *
424
  * @return array $links
425
+ * @since 1.6.14
426
  */
427
  public function add_plugin_links( $links ) {
428
 
499
  $from = isset( $form['advanced_ads_disable_from'] ) ? $form['advanced_ads_disable_from'] : '';
500
  // the user clicked on the "don’t disable" button or if an address is given in the form then use that one.
501
  if ( isset( $form['advanced_ads_disable_reason'] )
502
+ && 'get help' === $form['advanced_ads_disable_reason']
503
+ && ! empty( $form['advanced_ads_disable_reply_email'] ) ) {
504
+ $email = isset( $form['advanced_ads_disable_reply_email'] ) ? trim( $form['advanced_ads_disable_reply_email'] ) : $current_user->email;
505
+ $current_user = wp_get_current_user();
506
+ $name = ( $current_user instanceof WP_User ) ? $current_user->user_nicename : '';
507
+ $from = $name . ' <' . $email . '>';
508
+ $is_german = ( preg_match( '/\.de$/', $from ) || "de_" === substr( get_locale(), 0, 3 ) || "de_" === substr( get_user_locale(), 0, 3 ) );
509
  if ( isset( $form['advanced_ads_disable_text'][0] )
510
+ && trim( $form['advanced_ads_disable_text'][0] ) !== '' ) { // is a text given then ask for help.
511
  // send German text
512
+ if ( $is_german ) {
513
+ $text .= "\n\n Hilfe ist auf dem Weg.";
514
  } else {
515
+ $text .= "\n\n Help is on its way.";
516
  }
517
  } else { // if no text is given, just reply.
518
+ if ( $is_german ) {
519
+ $text .= "\n\n Vielen Dank für das Feedback.";
520
  } else {
521
+ $text .= "\n\n Thank you for your feedback.";
522
  }
523
  }
524
  }
541
  * Configure TinyMCE to allow unsafe link target.
542
  *
543
  * @param boolean $mce_init the tinyMce initialization array.
544
+ *
545
  * @return boolean
546
  */
547
  public function tinymce_allow_unsafe_link_target( $mce_init ) {
564
  *
565
  * @param array $a array to be compared.
566
  * @param array $b array to be compared.
567
+ *
568
  * @since 1.8.12
569
  */
570
  public static function sort_condition_array_by_label( $a, $b ) {
571
  if ( ! isset( $a['label'] ) || ! isset( $b['label'] ) ) {
572
  return;
573
  }
574
+
575
  return strcmp( strtolower( $a['label'] ), strtolower( $b['label'] ) );
576
  }
577
 
580
  *
581
  * @param object $result original result object.
582
  * @param unknown $action action.
583
+ * @param object $args additional arguments.
584
  */
585
  public function recommend_suitable_add_ons( $result, $action, $args ) {
586
  if ( empty( $args->browse ) ) {
597
 
598
  // Recommend AdSense In-Feed add-on.
599
  if ( ! is_plugin_active( 'advanced-ads-adsense-in-feed/advanced-ads-in-feed.php' )
600
+ && ! is_plugin_active_for_network( 'advanced-ads-adsense-in-feed/advanced-ads-in-feed.php' ) ) {
601
 
602
  // Grab all slugs from the api results.
603
  $result_slugs = wp_list_pluck( $result->plugins, 'slug' );
628
 
629
  // Recommend Genesis Ads add-on.
630
  if ( defined( 'PARENT_THEME_NAME' ) && 'Genesis' === PARENT_THEME_NAME
631
+ && ! is_plugin_active( 'advanced-ads-genesis/genesis-ads.php' )
632
+ && ! is_plugin_active_for_network( 'advanced-ads-genesis/genesis-ads.php' ) ) {
633
 
634
  // Grab all slugs from the api results.
635
  $result_slugs = wp_list_pluck( $result->plugins, 'slug' );
660
 
661
  // Recommend WP Bakery (former Visual Composer) add-on.
662
  if ( defined( 'WPB_VC_VERSION' )
663
+ && ! is_plugin_active( 'ads-for-visual-composer/advanced-ads-vc.php' )
664
+ && ! is_plugin_active_for_network( 'ads-for-visual-composer/advanced-ads-vc.php' ) ) {
665
 
666
  // Grab all slugs from the api results.
667
  $result_slugs = wp_list_pluck( $result->plugins, 'slug' );
707
  return sprintf( __( 'Thank the developer with a &#9733;&#9733;&#9733;&#9733;&#9733; review on <a href="%s" target="_blank">wordpress.org</a>', 'advanced-ads' ), 'https://wordpress.org/support/plugin/advanced-ads/reviews/#new-post' );
708
 
709
  }
710
+
711
  return $default_text;
712
  }
713
 
714
+ /**
715
+ * Import a starter setup for new users
716
+ */
717
+ public function import_starter_setup() {
718
+
719
+ if (
720
+ ! isset( $_GET['action'] )
721
+ || 'advanced_ads_starter_setup' !== $_GET['action']
722
+ || ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads' ) )
723
+ ) {
724
+ return;
725
+ }
726
+
727
+ check_admin_referer( 'advanced-ads-starter-setup' );
728
+
729
+ // remove_query_arg( 'inject-ad-setup' );
730
+
731
+ // start importing the ads.
732
+ $xml = file_get_contents( ADVADS_BASE_PATH . 'admin/assets/xml/starter-setup.xml' );
733
+
734
+ Advanced_Ads_Import::get_instance()->import( $xml );
735
+
736
+ // redirect to ad overview page.
737
+ wp_safe_redirect( admin_url( 'edit.php?post_type=advanced_ads&message=advanced-ads-starter-setup-success' ) );
738
+ }
739
+
740
+ /**
741
+ * Show success message after starter setup was created.
742
+ */
743
+ public function starter_setup_success_message() {
744
+
745
+ // load link to latest post.
746
+
747
+ $args = array(
748
+ 'numberposts' => 1,
749
+ );
750
+ $last_post = get_posts( $args );
751
+ $last_post_link = isset( $last_post[0]->ID ) ? get_permalink( $last_post[0]->ID ) : false;
752
+
753
+ include ADVADS_BASE_PATH . 'admin/views/notices/starter-setup-success.php';
754
+ }
755
+
756
  }
admin/includes/class-ad-type.php CHANGED
@@ -756,16 +756,15 @@ class Advanced_Ads_Admin_Ad_Type {
756
 
757
  $hide_wizard = get_user_meta( $user_id, 'advanced-ads-hide-wizard', true );
758
 
 
 
 
759
  $options = Advanced_Ads_Plugin::get_instance()->internal_options();
760
  $installed = isset( $options['installed'] ) ? $options['installed'] : 0;
761
-
762
- if ( '' === $hide_wizard && Advanced_Ads_Plugin::random_by_url() && $installed > 1570492800 ) {
763
- // choose setting.
764
- $hide_wizard = true;
765
  }
766
 
767
- global $post;
768
-
769
  // true if the wizard was never started or closed.
770
  return ( ( ! $hide_wizard && 'edit' !== $post->filter ) || 'false' === $hide_wizard ) ? true : false;
771
  }
756
 
757
  $hide_wizard = get_user_meta( $user_id, 'advanced-ads-hide-wizard', true );
758
 
759
+ global $post;
760
+
761
+ // disable wizard for already existing ads.
762
  $options = Advanced_Ads_Plugin::get_instance()->internal_options();
763
  $installed = isset( $options['installed'] ) ? $options['installed'] : 0;
764
+ if ( 'edit' === $post->filter && Advanced_Ads_Plugin::get_group_by_url( null, 'b' ) && $installed > 1573128000 ) {
765
+ return false;
 
 
766
  }
767
 
 
 
768
  // true if the wizard was never started or closed.
769
  return ( ( ! $hide_wizard && 'edit' !== $post->filter ) || 'false' === $hide_wizard ) ? true : false;
770
  }
admin/includes/class-meta-box.php CHANGED
@@ -159,13 +159,13 @@ class Advanced_Ads_Admin_Meta_Boxes {
159
  $view = 'ad-output-metabox.php';
160
  break;
161
  case 'ad-display-box':
162
- $view = 'ad-display-metabox.php';
163
  $hndlelinks = '<a href="#" class="advads-video-link">' . __('Video', 'advanced-ads') . '</a>';
164
  $hndlelinks .= '<a href="' . ADVADS_URL . 'manual/display-conditions#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-display" target="_blank">' . __('Manual', 'advanced-ads') . '</a>';
165
  $videomarkup = '<iframe width="420" height="315" src="https://www.youtube-nocookie.com/embed/wVB6UpeyWNA?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe>';
166
  break;
167
  case 'ad-visitor-box':
168
- $view = 'ad-visitor-metabox.php';
169
  $hndlelinks = '<a href="' . ADVADS_URL . 'manual/visitor-conditions#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor" target="_blank">' . __('Manual', 'advanced-ads') . '</a>';
170
  break;
171
  case 'advads-pro-pitch':
159
  $view = 'ad-output-metabox.php';
160
  break;
161
  case 'ad-display-box':
162
+ $view = 'conditions/ad-display-metabox.php';
163
  $hndlelinks = '<a href="#" class="advads-video-link">' . __('Video', 'advanced-ads') . '</a>';
164
  $hndlelinks .= '<a href="' . ADVADS_URL . 'manual/display-conditions#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-display" target="_blank">' . __('Manual', 'advanced-ads') . '</a>';
165
  $videomarkup = '<iframe width="420" height="315" src="https://www.youtube-nocookie.com/embed/wVB6UpeyWNA?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe>';
166
  break;
167
  case 'ad-visitor-box':
168
+ $view = 'conditions/ad-visitor-metabox.php';
169
  $hndlelinks = '<a href="' . ADVADS_URL . 'manual/visitor-conditions#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor" target="_blank">' . __('Manual', 'advanced-ads') . '</a>';
170
  break;
171
  case 'advads-pro-pitch':
admin/includes/class-notices.php CHANGED
@@ -157,16 +157,6 @@ class Advanced_Ads_Admin_Notices {
157
  $queue = isset( $options['queue'] ) ? $options['queue'] : array();
158
  $paused = isset( $options['paused'] ) ? $options['paused'] : array();
159
 
160
- // register intro message.
161
- if ( ! Advanced_Ads_Admin::get_instance()->screen_belongs_to_advanced_ads()
162
- && array() === $options && ! in_array( 'nl_intro', $queue, true ) && ! isset( $closed['nl_intro'] ) ) {
163
- $this->notices[] = 'nl_intro';
164
- } elseif ( Advanced_Ads_Admin::get_instance()->screen_belongs_to_advanced_ads() ) {
165
- $key = array_search( 'nl_intro', $this->notices, true );
166
- if ( false !== $key ) {
167
- unset( $this->notices[ $key ] );
168
- }
169
- }
170
  // offer free add-ons if not yet subscribed.
171
  if ( $this->user_can_subscribe() && ! in_array( 'nl_free_addons', $queue, true ) && ! isset( $closed['nl_free_addons'] ) ) {
172
  // get number of ads.
@@ -182,6 +172,17 @@ class Advanced_Ads_Admin_Notices {
182
  // no need to catch anything since we just use TRY/CATCH to prevent an issue caused by another plugin.
183
  }
184
 
 
 
 
 
 
 
 
 
 
 
 
185
  // ask for a review after 2 days and when 3 ads were created and when not paused.
186
  if ( ! in_array( 'review', $queue, true )
187
  && ! isset( $closed['review'] )
@@ -356,19 +357,16 @@ class Advanced_Ads_Admin_Notices {
356
  return;
357
  }
358
 
359
- // register Black Friday 2018 deals
360
- /*if( time() > 1542931200 &&
361
- time() <= 1543320000 && Advanced_Ads_Admin::get_instance()->screen_belongs_to_advanced_ads() ){
362
  $options = $this->options();
363
- $closed = isset($options['closed']) ? $options['closed'] : array();
364
 
365
- if( ! Advanced_Ads_Admin_Licenses::any_license_valid()
366
- && ! isset( $closed['bf2018'] ) ){
367
- $this->notices[] = 'bf2018';
368
- } elseif ( ! isset( $closed['bf2018_2'] ) ){
369
- $this->notices[] = 'bf2018_2';
370
  }
371
- }*/
372
 
373
  // load notices.
374
  include ADVADS_BASE_PATH . '/admin/includes/notices.php';
157
  $queue = isset( $options['queue'] ) ? $options['queue'] : array();
158
  $paused = isset( $options['paused'] ) ? $options['paused'] : array();
159
 
 
 
 
 
 
 
 
 
 
 
160
  // offer free add-ons if not yet subscribed.
161
  if ( $this->user_can_subscribe() && ! in_array( 'nl_free_addons', $queue, true ) && ! isset( $closed['nl_free_addons'] ) ) {
162
  // get number of ads.
172
  // no need to catch anything since we just use TRY/CATCH to prevent an issue caused by another plugin.
173
  }
174
 
175
+ // register intro message.
176
+ if ( ! $number_of_ads
177
+ && array() === $options && ! in_array( 'nl_intro', $queue, true ) && ! isset( $closed['nl_intro'] ) ) {
178
+ $this->notices[] = 'nl_intro';
179
+ } elseif ( $number_of_ads ) {
180
+ $key = array_search( 'nl_intro', $this->notices, true );
181
+ if ( false !== $key ) {
182
+ unset( $this->notices[ $key ] );
183
+ }
184
+ }
185
+
186
  // ask for a review after 2 days and when 3 ads were created and when not paused.
187
  if ( ! in_array( 'review', $queue, true )
188
  && ! isset( $closed['review'] )
357
  return;
358
  }
359
 
360
+ // register Black Friday 2019 deals.
361
+ if ( time() > 1574985600 &&
362
+ time() <= 1575374400 && Advanced_Ads_Admin::get_instance()->screen_belongs_to_advanced_ads() ) {
363
  $options = $this->options();
364
+ $closed = isset( $options['closed'] ) ? $options['closed'] : array();
365
 
366
+ if ( ! isset( $closed['bf2019'] ) ) {
367
+ $this->notices[] = 'bf2019';
 
 
 
368
  }
369
+ }
370
 
371
  // load notices.
372
  include ADVADS_BASE_PATH . '/admin/includes/notices.php';
admin/includes/class-options.php CHANGED
@@ -33,10 +33,10 @@ class Advanced_Ads_Admin_Options {
33
  /**
34
  * create a wrapper for a single option line
35
  *
36
- * @param str $id internal id of the option wrapper
37
- * @param str $title label of the option
38
- * @param str $content content of the option
39
- * @param str $description description of the option
40
  *
41
  */
42
  public static function render_option( $id, $title, $content, $description = '' ){
33
  /**
34
  * create a wrapper for a single option line
35
  *
36
+ * @param string $id internal id of the option wrapper
37
+ * @param string $title label of the option
38
+ * @param string $content content of the option
39
+ * @param string $description description of the option
40
  *
41
  */
42
  public static function render_option( $id, $title, $content, $description = '' ){
admin/includes/class-settings.php CHANGED
@@ -162,6 +162,14 @@ class Advanced_Ads_Admin_Settings {
162
  $hook,
163
  'advanced_ads_setting_section_injection'
164
  );
 
 
 
 
 
 
 
 
165
  // add setting fields for hiding ads from bots.
166
  add_settings_field(
167
  'block-bots',
@@ -500,6 +508,23 @@ class Advanced_Ads_Admin_Settings {
500
  echo '<p class="description">' . __( 'Advanced Ads ignores paragraphs and other elements in containers when injecting ads into the post content. Check this option to ignore this limitation and ads might show up again.', 'advanced-ads' ) . '</p>';
501
  }
502
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
503
  /**
504
  * render setting for blocking bots
505
  *
162
  $hook,
163
  'advanced_ads_setting_section_injection'
164
  );
165
+ // Add setting fields to enable new content injection.
166
+ add_settings_field(
167
+ 'content-injection-new',
168
+ __( 'Use new injection logic', 'advanced-ads' ),
169
+ array( $this, 'render_settings_content_injection_new' ),
170
+ $hook,
171
+ 'advanced_ads_setting_section_injection'
172
+ );
173
  // add setting fields for hiding ads from bots.
174
  add_settings_field(
175
  'block-bots',
508
  echo '<p class="description">' . __( 'Advanced Ads ignores paragraphs and other elements in containers when injecting ads into the post content. Check this option to ignore this limitation and ads might show up again.', 'advanced-ads' ) . '</p>';
509
  }
510
 
511
+ /**
512
+ * Render setting fields to enable new content injection.
513
+ *
514
+ * @since untagged
515
+ */
516
+ public function render_settings_content_injection_new() {
517
+ $checked = ( Advanced_Ads_Placements::is_new_content_injection() ) ? 1 : 0;
518
+
519
+ echo '<input id="advanced-ads-content-injection-new" type="checkbox" value="1" name="' . ADVADS_SLUG . '[content-injection-new]" ' . checked( $checked, 1, false ) . '>';
520
+
521
+ echo '<p class="description">' . sprintf(
522
+ // translators: %1$s is a starting <a> tag and %2$s a closing one.
523
+ __( 'Enable the new more stable injection logic. Please report any issues %1$shere%2$s.', 'advanced-ads' ), '<a href="'
524
+ . ADVADS_URL . 'support" target="_blank"> ', '</a>' ) . '</p>';
525
+
526
+ }
527
+
528
  /**
529
  * render setting for blocking bots
530
  *
admin/includes/notices.php CHANGED
@@ -52,26 +52,15 @@ $advanced_ads_admin_notices = apply_filters( 'advanced-ads-notices', array(
52
  . '</p></div>',
53
  'global' => false,
54
  ),
55
- // Black Friday 2018 promotion.
56
- /*'bf2018' => array(
57
  'type' => 'info',
58
  'text' => sprintf(
59
- // translators: %s is a link. `30%%` is correct, please use exactly that value so that it shows "30%"
60
  __( 'Our Black Friday / Cyber Monday Offer: <span style="font-weight: bold; font-size: 1.4em; color: green;">-30%%</span> on all add-ons and All Access.<a class="button button-primary" target="_blank" href="%s">Get All Access</a>', 'advanced-ads' ),
61
- ADVADS_URL . 'checkout/?edd_action=add_to_cart&download_id=95170&edd_options[price_id]=1&discount=BFCM2018#utm_source=advanced-ads&utm_medium=link&utm_campaign=bfcm-2018'
62
  ),
63
  'global' => true,
64
  ),
65
- // Black Friday 2018 #2 promotion.
66
- 'bf2018_2' => array(
67
- 'type' => 'info',
68
- 'text' => sprintf(
69
- // translators: %s is a link. `30%%` is correct, please use exactly that value so that it shows "30%"
70
- __( 'Our Black Friday / Cyber Monday Offer: <span style="font-weight: bold; font-size: 1.4em; color: green;">-30%%</span> on your upgrade.<a class="button button-primary" target="_blank" href="%s">Upgrade now</a>', 'advanced-ads' ),
71
- ADVADS_URL . 'manual/upgrade-to-larger-package/?discount=BFCM2018#utm_source=advanced-ads&utm_medium=link&utm_campaign=bfcm-2018-2'
72
- ),
73
- 'global' => true,
74
- ),*/
75
-
76
  ) );
77
 
52
  . '</p></div>',
53
  'global' => false,
54
  ),
55
+ // Black Friday 2019 promotion.
56
+ 'bf2019' => array(
57
  'type' => 'info',
58
  'text' => sprintf(
59
+ // translators: %s is a link. `30%%` is correct, please use exactly that value so that it shows "30%".
60
  __( 'Our Black Friday / Cyber Monday Offer: <span style="font-weight: bold; font-size: 1.4em; color: green;">-30%%</span> on all add-ons and All Access.<a class="button button-primary" target="_blank" href="%s">Get All Access</a>', 'advanced-ads' ),
61
+ ADVADS_URL . 'checkout/?edd_action=add_to_cart&download_id=95170&edd_options[price_id]=1&discount=BFCM2019#utm_source=advanced-ads&utm_medium=link&utm_campaign=bfcm-2019'
62
  ),
63
  'global' => true,
64
  ),
 
 
 
 
 
 
 
 
 
 
 
65
  ) );
66
 
admin/views/ad-display-metabox.php DELETED
@@ -1,217 +0,0 @@
1
- <?php
2
- /**
3
- * Render meta box for Display Conditions on ad edit page
4
- *
5
- * @package Advanced_Ads_Admin
6
- * @author Thomas Maier <thomas.maier@webgilde.com>
7
- * @license GPL-2.0+
8
- * @link https://wpadvancedads.com
9
- * @copyright since 2013 Thomas Maier, webgilde GmbH
10
- */
11
-
12
- $display_conditions = Advanced_Ads_Display_Conditions::get_instance()->get_conditions();
13
-
14
- // add mockup conditions if add-ons are missing.
15
- $pro_conditions = array();
16
- if ( ! defined( 'AAP_VERSION' ) ) {
17
- $pro_conditions[] = __( 'parent page', 'advanced-ads' );
18
- $pro_conditions[] = __( 'post meta', 'advanced-ads' );
19
- $pro_conditions[] = __( 'page template', 'advanced-ads' );
20
- $pro_conditions[] = __( 'url parameters', 'advanced-ads' );
21
- }
22
- if ( ! defined( 'AAR_VERSION' ) ) {
23
- $pro_conditions[] = __( 'accelerated mobile pages', 'advanced-ads' );
24
- }
25
- asort( $pro_conditions );
26
-
27
- $options = $ad->options( 'conditions' );
28
- $empty_options = ( ! is_array( $options ) || ! count( $options ) );
29
- if ( $empty_options ) :
30
- ?><div class="advads-show-in-wizard">
31
- <p><?php esc_attr_e( 'Click on the button below if the ad should NOT show up on all pages when included automatically.', 'advanced-ads' ); ?></p>
32
- <button type="button" class="button button-secondary" id="advads-wizard-display-conditions-show"><?php esc_attr_e( 'Hide the ad on some pages', 'advanced-ads' ); ?></button>
33
- </div>
34
- <?php endif; ?>
35
- <div id="advads-display-conditions"
36
- <?php
37
- if ( $empty_options ) :
38
- ?>
39
- class="advads-hide-in-wizard"<?php endif; ?>>
40
- <?php
41
- // display help when no conditions are given.
42
- if ( $empty_options ) :
43
- $options = array();
44
- ?>
45
- <p><button type="button" class="advads-video-link-inline button button-primary">
46
- <?php esc_attr_e( 'Watch video', 'advanced-ads' ); ?>
47
- </button>&nbsp;<a class="button button-secondary" href="<?php echo ADVADS_URL; ?>manual/display-conditions#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-display" target="_blank">
48
- <?php esc_attr_e( 'Visit the manual', 'advanced-ads' ); ?>
49
- </a></p>
50
- <?php
51
- endif;
52
- ?>
53
- <p class="advads-jqueryui-error advads-error-message hidden">
54
- <?php
55
- /*
56
- * translators: %s is a link to a tutorial.
57
- */
58
- printf( __( 'There might be a problem with layouts and scripts in your dashboard. Please check <a href="%s" target="_blank">this article to learn more</a>.', 'advanced-ads' ), ADVADS_URL . 'manual/jquery-problem-in-dashboard/#utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-jquery-error' ); ?></p>
59
- <p><?php esc_attr_e( 'A page with this ad on it must match all of the following conditions.', 'advanced-ads' ); ?></p>
60
- <table class="advads-conditions-table"><tbody>
61
- <?php
62
- $last_index = -1;
63
- $i = 0;
64
- if ( is_array( $options ) ) :
65
- foreach ( $options as $_index => $_options ) :
66
- $show_or_force_warning = false;
67
- // get type attribute from previous option format.
68
- $_options['type'] = isset( $_options['type'] ) ? $_options['type'] : $_index;
69
- $connector = ( ! isset( $_options['connector'] ) || 'or' !== $_options['connector'] ) ? 'and' : 'or';
70
- if ( isset( $_options['type'] ) && isset( $display_conditions[ $_options['type'] ]['metabox'] ) ) {
71
- $metabox = $display_conditions[ $_options['type'] ]['metabox'];
72
- } else {
73
- continue;
74
- }
75
- if ( method_exists( $metabox[0], $metabox[1] ) ) {
76
- /**
77
- * Show warning for connector when
78
- * not set to OR already
79
- * this condition and the previous are on page level and not from the identical type
80
- * they are both set to SHOW
81
- */
82
- $tax = ( isset( $_options['type'] ) && isset( $display_conditions[ $_options['type'] ]['taxonomy'] ) ) ? $display_conditions[ $_options['type'] ]['taxonomy'] : false;
83
- $last_tax = ( isset( $options[ $last_index ]['type'] ) && isset( $display_conditions[ $options[ $last_index ]['type'] ]['taxonomy'] ) ) ? $display_conditions[ $options[ $last_index ]['type'] ]['taxonomy'] : false;
84
- if ( $tax && $last_tax && $last_tax === $tax
85
- && ( ! isset( $_options['connector'] ) || 'or' !== $_options['connector'] )
86
- && 'is' === $_options['operator'] && 'is' === $options[ $last_index ]['operator']
87
- && $_options['type'] !== $options[ $last_index ]['type'] ) {
88
-
89
- $show_or_force_warning = true;
90
- }
91
-
92
- if ( $i > 0 ) :
93
-
94
- ?>
95
- <tr class="advads-conditions-connector advads-conditions-connector-<?php echo $connector; ?>">
96
- <td colspan="3">
97
- <?php
98
- echo Advanced_Ads_Display_Conditions::render_connector_option( $i, $connector );
99
- if ( $show_or_force_warning ) {
100
- ?>
101
- <p class="advads-error-message">
102
- <?php
103
- esc_attr_e( 'Forced to OR.', 'advanced-ads' );
104
- echo '&nbsp;<a target="_blank" href="' . ADVADS_URL . 'manual/display-conditions#manual-combining-multiple-conditions' . '">' . esc_attr__( 'manual', 'advanced-ads' ) . '</a>';
105
- ?>
106
- </p>
107
- <?php
108
-
109
- }
110
- ?>
111
- </td>
112
- </tr><?php endif; ?>
113
- <tr><td class="advads-conditions-type" data-condition-type="<?php echo $_options['type']; ?>"><?php echo $display_conditions[ $_options['type'] ]['label']; ?></td><td>
114
- <?php
115
- call_user_func( array( $metabox[0], $metabox[1] ), $_options, $i++ );
116
- ?>
117
- </td><td><button type="button" class="advads-conditions-remove button">x</button></td></tr>
118
- <?php
119
- }
120
- $last_index = $_index;
121
- endforeach;
122
- endif;
123
- ?>
124
- </tbody></table>
125
- <input type="hidden" id="advads-display-conditions-index" value="<?php echo is_array( $options ) ? count( $options ) : 0; ?>"/>
126
- <?php
127
- if ( $empty_options ) :
128
- ?>
129
- <p><?php esc_attr_e( 'If you want to display the ad everywhere, don\'t do anything here. ', 'advanced-ads' ); ?></p>
130
- <?php
131
- endif;
132
- ?>
133
- </div>
134
- <fieldset
135
- <?php
136
- if ( $empty_options ) :
137
- ?>
138
- class="advads-hide-in-wizard"<?php endif; ?>>
139
- <legend><?php esc_attr_e( 'New condition', 'advanced-ads' ); ?></legend>
140
- <div id="advads-display-conditions-new">
141
- <select>
142
- <option value=""><?php esc_attr_e( '-- choose a condition --', 'advanced-ads' ); ?></option>
143
- <?php foreach ( $display_conditions as $_condition_id => $_condition ) : ?>
144
- <option value="<?php echo $_condition_id; ?>"><?php echo $_condition['label']; ?></option>
145
- <?php
146
- endforeach;
147
- if ( count( $pro_conditions ) ) :
148
- ?>
149
- <optgroup label="<?php esc_attr_e( 'Add-On features', 'advanced-ads' ); ?>">
150
- <?php
151
- foreach ( $pro_conditions as $_pro_condition ) :
152
- ?>
153
- <option disabled="disabled"><?php echo $_pro_condition; ?></option>
154
- <?php
155
- endforeach;
156
- ?>
157
- </optgroup>
158
- <?php
159
- endif;
160
- ?>
161
- </select>
162
- <button type="button" class="button"><?php esc_attr_e( 'add', 'advanced-ads' ); ?></button>
163
- <span class="advads-loader" style="display: none;"></span>
164
- </div>
165
- </fieldset>
166
- <script>
167
- jQuery(document).ready(function ($) {
168
- $('#advads-display-conditions-new button').click(function () {
169
- var display_condition_type = $('#advads-display-conditions-new select').val();
170
- var display_condition_title = $('#advads-display-conditions-new select option:selected').text();
171
- var display_condition_index = parseInt($('#advads-display-conditions-index').val());
172
- if (!display_condition_type || '' == display_condition_type ){
173
- return;
174
- }
175
- $('#advads-display-conditions-new .advads-loader').show(); // show loader
176
- $('#advads-display-conditions-new button').hide(); // hide add button
177
- $.ajax({
178
- type: 'POST',
179
- url: ajaxurl,
180
- data: {
181
- action: 'load_display_conditions_metabox',
182
- type: display_condition_type,
183
- index: display_condition_index,
184
- nonce: advadsglobal.ajax_nonce
185
- },
186
- success: function (r, textStatus, XMLHttpRequest) {
187
- // add
188
- if (r) {
189
- var connector = '<input style="display:none;" type="checkbox" name="<?php echo Advanced_Ads_Display_Conditions::FORM_NAME; ?>[' + display_condition_index + '][connector]" checked="checked" value="or" id="advads-conditions-'+ display_condition_index +'-connector"><label for="advads-conditions-'+ display_condition_index +'-connector"><?php esc_attr_e( 'or', 'advanced-ads' ); ?></label>';
190
- var newline = '<tr class="advads-conditions-connector advads-conditions-connector-or"><td colspan="3">'+connector+'</td></tr><tr><td class="advads-conditions-type" data-condition-type="'+ display_condition_type +'">' + display_condition_title + '</td><td>' + r + '</td><td><button type="button" class="advads-conditions-remove button">x</button></td></tr>';
191
- $('#advads-display-conditions table tbody').append(newline);
192
- if ( jQuery.fn.advads_buttonset ) {
193
- $('#advads-display-conditions table tbody .advads-conditions-single.advads-buttonset').advads_buttonset();
194
- }
195
- if ( jQuery.fn.advads_button ) {
196
- $('#advads-display-conditions table tbody .advads-conditions-connector input').advads_button();
197
- }
198
- // increase count
199
- display_condition_index++;
200
- $('#advads-display-conditions-index').val(display_condition_index);
201
- // reset select
202
- $('#advads-display-conditions-new select')[0].selectedIndex = 0;
203
- }
204
- },
205
- error: function (MLHttpRequest, textStatus, errorThrown) {
206
- $('#advads-display-conditions-new').append(errorThrown);
207
- },
208
- complete: function( MLHttpRequest, textStatus ) {
209
- $('#advads-display-conditions-new .advads-loader').hide(); // hide loader
210
- $('#advads-display-conditions-new button').show(); // display add button
211
- }
212
- });
213
- });
214
- });
215
- </script>
216
- <?php
217
- do_action( 'advanced-ads-display-conditions-after', $ad );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/views/ad-visitor-metabox.php DELETED
@@ -1,207 +0,0 @@
1
- <?php
2
- $visitor_conditions = Advanced_Ads_Visitor_Conditions::get_instance()->get_conditions();
3
-
4
- // add mockup conditions if add-ons are missing
5
- $pro_conditions = array();
6
- if ( ! defined( 'AAP_VERSION' ) ) {
7
- $pro_conditions[] = __( 'browser language', 'advanced-ads' );
8
- $pro_conditions[] = __( 'cookie', 'advanced-ads' );
9
- $pro_conditions[] = __( 'max. ad clicks', 'advanced-ads' );
10
- $pro_conditions[] = __( 'max. ad impressions', 'advanced-ads' );
11
- $pro_conditions[] = __( 'new visitor', 'advanced-ads' );
12
- $pro_conditions[] = __( 'page impressions', 'advanced-ads' );
13
- $pro_conditions[] = __( 'referrer url', 'advanced-ads' );
14
- $pro_conditions[] = __( 'user agent', 'advanced-ads' );
15
- $pro_conditions[] = __( 'user can (capabilities)', 'advanced-ads' );
16
- $pro_conditions[] = __( 'user role', 'advanced-ads' );
17
- }
18
- if ( ! defined( 'AAGT_VERSION' ) ) {
19
- $pro_conditions[] = __( 'geo location', 'advanced-ads' );
20
- }
21
- if ( ! defined( 'AAR_VERSION' ) ) {
22
- $pro_conditions[] = __( 'browser width', 'advanced-ads' );
23
- }
24
- asort( $pro_conditions );
25
-
26
- $options = $ad->options( 'visitors' );
27
- $empty_options = ( ! is_array( $options ) || ! count( $options ) );
28
- if ( $empty_options ) :
29
- ?><div class="advads-show-in-wizard">
30
- <p><?php _e( 'Click on the button below if the ad should NOT be visible to all visitors', 'advanced-ads' ); ?></p>
31
- <button type="button" class="button button-secondary" id="advads-wizard-visitor-conditions-show"><?php _e( 'Hide the ad from some users', 'advanced-ads' ); ?></button>
32
- </div>
33
- <?php
34
- endif;
35
- ?>
36
- <div id="advads-visitor-conditions"
37
- <?php
38
- if ( $empty_options ) :
39
- ?>
40
- class="advads-hide-in-wizard"<?php endif; ?>>
41
- <p class="description"><?php _e( 'Display conditions that are based on the user. Use with caution on cached websites.', 'advanced-ads' ); ?></p>
42
- <?php
43
- // display help when no conditions are given
44
- if ( $empty_options ) :
45
- $options = array();
46
- ?>
47
- <p><a class="button button-primary" href="<?php echo ADVADS_URL; ?>manual/visitor-conditions#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor" target="_blank">
48
- <?php _e( 'Visit the manual', 'advanced-ads' ); ?>
49
- </a></p><?php endif;
50
- ?><table class="advads-conditions-table"><tbody>
51
- <?php
52
- if ( isset( $options ) ) :
53
- $i = 0;
54
- foreach ( $options as $_options ) :
55
- if ( isset( $visitor_conditions[ $_options['type'] ]['metabox'] ) ) {
56
- $metabox = $visitor_conditions[ $_options['type'] ]['metabox'];
57
- } else {
58
- continue;
59
- }
60
- $connector = ( ! isset( $_options['connector'] ) || 'or' !== $_options['connector'] ) ? 'and' : 'or';
61
- if ( method_exists( $metabox[0], $metabox[1] ) ) {
62
- if ( $i > 0 ) :
63
- ?>
64
- <tr class="advads-conditions-connector advads-conditions-connector-<?php echo $connector; ?>">
65
- <td colspan="3">
66
- <?php
67
- echo Advanced_Ads_Visitor_Conditions::render_connector_option( $i, $connector );
68
- ?>
69
- </td></tr>
70
- <?php endif; ?>
71
- <tr><td class="advads-conditions-type"><?php echo $visitor_conditions[ $_options['type'] ]['label']; ?></td><td>
72
- <?php
73
- call_user_func( array( $metabox[0], $metabox[1] ), $_options, $i++ );
74
- ?>
75
- </td><td><button type="button" class="advads-conditions-remove button">x</button></td></tr>
76
- <?php
77
- }
78
- endforeach;
79
- endif;
80
- ?>
81
- </tbody></table>
82
- <input type="hidden" id="advads-visitor-conditions-index" value="<?php echo isset( $options ) ? count( $options ) : 0; ?>"/>
83
- </div>
84
- <?php
85
- if ( $empty_options ) :
86
- ?>
87
- <p><?php _e( 'Visitor conditions limit the number of users who can see your ad. There is no need to set visitor conditions if you want all users to see the ad.', 'advanced-ads' ); ?></p>
88
- <?php
89
- elseif ( Advanced_Ads_Checks::cache() && ! defined( 'AAP_VERSION' ) ) :
90
- ?>
91
- <p><span class="advads-error-message"><?php _e( 'It seems that a caching plugin is activated.', 'advanced-ads' ); ?></span>&nbsp;
92
- <?php
93
- printf( __( 'Check out cache-busting in <a href="%s" target="_blank">Advanced Ads Pro</a> if dynamic features get cached.', 'advanced-ads' ), ADVADS_URL . 'add-ons/advanced-ads-pro/#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor' );
94
- ?>
95
- </p>
96
- <?php
97
- endif;
98
- ?>
99
- <fieldset<?php
100
- if ( $empty_options ) :
101
- ?> class="advads-hide-in-wizard"<?php endif; ?>>
102
- <legend><?php _e( 'New condition', 'advanced-ads' ); ?></legend>
103
- <div id="advads-visitor-conditions-new">
104
- <select>
105
- <option value=""><?php _e( '-- choose a condition --', 'advanced-ads' ); ?></option>
106
- <?php foreach ( $visitor_conditions as $_condition_id => $_condition ) : ?>
107
- <?php if ( empty( $_condition['disabled'] ) ) : ?>
108
- <option value="<?php echo $_condition_id; ?>"><?php echo $_condition['label']; ?></option>
109
- <?php endif; ?>
110
- <?php
111
- endforeach;
112
- if ( count( $pro_conditions ) ) :
113
- ?>
114
- <optgroup label="<?php _e( 'Add-On features', 'advanced-ads' ); ?>">
115
- <?php
116
- foreach ( $pro_conditions as $_pro_condition ) :
117
- ?>
118
- <option disabled="disabled"><?php echo $_pro_condition; ?></option>
119
- <?php
120
- endforeach;
121
- ?>
122
- </optgroup>
123
- <?php
124
- endif;
125
- ?>
126
- </select>
127
- <button type="button" class="button"><?php _e( 'add', 'advanced-ads' ); ?></button>
128
- <span class="advads-loader" style="display: none;"></span>
129
- </div>
130
- </fieldset>
131
- <?php if ( ! defined( 'AAR_SLUG' ) ) : ?>
132
- <p class="advads-hide-in-wizard"><?php printf( __( 'Define the exact browser width for which an ad should be visible using the <a href="%s" target="_blank">Responsive add-on</a>.', 'advanced-ads' ), ADVADS_URL . 'add-ons/responsive-ads/#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor' ); ?></p>
133
- <?php
134
- endif;
135
- ?>
136
- <script>
137
- jQuery( document ).ready(function ($) {
138
- $('#advads-visitor-conditions-new button').click(function(){
139
- var visitor_condition_type = $('#advads-visitor-conditions-new select').val();
140
- var visitor_condition_title = $('#advads-visitor-conditions-new select option:selected').text();
141
- var visitor_condition_index = parseInt( $('#advads-visitor-conditions-index').val() );
142
- if( ! visitor_condition_type ) return;
143
- $('#advads-visitor-conditions-new .advads-loader').show();
144
- $('#advads-visitor-conditions-new button').hide();
145
-
146
- $.ajax({
147
- type: 'POST',
148
- url: ajaxurl,
149
- data: {
150
- action: 'load_visitor_conditions_metabox',
151
- type: visitor_condition_type,
152
- index: visitor_condition_index,
153
- nonce: advadsglobal.ajax_nonce
154
- },
155
- success: function (r, textStatus, XMLHttpRequest) {
156
- // add
157
- if (r) {
158
- var connector = '<input type="checkbox" name="<?php echo Advanced_Ads_Visitor_Conditions::FORM_NAME; ?>[' + visitor_condition_index + '][connector]" value="or" id="advads-visitor-conditions-'+ visitor_condition_index +'-connector"><label for="advads-visitor-conditions-'+ visitor_condition_index +'-connector"><?php _e( 'and', 'advanced-ads' ); ?></label>';
159
- var newline = '<tr class="advads-conditions-connector advads-conditions-connector-and"><td colspan="3">'+connector+'</td></tr><tr><td>' + visitor_condition_title + '</td><td>' + r + '</td><td><button type="button" class="advads-conditions-remove button">x</button></td></tr>';
160
- $( '#advads-visitor-conditions table tbody' ).append( newline );
161
- if ( jQuery.fn.advads_buttonset ) { // only used in Pro right now
162
- $('#advads-visitor-conditions table tbody .advads-conditions-single.advads-buttonset').advads_buttonset();
163
- }
164
- if ( jQuery.fn.advads_button ) {
165
- $('#advads-visitor-conditions table tbody .advads-conditions-connector input').advads_button();
166
- }
167
- // increase count
168
- visitor_condition_index++;
169
- $('#advads-visitor-conditions-index').val( visitor_condition_index );
170
- $('#advads-visitor-conditions-new .advads-loader').hide();
171
- }
172
- },
173
- error: function (MLHttpRequest, textStatus, errorThrown) {
174
- $( '#advads-visitor-conditions-new' ).append( errorThrown );
175
- $('#advads-visitor-conditions-new .advads-loader').hide();
176
- },
177
- complete: function( MLHttpRequest, textStatus ) {
178
- $('#advads-visitor-conditions-new .advads-loader').hide(); // hide loader
179
- $('#advads-visitor-conditions-new button').show(); // display add button
180
- }
181
- });
182
- });
183
- });
184
- </script>
185
- <?php
186
- $options = $ad->options( 'visitor' );
187
- if ( isset( $options['mobile'] ) && '' !== $options['mobile'] ) :
188
- ?>
189
- <p style="color: red;"><?php _e( 'The visitor conditions below are deprecated. Please use the new version of visitor conditions to replace it.', 'advanced-ads' ); ?></p>
190
- <ul id="advanced-ad-visitor-mobile">
191
- <li>
192
- <input type="radio" name="advanced_ad[visitor][mobile]"
193
- id="advanced-ad-visitor-mobile-all" value=""
194
- <?php checked( empty( $options['mobile'] ), 1 ); ?>/>
195
- <label for="advanced-ad-visitor-mobile-all"><?php _e( 'Display on all devices', 'advanced-ads' ); ?></label>
196
- <input type="radio" name="advanced_ad[visitor][mobile]"
197
- id="advanced-ad-visitor-mobile-only" value="only"
198
- <?php checked( $options['mobile'], 'only' ); ?>/>
199
- <label for="advanced-ad-visitor-mobile-only"><?php _e( 'only on mobile devices', 'advanced-ads' ); ?></label>
200
- <input type="radio" name="advanced_ad[visitor][mobile]"
201
- id="advanced-ad-visitor-mobile-no" value="no"
202
- <?php checked( $options['mobile'], 'no' ); ?>/>
203
- <label for="advanced-ad-visitor-mobile-no"><?php _e( 'not on mobile devices', 'advanced-ads' ); ?></label>
204
- </li>
205
- </ul>
206
- <?php endif; ?>
207
- <?php do_action( 'advanced-ads-visitor-conditions-after', $ad ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/views/conditions/ad-display-metabox.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Render meta box for Display Conditions on ad edit page
4
+ *
5
+ * @package Advanced_Ads_Admin
6
+ * @author Thomas Maier <thomas.maier@webgilde.com>
7
+ * @license GPL-2.0+
8
+ * @link https://wpadvancedads.com
9
+ * @copyright since 2013 Thomas Maier, webgilde GmbH
10
+ */
11
+
12
+ $set_conditions = $ad->options( 'conditions' );
13
+ $empty_options = ( ! is_array( $set_conditions ) || ! count( $set_conditions ) );
14
+ if ( $empty_options ) :
15
+ ?>
16
+ <div class="advads-show-in-wizard">
17
+ <p><?php esc_attr_e( 'Click on the button below if the ad should NOT show up on all pages when included automatically.', 'advanced-ads' ); ?></p>
18
+ <button type="button" class="button button-secondary"
19
+ id="advads-wizard-display-conditions-show"><?php esc_attr_e( 'Hide the ad on some pages', 'advanced-ads' ); ?></button>
20
+ </div>
21
+ <?php endif; ?>
22
+ <div id="advads-display-conditions"
23
+ <?php
24
+ if ( $empty_options ) :
25
+ ?>
26
+ class="advads-hide-in-wizard"<?php endif; ?>>
27
+ <?php
28
+ // display help when no conditions are given.
29
+ if ( $empty_options ) :
30
+ $set_conditions = array();
31
+ ?>
32
+ <p>
33
+ <button type="button" class="advads-video-link-inline button button-primary">
34
+ <?php esc_attr_e( 'Watch video', 'advanced-ads' ); ?>
35
+ </button>&nbsp;<a class="button button-secondary"
36
+ href="<?php echo ADVADS_URL; ?>manual/display-conditions#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-display"
37
+ target="_blank">
38
+ <?php esc_attr_e( 'Visit the manual', 'advanced-ads' ); ?>
39
+ </a></p>
40
+ <?php
41
+ endif;
42
+ ?>
43
+ <p class="advads-jqueryui-error advads-error-message hidden">
44
+ <?php
45
+ // translators: %s is a link to a tutorial.
46
+ printf( __( 'There might be a problem with layouts and scripts in your dashboard. Please check <a href="%s" target="_blank">this article to learn more</a>.', 'advanced-ads' ), ADVADS_URL . 'manual/jquery-problem-in-dashboard/#utm_source=advanced-ads&utm_medium=link&utm_campaign=notice-jquery-error' ); ?></p>
47
+ <p><?php esc_attr_e( 'A page with this ad on it must match all of the following conditions.', 'advanced-ads' ); ?></p>
48
+ <?php
49
+ $conditions_list_target = 'advads-ad-display-conditions';
50
+ Advanced_Ads_Display_Conditions::render_condition_list( $set_conditions, $conditions_list_target );
51
+ ?></div><?php
52
+ do_action( 'advanced-ads-display-conditions-after', $ad );
admin/views/conditions/ad-visitor-metabox.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Render meta box for Visitor Conditions on ad edit page
4
+ *
5
+ * @package Advanced_Ads_Admin
6
+ * @author Thomas Maier <thomas.maier@webgilde.com>
7
+ * @license GPL-2.0+
8
+ * @link https://wpadvancedads.com
9
+ * @copyright since 2013 Thomas Maier, webgilde GmbH
10
+ */
11
+
12
+ $set_conditions = $ad->options( 'visitors' );
13
+ $empty_options = ( ! is_array( $set_conditions ) || ! count( $set_conditions ) );
14
+ if ( $empty_options ) :
15
+ ?>
16
+ <div class="advads-show-in-wizard">
17
+ <p><?php _e( 'Click on the button below if the ad should NOT be visible to all visitors', 'advanced-ads' ); ?></p>
18
+ <button type="button" class="button button-secondary"
19
+ id="advads-wizard-visitor-conditions-show"><?php _e( 'Hide the ad from some users', 'advanced-ads' ); ?></button>
20
+ </div>
21
+ <?php
22
+ endif;
23
+ ?>
24
+ <div id="advads-visitor-conditions"
25
+ <?php
26
+ if ( $empty_options ) :
27
+ ?>
28
+ class="advads-hide-in-wizard"<?php endif; ?>>
29
+ <p class="description"><?php _e( 'Display conditions that are based on the user. Use with caution on cached websites.', 'advanced-ads' ); ?></p>
30
+ <?php
31
+ // display help when no conditions are given
32
+ if ( $empty_options ) :
33
+ $set_conditions = array();
34
+ ?>
35
+ <p><a class="button button-primary"
36
+ href="<?php echo ADVADS_URL; ?>manual/visitor-conditions#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor"
37
+ target="_blank">
38
+ <?php _e( 'Visit the manual', 'advanced-ads' ); ?>
39
+ </a></p><?php endif;
40
+ $conditions_list_target = 'advads-ad-visitor-conditions';
41
+ Advanced_Ads_Visitor_Conditions::render_condition_list( $set_conditions, $conditions_list_target );
42
+ ?></div><?php
43
+ do_action( 'advanced-ads-visitor-conditions-after', $ad ); ?>
admin/views/conditions/condition-author.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="advads-conditions-single advads-buttonset">
2
+ <?php foreach ( $authors as $_author ) {
3
+ // don’t use strict comparasion because $values contains strings.
4
+ if ( in_array( $_author->ID, $values ) ) {
5
+ $_val = 1;
6
+ } else {
7
+ $_val = 0;
8
+ }
9
+ $author_name = $_author->display_name;
10
+ ?><label class="button ui-button"
11
+ for="advads-conditions-<?php echo absint( $index ); ?>-<?php echo absint( $_author->ID ); ?>">
12
+ <?php echo esc_attr( $author_name ); ?>
13
+ </label><input type="checkbox"
14
+ id="advads-conditions-<?php echo absint( $index ); ?>-<?php echo absint( $_author->ID ); ?>"
15
+ name="<?php echo $name; ?>[value][]" <?php checked( $_val, 1 ); ?>
16
+ value="<?php echo absint( $_author->ID ); ?>"><?php
17
+ }
18
+ ?>
19
+ <p class="advads-conditions-not-selected advads-error-message"><?php esc_html_x( 'Please select some items.', 'Error message shown when no display condition term is selected', 'advanced-ads' ); ?></p>
20
+ </div>
21
+ <?php
22
+ if ( count( $authors ) >= $max_authors ) :
23
+ ?>
24
+ <p class="advads-error-message">
25
+ <?php
26
+ printf( // translators: %d is the number of elements in the list and %s a URL.
27
+ __( 'Only %d elements are displayed above. Use the <code>advanced-ads-admin-max-terms</code> filter to change this limit according to <a href="%s" target="_blank">this page</a>.', 'advanced-ads' ),
28
+ absint( $max_authors ),
29
+ esc_url( ADVADS_URL . 'codex/filter-hooks//#utm_source=advanced-ads&utm_medium=link&utm_campaign=author-term-limit' )
30
+ );
31
+ ?>
32
+ </p>
33
+ <?php
34
+ endif;
admin/views/conditions/condition-device.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
2
+ <select name="<?php echo $name; ?>[operator]">
3
+ <option value="is" <?php selected( 'is', $operator ); ?>><?php _e( 'Mobile (including tablets)', 'advanced-ads' ); ?></option>
4
+ <option value="is_not" <?php selected( 'is_not', $operator ); ?>><?php _e( 'Desktop', 'advanced-ads' ); ?></option>
5
+ </select>
6
+ <p class="description"><?php echo $type_options[ $options['type'] ]['description'];
7
+ if ( isset( $type_options[ $options['type'] ]['helplink'] ) ) : ?>
8
+ <a href="<?php echo $type_options[ $options['type'] ]['helplink']; ?>" target="_blank"><?php
9
+ _e( 'Manual and Troubleshooting', 'advanced-ads' );
10
+ ?></a><?php endif; ?></p>
admin/views/conditions/condition-is-or-not.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
2
+ <select name="<?php echo $name; ?>[operator]">
3
+ <option value="is" <?php selected( 'is', $operator ); ?>><?php _e( 'is', 'advanced-ads' ); ?></option>
4
+ <option value="is_not" <?php selected( 'is_not', $operator ); ?>><?php _e( 'is not', 'advanced-ads' ); ?></option>
5
+ </select>
6
+ <p class="description"><?php echo $type_options[ $options['type'] ]['description'];
7
+ if ( isset( $type_options[ $options['type'] ]['helplink'] ) ) : ?>
8
+ <a href="<?php echo $type_options[ $options['type'] ]['helplink']; ?>" target="_blank"><?php
9
+ _e( 'Manual and Troubleshooting', 'advanced-ads' );
10
+ ?></a><?php endif; ?></p>
admin/views/conditions/condition-number.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
2
+ <select name="<?php echo $name; ?>[operator]">
3
+ <option value="is_equal" <?php selected( 'is_equal', $operator ); ?>><?php _e( 'equal', 'advanced-ads' ); ?></option>
4
+ <option value="is_higher" <?php selected( 'is_higher', $operator ); ?>><?php _e( 'equal or higher', 'advanced-ads' ); ?></option>
5
+ <option value="is_lower" <?php selected( 'is_lower', $operator ); ?>><?php _e( 'equal or lower', 'advanced-ads' ); ?></option>
6
+ </select><input type="number" name="<?php echo $name; ?>[value]" value="<?php echo absint( $value ); ?>"/>
7
+ <p class="description"><?php echo $type_options[ $options['type'] ]['description']; ?></p>
admin/views/conditions/condition-operator.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <select name="<?php echo $name; ?>[operator]">
2
+ <option value="is" <?php selected( 'is', $operator ); ?>><?php esc_attr_e( 'is', 'advanced-ads' ); ?></option>
3
+ <option value="is_not" <?php selected( 'is_not', $operator ); ?>><?php esc_attr_e( 'is not', 'advanced-ads' ); ?></option>
4
+ </select>
admin/views/conditions/condition-string.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
2
+ <div class="advads-condition-line-wrap">
3
+ <?php include( ADVADS_BASE_PATH . 'admin/views/ad-conditions-string-operators.php' ); ?>
4
+ <input type="text" name="<?php echo $name; ?>[value]" value="<?php echo $value; ?>"/>
5
+ </div>
6
+ <p class="description"><?php echo $type_options[ $options['type'] ]['description']; ?></p>
admin/views/conditions/conditions-form.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <fieldset data-condition-list-target="<?php echo $list_target; ?>"
2
+ data-condition-form-name="<?php echo $form_name; ?>"
3
+ data-condition-action="<?php echo $action; ?>"
4
+ data-condition-connector-default="<?php echo $connector_default; ?>"
5
+ <?php
6
+ if ( $empty_options ) :
7
+ ?> class="advads-hide-in-wizard"<?php endif; ?>>
8
+ <legend><?php esc_attr_e( 'New condition', 'advanced-ads' ); ?></legend>
9
+ <input type="hidden" class="advads-conditions-index"
10
+ value="<?php echo is_array( $set_conditions ) ? count( $set_conditions ) : 0; ?>"/>
11
+ <div class="advads-conditions-new">
12
+ <select>
13
+ <option value=""><?php esc_attr_e( '-- choose a condition --', 'advanced-ads' ); ?></option>
14
+ <?php foreach ( $conditions as $_condition_id => $_condition ) : ?>
15
+ <?php if ( empty( $_condition['disabled'] ) ) : ?>
16
+ <option value="<?php echo $_condition_id; ?>"><?php echo $_condition['label']; ?></option>
17
+ <?php endif; ?>
18
+ <?php
19
+ endforeach;
20
+ if ( isset( $pro_conditions ) && count( $pro_conditions ) ) :
21
+ ?>
22
+ <optgroup label="<?php esc_attr_e( 'Add-On features', 'advanced-ads' ); ?>">
23
+ <?php
24
+ foreach ( $pro_conditions as $_pro_condition ) :
25
+ ?>
26
+ <option disabled="disabled"><?php echo $_pro_condition; ?></option>
27
+ <?php
28
+ endforeach;
29
+ ?>
30
+ </optgroup>
31
+ <?php
32
+ endif;
33
+ ?>
34
+ </select>
35
+ <button type="button" class="button"><?php esc_attr_e( 'add', 'advanced-ads' ); ?></button>
36
+ <span class="advads-loader" style="display: none;"></span>
37
+ </div>
38
+ </fieldset>
admin/views/conditions/display-conditions-form-top.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php $empty_options = ( ! is_array( $set_conditions ) || ! count( $set_conditions ) );
2
+ if ( $empty_options ) :
3
+ ?>
4
+ <p><?php esc_attr_e( 'If you want to display the ad everywhere, don\'t do anything here. ', 'advanced-ads' ); ?></p>
5
+ <?php
6
+ endif;
admin/views/conditions/display-conditions-list.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table id="<?php echo $list_target; ?>" class="advads-conditions-table">
2
+ <tbody>
3
+ <?php
4
+ $last_index = - 1;
5
+ $i = 0;
6
+ if ( is_array( $set_conditions ) ) :
7
+ foreach ( $set_conditions as $_index => $_options ) :
8
+ $show_or_force_warning = false;
9
+ // get type attribute from previous option format.
10
+ $_options['type'] = isset( $_options['type'] ) ? $_options['type'] : $_index;
11
+ $connector = ( ! isset( $_options['connector'] ) || 'or' !== $_options['connector'] ) ? 'and' : 'or';
12
+ if ( isset( $_options['type'] ) && isset( $conditions[ $_options['type'] ]['metabox'] ) ) {
13
+ $metabox = $conditions[ $_options['type'] ]['metabox'];
14
+ } else {
15
+ continue;
16
+ }
17
+ if ( method_exists( $metabox[0], $metabox[1] ) ) {
18
+ /**
19
+ * Show warning for connector when
20
+ * not set to OR already
21
+ * this condition and the previous are on page level and not from the identical type
22
+ * they are both set to SHOW
23
+ */
24
+ $tax = ( isset( $_options['type'] ) && isset( $conditions[ $_options['type'] ]['taxonomy'] ) ) ? $conditions[ $_options['type'] ]['taxonomy'] : false;
25
+ $last_tax = ( isset( $set_conditions[ $last_index ]['type'] ) && isset( $conditions[ $set_conditions[ $last_index ]['type'] ]['taxonomy'] ) ) ? $conditions[ $set_conditions[ $last_index ]['type'] ]['taxonomy'] : false;
26
+ if ( $tax && $last_tax && $last_tax === $tax
27
+ && ( ! isset( $_options['connector'] ) || 'or' !== $_options['connector'] )
28
+ && 'is' === $_options['operator'] && 'is' === $set_conditions[ $last_index ]['operator']
29
+ && $_options['type'] !== $set_conditions[ $last_index ]['type'] ) {
30
+
31
+ $show_or_force_warning = true;
32
+ }
33
+
34
+ if ( $i > 0 ) :
35
+
36
+ ?>
37
+ <tr class="advads-conditions-connector advads-conditions-connector-<?php echo $connector; ?>">
38
+ <td colspan="3">
39
+ <?php
40
+ echo Advanced_Ads_Display_Conditions::render_connector_option( $i, $connector, $form_name );
41
+ if ( $show_or_force_warning ) {
42
+ ?>
43
+ <p class="advads-error-message">
44
+ <?php
45
+ esc_attr_e( 'Forced to OR.', 'advanced-ads' );
46
+ echo '&nbsp;<a target="_blank" href="' . ADVADS_URL . 'manual/display-conditions#manual-combining-multiple-conditions' . '">' . esc_attr__( 'manual', 'advanced-ads' ) . '</a>';
47
+ ?>
48
+ </p>
49
+ <?php
50
+
51
+ }
52
+ ?>
53
+ </td>
54
+ </tr><?php endif; ?>
55
+ <tr>
56
+ <td class="advads-conditions-type"
57
+ data-condition-type="<?php echo $_options['type']; ?>"><?php echo $conditions[ $_options['type'] ]['label']; ?></td>
58
+ <td>
59
+ <?php
60
+ call_user_func( array( $metabox[0], $metabox[1] ), $_options, $i ++, $form_name );
61
+ ?>
62
+ </td>
63
+ <td>
64
+ <button type="button" class="advads-conditions-remove button">x</button>
65
+ </td>
66
+ </tr>
67
+ <?php
68
+ }
69
+ $last_index = $_index;
70
+ endforeach;
71
+ endif;
72
+ ?>
73
+ </tbody>
74
+ </table>
admin/views/conditions/visitor-conditions-form-top.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php $empty_options = ( ! is_array( $set_conditions ) || ! count( $set_conditions ) );
2
+ if ( $empty_options ) :
3
+ ?>
4
+ <p><?php _e( 'Visitor conditions limit the number of users who can see your ad. There is no need to set visitor conditions if you want all users to see the ad.', 'advanced-ads' ); ?></p>
5
+ <?php
6
+ elseif ( Advanced_Ads_Checks::cache() && ! defined( 'AAP_VERSION' ) ) :
7
+ ?>
8
+ <p>
9
+ <span class="advads-error-message"><?php _e( 'It seems that a caching plugin is activated.', 'advanced-ads' ); ?></span>&nbsp;
10
+ <?php
11
+ printf( __( 'Check out cache-busting in <a href="%s" target="_blank">Advanced Ads Pro</a> if dynamic features get cached.', 'advanced-ads' ), ADVADS_URL . 'add-ons/advanced-ads-pro/#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor' );
12
+ ?>
13
+ </p>
14
+ <?php
15
+ endif;
admin/views/conditions/visitor-conditions-list.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table id="<?php echo $list_target; ?>" class="advads-conditions-table">
2
+ <tbody>
3
+ <?php
4
+ if ( isset( $set_conditions ) ) :
5
+ $i = 0;
6
+ foreach ( $set_conditions as $_options ) :
7
+ if ( isset( $conditions[ $_options['type'] ]['metabox'] ) ) {
8
+ $metabox = $conditions[ $_options['type'] ]['metabox'];
9
+ } else {
10
+ continue;
11
+ }
12
+ $connector = ( ! isset( $_options['connector'] ) || 'or' !== $_options['connector'] ) ? 'and' : 'or';
13
+ if ( method_exists( $metabox[0], $metabox[1] ) ) {
14
+ if ( $i > 0 ) :
15
+ ?>
16
+ <tr class="advads-conditions-connector advads-conditions-connector-<?php echo $connector; ?>">
17
+ <td colspan="3">
18
+ <?php
19
+ echo Advanced_Ads_Visitor_Conditions::render_connector_option( $i, $connector, $form_name );
20
+ ?>
21
+ </td>
22
+ </tr>
23
+ <?php endif; ?>
24
+ <tr>
25
+ <td class="advads-conditions-type"><?php echo $conditions[ $_options['type'] ]['label']; ?></td>
26
+ <td>
27
+ <?php
28
+ call_user_func( array( $metabox[0], $metabox[1] ), $_options, $i ++, $form_name );
29
+ ?>
30
+ </td>
31
+ <td>
32
+ <button type="button" class="advads-conditions-remove button">x</button>
33
+ </td>
34
+ </tr>
35
+ <?php
36
+ }
37
+ endforeach;
38
+ endif;
39
+ ?>
40
+ </tbody>
41
+ </table>
admin/views/notices/starter-setup-success.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="notice notice-success advads-admin-notice message">
2
+ <h2><?php esc_attr_e( '2 Test Ads successfully added!', 'advanced-ads' ); ?></h2>
3
+ <p><?php esc_attr_e( 'Look below for the list of created ads.', 'advanced-ads' ); ?></p>
4
+ <p>
5
+ <a href="<?php esc_attr_e( admin_url( 'admin.php?page=advanced-ads-placements' ) ); ?>"><?php esc_attr_e( 'Visit list of placements', 'advanced-ads' ); ?></a>
6
+ </p>
7
+ <?php if ( $last_post_link ) : ?>
8
+ <p>
9
+ <a href="<?php echo esc_url( $last_post_link ); ?>" target="_blank"><?php esc_attr_e( 'See them in action', 'advanced-ads' ); ?></a>
10
+ </p>
11
+ <?php endif; ?>
12
+ </div>
admin/views/notices/welcome-panel.php CHANGED
@@ -1,27 +1,72 @@
 
 
 
 
 
 
 
 
1
  <div id="aa-welcome-panel">
2
- <h2><?php _e( 'Welcome to Advanced Ads!', 'advanced-ads' ); ?></h2>
3
- <div class="aa-welcome-panel-column-container">
4
- <div class="aa-welcome-panel-column">
5
- <h3><?php _e( 'Get Started', 'advanced-ads' ); ?></h3>
6
- <a href="<?php echo admin_url( 'post-new.php?post_type=advanced_ads' ); ?>" class="button button-primary"><?php _e( 'Create your first ad', 'advanced-ads' ); ?></a>
7
- <ul>
8
- <li><a href="<?php echo ADVADS_URL . 'manual/first-ad/#utm_source=advanced-ads&utm_medium=link&utm_campaign=welcome-first-ad'; ?>" target="_blank"><?php _e( 'First ad tutorial', 'advanced-ads' ); ?></a></li>
9
- </ul>
10
- </div>
11
- <div class="aa-welcome-panel-column">
12
- <h3><?php _e( 'AdSense Options', 'advanced-ads' ); ?></h3>
13
- <a href="<?php echo admin_url( 'admin.php?page=advanced-ads-settings#top#adsense' ); ?>" class="button button-primary"><?php _e( 'Import ads from AdSense', 'advanced-ads' ); ?></a>
14
- <ul>
15
- <li><a href="<?php echo ADVADS_URL . 'adsense-auto-ads-wordpress/#utm_source=advanced-ads&utm_medium=link&utm_campaign=welcome-auto-ads'; ?>" target="_blank"><?php _e( 'Setting up Auto ads', 'advanced-ads' ); ?></a></li>
16
- <li><a href="<?php echo ADVADS_URL . 'place-adsense-ad-unit-manually/#utm_source=advanced-ads&utm_medium=link&utm_campaign=welcome-adsense'; ?>" target="_blank"><?php _e( 'Setting up AdSense ads manually', 'advanced-ads' ); ?></a></li>
17
- </ul>
18
- </div>
19
- <div class="aa-welcome-panel-column aa-welcome-panel-last">
20
- <h3><?php _e( 'Get help', 'advanced-ads' ); ?></h3>
21
- <ul>
22
- <li><?php printf( __( '<a href="%s" target="_blank">Manual</a>', 'advanced-ads' ), ADVADS_URL . 'manual/#utm_source=advanced-ads&utm_medium=link&utm_campaign=welcome-manual' ); ?></li>
23
- <li><a href="<?php echo ADVADS_URL . 'support/#utm_source=advanced-ads&utm_medium=link&utm_campaign=welcome-support'; ?>" target="_blank"><?php _e( 'Reach out for help', 'advanced-ads' ); ?></a></li>
24
- </ul>
25
- </div>
26
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  </div>
1
+ <?php $number_of_ads = 0;
2
+ // needed error handling due to a weird bug in the piklist plugin.
3
+ try {
4
+ $number_of_ads = Advanced_Ads::get_number_of_ads();
5
+ } catch ( Exception $e ) {
6
+ // no need to catch anything since we just use TRY/CATCH to prevent an issue caused by another plugin.
7
+ }
8
+ ?>
9
  <div id="aa-welcome-panel">
10
+ <h2><?php esc_attr_e( 'Welcome to Advanced Ads!', 'advanced-ads' ); ?></h2>
11
+ <div class="aa-welcome-panel-column-container">
12
+ <div class="aa-welcome-panel-column">
13
+ <h3><?php esc_attr_e( 'Get Started', 'advanced-ads' ); ?></h3>
14
+ <a href="<?php echo esc_url( admin_url( 'post-new.php?post_type=advanced_ads' ) ); ?>"
15
+ class="button button-primary"><?php esc_attr_e( 'Create your first ad', 'advanced-ads' ); ?></a>
16
+ <ul>
17
+ <li>
18
+ <a href="<?php echo esc_url( ADVADS_URL ); ?>manual/first-ad/#utm_source=advanced-ads&utm_medium=link&utm_campaign=welcome-first-ad"
19
+ target="_blank"><?php esc_attr_e( 'First ad tutorial', 'advanced-ads' ); ?></a></li>
20
+ </ul>
21
+ </div>
22
+ <?php
23
+ $options = Advanced_Ads_Plugin::get_instance()->internal_options();
24
+ $installed = isset( $options['installed'] ) ? $options['installed'] : 0;
25
+ $showed_basic_setup = false;
26
+ if ( ! $number_of_ads && Advanced_Ads_Plugin::get_group_by_url( null, 'a' ) && $installed > 1573128000 ) :
27
+ $showed_basic_setup = true;
28
+ ?>
29
+ <div class="aa-welcome-panel-column aa-welcome-panel-starter-setup aa-welcome-panel-last">
30
+ <h3><?php esc_attr_e( 'One-Click Setup', 'advanced-ads' ); ?></h3>
31
+ <?php
32
+ // generate link to basic setup.
33
+ $basic_setup_action = '?action=advanced_ads_starter_setup';
34
+ $basic_setup_url = wp_nonce_url( admin_url( $basic_setup_action ), 'advanced-ads-starter-setup' );
35
+ ?>
36
+ <a href="<?php echo esc_url( $basic_setup_url ); ?>"
37
+ class="button button-primary"><?php esc_attr_e( 'Create 2 test ads', 'advanced-ads' ); ?></a>
38
+ <p class="description"><?php esc_attr_e( 'Click to place two ads in the content of your site which are visible to you only.', 'advanced-ads' ); ?></p>
39
+ </div>
40
+ <?php endif; ?>
41
+ <div class="aa-welcome-panel-column">
42
+ <h3><?php esc_attr_e( 'AdSense Options', 'advanced-ads' ); ?></h3>
43
+ <a href="<?php echo esc_url( admin_url( 'admin.php?page=advanced-ads-settings#top#adsense' ) ); ?>"
44
+ class="button button-primary"><?php esc_attr_e( 'Import ads from AdSense', 'advanced-ads' ); ?></a>
45
+ <ul>
46
+ <li>
47
+ <a href="<?php echo esc_url( ADVADS_URL ); ?>adsense-auto-ads-wordpress/#utm_source=advanced-ads&utm_medium=link&utm_campaign=welcome-auto-ads"
48
+ target="_blank"><?php esc_attr_e( 'Setting up Auto ads', 'advanced-ads' ); ?></a></li>
49
+ <li>
50
+ <a href="<?php echo esc_url( ADVADS_URL ); ?>place-adsense-ad-unit-manually/#utm_source=advanced-ads&utm_medium=link&utm_campaign=welcome-adsense"
51
+ target="_blank"><?php esc_attr_e( 'Setting up AdSense ads manually', 'advanced-ads' ); ?></a>
52
+ </li>
53
+ </ul>
54
+ </div>
55
+ <?php
56
+ if ( ! $showed_basic_setup ) :
57
+ ?>
58
+ <div class="aa-welcome-panel-column aa-welcome-panel-last">
59
+ <h3><?php esc_attr_e( 'Get help', 'advanced-ads' ); ?></h3>
60
+ <ul>
61
+ <li>
62
+ <a href="<?php echo esc_url( ADVADS_URL ); ?>manual/#utm_source=advanced-ads&utm_medium=link&utm_campaign=welcome-manual"
63
+ target="_blank"><?php esc_attr_e( 'Manual', 'advanced-ads' ); ?></a>
64
+ </li>
65
+ <li>
66
+ <a href="<?php echo esc_url( ADVADS_URL ); ?>support/#utm_source=advanced-ads&utm_medium=link&utm_campaign=welcome-support"
67
+ target="_blank"><?php esc_attr_e( 'Reach out for help', 'advanced-ads' ); ?></a></li>
68
+ </ul>
69
+ </div>
70
+ <?php endif; ?>
71
+ </div>
72
  </div>
advanced-ads.php CHANGED
@@ -12,7 +12,7 @@
12
  * Plugin Name: Advanced Ads
13
  * Plugin URI: https://wpadvancedads.com
14
  * Description: Manage and optimize your ads in WordPress
15
- * Version: 1.14.11
16
  * Author: Thomas Maier
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.14.11' );
43
 
44
  /*----------------------------------------------------------------------------*
45
  * Autoloading, modules and functions
12
  * Plugin Name: Advanced Ads
13
  * Plugin URI: https://wpadvancedads.com
14
  * Description: Manage and optimize your ads in WordPress
15
+ * Version: 1.15
16
  * Author: Thomas Maier
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.15' );
43
 
44
  /*----------------------------------------------------------------------------*
45
  * Autoloading, modules and functions
classes/EDD_SL_Plugin_Updater.php CHANGED
@@ -476,7 +476,7 @@ class ADVADS_SL_Plugin_Updater {
476
  }
477
 
478
  if( ! current_user_can( 'update_plugins' ) ) {
479
- wp_die( __( 'You do not have permission to install plugin updates', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
480
  }
481
 
482
  $data = $edd_plugin_data[ $_REQUEST['slug'] ];
476
  }
477
 
478
  if( ! current_user_can( 'update_plugins' ) ) {
479
+ wp_die( __( 'You do not have permission to install plugin updates', 'advanced-ads' ), __( 'Error', 'advanced-ads' ), array( 'response' => 403 ) );
480
  }
481
 
482
  $data = $edd_plugin_data[ $_REQUEST['slug'] ];
classes/ad-ajax.php CHANGED
@@ -103,7 +103,8 @@ class Advanced_Ads_Ajax {
103
  $content = $selector->get_ad_by_method( $id, $method, $arguments );
104
  $adIds = array_slice( $advads->current_ads, $l ); // ads loaded by this request
105
 
106
- return array( 'status' => 'success', 'item' => $content, 'id' => $id, 'method' => $method, 'ads' => $adIds, 'blog_id' => get_current_blog_id() );
 
107
  } else {
108
  // report error
109
  return array( 'status' => 'error', 'message' => 'No valid ID or METHOD found.' );
103
  $content = $selector->get_ad_by_method( $id, $method, $arguments );
104
  $adIds = array_slice( $advads->current_ads, $l ); // ads loaded by this request
105
 
106
+ $r = array( 'status' => 'success', 'item' => $content, 'id' => $id, 'method' => $method, 'ads' => $adIds, 'blog_id' => get_current_blog_id() );
107
+ return apply_filters( 'advanced-ads-cache-busting-item', $r, array( 'id' => $id, 'method' => $method, 'args' => $arguments ) );
108
  } else {
109
  // report error
110
  return array( 'status' => 'error', 'message' => 'No valid ID or METHOD found.' );
classes/ad.php CHANGED
@@ -504,6 +504,23 @@ class Advanced_Ads_Ad {
504
  update_post_meta( $this->id, self::$options_meta_field, $options );
505
  }
506
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
507
  /**
508
  * native filter for content field before being saved
509
  *
504
  update_post_meta( $this->id, self::$options_meta_field, $options );
505
  }
506
 
507
+ /**
508
+ * Save ad options.
509
+ * Meant to be used from the outside of an ad.
510
+ *
511
+ * @param int $ad_id post ID of the ad.
512
+ * @param array $options ad options.
513
+ */
514
+ public static function save_ad_options( $ad_id, array $options ) {
515
+
516
+ // don’t allow to clear options by accident.
517
+ if ( array() === $options ) {
518
+ return;
519
+ }
520
+
521
+ update_post_meta( $ad_id, sefl::$options_meta_field, $options );
522
+ }
523
+
524
  /**
525
  * native filter for content field before being saved
526
  *
classes/ad_ajax_callbacks.php CHANGED
@@ -97,6 +97,8 @@ class Advanced_Ads_Ad_Ajax_Callbacks {
97
  $condition['type'] = isset( $_POST['type'] ) ? $_POST['type'] : '';
98
  $index = isset( $_POST['index'] ) ? $_POST['index'] : 0;
99
 
 
 
100
  if( isset( $visitor_conditions[$condition['type']] ) ) {
101
  $metabox = $visitor_conditions[$condition['type']]['metabox'];
102
  } else {
@@ -104,7 +106,7 @@ class Advanced_Ads_Ad_Ajax_Callbacks {
104
  }
105
 
106
  if ( method_exists( $metabox[0], $metabox[1] ) ) {
107
- call_user_func( array($metabox[0], $metabox[1]), $condition, $index );
108
  }
109
 
110
  die();
@@ -125,11 +127,11 @@ class Advanced_Ads_Ad_Ajax_Callbacks {
125
  // get display condition types
126
  $conditions = Advanced_Ads_Display_Conditions::get_instance()->conditions;
127
  $condition = array();
128
-
129
  $condition['type'] = isset( $_POST['type'] ) ? $_POST['type'] : '';
130
-
131
  $index = isset( $_POST['index'] ) ? $_POST['index'] : 0;
132
 
 
 
133
  if( isset( $conditions[$condition['type']] ) ) {
134
  $metabox = $conditions[$condition['type']]['metabox'];
135
  } else {
@@ -137,7 +139,7 @@ class Advanced_Ads_Ad_Ajax_Callbacks {
137
  }
138
 
139
  if ( method_exists( $metabox[0], $metabox[1] ) ) {
140
- call_user_func( array($metabox[0], $metabox[1]), $condition, $index );
141
  }
142
 
143
  die();
97
  $condition['type'] = isset( $_POST['type'] ) ? $_POST['type'] : '';
98
  $index = isset( $_POST['index'] ) ? $_POST['index'] : 0;
99
 
100
+ $form_name = isset( $_POST['form_name'] ) ? $_POST['form_name'] : Advanced_Ads_Visitor_Conditions::FORM_NAME;
101
+
102
  if( isset( $visitor_conditions[$condition['type']] ) ) {
103
  $metabox = $visitor_conditions[$condition['type']]['metabox'];
104
  } else {
106
  }
107
 
108
  if ( method_exists( $metabox[0], $metabox[1] ) ) {
109
+ call_user_func( array($metabox[0], $metabox[1]), $condition, $index, $form_name );
110
  }
111
 
112
  die();
127
  // get display condition types
128
  $conditions = Advanced_Ads_Display_Conditions::get_instance()->conditions;
129
  $condition = array();
 
130
  $condition['type'] = isset( $_POST['type'] ) ? $_POST['type'] : '';
 
131
  $index = isset( $_POST['index'] ) ? $_POST['index'] : 0;
132
 
133
+ $form_name = isset( $_POST['form_name'] ) ? $_POST['form_name'] : Advanced_Ads_Display_Conditions::FORM_NAME;
134
+
135
  if( isset( $conditions[$condition['type']] ) ) {
136
  $metabox = $conditions[$condition['type']]['metabox'];
137
  } else {
139
  }
140
 
141
  if ( method_exists( $metabox[0], $metabox[1] ) ) {
142
+ call_user_func( array($metabox[0], $metabox[1]), $condition, $index, $form_name );
143
  }
144
 
145
  die();
classes/ad_group.php CHANGED
@@ -357,8 +357,8 @@ class Advanced_Ads_Group {
357
 
358
  if ( $ads->have_posts() ) {
359
  $this->ads = $this->add_post_ids( $ads->posts );
360
- wp_cache_set( $key, $this->ads, Advanced_Ads_Model::OBJECT_CACHE_GROUP, Advanced_Ads_Model::OBJECT_CACHE_TTL);
361
  }
 
362
  }
363
 
364
  return $this->ads;
357
 
358
  if ( $ads->have_posts() ) {
359
  $this->ads = $this->add_post_ids( $ads->posts );
 
360
  }
361
+ wp_cache_set( $key, $this->ads, Advanced_Ads_Model::OBJECT_CACHE_GROUP, Advanced_Ads_Model::OBJECT_CACHE_TTL);
362
  }
363
 
364
  return $this->ads;
classes/ad_placements.php CHANGED
@@ -18,6 +18,11 @@
18
  * @author Thomas Maier <thomas.maier@webgilde.com>
19
  */
20
  class Advanced_Ads_Placements {
 
 
 
 
 
21
 
22
  /**
23
  * get placement types
@@ -362,37 +367,18 @@ class Advanced_Ads_Placements {
362
  if ( ! extension_loaded( 'dom' ) ) {
363
  return $content;
364
  }
365
-
366
  // get plugin options
367
  $plugin_options = Advanced_Ads::get_instance()->options();
368
 
369
- // parse document as DOM (fragment - having only a part of an actual post given)
370
- // -TODO may want to verify the wpcharset is supported by server (mb_list_encodings)
371
- // prevent messages from dom parser
372
  $wpCharset = get_bloginfo('charset');
373
- // check if mbstring exists
374
- if ( ! function_exists( 'mb_convert_encoding' ) ) {
375
- if ( $wpCharset === "UTF-8" ) {
376
- $content_to_load = htmlspecialchars_decode( htmlentities( $content, ENT_COMPAT, $wpCharset, false ) );
377
- } else {
378
- return $content;
379
- }
380
- } else {
381
- $content_to_load = mb_convert_encoding( $content, 'HTML-ENTITIES', $wpCharset );
382
- }
383
 
384
- // check which priority the wpautop filter has; might have been disabled on purpose
385
- $wpautop_priority = has_filter( 'the_content', 'wpautop');
386
- if ( $wpautop_priority && Advanced_Ads_Plugin::get_instance()->get_content_injection_priority() < $wpautop_priority ) {
387
- $content_to_load = wpautop( $content_to_load );
388
  }
389
 
390
- // temporarily change content during processing
391
- $replacements = array(
392
- 'gcse:search' => 'gcse__search', // Google custom search namespaced tags.
393
- );
394
- $content_to_load = str_replace( array_keys( $replacements ), array_values( $replacements ), $content_to_load );
395
-
396
  $dom = new DOMDocument('1.0', $wpCharset);
397
  // may loose some fragments or add autop-like code
398
  libxml_use_internal_errors(true); // avoid notices and warnings - html is most likely malformed
@@ -475,20 +461,20 @@ class Advanced_Ads_Placements {
475
  $did_inject = false;
476
 
477
  foreach ( $offsets as $offset ) {
478
- // test ad is emtpy
 
 
479
  $adContent = Advanced_Ads_Select::get_instance()->get_ad_by_method( $placement_id, 'placement', $placement_opts );
 
480
  if ( trim( $adContent, $whitespaces ) === '' ) {
481
  continue;
482
  }
483
 
 
 
484
  // convert HTML to XML!
485
  $adDom = new DOMDocument('1.0', $wpCharset);
486
  libxml_use_internal_errors(true);
487
- // replace `</` with `<\/` in ad content when placed within `document.write()` to prevent code from breaking
488
- // source for this regex: http://stackoverflow.com/questions/17852537/preg-replace-only-specific-part-of-string
489
- $adContent = preg_replace('#(document.write.+)</(.*)#', '$1<\/$2', $adContent); // escapes all closing html tags
490
- // $adContent = preg_replace('#(document.write.+)</sc(.*)#', '$1<\/sc$2', $adContent); // only escapes closing </script> tags
491
- // $adContent = preg_replace('#(document.write[^<^)]+)</sc(.*)#', '$1<\/sc$2', $adContent); // too restrict, doesn’t work when beginning <script> tag is in the same line
492
  $adDom->loadHtml('<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=' . $wpCharset . '" /><body>' . $adContent);
493
  // log errors
494
  if ( defined ( 'WP_DEBUG' ) && WP_DEBUG && current_user_can( 'advanced_ads_manage_options' ) ) {
@@ -500,8 +486,7 @@ class Advanced_Ads_Placements {
500
  }
501
  }
502
 
503
- // inject
504
- $node = apply_filters( 'advanced-ads-placement-content-injection-node', $paragraphs[$offset], $tag, $options['before'] );
505
  if ( $options['before'] ) {
506
  $refNode = $node;
507
 
@@ -536,23 +521,11 @@ class Advanced_Ads_Placements {
536
  return $content;
537
  }
538
 
 
539
  // convert to text-representation
540
  $content = $dom->saveHTML();
541
- // remove head and tail (required for dom parser but unwanted for content)
542
- $content = substr($content, stripos($content, '<body>') + 6);
543
- $content = str_replace(array('</body>', '</html>'), '', $content);
544
- $content = str_replace( array_values( $replacements ), array_keys( $replacements ), $content );
545
-
546
- // no fall-back desired: if there are too few paragraphs do nothing
547
 
548
- // fix shortcode quotes (malformed by backend editor)
549
- $matches = array();
550
- if (0 < preg_match_all('/\[[^]]+\]/Siu', $content, $matches, PREG_OFFSET_CAPTURE) && isset($matches[0])) {
551
- foreach ($matches[0] as $match) {
552
- $offset = $match[1];
553
- $content = substr($content, 0, $offset) . str_replace(array('“', '″', '&#8220;', '&quote;', '&#8243;'), '"', $match[0]) . substr($content, $offset + strlen($match[0]));
554
- }
555
- }
556
  /**
557
  * show a warning to ad admins in the Ad Health bar in the frontend, when
558
  *
@@ -575,6 +548,251 @@ class Advanced_Ads_Placements {
575
  return $content;
576
  }
577
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
578
  /**
579
  * Add a warning to 'Ad health'.
580
  *
@@ -632,4 +850,16 @@ class Advanced_Ads_Placements {
632
 
633
  return $result;
634
  }
 
 
 
 
 
 
 
 
 
 
 
635
  }
 
18
  * @author Thomas Maier <thomas.maier@webgilde.com>
19
  */
20
  class Advanced_Ads_Placements {
21
+ private static $ads_for_placeholders = array();
22
+ // temporarily change content during processing
23
+ private static $replacements = array(
24
+ 'gcse:search' => 'gcse__search', // Google custom search namespaced tags.
25
+ );
26
 
27
  /**
28
  * get placement types
367
  if ( ! extension_loaded( 'dom' ) ) {
368
  return $content;
369
  }
370
+
371
  // get plugin options
372
  $plugin_options = Advanced_Ads::get_instance()->options();
373
 
 
 
 
374
  $wpCharset = get_bloginfo('charset');
375
+ // parse document as DOM (fragment - having only a part of an actual post given)
 
 
 
 
 
 
 
 
 
376
 
377
+ $content_to_load = self::get_content_to_load( $content, $wpCharset );
378
+ if ( ! $content_to_load ) {
379
+ return $content;
 
380
  }
381
 
 
 
 
 
 
 
382
  $dom = new DOMDocument('1.0', $wpCharset);
383
  // may loose some fragments or add autop-like code
384
  libxml_use_internal_errors(true); // avoid notices and warnings - html is most likely malformed
461
  $did_inject = false;
462
 
463
  foreach ( $offsets as $offset ) {
464
+ // inject
465
+ $node = apply_filters( 'advanced-ads-placement-content-injection-node', $paragraphs[$offset], $tag, $options['before'] );
466
+
467
  $adContent = Advanced_Ads_Select::get_instance()->get_ad_by_method( $placement_id, 'placement', $placement_opts );
468
+
469
  if ( trim( $adContent, $whitespaces ) === '' ) {
470
  continue;
471
  }
472
 
473
+ $adContent = self::filter_ad_content( $adContent, $node->tagName, $options );
474
+
475
  // convert HTML to XML!
476
  $adDom = new DOMDocument('1.0', $wpCharset);
477
  libxml_use_internal_errors(true);
 
 
 
 
 
478
  $adDom->loadHtml('<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=' . $wpCharset . '" /><body>' . $adContent);
479
  // log errors
480
  if ( defined ( 'WP_DEBUG' ) && WP_DEBUG && current_user_can( 'advanced_ads_manage_options' ) ) {
486
  }
487
  }
488
 
489
+
 
490
  if ( $options['before'] ) {
491
  $refNode = $node;
492
 
521
  return $content;
522
  }
523
 
524
+ $content_orig = $content;
525
  // convert to text-representation
526
  $content = $dom->saveHTML();
527
+ $content = self::prepare_output( $content, $content_orig );
 
 
 
 
 
528
 
 
 
 
 
 
 
 
 
529
  /**
530
  * show a warning to ad admins in the Ad Health bar in the frontend, when
531
  *
548
  return $content;
549
  }
550
 
551
+ /**
552
+ * Get content to load.
553
+ *
554
+ * @param string $content Original content.
555
+ * @param $wpCharset Blog charset.
556
+ * @return string $content Content to load.
557
+ */
558
+ private static function get_content_to_load( $content, $wpCharset ) {
559
+ $plugin_options = Advanced_Ads::get_instance()->options();
560
+
561
+ if ( ! self::is_new_content_injection() ) {
562
+ // -TODO may want to verify the wpcharset is supported by server (mb_list_encodings)
563
+ // prevent messages from dom parser
564
+ // check if mbstring exists
565
+ if ( ! function_exists( 'mb_convert_encoding' ) ) {
566
+ if ( $wpCharset === "UTF-8" ) {
567
+ $content_to_load = htmlspecialchars_decode( htmlentities( $content, ENT_COMPAT, $wpCharset, false ) );
568
+ } else {
569
+ return;
570
+ }
571
+ } else {
572
+ $content_to_load = mb_convert_encoding( $content, 'HTML-ENTITIES', $wpCharset );
573
+ }
574
+
575
+ $content_to_load = str_replace( array_keys( self::$replacements ), array_values( self::$replacements ), $content_to_load );
576
+ } else {
577
+ // Prevent removing closing tags in scripts.
578
+ $content_to_load= preg_replace( '/<script.*?<\/script>/', '<!--\0-->', $content);
579
+ }
580
+
581
+
582
+ // check which priority the wpautop filter has; might have been disabled on purpose
583
+ $wpautop_priority = has_filter( 'the_content', 'wpautop');
584
+ if ( $wpautop_priority && Advanced_Ads_Plugin::get_instance()->get_content_injection_priority() < $wpautop_priority ) {
585
+ $content_to_load = wpautop( $content_to_load );
586
+ }
587
+
588
+ return $content_to_load;
589
+ }
590
+
591
+ /**
592
+ * Filter ad content.
593
+ *
594
+ * @param string $adContent Ad content.
595
+ * @param string $tag_name tar before/after the content.
596
+ * @param array $options Injection options.
597
+ * @return string $adContent Ad content.
598
+ */
599
+ private static function filter_ad_content( $ad_content, $tag_name, $options ) {
600
+ $plugin_options = Advanced_Ads::get_instance()->options();
601
+
602
+ if ( ! self::is_new_content_injection() ) {
603
+ // replace `</` with `<\/` in ad content when placed within `document.write()` to prevent code from breaking
604
+ // source for this regex: http://stackoverflow.com/questions/17852537/preg-replace-only-specific-part-of-string
605
+ $ad_content = preg_replace('#(document.write.+)</(.*)#', '$1<\/$2', $ad_content); // escapes all closing html tags
606
+ // $ad_content = preg_replace('#(document.write.+)</sc(.*)#', '$1<\/sc$2', $ad_content); // only escapes closing </script> tags
607
+ // $ad_content = preg_replace('#(document.write[^<^)]+)</sc(.*)#', '$1<\/sc$2', $ad_content); // too restrict, doesn’t work when beginning <script> tag is in the same line
608
+ } else {
609
+ //Inject placeholder.
610
+ $id = count( self::$ads_for_placeholders );
611
+ self::$ads_for_placeholders[] = array(
612
+ 'id' => $id,
613
+ 'tag' => $tag_name,
614
+ 'type' => $options['before'] ? 'before' : 'after',
615
+ 'ad' => $ad_content
616
+ );
617
+ $ad_content = '%advads_placeholder_' . $id . '%';
618
+ }
619
+
620
+ return $ad_content;
621
+ }
622
+
623
+ /**
624
+ * Prepare output.
625
+ *
626
+ * @param string $content Modified content.
627
+ * @param string $content_orig Original content.
628
+ * @return string $content Content to output.
629
+ */
630
+ private static function prepare_output( $content, $content_orig ) {
631
+ $plugin_options = Advanced_Ads::get_instance()->options();
632
+ if ( ! self::is_new_content_injection() ) {
633
+ // remove head and tail (required for dom parser but unwanted for content)
634
+ $content = substr($content, stripos($content, '<body>') + 6);
635
+ $content = str_replace(array('</body>', '</html>'), '', $content);
636
+ $content = str_replace( array_values( self::$replacements ), array_keys( self::$replacements ), $content );
637
+
638
+
639
+ // no fall-back desired: if there are too few paragraphs do nothing
640
+
641
+ // fix shortcode quotes (malformed by backend editor)
642
+ $matches = array();
643
+ if (0 < preg_match_all('/\[[^]]+\]/Siu', $content, $matches, PREG_OFFSET_CAPTURE) && isset($matches[0])) {
644
+ foreach ($matches[0] as $match) {
645
+ $offset = $match[1];
646
+ $content = substr($content, 0, $offset) . str_replace(array('“', '″', '&#8220;', '&quote;', '&#8243;'), '"', $match[0]) . substr($content, $offset + strlen($match[0]));
647
+ }
648
+ }
649
+ } else {
650
+ $content = self::inject_ads( $content, $content_orig, self::$ads_for_placeholders );
651
+ self::$ads_for_placeholders = array();
652
+ }
653
+ return $content;
654
+ }
655
+
656
+ /**
657
+ * Search for ad placeholders in the `$content` to determine positions at which to inject ads.
658
+ * Given the positions, inject ads into `$content_orig.
659
+ *
660
+ * @param string $content Post content with injected ad placeholders.
661
+ * @param string $content_orig Unmodified post content.
662
+ * @param arrray $options Injection options.
663
+ * @param arrray $ads_for_placeholders Array of ads.
664
+ * Each ad contains placeholder id, before or after which tag to inject the ad, the ad content.
665
+ * @return string $content
666
+ */
667
+ private static function inject_ads( $content, $content_orig, $ads_for_placeholders ) {
668
+ $self_closing_tags = array( 'area', 'base', 'basefont', 'bgsound', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr' );
669
+
670
+ // It is not possible to append/prepend in self closing tags.
671
+ foreach ( $ads_for_placeholders as &$ad_content ) {
672
+ if ( ( 'prepend' === $ad_content['type'] || 'append' === $ad_content['type'] )
673
+ && in_array( $ad_content['tag'], $self_closing_tags, true ) ) {
674
+ $ad_content['type'] = 'after';
675
+ }
676
+ }
677
+ unset( $ad_content );
678
+ usort( $ads_for_placeholders, array( 'Advanced_Ads_Placements', 'sort_ads_for_placehoders' ) );
679
+
680
+
681
+ // Add tags before/after which ad placehoders were injected.
682
+ foreach ( $ads_for_placeholders as $ad_content ) {
683
+ $tag = $ad_content['tag'];
684
+
685
+ switch( $ad_content['type'] ) {
686
+ case 'before':
687
+ case 'prepend':
688
+ $alts[] = "<${tag}[^>]*>";
689
+ break;
690
+ case 'after':
691
+ if ( in_array( $tag, $self_closing_tags, true ) ) {
692
+ $alts[] = "<${tag}[^>]*>";
693
+ } else {
694
+ $alts[] = "</${tag}>";
695
+ }
696
+ break;
697
+ case 'append':
698
+ $alts[] = "</${tag}>";
699
+ break;
700
+ }
701
+
702
+ }
703
+ $alts = array_unique( $alts );
704
+ $tag_regexp = implode( '|', $alts );
705
+ // Add ad placeholder.
706
+ $alts[] = '%advads_placeholder_(?:\d+)%';
707
+ $tag_and_placeholder_regexp = implode( '|', $alts );
708
+
709
+ preg_match_all( "#{$tag_and_placeholder_regexp}#i", $content, $tag_matches );
710
+ $count = 0;
711
+
712
+ // For each tag located before/after an ad placeholder, find its offset among the same tags.
713
+ foreach ( $tag_matches[0] as $r ) {
714
+ if ( preg_match( '/%advads_placeholder_(\d+)%/', $r, $result ) ) {
715
+ $id = $result[1];
716
+ $found_ad = false;
717
+ foreach ( $ads_for_placeholders as $n => $ad ) {
718
+ if ( (int) $ad['id'] === (int) $id ) {
719
+ $found_ad = $ad;
720
+ break;
721
+ }
722
+ }
723
+ if ( ! $found_ad ) {
724
+ continue;
725
+ }
726
+
727
+ switch( $found_ad['type'] ) {
728
+ case 'before':
729
+ case 'append':
730
+ $ads_for_placeholders[ $n ]['offset'] = $count;
731
+ break;
732
+ case 'after':
733
+ case 'prepend':
734
+ $ads_for_placeholders[ $n ]['offset'] = $count -1;
735
+ break;
736
+ }
737
+
738
+ } else {
739
+ $count++;
740
+ }
741
+ }
742
+
743
+ // Find tags before/after which we need to inject ads.
744
+ preg_match_all( "#{$tag_regexp}#i", $content_orig, $orig_tag_matches, PREG_OFFSET_CAPTURE );
745
+ $new_content = '';
746
+ $pos = 0;
747
+
748
+ foreach ( $orig_tag_matches[0] as $n => $r ) {
749
+ $to_inject = array();
750
+ // Check if we need to inject an ad at this offset.
751
+ foreach ( $ads_for_placeholders as $ad ) {
752
+ if ( isset( $ad['offset'] ) && $ad['offset'] === $n ) {
753
+ $to_inject[] = $ad;
754
+ }
755
+ }
756
+
757
+ foreach ( $to_inject as $item ) {
758
+ switch( $item['type'] ) {
759
+ case 'before':
760
+ case 'append':
761
+ $found_pos = $r[1];
762
+ break;
763
+ case 'after':
764
+ case 'prepend':
765
+ $found_pos = $r[1] + strlen( $r[0] );
766
+ break;
767
+ }
768
+
769
+ $new_content .= substr( $content_orig, $pos, $found_pos - $pos );
770
+ $pos = $found_pos;
771
+ $new_content .= $item['ad'];
772
+ }
773
+ }
774
+ $new_content .= substr( $content_orig, $pos );
775
+ return $new_content;
776
+ }
777
+
778
+
779
+ /**
780
+ * Callback function for usort() to sort ads for placeholders.
781
+ *
782
+ * @param array $first The first array to compare.
783
+ * @param array $second The second array to compare.
784
+ * @return int 0 if both objects equal. -1 if second array should come first, 1 otherwise.
785
+ */
786
+ public static function sort_ads_for_placehoders( $first, $second ) {
787
+ if ( $first['type'] === $second['type'] ) {
788
+ return 0;
789
+ }
790
+
791
+ $num = array( 'before' => 1, 'prepend' => 2, 'append' => 3, 'after' => 4 );
792
+
793
+ return $num[ $first['type'] ] > $num[ $second['type'] ] ? 1 : -1;
794
+ }
795
+
796
  /**
797
  * Add a warning to 'Ad health'.
798
  *
850
 
851
  return $result;
852
  }
853
+
854
+ /**
855
+ * Check if new content injection logic should be used.
856
+ *
857
+ * @return bool
858
+ */
859
+ public static function is_new_content_injection() {
860
+ // Enabled for new users or those who enabled it.
861
+ $plugin_options = Advanced_Ads::get_instance()->options();
862
+ return ! $plugin_options || ! empty( $plugin_options['content-injection-new'] );
863
+ }
864
  }
865
+
classes/ad_type_dummy.php CHANGED
@@ -46,7 +46,7 @@ class Advanced_Ads_Ad_Type_Dummy extends Advanced_Ads_Ad_Type_Abstract{
46
  <div><input type="text" name="advanced_ad[url]" id="advads-url" class="advads-ad-url" value="<?php echo $url; ?>"/></div><hr/>
47
  <?php endif;
48
 
49
- ?><img src="<?php echo ADVADS_BASE_URL ?>/public/assets/img/dummy.jpg" width="300" height="250"/><?php
50
 
51
  ?><input type="hidden" name="advanced_ad[width]" value="300"/>
52
  <input type="hidden" name="advanced_ad[height]" value="250"/><?php
@@ -67,7 +67,7 @@ class Advanced_Ads_Ad_Type_Dummy extends Advanced_Ads_Ad_Type_Abstract{
67
 
68
  ob_start();
69
  if( ! defined( 'AAT_VERSION' ) && $url ){ echo '<a href="'. $url .'"'.$target_blank.'>'; }
70
- echo '<img src="' . ADVADS_BASE_URL . '/public/assets/img/dummy.jpg" width="300" height="250"/>';
71
  if( ! defined( 'AAT_VERSION' ) && $url ){ echo '</a>'; }
72
 
73
  return ob_get_clean();
46
  <div><input type="text" name="advanced_ad[url]" id="advads-url" class="advads-ad-url" value="<?php echo $url; ?>"/></div><hr/>
47
  <?php endif;
48
 
49
+ ?><img src="<?php echo ADVADS_BASE_URL ?>public/assets/img/dummy.jpg" width="300" height="250"/><?php
50
 
51
  ?><input type="hidden" name="advanced_ad[width]" value="300"/>
52
  <input type="hidden" name="advanced_ad[height]" value="250"/><?php
67
 
68
  ob_start();
69
  if( ! defined( 'AAT_VERSION' ) && $url ){ echo '<a href="'. $url .'"'.$target_blank.'>'; }
70
+ echo '<img src="' . ADVADS_BASE_URL . 'public/assets/img/dummy.jpg" width="300" height="250"/>';
71
  if( ! defined( 'AAT_VERSION' ) && $url ){ echo '</a>'; }
72
 
73
  return ob_get_clean();
classes/checks.php CHANGED
@@ -202,21 +202,24 @@ class Advanced_Ads_Checks {
202
 
203
  $conflicting_plugins = array();
204
 
205
- if( defined( 'Publicize_Base' ) ){ // JetPack Publicize module
206
  $conflicting_plugins[] = 'Jetpack – Publicize';
207
  }
208
- if( defined( 'PF__PLUGIN_DIR' ) ){ // Facebook Instant Articles & Google AMP Pages by PageFrog
209
  $conflicting_plugins[] = 'Facebook Instant Articles & Google AMP Pages by PageFrog';
210
  }
211
  if( defined( 'GT_VERSION' ) ){ // GT ShortCodes
212
  $conflicting_plugins[] = 'GT ShortCodes';
213
  }
214
- if( class_exists( 'ITSEC_Core', false ) && defined ( 'AAP_VERSION' ) ){ // iThemes Security, but only if Pro is enabled
215
  $conflicting_plugins[] = 'iThemes Security';
216
  }
217
- if( class_exists( 'SimilarPosts', false ) ){ // Similar Posts, https://de.wordpress.org/plugins/similar-posts/
218
  $conflicting_plugins[] = 'Similar Posts';
219
  }
 
 
 
220
 
221
  return $conflicting_plugins;
222
  }
202
 
203
  $conflicting_plugins = array();
204
 
205
+ if( defined( 'Publicize_Base' ) ){ // JetPack Publicize module.
206
  $conflicting_plugins[] = 'Jetpack – Publicize';
207
  }
208
+ if( defined( 'PF__PLUGIN_DIR' ) ){ // Facebook Instant Articles & Google AMP Pages by PageFrog.
209
  $conflicting_plugins[] = 'Facebook Instant Articles & Google AMP Pages by PageFrog';
210
  }
211
  if( defined( 'GT_VERSION' ) ){ // GT ShortCodes
212
  $conflicting_plugins[] = 'GT ShortCodes';
213
  }
214
+ if( class_exists( 'ITSEC_Core', false ) && defined ( 'AAP_VERSION' ) ){ // iThemes Security, but only if Pro is enabled.
215
  $conflicting_plugins[] = 'iThemes Security';
216
  }
217
+ if( class_exists( 'SimilarPosts', false ) ){ // Similar Posts, https://de.wordpress.org/plugins/similar-posts/.
218
  $conflicting_plugins[] = 'Similar Posts';
219
  }
220
+ if( defined( 'WPAUTOTERMS_SLUG' ) ) { // https://wordpress.org/plugins/auto-terms-of-service-and-privacy-policy/.
221
+ $conflicting_plugins[] = 'WP AutoTerms';
222
+ }
223
 
224
  return $conflicting_plugins;
225
  }
classes/display-conditions.php CHANGED
@@ -8,597 +8,752 @@
8
  */
9
  class Advanced_Ads_Display_Conditions {
10
 
11
- /**
12
- *
13
- * @var Advanced_Ads_Display_Conditions
14
- */
15
- protected static $instance;
16
-
17
- /**
18
- * registered display conditions
19
- */
20
- public $conditions;
21
-
22
- /**
23
- * start of name in form elements
24
- */
25
- const FORM_NAME = 'advanced_ad[conditions]';
26
-
27
- protected static $query_var_keys = array(
28
- // 'is_single',
29
- 'is_archive',
30
- 'is_search',
31
- 'is_home',
32
- 'is_404',
33
- 'is_attachment',
34
- 'is_singular',
35
- 'is_front_page',
36
- 'is_feed'
37
- );
38
-
39
- // this is how the general conditions should look like by default
40
- protected static $default_general_keys = array(
41
- 'is_front_page',
42
- 'is_singular',
43
- 'is_archive',
44
- 'is_search',
45
- 'is_404',
46
- 'is_attachment',
47
- 'is_main_query',
48
- 'is_feed'
49
- );
50
-
51
- private function __construct() {
52
-
53
- // register filter
54
- add_filter('advanced-ads-ad-select-args', array($this, 'ad_select_args_callback'));
55
- add_filter('advanced-ads-can-display', array($this, 'can_display'), 10, 2);
56
-
57
- // register conditions with init hook, register as late as possible so other plugins can use the same hook to add new taxonomies
58
- add_action( 'init', array($this, 'register_conditions'), 100 );
59
- }
60
-
61
- /**
62
- * register display conditions
63
- *
64
- * @since 1.7.1.4
65
- */
66
- public function register_conditions(){
67
- $conditions = array(
68
- 'posttypes' => array(// post types condition
69
- 'label' => __('post type', 'advanced-ads'),
70
- 'description' => __('Choose the public post types on which to display the ad.', 'advanced-ads'),
71
- 'metabox' => array('Advanced_Ads_Display_Conditions', 'metabox_post_type'), // callback to generate the metabox
72
- 'check' => array('Advanced_Ads_Display_Conditions', 'check_post_type'), // callback for frontend check
73
- // 'helplink' => ADVADS_URL . 'manual/display-ads-either-on-mobile-or-desktop/#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor-mobile' // link to help section
74
- ),
75
- 'postids' => array(// post id condition
76
- 'label' => __('specific pages', 'advanced-ads'),
77
- 'description' => __('Choose on which individual posts, pages and public post type pages you want to display or hide ads.', 'advanced-ads'),
78
- 'metabox' => array('Advanced_Ads_Display_Conditions', 'metabox_post_ids'), // callback to generate the metabox
79
- 'check' => array('Advanced_Ads_Display_Conditions', 'check_post_ids'), // callback for frontend check
80
- ),
81
- 'general' => array(// general conditions
82
- 'label' => __('general conditions', 'advanced-ads'),
83
- // 'description' => __( 'Choose on which individual posts, pages and public post type pages you want to display or hide ads.', 'advanced-ads' ),
84
- 'metabox' => array('Advanced_Ads_Display_Conditions', 'metabox_general'), // callback to generate the metabox
85
- 'check' => array('Advanced_Ads_Display_Conditions', 'check_general'), // callback for frontend check
86
- ),
87
- 'author' => array(// author conditions
88
- 'label' => __('author', 'advanced-ads'),
89
- // 'description' => __( 'Choose on which individual posts, pages and public post type pages you want to display or hide ads.', 'advanced-ads' ),
90
- 'metabox' => array('Advanced_Ads_Display_Conditions', 'metabox_author'), // callback to generate the metabox
91
- 'check' => array('Advanced_Ads_Display_Conditions', 'check_author'), // callback for frontend check
92
- ),
93
- /**
94
- * display ads only in content older or younger than a specific age
95
- */
96
- 'content_age' => array(
97
- 'label' => __( 'content age', 'advanced-ads' ),
98
- 'description' => __( 'Display ads based on age of the page.', 'advanced-ads' ),
99
- 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_content_age' ), // callback to generate the metabox
100
- 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_content_age' ) // callback for frontend check
101
- ),
102
- /**
103
- * condition for taxonomies in general
104
- */
105
- 'taxonomy' => array(
106
- 'label' => __( 'taxonomy', 'advanced-ads' ),
107
- 'description' => __( 'Display ads based on the taxonomy of an archive page.', 'advanced-ads' ),
108
- 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_taxonomies' ), // callback to generate the metabox
109
- 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_taxonomy' ) // callback for frontend check
110
- ),
111
  );
112
-
113
- // register a condition for each taxonomy for posts.
114
- $taxonomies = get_taxonomies(array('public' => true, 'publicly_queryable' => true), 'objects', 'or');
115
-
116
- $tax_label_counts = array();
117
-
118
- foreach ($taxonomies as $_tax) :
119
- if ( in_array( $_tax->name, array( 'advanced_ads_groups' ) ) ) {
120
- continue;
121
- }
122
-
123
- /**
124
- * Count names of taxonomies and adjust label if there are duplicates.
125
- * we can’t use `array_count_values` here because "label" might not always be a simple string (though it should be)
126
- */
127
- $tax_label_counts[ $_tax->label ] = isset( $tax_label_counts[ $_tax->label ] ) ? $tax_label_counts[ $_tax->label ] + 1 : $tax_label_counts[ $_tax->label ] = 1;
128
-
129
- // add tax type to label if we find it multiple times.
130
- if ( $tax_label_counts[ $_tax->label ] < 2 ) {
131
- $label = $_tax->label;
132
- $archive_label = $_tax->labels->singular_name;
133
- } else {
134
- $label = sprintf( '%s (%s)', $_tax->label, $_tax->name );
135
- $archive_label = sprintf( '%s (%s)', $_tax->labels->singular_name, $_tax->name );
136
- }
137
-
138
- $conditions['taxonomy_' . $_tax->name] = array(
139
- 'label' => $label,
140
- // 'description' => sprintf(__( 'Choose terms from the %s taxonomy a post must belong to for showing or hiding ads.', 'advanced-ads' ), $_tax->label ),
141
- 'metabox' => array('Advanced_Ads_Display_Conditions', 'metabox_taxonomy_terms'), // callback to generate the metabox
142
- 'check' => array('Advanced_Ads_Display_Conditions', 'check_taxonomies'), // callback for frontend check
143
- 'taxonomy' => $_tax->name, // unique for this type: the taxonomy name
144
- );
145
-
146
- $conditions['archive_' . $_tax->name] = array(
147
- 'label' => sprintf(__('archive: %s', 'advanced-ads'), $archive_label),
148
- // 'description' => sprintf(__( 'Choose on which %s archive page ads are hidden or displayeds.', 'advanced-ads' ), $_tax->label ),
149
- 'metabox' => array('Advanced_Ads_Display_Conditions', 'metabox_taxonomy_terms'), // callback to generate the metabox
150
- 'check' => array('Advanced_Ads_Display_Conditions', 'check_taxonomy_archive'), // callback for frontend check
151
- 'taxonomy' => $_tax->name, // unique for this type: the taxonomy name
152
- );
153
- endforeach;
154
-
155
- $this->conditions = apply_filters('advanced-ads-display-conditions', $conditions);
156
- }
157
-
158
- /**
159
- *
160
- * @return Advanced_Ads_Plugin
161
- */
162
- public static function get_instance() {
163
- // If the single instance hasn't been set, set it now.
164
- if (null === self::$instance) {
165
- self::$instance = new self;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  }
167
 
168
- return self::$instance;
169
- }
170
-
171
-
172
- /**
173
- * get the conditions array alphabetically by label
174
- *
175
- * @since 1.8.12
176
- */
177
- public function get_conditions(){
178
- uasort( $this->conditions, 'Advanced_Ads_Admin::sort_condition_array_by_label' );
179
-
180
- return $this->conditions;
181
- }
182
-
183
- /**
184
- * controls frontend checks for conditions
185
- *
186
- * @param arr $options options of the condition
187
- * @param ob $ad Advanced_Ads_Ad
188
- * @return bool false, if ad can’t be delivered
189
- */
190
- static function frontend_check($options = array(), $ad = false) {
191
- $display_conditions = Advanced_Ads_Display_Conditions::get_instance()->conditions;
192
-
193
- if (is_array($options) && isset( $options['type'] ) && isset($display_conditions[$options['type']]['check'])) {
194
- $check = $display_conditions[$options['type']]['check'];
195
- } else {
196
- return true;
197
  }
198
 
199
- // call frontend check callback
200
- if (method_exists($check[0], $check[1])) {
201
- return call_user_func(array($check[0], $check[1]), $options, $ad);
 
 
 
 
 
 
 
 
 
202
  }
203
 
204
- return true;
205
- }
206
-
207
- /**
208
- * render connector option
209
- *
210
- * @since 1.7.0.4
211
- * @param int $index
212
- */
213
- static function render_connector_option( $index = 0, $value = 'or' ){
214
-
215
- $label = ( $value === 'or' ) ? __( 'or', 'advanced-ads' ) : __( 'and', 'advanced-ads' );
216
-
217
- return '<input style="display:none;" type="checkbox" name="' . self::FORM_NAME . '[' . $index . '][connector]' . '" value="or" id="advads-conditions-' .
218
- $index . '-connector"' .
219
- checked( 'or', $value, false )
220
- .'><label for="advads-conditions-' . $index . '-connector">' . $label . '</label>';
221
- }
222
-
223
- /**
224
- * callback to display the metabox for the post type condition
225
- *
226
- * @param arr $options options of the condition
227
- * @param int $index index of the condition
228
- */
229
- static function metabox_post_type($options, $index = 0) {
230
- if (!isset($options['type']) || '' === $options['type']) {
231
- return;
232
  }
233
 
234
- $type_options = self::get_instance()->conditions;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
- if (!isset($type_options[$options['type']])) {
237
- return;
 
 
 
 
 
 
 
 
 
 
 
 
238
  }
239
 
240
- // get values and select operator based on previous settings
241
- $operator = ( isset($options['operator']) && $options['operator'] === 'is_not' ) ? 'is_not' : 'is';
242
- $values = ( isset($options['value'] ) && is_array( $options['value'] ) ) ? $options['value'] : array();
243
-
244
- // form name basis
245
- $name = self::FORM_NAME . '[' . $index . ']';
246
-
247
- // options
248
- ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
249
- <select name="<?php echo $name; ?>[operator]">
250
- <option value="is" <?php selected('is', $operator); ?>><?php _e('is', 'advanced-ads'); ?></option>
251
- <option value="is_not" <?php selected('is_not', $operator); ?>><?php _e('is not', 'advanced-ads' ); ?></option>
252
- </select><?php
253
-
254
- // set defaults
255
- $post_types = get_post_types(array('public' => true, 'publicly_queryable' => true), 'object', 'or');
256
- ?><div class="advads-conditions-single advads-buttonset"><?php
257
- $type_label_counts = array_count_values( wp_list_pluck( $post_types, 'label' ) );
258
-
259
- foreach ($post_types as $_type_id => $_type) {
260
- if ( in_array($_type_id, $values)) {
261
- $_val = 1;
262
- } else {
263
- $_val = 0;
264
- }
265
-
266
- if ( $type_label_counts[ $_type->label ] < 2 ) {
267
- $_label = $_type->label;
268
- } else {
269
- $_label = sprintf( '%s (%s)', $_type->label, $_type_id );
270
- }
271
- ?><label class="button" for="advads-conditions-<?php echo $index; ?>-<?php echo $_type_id;
272
- ?>"><?php echo $_label ?></label><input type="checkbox" id="advads-conditions-<?php echo $index; ?>-<?php echo $_type_id; ?>" name="<?php echo $name; ?>[value][]" <?php checked($_val, 1); ?> value="<?php echo $_type_id; ?>"><?php
273
- }
274
- ?><p class="advads-conditions-not-selected advads-error-message"><?php _ex( 'Please select some items.', 'Error message shown when no display condition term is selected', 'advanced-ads' ); ?></p></div><?php
275
- }
276
-
277
- /**
278
- * callback to display the metabox for the author condition
279
- *
280
- * @param arr $options options of the condition
281
- * @param int $index index of the condition
282
- */
283
- static function metabox_author($options, $index = 0) {
284
-
285
- if (!isset($options['type']) || '' === $options['type']) {
286
- return;
287
- }
288
-
289
- $type_options = self::get_instance()->conditions;
290
-
291
- if (!isset($type_options[$options['type']])) {
292
- return;
293
- }
294
-
295
- // get values and select operator based on previous settings
296
- $operator = ( isset($options['operator']) && $options['operator'] === 'is_not' ) ? 'is_not' : 'is';
297
- $values = ( isset($options['value']) && is_array($options['value']) ) ? $options['value'] : array();
298
-
299
- // form name basis
300
- $name = self::FORM_NAME . '[' . $index . ']';
301
- ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
302
- <select name="<?php echo $name; ?>[operator]">
303
- <option value="is" <?php selected('is', $operator); ?>><?php _e('is', 'advanced-ads'); ?></option>
304
- <option value="is_not" <?php selected('is_not', $operator); ?>><?php _e('is not', 'advanced-ads'); ?></option>
305
- </select><?php
306
- // set defaults
307
- $max_authors = absint( apply_filters( 'advanced-ads-admin-max-terms', 50 ) );
308
- $authors = get_users(array('who' => 'authors', 'orderby' => 'nicename', 'number' => $max_authors ) );
309
- ?><div class="advads-conditions-single advads-buttonset"><?php
310
- foreach ($authors as $_author) {
311
- if ( in_array($_author->ID, $values ) ) {
312
- $_val = 1;
313
- } else {
314
- $_val = 0;
315
- }
316
- ?><label class="button ui-button" for="advads-conditions-<?php echo $index; ?>-<?php echo $_author->ID;
317
- ?>"><?php echo $_author->display_name; ?></label><input type="checkbox" id="advads-conditions-<?php echo $index; ?>-<?php echo $_author->ID; ?>" name="<?php echo $name; ?>[value][]" <?php checked($_val, 1); ?> value="<?php echo $_author->ID; ?>"><?php
318
  }
319
- ?><p class="advads-conditions-not-selected advads-error-message"><?php _ex( 'Please select some items.', 'Error message shown when no display condition term is selected', 'advanced-ads' ); ?></p></div>
320
- <?php if( count( $authors ) >= $max_authors ) : ?><p class="advads-error-message"><?php printf( __( 'Only %d elements are displayed above. Use the <code>advanced-ads-admin-max-terms</code> filter to change this limit according to <a href="%s" target="_blank">this page</a>.', 'advanced-ads' ), $max_authors, ADVADS_URL . 'codex/filter-hooks//#utm_source=advanced-ads&utm_medium=link&utm_campaign=author-term-limit' ); ?></p><?php endif;
321
- }
322
 
323
  /**
324
- * callback to display the metabox for the taxonomy archive pages
325
  *
326
- * @param arr $options options of the condition
327
- * @param int $index index of the condition
 
328
  */
329
- static function metabox_taxonomy_terms($options, $index = 0) {
330
 
331
- if (!isset($options['type']) || '' === $options['type']) {
332
- return;
333
  }
334
 
335
  $type_options = self::get_instance()->conditions;
336
 
337
- // don’t use if this is not a taxonomy
338
- if (!isset($type_options[$options['type']]) || !isset($type_options[$options['type']]['taxonomy'])) {
339
- return;
340
  }
341
 
342
- $taxonomy = get_taxonomy($type_options[$options['type']]['taxonomy']);
343
- if (false == $taxonomy) {
344
- return;
345
  }
346
 
347
- // get values and select operator based on previous settings
348
- $operator = ( isset($options['operator']) && $options['operator'] === 'is_not' ) ? 'is_not' : 'is';
349
- $values = ( isset($options['value']) && is_array($options['value']) ) ? $options['value'] : array();
350
 
351
- // limit the number of terms so many terms don’t break the admin page
352
- $max_terms = absint(apply_filters('advanced-ads-admin-max-terms', 50));
353
 
354
- // form name basis
355
- $name = self::FORM_NAME . '[' . $index . ']';
356
- ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
357
- <select name="<?php echo $name; ?>[operator]">
358
- <option value="is" <?php selected('is', $operator); ?>><?php _e('is', 'advanced-ads'); ?></option>
359
- <option value="is_not" <?php selected('is_not', $operator); ?>><?php _e('is not', 'advanced-ads'); ?></option>
360
- </select><?php
361
- ?><div class="advads-conditions-single advads-buttonset"><?php
362
- self::display_term_list($taxonomy, $values, $name . '[value][]', $max_terms, $index);
 
 
 
363
  ?></div><?php
364
  }
365
-
366
  /**
367
- * callback to display the metabox for the taxonomies
368
  *
369
- * @param arr $options options of the condition
370
- * @param int $index index of the condition
 
371
  */
372
- static function metabox_taxonomies($options, $index = 0) {
373
 
374
- if (!isset($options['type']) || '' === $options['type']) {
375
- return;
376
  }
377
 
378
  $taxonomies = get_taxonomies( array( 'public' => 1 ), 'objects' );
379
-
380
- $name = self::FORM_NAME . '[' . $index . ']';
381
-
382
- // get values and select operator based on previous settings
383
- $operator = ( isset($options['operator']) && $options['operator'] === 'is_not' ) ? 'is_not' : 'is';
384
- $values = ( isset($options['value']) && is_array($options['value']) ) ? $options['value'] : array();
385
-
386
- ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
387
- <div class="advads-conditions-single advads-buttonset"><?php
388
- $tax_label_counts = array_count_values( wp_list_pluck( $taxonomies, 'label' ) );
389
-
390
- foreach ($taxonomies as $_taxonomy_id => $_taxonomy) :
391
-
392
- if ( in_array($_taxonomy_id, $values)) {
393
- $_val = 1;
394
- } else {
395
- $_val = 0;
396
- }
397
-
398
- if ( $tax_label_counts[ $_taxonomy->label ] < 2 ) {
399
- $_label = $_taxonomy->label;
400
- } else {
401
- $_label = sprintf( '%s (%s)', $_taxonomy->label, $_taxonomy_id );
402
- }
403
- ?><label class="button" for="advads-conditions-<?php echo $index; ?>-<?php echo $_taxonomy_id;
404
- ?>"><?php echo $_label ?></label><input type="checkbox" id="advads-conditions-<?php echo $index; ?>-<?php echo $_taxonomy_id; ?>" name="<?php echo $name; ?>[value][]" <?php checked($_val, 1); ?> value="<?php echo $_taxonomy_id; ?>"><?php
405
- endforeach;
406
- ?><p class="advads-conditions-not-selected advads-error-message"><?php _ex( 'Please select some items.', 'Error message shown when no display condition term is selected', 'advanced-ads' ); ?></p></div><?php
 
 
 
 
 
 
 
 
 
407
  }
408
 
409
  /**
410
- * display terms of a taxonomy for choice
411
- *
412
- * @param obj $taxonomy taxonomy object
413
- * @param arr $checked ids of checked terms
414
- * @param str $inputname name of the input field
415
- * @param int $max_terms maximum number of terms to show
416
- * @param int $index index of the conditions group
417
  */
418
- public static function display_term_list($taxonomy, $checked = array(), $inputname = '', $max_terms = 50, $index = 0) {
419
-
420
- $terms = get_terms($taxonomy->name, array('hide_empty' => false, 'number' => $max_terms));
421
-
422
- if (!empty($terms) && !is_wp_error($terms)):
423
- // display search field if the term limit is reached
424
- if (count($terms) == $max_terms) :
425
-
426
- // query active terms
427
- if (is_array($checked) && count($checked)) {
428
- $args = array('hide_empty' => false);
429
- $args['include'] = $checked;
430
- $checked_terms = get_terms($taxonomy->name, $args);
431
- ?><div class="advads-conditions-terms-buttons dynamic-search"><?php
432
- foreach ($checked_terms as $_checked_term) :
433
- ?><label class="button ui-state-active"><?php echo $_checked_term->name;
434
- ?><input type="hidden" name="<?php echo $inputname; ?>" value="<?php echo $_checked_term->term_id; ?>"></label><?php
435
- endforeach;
436
- ?></div><?php
437
- } else {
438
- ?><div class="advads-conditions-terms-buttons dynamic-search"></div><?php
439
- }
440
- ?><span class="advads-conditions-terms-show-search button" title="<?php
441
- _ex('add more terms', 'display the terms search field on ad edit page', 'advanced-ads');
442
- ?>">+</span><br/><input type="text" class="advads-conditions-terms-search" data-tag-name="<?php echo $taxonomy->name;
443
- ?>" data-input-name="<?php echo $inputname; ?>" placeholder="<?php _e('term name or id', 'advanced-ads'); ?>"/><?php
444
- else :
445
- ?><div class="advads-conditions-terms-buttons advads-buttonset"><?php
446
- foreach ($terms as $_term) :
447
- $field_id = "advads-conditions-$index-$_term->term_id";
448
- ?><input type="checkbox" id="<?php echo $field_id; ?>" name="<?php echo $inputname; ?>" value="<?php echo $_term->term_id; ?>" <?php checked(in_array($_term->term_id, $checked), true); ?>><label for="<?php echo $field_id; ?>"><?php echo $_term->name; ?></label><?php
449
- endforeach;
450
- ?><p class="advads-conditions-not-selected advads-error-message"><?php _ex( 'Please select some items.', 'Error message shown when no display condition term is selected', 'advanced-ads' ); ?></p></div><?php
451
- endif;
452
- endif;
453
- }
454
-
455
- /**
456
- * callback to display the metabox for the taxonomy archive pages
457
- *
458
- * @param arr $options options of the condition
459
- * @param int $index index of the condition
460
- */
461
- static function metabox_post_ids($options, $index = 0) {
462
-
463
- if (!isset($options['type']) || '' === $options['type']) {
464
- return;
 
 
 
 
465
  }
466
 
467
- // get values and select operator based on previous settings
468
- $operator = ( isset($options['operator']) && $options['operator'] === 'is_not' ) ? 'is_not' : 'is';
469
- $values = ( isset($options['value']) && is_array($options['value']) ) ? $options['value'] : array();
470
-
471
- // form name basis
472
- $name = self::FORM_NAME . '[' . $index . ']';
473
- ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
474
- <select name="<?php echo $name; ?>[operator]">
475
- <option value="is" <?php selected('is', $operator); ?>><?php _e('is', 'advanced-ads'); ?></option>
476
- <option value="is_not" <?php selected('is_not', $operator); ?>><?php _e('is not', 'advanced-ads'); ?></option>
477
- </select><?php ?><div class="advads-conditions-single advads-buttonset advads-conditions-postid-buttons"><?php
478
- // query active post ids
479
- if ($values != array()) {
480
- $args = array(
481
- 'post_type' => 'any',
482
- // 'post_status' => 'publish',
483
- 'post__in' => $values,
484
- 'posts_per_page' => -1,
485
- // 'ignore_sticky_posts' => 1,
486
- 'order' => 'ASC',
487
- 'order_by' => 'title',
488
-
489
- );
490
-
491
- $the_query = new WP_Query($args);
492
- while ($the_query->have_posts()) {
493
- $the_query->next_post();
494
- ?><label class="button ui-state-active"><?php echo get_the_title($the_query->post->ID) . ' (' . $the_query->post->post_type . ')';
495
- ?><input type="hidden" name="<?php echo $name; ?>[value][]" value="<?php echo $the_query->post->ID; ?>"></label><?php
496
- }
497
- }
498
- ?><span class="advads-conditions-postids-show-search button" <?php
499
- if (!count($values)) {
500
- echo 'style="display:none;"';
501
- }
502
- ?>>+</span>
503
- <p class="advads-conditions-postids-search-line">
504
- <input type="text" class="advads-display-conditions-individual-post" <?php if (count($values)) {
505
- echo 'style="display:none;"';
506
- } ?>
507
- placeholder="<?php _e('title or id', 'advanced-ads'); ?>"
508
- data-field-name="<?php echo $name; ?>"/><?php
509
- wp_nonce_field('internal-linking', '_ajax_linking_nonce', false);
510
- ?></p></div><?php
511
- }
512
-
513
- /**
514
- * callback to display the metabox for the general display conditions
515
- *
516
- * @param arr $options options of the condition
517
- * @param int $index index of the condition
518
- */
519
- static function metabox_general($options, $index = 0) {
520
-
521
- // general conditions array
522
- $conditions = self::get_instance()->general_conditions();
523
- if (!isset($options['type']) || '' === $options['type']) {
524
- return;
 
 
 
525
  }
526
 
527
- $name = self::FORM_NAME . '[' . $index . ']';
528
- $values = isset($options['value']) ? $options['value'] : array();
529
- ?><div class="advads-conditions-single advads-buttonset">
530
- <input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/><?php
531
- foreach ($conditions as $_key => $_condition) :
 
 
 
 
 
 
 
 
 
532
 
533
- // activate by default
534
- $value = ( $values === array() || in_array($_key, $values) ) ? 1 : 0;
 
 
 
535
 
536
- $field_id = "advads-conditions-$index-$_key";
537
- ?><input type="checkbox" id="<?php echo $field_id; ?>" name="<?php echo $name; ?>[value][]" value="<?php echo $_key; ?>" <?php checked(1, $value); ?>><label for="<?php echo $field_id; ?>"><?php echo $_condition['label']; ?></label><?php
538
- endforeach;
539
- ?></div><?php
540
- return;
541
- }
 
 
 
 
 
 
 
 
 
542
 
543
  /**
544
- * retrieve the array with general conditions
545
- *
546
- * @return arr $conditions
547
- *
548
  */
549
- static function general_conditions() {
550
- return $conditions = apply_filters( 'advanced-ads-display-conditions-general', array(
551
- 'is_front_page' => array(
552
- 'label' => __('Home Page', 'advanced-ads'),
553
- 'description' => __('show on Home page', 'advanced-ads'),
554
- 'type' => 'radio',
555
- ),
556
- 'is_singular' => array(
557
- 'label' => __('Singular Pages', 'advanced-ads'),
558
- 'description' => __('show on singular pages/posts', 'advanced-ads'),
559
- 'type' => 'radio',
560
- ),
561
- 'is_archive' => array(
562
- 'label' => __('Archive Pages', 'advanced-ads'),
563
- 'description' => __('show on any type of archive page (category, tag, author and date)', 'advanced-ads'),
564
- 'type' => 'radio',
565
- ),
566
- 'is_search' => array(
567
- 'label' => __('Search Results', 'advanced-ads'),
568
- 'description' => __('show on search result pages', 'advanced-ads'),
569
- 'type' => 'radio',
570
- ),
571
- 'is_404' => array(
572
- 'label' => __('404 Page', 'advanced-ads'),
573
- 'description' => __('show on 404 error page', 'advanced-ads'),
574
- 'type' => 'radio',
575
- ),
576
- 'is_attachment' => array(
577
- 'label' => __('Attachment Pages', 'advanced-ads'),
578
- 'description' => __('show on attachment pages', 'advanced-ads'),
579
- 'type' => 'radio',
580
- ),
581
- 'is_main_query' => array(
582
- 'label' => __('Secondary Queries', 'advanced-ads'),
583
- 'description' => __('allow ads in secondary queries', 'advanced-ads'),
584
- 'type' => 'radio',
585
- ),
586
- 'is_feed' => array(
587
- 'label' => __('RSS Feed', 'advanced-ads'),
588
- 'description' => __('allow ads in RSS Feed', 'advanced-ads'),
589
- 'type' => 'radio',
590
- )
591
- ) );
 
 
592
  }
593
-
594
  /**
595
  * Callback to display the 'content age' condition
596
  *
597
- * @param arr $options options of the condition
598
- * @param int $index index of the condition
 
599
  */
600
- static function metabox_content_age( $options, $index = 0 ){
601
- if ( ! isset ( $options['type'] ) || '' === $options['type'] ) { return; }
 
 
602
 
603
  $type_options = Advanced_Ads_Display_Conditions::get_instance()->conditions;
604
 
@@ -606,311 +761,323 @@ class Advanced_Ads_Display_Conditions {
606
  return;
607
  }
608
 
609
- // form name basis
610
- $name = Advanced_Ads_Display_Conditions::FORM_NAME . '[' . $index . ']';
611
 
612
  $operator = isset( $options['operator'] ) ? $options['operator'] : 'older_than';
613
- $value = ( isset( $options['value'] ) && is_numeric( $options['value'] ) ) ? floatval( $options['value'] ) : 0;
614
- ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
 
 
 
615
  <select name="<?php echo $name; ?>[operator]">
616
- <option value="older_than" <?php selected( 'older_than', $operator ); ?>><?php _e( 'older than', 'advanced-ads'); ?></option>
617
- <option value="younger_than" <?php selected( 'younger_than', $operator ); ?>><?php _e( 'younger than', 'advanced-ads' ); ?></option>
618
- </select><input type="text" name="<?php echo $name; ?>[value]" value="<?php echo $value; ?>"/>&nbsp;<?php _e( 'days', 'advanced-ads' );
619
- }
 
620
 
621
  /**
622
- * check post type display condition in frontend
 
 
 
623
  *
624
- * @param arr $options options of the condition
625
- * @param obj $ad Advanced_Ads_Ad
626
  * @return bool true if can be displayed
627
  */
628
- static function check_post_type($options = array(), Advanced_Ads_Ad $ad) {
629
- if (!isset($options['value']) || !is_array($options['value'])) {
630
- return false;
631
- }
632
 
633
- if (isset($options['operator']) && $options['operator'] === 'is_not') {
634
- $operator = 'is_not';
635
- } else {
636
- $operator = 'is';
637
- }
638
 
639
- $ad_options = $ad->options();
640
- $query = $ad_options['wp_the_query'];
641
- $post = isset($ad_options['post']) ? $ad_options['post'] : null;
642
- $post_type = isset($post['post_type']) ? $post['post_type'] : false;
643
 
644
- if ( ! self::can_display_ids( $post_type, $options['value'], $operator ) ) {
645
- return false;
646
- }
647
 
648
- return true;
649
  }
650
 
651
  /**
652
- * check author display condition in frontend
 
 
 
653
  *
654
- * @param arr $options options of the condition
655
- * @param obj $ad Advanced_Ads_Ad
656
  * @return bool true if can be displayed
657
  */
658
- static function check_author($options = array(), Advanced_Ads_Ad $ad) {
659
 
660
- if (!isset($options['value']) || !is_array($options['value'])) {
661
- return false;
662
- }
663
 
664
- if (isset($options['operator']) && $options['operator'] === 'is_not') {
665
- $operator = 'is_not';
666
- } else {
667
- $operator = 'is';
668
- }
669
 
670
- $ad_options = $ad->options();
671
- $post = isset($ad_options['post']) ? $ad_options['post'] : null;
672
- $post_author = isset($post['author']) ? $post['author'] : false;
673
 
674
- if (!self::can_display_ids($post_author, $options['value'], $operator)) {
675
- return false;
676
- }
677
 
678
- return true;
679
  }
680
 
681
  /**
682
- * check taxonomies display condition in frontend
 
 
 
683
  *
684
- * @param arr $options options of the condition
685
  * @return bool true if can be displayed
686
  */
687
- static function check_taxonomies($options = array(), Advanced_Ads_Ad $ad) {
688
 
689
- if( !isset( $options['value']) ){
690
- return false;
691
- }
692
-
693
- if (isset($options['operator']) && $options['operator'] === 'is_not') {
694
- $operator = 'is_not';
695
- } else {
696
- $operator = 'is';
697
- }
698
-
699
- $ad_options = $ad->options();
700
- $query = $ad_options['wp_the_query'];
701
- $post_id = isset($ad_options['post']['id']) ? $ad_options['post']['id'] : null;
702
-
703
- // get terms of the current taxonomy
704
- $type_options = self::get_instance()->conditions;
705
- if (!isset($options['type']) || !isset($type_options[$options['type']]['taxonomy'])) {
706
- return true;
707
- }
708
- $taxonomy = $type_options[$options['type']]['taxonomy'];
709
-
710
- $terms = get_the_terms($post_id, $taxonomy);
711
-
712
- if ( is_array($terms) ) {
713
- foreach ($terms as $term) {
714
- $term_ids[] = $term->term_id;
715
  }
716
- } elseif( false === $terms && 'is' === $operator ) {
717
- // don’t show if should show only for a specific tag
718
- return false;
719
- } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
720
  return true;
721
- }
722
-
723
- if( 'is' === $operator && ( ! isset($query['is_singular']) || ! $query['is_singular'] ) ){
724
- return false;
725
- } elseif (isset($query['is_singular']) && $query['is_singular'] && !self::can_display_ids($options['value'], $term_ids, $operator)
726
- ) {
727
- return false;
728
- }
729
-
730
- return true;
731
  }
732
 
733
  /**
734
- * check taxonomy archive display condition in frontend
 
 
 
735
  *
736
- * @param arr $options options of the condition
737
  * @return bool true if can be displayed
738
  */
739
- static function check_taxonomy_archive($options = array(), Advanced_Ads_Ad $ad) {
740
 
741
- if( !isset( $options['value']) ){
742
- return false;
743
- }
744
-
745
- if (isset($options['operator']) && $options['operator'] === 'is_not') {
746
- $operator = 'is_not';
747
- } else {
748
- $operator = 'is';
749
- }
750
-
751
- $ad_options = $ad->options();
752
- $query = $ad_options['wp_the_query'];
753
-
754
- // return false if operator is "is", but important query vars are not given
755
- if( 'is' === $operator && ( empty( $query['term_id'] ) || empty($query['is_archive']) ) ){
756
- return false;
757
- } elseif ( isset($query['term_id']) && isset($query['is_archive']) && $query['is_archive'] && !self::can_display_ids($query['term_id'], $options['value'], $operator)
758
- ) {
759
- return false;
760
- }
761
-
762
- return true;
763
  }
764
-
765
  /**
766
- * check if a specific archive belongs to a taxonomy in general (not a specific term)
 
 
 
767
  *
768
- * @param arr $options options of the condition
769
  * @return bool true if can be displayed
770
  */
771
  static function check_taxonomy( $options = array(), Advanced_Ads_Ad $ad ) {
772
 
773
- if( !isset( $options['value']) ){
774
- return false;
775
- }
776
-
777
- if (isset($options['operator']) && $options['operator'] === 'is_not') {
778
- $operator = 'is_not';
779
- } else {
780
- $operator = 'is';
781
- }
782
-
783
- $ad_options = $ad->options();
784
- $query = $ad_options['wp_the_query'];
785
-
786
- // return false if operator is "is", but important query vars are not given
787
- if( 'is' === $operator && ( empty( $query['taxonomy'] ) || empty($query['is_archive']) ) ){
788
- return false;
789
- } elseif ( isset($query['taxonomy']) && isset($query['is_archive']) && $query['is_archive'] && !self::can_display_ids($query['taxonomy'], $options['value'], $operator)
790
- ) {
791
- return false;
792
- }
793
-
794
- return true;
795
  }
796
 
797
  /**
798
- * check post ids display condition in frontend
799
- *
800
- * @param arr $options options of the condition
 
 
801
  * @return bool true if can be displayed
802
  */
803
- static function check_post_ids($options = array(), Advanced_Ads_Ad $ad) {
804
 
805
- if (isset($options['operator']) && $options['operator'] === 'is_not') {
806
- $operator = 'is_not';
807
  } else {
808
- $operator = 'is';
809
  }
810
 
811
  $ad_options = $ad->options();
812
- $query = $ad_options['wp_the_query'];
813
- $post_id = isset($ad_options['post']['id']) ? $ad_options['post']['id'] : null;
814
-
815
- //fixes page id on BuddyPress pages
816
- if ( $post_id == 0 && class_exists( 'BuddyPress' ) && function_exists( 'bp_current_component' )){
817
- $component = bp_current_component();
818
- $bp_pages = get_option( 'bp-pages' );
819
- if ( isset( $bp_pages[$component] ) ){
820
- $post_id = $bp_pages[$component];
821
- }
822
- }
823
-
824
  /**
825
  * WooCommerce Store page fix
826
  * since WooCommerce changes the post ID of the static page selected to be the product overview page, we need to get the original page id from the WC options
827
  */
828
  if ( function_exists( 'is_shop' ) && is_shop() && isset( $options['value'] ) && is_array( $options['value'] ) ) {
829
  $post_id = get_option( 'woocommerce_shop_page_id' );
830
- return self::can_display_ids($post_id, $options['value'], $operator);
 
831
  }
832
-
833
- if( empty( $ad_options['wp_the_query']['is_singular'] ) ){
834
- if( 'is_not' === $operator ){
835
- return true;
836
- } else {
837
- return false;
838
- }
839
  }
840
 
841
  if ( ! isset( $options['value'] ) || ! is_array( $options['value'] ) || ! $post_id ) {
842
  return true;
843
  }
844
 
845
- return self::can_display_ids($post_id, $options['value'], $operator);
846
  }
847
 
848
  /**
849
- * check general display conditions in frontend
 
 
 
850
  *
851
- * @param arr $options options of the condition
852
- * @param obj $ad Advanced_Ads_Ad
853
  * @return bool true if can be displayed
854
  */
855
- static function check_general($options = array(), Advanced_Ads_Ad $ad) {
856
 
857
- // display by default
858
- if (!isset($options['value']) || !is_array($options['value']) || !count($options['value'])) {
859
- return true;
860
- }
861
 
862
- // check general conditions added by other add-ons
863
- if ( null !== ( $result = apply_filters( 'advanced-ads-display-conditions-check-general', null, $options['value'] ) ) ) {
864
- return $result;
865
- }
866
 
867
- // skip checks, if general conditions are unchanged
868
- if( self::$default_general_keys === $options['value'] ){
869
- return true;
870
- }
871
-
872
- // get plugin options
873
- $plugin_options = Advanced_Ads_Plugin::get_instance()->options();
874
-
875
- // error_log(print_r($options, true));
876
- // error_log(print_r(debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), true));
877
-
878
- $ad_options = $ad->options();
879
- $query = $ad_options['wp_the_query'];
880
-
881
- // check main query
882
- if ( isset( $query['is_main_query'] ) && ! $query['is_main_query'] && ! in_array('is_main_query', $options['value'] ) ) {
883
- return false;
884
- }
885
-
886
- // check home page
887
- if ( ( ( isset($query['is_front_page']) && $query['is_front_page'] )
888
- || ( isset($query['is_home']) && $query['is_home'] ) )
889
- && in_array('is_front_page', $options['value'])
890
- ) {
891
- return true;
892
- } elseif (isset($query['is_front_page']) && $query['is_front_page'] && (
893
- !in_array('is_front_page', $options['value'])
894
- )) {
895
- return false;
896
- }
897
 
898
- // check common tests
899
- foreach (self::$query_var_keys as $_type) {
900
- if ('is_main_query' !== $_type && isset($query[$_type]) && $query[$_type] &&
901
- in_array($_type, $options['value'])) {
902
- return true;
 
903
  }
904
- }
905
 
906
- return false;
907
  }
908
 
909
  /**
910
  * Check 'content age' condition in frontend.
911
  *
912
- * @param array $options options of the condition.
913
- * @param object $ad Advanced_Ads_Ad.
 
914
  * @return bool true if can be displayed
915
  */
916
  public static function check_content_age( $options = array(), Advanced_Ads_Ad $ad ) {
@@ -940,117 +1107,118 @@ class Advanced_Ads_Display_Conditions {
940
  }
941
 
942
  /**
943
- * helper function to check for in array values
944
- *
945
- * @param mixed $id scalar (key) or array of keys as needle
946
- * @param array $ids haystack
947
  *
948
  * @return boolean void if either argument is empty
949
  */
950
- static function in_array($id, $ids) {
951
- // empty?
952
- if (!isset($id) || $id === array()) {
953
- return;
954
- }
955
 
956
- // invalid?
957
- if (!is_array($ids)) {
958
- return;
959
- }
960
 
961
- return is_array($id) ? array_intersect($id, $ids) !== array() : in_array($id, $ids);
962
  }
963
 
964
  /**
965
- * helper to compare ids
966
- *
967
- * @param arr $needle ids that should be searched for in haystack
968
- * @param arr $haystack reference ids
969
- * @param str $operator whether it should be included or not
 
970
  * @return boolean
971
  */
972
- static function can_display_ids($needle, $haystack, $operator = 'is') {
973
 
974
- if ('is' === $operator && self::in_array($needle, $haystack) === false) {
975
- return false;
976
- }
977
 
978
- if ('is_not' === $operator && self::in_array($needle, $haystack) === true) {
979
- return false;
980
- }
981
 
982
- return true;
983
  }
984
 
985
  /**
986
- * check display conditions
987
  *
988
- * @since 1.1.0 moved here from can_display()
989
- * @since 1.7.0 moved here from display-by-query module
990
  * @return bool $can_display true if can be displayed in frontend
 
 
991
  */
992
- public function can_display($can_display, $ad) {
993
- if (!$can_display) {
994
- return false;
995
- }
996
-
997
- $options = $ad->options();
998
- if (
999
- // test if anything is to be limited at all
1000
- !isset($options['conditions']) || !is_array($options['conditions'])
1001
- // query arguments required
1002
- || !isset($options['wp_the_query'])
1003
- ) {
1004
- return true;
1005
- }
1006
- // get conditions with rebased index keys
1007
- $conditions = array_values( $options['conditions'] );
1008
- $query = $options['wp_the_query'];
1009
- $post = isset($options['post']) ? $options['post'] : null;
1010
-
1011
-
1012
- $last_result = false;
1013
- $length = count( $conditions );
1014
-
1015
- for($i = 0; $i < $length; ++$i) {
1016
- $_condition = current( $conditions );
1017
- $next = next( $conditions );
1018
- $next_key = key( $conditions );
1019
-
1020
- /**
1021
- * force next condition’s connector to OR if
1022
- * not set to OR already
1023
- * this condition and the next are from the same taxonomy
1024
- * the conditions don’t have the same condition type
1025
- * they are both set to SHOW
1026
- */
1027
- $tax = ( isset( $_condition['type'] ) && isset( $this->conditions[ $_condition['type'] ]['taxonomy'] ) ) ? $this->conditions[ $_condition['type'] ]['taxonomy'] : false;
1028
- $next_tax = ( isset( $next['type'] ) && isset( $this->conditions[ $next['type'] ]['taxonomy'] ) ) ? $this->conditions[ $next['type'] ]['taxonomy'] : false;
1029
- if( $tax && $next_tax && $next_key
1030
- && $next_tax === $tax
1031
- && ( ! isset( $next['connector'] ) || $next['connector'] !== 'or' )
1032
- && 'is' === $_condition['operator'] && 'is' === $next['operator']
1033
- && $_condition['type'] !== $next['type'] ){
1034
- // error_log(print_r('force_or', true));
1035
- $next['connector'] = 'or';
1036
- $conditions[ $next_key ]['connector'] = 'or';
1037
  }
1038
-
1039
- // ignore OR if last result was true
1040
- if( $last_result && isset( $_condition['connector'] ) && 'or' === $_condition['connector'] ){
1041
- continue;
 
 
 
 
 
1042
  }
1043
-
1044
- $last_result = $result = self::frontend_check($_condition, $ad);
1045
- if( ! $result ) {
1046
- // return false only, if the next condition doesn’t have an OR operator
1047
- if( ! isset( $next['connector'] ) || $next['connector'] !== 'or' ) {
1048
- return false;
1049
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1050
  }
1051
- }
1052
 
1053
- return true;
1054
  }
1055
 
1056
  /**
@@ -1059,136 +1227,142 @@ class Advanced_Ads_Display_Conditions {
1059
  * Existing arguments must not be overridden.
1060
  * Some arguments might be cachable.
1061
  *
1062
- * @param array $args
1063
  *
1064
  * @return array
1065
  */
1066
- public function ad_select_args_callback($args) {
1067
- global $post, $wp_the_query, $wp_query, $numpages;
1068
 
1069
- if (isset($post)) {
1070
- if (!isset($args['post'])) {
1071
- $args['post'] = array();
1072
- }
1073
- if (!isset($args['post']['id'])) {
1074
-
1075
- // if currently on a single site, use the main query information just in case a custom query is broken
1076
- if( isset( $wp_the_query->post->ID ) && $wp_the_query->is_single() ){
1077
- $args['post']['id'] = $wp_the_query->post->ID;
1078
- } else {
1079
- $args['post']['id'] = $post->ID;
1080
- }
1081
- }
1082
- if (!isset($args['post']['author'])) {
1083
- // if currently on a single site, use the main query information just in case a custom query is broken
1084
- if( isset( $wp_the_query->post->post_author ) && $wp_the_query->is_single() ){
1085
- $args['post']['author'] = $wp_the_query->post->post_author;
1086
- } else {
1087
- $args['post']['author'] = $post->post_author;
1088
- }
1089
- }
1090
- if (!isset($args['post']['post_type'])) {
1091
- // if currently on a single site, use the main query information just in case a custom query is broken
1092
- if( isset( $wp_the_query->post->post_type ) && $wp_the_query->is_single() ){
1093
- $args['post']['post_type'] = $wp_the_query->post->post_type;
1094
- } else {
1095
- $args['post']['post_type'] = $post->post_type;
1096
- }
 
 
 
1097
  }
1098
- }
1099
 
1100
- // pass query arguments
1101
- if (isset($wp_the_query)) {
1102
- if (!isset($args['wp_the_query'])) {
1103
- $args['wp_the_query'] = array();
1104
- }
1105
- $query = $wp_the_query->get_queried_object();
1106
- // term_id exists only for taxonomy archive pages
1107
- if (!isset($args['wp_the_query']['term_id']) && $query) {
1108
- $args['wp_the_query']['term_id'] = isset($query->term_id) ? $query->term_id : '';
1109
- }
1110
- // taxonomy
1111
- if (!isset($args['wp_the_query']['taxonomy']) && $query) {
1112
- $args['wp_the_query']['taxonomy'] = isset($query->taxonomy) ? $query->taxonomy : '';
1113
- }
1114
 
1115
- // query type/ context
1116
- if (!isset($args['wp_the_query']['is_main_query'])) {
1117
- $args['wp_the_query']['is_main_query'] = Advanced_Ads::get_instance()->is_main_query();
1118
- }
1119
 
1120
- // `<!-- nextpage -->` tags
1121
- if ( ! isset( $args['wp_the_query']['page'] ) ) {
1122
- $args['wp_the_query']['page'] = isset( $wp_the_query->query_vars['page'] ) && $wp_the_query->query_vars['page'] ? $wp_the_query->query_vars['page'] : 1;
1123
- $args['wp_the_query']['numpages'] = isset( $numpages ) ? $numpages : 1;
1124
- }
1125
 
1126
- // query vars
1127
- foreach (self::$query_var_keys as $key) {
1128
- if (!isset($args['wp_the_query'][$key])) {
1129
- $args['wp_the_query'][$key] = $wp_the_query->$key();
1130
- }
 
1131
  }
1132
- }
1133
 
1134
- return $args;
1135
  }
1136
 
1137
  /**
1138
- * modify post search query to search by post_title or ID
1139
  *
1140
- * @param array $query
1141
- * @return string
 
1142
  */
1143
  public static function modify_post_search( $query ) {
1144
-
1145
- // use ID and not search field if ID given
1146
- if( 0 !== absint( $query['s'] ) && strlen( $query['s'] ) == strlen ( absint( $query['s'] ) ) ){
1147
- $query['post__in'] = array( absint( $query['s'] ));
1148
- unset( $query['s'] );
1149
  }
1150
-
1151
  $query['suppress_filters'] = false;
1152
- $query['orderby'] = 'post_title';
1153
- $query['post_status'] = array( 'publish', 'pending', 'draft', 'future' );
 
1154
  return $query;
1155
  }
1156
 
1157
  /**
1158
- * modify post search sql to search only in post title
 
 
1159
  *
1160
- * @param string $sql
1161
  * @return string
1162
  */
1163
  public static function modify_post_search_sql( $sql ) {
1164
  global $wpdb;
1165
-
1166
  // $sql = preg_replace_callback( "/{$wpdb->posts}.post_(content|excerpt)( NOT)? LIKE '%(.*?)%'/", array( 'Advanced_Ads_Display_Conditions', 'modify_post_search_sql_callback' ), $sql );
1167
-
1168
- // removes the search in content and excerpt columns
1169
  $sql = preg_replace( "/OR \({$wpdb->posts}.post_(content|excerpt)( NOT)? LIKE '(.*?)'\)/", '', $sql );
1170
-
1171
  return $sql;
1172
  }
1173
 
1174
  /**
1175
- * preg_replace callback used in modify_post_search_sql()
 
 
1176
  *
1177
- * @param array $matches
1178
  * @return string
1179
  * @deprecated since version 1.8.16
1180
  */
1181
  public static function modify_post_search_sql_callback( $matches ) {
1182
  global $wpdb;
1183
- if ( $matches[1] === 'content' && preg_match( '@^([0-9]+)$@', $matches[3], $matches_id ) ) {
1184
- $equals_op = $matches[2] === ' NOT' ? '!=' : '=';
 
1185
  return "{$wpdb->posts}.ID$equals_op$matches_id[1]";
1186
- } else if ( $matches[2] === ' NOT' ) {
1187
  return '1=1';
1188
  } else {
1189
  return '1=0';
1190
  }
1191
  }
1192
 
1193
- }
1194
-
8
  */
9
  class Advanced_Ads_Display_Conditions {
10
 
11
+ /**
12
+ * Advanced_Ads_Display_Conditions
13
+ *
14
+ * @var Advanced_Ads_Display_Conditions
15
+ */
16
+ protected static $instance;
17
+
18
+ /**
19
+ * Conditonis
20
+ *
21
+ * Registered display conditions.
22
+ *
23
+ * @var $conditions
24
+ */
25
+ public $conditions;
26
+
27
+ /**
28
+ * Start of name in form elements
29
+ */
30
+ const FORM_NAME = 'advanced_ad[conditions]';
31
+
32
+ /**
33
+ * List of query var values
34
+ *
35
+ * @var array
36
+ */
37
+ protected static $query_var_keys = array(
38
+ // 'is_single',
39
+ 'is_archive',
40
+ 'is_search',
41
+ 'is_home',
42
+ 'is_404',
43
+ 'is_attachment',
44
+ 'is_singular',
45
+ 'is_front_page',
46
+ 'is_feed',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  );
48
+
49
+ /**
50
+ * List of options for the General Conditions
51
+ *
52
+ * @var array
53
+ */
54
+
55
+ protected static $default_general_keys = array(
56
+ 'is_front_page',
57
+ 'is_singular',
58
+ 'is_archive',
59
+ 'is_search',
60
+ 'is_404',
61
+ 'is_attachment',
62
+ 'is_main_query',
63
+ 'is_feed',
64
+ );
65
+
66
+ /**
67
+ * Constructor
68
+ */
69
+ private function __construct() {
70
+
71
+ // register filter.
72
+ add_filter( 'advanced-ads-ad-select-args', array( $this, 'ad_select_args_callback' ) );
73
+ add_filter( 'advanced-ads-can-display', array( $this, 'can_display' ), 10, 2 );
74
+
75
+ // register conditions with init hook, register as late as possible so other plugins can use the same hook to add new taxonomies.
76
+ add_action( 'init', array( $this, 'register_conditions' ), 100 );
77
+ }
78
+
79
+ /**
80
+ * Register display conditions
81
+ *
82
+ * @since 1.7.1.4
83
+ */
84
+ public function register_conditions() {
85
+ $conditions = array(
86
+ // post types condition.
87
+ 'posttypes' => array(
88
+ 'label' => __( 'post type', 'advanced-ads' ),
89
+ 'description' => __( 'Choose the public post types on which to display the ad.', 'advanced-ads' ),
90
+ 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_post_type' ), // callback to generate the metabox.
91
+ 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_post_type' ), // callback for frontend check
92
+ // 'helplink' => ADVADS_URL . 'manual/display-ads-either-on-mobile-or-desktop/#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor-mobile' // link to help section
93
+ ),
94
+ // post id condition.
95
+ 'postids' => array(
96
+ 'label' => __( 'specific pages', 'advanced-ads' ),
97
+ 'description' => __( 'Choose on which individual posts, pages and public post type pages you want to display or hide ads.', 'advanced-ads' ),
98
+ 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_post_ids' ), // callback to generate the metabox.
99
+ 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_post_ids' ), // callback for frontend check.
100
+ ),
101
+ // general conditions.
102
+ 'general' => array(
103
+ 'label' => __( 'general conditions', 'advanced-ads' ),
104
+ // 'description' => __( 'Choose on which individual posts, pages and public post type pages you want to display or hide ads.', 'advanced-ads' ),
105
+ 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_general' ), // callback to generate the metabox.
106
+ 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_general' ), // callback for frontend check.
107
+ ),
108
+ // author conditions.
109
+ 'author' => array(
110
+ 'label' => __( 'author', 'advanced-ads' ),
111
+ // 'description' => __( 'Choose on which individual posts, pages and public post type pages you want to display or hide ads.', 'advanced-ads' ),
112
+ 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_author' ), // callback to generate the metabox.
113
+ 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_author' ), // callback for frontend check.
114
+ ),
115
+ // display ads only in content older or younger than a specific age.
116
+ 'content_age' => array(
117
+ 'label' => __( 'content age', 'advanced-ads' ),
118
+ 'description' => __( 'Display ads based on age of the page.', 'advanced-ads' ),
119
+ 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_content_age' ), // callback to generate the metabox.
120
+ 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_content_age' ), // callback for frontend check.
121
+ ),
122
+ // condition for taxonomies in general.
123
+ 'taxonomy' => array(
124
+ 'label' => __( 'taxonomy', 'advanced-ads' ),
125
+ 'description' => __( 'Display ads based on the taxonomy of an archive page.', 'advanced-ads' ),
126
+ 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_taxonomies' ), // callback to generate the metabox.
127
+ 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_taxonomy' ), // callback for frontend check.
128
+ ),
129
+ );
130
+
131
+ // register a condition for each taxonomy for posts.
132
+ $taxonomies = get_taxonomies( array( 'public' => true, 'publicly_queryable' => true ), 'objects', 'or' );
133
+
134
+ $tax_label_counts = array();
135
+
136
+ foreach ( $taxonomies as $_tax ) :
137
+ if ( in_array( $_tax->name, array( 'advanced_ads_groups' ), true ) ) {
138
+ continue;
139
+ }
140
+
141
+ /**
142
+ * Count names of taxonomies and adjust label if there are duplicates.
143
+ * we can’t use `array_count_values` here because "label" might not always be a simple string (though it should be)
144
+ */
145
+ $tax_label_counts[ $_tax->label ] = isset( $tax_label_counts[ $_tax->label ] ) ? $tax_label_counts[ $_tax->label ] + 1 : $tax_label_counts[ $_tax->label ] = 1;
146
+
147
+ // add tax type to label if we find it multiple times.
148
+ if ( $tax_label_counts[ $_tax->label ] < 2 ) {
149
+ $label = $_tax->label;
150
+ $archive_label = $_tax->labels->singular_name;
151
+ } else {
152
+ $label = sprintf( '%s (%s)', $_tax->label, $_tax->name );
153
+ $archive_label = sprintf( '%s (%s)', $_tax->labels->singular_name, $_tax->name );
154
+ }
155
+
156
+ $conditions[ 'taxonomy_' . $_tax->name ] = array(
157
+ 'label' => $label,
158
+ // 'description' => sprintf(__( 'Choose terms from the %s taxonomy a post must belong to for showing or hiding ads.', 'advanced-ads' ), $_tax->label ),
159
+ 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_taxonomy_terms' ), // callback to generate the metabox
160
+ 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_taxonomies' ), // callback for frontend check
161
+ 'taxonomy' => $_tax->name, // unique for this type: the taxonomy name
162
+ );
163
+
164
+ $conditions[ 'archive_' . $_tax->name ] = array(
165
+ 'label' => sprintf( __( 'archive: %s', 'advanced-ads' ), $archive_label ),
166
+ // 'description' => sprintf(__( 'Choose on which %s archive page ads are hidden or displayeds.', 'advanced-ads' ), $_tax->label ),
167
+ 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_taxonomy_terms' ), // callback to generate the metabox.
168
+ 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_taxonomy_archive' ), // callback for frontend check.
169
+ 'taxonomy' => $_tax->name, // unique for this type: the taxonomy name.
170
+ );
171
+ endforeach;
172
+
173
+ $this->conditions = apply_filters( 'advanced-ads-display-conditions', $conditions );
174
+ }
175
+
176
+ /**
177
+ * Instance of Advanced_Ads_Plugin
178
+ *
179
+ * @return Advanced_Ads_Plugin
180
+ */
181
+ public static function get_instance() {
182
+ // If the single instance hasn't been set, set it now.
183
+ if ( null === self::$instance ) {
184
+ self::$instance = new self();
185
+ }
186
+
187
+ return self::$instance;
188
+ }
189
+
190
+
191
+ /**
192
+ * Get the conditions array alphabetically by label
193
+ *
194
+ * @since 1.8.12
195
+ */
196
+ public function get_conditions() {
197
+ uasort( $this->conditions, 'Advanced_Ads_Admin::sort_condition_array_by_label' );
198
+
199
+ return $this->conditions;
200
+ }
201
+
202
+ /**
203
+ * Controls frontend checks for conditions
204
+ *
205
+ * @param array $options options of the condition.
206
+ * @param Advanced_Ads_Ad $ad ad.
207
+ *
208
+ * @return bool false, if ad can’t be delivered
209
+ */
210
+ public static function frontend_check( $options = array(), $ad = false ) {
211
+ $display_conditions = self::get_instance()->conditions;
212
+
213
+ if ( is_array( $options ) && isset( $options['type'] ) && isset( $display_conditions[ $options['type'] ]['check'] ) ) {
214
+ $check = $display_conditions[ $options['type'] ]['check'];
215
+ } else {
216
+ return true;
217
+ }
218
+
219
+ // call frontend check callback.
220
+ if ( method_exists( $check[0], $check[1] ) ) {
221
+ return call_user_func( array( $check[0], $check[1] ), $options, $ad );
222
+ }
223
+
224
+ return true;
225
+ }
226
+
227
+ /**
228
+ * Render the list of set display conditions
229
+ *
230
+ * @param array $set_conditions array of existing conditions.
231
+ * @param string $list_target ID of the list with the conditions.
232
+ * @param string $form_name prefix of the form field name attribute.
233
+ */
234
+ public static function render_condition_list( array $set_conditions, $list_target = '', $form_name = '' ) {
235
+
236
+ $conditions = self::get_instance()->get_conditions();
237
+
238
+ // use default form name if not given explicitly.
239
+ // @todo create a random form name, in case we have more than one form per page and the parameter is not given.
240
+ $form_name = ! $form_name ? self::FORM_NAME : $form_name;
241
+
242
+ include ADVADS_BASE_PATH . 'admin/views/conditions/display-conditions-list.php';
243
+
244
+ /**
245
+ * Prepare condition form
246
+ *
247
+ * @todo if needed, allow to disable the form to add new conditions
248
+ */
249
+
250
+ // add mockup conditions if add-ons are missing.
251
+ $pro_conditions = array();
252
+ if ( ! defined( 'AAP_VERSION' ) ) {
253
+ $pro_conditions[] = __( 'parent page', 'advanced-ads' );
254
+ $pro_conditions[] = __( 'post meta', 'advanced-ads' );
255
+ $pro_conditions[] = __( 'page template', 'advanced-ads' );
256
+ $pro_conditions[] = __( 'url parameters', 'advanced-ads' );
257
+ }
258
+ if ( ! defined( 'AAR_VERSION' ) ) {
259
+ $pro_conditions[] = __( 'accelerated mobile pages', 'advanced-ads' );
260
+ }
261
+ asort( $pro_conditions );
262
+
263
+ // the action to call using AJAX.
264
+ $action = 'load_display_conditions_metabox';
265
+ $connector_default = 'or';
266
+
267
+ include ADVADS_BASE_PATH . 'admin/views/conditions/display-conditions-form-top.php';
268
+ include ADVADS_BASE_PATH . 'admin/views/conditions/conditions-form.php';
269
  }
270
 
271
+ /**
272
+ * Render connector option
273
+ *
274
+ * @param int $index incremental index of the options.
275
+ * @param string $value connector value.
276
+ * @param string $form_name name of the form, falls back to class constant.
277
+ *
278
+ * @return string HTML for connector option.
279
+ * @since 1.7.0.4
280
+ */
281
+ public static function render_connector_option( $index = 0, $value = 'or', $form_name ) {
282
+
283
+ $label = ( 'or' === $value ) ? __( 'or', 'advanced-ads' ) : __( 'and', 'advanced-ads' );
284
+
285
+ $name = self::get_form_name_with_index( $form_name, $index );
286
+
287
+ // create random value to identify the form field.
288
+ $rand = md5( $form_name );
289
+
290
+ return '<input style="display:none;" type="checkbox" name="' . $name . '[connector]' . '" value="or"
291
+ id="advads-conditions-' . $index . '-connector-' . $rand . '"' . checked( 'or', $value, false ) . '>
292
+ <label for="advads-conditions-' . $index . '-connector-' . $rand . '">' . $label . '</label>';
 
 
 
 
 
 
 
293
  }
294
 
295
+ /**
296
+ * Render type field
297
+ *
298
+ * @param string $type type of the current condition.
299
+ * @param string $name name of the form, falls back to class constant.
300
+ */
301
+ public static function render_type_field( $type, $name ) {
302
+
303
+ ?>
304
+ <input type="hidden" name="<?php echo $name; ?>[type]" value="<?php esc_attr_e( $type ); ?>"/>
305
+ <?php
306
+
307
  }
308
 
309
+ /**
310
+ * Helper function to the name of a form field.
311
+ * falls back to default
312
+ *
313
+ * @param string $form_name form name if submitted.
314
+ * @param int $index index of the condition.
315
+ *
316
+ * @return string
317
+ */
318
+ public static function get_form_name_with_index( $form_name = '', $index = 0 ) {
319
+ return ! empty( $form_name ) ? $form_name . '[' . $index . ']' : self::FORM_NAME . '[' . $index . ']';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
  }
321
 
322
+ /**
323
+ * Callback to display the metabox for the post type condition
324
+ *
325
+ * @param array $options options of the condition.
326
+ * @param int $index index of the condition.
327
+ * @param string $form_name name of the form, falls back to class constant.
328
+ */
329
+ public static function metabox_post_type( $options, $index = 0, $form_name = '' ) {
330
+ if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
331
+ return;
332
+ }
333
+
334
+ $type_options = self::get_instance()->conditions;
335
+
336
+ if ( ! isset( $type_options[ $options['type'] ] ) ) {
337
+ return;
338
+ }
339
+
340
+ // get values and select operator based on previous settings.
341
+ $operator = ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) ? 'is_not' : 'is';
342
+ $values = ( isset( $options['value'] ) && is_array( $options['value'] ) ) ? $options['value'] : array();
343
+
344
+ // form name basis.
345
+ $name = self::get_form_name_with_index( $form_name, $index );
346
+
347
+ self::render_type_field( $options['type'], $name );
348
+
349
+ // load operator template.
350
+ include ADVADS_BASE_PATH . 'admin/views/conditions/condition-operator.php';
351
+
352
+ // set defaults.
353
+ $post_types = get_post_types(
354
+ array(
355
+ 'public' => true,
356
+ 'publicly_queryable' => true,
357
+ ),
358
+ 'object',
359
+ 'or'
360
+ );
361
+ ?>
362
+ <div class="advads-conditions-single advads-buttonset"><?php
363
+ $type_label_counts = array_count_values( wp_list_pluck( $post_types, 'label' ) );
364
+
365
+ foreach ( $post_types as $_type_id => $_type ) {
366
+ if ( in_array( $_type_id, $values, true ) ) {
367
+ $_val = 1;
368
+ } else {
369
+ $_val = 0;
370
+ }
371
 
372
+ if ( $type_label_counts[ $_type->label ] < 2 ) {
373
+ $_label = $_type->label;
374
+ } else {
375
+ $_label = sprintf( '%s (%s)', $_type->label, $_type_id );
376
+ }
377
+ ?><label class="button" for="advads-conditions-<?php echo $index; ?>-<?php echo $_type_id;
378
+ ?>"><?php echo $_label ?></label><input type="checkbox"
379
+ id="advads-conditions-<?php echo $index; ?>-<?php echo $_type_id; ?>"
380
+ name="<?php echo $name; ?>[value][]" <?php checked( $_val, 1 ); ?>
381
+ value="<?php echo $_type_id; ?>"><?php
382
+ }
383
+ ?>
384
+ <p class="advads-conditions-not-selected advads-error-message"><?php _ex( 'Please select some items.', 'Error message shown when no display condition term is selected', 'advanced-ads' ); ?></p>
385
+ </div><?php
386
  }
387
 
388
+ /**
389
+ * Callback to display the metabox for the author condition
390
+ *
391
+ * @param array $options options of the condition.
392
+ * @param int $index index of the condition.
393
+ * @param string $form_name name of the form, falls back to class constant.
394
+ */
395
+ public static function metabox_author( $options, $index = 0, $form_name = '' ) {
396
+
397
+ if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
398
+ return;
399
+ }
400
+
401
+ $type_options = self::get_instance()->conditions;
402
+
403
+ if ( ! isset( $type_options[ $options['type'] ] ) ) {
404
+ return;
405
+ }
406
+
407
+ // get values and select operator based on previous settings.
408
+ $operator = ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) ? 'is_not' : 'is';
409
+ $values = ( isset( $options['value'] ) && is_array( $options['value'] ) ) ? $options['value'] : array();
410
+
411
+ // form name basis.
412
+ $name = self::get_form_name_with_index( $form_name, $index );
413
+
414
+ self::render_type_field( $options['type'], $name );
415
+
416
+ // load operator template.
417
+ include ADVADS_BASE_PATH . 'admin/views/conditions/condition-operator.php';
418
+
419
+ // set defaults.
420
+ $max_authors = absint( apply_filters( 'advanced-ads-admin-max-terms', 50 ) );
421
+ $authors = get_users(
422
+ array(
423
+ 'who' => 'authors',
424
+ 'orderby' => 'nicename',
425
+ 'number' => $max_authors,
426
+ )
427
+ );
428
+
429
+ include ADVADS_BASE_PATH . 'admin/views/conditions/condition-author.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
430
  }
 
 
 
431
 
432
  /**
433
+ * Callback to display the metabox for the taxonomy archive pages
434
  *
435
+ * @param array $options options of the condition.
436
+ * @param int $index index of the condition.
437
+ * @param string $form_name name of the form, falls back to class constant.
438
  */
439
+ public static function metabox_taxonomy_terms( $options, $index = 0, $form_name = '' ) {
440
 
441
+ if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
442
+ return;
443
  }
444
 
445
  $type_options = self::get_instance()->conditions;
446
 
447
+ // don’t use if this is not a taxonomy.
448
+ if ( ! isset( $type_options[ $options['type'] ] ) || ! isset( $type_options[ $options['type'] ]['taxonomy'] ) ) {
449
+ return;
450
  }
451
 
452
+ $taxonomy = get_taxonomy( $type_options[ $options['type'] ]['taxonomy'] );
453
+ if ( $taxonomy == false ) {
454
+ return;
455
  }
456
 
457
+ // get values and select operator based on previous settings.
458
+ $operator = ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) ? 'is_not' : 'is';
459
+ $values = ( isset( $options['value'] ) && is_array( $options['value'] ) ) ? $options['value'] : array();
460
 
461
+ // limit the number of terms so many terms don’t break the admin page.
462
+ $max_terms = absint( apply_filters( 'advanced-ads-admin-max-terms', 50 ) );
463
 
464
+ // form name basis.
465
+ $name = self::get_form_name_with_index( $form_name, $index );
466
+
467
+ self::render_type_field( $options['type'], $name );
468
+
469
+ // load operator template.
470
+ include ADVADS_BASE_PATH . 'admin/views/conditions/condition-operator.php';
471
+
472
+ ?>
473
+ <div class="advads-conditions-single advads-buttonset">
474
+ <?php
475
+ self::display_term_list( $taxonomy, $values, $name . '[value][]', $max_terms, $index );
476
  ?></div><?php
477
  }
478
+
479
  /**
480
+ * Callback to display the metabox for the taxonomies
481
  *
482
+ * @param array $options options of the condition.
483
+ * @param int $index index of the condition.
484
+ * @param string $form_name name of the form, falls back to class constant.
485
  */
486
+ public static function metabox_taxonomies( $options, $index = 0, $form_name = '' ) {
487
 
488
+ if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
489
+ return;
490
  }
491
 
492
  $taxonomies = get_taxonomies( array( 'public' => 1 ), 'objects' );
493
+
494
+ $name = self::get_form_name_with_index( $form_name, $index );
495
+
496
+ // get values and select operator based on previous settings.
497
+ $operator = ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) ? 'is_not' : 'is';
498
+ $values = ( isset( $options['value'] ) && is_array( $options['value'] ) ) ? $options['value'] : array();
499
+
500
+ self::render_type_field( $options['type'], $name );
501
+
502
+ ?>
503
+ <div class="advads-conditions-single advads-buttonset">
504
+ <?php
505
+ $tax_label_counts = array_count_values( wp_list_pluck( $taxonomies, 'label' ) );
506
+
507
+ foreach ( $taxonomies as $_taxonomy_id => $_taxonomy ) :
508
+
509
+ if ( in_array( $_taxonomy_id, $values ) ) {
510
+ $_val = 1;
511
+ } else {
512
+ $_val = 0;
513
+ }
514
+
515
+ if ( $tax_label_counts[ $_taxonomy->label ] < 2 ) {
516
+ $_label = $_taxonomy->label;
517
+ } else {
518
+ $_label = sprintf( '%s (%s)', $_taxonomy->label, $_taxonomy_id );
519
+ }
520
+ ?><label class="button" for="advads-conditions-<?php echo $index; ?>-<?php echo $_taxonomy_id;
521
+ ?>"><?php echo $_label ?></label><input type="checkbox"
522
+ id="advads-conditions-<?php echo $index; ?>-<?php echo $_taxonomy_id; ?>"
523
+ name="<?php echo $name; ?>[value][]" <?php checked( $_val, 1 ); ?>
524
+ value="<?php echo $_taxonomy_id; ?>"><?php
525
+ endforeach;
526
+ ?>
527
+ <p class="advads-conditions-not-selected advads-error-message"><?php echo esc_attr_x( 'Please select some items.', 'Error message shown when no display condition term is selected', 'advanced-ads' ); ?></p>
528
+ </div>
529
+ <?php
530
  }
531
 
532
  /**
533
+ * Display terms of a taxonomy for choice
534
+ *
535
+ * @param object $taxonomy taxonomy object.
536
+ * @param array $checked ids of checked terms.
537
+ * @param string $inputname name of the input field.
538
+ * @param int $max_terms maximum number of terms to show.
539
+ * @param int $index index of the conditions group.
540
  */
541
+ public static function display_term_list( $taxonomy, $checked = array(), $inputname = '', $max_terms = 50, $index = 0 ) {
542
+
543
+ $terms = get_terms(
544
+ $taxonomy->name,
545
+ array(
546
+ 'hide_empty' => false,
547
+ 'number' => $max_terms,
548
+ )
549
+ );
550
+
551
+ if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) :
552
+ // display search field if the term limit is reached.
553
+ if ( count( $terms ) == $max_terms ) :
554
+
555
+ // query active terms.
556
+ if ( is_array( $checked ) && count( $checked ) ) {
557
+ $args = array( 'hide_empty' => false );
558
+ $args['include'] = $checked;
559
+ $checked_terms = get_terms( $taxonomy->name, $args );
560
+ ?>
561
+ <div class="advads-conditions-terms-buttons dynamic-search"><?php
562
+ foreach ( $checked_terms as $_checked_term ) :
563
+ ?><label class="button ui-state-active"><?php echo $_checked_term->name;
564
+ ?><input type="hidden" name="<?php echo $inputname; ?>"
565
+ value="<?php echo $_checked_term->term_id; ?>"></label><?php
566
+ endforeach;
567
+ ?></div><?php
568
+ } else {
569
+ ?>
570
+ <div class="advads-conditions-terms-buttons dynamic-search"></div><?php
571
+ }
572
+ ?><span class="advads-conditions-terms-show-search button" title="<?php
573
+ _ex( 'add more terms', 'display the terms search field on ad edit page', 'advanced-ads' );
574
+ ?>">+</span><br/><input type="text" class="advads-conditions-terms-search"
575
+ data-tag-name="<?php echo $taxonomy->name;
576
+ ?>" data-input-name="<?php echo $inputname; ?>"
577
+ placeholder="<?php _e( 'term name or id', 'advanced-ads' ); ?>"/><?php
578
+ else :
579
+ ?>
580
+ <div class="advads-conditions-terms-buttons advads-buttonset"><?php
581
+ foreach ( $terms as $_term ) :
582
+ $field_id = "advads-conditions-$index-$_term->term_id";
583
+ ?><input type="checkbox" id="<?php echo $field_id; ?>" name="<?php echo $inputname; ?>"
584
+ value="<?php echo $_term->term_id; ?>" <?php checked( in_array( $_term->term_id, $checked ), true );
585
+ ?>><label for="<?php echo $field_id; ?>"><?php echo $_term->name; ?></label><?php
586
+ endforeach;
587
+ ?>
588
+ <p class="advads-conditions-not-selected advads-error-message"><?php _ex( 'Please select some items.', 'Error message shown when no display condition term is selected', 'advanced-ads' ); ?></p>
589
+ </div><?php
590
+ endif;
591
+ endif;
592
  }
593
 
594
+ /**
595
+ * Callback to display the metabox for the taxonomy archive pages
596
+ *
597
+ * @param array $options options of the condition.
598
+ * @param int $index index of the condition.
599
+ * @param string $form_name name of the form, falls back to class constant.
600
+ */
601
+ public static function metabox_post_ids( $options, $index = 0, $form_name = '' ) {
602
+
603
+ if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
604
+ return;
605
+ }
606
+
607
+ // get values and select operator based on previous settings.
608
+ $operator = ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) ? 'is_not' : 'is';
609
+ $values = ( isset( $options['value'] ) && is_array( $options['value'] ) ) ? $options['value'] : array();
610
+
611
+ // form name basis.
612
+ $name = self::get_form_name_with_index( $form_name, $index );
613
+
614
+ self::render_type_field( $options['type'], $name );
615
+
616
+ // load operator template.
617
+ include ADVADS_BASE_PATH . 'admin/views/conditions/condition-operator.php';
618
+
619
+ ?>
620
+ <div class="advads-conditions-single advads-buttonset advads-conditions-postid-buttons">
621
+ <?php
622
+ // query active post ids.
623
+ if ( array() !== $values ) {
624
+ $args = array(
625
+ 'post_type' => 'any',
626
+ 'post__in' => $values,
627
+ 'posts_per_page' => - 1,
628
+ 'order' => 'ASC',
629
+ 'order_by' => 'title',
630
+
631
+ );
632
+
633
+ $the_query = new WP_Query( $args );
634
+ while ( $the_query->have_posts() ) {
635
+ $the_query->next_post();
636
+ ?><label
637
+ class="button ui-state-active"><?php echo get_the_title( $the_query->post->ID ) . ' (' . $the_query->post->post_type . ')';
638
+ ?><input type="hidden" name="<?php echo $name; ?>[value][]" value="<?php echo $the_query->post->ID; ?>">
639
+ </label><?php
640
+ }
641
+ }
642
+ ?><span class="advads-conditions-postids-show-search button" <?php
643
+ if ( ! count( $values ) ) {
644
+ echo 'style="display:none;"';
645
+ }
646
+ ?>>+</span>
647
+ <p class="advads-conditions-postids-search-line">
648
+ <input type="text" class="advads-display-conditions-individual-post" <?php if ( count( $values ) ) {
649
+ echo 'style="display:none;"';
650
+ } ?>
651
+ placeholder="<?php _e( 'title or id', 'advanced-ads' ); ?>"
652
+ data-field-name="<?php echo $name; ?>"/><?php
653
+ wp_nonce_field( 'internal-linking', '_ajax_linking_nonce', false );
654
+ ?></p></div><?php
655
  }
656
 
657
+ /**
658
+ * Callback to display the metabox for the general display conditions
659
+ *
660
+ * @param array $options options of the condition.
661
+ * @param int $index index of the condition.
662
+ * @param string $form_name name of the form, falls back to class constant.
663
+ */
664
+ public static function metabox_general( $options, $index = 0, $form_name = '' ) {
665
+
666
+ // general conditions array.
667
+ $conditions = self::get_instance()->general_conditions();
668
+ if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
669
+ return;
670
+ }
671
 
672
+ $name = self::get_form_name_with_index( $form_name, $index );
673
+ $values = isset( $options['value'] ) ? $options['value'] : array();
674
+ ?>
675
+ <div class="advads-conditions-single advads-buttonset">
676
+ <?php
677
 
678
+ self::render_type_field( $options['type'], $name );
679
+
680
+ foreach ( $conditions as $_key => $_condition ) :
681
+
682
+ // activate by default.
683
+ $value = ( array() === $values || in_array( $_key, $values, true ) ) ? 1 : 0;
684
+
685
+ $field_id = "advads-conditions-$index-$_key";
686
+ ?><input type="checkbox" id="<?php echo $field_id; ?>" name="<?php echo $name; ?>[value][]"
687
+ value="<?php echo $_key; ?>" <?php checked( 1, $value ); ?>><label
688
+ for="<?php echo $field_id; ?>"><?php echo $_condition['label']; ?></label><?php
689
+ endforeach;
690
+ ?></div><?php
691
+ return;
692
+ }
693
 
694
  /**
695
+ * Retrieve the array with general conditions
696
+ *
697
+ * @return array $conditions
 
698
  */
699
+ public static function general_conditions() {
700
+ return $conditions = apply_filters( 'advanced-ads-display-conditions-general',
701
+ array(
702
+ 'is_front_page' => array(
703
+ 'label' => __( 'Home Page', 'advanced-ads' ),
704
+ 'description' => __( 'show on Home page', 'advanced-ads' ),
705
+ 'type' => 'radio',
706
+ ),
707
+ 'is_singular' => array(
708
+ 'label' => __( 'Singular Pages', 'advanced-ads' ),
709
+ 'description' => __( 'show on singular pages/posts', 'advanced-ads' ),
710
+ 'type' => 'radio',
711
+ ),
712
+ 'is_archive' => array(
713
+ 'label' => __( 'Archive Pages', 'advanced-ads' ),
714
+ 'description' => __( 'show on any type of archive page (category, tag, author and date)', 'advanced-ads' ),
715
+ 'type' => 'radio',
716
+ ),
717
+ 'is_search' => array(
718
+ 'label' => __( 'Search Results', 'advanced-ads' ),
719
+ 'description' => __( 'show on search result pages', 'advanced-ads' ),
720
+ 'type' => 'radio',
721
+ ),
722
+ 'is_404' => array(
723
+ 'label' => __( '404 Page', 'advanced-ads' ),
724
+ 'description' => __( 'show on 404 error page', 'advanced-ads' ),
725
+ 'type' => 'radio',
726
+ ),
727
+ 'is_attachment' => array(
728
+ 'label' => __( 'Attachment Pages', 'advanced-ads' ),
729
+ 'description' => __( 'show on attachment pages', 'advanced-ads' ),
730
+ 'type' => 'radio',
731
+ ),
732
+ 'is_main_query' => array(
733
+ 'label' => __( 'Secondary Queries', 'advanced-ads' ),
734
+ 'description' => __( 'allow ads in secondary queries', 'advanced-ads' ),
735
+ 'type' => 'radio',
736
+ ),
737
+ 'is_feed' => array(
738
+ 'label' => __( 'RSS Feed', 'advanced-ads' ),
739
+ 'description' => __( 'allow ads in RSS Feed', 'advanced-ads' ),
740
+ 'type' => 'radio',
741
+ ),
742
+ )
743
+ );
744
  }
745
+
746
  /**
747
  * Callback to display the 'content age' condition
748
  *
749
+ * @param array $options options of the condition.
750
+ * @param int $index index of the condition.
751
+ * @param string $form_name name of the form, falls back to class constant.
752
  */
753
+ public static function metabox_content_age( $options, $index = 0, $form_name = '' ) {
754
+ if ( ! isset ( $options['type'] ) || '' === $options['type'] ) {
755
+ return;
756
+ }
757
 
758
  $type_options = Advanced_Ads_Display_Conditions::get_instance()->conditions;
759
 
761
  return;
762
  }
763
 
764
+ // form name basis.
765
+ $name = self::get_form_name_with_index( $form_name, $index );
766
 
767
  $operator = isset( $options['operator'] ) ? $options['operator'] : 'older_than';
768
+ $value = ( isset( $options['value'] ) && is_numeric( $options['value'] ) ) ? floatval( $options['value'] ) : 0;
769
+
770
+ self::render_type_field( $options['type'], $name );
771
+
772
+ ?>
773
  <select name="<?php echo $name; ?>[operator]">
774
+ <option value="older_than" <?php selected( 'older_than', $operator ); ?>><?php _e( 'older than', 'advanced-ads' ); ?></option>
775
+ <option value="younger_than" <?php selected( 'younger_than', $operator ); ?>><?php _e( 'younger than', 'advanced-ads' ); ?></option>
776
+ </select><input type="text" name="<?php echo $name; ?>[value]"
777
+ value="<?php echo $value; ?>"/>&nbsp;<?php _e( 'days', 'advanced-ads' );
778
+ }
779
 
780
  /**
781
+ * Check post type display condition in frontend
782
+ *
783
+ * @param array $options options of the condition.
784
+ * @param Advanced_Ads_Ad $ad Advanced_Ads_Ad.
785
  *
 
 
786
  * @return bool true if can be displayed
787
  */
788
+ public static function check_post_type( $options = array(), Advanced_Ads_Ad $ad ) {
789
+ if ( ! isset( $options['value'] ) || ! is_array( $options['value'] ) ) {
790
+ return false;
791
+ }
792
 
793
+ if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
794
+ $operator = 'is_not';
795
+ } else {
796
+ $operator = 'is';
797
+ }
798
 
799
+ $ad_options = $ad->options();
800
+ $query = $ad_options['wp_the_query'];
801
+ $post = isset( $ad_options['post'] ) ? $ad_options['post'] : null;
802
+ $post_type = isset( $post['post_type'] ) ? $post['post_type'] : false;
803
 
804
+ if ( ! self::can_display_ids( $post_type, $options['value'], $operator ) ) {
805
+ return false;
806
+ }
807
 
808
+ return true;
809
  }
810
 
811
  /**
812
+ * Check author display condition in frontend
813
+ *
814
+ * @param array $options options of the condition.
815
+ * @param Advanced_Ads_Ad $ad Advanced_Ads_Ad.
816
  *
 
 
817
  * @return bool true if can be displayed
818
  */
819
+ public static function check_author( $options = array(), Advanced_Ads_Ad $ad ) {
820
 
821
+ if ( ! isset( $options['value'] ) || ! is_array( $options['value'] ) ) {
822
+ return false;
823
+ }
824
 
825
+ if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
826
+ $operator = 'is_not';
827
+ } else {
828
+ $operator = 'is';
829
+ }
830
 
831
+ $ad_options = $ad->options();
832
+ $post = isset( $ad_options['post'] ) ? $ad_options['post'] : null;
833
+ $post_author = isset( $post['author'] ) ? $post['author'] : false;
834
 
835
+ if ( ! self::can_display_ids( $post_author, $options['value'], $operator ) ) {
836
+ return false;
837
+ }
838
 
839
+ return true;
840
  }
841
 
842
  /**
843
+ * Check taxonomies display condition in frontend
844
+ *
845
+ * @param array $options options of the condition.
846
+ * @param Advanced_Ads_Ad $ad ad.
847
  *
 
848
  * @return bool true if can be displayed
849
  */
850
+ public static function check_taxonomies( $options = array(), Advanced_Ads_Ad $ad ) {
851
 
852
+ if ( ! isset( $options['value'] ) ) {
853
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
854
  }
855
+
856
+ if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
857
+ $operator = 'is_not';
858
+ } else {
859
+ $operator = 'is';
860
+ }
861
+
862
+ $ad_options = $ad->options();
863
+ $query = $ad_options['wp_the_query'];
864
+ $post_id = isset( $ad_options['post']['id'] ) ? $ad_options['post']['id'] : null;
865
+
866
+ // get terms of the current taxonomy.
867
+ $type_options = self::get_instance()->conditions;
868
+ if ( ! isset( $options['type'] ) || ! isset( $type_options[ $options['type'] ]['taxonomy'] ) ) {
869
+ return true;
870
+ }
871
+ $taxonomy = $type_options[ $options['type'] ]['taxonomy'];
872
+
873
+ $terms = get_the_terms( $post_id, $taxonomy );
874
+
875
+ if ( is_array( $terms ) ) {
876
+ foreach ( $terms as $term ) {
877
+ $term_ids[] = $term->term_id;
878
+ }
879
+ } elseif ( false === $terms && 'is' === $operator ) {
880
+ // don’t show if should show only for a specific tag.
881
+ return false;
882
+ } else {
883
+ return true;
884
+ }
885
+
886
+ if ( 'is' === $operator && ( ! isset( $query['is_singular'] ) || ! $query['is_singular'] ) ) {
887
+ return false;
888
+ } elseif ( isset( $query['is_singular'] ) && $query['is_singular'] && ! self::can_display_ids( $options['value'], $term_ids, $operator )
889
+ ) {
890
+ return false;
891
+ }
892
+
893
  return true;
 
 
 
 
 
 
 
 
 
 
894
  }
895
 
896
  /**
897
+ * Check taxonomy archive display condition in frontend
898
+ *
899
+ * @param array $options options of the condition.
900
+ * @param Advanced_Ads_Ad $ad ad.
901
  *
 
902
  * @return bool true if can be displayed
903
  */
904
+ public static function check_taxonomy_archive( $options = array(), Advanced_Ads_Ad $ad ) {
905
 
906
+ if ( ! isset( $options['value'] ) ) {
907
+ return false;
908
+ }
909
+
910
+ if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
911
+ $operator = 'is_not';
912
+ } else {
913
+ $operator = 'is';
914
+ }
915
+
916
+ $ad_options = $ad->options();
917
+ $query = $ad_options['wp_the_query'];
918
+
919
+ // return false if operator is "is", but important query vars are not given.
920
+ if ( 'is' === $operator && ( empty( $query['term_id'] ) || empty( $query['is_archive'] ) ) ) {
921
+ return false;
922
+ } elseif ( isset( $query['term_id'] ) && isset( $query['is_archive'] ) && $query['is_archive'] && ! self::can_display_ids( $query['term_id'], $options['value'], $operator )
923
+ ) {
924
+ return false;
925
+ }
926
+
927
+ return true;
928
  }
929
+
930
  /**
931
+ * Check if a specific archive belongs to a taxonomy in general (not a specific term)
932
+ *
933
+ * @param array $options options of the condition.
934
+ * @param Advanced_Ads_Ad $ad ad.
935
  *
 
936
  * @return bool true if can be displayed
937
  */
938
  static function check_taxonomy( $options = array(), Advanced_Ads_Ad $ad ) {
939
 
940
+ if ( ! isset( $options['value'] ) ) {
941
+ return false;
942
+ }
943
+
944
+ if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
945
+ $operator = 'is_not';
946
+ } else {
947
+ $operator = 'is';
948
+ }
949
+
950
+ $ad_options = $ad->options();
951
+ $query = $ad_options['wp_the_query'];
952
+
953
+ // return false if operator is "is", but important query vars are not given.
954
+ if ( 'is' === $operator && ( empty( $query['taxonomy'] ) || empty( $query['is_archive'] ) ) ) {
955
+ return false;
956
+ } elseif ( isset( $query['taxonomy'] ) && isset( $query['is_archive'] ) && $query['is_archive'] && ! self::can_display_ids( $query['taxonomy'], $options['value'], $operator )
957
+ ) {
958
+ return false;
959
+ }
960
+
961
+ return true;
962
  }
963
 
964
  /**
965
+ * Check post ids display condition in frontend
966
+ *
967
+ * @param array $options options of the condition.
968
+ * @param Advanced_Ads_Ad $ad ad.
969
+ *
970
  * @return bool true if can be displayed
971
  */
972
+ public static function check_post_ids( $options = array(), Advanced_Ads_Ad $ad ) {
973
 
974
+ if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
975
+ $operator = 'is_not';
976
  } else {
977
+ $operator = 'is';
978
  }
979
 
980
  $ad_options = $ad->options();
981
+ $query = $ad_options['wp_the_query'];
982
+ $post_id = isset( $ad_options['post']['id'] ) ? $ad_options['post']['id'] : null;
983
+
984
+ // ixes page id on BuddyPress pages.
985
+ if ( 0 === $post_id && class_exists( 'BuddyPress' ) && function_exists( 'bp_current_component' ) ) {
986
+ $component = bp_current_component();
987
+ $bp_pages = get_option( 'bp-pages' );
988
+ if ( isset( $bp_pages[ $component ] ) ) {
989
+ $post_id = $bp_pages[ $component ];
990
+ }
991
+ }
992
+
993
  /**
994
  * WooCommerce Store page fix
995
  * since WooCommerce changes the post ID of the static page selected to be the product overview page, we need to get the original page id from the WC options
996
  */
997
  if ( function_exists( 'is_shop' ) && is_shop() && isset( $options['value'] ) && is_array( $options['value'] ) ) {
998
  $post_id = get_option( 'woocommerce_shop_page_id' );
999
+
1000
+ return self::can_display_ids( $post_id, $options['value'], $operator );
1001
  }
1002
+
1003
+ if ( empty( $ad_options['wp_the_query']['is_singular'] ) ) {
1004
+ if ( 'is_not' === $operator ) {
1005
+ return true;
1006
+ } else {
1007
+ return false;
1008
+ }
1009
  }
1010
 
1011
  if ( ! isset( $options['value'] ) || ! is_array( $options['value'] ) || ! $post_id ) {
1012
  return true;
1013
  }
1014
 
1015
+ return self::can_display_ids( $post_id, $options['value'], $operator );
1016
  }
1017
 
1018
  /**
1019
+ * Check general display conditions in frontend
1020
+ *
1021
+ * @param array $options options of the condition.
1022
+ * @param Advanced_Ads_Ad $ad ad.
1023
  *
 
 
1024
  * @return bool true if can be displayed
1025
  */
1026
+ public static function check_general( $options = array(), Advanced_Ads_Ad $ad ) {
1027
 
1028
+ // display by default.
1029
+ if ( ! isset( $options['value'] ) || ! is_array( $options['value'] ) || ! count( $options['value'] ) ) {
1030
+ return true;
1031
+ }
1032
 
1033
+ // check general conditions added by other add-ons.
1034
+ if ( null !== ( $result = apply_filters( 'advanced-ads-display-conditions-check-general', null, $options['value'] ) ) ) {
1035
+ return $result;
1036
+ }
1037
 
1038
+ // skip checks, if general conditions are unchanged.
1039
+ if ( self::$default_general_keys === $options['value'] ) {
1040
+ return true;
1041
+ }
1042
+
1043
+ // get plugin options.
1044
+ $ad_options = $ad->options();
1045
+ $query = $ad_options['wp_the_query'];
1046
+
1047
+ // check main query.
1048
+ if ( isset( $query['is_main_query'] ) && ! $query['is_main_query'] && ! in_array( 'is_main_query', $options['value'], true ) ) {
1049
+ return false;
1050
+ }
1051
+
1052
+ // check home page.
1053
+ if ( ( ( isset( $query['is_front_page'] ) && $query['is_front_page'] )
1054
+ || ( isset( $query['is_home'] ) && $query['is_home'] ) )
1055
+ && in_array( 'is_front_page', $options['value'], true )
1056
+ ) {
1057
+ return true;
1058
+ } elseif ( isset( $query['is_front_page'] ) && $query['is_front_page'] && (
1059
+ ! in_array( 'is_front_page', $options['value'], true )
1060
+ ) ) {
1061
+ return false;
1062
+ }
 
 
 
 
 
1063
 
1064
+ // check common tests.
1065
+ foreach ( self::$query_var_keys as $_type ) {
1066
+ if ( 'is_main_query' !== $_type && isset( $query[ $_type ] ) && $query[ $_type ] &&
1067
+ in_array( $_type, $options['value'], true ) ) {
1068
+ return true;
1069
+ }
1070
  }
 
1071
 
1072
+ return false;
1073
  }
1074
 
1075
  /**
1076
  * Check 'content age' condition in frontend.
1077
  *
1078
+ * @param array $options options of the condition.
1079
+ * @param Advanced_Ads_Ad $ad ad.
1080
+ *
1081
  * @return bool true if can be displayed
1082
  */
1083
  public static function check_content_age( $options = array(), Advanced_Ads_Ad $ad ) {
1107
  }
1108
 
1109
  /**
1110
+ * Helper function to check for in array values
1111
+ *
1112
+ * @param mixed $id scalar (key) or array of keys as needle.
1113
+ * @param array $ids haystack.
1114
  *
1115
  * @return boolean void if either argument is empty
1116
  */
1117
+ public static function in_array( $id, $ids ) {
1118
+ // empty?
1119
+ if ( ! isset( $id ) || array() === $id ) {
1120
+ return;
1121
+ }
1122
 
1123
+ // invalid?
1124
+ if ( ! is_array( $ids ) ) {
1125
+ return;
1126
+ }
1127
 
1128
+ return is_array( $id ) ? array() !== array_intersect( $id, $ids ) : in_array( $id, $ids );
1129
  }
1130
 
1131
  /**
1132
+ * Helper to compare ids.
1133
+ *
1134
+ * @param array $needle ids that should be searched for in haystack.
1135
+ * @param array $haystack reference ids.
1136
+ * @param string $operator whether it should be included or not.
1137
+ *
1138
  * @return boolean
1139
  */
1140
+ public static function can_display_ids( $needle, $haystack, $operator = 'is' ) {
1141
 
1142
+ if ( 'is' === $operator && self::in_array( $needle, $haystack ) === false ) {
1143
+ return false;
1144
+ }
1145
 
1146
+ if ( 'is_not' === $operator && self::in_array( $needle, $haystack ) === true ) {
1147
+ return false;
1148
+ }
1149
 
1150
+ return true;
1151
  }
1152
 
1153
  /**
1154
+ * Check display conditions
1155
  *
 
 
1156
  * @return bool $can_display true if can be displayed in frontend
1157
+ * @since 1.7.0 moved here from display-by-query module
1158
+ * @since 1.1.0 moved here from can_display()
1159
  */
1160
+ public function can_display( $can_display, $ad ) {
1161
+ if ( ! $can_display ) {
1162
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1163
  }
1164
+
1165
+ $options = $ad->options();
1166
+ if (
1167
+ // test if anything is to be limited at all.
1168
+ ! isset( $options['conditions'] ) || ! is_array( $options['conditions'] )
1169
+ // query arguments required.
1170
+ || ! isset( $options['wp_the_query'] )
1171
+ ) {
1172
+ return true;
1173
  }
1174
+ // get conditions with rebased index keys.
1175
+ $conditions = array_values( $options['conditions'] );
1176
+ $query = $options['wp_the_query'];
1177
+ $post = isset( $options['post'] ) ? $options['post'] : null;
1178
+
1179
+
1180
+ $last_result = false;
1181
+ $length = count( $conditions );
1182
+
1183
+ for ( $i = 0; $i < $length; ++ $i ) {
1184
+ $_condition = current( $conditions );
1185
+ $next = next( $conditions );
1186
+ $next_key = key( $conditions );
1187
+
1188
+ /**
1189
+ * Force next condition’s connector to OR if
1190
+ * not set to OR already
1191
+ * this condition and the next are from the same taxonomy
1192
+ * the conditions don’t have the same condition type
1193
+ * they are both set to SHOW
1194
+ */
1195
+ $tax = ( isset( $_condition['type'] ) && isset( $this->conditions[ $_condition['type'] ]['taxonomy'] ) ) ? $this->conditions[ $_condition['type'] ]['taxonomy'] : false;
1196
+ $next_tax = ( isset( $next['type'] ) && isset( $this->conditions[ $next['type'] ]['taxonomy'] ) ) ? $this->conditions[ $next['type'] ]['taxonomy'] : false;
1197
+ if ( $tax && $next_tax && $next_key
1198
+ && $next_tax === $tax
1199
+ && ( ! isset( $next['connector'] ) || 'or' !== $next['connector'] )
1200
+ && 'is' === $_condition['operator'] && 'is' === $next['operator']
1201
+ && $_condition['type'] !== $next['type'] ) {
1202
+ $next['connector'] = 'or';
1203
+ $conditions[ $next_key ]['connector'] = 'or';
1204
+ }
1205
+
1206
+ // ignore OR if last result was true.
1207
+ if ( $last_result && isset( $_condition['connector'] ) && 'or' === $_condition['connector'] ) {
1208
+ continue;
1209
+ }
1210
+
1211
+ $result = self::frontend_check( $_condition, $ad );
1212
+ $last_result = $result;
1213
+ if ( ! $result ) {
1214
+ // return false only, if the next condition doesn’t have an OR operator.
1215
+ if ( ! isset( $next['connector'] ) || 'or' !== $next['connector'] ) {
1216
+ return false;
1217
+ }
1218
+ }
1219
  }
 
1220
 
1221
+ return true;
1222
  }
1223
 
1224
  /**
1227
  * Existing arguments must not be overridden.
1228
  * Some arguments might be cachable.
1229
  *
1230
+ * @param array $args arguments.
1231
  *
1232
  * @return array
1233
  */
1234
+ public function ad_select_args_callback( $args ) {
1235
+ global $post, $wp_the_query, $wp_query, $numpages;
1236
 
1237
+ if ( isset( $post ) ) {
1238
+ if ( ! isset( $args['post'] ) ) {
1239
+ $args['post'] = array();
1240
+ }
1241
+ if ( ! isset( $args['post']['id'] ) ) {
1242
+
1243
+ // if currently on a single site, use the main query information just in case a custom query is broken.
1244
+ if ( isset( $wp_the_query->post->ID ) && $wp_the_query->is_single() ) {
1245
+ $args['post']['id'] = $wp_the_query->post->ID;
1246
+ } else {
1247
+ $args['post']['id'] = $post->ID;
1248
+ }
1249
+ }
1250
+ if ( ! isset( $args['post']['author'] ) ) {
1251
+ // if currently on a single site, use the main query information just in case a custom query is broken.
1252
+ if ( isset( $wp_the_query->post->post_author ) && $wp_the_query->is_single() ) {
1253
+ $args['post']['author'] = $wp_the_query->post->post_author;
1254
+ } else {
1255
+ // a user reported that the missing $post_author property issue appeared so let’s check if it exists.
1256
+ $args['post']['author'] = isset( $post->post_author ) ? $post->post_author : '';
1257
+ }
1258
+ }
1259
+ if ( ! isset( $args['post']['post_type'] ) ) {
1260
+ // if currently on a single site, use the main query information just in case a custom query is broken.
1261
+ if ( isset( $wp_the_query->post->post_type ) && $wp_the_query->is_single() ) {
1262
+ $args['post']['post_type'] = $wp_the_query->post->post_type;
1263
+ } else {
1264
+ // a user reported that the missing $post_type property issue appeared so let’s check if it exists.
1265
+ $args['post']['post_type'] = isset( $post->post_type ) ? $post->post_type : '';
1266
+ }
1267
+ }
1268
  }
 
1269
 
1270
+ // pass query arguments.
1271
+ if ( isset( $wp_the_query ) ) {
1272
+ if ( ! isset( $args['wp_the_query'] ) ) {
1273
+ $args['wp_the_query'] = array();
1274
+ }
1275
+ $query = $wp_the_query->get_queried_object();
1276
+ // term_id exists only for taxonomy archive pages.
1277
+ if ( ! isset( $args['wp_the_query']['term_id'] ) && $query ) {
1278
+ $args['wp_the_query']['term_id'] = isset( $query->term_id ) ? $query->term_id : '';
1279
+ }
1280
+ // taxonomy.
1281
+ if ( ! isset( $args['wp_the_query']['taxonomy'] ) && $query ) {
1282
+ $args['wp_the_query']['taxonomy'] = isset( $query->taxonomy ) ? $query->taxonomy : '';
1283
+ }
1284
 
1285
+ // query type/ context.
1286
+ if ( ! isset( $args['wp_the_query']['is_main_query'] ) ) {
1287
+ $args['wp_the_query']['is_main_query'] = Advanced_Ads::get_instance()->is_main_query();
1288
+ }
1289
 
1290
+ // `<!-- nextpage -->` tags.
1291
+ if ( ! isset( $args['wp_the_query']['page'] ) ) {
1292
+ $args['wp_the_query']['page'] = isset( $wp_the_query->query_vars['page'] ) && $wp_the_query->query_vars['page'] ? $wp_the_query->query_vars['page'] : 1;
1293
+ $args['wp_the_query']['numpages'] = isset( $numpages ) ? $numpages : 1;
1294
+ }
1295
 
1296
+ // query vars.
1297
+ foreach ( self::$query_var_keys as $key ) {
1298
+ if ( ! isset( $args['wp_the_query'][ $key ] ) ) {
1299
+ $args['wp_the_query'][ $key ] = $wp_the_query->$key();
1300
+ }
1301
+ }
1302
  }
 
1303
 
1304
+ return $args;
1305
  }
1306
 
1307
  /**
1308
+ * ;odify post search query to search by post_title or ID
1309
  *
1310
+ * @param array $query post search query.
1311
+ *
1312
+ * @return array
1313
  */
1314
  public static function modify_post_search( $query ) {
1315
+
1316
+ // use ID and not search field if ID given.
1317
+ if ( 0 !== absint( $query['s'] ) && strlen( $query['s'] ) === strlen( absint( $query['s'] ) ) ) {
1318
+ $query['post__in'] = array( absint( $query['s'] ) );
1319
+ unset( $query['s'] );
1320
  }
1321
+
1322
  $query['suppress_filters'] = false;
1323
+ $query['orderby'] = 'post_title';
1324
+ $query['post_status'] = array( 'publish', 'pending', 'draft', 'future' );
1325
+
1326
  return $query;
1327
  }
1328
 
1329
  /**
1330
+ * Modify post search SQL to search only in post title
1331
+ *
1332
+ * @param string $sql SQL statement.
1333
  *
 
1334
  * @return string
1335
  */
1336
  public static function modify_post_search_sql( $sql ) {
1337
  global $wpdb;
1338
+
1339
  // $sql = preg_replace_callback( "/{$wpdb->posts}.post_(content|excerpt)( NOT)? LIKE '%(.*?)%'/", array( 'Advanced_Ads_Display_Conditions', 'modify_post_search_sql_callback' ), $sql );
1340
+
1341
+ // removes the search in content and excerpt columns.
1342
  $sql = preg_replace( "/OR \({$wpdb->posts}.post_(content|excerpt)( NOT)? LIKE '(.*?)'\)/", '', $sql );
1343
+
1344
  return $sql;
1345
  }
1346
 
1347
  /**
1348
+ * Preg_replace callback used in modify_post_search_sql()
1349
+ *
1350
+ * @param array $matches results for post search.
1351
  *
 
1352
  * @return string
1353
  * @deprecated since version 1.8.16
1354
  */
1355
  public static function modify_post_search_sql_callback( $matches ) {
1356
  global $wpdb;
1357
+ if ( 'content' === $matches[1] && preg_match( '@^([0-9]+)$@', $matches[3], $matches_id ) ) {
1358
+ $equals_op = ' NOT' === $matches[2] ? '!=' : '=';
1359
+
1360
  return "{$wpdb->posts}.ID$equals_op$matches_id[1]";
1361
+ } elseif ( ' NOT' === $matches[2] ) {
1362
  return '1=1';
1363
  } else {
1364
  return '1=0';
1365
  }
1366
  }
1367
 
1368
+ }
 
classes/plugin.php CHANGED
@@ -703,56 +703,65 @@ class Advanced_Ads_Plugin {
703
 
704
  wp_cache_flush();
705
  }
706
-
707
  /**
708
- * check if any add-on is activated
709
- *
710
- * @return bol true if there is any add-on activated
711
- */
712
- static function any_activated_add_on(){
713
- return ( defined( 'AAP_VERSION' ) // Advanced Ads Pro
714
- || defined( 'AASA_VERSION' ) // Selling Ads
715
- || defined( 'AAT_VERSION' ) // Tracking
716
- || defined( 'AASADS_VERSION' ) // Sticky Ads
717
- || defined( 'AAR_VERSION' ) // Responsive Ads
718
- || defined( 'AAPLDS_VERSION' ) // PopUp and Layer Ads
719
- || defined( 'AAGT_SLUG' ) // Geo-Targeting
720
  );
721
  }
722
-
723
  /**
724
  * Get the correct support URL: wp.org for free users and website for those with any add-on installed
725
  *
726
- * @param str $utm add UTM parameter to the link leading to https://wpadvancedads.com, if given
 
 
727
  */
728
- static function support_url( $utm = '' ){
729
 
730
  // return self::any_activated_add_on() ? ADVADS_URL . 'support/' .$utm : 'https://wordpress.org/support/plugin/advanced-ads#new-post';
731
  // $utm = empty( $utm ) ? '#utm_source=advanced-ads&utm_medium=link&utm_campaign=disable-support' : $utm;
732
- if( self::any_activated_add_on() ){
733
- $url = ADVADS_URL . 'support/' .$utm . '-with-addons';
734
  } else {
735
- $url = ADVADS_URL . 'support/' .$utm . '-free-user';
736
  }
737
  return $url;
738
  }
739
 
740
  /**
741
- * Create a unique hash from the URL
 
 
 
742
  *
743
  * @return bool
744
  */
745
- public static function random_by_url() {
746
- $url = home_url();
747
- $hash = hash( 'md5', $url );
748
 
749
- if ( preg_match_all( '/\d/', $hash, $numbers ) ) {
750
- $numbers_int = array_map( 'intval', $numbers[0] );
751
- $sum = array_sum( $numbers_int );
752
- } else {
753
- return false;
754
- }
755
 
756
- return 0 !== $sum % 2;
 
 
 
 
 
 
 
 
 
757
  }
758
  }
703
 
704
  wp_cache_flush();
705
  }
706
+
707
  /**
708
+ * Check if any add-on is activated
709
+ *
710
+ * @return bool true if there is any add-on activated
711
+ */
712
+ public static function any_activated_add_on() {
713
+ return ( defined( 'AAP_VERSION' ) // Advanced Ads Pro.
714
+ || defined( 'AASA_VERSION' ) // Selling Ads.
715
+ || defined( 'AAT_VERSION' ) // Tracking.
716
+ || defined( 'AASADS_VERSION' ) // Sticky Ads.
717
+ || defined( 'AAR_VERSION' ) // Responsive Ads.
718
+ || defined( 'AAPLDS_VERSION' ) // PopUp and Layer Ads.
719
+ || defined( 'AAGT_SLUG' ) // Geo-Targeting.
720
  );
721
  }
722
+
723
  /**
724
  * Get the correct support URL: wp.org for free users and website for those with any add-on installed
725
  *
726
+ * @param string $utm add UTM parameter to the link leading to https://wpadvancedads.com, if given
727
+ *
728
+ * @return string URL.
729
  */
730
+ static function support_url( $utm = '' ) {
731
 
732
  // return self::any_activated_add_on() ? ADVADS_URL . 'support/' .$utm : 'https://wordpress.org/support/plugin/advanced-ads#new-post';
733
  // $utm = empty( $utm ) ? '#utm_source=advanced-ads&utm_medium=link&utm_campaign=disable-support' : $utm;
734
+ if ( self::any_activated_add_on() ) {
735
+ $url = ADVADS_URL . 'support/' . $utm . '-with-addons';
736
  } else {
737
+ $url = ADVADS_URL . 'support/' . $utm . '-free-user';
738
  }
739
  return $url;
740
  }
741
 
742
  /**
743
+ * Create a random group
744
+ *
745
+ * @param string $url optional parameter.
746
+ * @param string $ex
747
  *
748
  * @return bool
749
  */
750
+ public static function get_group_by_url( $url = '', $ex = 'a' ) {
 
 
751
 
752
+ $url = empty( $url ) ? home_url() : $url;
753
+
754
+ $code = intval( substr( md5( $url ), -1 ), 16 );
 
 
 
755
 
756
+ switch ( $ex ) {
757
+ case 'b':
758
+ return ( $code & 2 ) >> 1; // returns 1 or 0.
759
+ case 'c':
760
+ return ( $code & 4 ) >> 2; // returns 1 or 0.
761
+ case 'd':
762
+ return ( $code & 8 ) >> 3; // returns 1 or 0.
763
+ default:
764
+ return $code & 1; // returns 1 or 0.
765
+ }
766
  }
767
  }
classes/visitor-conditions.php CHANGED
@@ -1,221 +1,218 @@
1
  <?php
2
 
3
  /**
4
- * visitor conditions under which to (not) show an ad
5
  *
6
  * @since 1.5.4
7
- *
8
  */
9
  class Advanced_Ads_Visitor_Conditions {
10
 
11
  /**
 
12
  *
13
  * @var Advanced_Ads_Visitor_Conditions
14
  */
15
  protected static $instance;
16
 
17
  /**
18
- * registered visitor conditions
 
 
19
  */
20
  public $conditions;
21
 
22
  /**
23
- * start of name in form elements
24
  */
25
  const FORM_NAME = 'advanced_ad[visitors]';
26
 
 
 
 
27
  public function __construct() {
28
 
29
- // register conditions
30
- $this->conditions = apply_filters( 'advanced-ads-visitor-conditions', array(
31
- 'mobile' => array( // type of the condition
32
- 'label' => __( 'device', 'advanced-ads' ),
33
- 'description' => __( 'Display ads only on mobile devices or hide them.', 'advanced-ads' ),
34
- 'metabox' => array( 'Advanced_Ads_Visitor_Conditions', 'mobile_is_or_not' ), // callback to generate the metabox
35
- 'check' => array( 'Advanced_Ads_Visitor_Conditions', 'check_mobile' ), // callback for frontend check
36
- 'helplink' => ADVADS_URL . 'manual/display-ads-either-on-mobile-or-desktop/#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor-mobile' // link to help section
37
- ),
38
- 'loggedin' => array(
39
- 'label' => __( 'logged in visitor', 'advanced-ads' ),
40
- 'description' => __( 'Whether the visitor has to be logged in or not in order to see the ads.', 'advanced-ads' ),
41
- 'metabox' => array( 'Advanced_Ads_Visitor_Conditions', 'metabox_is_or_not' ), // callback to generate the metabox
42
- 'check' => array( 'Advanced_Ads_Visitor_Conditions', 'check_logged_in' ), // callback for frontend check
43
- 'passive_info' => array( 'hash_fields' => null, 'remove' => 'login', 'function' => 'is_user_logged_in' )
 
 
 
 
 
 
 
44
  ),
45
- ));
 
46
  }
47
 
48
  /**
 
49
  *
50
- * @return Advanced_Ads_Plugin
51
  */
52
  public static function get_instance() {
53
  // If the single instance hasn't been set, set it now.
54
  if ( null === self::$instance ) {
55
- self::$instance = new self;
56
  }
57
 
58
  return self::$instance;
59
  }
60
-
61
-
62
  /**
63
- * get the conditions array alphabetically by label
64
- *
65
  * @since 1.8.12
66
  */
67
- public function get_conditions(){
68
  uasort( $this->conditions, 'Advanced_Ads_Admin::sort_condition_array_by_label' );
69
-
70
  return $this->conditions;
71
- }
72
 
73
  /**
74
- * callback to render the mobile condition using the "is not" condition
75
  *
76
- * @param arr $options options of the condition
77
- * @param int $index index of the condition
 
78
  */
79
- static function mobile_is_or_not( $options, $index = 0 ){
80
-
81
- if ( ! isset ( $options['type'] ) || '' === $options['type'] ) { return; }
82
-
83
- $type_options = self::get_instance()->conditions;
84
-
85
- if ( ! isset( $type_options[ $options['type'] ] ) ) {
86
- return;
87
- }
88
-
89
- // form name basis
90
- $name = self::FORM_NAME . '[' . $index . ']';
91
-
92
- // options
93
- $operator = isset( $options['operator'] ) ? $options['operator'] : 'is';
94
-
95
- ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
96
- <select name="<?php echo $name; ?>[operator]">
97
- <option value="is" <?php selected( 'is', $operator ); ?>><?php _e( 'Mobile (including tablets)', 'advanced-ads' ); ?></option>
98
- <option value="is_not" <?php selected( 'is_not', $operator ); ?>><?php _e( 'Desktop', 'advanced-ads' ); ?></option>
99
- </select>
100
- <p class="description"><?php echo $type_options[ $options['type'] ]['description'];
101
- if( isset( $type_options[ $options['type'] ]['helplink'] ) ) : ?>
102
- <a href="<?php echo $type_options[ $options['type'] ]['helplink']; ?>" target="_blank"><?php
103
- _e( 'Manual and Troubleshooting', 'advanced-ads' );
104
- ?></a><?php endif; ?></p><?php
105
-
106
- if ( ! isset ( $options['type'] ) || '' === $options['type'] ) { return; }
107
-
108
- if( ! defined( 'AAR_SLUG' ) ){
109
- echo '<p>' . sprintf(__( 'Display ads by the available space on the device or target tablets with the <a href="%s" target="_blank">Responsive add-on</a>', 'advanced-ads' ), ADVADS_URL . 'add-ons/responsive-ads/#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor-responsive') . '</p>';
110
- }
111
  }
112
-
113
  /**
114
- * callback to display the "is not" condition
115
  *
116
- * @param arr $options options of the condition
117
- * @param int $index index of the condition
 
118
  */
119
- static function metabox_is_or_not( $options, $index = 0 ){
120
 
121
- if ( ! isset ( $options['type'] ) || '' === $options['type'] ) { return; }
 
 
122
 
123
- $type_options = self::get_instance()->conditions;
124
 
125
- if ( ! isset( $type_options[ $options['type'] ] ) ) {
126
- return;
127
- }
128
 
129
- // form name basis
130
- $name = self::FORM_NAME . '[' . $index . ']';
131
 
132
- // options
133
- $operator = isset( $options['operator'] ) ? $options['operator'] : 'is';
134
 
135
- ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
136
- <select name="<?php echo $name; ?>[operator]">
137
- <option value="is" <?php selected( 'is', $operator ); ?>><?php _e( 'is', 'advanced-ads' ); ?></option>
138
- <option value="is_not" <?php selected( 'is_not', $operator ); ?>><?php _e( 'is not', 'advanced-ads' ); ?></option>
139
- </select>
140
- <p class="description"><?php echo $type_options[ $options['type'] ]['description'];
141
- if( isset( $type_options[ $options['type'] ]['helplink'] ) ) : ?>
142
- <a href="<?php echo $type_options[ $options['type'] ]['helplink']; ?>" target="_blank"><?php
143
- _e( 'Manual and Troubleshooting', 'advanced-ads' );
144
- ?></a><?php endif; ?></p><?php
145
  }
146
 
147
  /**
148
- * callback to display the any condition based on a number
149
  *
150
- * @param arr $options options of the condition
151
- * @param int $index index of the condition
 
152
  */
153
- static function metabox_number( $options, $index = 0 ){
154
 
155
- if ( ! isset ( $options['type'] ) || '' === $options['type'] ) { return; }
 
 
156
 
157
- $type_options = self::get_instance()->conditions;
158
 
159
- if ( ! isset( $type_options[ $options['type'] ] ) ) {
160
- return;
161
- }
162
 
163
- // form name basis
164
- $name = self::FORM_NAME . '[' . $index . ']';
165
 
166
- // options
167
- $value = isset( $options['value'] ) ? $options['value'] : 0;
168
- $operator = isset( $options['operator'] ) ? $options['operator'] : 'is_equal';
169
 
170
- ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
171
- <select name="<?php echo $name; ?>[operator]">
172
- <option value="is_equal" <?php selected( 'is_equal', $operator ); ?>><?php _e( 'equal', 'advanced-ads' ); ?></option>
173
- <option value="is_higher" <?php selected( 'is_higher', $operator ); ?>><?php _e( 'equal or higher', 'advanced-ads' ); ?></option>
174
- <option value="is_lower" <?php selected( 'is_lower', $operator ); ?>><?php _e( 'equal or lower', 'advanced-ads' ); ?></option>
175
- </select><input type="number" name="<?php echo $name; ?>[value]" value="<?php echo absint( $value ); ?>"/>
176
- <p class="description"><?php echo $type_options[ $options['type'] ]['description']; ?></p><?php
177
  }
178
 
179
  /**
180
- * callback to display the any condition based on a number
181
  *
182
- * @param arr $options options of the condition
183
- * @param int $index index of the condition
 
184
  */
185
- static function metabox_string( $options, $index = 0 ){
186
 
187
- if ( ! isset ( $options['type'] ) || '' === $options['type'] ) { return; }
 
 
188
 
189
- $type_options = self::get_instance()->conditions;
190
 
191
- if ( ! isset( $type_options[ $options['type'] ] ) ) {
192
- return;
193
- }
194
 
195
- // form name basis
196
- $name = self::FORM_NAME . '[' . $index . ']';
197
 
198
- // options
199
- $value = isset( $options['value'] ) ? $options['value'] : '';
200
- $operator = isset( $options['operator'] ) ? $options['operator'] : 'contains';
201
 
202
- ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
203
- <div class="advads-condition-line-wrap">
204
- <?php include( ADVADS_BASE_PATH . 'admin/views/ad-conditions-string-operators.php' ); ?>
205
- <input type="text" name="<?php echo $name; ?>[value]" value="<?php echo $value; ?>"/>
206
- </div>
207
- <p class="description"><?php echo $type_options[ $options['type'] ]['description']; ?></p><?php
208
  }
209
 
210
  /**
211
- * controls frontend checks for conditions
 
 
 
212
  *
213
- * @param arr $options options of the condition
214
- * @param ob $ad Advanced_Ads_Ad
215
  * @return bool false, if ad can’t be delivered
216
  */
217
- static function frontend_check( $options = array(), $ad = false ){
218
- $visitor_conditions = Advanced_Ads_Visitor_Conditions::get_instance()->conditions;
219
 
220
  if ( is_array( $options ) && isset( $visitor_conditions[ $options['type'] ]['check'] ) ) {
221
  $check = $visitor_conditions[ $options['type'] ]['check'];
@@ -223,144 +220,233 @@ class Advanced_Ads_Visitor_Conditions {
223
  return true;
224
  }
225
 
226
- // call frontend check callback
227
  if ( method_exists( $check[0], $check[1] ) ) {
228
  return call_user_func( array( $check[0], $check[1] ), $options, $ad );
229
  }
230
 
231
  return true;
232
  }
233
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  /**
235
- * render connector option
236
- *
 
 
 
 
 
 
 
237
  * @since 1.7.0.4
238
- * @param int $index
239
  */
240
- static function render_connector_option( $index = 0, $value = 'or' ){
 
 
241
 
242
- $label = ( $value === 'or' ) ? __( 'or', 'advanced-ads' ) : __( 'and', 'advanced-ads' );
243
 
244
- return '<input type="checkbox" name="' . self::FORM_NAME . '[' . $index . '][connector]' . '" value="or" id="advads-visitor-conditions-' .
245
- $index . '-connector"' .
246
- checked( 'or', $value, false )
247
- .'><label for="advads-visitor-conditions-' . $index . '-connector">' . $label . '</label>';
248
- }
 
 
 
249
 
250
  /**
251
- * check mobile visitor condition in frontend
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  *
253
- * @param arr $options options of the condition
254
  * @return bool true if can be displayed
255
  */
256
- static function check_mobile( $options = array() ){
257
 
258
- if ( ! isset( $options['operator'] ) ) {
259
  return true;
260
- }
261
-
262
- switch ( $options['operator'] ){
263
- case 'is' :
264
- if ( ! wp_is_mobile() ) { return false; }
265
- break;
266
- case 'is_not' :
267
- if ( wp_is_mobile() ) { return false; }
268
- break;
269
- }
270
-
271
- return true;
 
 
 
 
272
  }
273
 
274
  /**
275
- * check mobile visitor condition in frontend
 
 
276
  *
277
- * @since 1.6.3
278
- * @param arr $options options of the condition
279
  * @return bool true if can be displayed
 
280
  */
281
- static function check_logged_in( $options = array() ){
282
 
283
- if ( ! isset( $options['operator'] ) ) {
284
  return true;
285
- }
286
-
287
- switch ( $options['operator'] ){
288
- case 'is' :
289
- if ( ! is_user_logged_in() ) { return false; }
290
- break;
291
- case 'is_not' :
292
- if ( is_user_logged_in() ) { return false; }
293
- break;
294
- }
295
-
296
- return true;
 
 
 
 
297
  }
298
 
299
  /**
300
- * helper for check with strings
 
 
 
301
  *
302
- * @since 1.6.3
303
- * @param str $string string that is going to be checked
304
  * @return bool true if ad can be displayed
 
305
  */
306
- static function helper_check_string( $string = '', $options = array() ){
307
 
308
- if ( ! isset( $options['operator'] ) || ! isset( $options['value'] ) || '' === $options['value'] ){
309
  return true;
310
  }
311
 
312
  $operator = $options['operator'];
313
- $value = $options['value'];
314
 
315
- // check the condition by mode and bool
316
  $condition = true;
317
- switch ( $operator ){
318
- // referrer contains string on any position
319
- case 'contain' :
320
  $condition = stripos( $string, $value ) !== false;
321
  break;
322
- // referrer does not contain string on any position
323
- case 'contain_not' :
324
  $condition = stripos( $string, $value ) === false;
325
  break;
326
- // referrer starts with the string
327
- case 'start' :
328
  $condition = stripos( $string, $value ) === 0;
329
  break;
330
- // referrer does not start with the string
331
- case 'start_not' :
332
  $condition = stripos( $string, $value ) !== 0;
333
  break;
334
- // referrer ends with the string
335
- case 'end' :
336
- $condition = $value === substr( $string, -strlen( $value ) );
337
  break;
338
- // referrer does not end with the string
339
- case 'end_not' :
340
- $condition = $value !== substr( $string, -strlen( $value ) );
341
  break;
342
- // referrer is equal to the string
343
- case 'match' :
344
- // strings do match, but should not or not match but should
345
- $condition = strcasecmp($value, $string) === 0;
346
  break;
347
- // referrer is not equal to the string
348
- case 'match_not' :
349
- // strings do match, but should not or not match but should
350
- $condition = strcasecmp($value, $string) !== 0;
351
  break;
352
- // string is a regular expression
353
- case 'regex' :
354
- // check regular expression first
355
- if( @preg_match( $value, null ) === false ){
356
  Advanced_Ads::log( "Advanced Ads: regular expression '$value' in visitor condition is broken." );
357
  } else {
358
  $condition = preg_match( $value, $string );
359
  }
360
  break;
361
- // string is not a regular expression
362
- case 'regex_not' :
363
- if( @preg_match( $value, null ) === false ){
364
  Advanced_Ads::log( "Advanced Ads: regular expression '$value' in visitor condition is broken." );
365
  } else {
366
  $condition = ! preg_match( $value, $string );
1
  <?php
2
 
3
  /**
4
+ * Visitor conditions under which to (not) show an ad
5
  *
6
  * @since 1.5.4
 
7
  */
8
  class Advanced_Ads_Visitor_Conditions {
9
 
10
  /**
11
+ * Instance of Advanced_Ads_Visitor_Conditions
12
  *
13
  * @var Advanced_Ads_Visitor_Conditions
14
  */
15
  protected static $instance;
16
 
17
  /**
18
+ * Registered visitor conditions
19
+ *
20
+ * @var array $conditions
21
  */
22
  public $conditions;
23
 
24
  /**
25
+ * Start of name in form elements
26
  */
27
  const FORM_NAME = 'advanced_ad[visitors]';
28
 
29
+ /**
30
+ * Advanced_Ads_Visitor_Conditions constructor
31
+ */
32
  public function __construct() {
33
 
34
+ // register conditions.
35
+ $this->conditions = apply_filters(
36
+ 'advanced-ads-visitor-conditions',
37
+ array(
38
+ 'mobile' => array(
39
+ // type of the condition.
40
+ 'label' => __( 'device', 'advanced-ads' ),
41
+ 'description' => __( 'Display ads only on mobile devices or hide them.', 'advanced-ads' ),
42
+ 'metabox' => array( 'Advanced_Ads_Visitor_Conditions', 'mobile_is_or_not' ), // callback to generate the metabox.
43
+ 'check' => array( 'Advanced_Ads_Visitor_Conditions', 'check_mobile' ), // callback for frontend check.
44
+ 'helplink' => ADVADS_URL . 'manual/display-ads-either-on-mobile-or-desktop/#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor-mobile', // link to help section.
45
+ ),
46
+ 'loggedin' => array(
47
+ 'label' => __( 'logged-in visitor', 'advanced-ads' ),
48
+ 'description' => __( 'Whether the visitor has to be logged in or not in order to see the ads.', 'advanced-ads' ),
49
+ 'metabox' => array( 'Advanced_Ads_Visitor_Conditions', 'metabox_is_or_not' ), // callback to generate the metabox.
50
+ 'check' => array( 'Advanced_Ads_Visitor_Conditions', 'check_logged_in' ), // callback for frontend check.
51
+ 'passive_info' => array(
52
+ 'hash_fields' => null,
53
+ 'remove' => 'login',
54
+ 'function' => 'is_user_logged_in',
55
+ ),
56
  ),
57
+ )
58
+ );
59
  }
60
 
61
  /**
62
+ * Load instance of Advanced_Ads_Visitor_Conditions
63
  *
64
+ * @return Advanced_Ads_Visitor_Conditions
65
  */
66
  public static function get_instance() {
67
  // If the single instance hasn't been set, set it now.
68
  if ( null === self::$instance ) {
69
+ self::$instance = new self();
70
  }
71
 
72
  return self::$instance;
73
  }
74
+
75
+
76
  /**
77
+ * Get the conditions array alphabetically by label
78
+ *
79
  * @since 1.8.12
80
  */
81
+ public function get_conditions() {
82
  uasort( $this->conditions, 'Advanced_Ads_Admin::sort_condition_array_by_label' );
83
+
84
  return $this->conditions;
85
+ }
86
 
87
  /**
88
+ * Callback to render the mobile condition using the "is not" condition
89
  *
90
+ * @param array $options options of the condition.
91
+ * @param int $index index of the condition.
92
+ * @param string $form_name name of the form, falls back to class constant.
93
  */
94
+ public static function mobile_is_or_not( $options, $index = 0, $form_name = '' ) {
95
+
96
+ if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
97
+ return;
98
+ }
99
+
100
+ $type_options = self::get_instance()->conditions;
101
+
102
+ if ( ! isset( $type_options[ $options['type'] ] ) ) {
103
+ return;
104
+ }
105
+
106
+ // form name basis.
107
+ $name = self::get_form_name_with_index( $form_name, $index );
108
+
109
+ // options.
110
+ $operator = isset( $options['operator'] ) ? $options['operator'] : 'is';
111
+
112
+ include ADVADS_BASE_PATH . 'admin/views/conditions/condition-device.php';
113
+
114
+ if ( ! defined( 'AAR_SLUG' ) ) {
115
+ // translators: %s is a URL. Please don’t change it.
116
+ echo '<p>' . sprintf( __( 'Display ads by the available space on the device or target tablets with the <a href="%s" target="_blank">Responsive add-on</a>', 'advanced-ads' ), ADVADS_URL . 'add-ons/responsive-ads/#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor-responsive' ) . '</p>';
117
+ }
 
 
 
 
 
 
 
 
118
  }
119
+
120
  /**
121
+ * Callback to display the "is not" condition
122
  *
123
+ * @param array $options options of the condition.
124
+ * @param int $index index of the condition.
125
+ * @param string $form_name name of the form, falls back to class constant.
126
  */
127
+ public static function metabox_is_or_not( $options, $index = 0, $form_name = '' ) {
128
 
129
+ if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
130
+ return;
131
+ }
132
 
133
+ $type_options = self::get_instance()->conditions;
134
 
135
+ if ( ! isset( $type_options[ $options['type'] ] ) ) {
136
+ return;
137
+ }
138
 
139
+ // form name basis.
140
+ $name = self::get_form_name_with_index( $form_name, $index );
141
 
142
+ // options.
143
+ $operator = isset( $options['operator'] ) ? $options['operator'] : 'is';
144
 
145
+ include ADVADS_BASE_PATH . 'admin/views/conditions/condition-is-or-not.php';
 
 
 
 
 
 
 
 
 
146
  }
147
 
148
  /**
149
+ * Callback to display the any condition based on a number
150
  *
151
+ * @param array $options options of the condition.
152
+ * @param int $index index of the condition.
153
+ * @param string $form_name name of the form, falls back to class constant.
154
  */
155
+ public static function metabox_number( $options, $index = 0, $form_name = '' ) {
156
 
157
+ if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
158
+ return;
159
+ }
160
 
161
+ $type_options = self::get_instance()->conditions;
162
 
163
+ if ( ! isset( $type_options[ $options['type'] ] ) ) {
164
+ return;
165
+ }
166
 
167
+ // form name basis.
168
+ $name = self::get_form_name_with_index( $form_name, $index );
169
 
170
+ // options.
171
+ $value = isset( $options['value'] ) ? $options['value'] : 0;
172
+ $operator = isset( $options['operator'] ) ? $options['operator'] : 'is_equal';
173
 
174
+ include ADVADS_BASE_PATH . 'admin/views/conditions/condition-number.php';
 
 
 
 
 
 
175
  }
176
 
177
  /**
178
+ * Callback to display the any condition based on a number
179
  *
180
+ * @param array $options options of the condition.
181
+ * @param int $index index of the condition.
182
+ * @param string $form_name name of the form, falls back to class constant.
183
  */
184
+ public static function metabox_string( $options, $index = 0, $form_name = '' ) {
185
 
186
+ if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
187
+ return;
188
+ }
189
 
190
+ $type_options = self::get_instance()->conditions;
191
 
192
+ if ( ! isset( $type_options[ $options['type'] ] ) ) {
193
+ return;
194
+ }
195
 
196
+ // form name basis.
197
+ $name = self::get_form_name_with_index( $form_name, $index );
198
 
199
+ // options.
200
+ $value = isset( $options['value'] ) ? $options['value'] : '';
201
+ $operator = isset( $options['operator'] ) ? $options['operator'] : 'contains';
202
 
203
+ include ADVADS_BASE_PATH . 'admin/views/conditions/condition-string.php';
 
 
 
 
 
204
  }
205
 
206
  /**
207
+ * Controls frontend checks for conditions
208
+ *
209
+ * @param array $options options of the condition.
210
+ * @param object $ad Advanced_Ads_Ad.
211
  *
 
 
212
  * @return bool false, if ad can’t be delivered
213
  */
214
+ public static function frontend_check( $options = array(), $ad = false ) {
215
+ $visitor_conditions = self::get_instance()->conditions;
216
 
217
  if ( is_array( $options ) && isset( $visitor_conditions[ $options['type'] ]['check'] ) ) {
218
  $check = $visitor_conditions[ $options['type'] ]['check'];
220
  return true;
221
  }
222
 
223
+ // call frontend check callback.
224
  if ( method_exists( $check[0], $check[1] ) ) {
225
  return call_user_func( array( $check[0], $check[1] ), $options, $ad );
226
  }
227
 
228
  return true;
229
  }
230
+
231
+ /**
232
+ * Render the list of set visisor conditions
233
+ *
234
+ * @param array $set_conditions array of existing conditions.
235
+ * @param string $list_target ID of the list with the conditions.
236
+ * @param string $form_name prefix of the form.
237
+ */
238
+ public static function render_condition_list( array $set_conditions, $list_target = '', $form_name = '' ) {
239
+
240
+ $conditions = self::get_instance()->get_conditions();
241
+
242
+ // use default form name if not given explicitly.
243
+ // @todo create a random form name, in case we have more than one form per page and the parameter is not given.
244
+ $form_name = ! $form_name ? self::FORM_NAME : $form_name;
245
+
246
+ include ADVADS_BASE_PATH . 'admin/views/conditions/visitor-conditions-list.php';
247
+
248
+ /**
249
+ * Prepare condition form
250
+ *
251
+ * @todo if needed, allow to disable the form to add new conditions
252
+ */
253
+
254
+ // add mockup conditions if add-ons are missing.
255
+ $pro_conditions = array();
256
+ if ( ! defined( 'AAP_VERSION' ) ) {
257
+ $pro_conditions[] = __( 'browser language', 'advanced-ads' );
258
+ $pro_conditions[] = __( 'cookie', 'advanced-ads' );
259
+ $pro_conditions[] = __( 'max. ad clicks', 'advanced-ads' );
260
+ $pro_conditions[] = __( 'max. ad impressions', 'advanced-ads' );
261
+ $pro_conditions[] = __( 'new visitor', 'advanced-ads' );
262
+ $pro_conditions[] = __( 'page impressions', 'advanced-ads' );
263
+ $pro_conditions[] = __( 'referrer url', 'advanced-ads' );
264
+ $pro_conditions[] = __( 'user agent', 'advanced-ads' );
265
+ $pro_conditions[] = __( 'user can (capabilities)', 'advanced-ads' );
266
+ $pro_conditions[] = __( 'user role', 'advanced-ads' );
267
+ }
268
+ if ( ! defined( 'AAGT_VERSION' ) ) {
269
+ $pro_conditions[] = __( 'geo location', 'advanced-ads' );
270
+ }
271
+ if ( ! defined( 'AAR_VERSION' ) ) {
272
+ $pro_conditions[] = __( 'browser width', 'advanced-ads' );
273
+ }
274
+ asort( $pro_conditions );
275
+
276
+ // the action to call using AJAX.
277
+ $action = 'load_visitor_conditions_metabox';
278
+ $connector_default = 'and';
279
+
280
+ include ADVADS_BASE_PATH . 'admin/views/conditions/visitor-conditions-form-top.php';
281
+ include ADVADS_BASE_PATH . 'admin/views/conditions/conditions-form.php';
282
+ }
283
+
284
  /**
285
+ * Render connector option
286
+ *
287
+ * @param int $index incremental index of the options.
288
+ * @param string $value connector value.
289
+ * @param string $form_name name of the form, falls back to class constant.
290
+ *
291
+ * @return string HTML of the connector option
292
+ * @todo combine this with the same function used for Display Conditions
293
+ *
294
  * @since 1.7.0.4
 
295
  */
296
+ public static function render_connector_option( $index = 0, $value = 'or', $form_name ) {
297
+
298
+ $label = ( 'or' === $value ) ? __( 'or', 'advanced-ads' ) : __( 'and', 'advanced-ads' );
299
 
300
+ $name = self::get_form_name_with_index( $form_name, $index );
301
 
302
+ // create random value to identify the form field.
303
+ $rand = md5( $form_name );
304
+
305
+ return '<input type="checkbox" name="' . $name . '[connector]' . '" value="or" id="advads-conditions-' .
306
+ $index . '-connector-' . $rand . '"' .
307
+ checked( 'or', $value, false )
308
+ . '><label for="advads-conditions-' . $index . '-connector-' . $rand . '">' . $label . '</label>';
309
+ }
310
 
311
  /**
312
+ * Helper function to the name of a form field.
313
+ * falls back to default
314
+ *
315
+ * @param string $form_name form name if submitted.
316
+ * @param int $index index of the condition.
317
+ *
318
+ * @return string
319
+ */
320
+ public static function get_form_name_with_index( $form_name = '', $index = 0 ) {
321
+ return ! empty( $form_name ) ? $form_name . '[' . $index . ']' : self::FORM_NAME . '[' . $index . ']';
322
+ }
323
+
324
+ /**
325
+ * Check mobile visitor condition in frontend
326
+ *
327
+ * @param array $options options of the condition.
328
  *
 
329
  * @return bool true if can be displayed
330
  */
331
+ public static function check_mobile( $options = array() ) {
332
 
333
+ if ( ! isset( $options['operator'] ) ) {
334
  return true;
335
+ }
336
+
337
+ switch ( $options['operator'] ) {
338
+ case 'is':
339
+ if ( ! wp_is_mobile() ) {
340
+ return false;
341
+ }
342
+ break;
343
+ case 'is_not':
344
+ if ( wp_is_mobile() ) {
345
+ return false;
346
+ }
347
+ break;
348
+ }
349
+
350
+ return true;
351
  }
352
 
353
  /**
354
+ * Check mobile visitor condition in frontend
355
+ *
356
+ * @param array $options options of the condition.
357
  *
 
 
358
  * @return bool true if can be displayed
359
+ * @since 1.6.3
360
  */
361
+ public static function check_logged_in( $options = array() ) {
362
 
363
+ if ( ! isset( $options['operator'] ) ) {
364
  return true;
365
+ }
366
+
367
+ switch ( $options['operator'] ) {
368
+ case 'is':
369
+ if ( ! is_user_logged_in() ) {
370
+ return false;
371
+ }
372
+ break;
373
+ case 'is_not':
374
+ if ( is_user_logged_in() ) {
375
+ return false;
376
+ }
377
+ break;
378
+ }
379
+
380
+ return true;
381
  }
382
 
383
  /**
384
+ * Helper for check with strings
385
+ *
386
+ * @param string $string string that is going to be checked.
387
+ * @param array $options options of this condition.
388
  *
 
 
389
  * @return bool true if ad can be displayed
390
+ * @since 1.6.3
391
  */
392
+ public static function helper_check_string( $string = '', $options = array() ) {
393
 
394
+ if ( ! isset( $options['operator'] ) || ! isset( $options['value'] ) || '' === $options['value'] ) {
395
  return true;
396
  }
397
 
398
  $operator = $options['operator'];
399
+ $value = $options['value'];
400
 
401
+ // check the condition by mode and bool.
402
  $condition = true;
403
+ switch ( $operator ) {
404
+ // referrer contains string on any position.
405
+ case 'contain':
406
  $condition = stripos( $string, $value ) !== false;
407
  break;
408
+ // referrer does not contain string on any position.
409
+ case 'contain_not':
410
  $condition = stripos( $string, $value ) === false;
411
  break;
412
+ // referrer starts with the string.
413
+ case 'start':
414
  $condition = stripos( $string, $value ) === 0;
415
  break;
416
+ // referrer does not start with the string.
417
+ case 'start_not':
418
  $condition = stripos( $string, $value ) !== 0;
419
  break;
420
+ // referrer ends with the string.
421
+ case 'end':
422
+ $condition = substr( $string, - strlen( $value ) ) === $value;
423
  break;
424
+ // referrer does not end with the string.
425
+ case 'end_not':
426
+ $condition = substr( $string, - strlen( $value ) ) !== $value;
427
  break;
428
+ // referrer is equal to the string.
429
+ case 'match':
430
+ // strings do match, but should not or not match but should.
431
+ $condition = strcasecmp( $value, $string ) === 0;
432
  break;
433
+ // referrer is not equal to the string.
434
+ case 'match_not':
435
+ // strings do match, but should not or not match but should.
436
+ $condition = strcasecmp( $value, $string ) !== 0;
437
  break;
438
+ // string is a regular expression.
439
+ case 'regex':
440
+ // check regular expression first.
441
+ if ( @preg_match( $value, null ) === false ) {
442
  Advanced_Ads::log( "Advanced Ads: regular expression '$value' in visitor condition is broken." );
443
  } else {
444
  $condition = preg_match( $value, $string );
445
  }
446
  break;
447
+ // string is not a regular expression.
448
+ case 'regex_not':
449
+ if ( @preg_match( $value, null ) === false ) {
450
  Advanced_Ads::log( "Advanced Ads: regular expression '$value' in visitor condition is broken." );
451
  } else {
452
  $condition = ! preg_match( $value, $string );
languages/advanced-ads.pot CHANGED
@@ -3,7 +3,7 @@ msgid ""
3
  msgstr ""
4
  "Project-Id-Version: Advanved Ads\n"
5
  "Report-Msgid-Bugs-To: http://wordpress.org/plugins/plugin-name\n"
6
- "POT-Creation-Date: 2019-09-24 07:14+0000\n"
7
  "POT-Revision-Date: Wed Jul 13 2016 13:23:05 GMT+0200 (CEST)\n"
8
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
9
  "Last-Translator: Thomas Maier <post@webzunft.de>\n"
@@ -23,76 +23,76 @@ msgstr ""
23
  "X-Poedit-Basepath: ../\n"
24
  "X-Poedit-SearchPath-0: ."
25
 
26
- #: admin/class-advanced-ads-admin.php:222 classes/display-conditions.php:215
27
- #: classes/visitor-conditions.php:242 admin/views/ad-display-metabox.php:189
28
  #: modules/gadsense/admin/views/external-ads-links.php:17
29
  #: modules/gadsense/admin/views/external-ads-links.php:21
30
  #: modules/gadsense/admin/views/external-ads-links.php:28
31
  msgid "or"
32
  msgstr ""
33
 
34
- #: admin/class-advanced-ads-admin.php:223 classes/display-conditions.php:215
35
- #: classes/visitor-conditions.php:242 admin/views/ad-visitor-metabox.php:158
36
  msgid "and"
37
  msgstr ""
38
 
39
- #: admin/class-advanced-ads-admin.php:224
40
  msgid "After which paragraph?"
41
  msgstr ""
42
 
43
- #: admin/class-advanced-ads-admin.php:226
44
  msgid "Today"
45
  msgstr ""
46
 
47
- #: admin/class-advanced-ads-admin.php:227
48
  msgid "Yesterday"
49
  msgstr ""
50
 
51
- #: admin/class-advanced-ads-admin.php:228
52
  msgid "This Month"
53
  msgstr ""
54
 
55
  #. 1: The number of days.
56
- #: admin/class-advanced-ads-admin.php:230
57
  #, php-format
58
  msgid "Last %1$d days"
59
  msgstr ""
60
 
61
- #: admin/class-advanced-ads-admin.php:233
62
  msgid "All"
63
  msgstr ""
64
 
65
- #: admin/class-advanced-ads-admin.php:234
66
  msgid ""
67
  "There were no results returned for this ad. Please make sure it is active, "
68
  "generating impressions and double check your ad parameters."
69
  msgstr ""
70
 
71
- #: admin/class-advanced-ads-admin.php:235
72
  #: modules/gadsense/admin/views/external-ads-list.php:12
73
  msgid "Show inactive ads"
74
  msgstr ""
75
 
76
- #: admin/class-advanced-ads-admin.php:236
77
  msgid "Hide inactive ads"
78
  msgstr ""
79
 
80
- #: admin/class-advanced-ads-admin.php:347
81
  #, php-format
82
  msgid "time of %s"
83
  msgstr ""
84
 
85
- #: admin/class-advanced-ads-admin.php:413 admin/includes/class-menu.php:113
86
  #: admin/includes/class-menu.php:116 admin/views/settings.php:28
87
  msgid "Support"
88
  msgstr ""
89
 
90
- #: admin/class-advanced-ads-admin.php:417
91
  #: admin/includes/class-overview-widgets.php:58
92
  msgid "Add-Ons"
93
  msgstr ""
94
 
95
- #: admin/class-advanced-ads-admin.php:683
96
  #: admin/includes/class-overview-widgets.php:175
97
  #, php-format
98
  msgid ""
@@ -168,98 +168,98 @@ msgstr ""
168
  msgid "Learn more about AdSense account issues %1$shere%2$s."
169
  msgstr ""
170
 
171
- #: classes/ad_placements.php:31
172
  msgid "Manual Placement"
173
  msgstr ""
174
 
175
- #: classes/ad_placements.php:32
176
  msgid "Manual placement to use as function or shortcode."
177
  msgstr ""
178
 
179
- #: classes/ad_placements.php:37
180
  msgid "Header Code"
181
  msgstr ""
182
 
183
- #: classes/ad_placements.php:38
184
  msgid ""
185
  "Injected in Header (before closing &lt;/head&gt; Tag, often not visible)."
186
  msgstr ""
187
 
188
- #: classes/ad_placements.php:42
189
  msgid "Footer Code"
190
  msgstr ""
191
 
192
- #: classes/ad_placements.php:43
193
  msgid "Injected in Footer (before closing &lt;/body&gt; Tag)."
194
  msgstr ""
195
 
196
- #: classes/ad_placements.php:48 admin/views/placement-injection-top.php:49
197
  msgid "Before Content"
198
  msgstr ""
199
 
200
- #: classes/ad_placements.php:49
201
  msgid "Injected before the post content."
202
  msgstr ""
203
 
204
- #: classes/ad_placements.php:54 admin/views/placement-injection-top.php:51
205
  msgid "After Content"
206
  msgstr ""
207
 
208
- #: classes/ad_placements.php:55
209
  msgid "Injected after the post content."
210
  msgstr ""
211
 
212
- #: classes/ad_placements.php:60 admin/views/placement-injection-top.php:50
213
  msgid "Content"
214
  msgstr ""
215
 
216
- #: classes/ad_placements.php:61
217
  msgid ""
218
  "Injected into the content. You can choose the paragraph after which the ad "
219
  "content is displayed."
220
  msgstr ""
221
 
222
- #: classes/ad_placements.php:66
223
  msgid "Sidebar Widget"
224
  msgstr ""
225
 
226
- #: classes/ad_placements.php:67
227
  msgid ""
228
  "Create a sidebar widget with an ad. Can be placed and used like any other "
229
  "widget."
230
  msgstr ""
231
 
232
- #: classes/ad_placements.php:238
233
  #, php-format
234
  msgid "paragraph (%s)"
235
  msgstr ""
236
 
237
- #: classes/ad_placements.php:239
238
  #, php-format
239
  msgid "paragraph without image (%s)"
240
  msgstr ""
241
 
242
- #: classes/ad_placements.php:240
243
  #, php-format
244
  msgid "headline 2 (%s)"
245
  msgstr ""
246
 
247
- #: classes/ad_placements.php:241
248
  #, php-format
249
  msgid "headline 3 (%s)"
250
  msgstr ""
251
 
252
- #: classes/ad_placements.php:242
253
  #, php-format
254
  msgid "headline 4 (%s)"
255
  msgstr ""
256
 
257
- #: classes/ad_placements.php:590
258
  #, php-format
259
  msgid "Set <em>%s</em> to show more ads"
260
  msgstr ""
261
 
262
- #: classes/ad_placements.php:591 admin/includes/class-settings.php:160
263
  msgid "Disable level limitation"
264
  msgstr ""
265
 
@@ -378,165 +378,166 @@ msgstr ""
378
  msgid "No shortcode detected in your code."
379
  msgstr ""
380
 
381
- #: classes/display-conditions.php:69
382
  msgid "post type"
383
  msgstr ""
384
 
385
- #: classes/display-conditions.php:70 includes/array_ad_conditions.php:40
386
  msgid "Choose the public post types on which to display the ad."
387
  msgstr ""
388
 
389
- #: classes/display-conditions.php:76
390
  msgid "specific pages"
391
  msgstr ""
392
 
393
- #: classes/display-conditions.php:77 includes/array_ad_conditions.php:58
394
  msgid ""
395
  "Choose on which individual posts, pages and public post type pages you want "
396
  "to display or hide ads."
397
  msgstr ""
398
 
399
- #: classes/display-conditions.php:82
400
  msgid "general conditions"
401
  msgstr ""
402
 
403
- #: classes/display-conditions.php:88
404
  msgid "author"
405
  msgstr ""
406
 
407
- #: classes/display-conditions.php:97
408
  msgid "content age"
409
  msgstr ""
410
 
411
- #: classes/display-conditions.php:98
412
  msgid "Display ads based on age of the page."
413
  msgstr ""
414
 
415
- #: classes/display-conditions.php:106
416
  msgid "taxonomy"
417
  msgstr ""
418
 
419
- #: classes/display-conditions.php:107
420
  msgid "Display ads based on the taxonomy of an archive page."
421
  msgstr ""
422
 
423
- #: classes/display-conditions.php:147
424
  #, php-format
425
  msgid "archive: %s"
426
  msgstr ""
427
 
428
- #: classes/display-conditions.php:250 classes/display-conditions.php:303
429
- #: classes/display-conditions.php:358 classes/display-conditions.php:475
430
- #: classes/visitor-conditions.php:137
431
- msgid "is"
432
  msgstr ""
433
 
434
- #: classes/display-conditions.php:251 classes/display-conditions.php:304
435
- #: classes/display-conditions.php:359 classes/display-conditions.php:476
436
- #: classes/visitor-conditions.php:138
437
- msgid "is not"
438
  msgstr ""
439
 
440
- #: classes/display-conditions.php:274 classes/display-conditions.php:319
441
- #: classes/display-conditions.php:406 classes/display-conditions.php:450
442
- msgctxt "Error message shown when no display condition term is selected"
443
- msgid "Please select some items."
444
  msgstr ""
445
 
446
- #: classes/display-conditions.php:320
447
- #, php-format
448
- msgid ""
449
- "Only %d elements are displayed above. Use the <code>advanced-ads-admin-max-"
450
- "terms</code> filter to change this limit according to <a href=\"%s\" "
451
- "target=\"_blank\">this page</a>."
452
  msgstr ""
453
 
454
- #: classes/display-conditions.php:441
 
 
 
 
 
 
 
 
 
 
 
455
  msgctxt "display the terms search field on ad edit page"
456
  msgid "add more terms"
457
  msgstr ""
458
 
459
- #: classes/display-conditions.php:443
460
  msgid "term name or id"
461
  msgstr ""
462
 
463
- #: classes/display-conditions.php:504
464
  msgid "title or id"
465
  msgstr ""
466
 
467
- #: classes/display-conditions.php:549 includes/array_ad_conditions.php:63
468
  msgid "Home Page"
469
  msgstr ""
470
 
471
- #: classes/display-conditions.php:550 includes/array_ad_conditions.php:64
472
  msgid "show on Home page"
473
  msgstr ""
474
 
475
- #: classes/display-conditions.php:554 includes/array_ad_conditions.php:68
476
  msgid "Singular Pages"
477
  msgstr ""
478
 
479
- #: classes/display-conditions.php:555 includes/array_ad_conditions.php:69
480
  msgid "show on singular pages/posts"
481
  msgstr ""
482
 
483
- #: classes/display-conditions.php:559 includes/array_ad_conditions.php:73
484
  msgid "Archive Pages"
485
  msgstr ""
486
 
487
- #: classes/display-conditions.php:560 includes/array_ad_conditions.php:74
488
  msgid "show on any type of archive page (category, tag, author and date)"
489
  msgstr ""
490
 
491
- #: classes/display-conditions.php:564 includes/array_ad_conditions.php:78
492
  msgid "Search Results"
493
  msgstr ""
494
 
495
- #: classes/display-conditions.php:565 includes/array_ad_conditions.php:79
496
  msgid "show on search result pages"
497
  msgstr ""
498
 
499
- #: classes/display-conditions.php:569 includes/array_ad_conditions.php:83
500
  msgid "404 Page"
501
  msgstr ""
502
 
503
- #: classes/display-conditions.php:570 includes/array_ad_conditions.php:84
504
  msgid "show on 404 error page"
505
  msgstr ""
506
 
507
- #: classes/display-conditions.php:574 includes/array_ad_conditions.php:88
508
  msgid "Attachment Pages"
509
  msgstr ""
510
 
511
- #: classes/display-conditions.php:575 includes/array_ad_conditions.php:89
512
  msgid "show on attachment pages"
513
  msgstr ""
514
 
515
- #: classes/display-conditions.php:579 includes/array_ad_conditions.php:93
516
  msgid "Secondary Queries"
517
  msgstr ""
518
 
519
- #: classes/display-conditions.php:580 includes/array_ad_conditions.php:94
520
  msgid "allow ads in secondary queries"
521
  msgstr ""
522
 
523
- #: classes/display-conditions.php:584
524
  msgid "RSS Feed"
525
  msgstr ""
526
 
527
- #: classes/display-conditions.php:585
528
  msgid "allow ads in RSS Feed"
529
  msgstr ""
530
 
531
- #: classes/display-conditions.php:613
532
  msgid "older than"
533
  msgstr ""
534
 
535
- #: classes/display-conditions.php:614
536
  msgid "younger than"
537
  msgstr ""
538
 
539
- #: classes/display-conditions.php:615
540
  msgid "days"
541
  msgstr ""
542
 
@@ -553,6 +554,14 @@ msgid ""
553
  "or %5$supdate now%6$s."
554
  msgstr ""
555
 
 
 
 
 
 
 
 
 
556
  #: classes/filesystem.php:61
557
  msgid "Could not access filesystem."
558
  msgstr ""
@@ -578,7 +587,7 @@ msgstr ""
578
  msgid "Random AdSense ads"
579
  msgstr ""
580
 
581
- #: classes/frontend_checks.php:109 admin/includes/class-settings.php:514
582
  msgid "You look like a bot"
583
  msgstr ""
584
 
@@ -672,8 +681,8 @@ msgstr ""
672
  msgid "Everything is fine"
673
  msgstr ""
674
 
675
- #: classes/frontend_checks.php:444 admin/includes/class-ad-type.php:676
676
- #: admin/views/notices/welcome-panel.php:20
677
  msgid "Get help"
678
  msgstr ""
679
 
@@ -683,51 +692,75 @@ msgid ""
683
  "admins"
684
  msgstr ""
685
 
686
- #: classes/visitor-conditions.php:32
687
  msgid "device"
688
  msgstr ""
689
 
690
- #: classes/visitor-conditions.php:33
691
  msgid "Display ads only on mobile devices or hide them."
692
  msgstr ""
693
 
694
- #: classes/visitor-conditions.php:39
695
- msgid "logged in visitor"
696
  msgstr ""
697
 
698
- #: classes/visitor-conditions.php:40
699
  msgid "Whether the visitor has to be logged in or not in order to see the ads."
700
  msgstr ""
701
 
702
- #: classes/visitor-conditions.php:97
703
- msgid "Mobile (including tablets)"
 
 
 
704
  msgstr ""
705
 
706
- #: classes/visitor-conditions.php:98
707
- msgid "Desktop"
708
  msgstr ""
709
 
710
- #: classes/visitor-conditions.php:103 classes/visitor-conditions.php:143
711
- msgid "Manual and Troubleshooting"
712
  msgstr ""
713
 
714
- #: classes/visitor-conditions.php:109
715
- #, php-format
716
- msgid ""
717
- "Display ads by the available space on the device or target tablets with the "
718
- "<a href=\"%s\" target=\"_blank\">Responsive add-on</a>"
719
  msgstr ""
720
 
721
- #: classes/visitor-conditions.php:172
722
- msgid "equal"
723
  msgstr ""
724
 
725
- #: classes/visitor-conditions.php:173
726
- msgid "equal or higher"
727
  msgstr ""
728
 
729
- #: classes/visitor-conditions.php:174
730
- msgid "equal or lower"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
731
  msgstr ""
732
 
733
  #: classes/widget.php:22
@@ -744,14 +777,14 @@ msgid "--empty--"
744
  msgstr ""
745
 
746
  #: classes/widget.php:78 admin/includes/class-menu.php:95
747
- #: admin/includes/class-shortcode-creator.php:98 admin/views/placements.php:26
748
  #: modules/gutenberg/includes/class-gutenberg.php:81
749
  #: modules/import-export/views/page.php:25
750
  msgid "Placements"
751
  msgstr ""
752
 
753
  #: classes/widget.php:85 admin/includes/class-shortcode-creator.php:91
754
- #: admin/views/placements-item.php:4 admin/views/placements.php:253
755
  #: modules/gutenberg/includes/class-gutenberg.php:80
756
  msgid "Ad Groups"
757
  msgstr ""
@@ -760,8 +793,8 @@ msgstr ""
760
  #: admin/includes/class-menu.php:68 admin/includes/class-menu.php:68
761
  #: admin/includes/class-shortcode-creator.php:84
762
  #: admin/views/ad-group-list-form-row.php:90
763
- #: admin/views/ad-group-list-header.php:17 admin/views/placements-item.php:16
764
- #: admin/views/placements.php:260
765
  #: modules/gutenberg/includes/class-gutenberg.php:79
766
  #: modules/import-export/views/page.php:23
767
  msgid "Ads"
@@ -921,7 +954,7 @@ msgid ""
921
  "<a href=\"%2$s\" target=\"_blank\">Learn more</a>."
922
  msgstr ""
923
 
924
- #: admin/includes/ad-health-notices.php:74
925
  #, php-format
926
  msgid ""
927
  "Missing PHP extensions could cause issues. Please ask your hosting provider "
@@ -1017,7 +1050,7 @@ msgstr ""
1017
 
1018
  #. %s is a service or plugin name.
1019
  #: admin/includes/ad-health-notices.php:287
1020
- #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:187
1021
  #, php-format
1022
  msgid "%s detected."
1023
  msgstr ""
@@ -1128,86 +1161,86 @@ msgstr ""
1128
  msgid "No ad group created"
1129
  msgstr ""
1130
 
1131
- #: admin/includes/class-ad-type.php:88 admin/includes/class-ad-type.php:94
1132
  msgid "Ad Details"
1133
  msgstr ""
1134
 
1135
- #: admin/includes/class-ad-type.php:89 admin/includes/class-ad-type.php:95
1136
  msgid "Ad Planning"
1137
  msgstr ""
1138
 
1139
- #: admin/includes/class-ad-type.php:90 admin/includes/class-ad-type.php:96
1140
  msgid "Ad Shortcode"
1141
  msgstr ""
1142
 
1143
- #: admin/includes/class-ad-type.php:242
1144
  #, php-format
1145
  msgid "%s ad updated."
1146
  msgid_plural "%s ads updated."
1147
  msgstr[0] ""
1148
  msgstr[1] ""
1149
 
1150
- #: admin/includes/class-ad-type.php:243
1151
  #, php-format
1152
  msgid "%s ad not updated, somebody is editing it."
1153
  msgid_plural "%s ads not updated, somebody is editing them."
1154
  msgstr[0] ""
1155
  msgstr[1] ""
1156
 
1157
- #: admin/includes/class-ad-type.php:244
1158
  #, php-format
1159
  msgid "%s ad permanently deleted."
1160
  msgid_plural "%s ads permanently deleted."
1161
  msgstr[0] ""
1162
  msgstr[1] ""
1163
 
1164
- #: admin/includes/class-ad-type.php:245
1165
  #, php-format
1166
  msgid "%s ad moved to the Trash."
1167
  msgid_plural "%s ads moved to the Trash."
1168
  msgstr[0] ""
1169
  msgstr[1] ""
1170
 
1171
- #: admin/includes/class-ad-type.php:246
1172
  #, php-format
1173
  msgid "%s ad restored from the Trash."
1174
  msgid_plural "%s ads restored from the Trash."
1175
  msgstr[0] ""
1176
  msgstr[1] ""
1177
 
1178
- #: admin/includes/class-ad-type.php:576 admin/includes/class-ad-type.php:577
1179
  msgid "Ad updated."
1180
  msgstr ""
1181
 
1182
  #. translators: %s: date and time of the revision
1183
- #: admin/includes/class-ad-type.php:579
1184
  #, php-format
1185
  msgid "Ad restored to revision from %s"
1186
  msgstr ""
1187
 
1188
- #: admin/includes/class-ad-type.php:580 admin/includes/class-ad-type.php:581
1189
  msgid "Ad saved."
1190
  msgstr ""
1191
 
1192
- #: admin/includes/class-ad-type.php:582
1193
  msgid "Ad submitted."
1194
  msgstr ""
1195
 
1196
- #: admin/includes/class-ad-type.php:584
1197
  #, php-format
1198
  msgid "Ad scheduled for: <strong>%1$s</strong>."
1199
  msgstr ""
1200
 
1201
  #. translators: Publish box date format, see http://php.net/date
1202
- #: admin/includes/class-ad-type.php:586
1203
  msgid "M j, Y @ G:i"
1204
  msgstr ""
1205
 
1206
- #: admin/includes/class-ad-type.php:588
1207
  msgid "Ad draft updated."
1208
  msgstr ""
1209
 
1210
- #: admin/includes/class-ad-type.php:675
1211
  msgid ""
1212
  "You don’t have access to ads. Please deactivate and re-enable Advanced Ads "
1213
  "again to fix this."
@@ -1318,7 +1351,7 @@ msgid "Settings"
1318
  msgstr ""
1319
 
1320
  #: admin/includes/class-menu.php:131 admin/includes/class-menu.php:135
1321
- #: admin/includes/class-settings.php:269
1322
  msgid "Licenses"
1323
  msgstr ""
1324
 
@@ -1358,8 +1391,9 @@ msgid "Ad Stats"
1358
  msgstr ""
1359
 
1360
  #: admin/includes/class-meta-box.php:153 admin/includes/class-meta-box.php:164
1361
- #: admin/includes/class-meta-box.php:169 admin/includes/class-settings.php:607
1362
  #: admin/views/ad-output-metabox.php:82
 
1363
  #: modules/ads-txt/admin/views/setting-create.php:11
1364
  #: modules/privacy/admin/views/setting-enable.php:2
1365
  msgid "Manual"
@@ -1404,19 +1438,19 @@ msgstr ""
1404
  msgid "Latest posts on wpadvancedads.com"
1405
  msgstr ""
1406
 
1407
- #: admin/includes/class-notices.php:457
1408
  #, php-format
1409
  msgid ""
1410
  "You don’t seem to have an email address. Please use <a href=\"%s\" "
1411
  "target=\"_blank\">this form</a> to sign up."
1412
  msgstr ""
1413
 
1414
- #: admin/includes/class-notices.php:475
1415
  msgid ""
1416
  "How embarrassing. The email server seems to be down. Please try again later."
1417
  msgstr ""
1418
 
1419
- #: admin/includes/class-notices.php:480
1420
  #, php-format
1421
  msgid ""
1422
  "Please check your email (%s) for the confirmation message. If you didn’t "
@@ -1433,7 +1467,7 @@ msgid "Manual and Support"
1433
  msgstr ""
1434
 
1435
  #: admin/includes/class-overview-widgets.php:105
1436
- #: admin/views/notices/welcome-panel.php:6
1437
  msgid "Create your first ad"
1438
  msgstr ""
1439
 
@@ -1486,7 +1520,6 @@ msgid "Get the All Access pass"
1486
  msgstr ""
1487
 
1488
  #: admin/includes/class-overview-widgets.php:173
1489
- #: admin/views/notices/welcome-panel.php:22
1490
  #, php-format
1491
  msgid "<a href=\"%s\" target=\"_blank\">Manual</a>"
1492
  msgstr ""
@@ -1635,7 +1668,8 @@ msgid "Get full access"
1635
  msgstr ""
1636
 
1637
  #: admin/includes/class-overview-widgets.php:658
1638
- #: admin/views/ad-display-metabox.php:48 admin/views/ad-visitor-metabox.php:48
 
1639
  msgid "Visit the manual"
1640
  msgstr ""
1641
 
@@ -1668,82 +1702,86 @@ msgid "Priority of content injection filter"
1668
  msgstr ""
1669
 
1670
  #: admin/includes/class-settings.php:168
 
 
 
 
1671
  msgid "Hide ads from bots"
1672
  msgstr ""
1673
 
1674
- #: admin/includes/class-settings.php:177
1675
  msgid "Disable ads for post types"
1676
  msgstr ""
1677
 
1678
- #: admin/includes/class-settings.php:186
1679
  msgid "Disable Ad Health and other notices"
1680
  msgstr ""
1681
 
1682
- #: admin/includes/class-settings.php:194
1683
  msgid "ID prefix"
1684
  msgstr ""
1685
 
1686
- #: admin/includes/class-settings.php:202
1687
  msgid "Allow editors to manage ads"
1688
  msgstr ""
1689
 
1690
- #: admin/includes/class-settings.php:210
1691
  msgid "Ad label"
1692
  msgstr ""
1693
 
1694
- #: admin/includes/class-settings.php:219
1695
  msgid "Open links in a new window"
1696
  msgstr ""
1697
 
1698
- #: admin/includes/class-settings.php:227
1699
  msgid "Use advanced JavaScript"
1700
  msgstr ""
1701
 
1702
- #: admin/includes/class-settings.php:237
1703
  msgid "Delete data on uninstall"
1704
  msgstr ""
1705
 
1706
- #: admin/includes/class-settings.php:247
1707
  msgid "Disable shortcode button"
1708
  msgstr ""
1709
 
1710
- #: admin/includes/class-settings.php:286
1711
  msgid "Pro"
1712
  msgstr ""
1713
 
1714
- #: admin/includes/class-settings.php:302 admin/views/pitch-tracking.php:2
1715
  msgid "Tracking"
1716
  msgstr ""
1717
 
1718
- #: admin/includes/class-settings.php:350
1719
  #, php-format
1720
  msgid ""
1721
  "Enter license keys for our powerful <a href=\"%s\" target=\"_blank\">add-"
1722
  "ons</a>."
1723
  msgstr ""
1724
 
1725
- #: admin/includes/class-settings.php:351
1726
  #, php-format
1727
  msgid ""
1728
  "See also <a href=\"%s\" target=\"_blank\">Issues and questions about "
1729
  "licenses</a>."
1730
  msgstr ""
1731
 
1732
- #: admin/includes/class-settings.php:363
1733
  msgid "Are you missing something?"
1734
  msgstr ""
1735
 
1736
- #: admin/includes/class-settings.php:431
1737
  msgid "Choose the roles a user must have in order to not see any ads."
1738
  msgstr ""
1739
 
1740
- #: admin/includes/class-settings.php:445
1741
  msgid ""
1742
  "<strong>notice: </strong>the file is currently enabled by an add-on that "
1743
  "needs it."
1744
  msgstr ""
1745
 
1746
- #: admin/includes/class-settings.php:448
1747
  #, php-format
1748
  msgid ""
1749
  "Enable advanced JavaScript functions (<a href=\"%s\" target=\"_blank\">"
@@ -1751,7 +1789,7 @@ msgid ""
1751
  "need features from this file."
1752
  msgstr ""
1753
 
1754
- #: admin/includes/class-settings.php:468
1755
  msgid ""
1756
  "Some plugins and themes trigger ad injections where it shouldn’t happen. "
1757
  "Therefore, Advanced Ads ignores injected placements on non-singular pages "
@@ -1761,77 +1799,85 @@ msgid ""
1761
  "injection only in the first x posts on your archive pages."
1762
  msgstr ""
1763
 
1764
- #: admin/includes/class-settings.php:484
1765
  msgid ""
1766
  "Please check your post content. A priority of 10 and below might cause "
1767
  "issues (wpautop function might run twice)."
1768
  msgstr ""
1769
 
1770
- #: admin/includes/class-settings.php:486
1771
  msgid ""
1772
  "Play with this value in order to change the priority of the injected ads "
1773
  "compared to other auto injected elements in the post content."
1774
  msgstr ""
1775
 
1776
- #: admin/includes/class-settings.php:500
1777
  msgid ""
1778
  "Advanced Ads ignores paragraphs and other elements in containers when "
1779
  "injecting ads into the post content. Check this option to ignore this "
1780
  "limitation and ads might show up again."
1781
  msgstr ""
1782
 
1783
- #: admin/includes/class-settings.php:516
 
 
 
 
 
 
 
 
1784
  msgid "Read this first"
1785
  msgstr ""
1786
 
1787
- #: admin/includes/class-settings.php:517
1788
  msgid "Hide ads from crawlers, bots and empty user agents."
1789
  msgstr ""
1790
 
1791
- #: admin/includes/class-settings.php:530
1792
  msgid "Pro feature"
1793
  msgstr ""
1794
 
1795
  #. %1$s is a starting <a> tag and %2$s a closing one
1796
- #: admin/includes/class-settings.php:548
1797
  #, php-format
1798
  msgid ""
1799
  "Disable %1$sAd Health%2$s in frontend and backend, warnings and internal "
1800
  "notices like tips, tutorials, email newsletters and update notices."
1801
  msgstr ""
1802
 
1803
- #: admin/includes/class-settings.php:566
1804
  msgid ""
1805
  "Prefix of class or id attributes in the frontend. Change it if you don’t "
1806
  "want <strong>ad blockers</strong> to mark these blocks as ads.<br/>You might "
1807
  "need to <strong>rewrite css rules afterwards</strong>."
1808
  msgstr ""
1809
 
1810
- #: admin/includes/class-settings.php:585
1811
  msgid "Allow editors to also manage and publish ads."
1812
  msgstr ""
1813
 
1814
- #: admin/includes/class-settings.php:586
1815
  #, php-format
1816
  msgid ""
1817
  "You can assign different ad-related roles on a user basis with <a "
1818
  "href=\"%s\" target=\"_blank\">Advanced Ads Pro</a>."
1819
  msgstr ""
1820
 
1821
- #: admin/includes/class-settings.php:597
1822
  msgctxt "label before ads"
1823
  msgid "Advertisements"
1824
  msgstr ""
1825
 
1826
- #: admin/includes/class-settings.php:606
1827
  msgid "Displayed above ads."
1828
  msgstr ""
1829
 
1830
- #: admin/includes/class-settings.php:642
1831
  msgid "Clean up all data related to Advanced Ads when removing the plugin."
1832
  msgstr ""
1833
 
1834
- #: admin/includes/class-settings.php:655
1835
  msgid "Disable shortcode button in visual editor."
1836
  msgstr ""
1837
 
@@ -1896,6 +1942,16 @@ msgstr ""
1896
  msgid "Yes, but help me first to solve a problem, please"
1897
  msgstr ""
1898
 
 
 
 
 
 
 
 
 
 
 
1899
  #: admin/includes/shortcode-creator-l10n.php:10
1900
  msgctxt "shortcode creator"
1901
  msgid "Add an ad"
@@ -1952,85 +2008,6 @@ msgstr ""
1952
  msgid "does not match regex"
1953
  msgstr ""
1954
 
1955
- #: admin/views/ad-display-metabox.php:17
1956
- msgid "parent page"
1957
- msgstr ""
1958
-
1959
- #: admin/views/ad-display-metabox.php:18
1960
- msgid "post meta"
1961
- msgstr ""
1962
-
1963
- #: admin/views/ad-display-metabox.php:19
1964
- msgid "page template"
1965
- msgstr ""
1966
-
1967
- #: admin/views/ad-display-metabox.php:20
1968
- msgid "url parameters"
1969
- msgstr ""
1970
-
1971
- #: admin/views/ad-display-metabox.php:23
1972
- msgid "accelerated mobile pages"
1973
- msgstr ""
1974
-
1975
- #: admin/views/ad-display-metabox.php:31
1976
- msgid ""
1977
- "Click on the button below if the ad should NOT show up on all pages when "
1978
- "included automatically."
1979
- msgstr ""
1980
-
1981
- #: admin/views/ad-display-metabox.php:32
1982
- msgid "Hide the ad on some pages"
1983
- msgstr ""
1984
-
1985
- #: admin/views/ad-display-metabox.php:46
1986
- msgid "Watch video"
1987
- msgstr ""
1988
-
1989
- #: admin/views/ad-display-metabox.php:58
1990
- #: admin/views/notices/jqueryui_error.php:2
1991
- #, php-format
1992
- msgid ""
1993
- "There might be a problem with layouts and scripts in your dashboard. Please "
1994
- "check <a href=\"%s\" target=\"_blank\">this article to learn more</a>."
1995
- msgstr ""
1996
-
1997
- #: admin/views/ad-display-metabox.php:59
1998
- msgid "A page with this ad on it must match all of the following conditions."
1999
- msgstr ""
2000
-
2001
- #: admin/views/ad-display-metabox.php:103
2002
- msgid "Forced to OR."
2003
- msgstr ""
2004
-
2005
- #: admin/views/ad-display-metabox.php:104
2006
- #: modules/gadsense/admin/views/adsense-ad-parameters.php:121
2007
- msgid "manual"
2008
- msgstr ""
2009
-
2010
- #: admin/views/ad-display-metabox.php:129
2011
- msgid "If you want to display the ad everywhere, don't do anything here. "
2012
- msgstr ""
2013
-
2014
- #: admin/views/ad-display-metabox.php:139
2015
- #: admin/views/ad-visitor-metabox.php:102
2016
- msgid "New condition"
2017
- msgstr ""
2018
-
2019
- #: admin/views/ad-display-metabox.php:142
2020
- #: admin/views/ad-visitor-metabox.php:105
2021
- msgid "-- choose a condition --"
2022
- msgstr ""
2023
-
2024
- #: admin/views/ad-display-metabox.php:149
2025
- #: admin/views/ad-visitor-metabox.php:114
2026
- msgid "Add-On features"
2027
- msgstr ""
2028
-
2029
- #: admin/views/ad-display-metabox.php:162 admin/views/ad-group-list-ads.php:37
2030
- #: admin/views/ad-visitor-metabox.php:127
2031
- msgid "add"
2032
- msgstr ""
2033
-
2034
  #: admin/views/ad-group-edit.php:18
2035
  msgid "You did not select an item for editing."
2036
  msgstr ""
@@ -2067,14 +2044,19 @@ msgstr ""
2067
  msgid "weight"
2068
  msgstr ""
2069
 
2070
- #: admin/views/ad-group-list-form-row.php:29 admin/views/placements.php:32
 
 
 
 
 
2071
  #: modules/gadsense/admin/views/external-ads-list.php:30
2072
  #: modules/gadsense/admin/views/external-ads-list.php:43
2073
  #: modules/privacy/admin/views/setting-consent-method.php:9
2074
  msgid "Name"
2075
  msgstr ""
2076
 
2077
- #: admin/views/ad-group-list-form-row.php:55 admin/views/placements.php:31
2078
  #: modules/gadsense/admin/views/adsense-ad-parameters.php:110
2079
  msgid "Type"
2080
  msgstr ""
@@ -2097,7 +2079,7 @@ msgid "Details"
2097
  msgstr ""
2098
 
2099
  #: admin/views/ad-group-list-row.php:19 admin/views/ad-info.php:3
2100
- #: admin/views/placements.php:92
2101
  msgid "shortcode"
2102
  msgstr ""
2103
 
@@ -2268,7 +2250,7 @@ msgstr ""
2268
  #: admin/views/placements-ad-label-position.php:2
2269
  #: admin/views/placements-ad-label-position.php:5
2270
  #: admin/views/placements-ad-label.php:1 admin/views/placements-ad-label.php:4
2271
- #: admin/views/placements.php:74
2272
  #: modules/gadsense/includes/class-network-adsense.php:236
2273
  msgid "default"
2274
  msgstr ""
@@ -2396,112 +2378,6 @@ msgctxt ""
2396
  msgid "%1$s %2$s, %3$s @ %4$s %5$s"
2397
  msgstr ""
2398
 
2399
- #: admin/views/ad-visitor-metabox.php:7
2400
- msgid "browser language"
2401
- msgstr ""
2402
-
2403
- #: admin/views/ad-visitor-metabox.php:8
2404
- msgid "cookie"
2405
- msgstr ""
2406
-
2407
- #: admin/views/ad-visitor-metabox.php:9
2408
- msgid "max. ad clicks"
2409
- msgstr ""
2410
-
2411
- #: admin/views/ad-visitor-metabox.php:10
2412
- msgid "max. ad impressions"
2413
- msgstr ""
2414
-
2415
- #: admin/views/ad-visitor-metabox.php:11
2416
- msgid "new visitor"
2417
- msgstr ""
2418
-
2419
- #: admin/views/ad-visitor-metabox.php:12
2420
- msgid "page impressions"
2421
- msgstr ""
2422
-
2423
- #: admin/views/ad-visitor-metabox.php:13
2424
- msgid "referrer url"
2425
- msgstr ""
2426
-
2427
- #: admin/views/ad-visitor-metabox.php:14
2428
- msgid "user agent"
2429
- msgstr ""
2430
-
2431
- #: admin/views/ad-visitor-metabox.php:15
2432
- msgid "user can (capabilities)"
2433
- msgstr ""
2434
-
2435
- #: admin/views/ad-visitor-metabox.php:16
2436
- msgid "user role"
2437
- msgstr ""
2438
-
2439
- #: admin/views/ad-visitor-metabox.php:19
2440
- msgid "geo location"
2441
- msgstr ""
2442
-
2443
- #: admin/views/ad-visitor-metabox.php:22
2444
- msgid "browser width"
2445
- msgstr ""
2446
-
2447
- #: admin/views/ad-visitor-metabox.php:30
2448
- msgid ""
2449
- "Click on the button below if the ad should NOT be visible to all visitors"
2450
- msgstr ""
2451
-
2452
- #: admin/views/ad-visitor-metabox.php:31
2453
- msgid "Hide the ad from some users"
2454
- msgstr ""
2455
-
2456
- #: admin/views/ad-visitor-metabox.php:41
2457
- msgid ""
2458
- "Display conditions that are based on the user. Use with caution on cached "
2459
- "websites."
2460
- msgstr ""
2461
-
2462
- #: admin/views/ad-visitor-metabox.php:87
2463
- msgid ""
2464
- "Visitor conditions limit the number of users who can see your ad. There is "
2465
- "no need to set visitor conditions if you want all users to see the ad."
2466
- msgstr ""
2467
-
2468
- #: admin/views/ad-visitor-metabox.php:91
2469
- #: modules/privacy/admin/views/setting-enable.php:4
2470
- msgid "It seems that a caching plugin is activated."
2471
- msgstr ""
2472
-
2473
- #: admin/views/ad-visitor-metabox.php:93
2474
- #, php-format
2475
- msgid ""
2476
- "Check out cache-busting in <a href=\"%s\" target=\"_blank\">Advanced Ads "
2477
- "Pro</a> if dynamic features get cached."
2478
- msgstr ""
2479
-
2480
- #: admin/views/ad-visitor-metabox.php:132
2481
- #, php-format
2482
- msgid ""
2483
- "Define the exact browser width for which an ad should be visible using the "
2484
- "<a href=\"%s\" target=\"_blank\">Responsive add-on</a>."
2485
- msgstr ""
2486
-
2487
- #: admin/views/ad-visitor-metabox.php:189
2488
- msgid ""
2489
- "The visitor conditions below are deprecated. Please use the new version of "
2490
- "visitor conditions to replace it."
2491
- msgstr ""
2492
-
2493
- #: admin/views/ad-visitor-metabox.php:195
2494
- msgid "Display on all devices"
2495
- msgstr ""
2496
-
2497
- #: admin/views/ad-visitor-metabox.php:199
2498
- msgid "only on mobile devices"
2499
- msgstr ""
2500
-
2501
- #: admin/views/ad-visitor-metabox.php:203
2502
- msgid "not on mobile devices"
2503
- msgstr ""
2504
-
2505
  #: admin/views/checks.php:14
2506
  #, php-format
2507
  msgid ""
@@ -2634,6 +2510,55 @@ msgstr ""
2634
  msgid "spread impressions or clicks equally over a given period"
2635
  msgstr ""
2636
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2637
  #: admin/views/placement-injection-top.php:10
2638
  msgid "Congratulations! Your ad is now visible in the frontend."
2639
  msgstr ""
@@ -2771,10 +2696,6 @@ msgstr ""
2771
  msgid "start counting from bottom"
2772
  msgstr ""
2773
 
2774
- #: admin/views/placements-item.php:2 admin/views/placements.php:251
2775
- msgid "--not selected--"
2776
- msgstr ""
2777
-
2778
  #: admin/views/placements.php:10
2779
  msgid ""
2780
  "Couldn’t create the new placement. Please check your form field and whether "
@@ -2785,134 +2706,89 @@ msgstr ""
2785
  msgid "Placements updated"
2786
  msgstr ""
2787
 
2788
- #: admin/views/placements.php:20
 
 
 
 
 
 
 
 
2789
  msgid ""
2790
  "Placements are physically places in your theme and posts. You can use them "
2791
  "if you plan to change ads and ad groups on the same place without the need "
2792
  "to change your templates."
2793
  msgstr ""
2794
 
2795
- #: admin/views/placements.php:21
2796
  #, php-format
2797
  msgid ""
2798
  "See also the manual for more information on <a href=\"%s\">placements</a>."
2799
  msgstr ""
2800
 
2801
- #: admin/views/placements.php:33 modules/import-export/views/page.php:26
2802
  msgid "Options"
2803
  msgstr ""
2804
 
2805
- #: admin/views/placements.php:55
2806
  #, php-format
2807
  msgid ""
2808
  "Placement type \"%s\" is missing and was reset to \"default\".<br/>Please "
2809
  "check if the responsible add-on is activated."
2810
  msgstr ""
2811
 
2812
- #: admin/views/placements.php:83
2813
  msgid "show usage"
2814
  msgstr ""
2815
 
2816
- #: admin/views/placements.php:95
2817
  msgid "template (PHP)"
2818
  msgstr ""
2819
 
2820
- #: admin/views/placements.php:110
2821
  msgid "Item"
2822
  msgstr ""
2823
 
2824
- #: admin/views/placements.php:124
2825
  msgid "position"
2826
  msgstr ""
2827
 
2828
- #: admin/views/placements.php:130
2829
  msgid "Important Notice"
2830
  msgstr ""
2831
 
2832
- #: admin/views/placements.php:130
2833
  msgid ""
2834
  "Your server is missing an extension. This might break the content injection."
2835
  "<br/>Ignore this warning if everything works fine or else ask your hosting "
2836
  "provider to enable <em>mbstring</em>."
2837
  msgstr ""
2838
 
2839
- #: admin/views/placements.php:152
2840
  msgid "ad label"
2841
  msgstr ""
2842
 
2843
- #: admin/views/placements.php:162
2844
  msgid "show all options"
2845
  msgstr ""
2846
 
2847
- #: admin/views/placements.php:181
2848
  #, php-format
2849
  msgid ""
2850
  "Tutorial: <a href=\"%s\" target=\"_blank\">How to place visible ads in the "
2851
  "header of your website</a>."
2852
  msgstr ""
2853
 
2854
- #: admin/views/placements.php:190
2855
  msgctxt "checkbox to remove placement"
2856
  msgid "delete"
2857
  msgstr ""
2858
 
2859
- #: admin/views/placements.php:197
2860
  msgid "Save Placements"
2861
  msgstr ""
2862
 
2863
- #: admin/views/placements.php:199
2864
- msgid "Create a new placement"
2865
- msgstr ""
2866
-
2867
- #: admin/views/placements.php:201
2868
- msgid "New Placement"
2869
- msgstr ""
2870
-
2871
- #: admin/views/placements.php:220
2872
- msgid "Choose a placement type"
2873
- msgstr ""
2874
-
2875
- #: admin/views/placements.php:221
2876
- #, php-format
2877
- msgid ""
2878
- "Placement types define where the ad is going to be displayed. Learn more "
2879
- "about the different types from the <a href=\"%s\">manual</a>"
2880
- msgstr ""
2881
-
2882
- #: admin/views/placements.php:242
2883
- msgid "Please select a placement type."
2884
- msgstr ""
2885
-
2886
- #: admin/views/placements.php:244
2887
- msgid "Choose a Name"
2888
- msgstr ""
2889
-
2890
- #: admin/views/placements.php:245
2891
- msgid ""
2892
- "The name of the placement is only visible to you. Tip: choose a descriptive "
2893
- "one, e.g. <em>Below Post Headline</em>."
2894
- msgstr ""
2895
-
2896
- #: admin/views/placements.php:246
2897
- msgid "Placement Name"
2898
- msgstr ""
2899
-
2900
- #: admin/views/placements.php:247
2901
- msgid "Please enter a name for your placement."
2902
- msgstr ""
2903
-
2904
- #: admin/views/placements.php:248
2905
- msgid "Choose the Ad or Group"
2906
- msgstr ""
2907
-
2908
- #: admin/views/placements.php:249
2909
- msgid "The ad or group that should be displayed."
2910
- msgstr ""
2911
-
2912
- #: admin/views/placements.php:268
2913
- msgid "Save New Placement"
2914
- msgstr ""
2915
-
2916
  #: admin/views/post-ad-settings-metabox.php:1
2917
  msgid "How to disable ads on specific pages"
2918
  msgstr ""
@@ -3093,41 +2969,198 @@ msgstr ""
3093
  msgid "Find solutions in the manual"
3094
  msgstr ""
3095
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3096
  #: admin/views/notices/adblock.php:4
3097
  msgid ""
3098
  "Please disable your <strong>AdBlocker</strong> to prevent problems with your "
3099
  "ad setup."
3100
  msgstr ""
3101
 
3102
- #: admin/views/notices/welcome-panel.php:2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3103
  msgid "Welcome to Advanced Ads!"
3104
  msgstr ""
3105
 
3106
- #: admin/views/notices/welcome-panel.php:5
3107
  msgid "Get Started"
3108
  msgstr ""
3109
 
3110
- #: admin/views/notices/welcome-panel.php:8
3111
  msgid "First ad tutorial"
3112
  msgstr ""
3113
 
3114
- #: admin/views/notices/welcome-panel.php:12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3115
  msgid "AdSense Options"
3116
  msgstr ""
3117
 
3118
- #: admin/views/notices/welcome-panel.php:13
3119
  msgid "Import ads from AdSense"
3120
  msgstr ""
3121
 
3122
- #: admin/views/notices/welcome-panel.php:15
3123
  msgid "Setting up Auto ads"
3124
  msgstr ""
3125
 
3126
- #: admin/views/notices/welcome-panel.php:16
3127
  msgid "Setting up AdSense ads manually"
3128
  msgstr ""
3129
 
3130
- #: admin/views/notices/welcome-panel.php:23
3131
  msgid "Reach out for help"
3132
  msgstr ""
3133
 
@@ -3136,6 +3169,7 @@ msgid "Ad blocker fix"
3136
  msgstr ""
3137
 
3138
  #: modules/ad-blocker/admin/admin.php:150
 
3139
  msgid "Unable to connect to the filesystem. Please confirm your credentials."
3140
  msgstr ""
3141
 
@@ -3178,40 +3212,66 @@ msgstr ""
3178
  msgid "Ad blocker counter"
3179
  msgstr ""
3180
 
3181
- #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:167
3182
  #, php-format
3183
  msgid ""
3184
  "The ads.txt file cannot be placed because the URL contains a subdirectory. "
3185
  "You need to make the file available at %s"
3186
  msgstr ""
3187
 
3188
- #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:178
3189
  #, php-format
3190
  msgid "The file is available on %s."
3191
  msgstr ""
3192
 
3193
- #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:182
3194
  msgid "The file was not created."
3195
  msgstr ""
3196
 
3197
- #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:188
3198
  msgid "Find the solution here"
3199
  msgstr ""
3200
 
3201
- #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:203
 
 
 
 
 
 
 
 
 
 
3202
  #: modules/ads-txt/admin/views/setting-additional-content.php:4
3203
  #, php-format
3204
  msgid "An error occured: %s."
3205
  msgstr ""
3206
 
3207
  #. %s the line that may need to be added manually
3208
- #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:216
3209
  #, php-format
3210
  msgid ""
3211
  "If your site is located on a subdomain, you need to add the following line "
3212
  "to the ads.txt file of the root domain: %s"
3213
  msgstr ""
3214
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3215
  #: modules/gadsense/admin/admin.php:121
3216
  #, php-format
3217
  msgid ""
3
  msgstr ""
4
  "Project-Id-Version: Advanved Ads\n"
5
  "Report-Msgid-Bugs-To: http://wordpress.org/plugins/plugin-name\n"
6
+ "POT-Creation-Date: 2019-11-07 09:14+0000\n"
7
  "POT-Revision-Date: Wed Jul 13 2016 13:23:05 GMT+0200 (CEST)\n"
8
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
9
  "Last-Translator: Thomas Maier <post@webzunft.de>\n"
23
  "X-Poedit-Basepath: ../\n"
24
  "X-Poedit-SearchPath-0: ."
25
 
26
+ #: admin/class-advanced-ads-admin.php:232 classes/display-conditions.php:283
27
+ #: classes/visitor-conditions.php:298
28
  #: modules/gadsense/admin/views/external-ads-links.php:17
29
  #: modules/gadsense/admin/views/external-ads-links.php:21
30
  #: modules/gadsense/admin/views/external-ads-links.php:28
31
  msgid "or"
32
  msgstr ""
33
 
34
+ #: admin/class-advanced-ads-admin.php:233 classes/display-conditions.php:283
35
+ #: classes/visitor-conditions.php:298
36
  msgid "and"
37
  msgstr ""
38
 
39
+ #: admin/class-advanced-ads-admin.php:234
40
  msgid "After which paragraph?"
41
  msgstr ""
42
 
43
+ #: admin/class-advanced-ads-admin.php:236
44
  msgid "Today"
45
  msgstr ""
46
 
47
+ #: admin/class-advanced-ads-admin.php:237
48
  msgid "Yesterday"
49
  msgstr ""
50
 
51
+ #: admin/class-advanced-ads-admin.php:238
52
  msgid "This Month"
53
  msgstr ""
54
 
55
  #. 1: The number of days.
56
+ #: admin/class-advanced-ads-admin.php:240
57
  #, php-format
58
  msgid "Last %1$d days"
59
  msgstr ""
60
 
61
+ #: admin/class-advanced-ads-admin.php:243
62
  msgid "All"
63
  msgstr ""
64
 
65
+ #: admin/class-advanced-ads-admin.php:244
66
  msgid ""
67
  "There were no results returned for this ad. Please make sure it is active, "
68
  "generating impressions and double check your ad parameters."
69
  msgstr ""
70
 
71
+ #: admin/class-advanced-ads-admin.php:245
72
  #: modules/gadsense/admin/views/external-ads-list.php:12
73
  msgid "Show inactive ads"
74
  msgstr ""
75
 
76
+ #: admin/class-advanced-ads-admin.php:246
77
  msgid "Hide inactive ads"
78
  msgstr ""
79
 
80
+ #: admin/class-advanced-ads-admin.php:360
81
  #, php-format
82
  msgid "time of %s"
83
  msgstr ""
84
 
85
+ #: admin/class-advanced-ads-admin.php:434 admin/includes/class-menu.php:113
86
  #: admin/includes/class-menu.php:116 admin/views/settings.php:28
87
  msgid "Support"
88
  msgstr ""
89
 
90
+ #: admin/class-advanced-ads-admin.php:438
91
  #: admin/includes/class-overview-widgets.php:58
92
  msgid "Add-Ons"
93
  msgstr ""
94
 
95
+ #: admin/class-advanced-ads-admin.php:707
96
  #: admin/includes/class-overview-widgets.php:175
97
  #, php-format
98
  msgid ""
168
  msgid "Learn more about AdSense account issues %1$shere%2$s."
169
  msgstr ""
170
 
171
+ #: classes/ad_placements.php:36
172
  msgid "Manual Placement"
173
  msgstr ""
174
 
175
+ #: classes/ad_placements.php:37
176
  msgid "Manual placement to use as function or shortcode."
177
  msgstr ""
178
 
179
+ #: classes/ad_placements.php:42
180
  msgid "Header Code"
181
  msgstr ""
182
 
183
+ #: classes/ad_placements.php:43
184
  msgid ""
185
  "Injected in Header (before closing &lt;/head&gt; Tag, often not visible)."
186
  msgstr ""
187
 
188
+ #: classes/ad_placements.php:47
189
  msgid "Footer Code"
190
  msgstr ""
191
 
192
+ #: classes/ad_placements.php:48
193
  msgid "Injected in Footer (before closing &lt;/body&gt; Tag)."
194
  msgstr ""
195
 
196
+ #: classes/ad_placements.php:53 admin/views/placement-injection-top.php:49
197
  msgid "Before Content"
198
  msgstr ""
199
 
200
+ #: classes/ad_placements.php:54
201
  msgid "Injected before the post content."
202
  msgstr ""
203
 
204
+ #: classes/ad_placements.php:59 admin/views/placement-injection-top.php:51
205
  msgid "After Content"
206
  msgstr ""
207
 
208
+ #: classes/ad_placements.php:60
209
  msgid "Injected after the post content."
210
  msgstr ""
211
 
212
+ #: classes/ad_placements.php:65 admin/views/placement-injection-top.php:50
213
  msgid "Content"
214
  msgstr ""
215
 
216
+ #: classes/ad_placements.php:66
217
  msgid ""
218
  "Injected into the content. You can choose the paragraph after which the ad "
219
  "content is displayed."
220
  msgstr ""
221
 
222
+ #: classes/ad_placements.php:71
223
  msgid "Sidebar Widget"
224
  msgstr ""
225
 
226
+ #: classes/ad_placements.php:72
227
  msgid ""
228
  "Create a sidebar widget with an ad. Can be placed and used like any other "
229
  "widget."
230
  msgstr ""
231
 
232
+ #: classes/ad_placements.php:243
233
  #, php-format
234
  msgid "paragraph (%s)"
235
  msgstr ""
236
 
237
+ #: classes/ad_placements.php:244
238
  #, php-format
239
  msgid "paragraph without image (%s)"
240
  msgstr ""
241
 
242
+ #: classes/ad_placements.php:245
243
  #, php-format
244
  msgid "headline 2 (%s)"
245
  msgstr ""
246
 
247
+ #: classes/ad_placements.php:246
248
  #, php-format
249
  msgid "headline 3 (%s)"
250
  msgstr ""
251
 
252
+ #: classes/ad_placements.php:247
253
  #, php-format
254
  msgid "headline 4 (%s)"
255
  msgstr ""
256
 
257
+ #: classes/ad_placements.php:808
258
  #, php-format
259
  msgid "Set <em>%s</em> to show more ads"
260
  msgstr ""
261
 
262
+ #: classes/ad_placements.php:809 admin/includes/class-settings.php:160
263
  msgid "Disable level limitation"
264
  msgstr ""
265
 
378
  msgid "No shortcode detected in your code."
379
  msgstr ""
380
 
381
+ #: classes/display-conditions.php:88
382
  msgid "post type"
383
  msgstr ""
384
 
385
+ #: classes/display-conditions.php:89 includes/array_ad_conditions.php:40
386
  msgid "Choose the public post types on which to display the ad."
387
  msgstr ""
388
 
389
+ #: classes/display-conditions.php:96
390
  msgid "specific pages"
391
  msgstr ""
392
 
393
+ #: classes/display-conditions.php:97 includes/array_ad_conditions.php:58
394
  msgid ""
395
  "Choose on which individual posts, pages and public post type pages you want "
396
  "to display or hide ads."
397
  msgstr ""
398
 
399
+ #: classes/display-conditions.php:103
400
  msgid "general conditions"
401
  msgstr ""
402
 
403
+ #: classes/display-conditions.php:110
404
  msgid "author"
405
  msgstr ""
406
 
407
+ #: classes/display-conditions.php:117
408
  msgid "content age"
409
  msgstr ""
410
 
411
+ #: classes/display-conditions.php:118
412
  msgid "Display ads based on age of the page."
413
  msgstr ""
414
 
415
+ #: classes/display-conditions.php:124
416
  msgid "taxonomy"
417
  msgstr ""
418
 
419
+ #: classes/display-conditions.php:125
420
  msgid "Display ads based on the taxonomy of an archive page."
421
  msgstr ""
422
 
423
+ #: classes/display-conditions.php:165
424
  #, php-format
425
  msgid "archive: %s"
426
  msgstr ""
427
 
428
+ #: classes/display-conditions.php:253
429
+ msgid "parent page"
 
 
430
  msgstr ""
431
 
432
+ #: classes/display-conditions.php:254
433
+ msgid "post meta"
 
 
434
  msgstr ""
435
 
436
+ #: classes/display-conditions.php:255
437
+ msgid "page template"
 
 
438
  msgstr ""
439
 
440
+ #: classes/display-conditions.php:256
441
+ msgid "url parameters"
 
 
 
 
442
  msgstr ""
443
 
444
+ #: classes/display-conditions.php:259
445
+ msgid "accelerated mobile pages"
446
+ msgstr ""
447
+
448
+ #: classes/display-conditions.php:384 classes/display-conditions.php:527
449
+ #: classes/display-conditions.php:588
450
+ #: admin/views/conditions/condition-author.php:19
451
+ msgctxt "Error message shown when no display condition term is selected"
452
+ msgid "Please select some items."
453
+ msgstr ""
454
+
455
+ #: classes/display-conditions.php:573
456
  msgctxt "display the terms search field on ad edit page"
457
  msgid "add more terms"
458
  msgstr ""
459
 
460
+ #: classes/display-conditions.php:577
461
  msgid "term name or id"
462
  msgstr ""
463
 
464
+ #: classes/display-conditions.php:651
465
  msgid "title or id"
466
  msgstr ""
467
 
468
+ #: classes/display-conditions.php:703 includes/array_ad_conditions.php:63
469
  msgid "Home Page"
470
  msgstr ""
471
 
472
+ #: classes/display-conditions.php:704 includes/array_ad_conditions.php:64
473
  msgid "show on Home page"
474
  msgstr ""
475
 
476
+ #: classes/display-conditions.php:708 includes/array_ad_conditions.php:68
477
  msgid "Singular Pages"
478
  msgstr ""
479
 
480
+ #: classes/display-conditions.php:709 includes/array_ad_conditions.php:69
481
  msgid "show on singular pages/posts"
482
  msgstr ""
483
 
484
+ #: classes/display-conditions.php:713 includes/array_ad_conditions.php:73
485
  msgid "Archive Pages"
486
  msgstr ""
487
 
488
+ #: classes/display-conditions.php:714 includes/array_ad_conditions.php:74
489
  msgid "show on any type of archive page (category, tag, author and date)"
490
  msgstr ""
491
 
492
+ #: classes/display-conditions.php:718 includes/array_ad_conditions.php:78
493
  msgid "Search Results"
494
  msgstr ""
495
 
496
+ #: classes/display-conditions.php:719 includes/array_ad_conditions.php:79
497
  msgid "show on search result pages"
498
  msgstr ""
499
 
500
+ #: classes/display-conditions.php:723 includes/array_ad_conditions.php:83
501
  msgid "404 Page"
502
  msgstr ""
503
 
504
+ #: classes/display-conditions.php:724 includes/array_ad_conditions.php:84
505
  msgid "show on 404 error page"
506
  msgstr ""
507
 
508
+ #: classes/display-conditions.php:728 includes/array_ad_conditions.php:88
509
  msgid "Attachment Pages"
510
  msgstr ""
511
 
512
+ #: classes/display-conditions.php:729 includes/array_ad_conditions.php:89
513
  msgid "show on attachment pages"
514
  msgstr ""
515
 
516
+ #: classes/display-conditions.php:733 includes/array_ad_conditions.php:93
517
  msgid "Secondary Queries"
518
  msgstr ""
519
 
520
+ #: classes/display-conditions.php:734 includes/array_ad_conditions.php:94
521
  msgid "allow ads in secondary queries"
522
  msgstr ""
523
 
524
+ #: classes/display-conditions.php:738
525
  msgid "RSS Feed"
526
  msgstr ""
527
 
528
+ #: classes/display-conditions.php:739
529
  msgid "allow ads in RSS Feed"
530
  msgstr ""
531
 
532
+ #: classes/display-conditions.php:774
533
  msgid "older than"
534
  msgstr ""
535
 
536
+ #: classes/display-conditions.php:775
537
  msgid "younger than"
538
  msgstr ""
539
 
540
+ #: classes/display-conditions.php:777
541
  msgid "days"
542
  msgstr ""
543
 
554
  "or %5$supdate now%6$s."
555
  msgstr ""
556
 
557
+ #: classes/EDD_SL_Plugin_Updater.php:479
558
+ msgid "You do not have permission to install plugin updates"
559
+ msgstr ""
560
+
561
+ #: classes/EDD_SL_Plugin_Updater.php:479
562
+ msgid "Error"
563
+ msgstr ""
564
+
565
  #: classes/filesystem.php:61
566
  msgid "Could not access filesystem."
567
  msgstr ""
587
  msgid "Random AdSense ads"
588
  msgstr ""
589
 
590
+ #: classes/frontend_checks.php:109 admin/includes/class-settings.php:539
591
  msgid "You look like a bot"
592
  msgstr ""
593
 
681
  msgid "Everything is fine"
682
  msgstr ""
683
 
684
+ #: classes/frontend_checks.php:444 admin/includes/class-ad-type.php:785
685
+ #: admin/views/notices/welcome-panel.php:59
686
  msgid "Get help"
687
  msgstr ""
688
 
692
  "admins"
693
  msgstr ""
694
 
695
+ #: classes/visitor-conditions.php:40
696
  msgid "device"
697
  msgstr ""
698
 
699
+ #: classes/visitor-conditions.php:41
700
  msgid "Display ads only on mobile devices or hide them."
701
  msgstr ""
702
 
703
+ #: classes/visitor-conditions.php:47
704
+ msgid "logged-in visitor"
705
  msgstr ""
706
 
707
+ #: classes/visitor-conditions.php:48
708
  msgid "Whether the visitor has to be logged in or not in order to see the ads."
709
  msgstr ""
710
 
711
+ #: classes/visitor-conditions.php:116
712
+ #, php-format
713
+ msgid ""
714
+ "Display ads by the available space on the device or target tablets with the "
715
+ "<a href=\"%s\" target=\"_blank\">Responsive add-on</a>"
716
  msgstr ""
717
 
718
+ #: classes/visitor-conditions.php:257
719
+ msgid "browser language"
720
  msgstr ""
721
 
722
+ #: classes/visitor-conditions.php:258
723
+ msgid "cookie"
724
  msgstr ""
725
 
726
+ #: classes/visitor-conditions.php:259
727
+ msgid "max. ad clicks"
 
 
 
728
  msgstr ""
729
 
730
+ #: classes/visitor-conditions.php:260
731
+ msgid "max. ad impressions"
732
  msgstr ""
733
 
734
+ #: classes/visitor-conditions.php:261
735
+ msgid "new visitor"
736
  msgstr ""
737
 
738
+ #: classes/visitor-conditions.php:262
739
+ msgid "page impressions"
740
+ msgstr ""
741
+
742
+ #: classes/visitor-conditions.php:263
743
+ msgid "referrer url"
744
+ msgstr ""
745
+
746
+ #: classes/visitor-conditions.php:264
747
+ msgid "user agent"
748
+ msgstr ""
749
+
750
+ #: classes/visitor-conditions.php:265
751
+ msgid "user can (capabilities)"
752
+ msgstr ""
753
+
754
+ #: classes/visitor-conditions.php:266
755
+ msgid "user role"
756
+ msgstr ""
757
+
758
+ #: classes/visitor-conditions.php:269
759
+ msgid "geo location"
760
+ msgstr ""
761
+
762
+ #: classes/visitor-conditions.php:272
763
+ msgid "browser width"
764
  msgstr ""
765
 
766
  #: classes/widget.php:22
777
  msgstr ""
778
 
779
  #: classes/widget.php:78 admin/includes/class-menu.php:95
780
+ #: admin/includes/class-shortcode-creator.php:98 admin/views/placements.php:36
781
  #: modules/gutenberg/includes/class-gutenberg.php:81
782
  #: modules/import-export/views/page.php:25
783
  msgid "Placements"
784
  msgstr ""
785
 
786
  #: classes/widget.php:85 admin/includes/class-shortcode-creator.php:91
787
+ #: admin/views/placement-form.php:45 admin/views/placements-item.php:4
788
  #: modules/gutenberg/includes/class-gutenberg.php:80
789
  msgid "Ad Groups"
790
  msgstr ""
793
  #: admin/includes/class-menu.php:68 admin/includes/class-menu.php:68
794
  #: admin/includes/class-shortcode-creator.php:84
795
  #: admin/views/ad-group-list-form-row.php:90
796
+ #: admin/views/ad-group-list-header.php:17 admin/views/placement-form.php:52
797
+ #: admin/views/placements-item.php:16
798
  #: modules/gutenberg/includes/class-gutenberg.php:79
799
  #: modules/import-export/views/page.php:23
800
  msgid "Ads"
954
  "<a href=\"%2$s\" target=\"_blank\">Learn more</a>."
955
  msgstr ""
956
 
957
+ #: admin/includes/ad-health-notices.php:74 admin/views/placements.php:145
958
  #, php-format
959
  msgid ""
960
  "Missing PHP extensions could cause issues. Please ask your hosting provider "
1050
 
1051
  #. %s is a service or plugin name.
1052
  #: admin/includes/ad-health-notices.php:287
1053
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:196
1054
  #, php-format
1055
  msgid "%s detected."
1056
  msgstr ""
1161
  msgid "No ad group created"
1162
  msgstr ""
1163
 
1164
+ #: admin/includes/class-ad-type.php:193 admin/includes/class-ad-type.php:199
1165
  msgid "Ad Details"
1166
  msgstr ""
1167
 
1168
+ #: admin/includes/class-ad-type.php:194 admin/includes/class-ad-type.php:200
1169
  msgid "Ad Planning"
1170
  msgstr ""
1171
 
1172
+ #: admin/includes/class-ad-type.php:195 admin/includes/class-ad-type.php:201
1173
  msgid "Ad Shortcode"
1174
  msgstr ""
1175
 
1176
+ #: admin/includes/class-ad-type.php:357
1177
  #, php-format
1178
  msgid "%s ad updated."
1179
  msgid_plural "%s ads updated."
1180
  msgstr[0] ""
1181
  msgstr[1] ""
1182
 
1183
+ #: admin/includes/class-ad-type.php:359
1184
  #, php-format
1185
  msgid "%s ad not updated, somebody is editing it."
1186
  msgid_plural "%s ads not updated, somebody is editing them."
1187
  msgstr[0] ""
1188
  msgstr[1] ""
1189
 
1190
+ #: admin/includes/class-ad-type.php:361
1191
  #, php-format
1192
  msgid "%s ad permanently deleted."
1193
  msgid_plural "%s ads permanently deleted."
1194
  msgstr[0] ""
1195
  msgstr[1] ""
1196
 
1197
+ #: admin/includes/class-ad-type.php:363
1198
  #, php-format
1199
  msgid "%s ad moved to the Trash."
1200
  msgid_plural "%s ads moved to the Trash."
1201
  msgstr[0] ""
1202
  msgstr[1] ""
1203
 
1204
+ #: admin/includes/class-ad-type.php:365
1205
  #, php-format
1206
  msgid "%s ad restored from the Trash."
1207
  msgid_plural "%s ads restored from the Trash."
1208
  msgstr[0] ""
1209
  msgstr[1] ""
1210
 
1211
+ #: admin/includes/class-ad-type.php:712 admin/includes/class-ad-type.php:713
1212
  msgid "Ad updated."
1213
  msgstr ""
1214
 
1215
  #. translators: %s: date and time of the revision
1216
+ #: admin/includes/class-ad-type.php:714
1217
  #, php-format
1218
  msgid "Ad restored to revision from %s"
1219
  msgstr ""
1220
 
1221
+ #: admin/includes/class-ad-type.php:715 admin/includes/class-ad-type.php:716
1222
  msgid "Ad saved."
1223
  msgstr ""
1224
 
1225
+ #: admin/includes/class-ad-type.php:717
1226
  msgid "Ad submitted."
1227
  msgstr ""
1228
 
1229
+ #: admin/includes/class-ad-type.php:718
1230
  #, php-format
1231
  msgid "Ad scheduled for: <strong>%1$s</strong>."
1232
  msgstr ""
1233
 
1234
  #. translators: Publish box date format, see http://php.net/date
1235
+ #: admin/includes/class-ad-type.php:720
1236
  msgid "M j, Y @ G:i"
1237
  msgstr ""
1238
 
1239
+ #: admin/includes/class-ad-type.php:721
1240
  msgid "Ad draft updated."
1241
  msgstr ""
1242
 
1243
+ #: admin/includes/class-ad-type.php:784
1244
  msgid ""
1245
  "You don’t have access to ads. Please deactivate and re-enable Advanced Ads "
1246
  "again to fix this."
1351
  msgstr ""
1352
 
1353
  #: admin/includes/class-menu.php:131 admin/includes/class-menu.php:135
1354
+ #: admin/includes/class-settings.php:277
1355
  msgid "Licenses"
1356
  msgstr ""
1357
 
1391
  msgstr ""
1392
 
1393
  #: admin/includes/class-meta-box.php:153 admin/includes/class-meta-box.php:164
1394
+ #: admin/includes/class-meta-box.php:169 admin/includes/class-settings.php:632
1395
  #: admin/views/ad-output-metabox.php:82
1396
+ #: admin/views/notices/welcome-panel.php:63
1397
  #: modules/ads-txt/admin/views/setting-create.php:11
1398
  #: modules/privacy/admin/views/setting-enable.php:2
1399
  msgid "Manual"
1438
  msgid "Latest posts on wpadvancedads.com"
1439
  msgstr ""
1440
 
1441
+ #: admin/includes/class-notices.php:466
1442
  #, php-format
1443
  msgid ""
1444
  "You don’t seem to have an email address. Please use <a href=\"%s\" "
1445
  "target=\"_blank\">this form</a> to sign up."
1446
  msgstr ""
1447
 
1448
+ #: admin/includes/class-notices.php:485
1449
  msgid ""
1450
  "How embarrassing. The email server seems to be down. Please try again later."
1451
  msgstr ""
1452
 
1453
+ #: admin/includes/class-notices.php:492
1454
  #, php-format
1455
  msgid ""
1456
  "Please check your email (%s) for the confirmation message. If you didn’t "
1467
  msgstr ""
1468
 
1469
  #: admin/includes/class-overview-widgets.php:105
1470
+ #: admin/views/notices/welcome-panel.php:15
1471
  msgid "Create your first ad"
1472
  msgstr ""
1473
 
1520
  msgstr ""
1521
 
1522
  #: admin/includes/class-overview-widgets.php:173
 
1523
  #, php-format
1524
  msgid "<a href=\"%s\" target=\"_blank\">Manual</a>"
1525
  msgstr ""
1668
  msgstr ""
1669
 
1670
  #: admin/includes/class-overview-widgets.php:658
1671
+ #: admin/views/conditions/ad-display-metabox.php:38
1672
+ #: admin/views/conditions/ad-visitor-metabox.php:38
1673
  msgid "Visit the manual"
1674
  msgstr ""
1675
 
1702
  msgstr ""
1703
 
1704
  #: admin/includes/class-settings.php:168
1705
+ msgid "Use new injection logic"
1706
+ msgstr ""
1707
+
1708
+ #: admin/includes/class-settings.php:176
1709
  msgid "Hide ads from bots"
1710
  msgstr ""
1711
 
1712
+ #: admin/includes/class-settings.php:185
1713
  msgid "Disable ads for post types"
1714
  msgstr ""
1715
 
1716
+ #: admin/includes/class-settings.php:194
1717
  msgid "Disable Ad Health and other notices"
1718
  msgstr ""
1719
 
1720
+ #: admin/includes/class-settings.php:202
1721
  msgid "ID prefix"
1722
  msgstr ""
1723
 
1724
+ #: admin/includes/class-settings.php:210
1725
  msgid "Allow editors to manage ads"
1726
  msgstr ""
1727
 
1728
+ #: admin/includes/class-settings.php:218
1729
  msgid "Ad label"
1730
  msgstr ""
1731
 
1732
+ #: admin/includes/class-settings.php:227
1733
  msgid "Open links in a new window"
1734
  msgstr ""
1735
 
1736
+ #: admin/includes/class-settings.php:235
1737
  msgid "Use advanced JavaScript"
1738
  msgstr ""
1739
 
1740
+ #: admin/includes/class-settings.php:245
1741
  msgid "Delete data on uninstall"
1742
  msgstr ""
1743
 
1744
+ #: admin/includes/class-settings.php:255
1745
  msgid "Disable shortcode button"
1746
  msgstr ""
1747
 
1748
+ #: admin/includes/class-settings.php:294
1749
  msgid "Pro"
1750
  msgstr ""
1751
 
1752
+ #: admin/includes/class-settings.php:310 admin/views/pitch-tracking.php:2
1753
  msgid "Tracking"
1754
  msgstr ""
1755
 
1756
+ #: admin/includes/class-settings.php:358
1757
  #, php-format
1758
  msgid ""
1759
  "Enter license keys for our powerful <a href=\"%s\" target=\"_blank\">add-"
1760
  "ons</a>."
1761
  msgstr ""
1762
 
1763
+ #: admin/includes/class-settings.php:359
1764
  #, php-format
1765
  msgid ""
1766
  "See also <a href=\"%s\" target=\"_blank\">Issues and questions about "
1767
  "licenses</a>."
1768
  msgstr ""
1769
 
1770
+ #: admin/includes/class-settings.php:371
1771
  msgid "Are you missing something?"
1772
  msgstr ""
1773
 
1774
+ #: admin/includes/class-settings.php:439
1775
  msgid "Choose the roles a user must have in order to not see any ads."
1776
  msgstr ""
1777
 
1778
+ #: admin/includes/class-settings.php:453
1779
  msgid ""
1780
  "<strong>notice: </strong>the file is currently enabled by an add-on that "
1781
  "needs it."
1782
  msgstr ""
1783
 
1784
+ #: admin/includes/class-settings.php:456
1785
  #, php-format
1786
  msgid ""
1787
  "Enable advanced JavaScript functions (<a href=\"%s\" target=\"_blank\">"
1789
  "need features from this file."
1790
  msgstr ""
1791
 
1792
+ #: admin/includes/class-settings.php:476
1793
  msgid ""
1794
  "Some plugins and themes trigger ad injections where it shouldn’t happen. "
1795
  "Therefore, Advanced Ads ignores injected placements on non-singular pages "
1799
  "injection only in the first x posts on your archive pages."
1800
  msgstr ""
1801
 
1802
+ #: admin/includes/class-settings.php:492
1803
  msgid ""
1804
  "Please check your post content. A priority of 10 and below might cause "
1805
  "issues (wpautop function might run twice)."
1806
  msgstr ""
1807
 
1808
+ #: admin/includes/class-settings.php:494
1809
  msgid ""
1810
  "Play with this value in order to change the priority of the injected ads "
1811
  "compared to other auto injected elements in the post content."
1812
  msgstr ""
1813
 
1814
+ #: admin/includes/class-settings.php:508
1815
  msgid ""
1816
  "Advanced Ads ignores paragraphs and other elements in containers when "
1817
  "injecting ads into the post content. Check this option to ignore this "
1818
  "limitation and ads might show up again."
1819
  msgstr ""
1820
 
1821
+ #. %1$s is a starting <a> tag and %2$s a closing one.
1822
+ #: admin/includes/class-settings.php:523
1823
+ #, php-format
1824
+ msgid ""
1825
+ "Enable the new more stable injection logic. Please report any issues "
1826
+ "%1$shere%2$s."
1827
+ msgstr ""
1828
+
1829
+ #: admin/includes/class-settings.php:541
1830
  msgid "Read this first"
1831
  msgstr ""
1832
 
1833
+ #: admin/includes/class-settings.php:542
1834
  msgid "Hide ads from crawlers, bots and empty user agents."
1835
  msgstr ""
1836
 
1837
+ #: admin/includes/class-settings.php:555
1838
  msgid "Pro feature"
1839
  msgstr ""
1840
 
1841
  #. %1$s is a starting <a> tag and %2$s a closing one
1842
+ #: admin/includes/class-settings.php:573
1843
  #, php-format
1844
  msgid ""
1845
  "Disable %1$sAd Health%2$s in frontend and backend, warnings and internal "
1846
  "notices like tips, tutorials, email newsletters and update notices."
1847
  msgstr ""
1848
 
1849
+ #: admin/includes/class-settings.php:591
1850
  msgid ""
1851
  "Prefix of class or id attributes in the frontend. Change it if you don’t "
1852
  "want <strong>ad blockers</strong> to mark these blocks as ads.<br/>You might "
1853
  "need to <strong>rewrite css rules afterwards</strong>."
1854
  msgstr ""
1855
 
1856
+ #: admin/includes/class-settings.php:610
1857
  msgid "Allow editors to also manage and publish ads."
1858
  msgstr ""
1859
 
1860
+ #: admin/includes/class-settings.php:611
1861
  #, php-format
1862
  msgid ""
1863
  "You can assign different ad-related roles on a user basis with <a "
1864
  "href=\"%s\" target=\"_blank\">Advanced Ads Pro</a>."
1865
  msgstr ""
1866
 
1867
+ #: admin/includes/class-settings.php:622
1868
  msgctxt "label before ads"
1869
  msgid "Advertisements"
1870
  msgstr ""
1871
 
1872
+ #: admin/includes/class-settings.php:631
1873
  msgid "Displayed above ads."
1874
  msgstr ""
1875
 
1876
+ #: admin/includes/class-settings.php:667
1877
  msgid "Clean up all data related to Advanced Ads when removing the plugin."
1878
  msgstr ""
1879
 
1880
+ #: admin/includes/class-settings.php:680
1881
  msgid "Disable shortcode button in visual editor."
1882
  msgstr ""
1883
 
1942
  msgid "Yes, but help me first to solve a problem, please"
1943
  msgstr ""
1944
 
1945
+ #. %s is a link. `30%%` is correct, please use exactly that value so that it shows "30%".
1946
+ #: admin/includes/notices.php:60
1947
+ #, php-format
1948
+ msgid ""
1949
+ "Our Black Friday / Cyber Monday Offer: <span style=\"font-weight: bold; font-"
1950
+ "size: 1.4em; color: green;\">-30%%</span> on all add-ons and All Access.<a "
1951
+ "class=\"button button-primary\" target=\"_blank\" href=\"%s\">Get All "
1952
+ "Access</a>"
1953
+ msgstr ""
1954
+
1955
  #: admin/includes/shortcode-creator-l10n.php:10
1956
  msgctxt "shortcode creator"
1957
  msgid "Add an ad"
2008
  msgid "does not match regex"
2009
  msgstr ""
2010
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2011
  #: admin/views/ad-group-edit.php:18
2012
  msgid "You did not select an item for editing."
2013
  msgstr ""
2044
  msgid "weight"
2045
  msgstr ""
2046
 
2047
+ #: admin/views/ad-group-list-ads.php:37
2048
+ #: admin/views/conditions/conditions-form.php:35
2049
+ msgid "add"
2050
+ msgstr ""
2051
+
2052
+ #: admin/views/ad-group-list-form-row.php:29 admin/views/placements.php:42
2053
  #: modules/gadsense/admin/views/external-ads-list.php:30
2054
  #: modules/gadsense/admin/views/external-ads-list.php:43
2055
  #: modules/privacy/admin/views/setting-consent-method.php:9
2056
  msgid "Name"
2057
  msgstr ""
2058
 
2059
+ #: admin/views/ad-group-list-form-row.php:55 admin/views/placements.php:41
2060
  #: modules/gadsense/admin/views/adsense-ad-parameters.php:110
2061
  msgid "Type"
2062
  msgstr ""
2079
  msgstr ""
2080
 
2081
  #: admin/views/ad-group-list-row.php:19 admin/views/ad-info.php:3
2082
+ #: admin/views/placements.php:102
2083
  msgid "shortcode"
2084
  msgstr ""
2085
 
2250
  #: admin/views/placements-ad-label-position.php:2
2251
  #: admin/views/placements-ad-label-position.php:5
2252
  #: admin/views/placements-ad-label.php:1 admin/views/placements-ad-label.php:4
2253
+ #: admin/views/placements.php:84
2254
  #: modules/gadsense/includes/class-network-adsense.php:236
2255
  msgid "default"
2256
  msgstr ""
2378
  msgid "%1$s %2$s, %3$s @ %4$s %5$s"
2379
  msgstr ""
2380
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2381
  #: admin/views/checks.php:14
2382
  #, php-format
2383
  msgid ""
2510
  msgid "spread impressions or clicks equally over a given period"
2511
  msgstr ""
2512
 
2513
+ #: admin/views/placement-form.php:8
2514
+ msgid "Choose a placement type"
2515
+ msgstr ""
2516
+
2517
+ #: admin/views/placement-form.php:9
2518
+ #, php-format
2519
+ msgid ""
2520
+ "Placement types define where the ad is going to be displayed. Learn more "
2521
+ "about the different types from the <a href=\"%s\">manual</a>"
2522
+ msgstr ""
2523
+
2524
+ #: admin/views/placement-form.php:33
2525
+ msgid "Please select a placement type."
2526
+ msgstr ""
2527
+
2528
+ #: admin/views/placement-form.php:35
2529
+ msgid "Choose a Name"
2530
+ msgstr ""
2531
+
2532
+ #: admin/views/placement-form.php:36
2533
+ msgid ""
2534
+ "The name of the placement is only visible to you. Tip: choose a descriptive "
2535
+ "one, e.g. <em>Below Post Headline</em>."
2536
+ msgstr ""
2537
+
2538
+ #: admin/views/placement-form.php:38
2539
+ msgid "Placement Name"
2540
+ msgstr ""
2541
+
2542
+ #: admin/views/placement-form.php:39
2543
+ msgid "Please enter a name for your placement."
2544
+ msgstr ""
2545
+
2546
+ #: admin/views/placement-form.php:40
2547
+ msgid "Choose the Ad or Group"
2548
+ msgstr ""
2549
+
2550
+ #: admin/views/placement-form.php:41
2551
+ msgid "The ad or group that should be displayed."
2552
+ msgstr ""
2553
+
2554
+ #: admin/views/placement-form.php:43 admin/views/placements-item.php:2
2555
+ msgid "--not selected--"
2556
+ msgstr ""
2557
+
2558
+ #: admin/views/placement-form.php:60
2559
+ msgid "Save New Placement"
2560
+ msgstr ""
2561
+
2562
  #: admin/views/placement-injection-top.php:10
2563
  msgid "Congratulations! Your ad is now visible in the frontend."
2564
  msgstr ""
2696
  msgid "start counting from bottom"
2697
  msgstr ""
2698
 
 
 
 
 
2699
  #: admin/views/placements.php:10
2700
  msgid ""
2701
  "Couldn’t create the new placement. Please check your form field and whether "
2706
  msgid "Placements updated"
2707
  msgstr ""
2708
 
2709
+ #: admin/views/placements.php:20 admin/views/placements.php:214
2710
+ msgid "Create a new placement"
2711
+ msgstr ""
2712
+
2713
+ #: admin/views/placements.php:21 admin/views/placements.php:216
2714
+ msgid "New Placement"
2715
+ msgstr ""
2716
+
2717
+ #: admin/views/placements.php:26
2718
  msgid ""
2719
  "Placements are physically places in your theme and posts. You can use them "
2720
  "if you plan to change ads and ad groups on the same place without the need "
2721
  "to change your templates."
2722
  msgstr ""
2723
 
2724
+ #: admin/views/placements.php:27
2725
  #, php-format
2726
  msgid ""
2727
  "See also the manual for more information on <a href=\"%s\">placements</a>."
2728
  msgstr ""
2729
 
2730
+ #: admin/views/placements.php:43 modules/import-export/views/page.php:26
2731
  msgid "Options"
2732
  msgstr ""
2733
 
2734
+ #: admin/views/placements.php:65
2735
  #, php-format
2736
  msgid ""
2737
  "Placement type \"%s\" is missing and was reset to \"default\".<br/>Please "
2738
  "check if the responsible add-on is activated."
2739
  msgstr ""
2740
 
2741
+ #: admin/views/placements.php:93
2742
  msgid "show usage"
2743
  msgstr ""
2744
 
2745
+ #: admin/views/placements.php:105
2746
  msgid "template (PHP)"
2747
  msgstr ""
2748
 
2749
+ #: admin/views/placements.php:120
2750
  msgid "Item"
2751
  msgstr ""
2752
 
2753
+ #: admin/views/placements.php:134
2754
  msgid "position"
2755
  msgstr ""
2756
 
2757
+ #: admin/views/placements.php:140 admin/views/placements.php:145
2758
  msgid "Important Notice"
2759
  msgstr ""
2760
 
2761
+ #: admin/views/placements.php:140
2762
  msgid ""
2763
  "Your server is missing an extension. This might break the content injection."
2764
  "<br/>Ignore this warning if everything works fine or else ask your hosting "
2765
  "provider to enable <em>mbstring</em>."
2766
  msgstr ""
2767
 
2768
+ #: admin/views/placements.php:167
2769
  msgid "ad label"
2770
  msgstr ""
2771
 
2772
+ #: admin/views/placements.php:177
2773
  msgid "show all options"
2774
  msgstr ""
2775
 
2776
+ #: admin/views/placements.php:196
2777
  #, php-format
2778
  msgid ""
2779
  "Tutorial: <a href=\"%s\" target=\"_blank\">How to place visible ads in the "
2780
  "header of your website</a>."
2781
  msgstr ""
2782
 
2783
+ #: admin/views/placements.php:205
2784
  msgctxt "checkbox to remove placement"
2785
  msgid "delete"
2786
  msgstr ""
2787
 
2788
+ #: admin/views/placements.php:212
2789
  msgid "Save Placements"
2790
  msgstr ""
2791
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2792
  #: admin/views/post-ad-settings-metabox.php:1
2793
  msgid "How to disable ads on specific pages"
2794
  msgstr ""
2969
  msgid "Find solutions in the manual"
2970
  msgstr ""
2971
 
2972
+ #: admin/views/conditions/ad-display-metabox.php:17
2973
+ msgid ""
2974
+ "Click on the button below if the ad should NOT show up on all pages when "
2975
+ "included automatically."
2976
+ msgstr ""
2977
+
2978
+ #: admin/views/conditions/ad-display-metabox.php:19
2979
+ msgid "Hide the ad on some pages"
2980
+ msgstr ""
2981
+
2982
+ #: admin/views/conditions/ad-display-metabox.php:34
2983
+ msgid "Watch video"
2984
+ msgstr ""
2985
+
2986
+ #: admin/views/conditions/ad-display-metabox.php:46
2987
+ #: admin/views/notices/jqueryui_error.php:2
2988
+ #, php-format
2989
+ msgid ""
2990
+ "There might be a problem with layouts and scripts in your dashboard. Please "
2991
+ "check <a href=\"%s\" target=\"_blank\">this article to learn more</a>."
2992
+ msgstr ""
2993
+
2994
+ #: admin/views/conditions/ad-display-metabox.php:47
2995
+ msgid "A page with this ad on it must match all of the following conditions."
2996
+ msgstr ""
2997
+
2998
+ #: admin/views/conditions/ad-visitor-metabox.php:17
2999
+ msgid ""
3000
+ "Click on the button below if the ad should NOT be visible to all visitors"
3001
+ msgstr ""
3002
+
3003
+ #: admin/views/conditions/ad-visitor-metabox.php:19
3004
+ msgid "Hide the ad from some users"
3005
+ msgstr ""
3006
+
3007
+ #: admin/views/conditions/ad-visitor-metabox.php:29
3008
+ msgid ""
3009
+ "Display conditions that are based on the user. Use with caution on cached "
3010
+ "websites."
3011
+ msgstr ""
3012
+
3013
+ #: admin/views/conditions/condition-author.php:27
3014
+ #, php-format
3015
+ msgid ""
3016
+ "Only %d elements are displayed above. Use the <code>advanced-ads-admin-max-"
3017
+ "terms</code> filter to change this limit according to <a href=\"%s\" "
3018
+ "target=\"_blank\">this page</a>."
3019
+ msgstr ""
3020
+
3021
+ #: admin/views/conditions/condition-device.php:3
3022
+ msgid "Mobile (including tablets)"
3023
+ msgstr ""
3024
+
3025
+ #: admin/views/conditions/condition-device.php:4
3026
+ msgid "Desktop"
3027
+ msgstr ""
3028
+
3029
+ #: admin/views/conditions/condition-device.php:9
3030
+ #: admin/views/conditions/condition-is-or-not.php:9
3031
+ msgid "Manual and Troubleshooting"
3032
+ msgstr ""
3033
+
3034
+ #: admin/views/conditions/condition-is-or-not.php:3
3035
+ #: admin/views/conditions/condition-operator.php:2
3036
+ msgid "is"
3037
+ msgstr ""
3038
+
3039
+ #: admin/views/conditions/condition-is-or-not.php:4
3040
+ #: admin/views/conditions/condition-operator.php:3
3041
+ msgid "is not"
3042
+ msgstr ""
3043
+
3044
+ #: admin/views/conditions/condition-number.php:3
3045
+ msgid "equal"
3046
+ msgstr ""
3047
+
3048
+ #: admin/views/conditions/condition-number.php:4
3049
+ msgid "equal or higher"
3050
+ msgstr ""
3051
+
3052
+ #: admin/views/conditions/condition-number.php:5
3053
+ msgid "equal or lower"
3054
+ msgstr ""
3055
+
3056
+ #: admin/views/conditions/conditions-form.php:8
3057
+ msgid "New condition"
3058
+ msgstr ""
3059
+
3060
+ #: admin/views/conditions/conditions-form.php:13
3061
+ msgid "-- choose a condition --"
3062
+ msgstr ""
3063
+
3064
+ #: admin/views/conditions/conditions-form.php:22
3065
+ msgid "Add-On features"
3066
+ msgstr ""
3067
+
3068
+ #: admin/views/conditions/display-conditions-form-top.php:4
3069
+ msgid "If you want to display the ad everywhere, don't do anything here. "
3070
+ msgstr ""
3071
+
3072
+ #: admin/views/conditions/display-conditions-list.php:45
3073
+ msgid "Forced to OR."
3074
+ msgstr ""
3075
+
3076
+ #: admin/views/conditions/display-conditions-list.php:46
3077
+ #: modules/gadsense/admin/views/adsense-ad-parameters.php:121
3078
+ msgid "manual"
3079
+ msgstr ""
3080
+
3081
+ #: admin/views/conditions/visitor-conditions-form-top.php:4
3082
+ msgid ""
3083
+ "Visitor conditions limit the number of users who can see your ad. There is "
3084
+ "no need to set visitor conditions if you want all users to see the ad."
3085
+ msgstr ""
3086
+
3087
+ #: admin/views/conditions/visitor-conditions-form-top.php:9
3088
+ #: modules/privacy/admin/views/setting-enable.php:4
3089
+ msgid "It seems that a caching plugin is activated."
3090
+ msgstr ""
3091
+
3092
+ #: admin/views/conditions/visitor-conditions-form-top.php:11
3093
+ #, php-format
3094
+ msgid ""
3095
+ "Check out cache-busting in <a href=\"%s\" target=\"_blank\">Advanced Ads "
3096
+ "Pro</a> if dynamic features get cached."
3097
+ msgstr ""
3098
+
3099
  #: admin/views/notices/adblock.php:4
3100
  msgid ""
3101
  "Please disable your <strong>AdBlocker</strong> to prevent problems with your "
3102
  "ad setup."
3103
  msgstr ""
3104
 
3105
+ #: admin/views/notices/starter-setup-success.php:2
3106
+ msgid "2 Test Ads successfully added!"
3107
+ msgstr ""
3108
+
3109
+ #: admin/views/notices/starter-setup-success.php:3
3110
+ msgid "Look below for the list of created ads."
3111
+ msgstr ""
3112
+
3113
+ #: admin/views/notices/starter-setup-success.php:5
3114
+ msgid "Visit list of placements"
3115
+ msgstr ""
3116
+
3117
+ #: admin/views/notices/starter-setup-success.php:9
3118
+ msgid "See them in action"
3119
+ msgstr ""
3120
+
3121
+ #: admin/views/notices/welcome-panel.php:10
3122
  msgid "Welcome to Advanced Ads!"
3123
  msgstr ""
3124
 
3125
+ #: admin/views/notices/welcome-panel.php:13
3126
  msgid "Get Started"
3127
  msgstr ""
3128
 
3129
+ #: admin/views/notices/welcome-panel.php:19
3130
  msgid "First ad tutorial"
3131
  msgstr ""
3132
 
3133
+ #: admin/views/notices/welcome-panel.php:30
3134
+ msgid "One-Click Setup"
3135
+ msgstr ""
3136
+
3137
+ #: admin/views/notices/welcome-panel.php:37
3138
+ msgid "Create 2 test ads"
3139
+ msgstr ""
3140
+
3141
+ #: admin/views/notices/welcome-panel.php:38
3142
+ msgid ""
3143
+ "Click to place two ads in the content of your site which are visible to you "
3144
+ "only."
3145
+ msgstr ""
3146
+
3147
+ #: admin/views/notices/welcome-panel.php:42
3148
  msgid "AdSense Options"
3149
  msgstr ""
3150
 
3151
+ #: admin/views/notices/welcome-panel.php:44
3152
  msgid "Import ads from AdSense"
3153
  msgstr ""
3154
 
3155
+ #: admin/views/notices/welcome-panel.php:48
3156
  msgid "Setting up Auto ads"
3157
  msgstr ""
3158
 
3159
+ #: admin/views/notices/welcome-panel.php:51
3160
  msgid "Setting up AdSense ads manually"
3161
  msgstr ""
3162
 
3163
+ #: admin/views/notices/welcome-panel.php:67
3164
  msgid "Reach out for help"
3165
  msgstr ""
3166
 
3169
  msgstr ""
3170
 
3171
  #: modules/ad-blocker/admin/admin.php:150
3172
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:372
3173
  msgid "Unable to connect to the filesystem. Please confirm your credentials."
3174
  msgstr ""
3175
 
3212
  msgid "Ad blocker counter"
3213
  msgstr ""
3214
 
3215
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:176
3216
  #, php-format
3217
  msgid ""
3218
  "The ads.txt file cannot be placed because the URL contains a subdirectory. "
3219
  "You need to make the file available at %s"
3220
  msgstr ""
3221
 
3222
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:187
3223
  #, php-format
3224
  msgid "The file is available on %s."
3225
  msgstr ""
3226
 
3227
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:191
3228
  msgid "The file was not created."
3229
  msgstr ""
3230
 
3231
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:197
3232
  msgid "Find the solution here"
3233
  msgstr ""
3234
 
3235
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:208
3236
+ msgid "Import & Replace"
3237
+ msgstr ""
3238
+
3239
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:210
3240
+ msgid ""
3241
+ "Move the content of the existing ads.txt file into Advanced Ads and remove "
3242
+ "it."
3243
+ msgstr ""
3244
+
3245
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:217
3246
  #: modules/ads-txt/admin/views/setting-additional-content.php:4
3247
  #, php-format
3248
  msgid "An error occured: %s."
3249
  msgstr ""
3250
 
3251
  #. %s the line that may need to be added manually
3252
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:230
3253
  #, php-format
3254
  msgid ""
3255
  "If your site is located on a subdomain, you need to add the following line "
3256
  "to the ads.txt file of the root domain: %s"
3257
  msgstr ""
3258
 
3259
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:345
3260
+ msgid "The ads.txt is now managed with Advanced Ads."
3261
+ msgstr ""
3262
+
3263
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:390
3264
+ msgid "Not the main blog"
3265
+ msgstr ""
3266
+
3267
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:419
3268
+ msgid "Could not delete the existing ads.txt file"
3269
+ msgstr ""
3270
+
3271
+ #: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:422
3272
+ msgid "Could not find the existing ads.txt file"
3273
+ msgstr ""
3274
+
3275
  #: modules/gadsense/admin/admin.php:121
3276
  #, php-format
3277
  msgid ""
modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php CHANGED
@@ -15,8 +15,9 @@ class Advanced_Ads_Ads_Txt_Admin {
15
  *
16
  * @param obj $strategy Advanced_Ads_Ads_Txt_Strategy.
17
  */
18
- public function __construct( $strategy ) {
19
  $this->strategy = $strategy;
 
20
 
21
  add_filter( 'advanced-ads-sanitize-settings', array( $this, 'toggle' ), 10, 1 );
22
  add_action( 'pre_update_option_advanced-ads-adsense', array( $this, 'update_adsense_option' ), 10, 2 );
@@ -138,6 +139,7 @@ class Advanced_Ads_Ads_Txt_Admin {
138
  public function render_setting_additional_content() {
139
  $content = $this->strategy->get_additional_content();
140
  $notices = $this->get_notices();
 
141
  include dirname( __FILE__ ) . '/views/setting-additional-content.php';
142
  }
143
 
@@ -167,6 +169,7 @@ class Advanced_Ads_Ads_Txt_Admin {
167
 
168
  $notices = array();
169
  $link = sprintf( '<a href="%1$s" target="_blank">%1$s</a>', esc_url( $url . 'ads.txt' ) );
 
170
 
171
  if ( Advanced_Ads_Ads_Txt_Utils::is_subdir() ) {
172
  $notices[] = array( 'advads-error-message', sprintf(
@@ -199,10 +202,15 @@ class Advanced_Ads_Ads_Txt_Admin {
199
  }
200
 
201
  if ( $file['is_third_party'] ) {
202
- $notices[] = array( 'advads-error-message', sprintf(
203
- esc_html__( 'A third-party file exists: %s' ),
204
- $link
205
- ) );
 
 
 
 
 
206
  }
207
  } else {
208
  $notices[] = array( 'advads-error-message', sprintf(
@@ -226,12 +234,24 @@ class Advanced_Ads_Ads_Txt_Admin {
226
  }
227
  }
228
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  $r = '<ul id="advads-ads-txt-notices">';
230
  foreach( $notices as $notice ) {
231
  $r .= sprintf( '<li class="%s">%s</li>', $notice[0], $notice[1] );
232
  }
233
  $r .= '</ul>';
234
-
235
  return $r;
236
  }
237
 
@@ -314,10 +334,104 @@ class Advanced_Ads_Ads_Txt_Admin {
314
  return;
315
  }
316
 
317
- echo $this->get_notices();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  exit;
319
  }
320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  /**
322
  * Get transient key.
323
  */
15
  *
16
  * @param obj $strategy Advanced_Ads_Ads_Txt_Strategy.
17
  */
18
+ public function __construct( Advanced_Ads_Ads_Txt_Strategy $strategy, Advanced_Ads_Ads_Txt_Public $public ) {
19
  $this->strategy = $strategy;
20
+ $this->public = $public;
21
 
22
  add_filter( 'advanced-ads-sanitize-settings', array( $this, 'toggle' ), 10, 1 );
23
  add_action( 'pre_update_option_advanced-ads-adsense', array( $this, 'update_adsense_option' ), 10, 2 );
139
  public function render_setting_additional_content() {
140
  $content = $this->strategy->get_additional_content();
141
  $notices = $this->get_notices();
142
+ $notices = $this->get_notices_markup( $notices );
143
  include dirname( __FILE__ ) . '/views/setting-additional-content.php';
144
  }
145
 
169
 
170
  $notices = array();
171
  $link = sprintf( '<a href="%1$s" target="_blank">%1$s</a>', esc_url( $url . 'ads.txt' ) );
172
+ $button = ' <button type="button" class="advads-ads-txt-action button" style="vertical-align: middle;" id="%s">%s</button>';
173
 
174
  if ( Advanced_Ads_Ads_Txt_Utils::is_subdir() ) {
175
  $notices[] = array( 'advads-error-message', sprintf(
202
  }
203
 
204
  if ( $file['is_third_party'] ) {
205
+ $message = sprintf( esc_html__( 'A third-party file exists: %s' ), $link);
206
+
207
+ if ( $this->can_edit_real_file() ) {
208
+ $message .= sprintf( $button, 'advads-ads-txt-remove-real', __( 'Import & Replace', 'advanced-ads' ) );
209
+ $message .= '<p class="description">'
210
+ . __( 'Move the content of the existing ads.txt file into Advanced Ads and remove it.', 'advanced-ads' )
211
+ . '</p>';
212
+ }
213
+ $notices['is_third_party'] = array( 'advads-error-message', $message );
214
  }
215
  } else {
216
  $notices[] = array( 'advads-error-message', sprintf(
234
  }
235
  }
236
 
237
+ return $notices;
238
+ }
239
+
240
+ /**
241
+ * Get HTML markup of the notices.
242
+ *
243
+ * @param array $notices Notices.
244
+ * @return string $r HTML markup.
245
+ */
246
+ private function get_notices_markup( $notices ) {
247
+ if ( ! $notices ) {
248
+ return;
249
+ }
250
  $r = '<ul id="advads-ads-txt-notices">';
251
  foreach( $notices as $notice ) {
252
  $r .= sprintf( '<li class="%s">%s</li>', $notice[0], $notice[1] );
253
  }
254
  $r .= '</ul>';
 
255
  return $r;
256
  }
257
 
334
  return;
335
  }
336
 
337
+ $response = array();
338
+ $action_notices = array();
339
+ if ( isset( $_REQUEST['type'] ) ) {
340
+ if ( 'remove_real_file' === $_REQUEST['type'] ) {
341
+ $remove = $this->remove_real_file();
342
+ if ( is_wp_error( $remove ) ) {
343
+ $action_notices[] = array( 'advads-ads-txt-updated advads-error-message', $remove->get_error_message() );
344
+ } else {
345
+ $action_notices[] = array( 'advads-ads-txt-updated', __( 'The ads.txt is now managed with Advanced Ads.', 'advanced-ads' ) );
346
+ $options = $this->strategy->get_options();
347
+ $response['additional_content'] = esc_textarea( $options['custom'] );
348
+ }
349
+ }
350
+ if ( 'create_real_file' === $_REQUEST['type'] ) {
351
+ $action_notices[] = $this->create_real_file();
352
+ }
353
+ }
354
+
355
+
356
+ $notices = $this->get_notices();
357
+ $notices = array_merge( $notices, $action_notices );
358
+ $response['notices'] = $this->get_notices_markup( $notices );
359
+
360
+ echo wp_send_json( $response );
361
  exit;
362
  }
363
 
364
+ /**
365
+ * Connect to the filesystem.
366
+ */
367
+ private function fs_connect() {
368
+ global $wp_filesystem;
369
+ $fs_connect = Advanced_Ads_Filesystem::get_instance()->fs_connect( array( ABSPATH ) );
370
+
371
+ if ( false === $fs_connect || is_wp_error( $fs_connect ) ) {
372
+ $message = __( 'Unable to connect to the filesystem. Please confirm your credentials.', 'advanced-ads' );
373
+
374
+ if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
375
+ $message = esc_html( $wp_filesystem->errors->get_error_message() );
376
+ }
377
+ if ( is_wp_error( $fs_connect ) && $fs_connect->get_error_code() ) {
378
+ $message = esc_html( $fs_connect->get_error_message() );
379
+ }
380
+ return new WP_Error( 'can_not_connect', $message );
381
+ }
382
+ return true;
383
+ }
384
+
385
+ /**
386
+ * Remove existing real ads.txt file.
387
+ */
388
+ function remove_real_file() {
389
+ if ( ! $this->can_edit_real_file() ) {
390
+ new WP_Error( 'not_main_site', __( 'Not the main blog', 'advanced-ads' ) );
391
+ }
392
+
393
+ if ( is_wp_error( $this->fs_connect() ) ) {
394
+ return $fs_connect;
395
+ }
396
+
397
+ global $wp_filesystem;
398
+ $abspath = trailingslashit( $wp_filesystem->abspath() );
399
+ $file = $abspath . 'ads.txt';
400
+ if ( $wp_filesystem->exists( $file ) && $wp_filesystem->is_file( $file ) ) {
401
+ $data = $wp_filesystem->get_contents( $file );
402
+
403
+ $tp_file = new Advanced_Ads_Ads_Txt_Real_File();
404
+ $tp_file->parse_file( $data );
405
+
406
+ $aa_data = $this->public->get_frontend_output();
407
+ $aa_file = new Advanced_Ads_Ads_Txt_Real_File();
408
+ $aa_file->parse_file( $aa_data );
409
+
410
+ $tp_file->subtract( $aa_file );
411
+ $output = $tp_file->output();
412
+ $this->strategy->set_additional_content( $output );
413
+ $this->strategy->save_options();
414
+
415
+
416
+ if ( $wp_filesystem->delete( $file ) ) {
417
+ return true;
418
+ } else {
419
+ return new WP_Error( 'could_not_delete', __( 'Could not delete the existing ads.txt file', 'advanced-ads' ) );
420
+ }
421
+ } else {
422
+ return new WP_Error( 'not_found', __( 'Could not find the existing ads.txt file', 'advanced-ads' ) );
423
+ }
424
+ }
425
+
426
+
427
+ /**
428
+ * Check if the user is alowed to edit real file.
429
+ */
430
+ private function can_edit_real_file() {
431
+ return is_super_admin();
432
+ }
433
+
434
+
435
  /**
436
  * Get transient key.
437
  */
modules/ads-txt/admin/views/setting-additional-content.php CHANGED
@@ -1,5 +1,5 @@
1
- <textarea cols="50" rows="5" name="advads-ads-txt-additional-content"><?php echo esc_textarea( $content ); ?></textarea>
2
  <p class="description"><?php esc_html_e( 'Additional records to add to the file, one record per line. AdSense is added automatically.', 'advanced-ads' ); ?></p>
3
  <div id="advads-ads-txt-notice-wrapper"><?php echo $notices; ?></div>
4
  <p class="advads-error-message hidden" id="advads-ads-txt-notice-error"><?php esc_html_e( 'An error occured: %s.', 'advanced-ads' ); ?></p>
5
- <button class="button" type="button" id="advads-ads-txt-notice-refresh"><?php esc_html_e( 'Check for problems', 'advanced-ads' ); ?></button>
1
+ <textarea cols="50" rows="5" id="advads-ads-txt-additional-content" name="advads-ads-txt-additional-content"><?php echo esc_textarea( $content ); ?></textarea>
2
  <p class="description"><?php esc_html_e( 'Additional records to add to the file, one record per line. AdSense is added automatically.', 'advanced-ads' ); ?></p>
3
  <div id="advads-ads-txt-notice-wrapper"><?php echo $notices; ?></div>
4
  <p class="advads-error-message hidden" id="advads-ads-txt-notice-error"><?php esc_html_e( 'An error occured: %s.', 'advanced-ads' ); ?></p>
5
+ <button class="button advads-ads-txt-action" type="button" id="advads-ads-txt-notice-refresh"><?php esc_html_e( 'Check for problems', 'advanced-ads' ); ?></button>
modules/ads-txt/config.php CHANGED
@@ -11,6 +11,7 @@ return array(
11
  'Advanced_Ads_Ads_Txt_Strategy' => $path . '/includes/class-advanced-ads-ads-txt-strategy.php',
12
  'Advanced_Ads_Ads_Txt_Admin' => $path . '/admin/class-advanced-ads-ads-txt-admin.php',
13
  'Advanced_Ads_Ads_Txt_Utils' => $path . '/includes/class-advanced-ads-ads-txt-utils.php',
 
14
  ),
15
  'textdomain' => null,
16
  );
11
  'Advanced_Ads_Ads_Txt_Strategy' => $path . '/includes/class-advanced-ads-ads-txt-strategy.php',
12
  'Advanced_Ads_Ads_Txt_Admin' => $path . '/admin/class-advanced-ads-ads-txt-admin.php',
13
  'Advanced_Ads_Ads_Txt_Utils' => $path . '/includes/class-advanced-ads-ads-txt-utils.php',
14
+ 'Advanced_Ads_Ads_Txt_Real_File'=> $path . '/includes/class-advanced-ads-ads-txt-real-file.php',
15
  ),
16
  'textdomain' => null,
17
  );
modules/ads-txt/includes/class-advanced-ads-ads-txt-real-file.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Represents a real ads.txt file.
4
+ */
5
+ class Advanced_Ads_Ads_Txt_Real_File {
6
+ private $records = array();
7
+
8
+ /**
9
+ * Parse a real file.
10
+ *
11
+ * @param string $file File data.
12
+ */
13
+ public function parse_file( $file ) {
14
+ $lines = preg_split( '/\r\n|\r|\n/', $file );
15
+ $comments = array();
16
+
17
+ foreach ( $lines as $line ) {
18
+ $line = explode( '#', $line );
19
+
20
+ if ( ! empty( $line[1] ) && $comment = trim( $line[1] ) ) {
21
+ $comments[] = '# ' . $comment;
22
+ }
23
+
24
+ if ( ! trim( $line[0] ) ) {
25
+ continue;
26
+ }
27
+
28
+ $rec = explode( ',', $line[0] );
29
+ $data = array();
30
+
31
+ foreach ( $rec as $k => $r ) {
32
+ $r = trim( $r, " \n\r\t," );
33
+ if ( $r ) {
34
+ $data[] = $r;
35
+ }
36
+ }
37
+
38
+ if ( $data ) {
39
+ // Add the record and comments that were placed above or to the right of it.
40
+ $this->add_record( implode( ', ', $data ), $comments );
41
+ }
42
+
43
+ $comments = array();
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Add record.
49
+ *
50
+ * @string $data Record without comments.
51
+ * @array $comments Comments related to the record.
52
+ */
53
+ private function add_record( $data, $comments = array() ) {
54
+ $this->records[] = array( $data, $comments );
55
+ }
56
+
57
+ /**
58
+ * Get records
59
+ *
60
+ * @return array
61
+ */
62
+ public function get_records() {
63
+ return $this->records;
64
+ }
65
+
66
+ /**
67
+ * Output file
68
+ *
69
+ * @return string
70
+ */
71
+ public function output() {
72
+ $r = '';
73
+ foreach ( $this->records as $rec ) {
74
+ foreach ( $rec[1] as $rec1 ) {
75
+ $r .= $rec1 . "\n";
76
+ }
77
+ $r .= $rec[0] . "\n";
78
+ }
79
+ return $r;
80
+ }
81
+
82
+ /**
83
+ * Subtract another ads.txt file.
84
+ *
85
+ * @return string
86
+ */
87
+ public function subtract( Advanced_Ads_Ads_Txt_Real_File $subtrahend ) {
88
+ $r1 = $subtrahend->get_records();
89
+ foreach ( $this->records as $k => $record ) {
90
+ foreach ( $r1 as $r ) {
91
+ if ( $record[0] === $r[0] ) {
92
+ unset( $this->records[ $k ] );
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }
modules/ads-txt/includes/class-advanced-ads-ads-txt-strategy.php CHANGED
@@ -91,6 +91,30 @@ class Advanced_Ads_Ads_Txt_Strategy {
91
 
92
  }
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  /**
95
  * Prepare content of a blog for output.
96
  *
91
 
92
  }
93
 
94
+ /**
95
+ * Set additional content.
96
+ *
97
+ * @param string $custom Additional content.
98
+ * @param bool $replace Whether to replace or not.
99
+ *
100
+ * @return bool
101
+ */
102
+ public function set_additional_content( $custom, $replace = false ) {
103
+ $prev = $this->get_options();
104
+
105
+ if ( $replace ) {
106
+ $this->options['custom'] = $custom;
107
+ } else {
108
+ $this->options['custom'] .= "\n" . $custom;
109
+ }
110
+
111
+ if ( $this->options !== $prev ) {
112
+ $this->changed = true;
113
+ }
114
+
115
+ return true;
116
+ }
117
+
118
  /**
119
  * Prepare content of a blog for output.
120
  *
modules/ads-txt/main.php CHANGED
@@ -7,13 +7,21 @@
7
 
8
  class_exists( 'Advanced_Ads', false ) || exit();
9
 
10
- if (
11
- ! is_multisite()
12
- || ( function_exists( 'is_site_meta_supported' ) && is_site_meta_supported() )
13
- ) {
14
- if ( is_admin() ) {
15
- new Advanced_Ads_Ads_Txt_Admin( new Advanced_Ads_Ads_Txt_Strategy() );
16
- } else {
17
- new Advanced_Ads_Ads_Txt_Public( new Advanced_Ads_Ads_Txt_Strategy() );
 
 
 
 
 
18
  }
19
  }
 
 
 
7
 
8
  class_exists( 'Advanced_Ads', false ) || exit();
9
 
10
+ function advanced_ads_ads_txt_init() {
11
+ if (
12
+ ! is_multisite()
13
+ || ( function_exists( 'is_site_meta_supported' ) && is_site_meta_supported() )
14
+ ) {
15
+
16
+ $public = new Advanced_Ads_Ads_Txt_Public( new Advanced_Ads_Ads_Txt_Strategy() );
17
+
18
+ if ( is_admin() ) {
19
+ new Advanced_Ads_Ads_Txt_Admin( new Advanced_Ads_Ads_Txt_Strategy(), $public );
20
+ } else {
21
+ new Advanced_Ads_Ads_Txt_Public( new Advanced_Ads_Ads_Txt_Strategy() );
22
+ }
23
  }
24
  }
25
+
26
+ add_action( 'advanced-ads-plugin-loaded', 'advanced_ads_ads_txt_init' );
27
+
modules/ads-txt/public/class-advanced-ads-ads-txt-public.php CHANGED
@@ -40,13 +40,7 @@ class Advanced_Ads_Ads_Txt_Public {
40
  return;
41
  }
42
 
43
- if ( $this->strategy->is_all_network() ) {
44
- $content = $this->prepare_multisite();
45
- } else {
46
- $options = $this->strategy->get_options();
47
- $content = $this->strategy->parse_content( $options );
48
- $content = apply_filters( 'advanced-ads-ads-txt-content', $content, get_current_blog_id() );
49
- }
50
 
51
  if ( $content ) {
52
  $content = self::TOP . "\n" . $content;
@@ -57,6 +51,22 @@ class Advanced_Ads_Ads_Txt_Public {
57
  return '';
58
  }
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  /**
61
  * Prepare content of several blogs for output.
62
  *
40
  return;
41
  }
42
 
43
+ $content = $this->get_frontend_output();
 
 
 
 
 
 
44
 
45
  if ( $content ) {
46
  $content = self::TOP . "\n" . $content;
51
  return '';
52
  }
53
 
54
+ /**
55
+ * Get output for frontend.
56
+ *
57
+ * @return string
58
+ */
59
+ public function get_frontend_output() {
60
+ if ( $this->strategy->is_all_network() ) {
61
+ $content = $this->prepare_multisite();
62
+ } else {
63
+ $options = $this->strategy->get_options();
64
+ $content = $this->strategy->parse_content( $options );
65
+ $content = apply_filters( 'advanced-ads-ads-txt-content', $content, get_current_blog_id() );
66
+ }
67
+ return $content;
68
+ }
69
+
70
  /**
71
  * Prepare content of several blogs for output.
72
  *
modules/gadsense/admin/admin.php CHANGED
@@ -199,6 +199,6 @@ class Advanced_Ads_AdSense_Admin {
199
  $display_slot_id = true;
200
 
201
  require_once GADSENSE_BASE_PATH . 'admin/views/external-ads-list.php';
202
- require_once GADSENSE_BASE_PATH . 'admin/views/external-ads-adsense.php';
203
  }
204
  }
199
  $display_slot_id = true;
200
 
201
  require_once GADSENSE_BASE_PATH . 'admin/views/external-ads-list.php';
202
+ // require_once GADSENSE_BASE_PATH . 'admin/views/external-ads-adsense.php';
203
  }
204
  }
modules/gadsense/admin/views/external-ads-adsense.php CHANGED
@@ -0,0 +1 @@
 
1
+ <?php // Silence is golden.
modules/gadsense/public/templates/page-level.php CHANGED
@@ -2,9 +2,8 @@
2
  ?><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
3
  <script>(adsbygoogle = window.adsbygoogle || []).push({
4
  google_ad_client: "<?php echo $client_id; ?>",
5
- enable_page_level_ads: true,
6
- <?php if ( isset( $options['top-anchor-ad'] ) && $options['top-anchor-ad'] ) : ?>
7
- overlays: {bottom: true},
8
  <?php endif; ?>
9
  });
10
  </script>
@@ -24,9 +23,8 @@ overlays: {bottom: true},
24
 
25
  (adsbygoogle = window.adsbygoogle || []).push({
26
  google_ad_client: "<?php echo $client_id; ?>",
27
- enable_page_level_ads: true,
28
- <?php if ( isset( $options['top-anchor-ad'] ) && $options['top-anchor-ad'] ) : ?>
29
- overlays: {bottom: true},
30
  <?php endif; ?>
31
  });
32
  }
2
  ?><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
3
  <script>(adsbygoogle = window.adsbygoogle || []).push({
4
  google_ad_client: "<?php echo $client_id; ?>",
5
+ enable_page_level_ads: true<?php if ( isset( $options['top-anchor-ad'] ) && $options['top-anchor-ad'] ) : ?>,
6
+ overlays: {bottom: true}
 
7
  <?php endif; ?>
8
  });
9
  </script>
23
 
24
  (adsbygoogle = window.adsbygoogle || []).push({
25
  google_ad_client: "<?php echo $client_id; ?>",
26
+ enable_page_level_ads: true<?php if ( isset( $options['top-anchor-ad'] ) && $options['top-anchor-ad'] ) : ?>,
27
+ overlays: {bottom: true}
 
28
  <?php endif; ?>
29
  });
30
  }
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: webzunft, advancedads
3
  Donate link:https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5RRRCEBGN3UT2
4
  Tags: ads, ad manager, ad rotation, adsense, banner
5
  Requires at least: 4.6
6
- Tested up to: 5.2
7
  Requires PHP: 5.6
8
- Stable tag: 1.14.11
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -84,7 +84,7 @@ show ads based on conditions like:
84
  serve ads by conditions based on the visitor. [List of all visitor conditions](https://wpadvancedads.com/manual/visitor-conditions/)
85
 
86
  * display or hide a banner by device: mobile and tablet or desktop
87
- * display or hide a banner by role and for logged in visitors
88
  * advanced visitor conditions: previously visited URL (referrer), user capability, browser language, browser and device, URL parameters included in [Pro](https://wpadvancedads.com/add-ons/advanced-ads-pro/)
89
  * display ads by geolocation with the [Geo Targeting add-on](https://wpadvancedads.com/add-ons/geo-targeting/)
90
  * display ads by browser width with the [Responsive add-on](https://wpadvancedads.com/add-ons/responsive-ads/)
@@ -303,6 +303,15 @@ Yes. Advanced Ads is based on WordPress standards and therefore easily customiza
303
 
304
  == Changelog ==
305
 
 
 
 
 
 
 
 
 
 
306
  = 1.14.11 =
307
 
308
  * moved placement form above the list of existing placements
@@ -338,7 +347,6 @@ Yes. Advanced Ads is based on WordPress standards and therefore easily customiza
338
  * allow "Footer code" and "Sidebar Widget" placements on AMP pages created by the official AMP plugin
339
  * prevented AMP warnings on XMLRPC requests
340
  * removed unused debug function
341
- * made editing of AdSense ads possible in PHP < 5.5.10 (please note that Advanced Ads is recommended for PHP > 5.6)
342
 
343
  = 1.14.6 =
344
 
@@ -578,10 +586,9 @@ Yes. Advanced Ads is based on WordPress standards and therefore easily customiza
578
 
579
  == Upgrade Notice ==
580
 
581
- = 1.11.1 =
582
-
583
- * fixed AdSense code field not working if AdSense connection is missing
584
 
585
- = 1.11 =
 
586
 
587
- Improves AdSense onboarding
3
  Donate link:https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5RRRCEBGN3UT2
4
  Tags: ads, ad manager, ad rotation, adsense, banner
5
  Requires at least: 4.6
6
+ Tested up to: 5.3
7
  Requires PHP: 5.6
8
+ Stable tag: 1.15
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
84
  serve ads by conditions based on the visitor. [List of all visitor conditions](https://wpadvancedads.com/manual/visitor-conditions/)
85
 
86
  * display or hide a banner by device: mobile and tablet or desktop
87
+ * display or hide a banner by role and for logged-in visitors
88
  * advanced visitor conditions: previously visited URL (referrer), user capability, browser language, browser and device, URL parameters included in [Pro](https://wpadvancedads.com/add-ons/advanced-ads-pro/)
89
  * display ads by geolocation with the [Geo Targeting add-on](https://wpadvancedads.com/add-ons/geo-targeting/)
90
  * display ads by browser width with the [Responsive add-on](https://wpadvancedads.com/add-ons/responsive-ads/)
303
 
304
  == Changelog ==
305
 
306
+ = 1.15 =
307
+
308
+ * please enable the new content injection method under Advanced Ads > Settings > General > Content Injection > Use new injection logic
309
+ * rewritten content injection to prevent HTML markup modifications
310
+ * rewritten code for Display and Visitor Condition form fields on ad edit pages
311
+ * allow to replace existing ads.txt file with the option provided by Advanced Ads
312
+ * prevented duplicated SQL query when a group contains no ads
313
+ * added warning for WP AutoTerms plugin, which prevents ads from showing on category archive pages
314
+
315
  = 1.14.11 =
316
 
317
  * moved placement form above the list of existing placements
347
  * allow "Footer code" and "Sidebar Widget" placements on AMP pages created by the official AMP plugin
348
  * prevented AMP warnings on XMLRPC requests
349
  * removed unused debug function
 
350
 
351
  = 1.14.6 =
352
 
586
 
587
  == Upgrade Notice ==
588
 
589
+ = 1.15 =
 
 
590
 
591
+ We have rewritten the content injection method. For the next weeks, new users opt in by default, existing ones need to opt in manually.
592
+ As existing user, please enable the new content injection method under Advanced Ads > Settings > General > Content Injection > Use new injection logic.
593
 
594
+ Please report any issues.