class-ad-display-condition.php
1 year ago
class-ad-renderer.php
1 week ago
class-debug-ads.php
1 year ago
class-manager.php
1 year ago
class-scripts.php
2 months ago
class-stats.php
1 year ago
class-debug-ads.php
348 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Frontend Debug Ads. |
| 4 | * |
| 5 | * @package AdvancedAds |
| 6 | * @author Advanced Ads <info@wpadvancedads.com> |
| 7 | * @since 1.50.0 |
| 8 | */ |
| 9 | |
| 10 | namespace AdvancedAds\Frontend; |
| 11 | |
| 12 | use AdvancedAds\Abstracts\Ad; |
| 13 | use Advanced_Ads_Display_Conditions; |
| 14 | use Advanced_Ads_Visitor_Conditions; |
| 15 | use AdvancedAds\Utilities\Validation; |
| 16 | use AdvancedAds\Utilities\Conditional; |
| 17 | use AdvancedAds\Framework\Utilities\Str; |
| 18 | use AdvancedAds\Framework\Interfaces\Integration_Interface; |
| 19 | |
| 20 | defined( 'ABSPATH' ) || exit; |
| 21 | |
| 22 | /** |
| 23 | * Frontend Debug Ads. |
| 24 | */ |
| 25 | class Debug_Ads implements Integration_Interface { |
| 26 | |
| 27 | /** |
| 28 | * Hook into WordPress. |
| 29 | * |
| 30 | * @return void |
| 31 | */ |
| 32 | public function hooks(): void { |
| 33 | add_action( 'advanced-ads-ad-pre-output', [ $this, 'override_ad_output' ], 50, 2 ); |
| 34 | } |
| 35 | |
| 36 | /** |
| 37 | * Override ad output. |
| 38 | * |
| 39 | * @param string $output Override content. |
| 40 | * @param Ad $ad Ad object. |
| 41 | * |
| 42 | * @return string |
| 43 | */ |
| 44 | public function override_ad_output( $output, $ad ) { |
| 45 | $user_can_manage_ads = Conditional::user_can( 'advanced_ads_manage_options' ); |
| 46 | if ( |
| 47 | $ad->is_debug_mode() && |
| 48 | ( $user_can_manage_ads || ( ! $user_can_manage_ads && ! defined( 'ADVANCED_ADS_AD_DEBUG_FOR_ADMIN_ONLY' ) ) ) |
| 49 | ) { |
| 50 | return $this->prepare_output( $ad ); |
| 51 | } |
| 52 | |
| 53 | return $output; |
| 54 | } |
| 55 | |
| 56 | /** |
| 57 | * Prepare debug mode output. |
| 58 | * |
| 59 | * @param Ad $ad Ad instance. |
| 60 | * |
| 61 | * @return string The ad debug output. |
| 62 | */ |
| 63 | private function prepare_output( Ad $ad ): string { |
| 64 | global $post, $wp_query; |
| 65 | |
| 66 | $width = 300; |
| 67 | $height = 250; |
| 68 | if ( $ad->get_width() > 100 && $ad->get_height() > 100 ) { |
| 69 | $width = $ad->get_width(); |
| 70 | $height = $ad->get_height(); |
| 71 | } |
| 72 | |
| 73 | $style = "width:{$width}px;height:{$height}px;background-color:#ddd;overflow:scroll;"; |
| 74 | $style_full = 'width: 100%; height: 100vh; background-color: #ddd; overflow: scroll; position: fixed; top: 0; left: 0; min-width: 600px; z-index: 99999;'; |
| 75 | $wrapper_id = Str::is_non_empty( $ad->get_wrapper_id() ) |
| 76 | ? $ad->get_wrapper_id() |
| 77 | : wp_advads()->get_frontend_prefix() . wp_rand(); |
| 78 | |
| 79 | $content = []; |
| 80 | |
| 81 | if ( $ad->can_display( [ 'ignore_debugmode' => true ] ) ) { |
| 82 | $content[] = __( 'The ad is displayed on the page', 'advanced-ads' ); |
| 83 | } else { |
| 84 | $content[] = __( 'The ad is not displayed on the page', 'advanced-ads' ); |
| 85 | } |
| 86 | |
| 87 | // Compare current wp_query with global wp_main_query. |
| 88 | if ( ! $wp_query->is_main_query() ) { |
| 89 | $content[] = sprintf( '<span style="color: red;">%s</span>', __( 'Current query is not identical to main query.', 'advanced-ads' ) ); |
| 90 | $content[] = $this->build_query_diff_table(); |
| 91 | } |
| 92 | |
| 93 | if ( isset( $post->post_title ) && isset( $post->ID ) ) { |
| 94 | $content[] = sprintf( '%s: %s, %s: %s', __( 'current post', 'advanced-ads' ), $post->post_title, 'ID', $post->ID ); |
| 95 | } |
| 96 | |
| 97 | // Compare current post with global post. |
| 98 | if ( $wp_query->post !== $post ) { |
| 99 | $error = sprintf( '<span style="color: red;">%s</span>', __( 'Current post is not identical to main post.', 'advanced-ads' ) ); |
| 100 | if ( isset( $wp_query->post->post_title ) && $wp_query->post->ID ) { |
| 101 | $error .= sprintf( '<br />%s: %s, %s: %s', __( 'main post', 'advanced-ads' ), $wp_query->post->post_title, 'ID', $wp_query->post->ID ); |
| 102 | } |
| 103 | $content[] = $error; |
| 104 | } |
| 105 | |
| 106 | $content[] = $this->build_call_chain( $ad ); |
| 107 | $content[] = $this->build_display_conditions_table( $ad ); |
| 108 | $content[] = $this->build_visitor_conditions_table( $ad ); |
| 109 | |
| 110 | $message = Validation::is_ad_https( $ad ); |
| 111 | if ( $message ) { |
| 112 | $content[] = sprintf( '<span style="color: red;">%s</span>', $message ); |
| 113 | } |
| 114 | |
| 115 | $content = apply_filters( 'advanced-ads-ad-output-debug-content', $content, $ad ); |
| 116 | $content = array_filter( |
| 117 | $content, |
| 118 | fn( $value ) => ! empty( $value ) |
| 119 | ); |
| 120 | |
| 121 | ob_start(); |
| 122 | |
| 123 | include ADVADS_ABSPATH . '/public/views/ad-debug.php'; |
| 124 | |
| 125 | $output = ob_get_clean(); |
| 126 | $output = apply_filters( 'advanced-ads-ad-output-debug', $output, $ad ); |
| 127 | $output = apply_filters( 'advanced-ads-ad-output', $output, $ad ); |
| 128 | |
| 129 | return $output; |
| 130 | } |
| 131 | |
| 132 | /** |
| 133 | * Build table with differences between current and main query |
| 134 | * |
| 135 | * @since 1.7.0.3 |
| 136 | */ |
| 137 | private function build_query_diff_table() { |
| 138 | global $wp_query, $wp_the_query; |
| 139 | |
| 140 | $diff_current = array_diff_assoc( $wp_query->query_vars, $wp_the_query->query_vars ); |
| 141 | $diff_main = array_diff_assoc( $wp_the_query->query_vars, $wp_query->query_vars ); |
| 142 | |
| 143 | if ( ! is_array( $diff_current ) || ! is_array( $diff_main ) ) { |
| 144 | return ''; |
| 145 | } |
| 146 | |
| 147 | ob_start(); |
| 148 | |
| 149 | ?> |
| 150 | <table> |
| 151 | <thead> |
| 152 | <tr> |
| 153 | <th></th> |
| 154 | <th><?php esc_html_e( 'current query', 'advanced-ads' ); ?></th> |
| 155 | <th><?php esc_html_e( 'main query', 'advanced-ads' ); ?></th> |
| 156 | </tr> |
| 157 | </thead> |
| 158 | <?php foreach ( $diff_current as $_key => $_value ) : ?> |
| 159 | <tr> |
| 160 | <td><?php echo esc_html( $_key ); ?></td> |
| 161 | <td><?php echo esc_html( $_value ); ?></td> |
| 162 | <td><?php echo esc_html( $diff_main[ $_key ] ?? '' ); ?></td> |
| 163 | </tr> |
| 164 | <?php endforeach; ?> |
| 165 | </table> |
| 166 | <?php |
| 167 | |
| 168 | return ob_get_clean(); |
| 169 | } |
| 170 | |
| 171 | /** |
| 172 | * Build call chain (placement->group->ad) |
| 173 | * |
| 174 | * @param Ad $ad Ad instance. |
| 175 | * |
| 176 | * @return string |
| 177 | */ |
| 178 | private function build_call_chain( Ad $ad ) { |
| 179 | $output = ''; |
| 180 | |
| 181 | $output .= sprintf( |
| 182 | '%s: %s (%s)', |
| 183 | __( 'Ad', 'advanced-ads' ), |
| 184 | esc_html( $ad->get_title() ), |
| 185 | $ad->get_id() |
| 186 | ); |
| 187 | |
| 188 | if ( $ad->get_parent() ) { |
| 189 | $output .= sprintf( |
| 190 | '<br />%s: %s (%s)', |
| 191 | $ad->get_parent_entity_name(), |
| 192 | esc_html( $ad->get_parent()->get_title() ), |
| 193 | $ad->get_parent()->get_id() |
| 194 | ); |
| 195 | } |
| 196 | |
| 197 | return $output; |
| 198 | } |
| 199 | |
| 200 | /** |
| 201 | * Build display conditions table. |
| 202 | * |
| 203 | * @param Ad $ad Ad instance. |
| 204 | * |
| 205 | * @return string |
| 206 | */ |
| 207 | private function build_display_conditions_table( Ad $ad ) { |
| 208 | $conditions = $ad->get_display_conditions(); |
| 209 | if ( ! is_array( $conditions ) || empty( $conditions ) ) { |
| 210 | return; |
| 211 | } |
| 212 | |
| 213 | $display_conditions = Advanced_Ads_Display_Conditions::get_instance()->conditions; |
| 214 | $the_query = Advanced_Ads_Display_Conditions::get_instance()->ad_select_args_callback( [] ); |
| 215 | |
| 216 | ob_start(); |
| 217 | esc_html_e( 'Display Conditions', 'advanced-ads' ); |
| 218 | |
| 219 | foreach ( $conditions as $_condition ) { |
| 220 | if ( |
| 221 | ! is_array( $_condition ) || |
| 222 | ! isset( $_condition['type'] ) || |
| 223 | ! isset( $display_conditions[ $_condition['type'] ]['check'][1] ) |
| 224 | ) { |
| 225 | continue; |
| 226 | } |
| 227 | |
| 228 | printf( |
| 229 | '<div style="margin-bottom: 20px; white-space: pre-wrap; font-family: monospace; width: 100%%; background: %s;"><strong>%s</strong>', |
| 230 | Advanced_Ads_Display_Conditions::frontend_check( $_condition, $ad ) ? '#e9ffe9' : '#ffe9e9', |
| 231 | esc_html( $display_conditions[ $_condition['type'] ]['label'] ) |
| 232 | ); |
| 233 | |
| 234 | $check = $display_conditions[ $_condition['type'] ]['check'][1]; |
| 235 | if ( 'check_general' === $check ) { |
| 236 | printf( '<table border="1"><thead><tr><th></th><th>%s</th><th>%s</th></tr></thead>', esc_html__( 'Ad', 'advanced-ads' ), 'wp_the_query' ); |
| 237 | } else { |
| 238 | printf( '<table border="1"><thead><tr><th>%s</th><th>%s</th></tr></thead>', esc_html__( 'Ad', 'advanced-ads' ), 'wp_the_query' ); |
| 239 | } |
| 240 | |
| 241 | switch ( $check ) { |
| 242 | case 'check_post_type': |
| 243 | printf( |
| 244 | '<tr><td>%s</td><td>%s</td></tr>', |
| 245 | isset( $_condition['value'] ) && is_array( $_condition['value'] ) ? esc_html( implode( ',', $_condition['value'] ) ) : '', |
| 246 | isset( $the_query['post']['post_type'] ) ? esc_html( $the_query['post']['post_type'] ) : '' |
| 247 | ); |
| 248 | break; |
| 249 | case 'check_general': |
| 250 | if ( isset( $the_query['wp_the_query'] ) && is_array( $the_query['wp_the_query'] ) ) { |
| 251 | $ad_vars = ( isset( $_condition['value'] ) && is_array( $_condition['value'] ) ) ? $_condition['value'] : []; |
| 252 | |
| 253 | if ( in_array( 'is_front_page', $ad_vars, true ) ) { |
| 254 | $ad_vars[] = 'is_home'; |
| 255 | } |
| 256 | |
| 257 | foreach ( $the_query['wp_the_query'] as $_var => $_flag ) { |
| 258 | printf( |
| 259 | '<tr><td>%s</td><td>%s</td><td>%s</td></tr>', |
| 260 | esc_html( $_var ), |
| 261 | in_array( $_var, $ad_vars, true ) ? 1 : 0, |
| 262 | esc_html( $_flag ) |
| 263 | ); |
| 264 | } |
| 265 | } |
| 266 | break; |
| 267 | case 'check_author': |
| 268 | printf( |
| 269 | '<tr><td>%s</td><td>%s</td></tr>', |
| 270 | isset( $_condition['value'] ) && is_array( $_condition['value'] ) ? esc_html( implode( ',', $_condition['value'] ) ) : '', |
| 271 | isset( $the_query['post']['author'] ) ? esc_html( $the_query['post']['author'] ) : '' |
| 272 | ); |
| 273 | break; |
| 274 | case 'check_post_ids': |
| 275 | case 'check_taxonomies': |
| 276 | printf( |
| 277 | '<tr><td>%s</td><td>post_id: %s<br />is_singular: %s</td></tr>', |
| 278 | isset( $_condition['value'] ) && is_array( $_condition['value'] ) ? esc_html( implode( ',', $_condition['value'] ) ) : '', |
| 279 | isset( $the_query['post']['id'] ) ? esc_html( $the_query['post']['id'] ) : '', |
| 280 | ! empty( $the_query['wp_the_query']['is_singular'] ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 281 | ); |
| 282 | break; |
| 283 | case 'check_taxonomy_archive': |
| 284 | printf( |
| 285 | '<tr><td>%s</td><td>term_id: %s<br />is_archive: %s</td></tr>', |
| 286 | isset( $_condition['value'] ) && is_array( $_condition['value'] ) ? esc_html( implode( ',', $_condition['value'] ) ) : '', |
| 287 | isset( $the_query['wp_the_query']['term_id'] ) ? esc_html( $the_query['wp_the_query']['term_id'] ) : '', |
| 288 | ! empty( $the_query['wp_the_query']['is_archive'] ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 289 | ); |
| 290 | break; |
| 291 | default: |
| 292 | printf( |
| 293 | '<tr><td>%s</td><td>%s</td></tr>', |
| 294 | esc_html( print_r( $_condition, true ) ), // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r |
| 295 | print_r( $the_query, true ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.PHP.DevelopmentFunctions.error_log_print_r |
| 296 | ); |
| 297 | break; |
| 298 | } |
| 299 | |
| 300 | echo '</table></div>'; |
| 301 | } |
| 302 | |
| 303 | return ob_get_clean(); |
| 304 | } |
| 305 | |
| 306 | /** |
| 307 | * Build visitor conditions table. |
| 308 | * |
| 309 | * @param Ad $ad Ad instance. |
| 310 | * |
| 311 | * @return string |
| 312 | */ |
| 313 | private function build_visitor_conditions_table( Ad $ad ) { |
| 314 | $conditions = $ad->get_visitor_conditions(); |
| 315 | if ( ! is_array( $conditions ) || empty( $conditions ) ) { |
| 316 | return; |
| 317 | } |
| 318 | |
| 319 | ob_start(); |
| 320 | |
| 321 | $visitor_conditions = Advanced_Ads_Visitor_Conditions::get_instance()->conditions; |
| 322 | esc_html_e( 'Visitor Conditions', 'advanced-ads' ); |
| 323 | |
| 324 | foreach ( $conditions as $_condition ) { |
| 325 | if ( |
| 326 | ! is_array( $_condition ) || |
| 327 | ! isset( $_condition['type'] ) || |
| 328 | ! isset( $visitor_conditions[ $_condition['type'] ]['check'][1] ) |
| 329 | ) { |
| 330 | continue; |
| 331 | } |
| 332 | |
| 333 | $content = ''; |
| 334 | foreach ( $_condition as $_k => $_v ) { |
| 335 | $content .= esc_html( $_k ) . ': ' . esc_html( is_array( $_v ) ? implode( ', ', $_v ) : $_v ) . '<br>'; |
| 336 | } |
| 337 | |
| 338 | printf( |
| 339 | '<div style="margin-bottom: 20px; white-space: pre-wrap; font-family: monospace; width: 100%%; background: %s;">%s</div>', |
| 340 | Advanced_Ads_Visitor_Conditions::frontend_check( $_condition, $ad ) ? '#e9ffe9' : '#ffe9e9', |
| 341 | $content // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 342 | ); |
| 343 | } |
| 344 | |
| 345 | return ob_get_clean(); |
| 346 | } |
| 347 | } |
| 348 |