Advanced Ads - Version 1.19.1

Version Description

  • apply WordPress lazy loading for images to images in ad content
  • layout fixes for WordPress 5.5
Download this release

Release Info

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

Code changes from version 1.19.0 to 1.19.1

admin/assets/js/admin.js CHANGED
@@ -577,8 +577,8 @@ jQuery( document ).ready( function ( $ ) {
577
 
578
  // move meta box markup to hndle headline
579
  $( '.advads-hndlelinks' ).each( function () {
 
580
  $( this ).removeClass( 'hidden' )
581
- $( this ).appendTo( $( this ).parent( '.inside' ).siblings( 'h2.hndle' ) )
582
  } )
583
  // open tutorial link when clicked on it
584
  $( '.advads-video-link' ).click( function ( el ) {
@@ -1612,4 +1612,4 @@ jQuery( document ).ready( function () {
1612
  jQuery( document ).on( 'click', '.advads-tr-remove', function(){
1613
  jQuery( this ).closest( 'tr' ).remove();
1614
  });
1615
- });
577
 
578
  // move meta box markup to hndle headline
579
  $( '.advads-hndlelinks' ).each( function () {
580
+ $( this ).appendTo( $( this ).parents('.postbox').find( 'h2.hndle' ) )
581
  $( this ).removeClass( 'hidden' )
 
582
  } )
583
  // open tutorial link when clicked on it
584
  $( '.advads-video-link' ).click( function ( el ) {
1612
  jQuery( document ).on( 'click', '.advads-tr-remove', function(){
1613
  jQuery( this ).closest( 'tr' ).remove();
1614
  });
1615
+ });
admin/includes/class-licenses.php CHANGED
@@ -67,7 +67,7 @@ class Advanced_Ads_Admin_Licenses {
67
  if ( $this->get_license_status( $_add_on['options_slug'] ) !== 'valid' ) {
68
  // register warning.
69
  $plugin_file = plugin_basename( $_add_on['path'] );
70
- add_action( 'after_plugin_row_' . $plugin_file, array( $this, 'add_plugin_list_license_notice' ), 10, 3 );
71
  }
72
  }
73
  }
@@ -77,19 +77,27 @@ class Advanced_Ads_Admin_Licenses {
77
  *
78
  * @param string $plugin_file Path to the plugin file, relative to the plugins directory.
79
  * @param array $plugin_data An array of plugin data.
80
- * @param string $status Status of the plugin. Defaults are 'All', 'Active',
81
- * 'Inactive', 'Recently Activated', 'Upgrade', 'Must-Use',
82
- * 'Drop-ins', 'Search'.
83
  *
84
  * @since 1.7.12
85
- * @todo make this work on multisite as well
86
  */
87
- public function add_plugin_list_license_notice( $plugin_file, $plugin_data, $status ) {
88
-
89
- echo '<tr class="advads-plugin-update-tr plugin-update-tr active"><td class="plugin-update colspanchange" colspan="3"><div class="update-message notice inline notice-warning notice-alt"><p>'
90
- . sprintf( __( 'There might be a new version of %1$s. Please <strong>provide a valid license key</strong> in order to receive updates and support <a href="%2$s">on this page</a>.', 'advanced-ads' ), $plugin_data['Title'], admin_url( 'admin.php?page=advanced-ads-settings#top#licenses' ) )
91
- . '</p></div></td></tr>';
92
-
 
 
 
 
 
 
 
 
 
 
 
93
  }
94
 
95
 
67
  if ( $this->get_license_status( $_add_on['options_slug'] ) !== 'valid' ) {
68
  // register warning.
69
  $plugin_file = plugin_basename( $_add_on['path'] );
70
+ add_action( 'after_plugin_row_' . $plugin_file, array( $this, 'add_plugin_list_license_notice' ), 10, 2 );
71
  }
72
  }
73
  }
77
  *
78
  * @param string $plugin_file Path to the plugin file, relative to the plugins directory.
79
  * @param array $plugin_data An array of plugin data.
 
 
 
80
  *
81
  * @since 1.7.12
82
+ * @todo make this work on multisite as well
83
  */
84
+ public function add_plugin_list_license_notice( $plugin_file, $plugin_data ) {
85
+ static $cols;
86
+ if ( is_null( $cols ) ) {
87
+ $cols = count( _get_list_table( 'WP_Plugins_List_Table' )->get_columns() );
88
+ }
89
+ printf(
90
+ '<tr class="advads-plugin-update-tr plugin-update-tr active"><td class="plugin-update colspanchange" colspan="%d"><div class="update-message notice inline notice-warning notice-alt"><p>%s</p></div></td></tr>',
91
+ esc_attr( $cols ),
92
+ wp_kses_post(
93
+ sprintf(
94
+ /* Translators: 1: add-on name 2: admin URL to license page */
95
+ __( 'There might be a new version of %1$s. Please <strong>provide a valid license key</strong> in order to receive updates and support <a href="%2$s">on this page</a>.', 'advanced-ads' ),
96
+ $plugin_data['Title'],
97
+ admin_url( 'admin.php?page=advanced-ads-settings#top#licenses' )
98
+ )
99
+ )
100
+ );
101
  }
102
 
103
 
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.19.0
16
  * Author: Thomas Maier, Advanced Ads GmbH
17
  * Author URI: https://wpadvancedads.com
18
  * Text Domain: advanced-ads
@@ -39,7 +39,7 @@ define( 'ADVADS_BASE_DIR', dirname( ADVADS_BASE ) ); // directory of the plugin
39
  // general and global slug, e.g. to store options in WP.
40
  define( 'ADVADS_SLUG', 'advanced-ads' );
41
  define( 'ADVADS_URL', 'https://wpadvancedads.com/' );
42
- define( 'ADVADS_VERSION', '1.19.0' );
43
 
44
  // Autoloading, modules and functions.
45
 
12
  * Plugin Name: Advanced Ads
13
  * Plugin URI: https://wpadvancedads.com
14
  * Description: Manage and optimize your ads in WordPress
15
+ * Version: 1.19.1
16
  * Author: Thomas Maier, Advanced Ads GmbH
17
  * Author URI: https://wpadvancedads.com
18
  * Text Domain: advanced-ads
39
  // general and global slug, e.g. to store options in WP.
40
  define( 'ADVADS_SLUG', 'advanced-ads' );
41
  define( 'ADVADS_URL', 'https://wpadvancedads.com/' );
42
+ define( 'ADVADS_VERSION', '1.19.1' );
43
 
44
  // Autoloading, modules and functions.
45
 
classes/ad_type_content.php CHANGED
@@ -76,7 +76,7 @@ class Advanced_Ads_Ad_Type_Content extends Advanced_Ads_Ad_Type_Abstract{
76
  }
77
  ?>
78
  <br class="clear"/>
79
-
80
  <input type="hidden" name="advanced_ad[output][allow_shortcodes]" value="1" /><?php
81
  include ADVADS_BASE_PATH . 'admin/views/ad-info-after-textarea.php';
82
  }
@@ -91,20 +91,21 @@ class Advanced_Ads_Ad_Type_Content extends Advanced_Ads_Ad_Type_Abstract{
91
  public function sanitize_content($content = ''){
92
  // use WordPress core content filter
93
  $content = apply_filters( 'content_save_pre', $content );
94
-
95
  // remove slashes from content
96
  $content = wp_unslash( $content );
97
  return $content;
98
  }
99
 
100
  /**
101
- * Prepare the ads frontend output
102
  *
103
- * @param obj $ad ad object
104
- * @return str $content ad content prepared for frontend output
 
105
  * @since 1.0.0
106
  */
107
- public function prepare_output($ad){
108
 
109
  // apply functions normally running through the_content filter
110
  // the_content filter is not used here because it created an infinite loop (ads within ads for "before content" and other auto injections)
@@ -131,9 +132,19 @@ class Advanced_Ads_Ad_Type_Content extends Advanced_Ads_Ad_Type_Abstract{
131
  $output = wpautop( $output );
132
  $output = shortcode_unautop( $output );
133
  $output = $this->do_shortcode( $output, $ad );
134
- // make included images responsive, since WordPress 4.4
135
- if( ! defined( 'ADVADS_DISABLE_RESPONSIVE_IMAGES' ) && function_exists( 'wp_make_content_images_responsive' ) ){
136
- $output = wp_make_content_images_responsive( $output );
 
 
 
 
 
 
 
 
 
 
137
  }
138
 
139
  return $output;
76
  }
77
  ?>
78
  <br class="clear"/>
79
+
80
  <input type="hidden" name="advanced_ad[output][allow_shortcodes]" value="1" /><?php
81
  include ADVADS_BASE_PATH . 'admin/views/ad-info-after-textarea.php';
82
  }
91
  public function sanitize_content($content = ''){
92
  // use WordPress core content filter
93
  $content = apply_filters( 'content_save_pre', $content );
94
+
95
  // remove slashes from content
96
  $content = wp_unslash( $content );
97
  return $content;
98
  }
99
 
100
  /**
101
+ * Prepare the ads frontend output.
102
  *
103
+ * @param Advanced_Ads_Ad $ad The ad object.
104
+ *
105
+ * @return string $content ad content prepared for frontend output.
106
  * @since 1.0.0
107
  */
108
+ public function prepare_output( $ad ) {
109
 
110
  // apply functions normally running through the_content filter
111
  // the_content filter is not used here because it created an infinite loop (ads within ads for "before content" and other auto injections)
132
  $output = wpautop( $output );
133
  $output = shortcode_unautop( $output );
134
  $output = $this->do_shortcode( $output, $ad );
135
+
136
+ if ( defined( 'ADVADS_DISABLE_RESPONSIVE_IMAGES' ) && ADVADS_DISABLE_RESPONSIVE_IMAGES ) {
137
+ return $output;
138
+ }
139
+
140
+ // Make included images responsive, since WordPress 4.4, before WordPress 5.5.
141
+ if ( function_exists( 'wp_make_content_images_responsive' ) && ! function_exists( 'wp_filter_content_tags' ) ) {
142
+ return wp_make_content_images_responsive( $output );
143
+ }
144
+
145
+ // Function wp_make_content_images_responsive has been deprecated with WordPress 5.5.
146
+ if ( function_exists( 'wp_filter_content_tags' ) ) {
147
+ return wp_filter_content_tags( $output );
148
  }
149
 
150
  return $output;
classes/ad_type_dummy.php CHANGED
@@ -25,7 +25,7 @@ class Advanced_Ads_Ad_Type_Dummy extends Advanced_Ads_Ad_Type_Abstract{
25
  public function __construct() {
26
  $this->title = __( 'Dummy', 'advanced-ads' );
27
  $this->description = __( 'Uses a simple placeholder ad for quick testing.', 'advanced-ads' );
28
-
29
  }
30
 
31
  /**
@@ -38,40 +38,43 @@ class Advanced_Ads_Ad_Type_Dummy extends Advanced_Ads_Ad_Type_Abstract{
38
  * @param obj $ad ad object
39
  */
40
  public function render_parameters( $ad ){
41
-
42
  // don’t show url field if tracking plugin enabled
43
  if( ! defined( 'AAT_VERSION' )) :
44
  $url = ( ! empty( $ad->url ) ) ? esc_attr( $ad->url ) : home_url();
45
  ?><span class="label"><?php _e( 'URL', 'advanced-ads' ); ?></span>
46
  <div><input type="text" name="advanced_ad[url]" id="advads-url" class="advads-ad-url" value="<?php echo $url; ?>"/></div><hr/>
47
  <?php endif;
48
-
49
  ?><img src="<?php echo ADVADS_BASE_URL ?>public/assets/img/dummy.jpg" width="300" height="250"/><?php
50
-
51
  ?><input type="hidden" name="advanced_ad[width]" value="300"/>
52
  <input type="hidden" name="advanced_ad[height]" value="250"/><?php
53
  }
54
-
55
  /**
56
- * Prepare the ads frontend output
57
  *
58
- * @param obj $ad ad object
59
- * @return str static image content
 
60
  */
61
- public function prepare_output($ad){
62
-
63
- $url = ( isset( $ad->url ) ) ? esc_url( $ad->url ) : '';
64
- // get general target setting
65
- $options = Advanced_Ads::get_instance()->options();
66
- $target_blank = !empty( $options['target-blank'] ) ? ' target="_blank"' : '';
67
-
68
- ob_start();
69
- if( ! defined( 'AAT_VERSION' ) && $url ){ echo '<a href="'. $url .'"'.$target_blank.'>'; }
70
- echo '<img src="' . ADVADS_BASE_URL . 'public/assets/img/dummy.jpg" width="300" height="250"/>';
71
- if( ! defined( 'AAT_VERSION' ) && $url ){ echo '</a>'; }
72
 
73
- return ob_get_clean();
 
 
 
74
 
 
75
  }
76
 
77
  }
25
  public function __construct() {
26
  $this->title = __( 'Dummy', 'advanced-ads' );
27
  $this->description = __( 'Uses a simple placeholder ad for quick testing.', 'advanced-ads' );
28
+
29
  }
30
 
31
  /**
38
  * @param obj $ad ad object
39
  */
40
  public function render_parameters( $ad ){
41
+
42
  // don’t show url field if tracking plugin enabled
43
  if( ! defined( 'AAT_VERSION' )) :
44
  $url = ( ! empty( $ad->url ) ) ? esc_attr( $ad->url ) : home_url();
45
  ?><span class="label"><?php _e( 'URL', 'advanced-ads' ); ?></span>
46
  <div><input type="text" name="advanced_ad[url]" id="advads-url" class="advads-ad-url" value="<?php echo $url; ?>"/></div><hr/>
47
  <?php endif;
48
+
49
  ?><img src="<?php echo ADVADS_BASE_URL ?>public/assets/img/dummy.jpg" width="300" height="250"/><?php
50
+
51
  ?><input type="hidden" name="advanced_ad[width]" value="300"/>
52
  <input type="hidden" name="advanced_ad[height]" value="250"/><?php
53
  }
54
+
55
  /**
56
+ * Prepare the ads frontend output.
57
  *
58
+ * @param Advanced_Ads_Ad $ad The ad object.
59
+ *
60
+ * @return string static image content.
61
  */
62
+ public function prepare_output( $ad ) {
63
+ $img = '<img src="' . ADVADS_BASE_URL . 'public/assets/img/dummy.jpg" width="300" height="250"/>';
64
+ $url = ( isset( $ad->url ) ) ? esc_url( $ad->url ) : '';
65
+ if ( ! defined( 'AAT_VERSION' ) && $url ) {
66
+ // get general target setting.
67
+ $options = Advanced_Ads::get_instance()->options();
68
+ $target_blank = ! empty( $options['target-blank'] ) ? ' target="_blank"' : '';
69
+ $img = sprintf( '<a href="%s"%s>%s</a>', esc_url( $url ), $target_blank, $img );
70
+ }
 
 
71
 
72
+ // Add 'loading' attribute if applicable, available from WP 5.5.
73
+ if ( function_exists( 'wp_lazy_loading_enabled' ) && wp_lazy_loading_enabled( 'img', 'the_content' ) ) {
74
+ $img = wp_img_tag_add_loading_attr( $img, 'the_content' );
75
+ }
76
 
77
+ return $img;
78
  }
79
 
80
  }
classes/ad_type_image.php CHANGED
@@ -89,60 +89,78 @@ class Advanced_Ads_Ad_Type_Image extends Advanced_Ads_Ad_Type_Abstract {
89
  $image = wp_get_attachment_image_src( $attachment_id, 'full' );
90
  $style = '';
91
 
92
- if ( $image ) {
93
- list( $src, $width, $height ) = $image;
94
- // override image sizes with the sizes given in ad options, but in frontend only
95
- if ( ! is_admin() || ( // is frontend
96
- is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) ) { // is AJAX call (cache-busting)
97
- $width = isset( $ad->width ) ? absint( $ad->width ) : $width;
98
- $height = isset( $ad->height ) ? absint( $ad->height ) : $height;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  }
100
- $hwstring = image_hwstring( $width, $height );
101
- $attachment = get_post( $attachment_id );
102
- $alt = trim( esc_textarea( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) );
103
-
104
- global $wp_current_filter;
105
-
106
- // TODO: use an array for attributes so they are simpler to extend
107
- $sizes = '';
108
- $srcset = '';
109
- $more_attributes = $srcset;
110
- // create srcset and sizes attributes if we are in the the_content filter and in WordPress 4.4
111
- if ( isset( $wp_current_filter )
112
- && in_array( 'the_content', $wp_current_filter, true )
113
- && ! defined( 'ADVADS_DISABLE_RESPONSIVE_IMAGES' ) ) {
114
- if ( function_exists( 'wp_get_attachment_image_srcset' ) ) {
115
- $srcset = wp_get_attachment_image_srcset( $attachment_id, 'full' );
116
- }
117
- if ( function_exists( 'wp_get_attachment_image_sizes' ) ) {
118
- $sizes = wp_get_attachment_image_sizes( $attachment_id, 'full' );
119
- }
120
- if ( $srcset && $sizes ) {
121
- $more_attributes .= ' srcset="' . $srcset . '" sizes="' . $sizes . '"';
122
- }
123
  }
124
-
125
- // TODO: move to classes/compabtility.php when we have a simpler filter for additional attributes
126
- // compabitility with WP Smush. Disables their lazy load for image ads because it caused them to not show up in certain positions at all.
127
- $wp_smush_settings = get_option( 'wp-smush-settings' );
128
- if ( isset( $wp_smush_settings['lazy_load'] ) && $wp_smush_settings['lazy_load'] ) {
129
- // Lazy load is enabled.
130
- $more_attributes .= ' class="no-lazyload"';
131
  }
 
132
 
133
- // add css rule to be able to center the ad.
134
- if ( isset( $ad->output['position'] ) && 'center' === $ad->output['position'] ) {
135
- $style .= 'display: inline-block;';
136
- }
 
 
 
 
 
 
 
 
137
 
138
- $style = apply_filters( 'advanced-ads-ad-image-tag-style', $style );
139
- $style = '' !== $style ? 'style="' . $style . '"' : '';
140
 
141
- $more_attributes = apply_filters( 'advanced-ads-ad-image-tag-attributes', $more_attributes );
 
 
142
 
143
- //phpcs:ignore
144
- echo rtrim( "<img $hwstring" ) . " src='$src' alt='$alt' $more_attributes $style/>";
 
 
 
 
 
 
145
  }
 
 
 
146
  }
147
 
148
  /**
@@ -165,12 +183,11 @@ class Advanced_Ads_Ad_Type_Image extends Advanced_Ads_Ad_Type_Abstract {
165
  $height = 100;
166
  }
167
 
168
- $hwstring = trim( image_hwstring( $width, $height ) );
169
- $attachment = get_post( $attachment_id );
170
- $alt = trim( wp_strip_all_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) );
171
 
172
- //phpcs:ignore
173
- echo "<img $hwstring src='$src' alt='$alt' />";
174
  }
175
  }
176
 
@@ -184,18 +201,18 @@ class Advanced_Ads_Ad_Type_Image extends Advanced_Ads_Ad_Type_Abstract {
184
 
185
  $id = ( isset( $ad->output['image_id'] ) ) ? absint( $ad->output['image_id'] ) : '';
186
  $url = ( isset( $ad->url ) ) ? esc_url( $ad->url ) : '';
187
- // get general target setting
188
- $options = Advanced_Ads::get_instance()->options();
189
- $target_blank = ! empty( $options['target-blank'] ) ? ' target="_blank"' : '';
190
 
191
  ob_start();
 
 
192
  if ( ! defined( 'AAT_VERSION' ) && $url ) {
193
- echo '<a href="' . esc_url( $url ) . '"' . esc_attr( $target_blank ) . '>'; }
194
- echo $this->create_image_tag( $id, $ad );
195
- if ( ! defined( 'AAT_VERSION' ) && $url ) {
196
- echo '</a>'; }
 
197
 
198
- return ob_get_clean();
199
  }
200
 
201
  /**
89
  $image = wp_get_attachment_image_src( $attachment_id, 'full' );
90
  $style = '';
91
 
92
+ // if we don't have an image, bail early.
93
+ if ( ! $image ) {
94
+ return;
95
+ }
96
+
97
+ list( $src, $width, $height ) = $image;
98
+ // override image sizes with the sizes given in ad options, but in frontend only
99
+ if (
100
+ ! is_admin()
101
+ || ( defined( 'DOING_AJAX' ) && DOING_AJAX )
102
+ ) {
103
+ $width = isset( $ad->width ) ? absint( $ad->width ) : $width;
104
+ $height = isset( $ad->height ) ? absint( $ad->height ) : $height;
105
+ }
106
+ $hwstring = image_hwstring( $width, $height );
107
+ $alt = trim( esc_textarea( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) );
108
+
109
+ global $wp_current_filter;
110
+
111
+ // TODO: use an array for attributes so they are simpler to extend
112
+ $sizes = '';
113
+ $srcset = '';
114
+ $more_attributes = $srcset;
115
+ // create srcset and sizes attributes if we are in the the_content filter and in WordPress 4.4
116
+ if (
117
+ isset( $wp_current_filter )
118
+ && in_array( 'the_content', $wp_current_filter, true )
119
+ && ! defined( 'ADVADS_DISABLE_RESPONSIVE_IMAGES' )
120
+ ) {
121
+ if ( function_exists( 'wp_get_attachment_image_srcset' ) ) {
122
+ $srcset = wp_get_attachment_image_srcset( $attachment_id, 'full' );
123
  }
124
+ if ( function_exists( 'wp_get_attachment_image_sizes' ) ) {
125
+ $sizes = wp_get_attachment_image_sizes( $attachment_id, 'full' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  }
127
+ if ( $srcset && $sizes ) {
128
+ $more_attributes .= ' srcset="' . $srcset . '" sizes="' . $sizes . '"';
 
 
 
 
 
129
  }
130
+ }
131
 
132
+ // TODO: move to classes/compabtility.php when we have a simpler filter for additional attributes
133
+ // compabitility with WP Smush. Disables their lazy load for image ads because it caused them to not show up in certain positions at all.
134
+ $wp_smush_settings = get_option( 'wp-smush-settings' );
135
+ if ( isset( $wp_smush_settings['lazy_load'] ) && $wp_smush_settings['lazy_load'] ) {
136
+ // Lazy load is enabled.
137
+ $more_attributes .= ' class="no-lazyload"';
138
+ }
139
+
140
+ // add css rule to be able to center the ad.
141
+ if ( isset( $ad->output['position'] ) && 'center' === $ad->output['position'] ) {
142
+ $style .= 'display: inline-block;';
143
+ }
144
 
145
+ $style = apply_filters( 'advanced-ads-ad-image-tag-style', $style );
146
+ $style = '' !== $style ? 'style="' . $style . '"' : '';
147
 
148
+ $more_attributes = apply_filters( 'advanced-ads-ad-image-tag-attributes', $more_attributes );
149
+ $more_attributes .= $hwstring . ' ' . $style;
150
+ $img = sprintf( '<img src="%s" alt="%s" %s />', esc_url( $src ), esc_attr( $alt ), $more_attributes );
151
 
152
+ // Add 'loading' attribute if applicable, available from WP 5.5.
153
+ if (
154
+ $wp_current_filter
155
+ && function_exists( 'wp_lazy_loading_enabled' )
156
+ && wp_lazy_loading_enabled( 'img', $wp_current_filter )
157
+ && ! strpos( $more_attributes, 'loading=' )
158
+ ) {
159
+ $img = wp_img_tag_add_loading_attr( $img, $wp_current_filter );
160
  }
161
+
162
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- use unescaped image tag here
163
+ echo $img;
164
  }
165
 
166
  /**
183
  $height = 100;
184
  }
185
 
186
+ $hwstring = trim( image_hwstring( $width, $height ) );
187
+ $alt = trim( wp_strip_all_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) );
 
188
 
189
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $hwstring is not something we can escape.
190
+ printf( '<img src="%s" alt="%s" %s/>', esc_url( $src ), esc_attr( $alt ), $hwstring );
191
  }
192
  }
193
 
201
 
202
  $id = ( isset( $ad->output['image_id'] ) ) ? absint( $ad->output['image_id'] ) : '';
203
  $url = ( isset( $ad->url ) ) ? esc_url( $ad->url ) : '';
 
 
 
204
 
205
  ob_start();
206
+ $this->create_image_tag( $id, $ad );
207
+ $img = ob_get_clean();
208
  if ( ! defined( 'AAT_VERSION' ) && $url ) {
209
+ // get general target setting
210
+ $options = Advanced_Ads::get_instance()->options();
211
+ $target_blank = ! empty( $options['target-blank'] ) ? ' target="_blank"' : '';
212
+ $img = sprintf( '<a href="%s"%s>%s</a>', esc_url( $url ), $target_blank, $img );
213
+ }
214
 
215
+ return $img;
216
  }
217
 
218
  /**
classes/ad_type_plain.php CHANGED
@@ -139,27 +139,48 @@ class Advanced_Ads_Ad_Type_Plain extends Advanced_Ads_Ad_Type_Abstract {
139
  /**
140
  * Prepare the ads frontend output
141
  *
142
- * @param object $ad ad object.
143
  *
144
  * @return string $content ad content prepared for frontend output.
145
  * @since 1.0.0
146
  */
147
  public function prepare_output( $ad ) {
148
-
149
  // Evaluate the code as PHP if setting was never saved or is allowed.
150
  if ( ! defined( 'ADVANCED_ADS_DISALLOW_PHP' ) && ( ! isset( $ad->output['allow_php'] ) || $ad->output['allow_php'] ) ) {
151
  ob_start();
152
  // This code only runs if the "Allow PHP" option for plain text ads was enabled.
 
153
  eval( '?>' . $ad->content );
154
  $content = ob_get_clean();
155
- } else {
156
- $content = $ad->content;
 
 
157
  }
158
 
159
  if ( ! empty( $ad->output['allow_shortcodes'] ) ) {
160
  $content = $this->do_shortcode( $content, $ad );
161
  }
162
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  return $content;
164
  }
165
 
139
  /**
140
  * Prepare the ads frontend output
141
  *
142
+ * @param Advanced_Ads_Ad $ad ad object.
143
  *
144
  * @return string $content ad content prepared for frontend output.
145
  * @since 1.0.0
146
  */
147
  public function prepare_output( $ad ) {
148
+ $content = $ad->content;
149
  // Evaluate the code as PHP if setting was never saved or is allowed.
150
  if ( ! defined( 'ADVANCED_ADS_DISALLOW_PHP' ) && ( ! isset( $ad->output['allow_php'] ) || $ad->output['allow_php'] ) ) {
151
  ob_start();
152
  // This code only runs if the "Allow PHP" option for plain text ads was enabled.
153
+ // phpcs:ignore Squiz.PHP.Eval.Discouraged -- this is specifically eval'd so allow eval here.
154
  eval( '?>' . $ad->content );
155
  $content = ob_get_clean();
156
+ }
157
+
158
+ if ( ! is_string( $content ) ) {
159
+ return '';
160
  }
161
 
162
  if ( ! empty( $ad->output['allow_shortcodes'] ) ) {
163
  $content = $this->do_shortcode( $content, $ad );
164
  }
165
 
166
+ // Add 'loading' attribute if applicable, available from WP 5.5.
167
+ if (
168
+ function_exists( 'wp_lazy_loading_enabled' )
169
+ && wp_lazy_loading_enabled( 'img', 'the_content' )
170
+ && preg_match_all( '/<img\s[^>]+>/', $content, $matches )
171
+ ) {
172
+ // iterate images.
173
+ foreach ( $matches[0] as $image ) {
174
+ // skip if it already has the loading attribute.
175
+ if ( strpos( $image, 'loading=' ) !== false ) {
176
+ continue;
177
+ }
178
+
179
+ // replace the image string.
180
+ $content = str_replace( $image, wp_img_tag_add_loading_attr( $image, 'the_content' ), $content );
181
+ }
182
+ }
183
+
184
  return $content;
185
  }
186
 
languages/advanced-ads.pot CHANGED
@@ -2,14 +2,14 @@
2
  # This file is distributed under the same license as the Advanced Ads plugin.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Advanced Ads 1.19.0\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/advanced-ads/\n"
7
  "Last-Translator: Thomas Maier <post@webzunft.de>\n"
8
  "Language-Team: webgilde <support@wpadvancedads.com>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "POT-Creation-Date: 2020-08-05T08:31:33+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: advanced-ads\n"
@@ -461,64 +461,65 @@ msgstr ""
461
  msgid "A quick and error-free way of implementing ad units from your Google Ad Manager account."
462
  msgstr ""
463
 
464
- #: admin/includes/class-licenses.php:90
 
465
  msgid "There might be a new version of %1$s. Please <strong>provide a valid license key</strong> in order to receive updates and support <a href=\"%2$s\">on this page</a>."
466
  msgstr ""
467
 
468
- #: admin/includes/class-licenses.php:110
469
  msgid "Error while trying to register the license. Please contact support."
470
  msgstr ""
471
 
472
- #: admin/includes/class-licenses.php:115
473
  #: admin/views/setting-license.php:85
474
  msgid "Please enter a valid license key"
475
  msgstr ""
476
 
477
- #: admin/includes/class-licenses.php:172
478
  msgid "License couldn’t be activated. Please try again later."
479
  msgstr ""
480
 
481
- #: admin/includes/class-licenses.php:189
482
  msgid "This is the bundle license key."
483
  msgstr ""
484
 
485
- #: admin/includes/class-licenses.php:190
486
  msgid "This is not the correct key for this add-on."
487
  msgstr ""
488
 
489
- #: admin/includes/class-licenses.php:191
490
  msgid "There are no activations left."
491
  msgstr ""
492
 
493
  #. translators: %1$s is a starting link tag, %2$s is the closing one.
494
- #: admin/includes/class-licenses.php:194
495
  msgid "You can manage activations in %1$syour account%2$s."
496
  msgstr ""
497
 
498
  #. translators: %s is a string containing information about the issue.
499
- #: admin/includes/class-licenses.php:208
500
  msgid "License is invalid. Reason: %s"
501
  msgstr ""
502
 
503
  #. translators: %s is a list of server information like IP address. Just keep it as is.
504
- #: admin/includes/class-licenses.php:248
505
  msgid "Your request was blocked by our firewall. Please send us the following information to unblock you: %s."
506
  msgstr ""
507
 
508
- #: admin/includes/class-licenses.php:312
509
  msgid "Error while trying to disable the license. Please contact support."
510
  msgstr ""
511
 
512
- #: admin/includes/class-licenses.php:347
513
- #: admin/includes/class-licenses.php:370
514
  msgid "License couldn’t be deactivated. Please try again later."
515
  msgstr ""
516
 
517
- #: admin/includes/class-licenses.php:599
518
  msgid "Download failed. <a href=\"%s\">Click here to try another method</a>."
519
  msgstr ""
520
 
521
- #: admin/includes/class-licenses.php:601
522
  msgid "Download failed. <a href=\"%s\" target=\"_blank\">Click here to learn why</a>."
523
  msgstr ""
524
 
@@ -2680,7 +2681,7 @@ msgid "Link to target site including http(s)"
2680
  msgstr ""
2681
 
2682
  #. translators: $s is a size string like "728 x 90".
2683
- #: classes/ad_type_image.php:226
2684
  msgid "Original size: %s"
2685
  msgstr ""
2686
 
2
  # This file is distributed under the same license as the Advanced Ads plugin.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Advanced Ads 1.19.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/advanced-ads/\n"
7
  "Last-Translator: Thomas Maier <post@webzunft.de>\n"
8
  "Language-Team: webgilde <support@wpadvancedads.com>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2020-08-12T08:03:35+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: advanced-ads\n"
461
  msgid "A quick and error-free way of implementing ad units from your Google Ad Manager account."
462
  msgstr ""
463
 
464
+ #. Translators: 1: add-on name 2: admin URL to license page
465
+ #: admin/includes/class-licenses.php:95
466
  msgid "There might be a new version of %1$s. Please <strong>provide a valid license key</strong> in order to receive updates and support <a href=\"%2$s\">on this page</a>."
467
  msgstr ""
468
 
469
+ #: admin/includes/class-licenses.php:118
470
  msgid "Error while trying to register the license. Please contact support."
471
  msgstr ""
472
 
473
+ #: admin/includes/class-licenses.php:123
474
  #: admin/views/setting-license.php:85
475
  msgid "Please enter a valid license key"
476
  msgstr ""
477
 
478
+ #: admin/includes/class-licenses.php:180
479
  msgid "License couldn’t be activated. Please try again later."
480
  msgstr ""
481
 
482
+ #: admin/includes/class-licenses.php:197
483
  msgid "This is the bundle license key."
484
  msgstr ""
485
 
486
+ #: admin/includes/class-licenses.php:198
487
  msgid "This is not the correct key for this add-on."
488
  msgstr ""
489
 
490
+ #: admin/includes/class-licenses.php:199
491
  msgid "There are no activations left."
492
  msgstr ""
493
 
494
  #. translators: %1$s is a starting link tag, %2$s is the closing one.
495
+ #: admin/includes/class-licenses.php:202
496
  msgid "You can manage activations in %1$syour account%2$s."
497
  msgstr ""
498
 
499
  #. translators: %s is a string containing information about the issue.
500
+ #: admin/includes/class-licenses.php:216
501
  msgid "License is invalid. Reason: %s"
502
  msgstr ""
503
 
504
  #. translators: %s is a list of server information like IP address. Just keep it as is.
505
+ #: admin/includes/class-licenses.php:256
506
  msgid "Your request was blocked by our firewall. Please send us the following information to unblock you: %s."
507
  msgstr ""
508
 
509
+ #: admin/includes/class-licenses.php:320
510
  msgid "Error while trying to disable the license. Please contact support."
511
  msgstr ""
512
 
513
+ #: admin/includes/class-licenses.php:355
514
+ #: admin/includes/class-licenses.php:378
515
  msgid "License couldn’t be deactivated. Please try again later."
516
  msgstr ""
517
 
518
+ #: admin/includes/class-licenses.php:607
519
  msgid "Download failed. <a href=\"%s\">Click here to try another method</a>."
520
  msgstr ""
521
 
522
+ #: admin/includes/class-licenses.php:609
523
  msgid "Download failed. <a href=\"%s\" target=\"_blank\">Click here to learn why</a>."
524
  msgstr ""
525
 
2681
  msgstr ""
2682
 
2683
  #. translators: $s is a size string like "728 x 90".
2684
+ #: classes/ad_type_image.php:243
2685
  msgid "Original size: %s"
2686
  msgstr ""
2687
 
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: webzunft, advancedads
3
  Tags: ads, ad manager, ad rotation, adsense, banner
4
  Requires at least: 4.6
5
- Tested up to: 5.4
6
  Requires PHP: 5.6
7
- Stable tag: 1.19.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -312,6 +312,11 @@ Yes. You can use plenty of [hooks](https://wpadvancedads.com/codex/) to customiz
312
 
313
  == Changelog ==
314
 
 
 
 
 
 
315
  = 1.19.0 =
316
 
317
  - placements are now ordered by type on the Placements page. You can still choose ordering by name
2
  Contributors: webzunft, advancedads
3
  Tags: ads, ad manager, ad rotation, adsense, banner
4
  Requires at least: 4.6
5
+ Tested up to: 5.5
6
  Requires PHP: 5.6
7
+ Stable tag: 1.19.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
312
 
313
  == Changelog ==
314
 
315
+ = 1.19.1 =
316
+
317
+ - apply WordPress lazy loading for images to images in ad content
318
+ - layout fixes for WordPress 5.5
319
+
320
  = 1.19.0 =
321
 
322
  - placements are now ordered by type on the Placements page. You can still choose ordering by name