Advanced Ads - Version 1.14.7

Version Description

  • allow "Footer code" and "Sidebar Widget" placements on AMP pages created by the official AMP plugin
  • prevented AMP warnings on XMLRPC requests
  • removed unused debug function
  • made editing of AdSense ads possible in PHP < 5.5.10 (please note that Advanced Ads is recommended for PHP > 5.6)
Download this release

Release Info

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

Code changes from version 1.14.6 to 1.14.7

admin/includes/ad-health-notices.php CHANGED
@@ -36,17 +36,17 @@ $advanced_ads_ad_health_notices = apply_filters( 'advanced-ads-ad-health-notices
36
  ),
37
  // cache enabled, but not Advanced Ads Pro
38
  // checked using Advanced_Ads_Checks::cache() && ! defined( 'AAP_VERSION' ).
39
- 'cache_no_pro' => array(
40
  'text' => sprintf(
41
  // translators: %s is a target URL.
42
  __( 'Your <strong>website uses cache</strong>. Some dynamic features like ad rotation or visitor conditions might not work properly. Use the cache-busting feature of <a href="%s" target="_blank">Advanced Ads Pro</a> to load ads dynamically.', 'advanced-ads' ),
43
  ADVADS_URL . 'add-ons/advanced-ads-pro/#utm_source=advanced-ads&utm_medium=link&utm_campaign=error-cache'
44
  ),
45
  'type' => 'problem',
46
- ),
47
  // Autoptimize found, but no Advanced Ads Pro
48
  // Advanced_Ads_Checks::active_autoptimize() && ! defined( 'AAP_VERSION' ) ).
49
- // 1907: Autoptimize didn’t cause issues for a while. We are no longer showing the warning and might remove this if the plugin doesn’t cause problems anymore
50
  'autoptimize_no_pro' => array(
51
  'text' => sprintf(
52
  // translators: %s is a target URL.
@@ -200,7 +200,8 @@ $advanced_ads_ad_health_notices = apply_filters( 'advanced-ads-ad-health-notices
200
  admin_url( 'admin.php?page=advanced-ads-settings#general__advads-ads-txt' )
201
  ) . ' ' . Advanced_Ads_Ad_Health_Notices::get_adsense_error_link( 'ALERT_TYPE_ADS_TXT_UNAUTHORIZED' ),
202
  'type' => 'problem',
203
- ), // AdSense account alert. . Missing ads.txt – version 2.
 
204
  'adsense_alert_ADS_TXT_MISSING' => array(
205
  'text' => sprintf(
206
  __( 'One of your sites is missing the AdSense publisher ID in the ads.txt file.', 'advanced-ads' )
@@ -211,7 +212,7 @@ $advanced_ads_ad_health_notices = apply_filters( 'advanced-ads-ad-health-notices
211
  'type' => 'problem',
212
  ),
213
  // AdSense account alert. . Missing ads.txt – version 3.
214
- 'adsense_alert_ADS_TXT_ISSUES' => array(
215
  'text' => sprintf(
216
  __( 'One of your sites is missing the AdSense publisher ID in the ads.txt file.', 'advanced-ads' )
217
  . ' <a class="advads-settings-link" href="%s">'
@@ -294,7 +295,7 @@ $advanced_ads_ad_health_notices = apply_filters( 'advanced-ads-ad-health-notices
294
  // Notice about existing ads.txt plugins.
295
  // Advanced_Ads_Checks::ads_txt_plugins().
296
  'ads_txt_plugins_enabled' => array(
297
- 'text' => sprintf(
298
  __( 'Advanced Ads handles your ads.txt file automatically. You might be able to <strong>remove %1$s</strong>.', 'advanced-ads' ),
299
  implode( ', ', Advanced_Ads_Checks::ads_txt_plugins() )
300
  ),
@@ -304,8 +305,8 @@ $advanced_ads_ad_health_notices = apply_filters( 'advanced-ads-ad-health-notices
304
  ),
305
  // Notice about plugins that add header or footer code.
306
  // Advanced_Ads_Checks::header_footer_plugins().
307
- 'header_footer_plugins_enabled' => array(
308
- 'text' =>
309
  __( 'Advanced Ads handles header and footer codes.', 'advanced-ads' ) . '&nbsp;' .
310
  sprintf( __( 'You might be able to <strong>remove %1$s</strong>.', 'advanced-ads' ),
311
  implode( ', ', Advanced_Ads_Checks::header_footer_plugins() )
36
  ),
37
  // cache enabled, but not Advanced Ads Pro
38
  // checked using Advanced_Ads_Checks::cache() && ! defined( 'AAP_VERSION' ).
39
+ /*'cache_no_pro' => array(
40
  'text' => sprintf(
41
  // translators: %s is a target URL.
42
  __( 'Your <strong>website uses cache</strong>. Some dynamic features like ad rotation or visitor conditions might not work properly. Use the cache-busting feature of <a href="%s" target="_blank">Advanced Ads Pro</a> to load ads dynamically.', 'advanced-ads' ),
43
  ADVADS_URL . 'add-ons/advanced-ads-pro/#utm_source=advanced-ads&utm_medium=link&utm_campaign=error-cache'
44
  ),
45
  'type' => 'problem',
46
+ ),*/
47
  // Autoptimize found, but no Advanced Ads Pro
48
  // Advanced_Ads_Checks::active_autoptimize() && ! defined( 'AAP_VERSION' ) ).
49
+ // 1907: Autoptimize didn’t cause issues for a while. We are no longer showing the warning and might remove this if the plugin doesn’t cause problems anymore.
50
  'autoptimize_no_pro' => array(
51
  'text' => sprintf(
52
  // translators: %s is a target URL.
200
  admin_url( 'admin.php?page=advanced-ads-settings#general__advads-ads-txt' )
201
  ) . ' ' . Advanced_Ads_Ad_Health_Notices::get_adsense_error_link( 'ALERT_TYPE_ADS_TXT_UNAUTHORIZED' ),
202
  'type' => 'problem',
203
+ ),
204
+ // AdSense account alert. . Missing ads.txt – version 2.
205
  'adsense_alert_ADS_TXT_MISSING' => array(
206
  'text' => sprintf(
207
  __( 'One of your sites is missing the AdSense publisher ID in the ads.txt file.', 'advanced-ads' )
212
  'type' => 'problem',
213
  ),
214
  // AdSense account alert. . Missing ads.txt – version 3.
215
+ 'adsense_alert_ADS_TXT_ISSUES' => array(
216
  'text' => sprintf(
217
  __( 'One of your sites is missing the AdSense publisher ID in the ads.txt file.', 'advanced-ads' )
218
  . ' <a class="advads-settings-link" href="%s">'
295
  // Notice about existing ads.txt plugins.
296
  // Advanced_Ads_Checks::ads_txt_plugins().
297
  'ads_txt_plugins_enabled' => array(
298
+ 'text' => sprintf(
299
  __( 'Advanced Ads handles your ads.txt file automatically. You might be able to <strong>remove %1$s</strong>.', 'advanced-ads' ),
300
  implode( ', ', Advanced_Ads_Checks::ads_txt_plugins() )
301
  ),
305
  ),
306
  // Notice about plugins that add header or footer code.
307
  // Advanced_Ads_Checks::header_footer_plugins().
308
+ 'header_footer_plugins_enabled' => array(
309
+ 'text' =>
310
  __( 'Advanced Ads handles header and footer codes.', 'advanced-ads' ) . '&nbsp;' .
311
  sprintf( __( 'You might be able to <strong>remove %1$s</strong>.', 'advanced-ads' ),
312
  implode( ', ', Advanced_Ads_Checks::header_footer_plugins() )
admin/includes/class-ad-groups-list.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Groups List Table class.
4
  *
@@ -8,22 +9,26 @@
8
  class Advanced_Ads_Groups_List {
9
 
10
  /**
11
- * array with all groups
 
 
12
  */
13
  public $groups = array();
14
 
15
  /**
16
- * array with all ad group types
 
 
17
  */
18
  public $types = array();
19
 
20
  /**
21
- * construct the current list
22
  */
23
- public function __construct(){
24
 
25
- // set default vars
26
- $this->taxonomy = Advanced_Ads::AD_GROUP_TAXONOMY;
27
  $this->post_type = Advanced_Ads::POST_TYPE_SLUG;
28
 
29
  $this->load_groups();
@@ -32,34 +37,36 @@ class Advanced_Ads_Groups_List {
32
  }
33
 
34
  /**
35
- * load ad groups
36
  */
37
- public function load_groups(){
38
 
39
- // load all groups
40
- $search = ! empty($_REQUEST['s']) ? trim( wp_unslash( $_REQUEST['s'] ) ) : '';
41
 
42
  $args = array(
43
- 'taxonomy' => $this->taxonomy,
44
- 'search' => $search,
45
  'hide_empty' => 0,
46
  );
47
- // get wp term objects
48
  $terms = Advanced_Ads::get_ad_groups( $args );
49
 
50
- // add meta data to groups
51
  $this->groups = $this->load_groups_objects_from_terms( $terms );
52
  }
53
 
54
  /**
55
- * load ad groups objects from wp term objects
 
 
56
  *
57
- * @param arr $terms array of wp term objects
58
  */
59
- protected function load_groups_objects_from_terms(array $terms){
60
 
61
  $groups = array();
62
- foreach ( $terms as $_group ){
63
  $groups[] = new Advanced_Ads_Group( $_group );
64
  }
65
 
@@ -67,18 +74,18 @@ class Advanced_Ads_Groups_List {
67
  }
68
 
69
  /**
70
- * render group list header
71
  */
72
- public function render_header(){
73
  $file = ADVADS_BASE_PATH . 'admin/views/ad-group-list-header.php';
74
- require_once($file);
75
  }
76
 
77
  /**
78
  * render list rows
79
  */
80
- public function render_rows(){
81
- foreach ( $this->groups as $_group ){
82
  $this->render_row( $_group );
83
  $this->render_form_row( $_group );
84
  }
@@ -86,52 +93,52 @@ class Advanced_Ads_Groups_List {
86
 
87
 
88
  /**
89
- * render a single row
90
  *
91
- * @param obj $group the ad group object
92
  */
93
  public function render_row( Advanced_Ads_Group $group ) {
94
  $file = ADVADS_BASE_PATH . 'admin/views/ad-group-list-row.php';
95
- require($file);
96
  }
97
 
98
  /**
99
- * render the form row of a group
100
  *
101
- * @param obj $group the ad group object
102
  */
103
- public function render_form_row(Advanced_Ads_Group $group){
104
 
105
- // query ads
106
  $ads = $this->get_ads( $group );
107
 
108
- $weights = $group->get_ad_weights();
109
  $ad_form_rows = $weights;
110
  arsort( $ad_form_rows );
111
  $max_weight = Advanced_Ads_Group::get_max_ad_weight( $ads->post_count );
112
 
113
- // The Loop
114
  if ( $ads->post_count ) {
115
- foreach ( $ads->posts as $_ad ) {
116
- $row = '';
117
- $ad_id = $_ad->ID;
118
- $row .= '<tr data-ad-id="'. $ad_id . '" data-group-id="'. $group->id . '"><td>' . $_ad->post_title . '</td><td>';
119
- $row .= '<select name="advads-groups['. $group->id . '][ads]['.$_ad->ID.']">';
120
- $ad_weight = (isset($weights[$ad_id])) ? $weights[$ad_id] : Advanced_Ads_Group::MAX_AD_GROUP_DEFAULT_WEIGHT;
121
- for ( $i = 0; $i <= $max_weight; $i++ ) {
122
  $row .= '<option ' . selected( $ad_weight, $i, false ) . '>' . $i . '</option>';
123
  }
124
- $row .= '</select</td><td><button type="button" class="advads-remove-ad-from-group button">x</button></td></tr>';
125
- $ad_form_rows[$_ad->ID] = $row;
126
  }
127
  }
128
  $ad_form_rows = $this->remove_empty_weights( $ad_form_rows );
129
- // Restore original Post Data
130
  wp_reset_postdata();
131
 
132
  $ads_for_select = $this->ads_for_select();
133
  $new_ad_weights = '<select class="advads-group-add-ad-list-weights">';
134
- for ( $i = 0; $i <= $max_weight; $i++ ) {
135
  $new_ad_weights .= '<option ' . selected( 10, $i, false ) . '>' . $i . '</option>';
136
  }
137
  $new_ad_weights .= '</select>';
@@ -140,138 +147,157 @@ class Advanced_Ads_Groups_List {
140
  }
141
 
142
  /**
143
- * render the ads list
144
  *
145
- * @param $obj $group group object
146
  */
147
- public function render_ads_list(Advanced_Ads_Group $group){
148
 
149
  $ads = $this->get_ads( $group );
150
 
151
- $weights = $group->get_ad_weights();
152
  $weight_sum = array_sum( $weights );
153
  $ads_output = $weights;
154
  arsort( $ads_output );
155
 
156
- // The Loop
157
  if ( $ads->have_posts() ) {
158
- echo ($group->type == 'default' && $weight_sum) ? '<ul>' : '<ol>';
159
  while ( $ads->have_posts() ) {
160
  $ads->the_post();
161
  $line_output = '<li><a href="' . get_edit_post_link( get_the_ID() ) . '">' . get_the_title() . '</a>';
162
 
163
- $_weight = (isset($weights[get_the_ID()])) ? $weights[get_the_ID()] : Advanced_Ads_Group::MAX_AD_GROUP_DEFAULT_WEIGHT;
164
- if ( $group->type == 'default' && $weight_sum ) {
165
- $line_output .= '<span class="ad-weight" title="'.__( 'Ad weight', 'advanced-ads' ).'">' . number_format( ($_weight / $weight_sum) * 100 ) .'%</span>';
166
  }
167
 
168
- $ad = new Advanced_Ads_Ad( get_the_ID() );
169
- $expiry_date_format = get_option( 'date_format' ). ', ' . get_option( 'time_format' );
170
-
171
  $post_start = get_post_time( 'U', true, $ad->id );
172
-
173
  $tz_option = get_option( 'timezone_string' );
174
-
175
  if ( $post_start > time() ) {
 
176
  $line_output .= '<br />' . sprintf( __( 'starts %s', 'advanced-ads' ), get_date_from_gmt( date( 'Y-m-d H:i:s', $post_start ), $expiry_date_format ) );
177
  }
178
  if ( isset( $ad->expiry_date ) && $ad->expiry_date ) {
179
- $expiry = $ad->expiry_date;
180
- $expiry_date = date_create( '@' . $expiry );
181
-
182
-
183
- if ( $tz_option ) {
184
- $expiry_date->setTimezone( Advanced_Ads_Admin::get_wp_timezone() );
185
- } else {
186
- $tz_name = Advanced_Ads_Admin::timezone_get_name( Advanced_Ads_Admin::get_wp_timezone() );
187
- $tz_offset = substr( $tz_name, 3 );
188
- $off_time = date_create( '2017-09-21 T10:44:02' . $tz_offset );
189
  $offset_in_sec = date_offset_get( $off_time );
190
- $expiry_date = date_create( '@' . ( $expiry + $offset_in_sec ) );
191
- }
192
-
193
- $TZ = ' ( ' . Advanced_Ads_Admin::timezone_get_name( Advanced_Ads_Admin::get_wp_timezone() ) . ' )';
194
-
195
  if ( $expiry > time() ) {
196
- $line_output .= '<br />' . sprintf( __( 'expires %s', 'advanced-ads' ), $expiry_date->format( $expiry_date_format ) ) . $TZ;
 
197
  } elseif ( $expiry <= time() ) {
198
- $line_output .= '<br />' . sprintf( __( '<strong>expired</strong> %s', 'advanced-ads' ), $expiry_date->format( $expiry_date_format ) ) . $TZ;
 
199
  }
200
  }
201
  $line_output .= '</li>';
202
 
203
- $ads_output[get_the_ID()] = $line_output;
204
  }
205
 
206
  $ads_output = $this->remove_empty_weights( $ads_output );
207
 
208
  echo implode( '', $ads_output );
209
- echo ($group->type == 'default' && $weight_sum) ? '</ul>' : '</ol>';
210
-
211
- if( $ads->post_count > 4 ){
212
- $hidden_ads = $ads->post_count - 3;
213
- echo '<p><a href="javascript:void(0)" class="advads-group-ads-list-show-more">+ ' . sprintf(__( 'show %d more ads', 'advanced-ads' ), $hidden_ads ) . '</a></p>';
 
 
214
  }
215
-
216
- if ( $group->ad_count === 'all' ) {
217
- echo '<p>' . __( 'all published ads are displayed', 'advanced-ads' ) . '</p>';
218
  } elseif ( $group->ad_count > 1 ) {
219
- echo '<p>' . sprintf( __( 'up to %d ads displayed', 'advanced-ads' ), $group->ad_count ) . '</p>';
 
220
  }
221
  } else {
222
- _e( 'No ads assigned', 'advanced-ads' );
223
- ?><br/><a class="edit">+ <?php _e( 'Add some', 'advanced-ads' ); ?></a><?php
 
 
224
  }
225
- // Restore original Post Data
226
  wp_reset_postdata();
227
  }
228
 
229
  /**
230
- * remove entries from the ad weight array that are just id
 
 
231
  *
 
232
  * @since 1.5.1
233
- * @param arr $ads_output array with any output other that an integer
234
- * @return arr $ads_output array with ad output
235
  */
236
- private function remove_empty_weights(array $ads_output){
237
 
238
- foreach ( $ads_output as $key => $value ){
239
  if ( is_int( $value ) ) {
240
- unset($ads_output[$key]); }
 
241
  }
242
 
243
  return $ads_output;
244
  }
245
 
246
  /**
247
- * get ads for this group
 
 
248
  *
249
- * @param obj $group group object
250
- * @return obj $ads WP_Query result with ads for this group
251
  */
252
- public function get_ads($group){
253
  $args = array(
254
- 'post_type' => $this->post_type,
255
- 'post_status' => array('publish', 'pending', 'future', 'private'),
256
- 'taxonomy' => $group->taxonomy,
257
- 'term' => $group->slug,
258
- 'posts_per_page' => -1
259
  );
260
- return $ads = new WP_Query( $args );
 
 
 
261
  }
262
 
263
  /**
264
- * list of all ads to display in select dropdown
265
  *
266
  * @return array
267
  */
268
- public function ads_for_select(){
269
  $select = array();
270
- $model = Advanced_Ads::get_instance()->get_model();
271
 
272
- // load all ads
273
- $ads = $model->get_ads( array('orderby' => 'title', 'order' => 'ASC') );
274
- foreach ( $ads as $_ad ){
 
 
 
 
 
275
  $select[ $_ad->ID ] = esc_html( $_ad->post_title );
276
  }
277
 
@@ -279,51 +305,53 @@ class Advanced_Ads_Groups_List {
279
  }
280
 
281
  /**
282
- * return ad group types
283
  *
284
- * @return arr $types ad group information
285
  */
286
- public function get_ad_group_types(){
287
  $types = array(
288
  'default' => array(
289
- 'title' => __( 'Random ads', 'advanced-ads' ),
290
- 'description' => __( 'Display random ads based on ad weight', 'advanced-ads' )
291
  ),
292
  'ordered' => array(
293
- 'title' => __( 'Ordered ads', 'advanced-ads' ),
294
  'description' => __( 'Display ads with the highest ad weight first', 'advanced-ads' ),
295
- )
296
  );
297
 
298
  return apply_filters( 'advanced-ads-group-types', $types );
299
  }
300
 
301
  /**
302
- * render ad group action links
303
  *
304
- * @param $obj $group group object
305
  */
306
- public function render_action_links($group){
307
  global $tax;
308
 
309
  $tax = get_taxonomy( $this->taxonomy );
310
 
311
  $actions = array();
312
  if ( current_user_can( $tax->cap->edit_terms ) ) {
313
- $actions['edit'] = '<a class="edit">' . __( 'Edit', 'advanced-ads' ) . '</a>';
314
  $actions['usage'] = '<a class="usage">' . __( 'Usage', 'advanced-ads' ) . '</a>';
315
  }
316
 
317
- if ( current_user_can( $tax->cap->delete_terms ) ){
318
- $args = array(
319
- 'action' => 'delete',
320
- 'group_id' => $group->id
321
  );
322
- $delete_link = self::group_page_url( $args );
323
  $actions['delete'] = "<a class='delete-tag' href='" . wp_nonce_url( $delete_link, 'delete-tag_' . $group->id ) . "'>" . __( 'Delete', 'advanced-ads' ) . '</a>';
324
  }
325
 
326
- if ( ! count( $actions ) ) { return; }
 
 
327
 
328
  echo '<div class="row-actions">';
329
  foreach ( $actions as $action => $link ) {
@@ -331,48 +359,49 @@ class Advanced_Ads_Groups_List {
331
  }
332
  echo '</div>';
333
  }
334
-
335
  /**
336
- * create a new group
337
- *
338
  */
339
- public function create_group(){
340
- // check nonce
341
  if ( ! isset( $_POST['advads-group-add-nonce'] )
342
- || ! wp_verify_nonce( $_POST['advads-group-add-nonce'], 'add-advads-groups' ) ){
343
 
344
  return new WP_Error( 'invalid_ad_group', __( 'Invalid Ad Group', 'advanced-ads' ) );
345
  }
346
 
347
- // check user rights
348
- if( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads') ) ) {
349
  return new WP_Error( 'invalid_ad_group_rights', __( 'You don’t have permission to change the ad groups', 'advanced-ads' ) );
350
  }
351
 
352
- if ( isset($_POST['advads-group-name']) && '' !== $_POST['advads-group-name'] ){
353
 
354
- $title = sanitize_text_field( $_POST['advads-group-name'] );
355
  $new_group = wp_create_term( $title, Advanced_Ads::AD_GROUP_TAXONOMY );
356
-
357
- if( is_wp_error($new_group ) ){
358
  return $new_group;
359
  }
360
-
361
- // save default values
362
- if( is_array( $new_group ) ){
363
  $group = new Advanced_Ads_Group( $new_group['term_id'] );
364
-
365
- // allow other add-ons to save their own group attributes
366
  $atts = apply_filters( 'advanced-ads-group-save-atts', array(
367
- 'type' => 'default',
368
  'ad_count' => 1,
369
- 'options' => array(),
370
- ), $group);
 
 
371
 
372
  $group->save( $atts );
373
  }
374
-
375
- // reload groups
376
  $this->load_groups();
377
 
378
  } else {
@@ -382,148 +411,155 @@ class Advanced_Ads_Groups_List {
382
  return true;
383
  }
384
 
385
-
386
- private function get_groups_by_ad_id($ad_id){
387
- $ids = array();
388
- $terms = wp_get_object_terms($ad_id, $this->taxonomy);
389
- foreach ($terms as $term){
390
- $ids[] = $term->term_id;
391
- }
392
- return $ids;
393
- }
394
  /**
395
- * bulk update groups
 
 
396
  *
 
397
  */
398
- public function update_groups(){
399
- // check nonce
 
 
 
 
 
 
 
 
 
 
 
 
 
400
  if ( ! isset( $_POST['advads-group-update-nonce'] )
401
- || ! wp_verify_nonce( $_POST['advads-group-update-nonce'], 'update-advads-groups' ) ){
402
 
403
  return new WP_Error( 'invalid_ad_group', __( 'Invalid Ad Group', 'advanced-ads' ) );
404
  }
405
-
406
- // check user rights
407
- if( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads') ) ) {
408
  return new WP_Error( 'invalid_ad_group_rights', __( 'You don’t have permission to change the ad groups', 'advanced-ads' ) );
409
  }
410
 
411
- /** empty group settings
412
  * edit: emptying disabled, because when only a few groups are saved (e.g. when filtered by search), options are reset
413
  * todo: needs a solution that also removes options when the group is removed
414
  */
415
- // empty weights
416
  // update_option( 'advads-ad-weights', array() );
417
-
418
  $all_weights = get_option( 'advads-ad-weights', array() );
419
 
420
  // ad_id => group_ids
421
  $ad_groups_assoc = array();
422
 
423
- if ( isset( $_POST['advads-groups-removed-ads'] ) && is_array( $_POST['advads-groups-removed-ads'] ) && isset( $_POST['advads-groups-removed-ads-gid'])) {
424
- $len = count($_POST['advads-groups-removed-ads']);
425
- for ($i=0; $i<$len; $i++){
426
- $ad_id = $_POST['advads-groups-removed-ads'][$i];
427
- $group_id = $_POST['advads-groups-removed-ads-gid'][$i];
428
  $ad_groups_assoc[ $ad_id ] = array();
429
- // remove it from the weights
430
- if ( isset($all_weights[$group_id]) && isset($all_weights[$group_id][$ad_id])){
431
- unset($all_weights[$group_id][$ad_id]);
432
  }
433
- // we need to load all the group ids, that are allocated to this ad and then remove the right one only.
434
- $group_ids = $this->get_groups_by_ad_id($ad_id);
435
- foreach ($group_ids as $gid){
436
- if ($gid != $group_id){
437
- $ad_groups_assoc[$ad_id][] = $gid;
438
- }
439
  }
440
  }
441
  }
442
-
443
 
444
- // iterate through groups
445
- if ( isset($_POST['advads-groups']) && count( $_POST['advads-groups'] ) ){
446
 
447
- foreach ( $_POST['advads-groups'] as $_group_id => $_group ){
448
-
449
- // save basic wp term
 
 
 
450
  wp_update_term( $_group_id, Advanced_Ads::AD_GROUP_TAXONOMY, $_group );
451
 
452
  $group = new Advanced_Ads_Group( $_group['id'] );
453
  if ( isset( $_group['ads'] ) && is_array( $_group['ads'] ) ) {
454
  foreach ( $_group['ads'] as $_ad_id => $_ad_weight ) {
455
  /**
456
- * check if this ad is representing the current group and remove it in this case
457
  * could cause an infinite loop otherwise
458
  * see also /classes/ad_type_group.php::remove_from_ad_group()
459
  */
460
  $ad = new Advanced_Ads_Ad( $_ad_id );
461
-
462
- // we will have to load all the groups allocated to this ad.
463
- if (! isset($ad_groups_assoc[$_ad_id])){
464
- $ad_groups_assoc[$_ad_id] = $this->get_groups_by_ad_id($_ad_id);
465
  }
466
-
467
- if( isset( $ad->type )
468
- && 'group' === $ad->type
469
- && isset( $ad->output['group_id'] )
470
- && absint( $ad->output['group_id'] ) == $_group_id
471
- ){
472
- unset( $_group['ads'][ $_ad_id ] );
473
  } else {
474
- $ad_groups_assoc[ $_ad_id ][] = (int) $_group_id;
475
  }
476
  }
477
-
478
- // save ad weights
479
- $all_weights[$group->id] = $group->sanitize_ad_weights( $_group['ads'] );
480
  //$group->save_ad_weights( $_group['ads'] );
481
  }
482
 
483
- // save other attributes
484
- $type = isset($_group['type']) ? $_group['type'] : 'default';
485
- $ad_count = isset($_group['ad_count']) ? $_group['ad_count'] : 1;
486
- $options = isset($_group['options']) ? $_group['options'] : array();
487
 
488
- // allow other add-ons to save their own group attributes
489
  $atts = apply_filters( 'advanced-ads-group-save-atts', array(
490
- 'type' => $type,
491
  'ad_count' => $ad_count,
492
- 'options' => $options,
493
- ), $_group);
494
 
495
  $group->save( $atts );
496
  }
497
-
498
  foreach ( $ad_groups_assoc as $_ad_id => $group_ids ) {
499
- wp_set_object_terms( $_ad_id, $group_ids, $this->taxonomy);
500
- }
501
 
502
  }
503
-
504
  update_option( 'advads-ad-weights', $all_weights );
505
 
506
- // reload groups
507
  $this->load_groups();
508
 
509
  return true;
510
  }
511
 
512
  /**
513
- * returns a link to the ad group list page
 
 
514
  *
515
- * @since 1.0.0
516
- * @param arr $args additional arguments, e.g. action or group_id
517
  * @return string admin url
 
518
  */
519
- public static function group_page_url($args = array()) {
520
  $plugin = Advanced_Ads::get_instance();
521
 
522
  $defaultargs = array(
523
- // 'post_type' => constant("Advanced_Ads::POST_TYPE_SLUG"),
524
  'page' => 'advanced-ads-groups',
525
  );
526
- $args = $args + $defaultargs;
527
 
528
  return add_query_arg( $args, admin_url( 'admin.php' ) );
529
  }
1
  <?php
2
+
3
  /**
4
  * Groups List Table class.
5
  *
9
  class Advanced_Ads_Groups_List {
10
 
11
  /**
12
+ * Array with all groups
13
+ *
14
+ * @var $groups
15
  */
16
  public $groups = array();
17
 
18
  /**
19
+ * Array with all ad group types
20
+ *
21
+ * @var $types
22
  */
23
  public $types = array();
24
 
25
  /**
26
+ * Construct the current list
27
  */
28
+ public function __construct() {
29
 
30
+ // set default vars.
31
+ $this->taxonomy = Advanced_Ads::AD_GROUP_TAXONOMY;
32
  $this->post_type = Advanced_Ads::POST_TYPE_SLUG;
33
 
34
  $this->load_groups();
37
  }
38
 
39
  /**
40
+ * Load ad groups
41
  */
42
+ public function load_groups() {
43
 
44
+ // load all groups.
45
+ $search = ! empty( $_REQUEST['s'] ) ? trim( wp_unslash( $_REQUEST['s'] ) ) : '';
46
 
47
  $args = array(
48
+ 'taxonomy' => $this->taxonomy,
49
+ 'search' => $search,
50
  'hide_empty' => 0,
51
  );
52
+ // get wp term objects.
53
  $terms = Advanced_Ads::get_ad_groups( $args );
54
 
55
+ // add meta data to groups.
56
  $this->groups = $this->load_groups_objects_from_terms( $terms );
57
  }
58
 
59
  /**
60
+ * Load ad groups objects from wp term objects
61
+ *
62
+ * @param array $terms array of wp term objects.
63
  *
64
+ * @return array
65
  */
66
+ protected function load_groups_objects_from_terms( array $terms ) {
67
 
68
  $groups = array();
69
+ foreach ( $terms as $_group ) {
70
  $groups[] = new Advanced_Ads_Group( $_group );
71
  }
72
 
74
  }
75
 
76
  /**
77
+ * Render group list header
78
  */
79
+ public function render_header() {
80
  $file = ADVADS_BASE_PATH . 'admin/views/ad-group-list-header.php';
81
+ require_once $file;
82
  }
83
 
84
  /**
85
  * render list rows
86
  */
87
+ public function render_rows() {
88
+ foreach ( $this->groups as $_group ) {
89
  $this->render_row( $_group );
90
  $this->render_form_row( $_group );
91
  }
93
 
94
 
95
  /**
96
+ * Render a single row
97
  *
98
+ * @param Advanced_Ads_Group $group the ad group object.
99
  */
100
  public function render_row( Advanced_Ads_Group $group ) {
101
  $file = ADVADS_BASE_PATH . 'admin/views/ad-group-list-row.php';
102
+ require $file;
103
  }
104
 
105
  /**
106
+ * Render the form row of a group
107
  *
108
+ * @param Advanced_Ads_Group $group the ad group object.
109
  */
110
+ public function render_form_row( Advanced_Ads_Group $group ) {
111
 
112
+ // query ads.
113
  $ads = $this->get_ads( $group );
114
 
115
+ $weights = $group->get_ad_weights();
116
  $ad_form_rows = $weights;
117
  arsort( $ad_form_rows );
118
  $max_weight = Advanced_Ads_Group::get_max_ad_weight( $ads->post_count );
119
 
120
+ // The Loop.
121
  if ( $ads->post_count ) {
122
+ foreach ( $ads->posts as $_ad ) {
123
+ $row = '';
124
+ $ad_id = $_ad->ID;
125
+ $row .= '<tr data-ad-id="' . $ad_id . '" data-group-id="' . $group->id . '"><td>' . $_ad->post_title . '</td><td>';
126
+ $row .= '<select name="advads-groups[' . $group->id . '][ads][' . $_ad->ID . ']">';
127
+ $ad_weight = ( isset( $weights[ $ad_id ] ) ) ? $weights[ $ad_id ] : Advanced_Ads_Group::MAX_AD_GROUP_DEFAULT_WEIGHT;
128
+ for ( $i = 0; $i <= $max_weight; $i ++ ) {
129
  $row .= '<option ' . selected( $ad_weight, $i, false ) . '>' . $i . '</option>';
130
  }
131
+ $row .= '</select</td><td><button type="button" class="advads-remove-ad-from-group button">x</button></td></tr>';
132
+ $ad_form_rows[ $_ad->ID ] = $row;
133
  }
134
  }
135
  $ad_form_rows = $this->remove_empty_weights( $ad_form_rows );
136
+ // Restore original Post Data.
137
  wp_reset_postdata();
138
 
139
  $ads_for_select = $this->ads_for_select();
140
  $new_ad_weights = '<select class="advads-group-add-ad-list-weights">';
141
+ for ( $i = 0; $i <= $max_weight; $i ++ ) {
142
  $new_ad_weights .= '<option ' . selected( 10, $i, false ) . '>' . $i . '</option>';
143
  }
144
  $new_ad_weights .= '</select>';
147
  }
148
 
149
  /**
150
+ * Render the ads list
151
  *
152
+ * @param Advanced_Ads_Group $group group object.
153
  */
154
+ public function render_ads_list( Advanced_Ads_Group $group ) {
155
 
156
  $ads = $this->get_ads( $group );
157
 
158
+ $weights = $group->get_ad_weights();
159
  $weight_sum = array_sum( $weights );
160
  $ads_output = $weights;
161
  arsort( $ads_output );
162
 
163
+ // The Loop.
164
  if ( $ads->have_posts() ) {
165
+ echo ( 'default' === $group->type && $weight_sum ) ? '<ul>' : '<ol>';
166
  while ( $ads->have_posts() ) {
167
  $ads->the_post();
168
  $line_output = '<li><a href="' . get_edit_post_link( get_the_ID() ) . '">' . get_the_title() . '</a>';
169
 
170
+ $_weight = ( isset( $weights[ get_the_ID() ] ) ) ? $weights[ get_the_ID() ] : Advanced_Ads_Group::MAX_AD_GROUP_DEFAULT_WEIGHT;
171
+ if ( 'default' === $group->type && $weight_sum ) {
172
+ $line_output .= '<span class="ad-weight" title="' . __( 'Ad weight', 'advanced-ads' ) . '">' . number_format( ( $_weight / $weight_sum ) * 100 ) . '%</span>';
173
  }
174
 
175
+ $ad = new Advanced_Ads_Ad( get_the_ID() );
176
+ $expiry_date_format = get_option( 'date_format' ) . ', ' . get_option( 'time_format' );
177
+
178
  $post_start = get_post_time( 'U', true, $ad->id );
179
+
180
  $tz_option = get_option( 'timezone_string' );
181
+
182
  if ( $post_start > time() ) {
183
+ // translators: %s is a date.
184
  $line_output .= '<br />' . sprintf( __( 'starts %s', 'advanced-ads' ), get_date_from_gmt( date( 'Y-m-d H:i:s', $post_start ), $expiry_date_format ) );
185
  }
186
  if ( isset( $ad->expiry_date ) && $ad->expiry_date ) {
187
+ $expiry = $ad->expiry_date;
188
+ $expiry_date = date_create( '@' . $expiry );
189
+
190
+
191
+ if ( $tz_option ) {
192
+ $expiry_date->setTimezone( Advanced_Ads_Admin::get_wp_timezone() );
193
+ } else {
194
+ $tz_name = Advanced_Ads_Admin::timezone_get_name( Advanced_Ads_Admin::get_wp_timezone() );
195
+ $tz_offset = substr( $tz_name, 3 );
196
+ $off_time = date_create( '2017-09-21 T10:44:02' . $tz_offset );
197
  $offset_in_sec = date_offset_get( $off_time );
198
+ $expiry_date = date_create( '@' . ( $expiry + $offset_in_sec ) );
199
+ }
200
+
201
+ $tz = ' ( ' . Advanced_Ads_Admin::timezone_get_name( Advanced_Ads_Admin::get_wp_timezone() ) . ' )';
202
+
203
  if ( $expiry > time() ) {
204
+ // translators: %s is a date.
205
+ $line_output .= '<br />' . sprintf( __( 'expires %s', 'advanced-ads' ), $expiry_date->format( $expiry_date_format ) ) . $tz;
206
  } elseif ( $expiry <= time() ) {
207
+ // translators: %s is a date.
208
+ $line_output .= '<br />' . sprintf( __( '<strong>expired</strong> %s', 'advanced-ads' ), $expiry_date->format( $expiry_date_format ) ) . $tz;
209
  }
210
  }
211
  $line_output .= '</li>';
212
 
213
+ $ads_output[ get_the_ID() ] = $line_output;
214
  }
215
 
216
  $ads_output = $this->remove_empty_weights( $ads_output );
217
 
218
  echo implode( '', $ads_output );
219
+ echo ( 'default' === $group->type && $weight_sum ) ? '</ul>' : '</ol>';
220
+
221
+ if ( $ads->post_count > 4 ) {
222
+ $hidden_ads = $ads->post_count - 3;
223
+ echo '<p><a href="javascript:void(0)" class="advads-group-ads-list-show-more">+ ' .
224
+ // translators: %d is a number.
225
+ sprintf( __( 'show %d more ads', 'advanced-ads' ), $hidden_ads ) . '</a></p>';
226
  }
227
+
228
+ if ( 'all' === $group->ad_count ) {
229
+ echo '<p>' . esc_html__( 'all published ads are displayed', 'advanced-ads' ) . '</p>';
230
  } elseif ( $group->ad_count > 1 ) {
231
+ // translators: %d is a number.
232
+ echo '<p>' . sprintf( esc_html__( 'up to %d ads displayed', 'advanced-ads' ), absint( $group->ad_count ) ) . '</p>';
233
  }
234
  } else {
235
+ esc_html_e( 'No ads assigned', 'advanced-ads' );
236
+ ?>
237
+ <br/><a class="edit">+ <?php esc_html_e( 'Add some', 'advanced-ads' ); ?></a>
238
+ <?php
239
  }
240
+ // Restore original Post Data.
241
  wp_reset_postdata();
242
  }
243
 
244
  /**
245
+ * Remove entries from the ad weight array that are just id
246
+ *
247
+ * @param array $ads_output array with any output other that an integer.
248
  *
249
+ * @return array $ads_output array with ad output.
250
  * @since 1.5.1
 
 
251
  */
252
+ private function remove_empty_weights( array $ads_output ) {
253
 
254
+ foreach ( $ads_output as $key => $value ) {
255
  if ( is_int( $value ) ) {
256
+ unset( $ads_output[ $key ] );
257
+ }
258
  }
259
 
260
  return $ads_output;
261
  }
262
 
263
  /**
264
+ * Get ads for this group
265
+ *
266
+ * @param object $group group object.
267
  *
268
+ * @return object $ads WP_Query result with ads for this group.
 
269
  */
270
+ public function get_ads( $group ) {
271
  $args = array(
272
+ 'post_type' => $this->post_type,
273
+ 'post_status' => array( 'publish', 'pending', 'future', 'private' ),
274
+ 'taxonomy' => $group->taxonomy,
275
+ 'term' => $group->slug,
276
+ 'posts_per_page' => - 1,
277
  );
278
+
279
+ $ads = new WP_Query( $args );
280
+
281
+ return $ads;
282
  }
283
 
284
  /**
285
+ * List of all ads to display in select dropdown
286
  *
287
  * @return array
288
  */
289
+ public function ads_for_select() {
290
  $select = array();
291
+ $model = Advanced_Ads::get_instance()->get_model();
292
 
293
+ // load all ads.
294
+ $ads = $model->get_ads(
295
+ array(
296
+ 'orderby' => 'title',
297
+ 'order' => 'ASC',
298
+ )
299
+ );
300
+ foreach ( $ads as $_ad ) {
301
  $select[ $_ad->ID ] = esc_html( $_ad->post_title );
302
  }
303
 
305
  }
306
 
307
  /**
308
+ * Return ad group types
309
  *
310
+ * @return array $types ad group information
311
  */
312
+ public function get_ad_group_types() {
313
  $types = array(
314
  'default' => array(
315
+ 'title' => __( 'Random ads', 'advanced-ads' ),
316
+ 'description' => __( 'Display random ads based on ad weight', 'advanced-ads' ),
317
  ),
318
  'ordered' => array(
319
+ 'title' => __( 'Ordered ads', 'advanced-ads' ),
320
  'description' => __( 'Display ads with the highest ad weight first', 'advanced-ads' ),
321
+ ),
322
  );
323
 
324
  return apply_filters( 'advanced-ads-group-types', $types );
325
  }
326
 
327
  /**
328
+ * Render ad group action links
329
  *
330
+ * @param object $group group object.
331
  */
332
+ public function render_action_links( $group ) {
333
  global $tax;
334
 
335
  $tax = get_taxonomy( $this->taxonomy );
336
 
337
  $actions = array();
338
  if ( current_user_can( $tax->cap->edit_terms ) ) {
339
+ $actions['edit'] = '<a class="edit">' . __( 'Edit', 'advanced-ads' ) . '</a>';
340
  $actions['usage'] = '<a class="usage">' . __( 'Usage', 'advanced-ads' ) . '</a>';
341
  }
342
 
343
+ if ( current_user_can( $tax->cap->delete_terms ) ) {
344
+ $args = array(
345
+ 'action' => 'delete',
346
+ 'group_id' => $group->id,
347
  );
348
+ $delete_link = self::group_page_url( $args );
349
  $actions['delete'] = "<a class='delete-tag' href='" . wp_nonce_url( $delete_link, 'delete-tag_' . $group->id ) . "'>" . __( 'Delete', 'advanced-ads' ) . '</a>';
350
  }
351
 
352
+ if ( ! count( $actions ) ) {
353
+ return;
354
+ }
355
 
356
  echo '<div class="row-actions">';
357
  foreach ( $actions as $action => $link ) {
359
  }
360
  echo '</div>';
361
  }
362
+
363
  /**
364
+ * Create a new group
 
365
  */
366
+ public function create_group() {
367
+ // check nonce.
368
  if ( ! isset( $_POST['advads-group-add-nonce'] )
369
+ || ! wp_verify_nonce( $_POST['advads-group-add-nonce'], 'add-advads-groups' ) ) {
370
 
371
  return new WP_Error( 'invalid_ad_group', __( 'Invalid Ad Group', 'advanced-ads' ) );
372
  }
373
 
374
+ // check user rights.
375
+ if ( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads' ) ) ) {
376
  return new WP_Error( 'invalid_ad_group_rights', __( 'You don’t have permission to change the ad groups', 'advanced-ads' ) );
377
  }
378
 
379
+ if ( isset( $_POST['advads-group-name'] ) && '' !== $_POST['advads-group-name'] ) {
380
 
381
+ $title = sanitize_text_field( $_POST['advads-group-name'] );
382
  $new_group = wp_create_term( $title, Advanced_Ads::AD_GROUP_TAXONOMY );
383
+
384
+ if ( is_wp_error( $new_group ) ) {
385
  return $new_group;
386
  }
387
+
388
+ // save default values.
389
+ if ( is_array( $new_group ) ) {
390
  $group = new Advanced_Ads_Group( $new_group['term_id'] );
391
+
392
+ // allow other add-ons to save their own group attributes.
393
  $atts = apply_filters( 'advanced-ads-group-save-atts', array(
394
+ 'type' => 'default',
395
  'ad_count' => 1,
396
+ 'options' => array(),
397
+ ),
398
+ $group
399
+ );
400
 
401
  $group->save( $atts );
402
  }
403
+
404
+ // reload groups.
405
  $this->load_groups();
406
 
407
  } else {
411
  return true;
412
  }
413
 
 
 
 
 
 
 
 
 
 
414
  /**
415
+ * Load groups with a given ad in them.
416
+ *
417
+ * @param integer $ad_id ad ID.
418
  *
419
+ * @return array
420
  */
421
+ private function get_groups_by_ad_id( $ad_id ) {
422
+ $ids = array();
423
+ $terms = wp_get_object_terms( $ad_id, $this->taxonomy );
424
+ foreach ( $terms as $term ) {
425
+ $ids[] = $term->term_id;
426
+ }
427
+
428
+ return $ids;
429
+ }
430
+
431
+ /**
432
+ * Bulk update groups
433
+ */
434
+ public function update_groups() {
435
+ // check nonce.
436
  if ( ! isset( $_POST['advads-group-update-nonce'] )
437
+ || ! wp_verify_nonce( $_POST['advads-group-update-nonce'], 'update-advads-groups' ) ) {
438
 
439
  return new WP_Error( 'invalid_ad_group', __( 'Invalid Ad Group', 'advanced-ads' ) );
440
  }
441
+
442
+ // check user rights.
443
+ if ( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads' ) ) ) {
444
  return new WP_Error( 'invalid_ad_group_rights', __( 'You don’t have permission to change the ad groups', 'advanced-ads' ) );
445
  }
446
 
447
+ /** Empty group settings
448
  * edit: emptying disabled, because when only a few groups are saved (e.g. when filtered by search), options are reset
449
  * todo: needs a solution that also removes options when the group is removed
450
  */
451
+ // empty weights.
452
  // update_option( 'advads-ad-weights', array() );
453
+
454
  $all_weights = get_option( 'advads-ad-weights', array() );
455
 
456
  // ad_id => group_ids
457
  $ad_groups_assoc = array();
458
 
459
+ if ( isset( $_POST['advads-groups-removed-ads'] ) && is_array( $_POST['advads-groups-removed-ads'] ) && isset( $_POST['advads-groups-removed-ads-gid'] ) ) {
460
+ $len = count( $_POST['advads-groups-removed-ads'] );
461
+ for ( $i = 0; $i < $len; $i ++ ) {
462
+ $ad_id = $_POST['advads-groups-removed-ads'][ $i ];
463
+ $group_id = $_POST['advads-groups-removed-ads-gid'][ $i ];
464
  $ad_groups_assoc[ $ad_id ] = array();
465
+ // remove it from the weights.
466
+ if ( isset( $all_weights[ $group_id ] ) && isset( $all_weights[ $group_id ][ $ad_id ] ) ) {
467
+ unset( $all_weights[ $group_id ][ $ad_id ] );
468
  }
469
+ // we need to load all the group ids, that are allocated to this ad and then remove the right one only.
470
+ $group_ids = $this->get_groups_by_ad_id( $ad_id );
471
+ foreach ( $group_ids as $gid ) {
472
+ if ( $gid != $group_id ) {
473
+ $ad_groups_assoc[ $ad_id ][] = $gid;
474
+ }
475
  }
476
  }
477
  }
 
478
 
 
 
479
 
480
+ // iterate through groups.
481
+ if ( isset( $_POST['advads-groups'] ) && count( $_POST['advads-groups'] ) ) {
482
+
483
+ foreach ( $_POST['advads-groups'] as $_group_id => $_group ) {
484
+
485
+ // save basic wp term.
486
  wp_update_term( $_group_id, Advanced_Ads::AD_GROUP_TAXONOMY, $_group );
487
 
488
  $group = new Advanced_Ads_Group( $_group['id'] );
489
  if ( isset( $_group['ads'] ) && is_array( $_group['ads'] ) ) {
490
  foreach ( $_group['ads'] as $_ad_id => $_ad_weight ) {
491
  /**
492
+ * Check if this ad is representing the current group and remove it in this case
493
  * could cause an infinite loop otherwise
494
  * see also /classes/ad_type_group.php::remove_from_ad_group()
495
  */
496
  $ad = new Advanced_Ads_Ad( $_ad_id );
497
+
498
+ // we will have to load all the groups allocated to this ad.
499
+ if ( ! isset( $ad_groups_assoc[ $_ad_id ] ) ) {
500
+ $ad_groups_assoc[ $_ad_id ] = $this->get_groups_by_ad_id( $_ad_id );
501
  }
502
+
503
+ if ( isset( $ad->type )
504
+ && 'group' === $ad->type
505
+ && isset( $ad->output['group_id'] )
506
+ && absint( $ad->output['group_id'] ) == $_group_id
507
+ ) {
508
+ unset( $_group['ads'][ $_ad_id ] );
509
  } else {
510
+ $ad_groups_assoc[ $_ad_id ][] = (int) $_group_id;
511
  }
512
  }
513
+
514
+ // save ad weights.
515
+ $all_weights[ $group->id ] = $group->sanitize_ad_weights( $_group['ads'] );
516
  //$group->save_ad_weights( $_group['ads'] );
517
  }
518
 
519
+ // save other attributes.
520
+ $type = isset( $_group['type'] ) ? $_group['type'] : 'default';
521
+ $ad_count = isset( $_group['ad_count'] ) ? $_group['ad_count'] : 1;
522
+ $options = isset( $_group['options'] ) ? $_group['options'] : array();
523
 
524
+ // allow other add-ons to save their own group attributes.
525
  $atts = apply_filters( 'advanced-ads-group-save-atts', array(
526
+ 'type' => $type,
527
  'ad_count' => $ad_count,
528
+ 'options' => $options,
529
+ ), $_group );
530
 
531
  $group->save( $atts );
532
  }
533
+
534
  foreach ( $ad_groups_assoc as $_ad_id => $group_ids ) {
535
+ wp_set_object_terms( $_ad_id, $group_ids, $this->taxonomy );
536
+ };
537
 
538
  }
539
+
540
  update_option( 'advads-ad-weights', $all_weights );
541
 
542
+ // reload groups.
543
  $this->load_groups();
544
 
545
  return true;
546
  }
547
 
548
  /**
549
+ * Returns a link to the ad group list page
550
+ *
551
+ * @param array $args additional arguments, e.g. action or group_id.
552
  *
 
 
553
  * @return string admin url
554
+ * @since 1.0.0
555
  */
556
+ public static function group_page_url( $args = array() ) {
557
  $plugin = Advanced_Ads::get_instance();
558
 
559
  $defaultargs = array(
 
560
  'page' => 'advanced-ads-groups',
561
  );
562
+ $args = $args + $defaultargs;
563
 
564
  return add_query_arg( $args, admin_url( 'admin.php' ) );
565
  }
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.6
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.6' );
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.7
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.7' );
43
 
44
  /*----------------------------------------------------------------------------*
45
  * Autoloading, modules and functions
classes/ad_placements.php CHANGED
@@ -31,7 +31,7 @@ class Advanced_Ads_Placements {
31
  'title' => __( 'Manual Placement', 'advanced-ads' ),
32
  'description' => __( 'Manual placement to use as function or shortcode.', 'advanced-ads' ),
33
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/manual.png',
34
- 'options' => array( 'show_position' => true, 'show_lazy_load' => true )
35
  ),
36
  'header' => array(
37
  'title' => __( 'Header Code', 'advanced-ads' ),
@@ -41,31 +41,32 @@ class Advanced_Ads_Placements {
41
  'footer' => array(
42
  'title' => __( 'Footer Code', 'advanced-ads' ),
43
  'description' => __( 'Injected in Footer (before closing &lt;/body&gt; Tag).', 'advanced-ads' ),
44
- 'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/footer.png'
 
45
  ),
46
  'post_top' => array(
47
  'title' => __( 'Before Content', 'advanced-ads' ),
48
  'description' => __( 'Injected before the post content.', 'advanced-ads' ),
49
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-before.png',
50
- 'options' => array( 'show_position' => true, 'show_lazy_load' => true, 'uses_the_content' => true )
51
  ),
52
  'post_bottom' => array(
53
  'title' => __( 'After Content', 'advanced-ads' ),
54
  'description' => __( 'Injected after the post content.', 'advanced-ads' ),
55
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-after.png',
56
- 'options' => array( 'show_position' => true, 'show_lazy_load' => true, 'uses_the_content' => true )
57
  ),
58
  'post_content' => array(
59
  'title' => __( 'Content', 'advanced-ads' ),
60
  'description' => __( 'Injected into the content. You can choose the paragraph after which the ad content is displayed.', 'advanced-ads' ),
61
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-within.png',
62
- 'options' => array( 'show_position' => true, 'show_lazy_load' => true, 'uses_the_content' => true )
63
  ),
64
  'sidebar_widget' => array(
65
  'title' => __( 'Sidebar Widget', 'advanced-ads' ),
66
  'description' => __( 'Create a sidebar widget with an ad. Can be placed and used like any other widget.', 'advanced-ads' ),
67
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/widget.png',
68
- 'options' => array( 'show_lazy_load' => true )
69
  ),
70
  );
71
  return apply_filters( 'advanced-ads-placement-types', $types );
31
  'title' => __( 'Manual Placement', 'advanced-ads' ),
32
  'description' => __( 'Manual placement to use as function or shortcode.', 'advanced-ads' ),
33
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/manual.png',
34
+ 'options' => array( 'show_position' => true, 'show_lazy_load' => true, 'amp' => true )
35
  ),
36
  'header' => array(
37
  'title' => __( 'Header Code', 'advanced-ads' ),
41
  'footer' => array(
42
  'title' => __( 'Footer Code', 'advanced-ads' ),
43
  'description' => __( 'Injected in Footer (before closing &lt;/body&gt; Tag).', 'advanced-ads' ),
44
+ 'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/footer.png',
45
+ 'options' => array( 'amp' => true )
46
  ),
47
  'post_top' => array(
48
  'title' => __( 'Before Content', 'advanced-ads' ),
49
  'description' => __( 'Injected before the post content.', 'advanced-ads' ),
50
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-before.png',
51
+ 'options' => array( 'show_position' => true, 'show_lazy_load' => true, 'uses_the_content' => true, 'amp' => true )
52
  ),
53
  'post_bottom' => array(
54
  'title' => __( 'After Content', 'advanced-ads' ),
55
  'description' => __( 'Injected after the post content.', 'advanced-ads' ),
56
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-after.png',
57
+ 'options' => array( 'show_position' => true, 'show_lazy_load' => true, 'uses_the_content' => true, 'amp' => true )
58
  ),
59
  'post_content' => array(
60
  'title' => __( 'Content', 'advanced-ads' ),
61
  'description' => __( 'Injected into the content. You can choose the paragraph after which the ad content is displayed.', 'advanced-ads' ),
62
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/content-within.png',
63
+ 'options' => array( 'show_position' => true, 'show_lazy_load' => true, 'uses_the_content' => true, 'amp' => true )
64
  ),
65
  'sidebar_widget' => array(
66
  'title' => __( 'Sidebar Widget', 'advanced-ads' ),
67
  'description' => __( 'Create a sidebar widget with an ad. Can be placed and used like any other widget.', 'advanced-ads' ),
68
  'image' => ADVADS_BASE_URL . 'admin/assets/img/placements/widget.png',
69
+ 'options' => array( 'show_lazy_load' => true, 'amp' => true )
70
  ),
71
  );
72
  return apply_filters( 'advanced-ads-placement-types', $types );
classes/display-conditions.php CHANGED
@@ -610,9 +610,9 @@ class Advanced_Ads_Display_Conditions {
610
  $value = ( isset( $options['value'] ) && is_numeric( $options['value'] ) ) ? floatval( $options['value'] ) : 0;
611
  ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
612
  <select name="<?php echo $name; ?>[operator]">
613
- <option value="older_than" <?php selected( 'older_than', $operator ); ?>><?php _e( 'older than', 'advanced-ads-pro'); ?></option>
614
- <option value="younger_than" <?php selected( 'younger_than', $operator ); ?>><?php _e( 'younger than', 'advanced-ads-pro' ); ?></option>
615
- </select><input type="text" name="<?php echo $name; ?>[value]" value="<?php echo $value; ?>"/>&nbsp;<?php _e( 'days', 'advanced-ads-pro' );
616
  }
617
 
618
  /**
610
  $value = ( isset( $options['value'] ) && is_numeric( $options['value'] ) ) ? floatval( $options['value'] ) : 0;
611
  ?><input type="hidden" name="<?php echo $name; ?>[type]" value="<?php echo $options['type']; ?>"/>
612
  <select name="<?php echo $name; ?>[operator]">
613
+ <option value="older_than" <?php selected( 'older_than', $operator ); ?>><?php _e( 'older than', 'advanced-ads'); ?></option>
614
+ <option value="younger_than" <?php selected( 'younger_than', $operator ); ?>><?php _e( 'younger than', 'advanced-ads' ); ?></option>
615
+ </select><input type="text" name="<?php echo $name; ?>[value]" value="<?php echo $value; ?>"/>&nbsp;<?php _e( 'days', 'advanced-ads' );
616
  }
617
 
618
  /**
classes/frontend_checks.php CHANGED
@@ -396,7 +396,7 @@ class Advanced_Ads_Frontend_Checks {
396
  * @param int $issues Number of all issues.
397
  * @param int $notices Number of notices.
398
  */
399
- public static function add_header_nodes( $wp_admin_bar, $issues, $notices ) {
400
  $wp_admin_bar->add_node( array(
401
  'id' => 'advanced_ads_ad_health',
402
  'title' => __( 'Ad Health', 'advanced-ads' ) . '&nbsp;<span class="advanced-ads-issue-counter">' . $issues . '</span>',
@@ -425,7 +425,7 @@ class Advanced_Ads_Frontend_Checks {
425
  * @param obj $wp_admin_bar WP_Admin_Bar object.
426
  * @param int $issues Number of all issues.
427
  */
428
- public static function add_footer_nodes( $wp_admin_bar, $issues ) {
429
  if ( ! $issues ) {
430
  $wp_admin_bar->add_node( array(
431
  'parent' => 'advanced_ads_ad_health',
396
  * @param int $issues Number of all issues.
397
  * @param int $notices Number of notices.
398
  */
399
+ private function add_header_nodes( $wp_admin_bar, $issues, $notices ) {
400
  $wp_admin_bar->add_node( array(
401
  'id' => 'advanced_ads_ad_health',
402
  'title' => __( 'Ad Health', 'advanced-ads' ) . '&nbsp;<span class="advanced-ads-issue-counter">' . $issues . '</span>',
425
  * @param obj $wp_admin_bar WP_Admin_Bar object.
426
  * @param int $issues Number of all issues.
427
  */
428
+ private function add_footer_nodes( $wp_admin_bar, $issues ) {
429
  if ( ! $issues ) {
430
  $wp_admin_bar->add_node( array(
431
  'parent' => 'advanced_ads_ad_health',
includes/functions.php CHANGED
@@ -95,7 +95,10 @@ function advads_can_display_ads(){
95
  * @return bool true if amp url, false otherwise
96
  */
97
  function advads_is_amp() {
98
- if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) {
 
 
 
99
  return false;
100
  }
101
 
95
  * @return bool true if amp url, false otherwise
96
  */
97
  function advads_is_amp() {
98
+ if ( is_admin()
99
+ || ( defined( 'REST_REQUEST' ) && REST_REQUEST )
100
+ || ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST )
101
+ ) {
102
  return false;
103
  }
104
 
modules/ad-blocker/admin/admin.php CHANGED
@@ -147,7 +147,7 @@ class Advanced_Ads_Ad_Blocker_Admin
147
  $fs_connect = Advanced_Ads_Filesystem::get_instance()->fs_connect( $this->upload_dir['basedir'] );
148
 
149
  if ( false === $fs_connect || is_wp_error( $fs_connect ) ) {
150
- $message = __( 'Unable to connect to the filesystem. Please confirm your credentials.', 'advanced-ads-pro' );
151
 
152
  if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
153
  $message = esc_html( $wp_filesystem->errors->get_error_message() );
147
  $fs_connect = Advanced_Ads_Filesystem::get_instance()->fs_connect( $this->upload_dir['basedir'] );
148
 
149
  if ( false === $fs_connect || is_wp_error( $fs_connect ) ) {
150
+ $message = __( 'Unable to connect to the filesystem. Please confirm your credentials.', 'advanced-ads' );
151
 
152
  if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
153
  $message = esc_html( $wp_filesystem->errors->get_error_message() );
modules/gadsense/includes/class-adsense-report.php CHANGED
@@ -502,21 +502,27 @@ class Advanced_Ads_AdSense_Dashboard_Summary{
502
  }
503
 
504
  private static final function get_timezone(){
505
- $gmt_offset = get_option('gmt_offset');
506
- $sign = $gmt_offset < 0 ? "-" : "+";
507
- $gmt_offset = abs($gmt_offset);
508
- $gmt_offset_modulo = fmod($gmt_offset, 1.0);
509
- $hours = sprintf("%02d", $gmt_offset);
510
- $minutes = "00";
511
- if ($gmt_offset_modulo != 0){
512
- $minutes = (int)($gmt_offset_modulo * 60);
513
- }
514
- $timezone_string = $sign . $hours . $minutes;
 
 
 
 
 
 
515
  try {
516
  $tz = new DateTimeZone($timezone_string);
517
  } catch (Exception $e) {
518
  error_log($e->getMessage());
519
- $tz = new DateTimeZone();
520
  }
521
  return $tz;
522
  }
@@ -564,4 +570,4 @@ class Advanced_Ads_AdSense_Dashboard_Summary{
564
  }
565
  }
566
 
567
- ?>
502
  }
503
 
504
  private static final function get_timezone(){
505
+ $timezone_string = get_option( 'timezone_string' );
506
+ if ( ! $timezone_string ) {
507
+ $gmt_offset = get_option('gmt_offset');
508
+ $sign = $gmt_offset < 0 ? "-" : "+";
509
+ $gmt_offset = abs($gmt_offset);
510
+ $gmt_offset_modulo = fmod($gmt_offset, 1.0);
511
+ $hours = sprintf("%02d", $gmt_offset);
512
+ $minutes = "00";
513
+ if ($gmt_offset_modulo != 0){
514
+ $minutes = (int)($gmt_offset_modulo * 60);
515
+ }
516
+ // PHP < 5.5.10 and HHVM do not recognize this format, 'UTC' will be used
517
+ // https://stackoverflow.com/q/14068594
518
+ $timezone_string = $sign . $hours . $minutes;
519
+ }
520
+
521
  try {
522
  $tz = new DateTimeZone($timezone_string);
523
  } catch (Exception $e) {
524
  error_log($e->getMessage());
525
+ $tz = new DateTimeZone( 'UTC' );
526
  }
527
  return $tz;
528
  }
570
  }
571
  }
572
 
573
+ ?>
public/views/ad-debug.php CHANGED
@@ -1,24 +1,8 @@
1
  <?php if ( ! advads_is_amp() ):
2
  ob_start(); ?>
3
- <script>
4
- // Output script that makes full-screen mode.
5
- if ( typeof advanced_ads_full_screen_debug !== 'function' ) {
6
- function advanced_ads_full_screen_debug( ad ) {
7
- if ( ! ad || ! document.body ) { return; }
8
-
9
- var ad_full = document.createElement( 'div' );
10
- ad_full.style.cssText = '<?php echo $style_full; ?>';
11
- ad_full.ondblclick = function() {
12
- this.parentNode.removeChild( this );
13
- }
14
- ad_full.innerHTML = ad.innerHTML;
15
- document.body.appendChild( ad_full );
16
- }
17
- }
18
- </script>
19
  <?php echo Advanced_Ads_Utils::get_inline_asset( ob_get_clean() );
20
  endif; ?>
21
- <div id="<?php echo $wrapper_id; ?>" style="<?php echo $style; ?>" ondblclick="advanced_ads_full_screen_debug( this );">
22
  <strong><?php _e( 'Ad debug output', 'advanced-ads' ); ?></strong>
23
  <?php echo '<br /><br />' . implode( '<br /><br />', $content ); ?>
24
  <br /><br /><a style="color: green;" href="<?php echo ADVADS_URL; ?>manual/ad-debug-mode/#utm_source=advanced-ads&utm_medium=link&utm_campaign=ad-debug-mode" target="_blank"><?php _e( 'Find solutions in the manual', 'advanced-ads' ); ?></a>
1
  <?php if ( ! advads_is_amp() ):
2
  ob_start(); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  <?php echo Advanced_Ads_Utils::get_inline_asset( ob_get_clean() );
4
  endif; ?>
5
+ <div id="<?php echo $wrapper_id; ?>" style="<?php echo $style; ?>">
6
  <strong><?php _e( 'Ad debug output', 'advanced-ads' ); ?></strong>
7
  <?php echo '<br /><br />' . implode( '<br /><br />', $content ); ?>
8
  <br /><br /><a style="color: green;" href="<?php echo ADVADS_URL; ?>manual/ad-debug-mode/#utm_source=advanced-ads&utm_medium=link&utm_campaign=ad-debug-mode" target="_blank"><?php _e( 'Find solutions in the manual', 'advanced-ads' ); ?></a>
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.6
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -303,6 +303,13 @@ Yes. Advanced Ads is based on WordPress standards and therefore easily customiza
303
 
304
  == Changelog ==
305
 
 
 
 
 
 
 
 
306
  = 1.14.6 =
307
 
308
  * fixed frontend issue showing for admins if the HEAD placement is used
5
  Requires at least: 4.6
6
  Tested up to: 5.2
7
  Requires PHP: 5.6
8
+ Stable tag: 1.14.7
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.7 =
307
+
308
+ * allow "Footer code" and "Sidebar Widget" placements on AMP pages created by the official AMP plugin
309
+ * prevented AMP warnings on XMLRPC requests
310
+ * removed unused debug function
311
+ * made editing of AdSense ads possible in PHP < 5.5.10 (please note that Advanced Ads is recommended for PHP > 5.6)
312
+
313
  = 1.14.6 =
314
 
315
  * fixed frontend issue showing for admins if the HEAD placement is used