Advanced Ads - Version 1.14.11

Version Description

  • moved placement form above the list of existing placements
  • made "ads.txt" file available before the Settings page is saved
  • removed leading and trailing spaces from privacy options to prevent accidental misconfiguration
  • implementing coding standards in a few backend files
  • fixed welcome panel not showing up
  • fix for plugins using the "pre_option_upload_path" or "pre_option_upload_url_path" filters
Download this release

Release Info

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

Code changes from version 1.14.10 to 1.14.11

admin/assets/js/admin.js CHANGED
@@ -788,6 +788,18 @@ function advads_post_search( searchParam, callback ) {
788
  }, 'json');
789
  }
790
 
 
 
 
 
 
 
 
 
 
 
 
 
791
  /**
792
  * toggle content elements (hide/show)
793
  *
788
  }, 'json');
789
  }
790
 
791
+ /**
792
+ * Scroll to position in backend minus admin bar height
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
  /**
804
  * toggle content elements (hide/show)
805
  *
admin/class-advanced-ads-admin.php CHANGED
@@ -385,7 +385,7 @@ class Advanced_Ads_Admin {
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', false )
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;
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;
admin/includes/class-ad-type.php CHANGED
@@ -1,6 +1,9 @@
1
  <?php
2
- defined( 'ABSPATH' ) || exit;
3
 
 
 
 
4
  class Advanced_Ads_Admin_Ad_Type {
5
  /**
6
  * Instance of this class.
@@ -10,51 +13,114 @@ class Advanced_Ads_Admin_Ad_Type {
10
  protected static $instance = null;
11
 
12
  /**
13
- * post type slug
14
  *
15
  * @since 1.0.0
16
  * @var string
17
  */
18
  protected $post_type = '';
19
 
 
 
 
20
  private function __construct() {
21
- // registering custom columns needs to work with and without DOING_AJAX
22
- add_filter( 'manage_advanced_ads_posts_columns', array($this, 'ad_list_columns_head') ); // extra column
23
- add_filter( 'manage_advanced_ads_posts_custom_column', array($this, 'ad_list_columns_content'), 10, 2 ); // extra column
24
- add_filter( 'manage_advanced_ads_posts_custom_column', array($this, 'ad_list_columns_timing'), 10, 2 ); // extra column
25
- add_filter( 'manage_advanced_ads_posts_custom_column', array($this, 'ad_list_columns_shortcode'), 10, 2 ); // extra column
26
- add_action( 'restrict_manage_posts', array( $this, 'ad_list_add_filters') );
27
- add_filter( 'default_hidden_columns', array( $this, 'hide_ad_list_columns' ), 10, 2 ); // hide the ad shortcode column by default
28
-
29
- // ad updated messages
30
- add_filter( 'bulk_post_updated_messages', array($this, 'ad_bulk_update_messages'), 10, 2 );
31
-
32
- // handling (ad) lists
33
- add_filter( 'request', array($this, 'ad_list_request') ); // order ads by title, not ID
34
- add_action( 'all_admin_notices', array($this, 'no_ads_yet_notice') );
35
-
36
- // save ads post type
37
- add_action( 'save_post', array($this, 'save_ad') );
38
- // delete ads post type
39
- add_action( 'delete_post', array($this, 'delete_ad') );
40
-
41
- // on post/ad edit screen
42
- add_action( 'edit_form_top', array($this, 'edit_form_above_title') );
43
- add_action( 'edit_form_after_title', array($this, 'edit_form_below_title') );
44
- add_action( 'dbx_post_sidebar', array($this, 'edit_form_end') );
45
- add_action( 'post_submitbox_misc_actions', array($this, 'add_submit_box_meta') );
46
- add_action( 'admin_enqueue_scripts', array($this, 'use_code_editor') );
47
-
48
- // ad updated messages
49
- add_filter( 'post_updated_messages', array($this, 'ad_update_messages') );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  $this->post_type = constant( 'Advanced_Ads::POST_TYPE_SLUG' );
52
 
53
- add_filter( 'gettext', array( $this, 'replace_cheating_message' ), 20, 2 );
 
 
 
54
 
55
- // things that need to know the current screen
56
- add_action( 'current_screen', array( $this, 'run_on_ad_edit_screen' ) );
57
- add_filter( 'pre_wp_unique_post_slug', array( $this, 'pre_wp_unique_post_slug' ), 10, 6 );
 
 
 
 
 
 
58
 
59
  }
60
 
@@ -66,49 +132,88 @@ class Advanced_Ads_Admin_Ad_Type {
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
- * add heading for extra column of ads list
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  * remove the date column
78
  *
 
 
 
79
  * @since 1.3.3
80
- * @param arr $columns
81
  */
82
- public function ad_list_columns_head( $columns ){
83
  $new_columns = array();
84
- if( is_array( $columns ) ){
85
- foreach( $columns as $key => $value ) {
86
  $new_columns[ $key ] = $value;
87
- if ( $key == 'title' ){
88
- $new_columns[ 'ad_details' ] = __( 'Ad Details', 'advanced-ads' );
89
- $new_columns[ 'ad_timing' ] = __( 'Ad Planning', 'advanced-ads' );
90
- $new_columns[ 'ad_shortcode' ] = __( 'Ad Shortcode', 'advanced-ads' );
91
  }
92
  }
93
  } else {
94
- $new_columns[ 'ad_details' ] = __( 'Ad Details', 'advanced-ads' );
95
- $new_columns[ 'ad_timing' ] = __( 'Ad Planning', 'advanced-ads' );
96
- $new_columns[ 'ad_shortcode' ] = __( 'Ad Shortcode', 'advanced-ads' );
97
  }
98
 
99
- // white-listed columns
100
  $whitelist = apply_filters( 'advanced-ads-ad-list-allowed-columns', array(
101
- 'cb', // checkbox
102
- 'title',
103
- 'ad_details',
104
- 'ad_timing',
105
- 'ad_shortcode',
106
- 'taxonomy-advanced_ads_groups',
107
  ) );
108
 
109
- // remove non-white-listed columns
110
- foreach( $new_columns as $_key => $_value ){
111
- if( ! in_array( $_key, $whitelist ) ){
112
  unset( $new_columns[ $_key ] );
113
  }
114
  }
@@ -117,23 +222,24 @@ class Advanced_Ads_Admin_Ad_Type {
117
  }
118
 
119
  /**
120
- * display ad details in ads list
 
 
 
121
  *
122
  * @since 1.3.3
123
- * @param string $column_name name of the column
124
- * @param int $ad_id id of the ad
125
  */
126
- public function ad_list_columns_content($column_name, $ad_id) {
127
- if ( $column_name == 'ad_details' ) {
128
  $ad = new Advanced_Ads_Ad( $ad_id );
129
 
130
- // load ad type title
131
  $types = Advanced_Ads::get_instance()->ad_types;
132
- $type = ( ! empty($types[$ad->type]->title)) ? $types[$ad->type]->title : 0;
133
 
134
- // load ad size
135
  $size = 0;
136
- if ( ! empty($ad->width) || ! empty($ad->height) ) {
137
  $size = sprintf( '%d x %d', $ad->width, $ad->height );
138
  }
139
 
@@ -144,105 +250,118 @@ class Advanced_Ads_Admin_Ad_Type {
144
  }
145
 
146
  /**
147
- * display ad details in ads list
 
 
 
148
  *
149
  * @since 1.6.11
150
- * @param string $column_name name of the column
151
- * @param int $ad_id id of the ad
152
  */
153
- public function ad_list_columns_timing($column_name, $ad_id) {
154
- if ( $column_name == 'ad_timing' ) {
155
  $ad = new Advanced_Ads_Ad( $ad_id );
156
 
157
- $expiry = false;
158
- $post_future = false;
159
- $post_start = get_post_time('U', true, $ad->id );
160
- $html_classes = 'advads-filter-timing';
161
- $expiry_date_format = get_option( 'date_format' ). ', ' . get_option( 'time_format' );
162
 
163
- if( isset( $ad->expiry_date ) && $ad->expiry_date ){
164
  $html_classes .= ' advads-filter-any-exp-date';
165
 
166
  $expiry = $ad->expiry_date;
167
- if( $ad->expiry_date < time() ){
168
  $html_classes .= ' advads-filter-expired';
169
  }
170
  }
171
- if( $post_start > time() ){
172
- $post_future = $post_start;
173
  $html_classes .= ' advads-filter-future';
174
  }
175
 
176
- ob_start();
177
- do_action_ref_array( 'advanced-ads-ad-list-timing-column-after', array( $ad, &$html_classes ) );
178
- $content_after = ob_get_clean();
 
 
 
179
 
180
  include ADVADS_BASE_PATH . 'admin/views/ad-list-timing-column.php';
181
  }
182
  }
183
 
184
  /**
185
- * display ad shortcode in ads list
 
 
 
186
  *
187
  * @since 1.8.2
188
- * @param string $column_name name of the column
189
- * @param int $ad_id id of the ad
190
  */
191
- public function ad_list_columns_shortcode($column_name, $ad_id) {
192
- if ( $column_name == 'ad_shortcode' ) {
193
  $ad = new Advanced_Ads_Ad( $ad_id );
194
-
195
  include ADVADS_BASE_PATH . 'admin/views/ad-list-shortcode-column.php';
196
  }
197
  }
198
-
199
  /**
200
- * display ad shortcode in ads list
201
  *
202
- * @since 1.10.5
203
- * @param array $hidden An array of columns hidden by default.
204
  * @param WP_Screen $screen WP_Screen object of the current screen.
 
 
 
205
  */
206
  public function hide_ad_list_columns( $hidden, $screen ) {
207
-
208
- if( isset( $screen->id ) && 'edit-' . Advanced_Ads::POST_TYPE_SLUG === $screen->id ){
209
-
210
  $hidden[] = 'ad_shortcode';
211
-
212
  }
213
-
214
  return $hidden;
215
  }
216
 
217
  /**
218
- * adds filter dropdowns before the 'Filter' button on the ad list table
219
  */
220
  public function ad_list_add_filters() {
221
  $screen = get_current_screen();
222
- if ( ! isset( $screen->id ) || $screen->id !== 'edit-advanced_ads' ) {
223
  return;
224
  }
225
  include ADVADS_BASE_PATH . 'admin/views/ad-list-filters.php';
226
  }
227
 
228
  /**
229
- * edit ad bulk update messages
230
  *
231
- * @since 1.4.7
232
- * @param arr $messages existing bulk update messages
233
- * @param arr $counts numbers of updated ads
234
- * @return arr $messages
235
  *
 
236
  * @see wp-admin/edit.php
237
  */
238
- public function ad_bulk_update_messages(array $messages, array $counts){
239
  $post = get_post();
240
 
241
- $messages[Advanced_Ads::POST_TYPE_SLUG] = array(
 
242
  'updated' => _n( '%s ad updated.', '%s ads updated.', $counts['updated'], 'advanced-ads' ),
 
243
  'locked' => _n( '%s ad not updated, somebody is editing it.', '%s ads not updated, somebody is editing them.', $counts['locked'], 'advanced-ads' ),
 
244
  'deleted' => _n( '%s ad permanently deleted.', '%s ads permanently deleted.', $counts['deleted'], 'advanced-ads' ),
 
245
  'trashed' => _n( '%s ad moved to the Trash.', '%s ads moved to the Trash.', $counts['trashed'], 'advanced-ads' ),
 
246
  'untrashed' => _n( '%s ad restored from the Trash.', '%s ads restored from the Trash.', $counts['untrashed'], 'advanced-ads' ),
247
  );
248
 
@@ -250,18 +369,20 @@ class Advanced_Ads_Admin_Ad_Type {
250
  }
251
 
252
  /**
253
- * order ads by title on ads list
254
  *
 
 
 
255
  * @since 1.3.18
256
- * @param arr $vars array with request vars
257
  */
258
- public function ad_list_request($vars){
259
 
260
- // order ads by title on ads list
261
- if ( is_admin() && empty( $vars['orderby'] ) && isset( $vars['post_type'] ) && $this->post_type == $vars['post_type'] ) {
262
  $vars = array_merge( $vars, array(
263
  'orderby' => 'title',
264
- 'order' => 'ASC'
265
  ) );
266
  }
267
 
@@ -269,113 +390,120 @@ class Advanced_Ads_Admin_Ad_Type {
269
  }
270
 
271
  /**
272
- * show instructions to create first ad above the ad list
273
  *
274
- * @return type
275
  */
276
- public function no_ads_yet_notice(){
277
  $screen = get_current_screen();
278
- if ( ! isset( $screen->id ) || $screen->id !== 'edit-advanced_ads' ) {
279
  return;
280
  }
281
-
282
- // get number of ads
283
  $existing_ads = Advanced_Ads::get_number_of_ads();
284
 
285
- // only display if there are no more than 2 ads
286
- if( 3 > $existing_ads ){
287
- echo '<div class="advads-ad-metabox postbox" style="clear: both; margin: 10px 20px 0 2px;">';
288
- include ADVADS_BASE_PATH . 'admin/views/ad-list-no-ads.php';
289
- echo '</div>';
290
  }
291
  }
292
 
293
-
294
  /**
295
- * prepare the ad post type to be saved
 
 
296
  *
297
  * @since 1.0.0
298
- * @param int $post_id id of the post
299
  * @todo handling this more dynamic based on ad type
300
  */
301
- public function save_ad($post_id) {
302
-
303
- if ( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads') )
304
- // only use for ads, no other post type
305
- || ! isset($_POST['post_type'])
306
- || $this->post_type != $_POST['post_type']
307
- || ! isset($_POST['advanced_ad']['type'])
308
- || wp_is_post_revision( $post_id ) ) {
309
  return;
310
  }
311
 
312
- // get ad object
313
  $ad = new Advanced_Ads_Ad( $post_id );
314
  if ( ! $ad instanceof Advanced_Ads_Ad ) {
315
  return;
316
  }
317
 
318
- // filter to allow change of submitted ad settings
319
  $_POST['advanced_ad'] = apply_filters( 'advanced-ads-ad-settings-pre-save', $_POST['advanced_ad'] );
320
 
321
  $ad->type = $_POST['advanced_ad']['type'];
322
 
323
  /**
324
- * deprecated since introduction of "visitors" in 1.5.4
325
  */
326
- if ( isset($_POST['advanced_ad']['visitor']) ) {
327
  $ad->set_option( 'visitor', $_POST['advanced_ad']['visitor'] );
328
  } else {
329
  $ad->set_option( 'visitor', array() );
330
  }
331
- // visitor conditions
332
- if ( isset($_POST['advanced_ad']['visitors']) ) {
333
  $ad->set_option( 'visitors', $_POST['advanced_ad']['visitors'] );
334
  } else {
335
  $ad->set_option( 'visitors', array() );
336
  }
337
  $ad->url = 0;
338
- if ( isset($_POST['advanced_ad']['url']) ) {
339
  // May contain placeholders added by the tracking add-on.
340
  $ad->url = trim( $_POST['advanced_ad']['url'] );
341
  }
342
 
343
- // save size
344
  $ad->width = 0;
345
- if ( isset($_POST['advanced_ad']['width']) ) {
346
  $ad->width = absint( $_POST['advanced_ad']['width'] );
347
  }
348
  $ad->height = 0;
349
- if ( isset($_POST['advanced_ad']['height']) ) {
350
  $ad->height = absint( $_POST['advanced_ad']['height'] );
351
  }
352
 
353
- if ( ! empty($_POST['advanced_ad']['description']) ) {
354
- $ad->description = esc_textarea( $_POST['advanced_ad']['description'] ); }
355
- else { $ad->description = ''; }
 
 
356
 
357
- if ( ! empty($_POST['advanced_ad']['content']) ) {
358
- $ad->content = $_POST['advanced_ad']['content']; }
359
- else { $ad->content = ''; }
 
 
360
 
361
  $output = isset( $_POST['advanced_ad']['output'] ) ? $_POST['advanced_ad']['output'] : array();
362
 
363
  // Find Advanced Ads shortcodes.
364
  if ( ! empty( $output['allow_shortcodes'] ) ) {
365
- $shortcode_pattern = get_shortcode_regex( array( 'the_ad', 'the_ad_group', 'the_ad_placement' ) );
 
 
 
 
366
  $output['has_shortcode'] = preg_match( '/' . $shortcode_pattern . '/s', $ad->content );
367
  }
368
 
369
  // Set output.
370
  $ad->set_option( 'output', $output );
371
 
372
- if ( ! empty($_POST['advanced_ad']['conditions']) ){
373
  $ad->conditions = $_POST['advanced_ad']['conditions'];
374
  } else {
375
  $ad->conditions = array();
376
  }
377
- // prepare expiry date
378
- if ( isset($_POST['advanced_ad']['expiry_date']['enabled']) ) {
379
  $year = absint( $_POST['advanced_ad']['expiry_date']['year'] );
380
  $month = absint( $_POST['advanced_ad']['expiry_date']['month'] );
381
  $day = absint( $_POST['advanced_ad']['expiry_date']['day'] );
@@ -383,16 +511,17 @@ class Advanced_Ads_Admin_Ad_Type {
383
  $minute = absint( $_POST['advanced_ad']['expiry_date']['minute'] );
384
 
385
  $expiration_date = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $year, $month, $day, $hour, $minute, '00' );
386
- $valid_date = wp_checkdate( $month, $day, $year, $expiration_date );
387
 
388
- if ( !$valid_date ) {
389
  $ad->expiry_date = 0;
390
  } else {
391
- $_gmDate = date_create( $expiration_date, Advanced_Ads_Admin::get_wp_timezone() );
392
- $_gmDate->setTimezone( new DateTimeZone( 'UTC' ) );
393
- $gmDate = $_gmDate->format( 'Y-m-d-H-i' );
394
- list( $year, $month, $day, $hour, $minute ) = explode( '-', $gmDate );
395
- $ad->expiry_date = gmmktime($hour, $minute, 0, $month, $day, $year);
 
396
  }
397
  } else {
398
  $ad->expiry_date = 0;
@@ -402,7 +531,12 @@ class Advanced_Ads_Admin_Ad_Type {
402
  if ( $image_id ) {
403
  $attachment = get_post( $image_id );
404
  if ( $attachment && 0 === $attachment->post_parent ) {
405
- wp_update_post( array( 'ID' => $image_id, 'post_parent' => $post_id ) );
 
 
 
 
 
406
  }
407
  }
408
 
@@ -410,9 +544,9 @@ class Advanced_Ads_Admin_Ad_Type {
410
  }
411
 
412
  /**
413
- * prepare the ad post type to be removed
414
  *
415
- * @param int $post_id id of the post
416
  */
417
  public function delete_ad( $post_id ) {
418
  global $wpdb;
@@ -423,50 +557,54 @@ class Advanced_Ads_Admin_Ad_Type {
423
 
424
  if ( $post_id > 0 ) {
425
  $post_type = get_post_type( $post_id );
426
- if ( $post_type == $this->post_type ) {
427
- $wpdb->query(
428
- $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %d", '_advanced-ads_parent_id', $post_id )
429
- );
430
  }
431
  }
432
  }
433
 
434
  /**
435
- * add information above the ad title
 
 
436
  *
437
  * @since 1.5.6
438
- * @param obj $post
439
  */
440
- public function edit_form_above_title($post){
441
- if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
442
  return;
443
  }
444
-
445
- // highlight Dummy ad if this is the first ad
446
- if( ! Advanced_Ads::get_number_of_ads() ){
447
- ?><style>.advanced-ads-type-list-dummy { font-weight: bold; }</style><?php
 
 
 
 
448
  }
449
 
450
-
451
  $ad = new Advanced_Ads_Ad( $post->ID );
452
 
453
  $placement_types = Advanced_Ads_Placements::get_placement_types();
454
- $placements = Advanced_Ads::get_ad_placements_array(); // -TODO use model
455
 
456
- // display general and wizard information
457
  include ADVADS_BASE_PATH . 'admin/views/ad-info-top.php';
458
- // display ad injection information
459
  include ADVADS_BASE_PATH . 'admin/views/placement-injection-top.php';
460
  }
461
 
462
  /**
463
- * add information about the ad below the ad title
 
 
464
  *
465
  * @since 1.1.0
466
- * @param obj $post
467
  */
468
- public function edit_form_below_title($post){
469
- if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
470
  return;
471
  }
472
  $ad = new Advanced_Ads_Ad( $post->ID );
@@ -475,13 +613,14 @@ class Advanced_Ads_Admin_Ad_Type {
475
  }
476
 
477
  /**
478
- * add information below the ad edit form
 
 
479
  *
480
  * @since 1.7.3
481
- * @param obj $post
482
  */
483
- public function edit_form_end($post){
484
- if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
485
  return;
486
  }
487
 
@@ -489,54 +628,54 @@ class Advanced_Ads_Admin_Ad_Type {
489
  }
490
 
491
  /**
492
- * add meta values below submit box
493
  *
494
  * @since 1.3.15
495
  */
496
- public function add_submit_box_meta(){
497
  global $post, $wp_locale;
498
 
499
- if ( $post->post_type !== Advanced_Ads::POST_TYPE_SLUG ) { return; }
 
 
500
 
501
  $ad = new Advanced_Ads_Ad( $post->ID );
502
 
503
- // get time set for ad or current timestamp (both GMT)
504
- $utc_ts = $ad->expiry_date ? $ad->expiry_date : time();
505
- $utc_time = date_create( '@' . $utc_ts );
506
- $tz_option = get_option( 'timezone_string' );
507
- $exp_time = clone $utc_time;
508
-
509
- if ( $tz_option ) {
510
- $exp_time->setTimezone( Advanced_Ads_Admin::get_wp_timezone() );
511
- } else {
512
- $tz_name = Advanced_Ads_Admin::timezone_get_name( Advanced_Ads_Admin::get_wp_timezone() );
513
- $tz_offset = substr( $tz_name, 3 );
514
- $off_time = date_create( $utc_time->format( 'Y-m-d\TH:i:s' ) . $tz_offset );
515
- $offset_in_sec = date_offset_get( $off_time );
516
- $exp_time = date_create( '@' . ( $utc_ts + $offset_in_sec ) );
517
- }
518
 
519
  list( $curr_year, $curr_month, $curr_day, $curr_hour, $curr_minute ) = explode( '-', $exp_time->format( 'Y-m-d-H-i' ) );
520
- $enabled = 1 - empty($ad->expiry_date);
521
 
522
  include ADVADS_BASE_PATH . 'admin/views/ad-submitbox-meta.php';
523
  }
524
-
525
  /**
526
- * use CodeMirror for plain text input field
527
- *
528
- * needs WordPress 4.9 and higher
529
- *
530
  * @since 1.8.15
531
  */
532
- public function use_code_editor(){
533
  global $wp_version;
534
- if ( 'advanced_ads' !== get_current_screen()->id
535
- || defined( 'ADVANCED_ADS_DISABLE_CODE_HIGHLIGHTING' )
536
- || -1 === version_compare( $wp_version, '4.9' ) ) {
537
- return;
538
  }
539
-
540
  // Enqueue code editor and settings for manipulating HTML.
541
  $settings = wp_enqueue_code_editor( array( 'type' => 'application/x-httpd-php' ) );
542
 
@@ -545,135 +684,106 @@ class Advanced_Ads_Admin_Ad_Type {
545
  return;
546
  }
547
 
548
- wp_add_inline_script(
549
- 'code-editor',
550
- sprintf(
551
- 'jQuery( function() { if( jQuery( "#advads-ad-content-plain" ).length && typeof Advanced_Ads_Admin !== "undefined" ){ Advanced_Ads_Admin.editor = wp.codeEditor.initialize( "advads-ad-content-plain", %s ); Advanced_Ads_Admin.editor.codemirror.on("keyup", Advanced_Ads_Admin.check_ad_source); jQuery( function() { Advanced_Ads_Admin.check_ad_source(); } ); } } );',
552
- wp_json_encode( $settings )
553
- )
554
- );
555
  }
556
 
557
  /**
558
- * edit ad update messages
559
  *
560
- * @since 1.4.7
561
- * @param arr $messages existing post update messages
562
- * @return arr $messages
563
  *
 
564
  * @see wp-admin/edit-form-advanced.php
565
  */
566
- public function ad_update_messages($messages = array()){
567
  $post = get_post();
568
 
569
- // added to hide error message caused by third party code that uses post_updated_messages filter wrong
570
- if( ! is_array( $messages )){
571
- return $messages;
572
  }
573
 
574
- $messages[Advanced_Ads::POST_TYPE_SLUG] = array(
575
  0 => '', // Unused. Messages start at index 1.
576
  1 => __( 'Ad updated.', 'advanced-ads' ),
577
- 4 => __( 'Ad updated.', 'advanced-ads' ),
578
- /* translators: %s: date and time of the revision */
579
  5 => isset( $_GET['revision'] ) ? sprintf( __( 'Ad restored to revision from %s', 'advanced-ads' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
580
- 6 => __( 'Ad saved.', 'advanced-ads' ), // published
581
- 7 => __( 'Ad saved.', 'advanced-ads' ), // saved
582
  8 => __( 'Ad submitted.', 'advanced-ads' ),
583
- 9 => sprintf(
584
- __( 'Ad scheduled for: <strong>%1$s</strong>.', 'advanced-ads' ),
585
- // translators: Publish box date format, see http://php.net/date
586
- date_i18n( __( 'M j, Y @ G:i', 'advanced-ads' ), strtotime( $post->post_date ) )
587
- ),
588
- 10 => __( 'Ad draft updated.', 'advanced-ads' )
589
  );
 
590
  return $messages;
591
  }
592
 
593
  /**
594
- * whether to show the wizard welcome message or not
595
  *
596
- * @since 1.7.4
597
  * @return bool true, if wizard welcome message should be displayed
 
598
  */
599
- public function show_wizard_welcome(){
600
  $user_id = get_current_user_id();
601
- if( ! $user_id ) {
602
- return true;
603
  }
604
 
605
- $hide_wizard = get_user_meta( $user_id, 'advanced-ads-hide-wizard', true );
606
  global $post;
607
 
608
  return ( ! $hide_wizard && 'edit' !== $post->filter ) ? true : false;
609
  }
610
 
611
  /**
612
- * whether to start the wizard by default or not
613
  *
614
  * @since 1.7.4
615
  * return bool true, if wizard should start automatically
616
  */
617
- public function start_wizard_automatically(){
618
  $user_id = get_current_user_id();
619
- if( ! $user_id ) {
620
- return true;
621
  }
622
 
623
- $hide_wizard = get_user_meta( $user_id, 'advanced-ads-hide-wizard', true );
624
- global $post;
625
 
626
- // true if the wizard was never started or closed
627
- return ( ( ! $hide_wizard && 'edit' !== $post->filter ) || 'false'=== $hide_wizard ) ? true : false;
628
- }
629
 
630
- /**
631
- * Check if an ad is not valid for 'Post Content' placement
632
- *
633
- * @param obj $ad Advanced_Ads_Ad object
634
- * @return string with error if not valid, empty string if valid
635
- */
636
- public static function check_ad_dom_is_not_valid( Advanced_Ads_Ad $ad ) {
637
- $adContent = ( isset( $ad->content ) ) ? $ad->content : '';
638
- if ( ! extension_loaded( 'dom' ) || ! $adContent ) {
639
- return false;
640
  }
641
 
642
- $wpCharset = get_bloginfo('charset');
643
- $adDom = new DOMDocument('1.0', $wpCharset);
644
-
645
- $libxml_previous_state = libxml_use_internal_errors( true );
646
- // clear existing errors
647
- libxml_clear_errors();
648
- // source for this regex: http://stackoverflow.com/questions/17852537/preg-replace-only-specific-part-of-string
649
- $adContent = preg_replace('#(document.write.+)</(.*)#', '$1<\/$2', $adContent); // escapes all closing html tags
650
- $adDom->loadHtml('<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=' . $wpCharset . '" /><body>' . $adContent);
651
-
652
- $errors = '';
653
- foreach( libxml_get_errors() as $_error ) {
654
- // continue, if there is '&' symbol, but not HTML entity
655
- if ( false === stripos( $_error->message, 'htmlParseEntityRef:' ) ) {
656
- $errors .= print_r( $_error, true );
657
- }
658
- }
659
 
660
- libxml_use_internal_errors( $libxml_previous_state );
661
- return $errors;
662
  }
663
 
664
  /**
665
  * Replace 'You need a higher level of permission.' message if user role does not have required permissions.
666
  *
667
- * @param string $translation Translated text.
668
- * @param string $text Text to translate.
 
669
  * @return string $translation Translated text.
670
  */
671
  public function replace_cheating_message( $translated_text, $untranslated_text ) {
672
  global $typenow;
673
 
674
- if ( isset( $typenow ) && $untranslated_text === 'You need a higher level of permission.' && $typenow === $this->post_type ) {
675
  $translated_text = __( 'You don’t have access to ads. Please deactivate and re-enable Advanced Ads again to fix this.', 'advanced-ads' )
676
- . '&nbsp;<a href="' . ADVADS_URL . 'manual/user-capabilities/?utm_source=advanced-ads&utm_medium=link&utm_campaign=wrong-user-role#You_dont_have_access_to_ads" target="_blank">' . __( 'Get help', 'advanced-ads' ) . '</a>';
677
  }
678
 
679
  return $translated_text;
@@ -689,22 +799,27 @@ class Advanced_Ads_Admin_Ad_Type {
689
  return;
690
  }
691
 
692
- // Remove parent group dropdown in ad edit
693
- add_filter( 'wp_dropdown_cats', array( $this, 'remove_parent_group_dropdown'), 10, 2 );
 
 
 
694
 
695
  }
696
 
697
  /**
698
  * Remove parent group dropdown from ad group taxonomy
699
  *
700
- * @param string $output parent group HTML
701
- * @param array $arguments
 
702
  * @return string new parent group HTML
703
  */
704
- public function remove_parent_group_dropdown( $output, $arguments) {
705
- if( $arguments['name']=='newadvanced_ads_groups_parent' ){
706
- $output ='';
707
  }
 
708
  return $output;
709
  }
710
 
@@ -713,13 +828,15 @@ class Advanced_Ads_Admin_Ad_Type {
713
  * Almost all code here copied from `wp_unique_post_slug()`.
714
  *
715
  * @param string $override_slug Short-circuit return value.
716
- * @param string $slug The desired slug (post_name).
717
- * @param int $post_ID Post ID.
718
- * @param string $post_status The post status.
719
- * @param string $post_type Post type.
720
- * @param int $post_parent Post parent ID.
 
 
721
  */
722
- function pre_wp_unique_post_slug( $override_slug, $slug, $post_ID, $post_status, $post_type, $post_parent ) {
723
  if ( Advanced_Ads::POST_TYPE_SLUG !== $post_type ) {
724
  return $override_slug;
725
  }
@@ -736,12 +853,12 @@ class Advanced_Ads_Admin_Ad_Type {
736
  $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID ) );
737
 
738
 
739
- if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug ) {
740
  $suffix = 2;
741
  do {
742
- $alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
743
  $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_ID ) );
744
- $suffix++;
745
  } while ( $post_name_check );
746
  $override_slug = $alt_post_name;
747
  }
1
  <?php
2
+ defined( 'ABSPATH' ) || exit;
3
 
4
+ /**
5
+ * Class Advanced_Ads_Admin_Ad_Type
6
+ */
7
  class Advanced_Ads_Admin_Ad_Type {
8
  /**
9
  * Instance of this class.
13
  protected static $instance = null;
14
 
15
  /**
16
+ * Post type slug
17
  *
18
  * @since 1.0.0
19
  * @var string
20
  */
21
  protected $post_type = '';
22
 
23
+ /**
24
+ * Register hooks function related to the ad type
25
+ */
26
  private function __construct() {
27
+ // registering custom columns needs to work with and without DOING_AJAX.
28
+ add_filter( 'manage_advanced_ads_posts_columns', array(
29
+ $this,
30
+ 'ad_list_columns_head',
31
+ ) ); // extra column.
32
+ add_filter( 'manage_advanced_ads_posts_custom_column', array(
33
+ $this,
34
+ 'ad_list_columns_content',
35
+ ), 10, 2 ); // extra column.
36
+ add_filter( 'manage_advanced_ads_posts_custom_column', array(
37
+ $this,
38
+ 'ad_list_columns_timing',
39
+ ), 10, 2 ); // extra column.
40
+ add_filter( 'manage_advanced_ads_posts_custom_column', array(
41
+ $this,
42
+ 'ad_list_columns_shortcode',
43
+ ), 10, 2 ); // extra column.
44
+ add_action( 'restrict_manage_posts', array(
45
+ $this,
46
+ 'ad_list_add_filters',
47
+ ) );
48
+ add_filter( 'default_hidden_columns', array(
49
+ $this,
50
+ 'hide_ad_list_columns',
51
+ ), 10, 2 ); // hide the ad shortcode column by default.
52
+
53
+ // ad updated messages.
54
+ add_filter( 'bulk_post_updated_messages', array(
55
+ $this,
56
+ 'ad_bulk_update_messages',
57
+ ), 10, 2 );
58
+
59
+ // handling (ad) lists.
60
+ add_filter( 'request', array(
61
+ $this,
62
+ 'ad_list_request',
63
+ ) ); // order ads by title, not ID.
64
+ add_action( 'all_admin_notices', array(
65
+ $this,
66
+ 'no_ads_yet_notice',
67
+ ) );
68
+
69
+ // save ads post type.
70
+ add_action( 'save_post', array(
71
+ $this,
72
+ 'save_ad',
73
+ ) );
74
+ // delete ads post type.
75
+ add_action( 'delete_post', array(
76
+ $this,
77
+ 'delete_ad',
78
+ ) );
79
+
80
+ // on post/ad edit screen.
81
+ add_action( 'edit_form_top', array(
82
+ $this,
83
+ 'edit_form_above_title',
84
+ ) );
85
+ add_action( 'edit_form_after_title', array(
86
+ $this,
87
+ 'edit_form_below_title',
88
+ ) );
89
+ add_action( 'dbx_post_sidebar', array(
90
+ $this,
91
+ 'edit_form_end',
92
+ ) );
93
+ add_action( 'post_submitbox_misc_actions', array(
94
+ $this,
95
+ 'add_submit_box_meta',
96
+ ) );
97
+ add_action( 'admin_enqueue_scripts', array(
98
+ $this,
99
+ 'use_code_editor',
100
+ ) );
101
+
102
+ // ad updated messages.
103
+ add_filter( 'post_updated_messages', array(
104
+ $this,
105
+ 'ad_update_messages',
106
+ ) );
107
 
108
  $this->post_type = constant( 'Advanced_Ads::POST_TYPE_SLUG' );
109
 
110
+ add_filter( 'gettext', array(
111
+ $this,
112
+ 'replace_cheating_message',
113
+ ), 20, 2 );
114
 
115
+ // things that need to know the current screen.
116
+ add_action( 'current_screen', array(
117
+ $this,
118
+ 'run_on_ad_edit_screen',
119
+ ) );
120
+ add_filter( 'pre_wp_unique_post_slug', array(
121
+ $this,
122
+ 'pre_wp_unique_post_slug',
123
+ ), 10, 6 );
124
 
125
  }
126
 
132
  public static function get_instance() {
133
  // If the single instance hasn't been set, set it now.
134
  if ( null == self::$instance ) {
135
+ self::$instance = new self();
136
  }
137
 
138
  return self::$instance;
139
  }
140
+
141
  /**
142
+ * Check if an ad is not valid for 'Post Content' placement
143
+ *
144
+ * @param Advanced_Ads_Ad $ad object.
145
+ *
146
+ * @return string with error if not valid, empty string if valid
147
+ */
148
+ public static function check_ad_dom_is_not_valid( Advanced_Ads_Ad $ad ) {
149
+ $ad_content = ( isset( $ad->content ) ) ? $ad->content : '';
150
+ if ( ! extension_loaded( 'dom' ) || ! $ad_content ) {
151
+ return false;
152
+ }
153
+
154
+ $wp_charset = get_bloginfo( 'charset' );
155
+ $ad_dom = new DOMDocument( '1.0', $wp_charset );
156
+
157
+ $libxml_previous_state = libxml_use_internal_errors( true );
158
+ // clear existing errors.
159
+ libxml_clear_errors();
160
+ // source for this regex: http://stackoverflow.com/questions/17852537/preg-replace-only-specific-part-of-string.
161
+ $ad_content = preg_replace( '#(document.write.+)</(.*)#', '$1<\/$2', $ad_content ); // escapes all closing
162
+ // html tags.
163
+ $ad_dom->loadHtml( '<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=' . $wp_charset . '" /><body>' . $ad_content );
164
+
165
+ $errors = '';
166
+ foreach ( libxml_get_errors() as $_error ) {
167
+ // continue, if there is '&' symbol, but not HTML entity.
168
+ if ( false === stripos( $_error->message, 'htmlParseEntityRef:' ) ) {
169
+ $errors .= print_r( $_error, true );
170
+ }
171
+ }
172
+
173
+ libxml_use_internal_errors( $libxml_previous_state );
174
+
175
+ return $errors;
176
+ }
177
+
178
+ /**
179
+ * Add heading for extra column of ads list
180
  * remove the date column
181
  *
182
+ * @param array $columns array with existing columns.
183
+ *
184
+ * @return array $new_columns
185
  * @since 1.3.3
 
186
  */
187
+ public function ad_list_columns_head( $columns ) {
188
  $new_columns = array();
189
+ if ( is_array( $columns ) ) {
190
+ foreach ( $columns as $key => $value ) {
191
  $new_columns[ $key ] = $value;
192
+ if ( 'title' === $key ) {
193
+ $new_columns['ad_details'] = __( 'Ad Details', 'advanced-ads' );
194
+ $new_columns['ad_timing'] = __( 'Ad Planning', 'advanced-ads' );
195
+ $new_columns['ad_shortcode'] = __( 'Ad Shortcode', 'advanced-ads' );
196
  }
197
  }
198
  } else {
199
+ $new_columns['ad_details'] = __( 'Ad Details', 'advanced-ads' );
200
+ $new_columns['ad_timing'] = __( 'Ad Planning', 'advanced-ads' );
201
+ $new_columns['ad_shortcode'] = __( 'Ad Shortcode', 'advanced-ads' );
202
  }
203
 
204
+ // white-listed columns.
205
  $whitelist = apply_filters( 'advanced-ads-ad-list-allowed-columns', array(
206
+ 'cb', // checkbox.
207
+ 'title',
208
+ 'ad_details',
209
+ 'ad_timing',
210
+ 'ad_shortcode',
211
+ 'taxonomy-advanced_ads_groups',
212
  ) );
213
 
214
+ // remove non-white-listed columns.
215
+ foreach ( $new_columns as $_key => $_value ) {
216
+ if ( ! in_array( $_key, $whitelist, true ) ) {
217
  unset( $new_columns[ $_key ] );
218
  }
219
  }
222
  }
223
 
224
  /**
225
+ * Display ad details in ads list
226
+ *
227
+ * @param string $column_name name of the column.
228
+ * @param int $ad_id id of the ad.
229
  *
230
  * @since 1.3.3
 
 
231
  */
232
+ public function ad_list_columns_content( $column_name, $ad_id ) {
233
+ if ( 'ad_details' === $column_name ) {
234
  $ad = new Advanced_Ads_Ad( $ad_id );
235
 
236
+ // load ad type title.
237
  $types = Advanced_Ads::get_instance()->ad_types;
238
+ $type = ( ! empty( $types[ $ad->type ]->title ) ) ? $types[ $ad->type ]->title : 0;
239
 
240
+ // load ad size.
241
  $size = 0;
242
+ if ( ! empty( $ad->width ) || ! empty( $ad->height ) ) {
243
  $size = sprintf( '%d x %d', $ad->width, $ad->height );
244
  }
245
 
250
  }
251
 
252
  /**
253
+ * Display ad details in ads list
254
+ *
255
+ * @param string $column_name name of the column.
256
+ * @param int $ad_id id of the ad.
257
  *
258
  * @since 1.6.11
 
 
259
  */
260
+ public function ad_list_columns_timing( $column_name, $ad_id ) {
261
+ if ( 'ad_timing' === $column_name ) {
262
  $ad = new Advanced_Ads_Ad( $ad_id );
263
 
264
+ $expiry = false;
265
+ $post_future = false;
266
+ $post_start = get_post_time( 'U', true, $ad->id );
267
+ $html_classes = 'advads-filter-timing';
268
+ $expiry_date_format = get_option( 'date_format' ) . ', ' . get_option( 'time_format' );
269
 
270
+ if ( isset( $ad->expiry_date ) && $ad->expiry_date ) {
271
  $html_classes .= ' advads-filter-any-exp-date';
272
 
273
  $expiry = $ad->expiry_date;
274
+ if ( $ad->expiry_date < time() ) {
275
  $html_classes .= ' advads-filter-expired';
276
  }
277
  }
278
+ if ( $post_start > time() ) {
279
+ $post_future = $post_start;
280
  $html_classes .= ' advads-filter-future';
281
  }
282
 
283
+ ob_start();
284
+ do_action_ref_array( 'advanced-ads-ad-list-timing-column-after', array(
285
+ $ad,
286
+ &$html_classes,
287
+ ) );
288
+ $content_after = ob_get_clean();
289
 
290
  include ADVADS_BASE_PATH . 'admin/views/ad-list-timing-column.php';
291
  }
292
  }
293
 
294
  /**
295
+ * Display ad shortcode in ads list
296
+ *
297
+ * @param string $column_name name of the column.
298
+ * @param int $ad_id id of the ad.
299
  *
300
  * @since 1.8.2
 
 
301
  */
302
+ public function ad_list_columns_shortcode( $column_name, $ad_id ) {
303
+ if ( 'ad_shortcode' === $column_name ) {
304
  $ad = new Advanced_Ads_Ad( $ad_id );
305
+
306
  include ADVADS_BASE_PATH . 'admin/views/ad-list-shortcode-column.php';
307
  }
308
  }
309
+
310
  /**
311
+ * Display ad shortcode in ads list
312
  *
313
+ * @param array $hidden an array of columns hidden by default.
 
314
  * @param WP_Screen $screen WP_Screen object of the current screen.
315
+ *
316
+ * @return array $hidden
317
+ * @since 1.10.5
318
  */
319
  public function hide_ad_list_columns( $hidden, $screen ) {
320
+
321
+ if ( isset( $screen->id ) && 'edit-' . Advanced_Ads::POST_TYPE_SLUG === $screen->id ) {
322
+
323
  $hidden[] = 'ad_shortcode';
324
+
325
  }
326
+
327
  return $hidden;
328
  }
329
 
330
  /**
331
+ * Adds filter dropdowns before the 'Filter' button on the ad list table
332
  */
333
  public function ad_list_add_filters() {
334
  $screen = get_current_screen();
335
+ if ( ! isset( $screen->id ) || 'edit-advanced_ads' !== $screen->id ) {
336
  return;
337
  }
338
  include ADVADS_BASE_PATH . 'admin/views/ad-list-filters.php';
339
  }
340
 
341
  /**
342
+ * Edit ad bulk update messages
343
  *
344
+ * @param array $messages existing bulk update messages.
345
+ * @param array $counts numbers of updated ads.
346
+ *
347
+ * @return array $messages
348
  *
349
+ * @since 1.4.7
350
  * @see wp-admin/edit.php
351
  */
352
+ public function ad_bulk_update_messages( array $messages, array $counts ) {
353
  $post = get_post();
354
 
355
+ $messages[ Advanced_Ads::POST_TYPE_SLUG ] = array(
356
+ // translators: %s is the number of ads.
357
  'updated' => _n( '%s ad updated.', '%s ads updated.', $counts['updated'], 'advanced-ads' ),
358
+ // translators: %s is the number of ads.
359
  'locked' => _n( '%s ad not updated, somebody is editing it.', '%s ads not updated, somebody is editing them.', $counts['locked'], 'advanced-ads' ),
360
+ // translators: %s is the number of ads.
361
  'deleted' => _n( '%s ad permanently deleted.', '%s ads permanently deleted.', $counts['deleted'], 'advanced-ads' ),
362
+ // translators: %s is the number of ads.
363
  'trashed' => _n( '%s ad moved to the Trash.', '%s ads moved to the Trash.', $counts['trashed'], 'advanced-ads' ),
364
+ // translators: %s is the number of ads.
365
  'untrashed' => _n( '%s ad restored from the Trash.', '%s ads restored from the Trash.', $counts['untrashed'], 'advanced-ads' ),
366
  );
367
 
369
  }
370
 
371
  /**
372
+ * Order ads by title on ads list
373
  *
374
+ * @param array $vars array with request vars.
375
+ *
376
+ * @return array $vars
377
  * @since 1.3.18
 
378
  */
379
+ public function ad_list_request( $vars ) {
380
 
381
+ // order ads by title on ads list.
382
+ if ( is_admin() && empty( $vars['orderby'] ) && isset( $vars['post_type'] ) && $this->post_type === $vars['post_type'] ) {
383
  $vars = array_merge( $vars, array(
384
  'orderby' => 'title',
385
+ 'order' => 'ASC',
386
  ) );
387
  }
388
 
390
  }
391
 
392
  /**
393
+ * Show instructions to create first ad above the ad list
394
  *
395
+ * @return string
396
  */
397
+ public function no_ads_yet_notice() {
398
  $screen = get_current_screen();
399
+ if ( ! isset( $screen->id ) || 'edit-advanced_ads' !== $screen->id ) {
400
  return;
401
  }
402
+
403
+ // get number of ads.
404
  $existing_ads = Advanced_Ads::get_number_of_ads();
405
 
406
+ // only display if there are no more than 2 ads.
407
+ if ( 3 > $existing_ads ) {
408
+ echo '<div class="advads-ad-metabox postbox" style="clear: both; margin: 10px 20px 0 2px;">';
409
+ include ADVADS_BASE_PATH . 'admin/views/ad-list-no-ads.php';
410
+ echo '</div>';
411
  }
412
  }
413
 
 
414
  /**
415
+ * Prepare the ad post type to be saved
416
+ *
417
+ * @param int $post_id id of the post.
418
  *
419
  * @since 1.0.0
 
420
  * @todo handling this more dynamic based on ad type
421
  */
422
+ public function save_ad( $post_id ) {
423
+
424
+ if ( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads' ) ) // only use for ads, no other post type.
425
+ || ! isset( $_POST['post_type'] )
426
+ || $this->post_type != $_POST['post_type']
427
+ || ! isset( $_POST['advanced_ad']['type'] )
428
+ || wp_is_post_revision( $post_id ) ) {
 
429
  return;
430
  }
431
 
432
+ // get ad object.
433
  $ad = new Advanced_Ads_Ad( $post_id );
434
  if ( ! $ad instanceof Advanced_Ads_Ad ) {
435
  return;
436
  }
437
 
438
+ // filter to allow change of submitted ad settings.
439
  $_POST['advanced_ad'] = apply_filters( 'advanced-ads-ad-settings-pre-save', $_POST['advanced_ad'] );
440
 
441
  $ad->type = $_POST['advanced_ad']['type'];
442
 
443
  /**
444
+ * Deprecated since introduction of "visitors" in 1.5.4
445
  */
446
+ if ( isset( $_POST['advanced_ad']['visitor'] ) ) {
447
  $ad->set_option( 'visitor', $_POST['advanced_ad']['visitor'] );
448
  } else {
449
  $ad->set_option( 'visitor', array() );
450
  }
451
+ // visitor conditions.
452
+ if ( isset( $_POST['advanced_ad']['visitors'] ) ) {
453
  $ad->set_option( 'visitors', $_POST['advanced_ad']['visitors'] );
454
  } else {
455
  $ad->set_option( 'visitors', array() );
456
  }
457
  $ad->url = 0;
458
+ if ( isset( $_POST['advanced_ad']['url'] ) ) {
459
  // May contain placeholders added by the tracking add-on.
460
  $ad->url = trim( $_POST['advanced_ad']['url'] );
461
  }
462
 
463
+ // save size.
464
  $ad->width = 0;
465
+ if ( isset( $_POST['advanced_ad']['width'] ) ) {
466
  $ad->width = absint( $_POST['advanced_ad']['width'] );
467
  }
468
  $ad->height = 0;
469
+ if ( isset( $_POST['advanced_ad']['height'] ) ) {
470
  $ad->height = absint( $_POST['advanced_ad']['height'] );
471
  }
472
 
473
+ if ( ! empty( $_POST['advanced_ad']['description'] ) ) {
474
+ $ad->description = esc_textarea( $_POST['advanced_ad']['description'] );
475
+ } else {
476
+ $ad->description = '';
477
+ }
478
 
479
+ if ( ! empty( $_POST['advanced_ad']['content'] ) ) {
480
+ $ad->content = $_POST['advanced_ad']['content'];
481
+ } else {
482
+ $ad->content = '';
483
+ }
484
 
485
  $output = isset( $_POST['advanced_ad']['output'] ) ? $_POST['advanced_ad']['output'] : array();
486
 
487
  // Find Advanced Ads shortcodes.
488
  if ( ! empty( $output['allow_shortcodes'] ) ) {
489
+ $shortcode_pattern = get_shortcode_regex( array(
490
+ 'the_ad',
491
+ 'the_ad_group',
492
+ 'the_ad_placement',
493
+ ) );
494
  $output['has_shortcode'] = preg_match( '/' . $shortcode_pattern . '/s', $ad->content );
495
  }
496
 
497
  // Set output.
498
  $ad->set_option( 'output', $output );
499
 
500
+ if ( ! empty( $_POST['advanced_ad']['conditions'] ) ) {
501
  $ad->conditions = $_POST['advanced_ad']['conditions'];
502
  } else {
503
  $ad->conditions = array();
504
  }
505
+ // prepare expiry date.
506
+ if ( isset( $_POST['advanced_ad']['expiry_date']['enabled'] ) ) {
507
  $year = absint( $_POST['advanced_ad']['expiry_date']['year'] );
508
  $month = absint( $_POST['advanced_ad']['expiry_date']['month'] );
509
  $day = absint( $_POST['advanced_ad']['expiry_date']['day'] );
511
  $minute = absint( $_POST['advanced_ad']['expiry_date']['minute'] );
512
 
513
  $expiration_date = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $year, $month, $day, $hour, $minute, '00' );
514
+ $valid_date = wp_checkdate( $month, $day, $year, $expiration_date );
515
 
516
+ if ( ! $valid_date ) {
517
  $ad->expiry_date = 0;
518
  } else {
519
+ $gm_date = date_create( $expiration_date, Advanced_Ads_Admin::get_wp_timezone() );
520
+ $gm_date->setTimezone( new DateTimeZone( 'UTC' ) );
521
+ $gm_date = $gm_date->format( 'Y-m-d-H-i' );
522
+ list
523
+ ( $year, $month, $day, $hour, $minute ) = explode( '-', $gm_date );
524
+ $ad->expiry_date = gmmktime( $hour, $minute, 0, $month, $day, $year );
525
  }
526
  } else {
527
  $ad->expiry_date = 0;
531
  if ( $image_id ) {
532
  $attachment = get_post( $image_id );
533
  if ( $attachment && 0 === $attachment->post_parent ) {
534
+ wp_update_post(
535
+ array(
536
+ 'ID' => $image_id,
537
+ 'post_parent' => $post_id,
538
+ )
539
+ );
540
  }
541
  }
542
 
544
  }
545
 
546
  /**
547
+ * Prepare the ad post type to be removed
548
  *
549
+ * @param int $post_id id of the post.
550
  */
551
  public function delete_ad( $post_id ) {
552
  global $wpdb;
557
 
558
  if ( $post_id > 0 ) {
559
  $post_type = get_post_type( $post_id );
560
+ if ( $post_type === $this->post_type ) {
561
+ $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %d", '_advanced-ads_parent_id', $post_id ) );
 
 
562
  }
563
  }
564
  }
565
 
566
  /**
567
+ * Add information above the ad title
568
+ *
569
+ * @param object $post WordPress post type object.
570
  *
571
  * @since 1.5.6
 
572
  */
573
+ public function edit_form_above_title( $post ) {
574
+ if ( ! isset( $post->post_type ) || $post->post_type !== $this->post_type ) {
575
  return;
576
  }
577
+
578
+ // highlight Dummy ad if this is the first ad.
579
+ if ( ! Advanced_Ads::get_number_of_ads() ) {
580
+ ?>
581
+ <style>.advanced-ads-type-list-dummy {
582
+ font-weight: bold;
583
+ }</style>
584
+ <?php
585
  }
586
 
587
+
588
  $ad = new Advanced_Ads_Ad( $post->ID );
589
 
590
  $placement_types = Advanced_Ads_Placements::get_placement_types();
591
+ $placements = Advanced_Ads::get_ad_placements_array(); // -TODO use model
592
 
593
+ // display general and wizard information.
594
  include ADVADS_BASE_PATH . 'admin/views/ad-info-top.php';
595
+ // display ad injection information.
596
  include ADVADS_BASE_PATH . 'admin/views/placement-injection-top.php';
597
  }
598
 
599
  /**
600
+ * Add information about the ad below the ad title
601
+ *
602
+ * @param object $post WordPress Post object.
603
  *
604
  * @since 1.1.0
 
605
  */
606
+ public function edit_form_below_title( $post ) {
607
+ if ( ! isset( $post->post_type ) || $post->post_type !== $this->post_type ) {
608
  return;
609
  }
610
  $ad = new Advanced_Ads_Ad( $post->ID );
613
  }
614
 
615
  /**
616
+ * Add information below the ad edit form
617
+ *
618
+ * @param object $post WordPress Post object.
619
  *
620
  * @since 1.7.3
 
621
  */
622
+ public function edit_form_end( $post ) {
623
+ if ( ! isset( $post->post_type ) || $post->post_type !== $this->post_type ) {
624
  return;
625
  }
626
 
628
  }
629
 
630
  /**
631
+ * Add meta values below submit box
632
  *
633
  * @since 1.3.15
634
  */
635
+ public function add_submit_box_meta() {
636
  global $post, $wp_locale;
637
 
638
+ if ( Advanced_Ads::POST_TYPE_SLUG !== $post->post_type ) {
639
+ return;
640
+ }
641
 
642
  $ad = new Advanced_Ads_Ad( $post->ID );
643
 
644
+ // get time set for ad or current timestamp (both GMT).
645
+ $utc_ts = $ad->expiry_date ? $ad->expiry_date : time();
646
+ $utc_time = date_create( '@' . $utc_ts );
647
+ $tz_option = get_option( 'timezone_string' );
648
+ $exp_time = clone $utc_time;
649
+
650
+ if ( $tz_option ) {
651
+ $exp_time->setTimezone( Advanced_Ads_Admin::get_wp_timezone() );
652
+ } else {
653
+ $tz_name = Advanced_Ads_Admin::timezone_get_name( Advanced_Ads_Admin::get_wp_timezone() );
654
+ $tz_offset = substr( $tz_name, 3 );
655
+ $off_time = date_create( $utc_time->format( 'Y-m-d\TH:i:s' ) . $tz_offset );
656
+ $offset_in_sec = date_offset_get( $off_time );
657
+ $exp_time = date_create( '@' . ( $utc_ts + $offset_in_sec ) );
658
+ }
659
 
660
  list( $curr_year, $curr_month, $curr_day, $curr_hour, $curr_minute ) = explode( '-', $exp_time->format( 'Y-m-d-H-i' ) );
661
+ $enabled = 1 - empty( $ad->expiry_date );
662
 
663
  include ADVADS_BASE_PATH . 'admin/views/ad-submitbox-meta.php';
664
  }
665
+
666
  /**
667
+ * Use CodeMirror for plain text input field
668
+ *
669
+ * Needs WordPress 4.9 and higher
670
+ *
671
  * @since 1.8.15
672
  */
673
+ public function use_code_editor() {
674
  global $wp_version;
675
+ if ( 'advanced_ads' !== get_current_screen()->id || defined( 'ADVANCED_ADS_DISABLE_CODE_HIGHLIGHTING' ) || - 1 === version_compare( $wp_version, '4.9' ) ) {
676
+ return;
 
 
677
  }
678
+
679
  // Enqueue code editor and settings for manipulating HTML.
680
  $settings = wp_enqueue_code_editor( array( 'type' => 'application/x-httpd-php' ) );
681
 
684
  return;
685
  }
686
 
687
+ wp_add_inline_script(
688
+ 'code-editor',
689
+ sprintf( 'jQuery( function() { if( jQuery( "#advads-ad-content-plain" ).length && typeof Advanced_Ads_Admin !== "undefined" ){ Advanced_Ads_Admin.editor = wp.codeEditor.initialize( "advads-ad-content-plain", %s ); Advanced_Ads_Admin.editor.codemirror.on("keyup", Advanced_Ads_Admin.check_ad_source); jQuery( function() { Advanced_Ads_Admin.check_ad_source(); } ); } } );', wp_json_encode( $settings ) ) );
 
 
 
 
690
  }
691
 
692
  /**
693
+ * Edit ad update messages
694
  *
695
+ * @param array $messages existing post update messages.
696
+ *
697
+ * @return array $messages
698
  *
699
+ * @since 1.4.7
700
  * @see wp-admin/edit-form-advanced.php
701
  */
702
+ public function ad_update_messages( $messages = array() ) {
703
  $post = get_post();
704
 
705
+ // added to hide error message caused by third party code that uses post_updated_messages filter wrong.
706
+ if ( ! is_array( $messages ) ) {
707
+ return $messages;
708
  }
709
 
710
+ $messages[ Advanced_Ads::POST_TYPE_SLUG ] = array(
711
  0 => '', // Unused. Messages start at index 1.
712
  1 => __( 'Ad updated.', 'advanced-ads' ),
713
+ 4 => __( 'Ad updated.', 'advanced-ads' ), /* translators: %s: date and time of the revision */
 
714
  5 => isset( $_GET['revision'] ) ? sprintf( __( 'Ad restored to revision from %s', 'advanced-ads' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
715
+ 6 => __( 'Ad saved.', 'advanced-ads' ), // published.
716
+ 7 => __( 'Ad saved.', 'advanced-ads' ), // saved.
717
  8 => __( 'Ad submitted.', 'advanced-ads' ),
718
+ 9 => sprintf( __( 'Ad scheduled for: <strong>%1$s</strong>.', 'advanced-ads' ),
719
+ // translators: Publish box date format, see http://php.net/date.
720
+ date_i18n( __( 'M j, Y @ G:i', 'advanced-ads' ), strtotime( $post->post_date ) ) ),
721
+ 10 => __( 'Ad draft updated.', 'advanced-ads' ),
 
 
722
  );
723
+
724
  return $messages;
725
  }
726
 
727
  /**
728
+ * Whether to show the wizard welcome message or not
729
  *
 
730
  * @return bool true, if wizard welcome message should be displayed
731
+ * @since 1.7.4
732
  */
733
+ public function show_wizard_welcome() {
734
  $user_id = get_current_user_id();
735
+ if ( ! $user_id ) {
736
+ return true;
737
  }
738
 
739
+ $hide_wizard = get_user_meta( $user_id, 'advanced-ads-hide-wizard', true );
740
  global $post;
741
 
742
  return ( ! $hide_wizard && 'edit' !== $post->filter ) ? true : false;
743
  }
744
 
745
  /**
746
+ * Whether to start the wizard by default or not
747
  *
748
  * @since 1.7.4
749
  * return bool true, if wizard should start automatically
750
  */
751
+ public function start_wizard_automatically() {
752
  $user_id = get_current_user_id();
753
+ if ( ! $user_id ) {
754
+ return true;
755
  }
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
  }
772
 
773
  /**
774
  * Replace 'You need a higher level of permission.' message if user role does not have required permissions.
775
  *
776
+ * @param string $translated_text Translated text.
777
+ * @param string $untranslated_text Text to translate.
778
+ *
779
  * @return string $translation Translated text.
780
  */
781
  public function replace_cheating_message( $translated_text, $untranslated_text ) {
782
  global $typenow;
783
 
784
+ if ( isset( $typenow ) && 'You need a higher level of permission.' === $untranslated_text && $typenow === $this->post_type ) {
785
  $translated_text = __( 'You don’t have access to ads. Please deactivate and re-enable Advanced Ads again to fix this.', 'advanced-ads' )
786
+ . '&nbsp;<a href="' . ADVADS_URL . 'manual/user-capabilities/?utm_source=advanced-ads&utm_medium=link&utm_campaign=wrong-user-role#You_dont_have_access_to_ads" target="_blank">' . __( 'Get help', 'advanced-ads' ) . '</a>';
787
  }
788
 
789
  return $translated_text;
799
  return;
800
  }
801
 
802
+ // Remove parent group dropdown in ad edit.
803
+ add_filter( 'wp_dropdown_cats', array(
804
+ $this,
805
+ 'remove_parent_group_dropdown',
806
+ ), 10, 2 );
807
 
808
  }
809
 
810
  /**
811
  * Remove parent group dropdown from ad group taxonomy
812
  *
813
+ * @param string $output parent group HTML.
814
+ * @param array $arguments additional parameters.
815
+ *
816
  * @return string new parent group HTML
817
  */
818
+ public function remove_parent_group_dropdown( $output, $arguments ) {
819
+ if ( 'newadvanced_ads_groups_parent' === $arguments['name'] ) {
820
+ $output = '';
821
  }
822
+
823
  return $output;
824
  }
825
 
828
  * Almost all code here copied from `wp_unique_post_slug()`.
829
  *
830
  * @param string $override_slug Short-circuit return value.
831
+ * @param string $slug The desired slug (post_name).
832
+ * @param int $post_ID Post ID.
833
+ * @param string $post_status The post status.
834
+ * @param string $post_type Post type.
835
+ * @param int $post_parent Post parent ID.
836
+ *
837
+ * @return string
838
  */
839
+ public function pre_wp_unique_post_slug( $override_slug, $slug, $post_ID, $post_status, $post_type, $post_parent ) {
840
  if ( Advanced_Ads::POST_TYPE_SLUG !== $post_type ) {
841
  return $override_slug;
842
  }
853
  $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID ) );
854
 
855
 
856
+ if ( $post_name_check || in_array( $slug, $feeds, true ) || 'embed' === $slug ) {
857
  $suffix = 2;
858
  do {
859
+ $alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
860
  $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_ID ) );
861
+ $suffix ++;
862
  } while ( $post_name_check );
863
  $override_slug = $alt_post_name;
864
  }
admin/includes/class-notices.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * container class for admin notices
5
  *
6
  * @package WordPress
7
  * @subpackage Advanced Ads Plugin
@@ -10,12 +10,12 @@
10
  class Advanced_Ads_Admin_Notices {
11
 
12
  /**
13
- * maximum number of notices to show at once
14
  */
15
- const MAX_NOTICES = 2;
16
 
17
  /**
18
- * instance of this class.
19
  *
20
  * @since 1.5.3
21
  * @var object
@@ -23,32 +23,35 @@ class Advanced_Ads_Admin_Notices {
23
  protected static $instance = null;
24
 
25
  /**
26
- * options
27
  *
28
- * @since 1.5.3
29
- * @var array
30
  */
31
  protected $options;
32
 
33
  /**
34
- * notices to be displayed
35
  *
36
- * @since 1.5.3
37
- * @var array
38
  */
39
  public $notices = array();
40
 
41
  /**
42
- * plugin class
 
 
43
  */
44
  private $plugin;
45
 
 
 
 
46
  public function __construct() {
47
  $this->plugin = Advanced_Ads_Plugin::get_instance();
48
- // load notices
49
  $this->load_notices();
50
- // display notices
51
- //$this->display_notices();
52
 
53
  add_action( 'advanced-ads-ad-params-before', array( $this, 'adsense_tutorial' ), 10, 2 );
54
  }
@@ -56,54 +59,55 @@ class Advanced_Ads_Admin_Notices {
56
  /**
57
  * Return an instance of this class.
58
  *
59
- * @since 1.5.3
60
  * @return object A single instance of this class.
 
61
  */
62
  public static function get_instance() {
63
 
64
- // If the single instance hasn't been set, set it now.
65
  if ( null == self::$instance ) {
66
- self::$instance = new self;
67
  }
68
 
69
  return self::$instance;
70
  }
71
 
72
  /**
73
- * load admin notices
74
  *
75
  * @since 1.4.5
76
  * @updated 1.5.3 moved from admin class here
77
  */
78
  public function load_notices() {
79
 
80
- $options = $this->options();
81
  $plugin_options = $this->plugin->options();
82
 
83
- // load notices from queue
84
- $this->notices = isset($options['queue']) ? $options['queue'] : array();
85
  $notices_before = $this->notices;
86
 
87
- // check license notices
88
  $this->register_license_notices();
89
 
90
- // don’t check non-critical notices if they are disabled
91
- if ( ! isset($plugin_options['disable-notices']) ) {
92
- // handle version notices
93
  $this->register_version_notices();
94
- // check other notices
95
  $this->check_notices();
96
  }
97
 
98
- // register notices in db so they get displayed until closed for good
99
  if ( $this->notices !== $notices_before ) {
100
  $this->add_to_queue( $this->notices );
101
  }
102
  }
103
 
104
  /**
105
- * register update notices
106
  *
 
107
  */
108
  public function register_version_notices() {
109
  if ( defined( 'DOING_AJAX' ) ) {
@@ -111,125 +115,126 @@ class Advanced_Ads_Admin_Notices {
111
  }
112
 
113
  $internal_options = $this->plugin->internal_options();
114
- $plugin_options = $this->plugin->options();
115
 
116
- // set an artifical older version for updates on installed plugins before the notice logic was invented
117
- if ( ! isset($internal_options['version']) && $plugin_options !== array() ) {
118
  $old_version = '1.4.4';
119
- } elseif ( isset($internal_options['version']) ) {
120
  $old_version = $internal_options['version'];
121
  } else {
122
- // empty version for new installations
123
  $old_version = 0;
124
  }
125
  }
126
-
127
  /**
128
- * update version number to latest one
129
  */
130
- public function update_version_number(){
131
-
132
- $internal_options = $this->plugin->internal_options();
133
- $new_options = $internal_options; // in case we udpate options here
134
-
135
- $new_options['version'] = ADVADS_VERSION;
136
-
137
- // update version numbers
138
- if ( $internal_options !== $new_options ) {
139
- $this->plugin->update_internal_options( $new_options );
140
- }
141
  }
142
 
143
  /**
144
- * check various notices conditions
145
  */
146
  public function check_notices() {
147
  $internal_options = $this->plugin->internal_options();
148
- $now = time();
149
- $activation = (isset($internal_options['installed'])) ? $internal_options['installed'] : $now; // activation time
150
 
151
  $options = $this->options();
152
- $closed = isset($options['closed']) ? $options['closed'] : array();
153
- $queue = isset($options['queue']) ? $options['queue'] : array();
154
- $paused = isset($options['paused']) ? $options['paused'] : array();
155
-
156
- // register intro message
157
- if( ! Advanced_Ads_Admin::get_instance()->screen_belongs_to_advanced_ads()
158
- && $options === array() && ! in_array( 'nl_intro', $queue ) && ! isset( $closed['nl_intro'] ) ){
159
  $this->notices[] = 'nl_intro';
160
- } elseif ( Advanced_Ads_Admin::get_instance()->screen_belongs_to_advanced_ads() ){
161
- $key = array_search( 'nl_intro', $this->notices );
162
- if ( $key !== false ) {
163
- unset( $this->notices[$key]);
164
  }
165
  }
166
- // offer free add-ons if not yet subscribed
167
- if ( $this->user_can_subscribe( ) && ! in_array( 'nl_free_addons', $queue ) && ! isset( $closed['nl_free_addons'] )) {
168
- // get number of ads
169
- if( Advanced_Ads::get_number_of_ads() ){
170
  $this->notices[] = 'nl_free_addons';
171
  }
172
  }
173
  $number_of_ads = 0;
174
- // needed error handling due to a weird bug in the piklist plugin
175
  try {
176
- $number_of_ads = Advanced_Ads::get_number_of_ads();
177
  } catch ( Exception $e ) {
178
-
179
- }
180
-
181
- // ask for a review after 2 days and when 3 ads were created and when not paused
182
- if ( ! in_array( 'review', $queue )
183
- && ! isset( $closed['review'] )
184
- && ( ! isset( $paused['review'] ) || $paused['review'] <= time() )
185
- && 172800 < ( time() - $activation)
186
- && 3 <= $number_of_ads
187
- ) {
188
- $this->notices[] = 'review';
189
- } elseif ( in_array( 'review', $queue ) && 3 > $number_of_ads ){
190
- $review_key = array_search( 'review', $this->notices );
191
- if ( $review_key !== false ) {
192
- unset( $this->notices[ $review_key ] );
193
- }
194
  }
195
  }
196
 
197
  /**
198
- * register license key notices
199
  */
200
- public function register_license_notices(){
201
 
202
- if( ! Advanced_Ads_Admin::screen_belongs_to_advanced_ads() ){
203
- return;
204
  }
205
 
206
  $options = $this->options();
207
- $queue = isset($options['queue']) ? $options['queue'] : array();
208
- // check license keys
209
-
210
- if ( Advanced_Ads_Checks::licenses_invalid() ){
211
- if( ! in_array( 'license_invalid', $queue )) {
212
- $this->notices[] = 'license_invalid';
213
- }
214
  } else {
215
- $this->remove_from_queue( 'license_invalid' );
216
  }
217
  }
218
 
219
  /**
220
- * add update notices to the queue of all notices that still needs to be closed
 
 
221
  *
222
  * @since 1.5.3
223
- * @param str|arr $notices one or more notices to be added to the queue
224
  */
225
- public function add_to_queue($notices = 0) {
226
  if ( ! $notices ) {
227
  return;
228
  }
229
 
230
- // get queue from options
231
  $options = $this->options();
232
- $queue = isset($options['queue']) ? $options['queue'] : array();
233
 
234
  if ( is_array( $notices ) ) {
235
  $queue = array_merge( $queue, $notices );
@@ -237,118 +242,120 @@ class Advanced_Ads_Admin_Notices {
237
  $queue[] = $notices;
238
  }
239
 
240
- // remove possible duplicated
241
  $queue = array_unique( $queue );
242
 
243
- // update db
244
  $options['queue'] = $queue;
245
  $this->update_options( $options );
246
  }
247
 
248
  /**
249
- * remove update notice from queue
250
  * move notice into "closed"
251
  *
 
 
252
  * @since 1.5.3
253
- * @param string $notice notice to be removed from the queue
254
  */
255
- public function remove_from_queue($notice) {
256
- if ( ! isset($notice) ) {
257
  return;
258
  }
259
 
260
- // get queue from options
261
  $options_before = $options = $this->options();
262
- if ( ! isset($options['queue']) ) {
263
  return;
264
  }
265
- $queue = (array) $options['queue'];
266
- $closed = isset($options['closed']) ? $options['closed'] : array();
267
- $paused = isset($options['paused']) ? $options['paused'] : array();
268
 
269
- $key = array_search( $notice, $queue );
270
- if ( $key !== false ) {
271
- unset($queue[$key]);
272
- // close message with timestamp
273
  }
274
- // don’t close again twice
275
- if( ! isset( $closed[$notice] )){
276
- $closed[$notice] = time();
277
  }
278
- // remove from pause
279
- if( isset( $paused[$notice] ) ){
280
- unset( $paused[$notice] );
281
  }
282
-
283
- // update db
284
- $options['queue'] = $queue;
285
  $options['closed'] = $closed;
286
  $options['paused'] = $paused;
287
-
288
-
289
- // only update if changed
290
- if( $options_before !== $options ){
291
- $this->update_options( $options );
292
- // update already registered notices
293
- $this->load_notices();
294
  }
295
  }
296
-
297
  /**
298
- * hide any notice for a given time
299
  * move notice into "paused" with notice as key and timestamp as value
300
  *
 
 
301
  * @since 1.8-17
302
- * @param str $notice notice to be paused
303
  */
304
- public function hide_notice($notice) {
305
- if ( ! isset($notice) ) {
306
  return;
307
  }
308
 
309
- // get queue from options
310
  $options_before = $options = $this->options();
311
- if ( ! isset($options['queue']) ) {
312
  return;
313
  }
314
- $queue = (array) $options['queue'];
315
- $paused = isset($options['paused']) ? $options['paused'] : array();
316
 
317
- $key = array_search( $notice, $queue );
318
- if ( $key !== false ) {
319
- unset($queue[$key]);
320
  }
321
  // close message with timestamp in 7 days
322
- // don’t close again twice
323
- if( ! isset( $paused[$notice] )){
324
- $paused[$notice] = time() + WEEK_IN_SECONDS;
325
  }
326
-
327
- // update db
328
- $options['queue'] = $queue;
329
  $options['paused'] = $paused;
330
-
331
- // only update if changed
332
- if( $options_before !== $options ){
333
- $this->update_options( $options );
334
- // update already registered notices
335
- $this->load_notices();
336
  }
337
  }
338
 
339
  /**
340
- *
341
- * display notices
342
- *
343
  */
344
  public function display_notices() {
345
 
346
  if ( defined( 'DOING_AJAX' ) ) {
347
- return; }
 
 
 
 
 
348
 
349
- if ( $this->notices === array() ) {
350
- return; }
351
-
352
  // register Black Friday 2018 deals
353
  /*if( time() > 1542931200 &&
354
  time() <= 1543320000 && Advanced_Ads_Admin::get_instance()->screen_belongs_to_advanced_ads() ){
@@ -363,60 +370,60 @@ class Advanced_Ads_Admin_Notices {
363
  }
364
  }*/
365
 
366
- // load notices
367
  include ADVADS_BASE_PATH . '/admin/includes/notices.php';
368
 
369
- // iterate through notices
370
  $count = 0;
371
  foreach ( $this->notices as $_notice ) {
372
 
373
- if ( isset($advanced_ads_admin_notices[$_notice]) ) {
374
- $notice = $advanced_ads_admin_notices[$_notice];
375
- $text = $advanced_ads_admin_notices[$_notice]['text'];
376
- $type = isset($advanced_ads_admin_notices[$_notice]['type']) ? $advanced_ads_admin_notices[$_notice]['type'] : '';
377
  } else {
378
  continue;
379
  }
380
-
381
- // don’t display non-global notices on other than plugin related pages
382
- if( ( ! isset( $advanced_ads_admin_notices[$_notice]['global'] ) || ! $advanced_ads_admin_notices[$_notice]['global'] )
383
- && ! Advanced_Ads_Admin::screen_belongs_to_advanced_ads() ) {
 
 
 
 
 
384
  continue;
385
  }
386
-
387
- // don't display license nag if ADVANCED_ADS_SUPPRESS_PLUGIN_ERROR_NOTICES is defined
388
- if( defined( 'ADVANCED_ADS_SUPPRESS_PLUGIN_ERROR_NOTICES' ) && $advanced_ads_admin_notices[$_notice]['type'] == 'plugin_error' ) {
389
- continue;
390
- }
391
 
392
  switch ( $type ) {
393
- case 'info' :
394
  include ADVADS_BASE_PATH . '/admin/views/notices/info.php';
395
- break;
396
- case 'subscribe' :
397
  include ADVADS_BASE_PATH . '/admin/views/notices/subscribe.php';
398
- break;
399
- case 'plugin_error' :
400
  include ADVADS_BASE_PATH . '/admin/views/notices/plugin_error.php';
401
- break;
402
- default :
403
  include ADVADS_BASE_PATH . '/admin/views/notices/error.php';
404
  }
405
 
406
- if( ++$count == self::MAX_NOTICES ) {
407
- break;
408
  }
409
  }
410
  }
411
 
412
  /**
413
- * return notices options
414
  *
415
- * @since 1.5.3
416
  * @return array $options
 
417
  */
418
  public function options() {
419
- if ( ! isset($this->options) ) {
420
  $this->options = get_option( ADVADS_SLUG . '-notices', array() );
421
  }
422
 
@@ -424,14 +431,15 @@ class Advanced_Ads_Admin_Notices {
424
  }
425
 
426
  /**
427
- * update notices options
 
 
428
  *
429
  * @since 1.5.3
430
- * @param array $options new options
431
  */
432
- public function update_options(array $options) {
433
- // do not allow to clear options
434
- if ( $options === array() ) {
435
  return;
436
  }
437
 
@@ -440,147 +448,149 @@ class Advanced_Ads_Admin_Notices {
440
  }
441
 
442
  /**
443
- * subscribe to newsletter and autoresponder
444
  *
 
 
 
445
  * @since 1.5.3
446
- * @param string $notice slug of the subscription notice to send the correct reply
447
  */
448
- public function subscribe($notice) {
449
  if ( ! isset( $notice ) ) {
450
- return;
451
  }
452
 
453
  global $current_user;
454
  $user = wp_get_current_user();
455
 
456
- if ( $user->user_email == '' ) {
 
457
  return sprintf( __( 'You don’t seem to have an email address. Please use <a href="%s" target="_blank">this form</a> to sign up.', 'advanced-ads' ), 'http://eepurl.com/bk4z4P' );
458
  }
459
 
460
  $data = array(
461
- 'email' => $user->user_email,
462
- 'notice' => $notice
463
  );
464
 
465
- $result = wp_remote_post('https://wpadvancedads.com/remote/subscribe.php?source=plugin', array(
466
- 'method' => 'POST',
467
- 'timeout' => 20,
468
- 'redirection' => 5,
469
- 'httpversion' => '1.1',
470
- 'blocking' => true,
471
- 'body' => $data)
 
472
  );
473
 
474
  if ( is_wp_error( $result ) ) {
475
  return __( 'How embarrassing. The email server seems to be down. Please try again later.', 'advanced-ads' );
476
  } else {
477
- // mark as subscribed and move notice from quere
478
  $this->mark_as_subscribed();
479
  $this->remove_from_queue( $notice );
480
- return sprintf(__( 'Please check your email (%s) for the confirmation message. If you didn’t receive one or want to use another email address then please use <a href="%s" target="_blank">this form</a> to sign up.', 'advanced-ads' ), $user->user_email, 'http://eepurl.com/bk4z4P' );
 
 
481
  }
482
  }
483
 
484
  /**
485
- * check if blog is subscribed to the newsletter
486
  */
487
  public function is_subscribed() {
488
 
489
- /**
490
- * respect previous settings
491
- */
492
  $options = $this->options();
493
- if ( isset($options['is_subscribed'] ) ) {
494
- return true;
495
  }
496
 
497
  $user_id = get_current_user_id();
498
- if( ! $user_id ) {
499
- return true;
500
  }
501
 
502
- $subscribed = get_user_meta($user_id, 'advanced-ads-subscribed', true);
 
503
  return $subscribed;
504
  }
505
-
506
  /**
507
- * check if a usesr can be subscribed to our newsletter
508
  * check if is already subscribed or email is invalid
509
- *
510
  * @return bool true if user can subscribe
511
  */
512
- public function user_can_subscribe( ){
513
-
514
- /**
515
- * respect previous settings
516
- */
517
  $options = $this->options();
518
- if ( isset($options['is_subscribed'] ) ) {
519
- return true;
520
  }
521
 
522
  $current_user = wp_get_current_user();
523
-
524
- if( empty( $current_user->ID ) || empty( $current_user->user_email ) ) {
525
- return false;
526
  }
527
 
528
- $subscribed = get_user_meta( $current_user->ID, 'advanced-ads-subscribed', true);
529
-
530
- // secureserver.net email address belong to GoDaddy (?) and have very, very low open rates. Seems like only temporary setup
531
- return ( ! $subscribed
532
- && is_email( $current_user->user_email )
533
- && false === strpos( $current_user->user_email, 'secureserver.net' ) )
534
  ? true : false;
535
-
536
  }
537
 
538
  /**
539
- * update information that the current user is subscribed
540
  */
541
  private function mark_as_subscribed() {
542
 
543
  $user_id = get_current_user_id();
544
 
545
- if( ! $this->is_subscribed() ) {
546
- update_user_meta( $user_id, 'advanced-ads-subscribed', true);
547
  }
548
  }
549
 
550
  /**
551
- * add AdSense tutorial notice
552
  *
553
- * @param obj $ad ad object
554
- * @param arr $types ad types
555
  */
556
- public function adsense_tutorial( $ad, $types = array() ){
557
 
558
- $options = $this->options();
559
- $_notice = 'nl_adsense';
560
 
561
- if ( $ad->type !== 'adsense' || isset($options['closed'][ $_notice ] ) ) {
562
- return;
563
- }
564
 
565
- include ADVADS_BASE_PATH . '/admin/includes/notices.php';
566
 
567
- if ( ! isset( $advanced_ads_admin_notices[ $_notice ] ) ) {
568
- return;
569
- }
570
 
571
- $notice = $advanced_ads_admin_notices[ $_notice ];
572
- $text = $notice['text'];
573
- include ADVADS_BASE_PATH . '/admin/views/notices/inline.php';
574
  }
575
-
576
  /**
577
- * create the content of a welcome panel like WordPress core does
578
  */
579
- public function get_welcome_panel(){
580
-
581
- ob_start();
582
- include ADVADS_BASE_PATH . '/admin/views/notices/welcome-panel.php';
583
- return ob_get_clean();
584
-
 
585
  }
586
  }
1
  <?php
2
 
3
  /**
4
+ * Container class for admin notices
5
  *
6
  * @package WordPress
7
  * @subpackage Advanced Ads Plugin
10
  class Advanced_Ads_Admin_Notices {
11
 
12
  /**
13
+ * Maximum number of notices to show at once
14
  */
15
+ const MAX_NOTICES = 2;
16
 
17
  /**
18
+ * Instance of this class
19
  *
20
  * @since 1.5.3
21
  * @var object
23
  protected static $instance = null;
24
 
25
  /**
26
+ * Options
27
  *
28
+ * @since 1.5.3
29
+ * @var array
30
  */
31
  protected $options;
32
 
33
  /**
34
+ * Notices to be displayed
35
  *
36
+ * @since 1.5.3
37
+ * @var array
38
  */
39
  public $notices = array();
40
 
41
  /**
42
+ * Plugin class
43
+ *
44
+ * @var Advanced_Ads_Plugin
45
  */
46
  private $plugin;
47
 
48
+ /**
49
+ * Advanced_Ads_Admin_Notices constructor to load notices
50
+ */
51
  public function __construct() {
52
  $this->plugin = Advanced_Ads_Plugin::get_instance();
53
+ // load notices.
54
  $this->load_notices();
 
 
55
 
56
  add_action( 'advanced-ads-ad-params-before', array( $this, 'adsense_tutorial' ), 10, 2 );
57
  }
59
  /**
60
  * Return an instance of this class.
61
  *
 
62
  * @return object A single instance of this class.
63
+ * @since 1.5.3
64
  */
65
  public static function get_instance() {
66
 
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
+ * Load admin notices
77
  *
78
  * @since 1.4.5
79
  * @updated 1.5.3 moved from admin class here
80
  */
81
  public function load_notices() {
82
 
83
+ $options = $this->options();
84
  $plugin_options = $this->plugin->options();
85
 
86
+ // load notices from queue.
87
+ $this->notices = isset( $options['queue'] ) ? $options['queue'] : array();
88
  $notices_before = $this->notices;
89
 
90
+ // check license notices.
91
  $this->register_license_notices();
92
 
93
+ // don’t check non-critical notices if they are disabled.
94
+ if ( ! isset( $plugin_options['disable-notices'] ) ) {
95
+ // handle version notices.
96
  $this->register_version_notices();
97
+ // check other notices.
98
  $this->check_notices();
99
  }
100
 
101
+ // register notices in db so they get displayed until closed for good.
102
  if ( $this->notices !== $notices_before ) {
103
  $this->add_to_queue( $this->notices );
104
  }
105
  }
106
 
107
  /**
108
+ * Register update notices
109
  *
110
+ * @deprecated since we don’t have any update notices and this logic didn’t work reliably in the past, probably because it was disabled for AJAX calls.
111
  */
112
  public function register_version_notices() {
113
  if ( defined( 'DOING_AJAX' ) ) {
115
  }
116
 
117
  $internal_options = $this->plugin->internal_options();
118
+ $plugin_options = $this->plugin->options();
119
 
120
+ // set an artificial older version for updates on installed plugins before the notice logic was invented.
121
+ if ( ! isset( $internal_options['version'] ) && array() !== $plugin_options ) {
122
  $old_version = '1.4.4';
123
+ } elseif ( isset( $internal_options['version'] ) ) {
124
  $old_version = $internal_options['version'];
125
  } else {
126
+ // empty version for new installations.
127
  $old_version = 0;
128
  }
129
  }
130
+
131
  /**
132
+ * Update version number to latest one
133
  */
134
+ public function update_version_number() {
135
+
136
+ $internal_options = $this->plugin->internal_options();
137
+ $new_options = $internal_options; // in case we udpate options here.
138
+
139
+ $new_options['version'] = ADVADS_VERSION;
140
+
141
+ // update version numbers.
142
+ if ( $internal_options !== $new_options ) {
143
+ $this->plugin->update_internal_options( $new_options );
144
+ }
145
  }
146
 
147
  /**
148
+ * Check various notices conditions
149
  */
150
  public function check_notices() {
151
  $internal_options = $this->plugin->internal_options();
152
+ $now = time();
153
+ $activation = ( isset( $internal_options['installed'] ) ) ? $internal_options['installed'] : $now; // activation time.
154
 
155
  $options = $this->options();
156
+ $closed = isset( $options['closed'] ) ? $options['closed'] : array();
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.
173
+ if ( Advanced_Ads::get_number_of_ads() ) {
174
  $this->notices[] = 'nl_free_addons';
175
  }
176
  }
177
  $number_of_ads = 0;
178
+ // needed error handling due to a weird bug in the piklist plugin.
179
  try {
180
+ $number_of_ads = Advanced_Ads::get_number_of_ads();
181
  } catch ( Exception $e ) {
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'] )
188
+ && ( ! isset( $paused['review'] ) || $paused['review'] <= time() )
189
+ && 172800 < ( time() - $activation )
190
+ && 3 <= $number_of_ads
191
+ ) {
192
+ $this->notices[] = 'review';
193
+ } elseif ( in_array( 'review', $queue, true ) && 3 > $number_of_ads ) {
194
+ $review_key = array_search( 'review', $this->notices, true );
195
+ if ( false !== $review_key ) {
196
+ unset( $this->notices[ $review_key ] );
197
+ }
198
  }
199
  }
200
 
201
  /**
202
+ * Register license key notices
203
  */
204
+ public function register_license_notices() {
205
 
206
+ if ( ! Advanced_Ads_Admin::screen_belongs_to_advanced_ads() ) {
207
+ return;
208
  }
209
 
210
  $options = $this->options();
211
+ $queue = isset( $options['queue'] ) ? $options['queue'] : array();
212
+ // check license keys.
213
+
214
+ if ( Advanced_Ads_Checks::licenses_invalid() ) {
215
+ if ( ! in_array( 'license_invalid', $queue, true ) ) {
216
+ $this->notices[] = 'license_invalid';
217
+ }
218
  } else {
219
+ $this->remove_from_queue( 'license_invalid' );
220
  }
221
  }
222
 
223
  /**
224
+ * Add update notices to the queue of all notices that still needs to be closed
225
+ *
226
+ * @param mixed $notices one or more notices to be added to the queue.
227
  *
228
  * @since 1.5.3
 
229
  */
230
+ public function add_to_queue( $notices = 0 ) {
231
  if ( ! $notices ) {
232
  return;
233
  }
234
 
235
+ // get queue from options.
236
  $options = $this->options();
237
+ $queue = isset( $options['queue'] ) ? $options['queue'] : array();
238
 
239
  if ( is_array( $notices ) ) {
240
  $queue = array_merge( $queue, $notices );
242
  $queue[] = $notices;
243
  }
244
 
245
+ // remove possible duplicated.
246
  $queue = array_unique( $queue );
247
 
248
+ // update db.
249
  $options['queue'] = $queue;
250
  $this->update_options( $options );
251
  }
252
 
253
  /**
254
+ * Remove update notice from queue
255
  * move notice into "closed"
256
  *
257
+ * @param string $notice notice to be removed from the queue.
258
+ *
259
  * @since 1.5.3
 
260
  */
261
+ public function remove_from_queue( $notice ) {
262
+ if ( ! isset( $notice ) ) {
263
  return;
264
  }
265
 
266
+ // get queue from options.
267
  $options_before = $options = $this->options();
268
+ if ( ! isset( $options['queue'] ) ) {
269
  return;
270
  }
271
+ $queue = (array) $options['queue'];
272
+ $closed = isset( $options['closed'] ) ? $options['closed'] : array();
273
+ $paused = isset( $options['paused'] ) ? $options['paused'] : array();
274
 
275
+ $key = array_search( $notice, $queue, true );
276
+ if ( false !== $key ) {
277
+ unset( $queue[ $key ] );
278
+ // close message with timestamp.
279
  }
280
+ // don’t close again twice.
281
+ if ( ! isset( $closed[ $notice ] ) ) {
282
+ $closed[ $notice ] = time();
283
  }
284
+ // remove from pause.
285
+ if ( isset( $paused[ $notice ] ) ) {
286
+ unset( $paused[ $notice ] );
287
  }
288
+
289
+ // update db.
290
+ $options['queue'] = $queue;
291
  $options['closed'] = $closed;
292
  $options['paused'] = $paused;
293
+
294
+
295
+ // only update if changed.
296
+ if ( $options_before !== $options ) {
297
+ $this->update_options( $options );
298
+ // update already registered notices.
299
+ $this->load_notices();
300
  }
301
  }
302
+
303
  /**
304
+ * Hide any notice for a given time
305
  * move notice into "paused" with notice as key and timestamp as value
306
  *
307
+ * @param string $notice notice to be paused.
308
+ *
309
  * @since 1.8-17
 
310
  */
311
+ public function hide_notice( $notice ) {
312
+ if ( ! isset( $notice ) ) {
313
  return;
314
  }
315
 
316
+ // get queue from options.
317
  $options_before = $options = $this->options();
318
+ if ( ! isset( $options['queue'] ) ) {
319
  return;
320
  }
321
+ $queue = (array) $options['queue'];
322
+ $paused = isset( $options['paused'] ) ? $options['paused'] : array();
323
 
324
+ $key = array_search( $notice, $queue, true );
325
+ if ( false !== $key ) {
326
+ unset( $queue[ $key ] );
327
  }
328
  // close message with timestamp in 7 days
329
+ // don’t close again twice.
330
+ if ( ! isset( $paused[ $notice ] ) ) {
331
+ $paused[ $notice ] = time() + WEEK_IN_SECONDS;
332
  }
333
+
334
+ // update db.
335
+ $options['queue'] = $queue;
336
  $options['paused'] = $paused;
337
+
338
+ // only update if changed.
339
+ if ( $options_before !== $options ) {
340
+ $this->update_options( $options );
341
+ // update already registered notices.
342
+ $this->load_notices();
343
  }
344
  }
345
 
346
  /**
347
+ * Display notices
 
 
348
  */
349
  public function display_notices() {
350
 
351
  if ( defined( 'DOING_AJAX' ) ) {
352
+ return;
353
+ }
354
+
355
+ if ( array() === $this->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() ){
370
  }
371
  }*/
372
 
373
+ // load notices.
374
  include ADVADS_BASE_PATH . '/admin/includes/notices.php';
375
 
376
+ // iterate through notices.
377
  $count = 0;
378
  foreach ( $this->notices as $_notice ) {
379
 
380
+ if ( isset( $advanced_ads_admin_notices[ $_notice ] ) ) {
381
+ $notice = $advanced_ads_admin_notices[ $_notice ];
382
+ $text = $advanced_ads_admin_notices[ $_notice ]['text'];
383
+ $type = isset( $advanced_ads_admin_notices[ $_notice ]['type'] ) ? $advanced_ads_admin_notices[ $_notice ]['type'] : '';
384
  } else {
385
  continue;
386
  }
387
+
388
+ // don’t display non-global notices on other than plugin related pages.
389
+ if ( ( ! isset( $advanced_ads_admin_notices[ $_notice ]['global'] ) || ! $advanced_ads_admin_notices[ $_notice ]['global'] )
390
+ && ! Advanced_Ads_Admin::screen_belongs_to_advanced_ads() ) {
391
+ continue;
392
+ }
393
+
394
+ // don't display license nag if ADVANCED_ADS_SUPPRESS_PLUGIN_ERROR_NOTICES is defined.
395
+ if ( defined( 'ADVANCED_ADS_SUPPRESS_PLUGIN_ERROR_NOTICES' ) && 'plugin_error' === $advanced_ads_admin_notices[ $_notice ]['type'] ) {
396
  continue;
397
  }
 
 
 
 
 
398
 
399
  switch ( $type ) {
400
+ case 'info':
401
  include ADVADS_BASE_PATH . '/admin/views/notices/info.php';
402
+ break;
403
+ case 'subscribe':
404
  include ADVADS_BASE_PATH . '/admin/views/notices/subscribe.php';
405
+ break;
406
+ case 'plugin_error':
407
  include ADVADS_BASE_PATH . '/admin/views/notices/plugin_error.php';
408
+ break;
409
+ default:
410
  include ADVADS_BASE_PATH . '/admin/views/notices/error.php';
411
  }
412
 
413
+ if ( ++ $count === self::MAX_NOTICES ) {
414
+ break;
415
  }
416
  }
417
  }
418
 
419
  /**
420
+ * Return notices options
421
  *
 
422
  * @return array $options
423
+ * @since 1.5.3
424
  */
425
  public function options() {
426
+ if ( ! isset( $this->options ) ) {
427
  $this->options = get_option( ADVADS_SLUG . '-notices', array() );
428
  }
429
 
431
  }
432
 
433
  /**
434
+ * Update notices options
435
+ *
436
+ * @param array $options new options.
437
  *
438
  * @since 1.5.3
 
439
  */
440
+ public function update_options( array $options ) {
441
+ // do not allow to clear options.
442
+ if ( array() === $options ) {
443
  return;
444
  }
445
 
448
  }
449
 
450
  /**
451
+ * Subscribe to newsletter and autoresponder
452
  *
453
+ * @param string $notice slug of the subscription notice to send the correct reply.
454
+ *
455
+ * @return string
456
  * @since 1.5.3
 
457
  */
458
+ public function subscribe( $notice ) {
459
  if ( ! isset( $notice ) ) {
460
+ return '';
461
  }
462
 
463
  global $current_user;
464
  $user = wp_get_current_user();
465
 
466
+ if ( '' === $user->user_email ) {
467
+ // translators: %s is a URL.
468
  return sprintf( __( 'You don’t seem to have an email address. Please use <a href="%s" target="_blank">this form</a> to sign up.', 'advanced-ads' ), 'http://eepurl.com/bk4z4P' );
469
  }
470
 
471
  $data = array(
472
+ 'email' => $user->user_email,
473
+ 'notice' => $notice,
474
  );
475
 
476
+ $result = wp_remote_post( 'https://wpadvancedads.com/remote/subscribe.php?source=plugin', array(
477
+ 'method' => 'POST',
478
+ 'timeout' => 20,
479
+ 'redirection' => 5,
480
+ 'httpversion' => '1.1',
481
+ 'blocking' => true,
482
+ 'body' => $data,
483
+ )
484
  );
485
 
486
  if ( is_wp_error( $result ) ) {
487
  return __( 'How embarrassing. The email server seems to be down. Please try again later.', 'advanced-ads' );
488
  } else {
489
+ // mark as subscribed and move notice from quere.
490
  $this->mark_as_subscribed();
491
  $this->remove_from_queue( $notice );
492
+
493
+ // translators: the first %s is an email address, the seconds %s is a URL.
494
+ return sprintf( __( 'Please check your email (%s) for the confirmation message. If you didn’t receive one or want to use another email address then please use <a href="%s" target="_blank">this form</a> to sign up.', 'advanced-ads' ), $user->user_email, 'http://eepurl.com/bk4z4P' );
495
  }
496
  }
497
 
498
  /**
499
+ * Check if blog is subscribed to the newsletter
500
  */
501
  public function is_subscribed() {
502
 
503
+ // respect previous settings.
 
 
504
  $options = $this->options();
505
+ if ( isset( $options['is_subscribed'] ) ) {
506
+ return true;
507
  }
508
 
509
  $user_id = get_current_user_id();
510
+ if ( ! $user_id ) {
511
+ return true;
512
  }
513
 
514
+ $subscribed = get_user_meta( $user_id, 'advanced-ads-subscribed', true );
515
+
516
  return $subscribed;
517
  }
518
+
519
  /**
520
+ * Check if a usesr can be subscribed to our newsletter
521
  * check if is already subscribed or email is invalid
522
+ *
523
  * @return bool true if user can subscribe
524
  */
525
+ public function user_can_subscribe() {
526
+
527
+ // respect previous settings.
 
 
528
  $options = $this->options();
529
+ if ( isset( $options['is_subscribed'] ) ) {
530
+ return true;
531
  }
532
 
533
  $current_user = wp_get_current_user();
534
+
535
+ if ( empty( $current_user->ID ) || empty( $current_user->user_email ) ) {
536
+ return false;
537
  }
538
 
539
+ $subscribed = get_user_meta( $current_user->ID, 'advanced-ads-subscribed', true );
540
+
541
+ // secureserver.net email address belong to GoDaddy (?) and have very, very low open rates. Seems like only temporary setup.
542
+ return ( ! $subscribed && is_email( $current_user->user_email ) && false === strpos( $current_user->user_email, 'secureserver.net' ) )
 
 
543
  ? true : false;
544
+
545
  }
546
 
547
  /**
548
+ * Update information that the current user is subscribed
549
  */
550
  private function mark_as_subscribed() {
551
 
552
  $user_id = get_current_user_id();
553
 
554
+ if ( ! $this->is_subscribed() ) {
555
+ update_user_meta( $user_id, 'advanced-ads-subscribed', true );
556
  }
557
  }
558
 
559
  /**
560
+ * Add AdSense tutorial notice
561
  *
562
+ * @param Advanced_Ads_Ad $ad ad object.
563
+ * @param array $types ad types.
564
  */
565
+ public function adsense_tutorial( $ad, $types = array() ) {
566
 
567
+ $options = $this->options();
568
+ $_notice = 'nl_adsense';
569
 
570
+ if ( 'adsense' !== $ad->type || isset( $options['closed'][ $_notice ] ) ) {
571
+ return;
572
+ }
573
 
574
+ include ADVADS_BASE_PATH . '/admin/includes/notices.php';
575
 
576
+ if ( ! isset( $advanced_ads_admin_notices[ $_notice ] ) ) {
577
+ return;
578
+ }
579
 
580
+ $notice = $advanced_ads_admin_notices[ $_notice ];
581
+ $text = $notice['text'];
582
+ include ADVADS_BASE_PATH . '/admin/views/notices/inline.php';
583
  }
584
+
585
  /**
586
+ * Create the content of a welcome panel like WordPress core does
587
  */
588
+ public function get_welcome_panel() {
589
+
590
+ ob_start();
591
+ include ADVADS_BASE_PATH . '/admin/views/notices/welcome-panel.php';
592
+
593
+ return ob_get_clean();
594
+
595
  }
596
  }
admin/views/placement-form.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <form method="POST" action="" onsubmit="return advads_validate_placement_form();" class="advads-placements-new-form" id="advads-placements-new-form"
2
+ <?php
3
+ if ( isset( $placements ) && count( $placements ) ) {
4
+ echo ' style="display: none;"';
5
+ }
6
+ ?>
7
+ >
8
+ <h3>1. <?php _e( 'Choose a placement type', 'advanced-ads' ); ?></h3>
9
+ <p class="description"><?php printf( __( 'Placement types define where the ad is going to be displayed. Learn more about the different types from the <a href="%s">manual</a>', 'advanced-ads' ), ADVADS_URL . 'manual/placements/#utm_source=advanced-ads&utm_medium=link&utm_campaign=placements' ); ?></p>
10
+ <div class="advads-new-placement-types advads-buttonset">
11
+ <?php
12
+ if ( is_array( $placement_types ) ) {
13
+ foreach ( $placement_types as $_key => $_place ) :
14
+ if ( isset( $_place['image'] ) ) :
15
+ $image = '<img src="' . $_place['image'] . '" alt="' . $_place['title'] . '"/>';
16
+ else :
17
+ $image = '<strong>' . $_place['title'] . '</strong><br/><p class="description">' . $_place['description'] . '</p>';
18
+ endif;
19
+ ?>
20
+ <div class="advads-placement-type"><label
21
+ for="advads-placement-type-<?php echo $_key; ?>"><?php echo $image; ?></label>
22
+ <input type="radio" id="advads-placement-type-<?php echo $_key; ?>" name="advads[placement][type]"
23
+ value="<?php echo $_key; ?>"/>
24
+ <p class="advads-placement-description">
25
+ <strong><?php echo $_place['title']; ?></strong><br/><?php echo $_place['description']; ?></p>
26
+ </div>
27
+ <?php
28
+ endforeach;
29
+ };
30
+ ?>
31
+ </div>
32
+ <div class="clear"></div>
33
+ <p class="advads-error-message advads-placement-type-error"><?php _e( 'Please select a placement type.', 'advanced-ads' ); ?></p>
34
+ <br/>
35
+ <h3>2. <?php _e( 'Choose a Name', 'advanced-ads' ); ?></h3>
36
+ <p class="description"><?php _e( 'The name of the placement is only visible to you. Tip: choose a descriptive one, e.g. <em>Below Post Headline</em>.', 'advanced-ads' ); ?></p>
37
+ <p><input name="advads[placement][name]" class="advads-new-placement-name" type="text" value=""
38
+ placeholder="<?php _e( 'Placement Name', 'advanced-ads' ); ?>"/></p>
39
+ <p class="advads-error-message advads-placement-name-error"><?php _e( 'Please enter a name for your placement.', 'advanced-ads' ); ?></p>
40
+ <h3>3. <?php _e( 'Choose the Ad or Group', 'advanced-ads' ); ?></h3>
41
+ <p class="description"><?php _e( 'The ad or group that should be displayed.', 'advanced-ads' ); ?></p>
42
+ <p><select name="advads[placement][item]">
43
+ <option value=""><?php _e( '--not selected--', 'advanced-ads' ); ?></option>
44
+ <?php if ( isset( $items['groups'] ) ) : ?>
45
+ <optgroup label="<?php _e( 'Ad Groups', 'advanced-ads' ); ?>">
46
+ <?php foreach ( $items['groups'] as $_item_id => $_item_title ) : ?>
47
+ <option value="<?php echo $_item_id; ?>"><?php echo $_item_title; ?></option>
48
+ <?php endforeach; ?>
49
+ </optgroup>
50
+ <?php endif; ?>
51
+ <?php if ( isset( $items['ads'] ) ) : ?>
52
+ <optgroup label="<?php _e( 'Ads', 'advanced-ads' ); ?>">
53
+ <?php foreach ( $items['ads'] as $_item_id => $_item_title ) : ?>
54
+ <option value="<?php echo $_item_id; ?>"><?php echo $_item_title; ?></option>
55
+ <?php endforeach; ?>
56
+ </optgroup>
57
+ <?php endif; ?>
58
+ </select></p>
59
+ <?php wp_nonce_field( 'advads-placement', 'advads_placement', true ); ?>
60
+ <input type="submit" class="button button-primary" value="<?php _e( 'Save New Placement', 'advanced-ads' ); ?>"/>
61
+ </form>
admin/views/placements.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /**
3
- * the view for the placements page
4
  */
5
  ?><div class="wrap">
6
  <?php
@@ -16,10 +16,20 @@ if ( isset( $_GET['message'] ) ) :
16
  endif;
17
  ?>
18
  <?php endif; ?>
19
- <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
 
 
 
 
 
 
20
  <p class="description"><?php _e( 'Placements are physically places in your theme and posts. You can use them if you plan to change ads and ad groups on the same place without the need to change your templates.', 'advanced-ads' ); ?></p>
21
  <p class="description"><?php printf( __( 'See also the manual for more information on <a href="%s">placements</a>.', 'advanced-ads' ), ADVADS_URL . 'manual/placements/#utm_source=advanced-ads&utm_medium=link&utm_campaign=placements' ); ?></p>
22
  <?php
 
 
 
 
23
  if ( isset( $placements ) && is_array( $placements ) && count( $placements ) ) :
24
  do_action( 'advanced-ads-placements-list-before', $placements );
25
  ?>
@@ -130,6 +140,11 @@ if ( isset( $placements ) && is_array( $placements ) && count( $placements ) ) :
130
  <p><span class="advads-error-message"><?php _e( 'Important Notice', 'advanced-ads' ); ?>: </span><?php _e( 'Your server is missing an extension. This might break the content injection.<br/>Ignore this warning if everything works fine or else ask your hosting provider to enable <em>mbstring</em>.', 'advanced-ads' ); ?></p>
131
  <?php
132
  endif;
 
 
 
 
 
133
  break;
134
  endswitch;
135
  do_action( 'advanced-ads-placement-options-after', $_placement_slug, $_placement );
@@ -196,7 +211,7 @@ if ( isset( $placements ) && is_array( $placements ) && count( $placements ) ) :
196
  <div class="tablenav bottom">
197
  <input type="submit" id="advads-save-placements-button" class="button button-primary" value="<?php _e( 'Save Placements', 'advanced-ads' ); ?>"/>
198
  <?php wp_nonce_field( 'advads-placement', 'advads_placement', true ); ?>
199
- <button type="button" title="<?php _e( 'Create a new placement', 'advanced-ads' ); ?>" class="button-secondary" onclick="advads_toggle('.advads-placements-new-form')">
200
  <?php
201
  _e( 'New Placement', 'advanced-ads' );
202
  ?>
@@ -209,62 +224,4 @@ if ( isset( $placements ) && is_array( $placements ) && count( $placements ) ) :
209
  do_action( 'advanced-ads-placements-list-after', $placements );
210
  endif;
211
 
212
- ?>
213
- <form method="POST" action="" onsubmit="return advads_validate_placement_form();" class="advads-placements-new-form"
214
- <?php
215
- if ( isset( $placements ) && count( $placements ) ) {
216
- echo ' style="display: none;"';
217
- }
218
- ?>
219
- >
220
- <h3>1. <?php _e( 'Choose a placement type', 'advanced-ads' ); ?></h3>
221
- <p class="description"><?php printf( __( 'Placement types define where the ad is going to be displayed. Learn more about the different types from the <a href="%s">manual</a>', 'advanced-ads' ), ADVADS_URL . 'manual/placements/#utm_source=advanced-ads&utm_medium=link&utm_campaign=placements' ); ?></p>
222
- <div class= "advads-new-placement-types advads-buttonset">
223
- <?php
224
- if ( is_array( $placement_types ) ) {
225
- foreach ( $placement_types as $_key => $_place ) :
226
- if ( isset( $_place['image'] ) ) :
227
- $image = '<img src="' . $_place['image'] . '" alt="' . $_place['title'] . '"/>';
228
- else :
229
- $image = '<strong>' . $_place['title'] . '</strong><br/><p class="description">' . $_place['description'] . '</p>';
230
- endif;
231
- ?>
232
- <div class="advads-placement-type"><label for="advads-placement-type-<?php echo $_key; ?>"><?php echo $image; ?></label>
233
- <input type="radio" id="advads-placement-type-<?php echo $_key; ?>" name="advads[placement][type]" value="<?php echo $_key; ?>"/>
234
- <p class="advads-placement-description"><strong><?php echo $_place['title']; ?></strong><br/><?php echo $_place['description']; ?></p>
235
- </div>
236
- <?php
237
- endforeach;
238
- };
239
- ?>
240
- </div>
241
- <div class="clear"></div>
242
- <p class="advads-error-message advads-placement-type-error"><?php _e( 'Please select a placement type.', 'advanced-ads' ); ?></p>
243
- <br/>
244
- <h3>2. <?php _e( 'Choose a Name', 'advanced-ads' ); ?></h3>
245
- <p class="description"><?php _e( 'The name of the placement is only visible to you. Tip: choose a descriptive one, e.g. <em>Below Post Headline</em>.', 'advanced-ads' ); ?></p>
246
- <p><input name="advads[placement][name]" class="advads-new-placement-name" type="text" value="" placeholder="<?php _e( 'Placement Name', 'advanced-ads' ); ?>"/></p>
247
- <p class="advads-error-message advads-placement-name-error"><?php _e( 'Please enter a name for your placement.', 'advanced-ads' ); ?></p>
248
- <h3>3. <?php _e( 'Choose the Ad or Group', 'advanced-ads' ); ?></h3>
249
- <p class="description"><?php _e( 'The ad or group that should be displayed.', 'advanced-ads' ); ?></p>
250
- <p><select name="advads[placement][item]">
251
- <option value=""><?php _e( '--not selected--', 'advanced-ads' ); ?></option>
252
- <?php if ( isset( $items['groups'] ) ) : ?>
253
- <optgroup label="<?php _e( 'Ad Groups', 'advanced-ads' ); ?>">
254
- <?php foreach ( $items['groups'] as $_item_id => $_item_title ) : ?>
255
- <option value="<?php echo $_item_id; ?>"><?php echo $_item_title; ?></option>
256
- <?php endforeach; ?>
257
- </optgroup>
258
- <?php endif; ?>
259
- <?php if ( isset( $items['ads'] ) ) : ?>
260
- <optgroup label="<?php _e( 'Ads', 'advanced-ads' ); ?>">
261
- <?php foreach ( $items['ads'] as $_item_id => $_item_title ) : ?>
262
- <option value="<?php echo $_item_id; ?>"><?php echo $_item_title; ?></option>
263
- <?php endforeach; ?>
264
- </optgroup>
265
- <?php endif; ?>
266
- </select></p>
267
- <?php wp_nonce_field( 'advads-placement', 'advads_placement', true ); ?>
268
- <input type="submit" class="button button-primary" value="<?php _e( 'Save New Placement', 'advanced-ads' ); ?>"/>
269
- </form>
270
- </div>
1
  <?php
2
  /**
3
+ * The view for the placements page
4
  */
5
  ?><div class="wrap">
6
  <?php
16
  endif;
17
  ?>
18
  <?php endif; ?>
19
+ <h1 class="wp-heading-inline"><?php echo esc_html( get_admin_page_title() ); ?></h1>
20
+ <a href="#" class="page-title-action" title="<?php _e( 'Create a new placement', 'advanced-ads' ); ?>" class="button-secondary" onclick="advads_toggle('.advads-placements-new-form'); advads_scroll_to_element('#advads-placements-new-form');"><?php
21
+ _e( 'New Placement', 'advanced-ads' );
22
+ ?></a>
23
+
24
+ <hr class="wp-header-end">
25
+
26
  <p class="description"><?php _e( 'Placements are physically places in your theme and posts. You can use them if you plan to change ads and ad groups on the same place without the need to change your templates.', 'advanced-ads' ); ?></p>
27
  <p class="description"><?php printf( __( 'See also the manual for more information on <a href="%s">placements</a>.', 'advanced-ads' ), ADVADS_URL . 'manual/placements/#utm_source=advanced-ads&utm_medium=link&utm_campaign=placements' ); ?></p>
28
  <?php
29
+
30
+ // add placement form.
31
+ include_once ADVADS_BASE_PATH . 'admin/views/placement-form.php';
32
+
33
  if ( isset( $placements ) && is_array( $placements ) && count( $placements ) ) :
34
  do_action( 'advanced-ads-placements-list-before', $placements );
35
  ?>
140
  <p><span class="advads-error-message"><?php _e( 'Important Notice', 'advanced-ads' ); ?>: </span><?php _e( 'Your server is missing an extension. This might break the content injection.<br/>Ignore this warning if everything works fine or else ask your hosting provider to enable <em>mbstring</em>.', 'advanced-ads' ); ?></p>
141
  <?php
142
  endif;
143
+ if ( ! extension_loaded( 'dom' ) ) :
144
+ ?>
145
+ <p><span class="advads-error-message"><?php _e( 'Important Notice', 'advanced-ads' ); ?>: </span><?php printf( __( 'Missing PHP extensions could cause issues. Please ask your hosting provider to enable them: %s', 'advanced-ads' ), 'dom (php_xml)' ); ?></p>
146
+ <?php
147
+ endif;
148
  break;
149
  endswitch;
150
  do_action( 'advanced-ads-placement-options-after', $_placement_slug, $_placement );
211
  <div class="tablenav bottom">
212
  <input type="submit" id="advads-save-placements-button" class="button button-primary" value="<?php _e( 'Save Placements', 'advanced-ads' ); ?>"/>
213
  <?php wp_nonce_field( 'advads-placement', 'advads_placement', true ); ?>
214
+ <button type="button" title="<?php _e( 'Create a new placement', 'advanced-ads' ); ?>" class="button-secondary" onclick="advads_toggle('.advads-placements-new-form'); advads_scroll_to_element('#advads-placements-new-form');">
215
  <?php
216
  _e( 'New Placement', 'advanced-ads' );
217
  ?>
224
  do_action( 'advanced-ads-placements-list-after', $placements );
225
  endif;
226
 
227
+ ?></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.10
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.10' );
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.14.11
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.14.11' );
43
 
44
  /*----------------------------------------------------------------------------*
45
  * Autoloading, modules and functions
classes/checks.php CHANGED
@@ -245,7 +245,7 @@ class Advanced_Ads_Checks {
245
  * check for required php extensions
246
  *
247
  * @since 1.8.21
248
- * @return bool
249
  */
250
  public static function php_extensions(){
251
 
@@ -255,8 +255,8 @@ class Advanced_Ads_Checks {
255
  $missing_extensions[] = 'dom';
256
  }
257
 
258
- if( !extension_loaded('xml') ){
259
- $missing_extensions[] = 'xml';
260
  }
261
 
262
  return $missing_extensions;
245
  * check for required php extensions
246
  *
247
  * @since 1.8.21
248
+ * @return array
249
  */
250
  public static function php_extensions(){
251
 
255
  $missing_extensions[] = 'dom';
256
  }
257
 
258
+ if ( ! extension_loaded( 'mbstring' ) ) {
259
+ $missing_extensions[] = 'mbstring';
260
  }
261
 
262
  return $missing_extensions;
classes/display-conditions.php CHANGED
@@ -483,6 +483,9 @@ class Advanced_Ads_Display_Conditions {
483
  'post__in' => $values,
484
  'posts_per_page' => -1,
485
  // 'ignore_sticky_posts' => 1,
 
 
 
486
  );
487
 
488
  $the_query = new WP_Query($args);
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);
modules/ad-blocker/classes/plugin.php CHANGED
@@ -33,7 +33,7 @@ class Advanced_Ads_Ad_Blocker
33
  $options['upload_dir']
34
  ) {
35
  $this->plugins_url = plugins_url();
36
- add_action( 'plugins_loaded', array( $this, 'wp_plugins_loaded' ) );
37
  }
38
  }
39
 
@@ -53,15 +53,6 @@ class Advanced_Ads_Ad_Blocker
53
  return self::$instance;
54
  }
55
 
56
- /**
57
- * Add actions/filters/hooks and localisation after module have been loaded
58
- *
59
- * @since 1.0.0
60
- */
61
- public function wp_plugins_loaded() {
62
- add_action( 'wp_enqueue_scripts', array( $this, 'edit_script_output' ), 101 );
63
- }
64
-
65
  /**
66
  * Edit the script output (URL's) for all advanced-ads plugins
67
  *
33
  $options['upload_dir']
34
  ) {
35
  $this->plugins_url = plugins_url();
36
+ add_action( 'wp_enqueue_scripts', array( $this, 'edit_script_output' ), 101 );
37
  }
38
  }
39
 
53
  return self::$instance;
54
  }
55
 
 
 
 
 
 
 
 
 
 
56
  /**
57
  * Edit the script output (URL's) for all advanced-ads plugins
58
  *
modules/ad-blocker/main.php CHANGED
@@ -1,24 +1,28 @@
1
  <?php
2
- if ( class_exists( 'Advanced_Ads', false ) ) {
3
 
4
- // only load if not already existing (maybe included from another plugin)
5
- if ( defined( 'ADVADS_AB_BASE_PATH' ) ) {
6
- return ;
7
- }
 
 
 
8
 
9
- // load basic path to the plugin
10
- define( 'ADVADS_AB_BASE_PATH', plugin_dir_path( __FILE__ ) );
11
- // general and global slug, e.g. to store options in WP, textdomain
12
- define( 'ADVADS_AB_SLUG', 'advanced-ads-ab-module' );
13
 
14
- Advanced_Ads_Ad_Blocker::get_instance();
15
 
16
- $is_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX;
17
 
18
- if ( is_admin() && ! $is_ajax ) {
19
- Advanced_Ads_Ad_Blocker_Admin::get_instance();
 
20
  }
21
  }
22
 
 
23
 
24
 
1
  <?php
 
2
 
3
+ function advanced_ads_load_adblocker() {
4
+ if ( class_exists( 'Advanced_Ads', false ) ) {
5
+
6
+ // only load if not already existing (maybe included from another plugin)
7
+ if ( defined( 'ADVADS_AB_BASE_PATH' ) ) {
8
+ return ;
9
+ }
10
 
11
+ // load basic path to the plugin
12
+ define( 'ADVADS_AB_BASE_PATH', plugin_dir_path( __FILE__ ) );
13
+ // general and global slug, e.g. to store options in WP, textdomain
14
+ define( 'ADVADS_AB_SLUG', 'advanced-ads-ab-module' );
15
 
16
+ Advanced_Ads_Ad_Blocker::get_instance();
17
 
18
+ $is_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX;
19
 
20
+ if ( is_admin() && ! $is_ajax ) {
21
+ Advanced_Ads_Ad_Blocker_Admin::get_instance();
22
+ }
23
  }
24
  }
25
 
26
+ add_action( 'advanced-ads-plugin-loaded', 'advanced_ads_load_adblocker' );
27
 
28
 
modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php CHANGED
@@ -19,7 +19,7 @@ class Advanced_Ads_Ads_Txt_Admin {
19
  $this->strategy = $strategy;
20
 
21
  add_filter( 'advanced-ads-sanitize-settings', array( $this, 'toggle' ), 10, 1 );
22
- add_action( 'update_option_advanced-ads-adsense', array( $this, 'update_adsense_option' ), 10, 2 );
23
  add_action( 'advanced-ads-settings-init', array( $this, 'add_settings' ) );
24
  add_action( self::ACTION, array( $this, 'ajax_refresh_notices' ) );
25
  }
@@ -55,11 +55,16 @@ class Advanced_Ads_Ads_Txt_Admin {
55
 
56
  /**
57
  * Update the 'ads.txt' file every time the AdSense settings are saved.
 
 
58
  *
59
  * @param array $prev Previous options.
60
  * @return array $new New options.
61
  */
62
- public function update_adsense_option( $prev, $new ) {
 
 
 
63
  $content = $this->get_adsense_blog_data( $new );
64
  $this->strategy->add_network_data( self::adsense, $content );
65
  $r = $this->strategy->save_options();
@@ -72,6 +77,7 @@ class Advanced_Ads_Ads_Txt_Admin {
72
  'error'
73
  );
74
  }
 
75
  }
76
 
77
  /**
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 );
23
  add_action( 'advanced-ads-settings-init', array( $this, 'add_settings' ) );
24
  add_action( self::ACTION, array( $this, 'ajax_refresh_notices' ) );
25
  }
55
 
56
  /**
57
  * Update the 'ads.txt' file every time the AdSense settings are saved.
58
+ * The reason for not using `update_option_*` filter is that the function
59
+ * should also get called for newly added AdSense options.
60
  *
61
  * @param array $prev Previous options.
62
  * @return array $new New options.
63
  */
64
+ public function update_adsense_option( $new, $prev ) {
65
+ if ( $new === $prev ) {
66
+ return $new;
67
+ }
68
  $content = $this->get_adsense_blog_data( $new );
69
  $this->strategy->add_network_data( self::adsense, $content );
70
  $r = $this->strategy->save_options();
77
  'error'
78
  );
79
  }
80
+ return $new;
81
  }
82
 
83
  /**
modules/privacy/admin/admin.php CHANGED
@@ -73,7 +73,7 @@ class Advanced_Ads_Privacy_Admin
73
  */
74
  public function settings_init($hook) {
75
 
76
- register_setting( ADVADS_PRIVACY_SLUG, Advanced_Ads_Privacy::OPTION_KEY );
77
 
78
  // add new section
79
  add_settings_section(
@@ -87,6 +87,18 @@ class Advanced_Ads_Privacy_Admin
87
  'consent-method', __('Consent method', 'advanced-ads'), array($this, 'render_settings_consent_method'), ADVADS_PRIVACY_SLUG . '-settings', ADVADS_PRIVACY_SLUG . '_settings_section'
88
  );
89
  }
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
 
92
  /**
73
  */
74
  public function settings_init($hook) {
75
 
76
+ register_setting( ADVADS_PRIVACY_SLUG, Advanced_Ads_Privacy::OPTION_KEY, array( $this, 'sanitize_settings' ) );
77
 
78
  // add new section
79
  add_settings_section(
87
  'consent-method', __('Consent method', 'advanced-ads'), array($this, 'render_settings_consent_method'), ADVADS_PRIVACY_SLUG . '-settings', ADVADS_PRIVACY_SLUG . '_settings_section'
88
  );
89
  }
90
+
91
+ /**
92
+ * Sanitize settings.
93
+ *
94
+ * @param array $options Privacy options.
95
+ * @return array $options Privacy options.
96
+ */
97
+ public function sanitize_settings( $options ) {
98
+ $options['custom-cookie-name'] = isset( $options['custom-cookie-name'] ) ? trim( $options['custom-cookie-name'] ) : '';
99
+ $options['custom-cookie-value'] = isset( $options['custom-cookie-value'] ) ? trim( $options['custom-cookie-value'] ) : '';
100
+ return $options;
101
+ }
102
 
103
 
104
  /**
readme.txt CHANGED
@@ -5,7 +5,7 @@ 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.10
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -303,12 +303,22 @@ Yes. Advanced Ads is based on WordPress standards and therefore easily customiza
303
 
304
  == Changelog ==
305
 
 
 
 
 
 
 
 
 
 
306
  = 1.14.10 =
307
 
308
  * creating unique slugs for the ad post type in order to prevent conflicts like found with Beaver Builder
309
  * added option to disable AdSense stats in the backend
310
  * fixed conflicts when $ (jQuery) was not available
311
  * fixed potential JS conflict in Wizard script
 
312
 
313
  = 1.14.9 =
314
 
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
 
303
 
304
  == Changelog ==
305
 
306
+ = 1.14.11 =
307
+
308
+ * moved placement form above the list of existing placements
309
+ * made "ads.txt" file available before the Settings page is saved
310
+ * removed leading and trailing spaces from privacy options to prevent accidental misconfiguration
311
+ * implementing coding standards in a few backend files
312
+ * fixed welcome panel not showing up
313
+ * fix for plugins using the "pre_option_upload_path" or "pre_option_upload_url_path" filters
314
+
315
  = 1.14.10 =
316
 
317
  * creating unique slugs for the ad post type in order to prevent conflicts like found with Beaver Builder
318
  * added option to disable AdSense stats in the backend
319
  * fixed conflicts when $ (jQuery) was not available
320
  * fixed potential JS conflict in Wizard script
321
+ * added a warning suggesting to install "dom" extension in order to use "Content" placement
322
 
323
  = 1.14.9 =
324