PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 2.0.25
Advanced Ads – Ad Manager & AdSense v2.0.25
2.0.25 2.0.24 2.0.23 2.0.22 2.0.21 1.38.0 1.39.0 1.39.1 1.39.2 1.39.3 1.39.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.40.0 1.40.1 1.40.2 1.41.0 1.42.0 1.42.1 1.42.2 1.43.0 1.44.0 1.44.1 1.45.0 1.45.1 1.46.0 1.47.0 1.47.1 1.47.2 1.47.3 1.47.4 1.47.5 1.48.0 1.48.1 1.49.0 1.5.0 1.5.0.1 1.5.1 1.5.2 1.5.2.1 1.5.4 1.5.4.1 1.5.5 1.50.0 1.51.0 1.51.1 1.51.2 1.51.3 1.52.0 1.52.1 1.52.2 1.52.3 1.52.4 1.53.0 1.53.1 1.53.2 1.54.0 1.54.1 1.55.0 1.56.0 1.56.1 1.56.2 1.56.3 1.56.4 1.6 1.6.1 1.6.10 1.6.10.1 1.6.10.2 1.6.11 1.6.11.1 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.17.1 1.6.17.2 1.6.2 1.6.2.1 1.6.3 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.6.1 1.6.7 1.6.7.1 1.6.8 1.6.8.1 1.6.8.2 1.6.8.3 1.6.9 1.6.9.1 1.6.9.2 1.6.9.3 1.6.9.4 1.7 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.1.1 1.7.1.2 1.7.1.3 1.7.1.4 1.7.1.5 1.7.10 trunk 1.7.11 1.0.1 1.7.12 1.0.2 1.7.13 1.0.3 1.7.14 1.1.0 1.7.15 1.1.1 1.7.16 1.1.2 1.7.17 1.1.3 1.7.18 1.10 1.7.19 1.10.1 1.7.2 1.10.10 1.7.2.1 1.10.11 1.7.20 1.10.12 1.7.21 1.10.2 1.7.22 1.10.3 1.7.23 1.10.4 1.7.24 1.10.5 1.7.25 1.10.6 1.7.3 1.10.7 1.7.4 1.10.8 1.7.4.1 1.10.9 1.7.4.2 1.11 1.7.4.3 1.11.1 1.7.4.4 1.11.2 1.7.4.5 1.12 1.7.5 1.13 1.7.5.1 1.13.1 1.7.6 1.13.2 1.7.7 1.13.3 1.7.8 1.13.4 1.7.9 1.13.5 1.7.9.1 1.13.6 1.7.9.2 1.13.7 1.7.9.3 1.13.8 1.8 1.14 1.8.1 1.14.1 1.8.10 1.14.10 1.8.11 1.14.11 1.8.12 1.14.2 1.8.13 1.14.3 1.8.14 1.14.4 1.8.15 1.14.5 1.8.16 1.14.6 1.8.17 1.14.7 1.8.18 1.14.8 1.8.19 1.14.9 1.8.2 1.15 1.8.20 1.16 1.8.21 1.16.1 1.8.22 1.17 1.8.23 1.17.1 1.8.24 1.17.10 1.8.25 1.17.10-rc.1 1.8.26 1.17.11 1.8.27 1.17.12 1.8.28 1.17.12-rc.1 1.8.29 1.17.2 1.8.3 1.17.3 1.8.30 1.17.4 1.8.4 1.17.5 1.8.5 1.17.6 1.8.6 1.17.7 1.8.7 1.17.8 1.8.8 1.17.9 1.8.9 1.17.9-beta.1 1.9 1.18.0 2.0.0 1.19.0 2.0.1 1.19.1 2.0.10 1.2 2.0.11 1.2.1 2.0.12 1.2.2 2.0.13 1.2.3 2.0.14 1.2.4 2.0.15 1.2.5 2.0.16 1.2.6 2.0.17 1.2.7 2.0.18 1.20.0 2.0.19 1.20.0-rc.1 2.0.2 1.20.0-rc.2 2.0.20 1.20.1 2.0.3 1.20.2 2.0.4 1.20.3 2.0.5 1.21.0 2.0.6 1.21.1 2.0.7 1.22.0 2.0.8 1.22.1 2.0.9 1.22.2 1.23.0 1.23.1 1.23.2 1.24.0 1.24.1 1.24.2 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.29.0 1.29.1 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.30.0 1.30.1 1.30.2 1.30.2-rc.1 1.30.3 1.30.4 1.30.4-rc.1 1.30.5 1.31.0 1.31.1 1.32.0 1.32.0-rc.1 1.33.0 1.33.1 1.33.2 1.34.0 1.35.0 1.35.1 1.36.0 1.36.1 1.36.2 1.36.3 1.37.0 1.37.1 1.37.2
advanced-ads / includes / admin / class-ajax.php
advanced-ads / includes / admin Last commit date
ads 1 week ago groups 1 week ago metaboxes 1 year ago pages 1 day ago placements 1 day ago class-action-links.php 1 week ago class-addon-box.php 1 day ago class-addon-updater.php 1 day ago class-admin-menu.php 1 day ago class-admin-notices.php 1 year ago class-ajax.php 1 day ago class-app.php 1 day ago class-assets.php 1 day ago class-authors.php 1 year ago class-edd-updater.php 1 day ago class-license-admin-post.php 1 day ago class-list-filters.php 1 week ago class-marketing.php 1 year ago class-metabox-ad-settings.php 1 year ago class-metabox-ad.php 1 year ago class-misc.php 1 week ago class-page-quick-edit.php 1 day ago class-plugin-auto-update.php 1 day ago class-plugin-installer.php 1 day ago class-post-list.php 1 year ago class-post-types.php 1 week ago class-screen-options.php 3 months ago class-settings.php 1 day ago class-shortcode-creator.php 1 year ago class-system-info.php 1 year ago class-tinymce.php 2 years ago class-translation-promo.php 1 year ago class-upgrades.php 1 year ago class-version-control.php 3 months ago class-welcome.php 1 year ago class-wordpress-dashboard.php 1 year ago index.php 2 years ago
class-ajax.php
859 lines
1 <?php
2 /**
3 * AJAX Ads
4 *
5 * @package AdvancedAds
6 * @author Advanced Ads <info@wpadvancedads.com>
7 * @since 1.50.0
8 */
9
10 namespace AdvancedAds\Admin;
11
12 use Advanced_Ads_Pro;
13 use Advanced_Ads_Privacy;
14 use AdvancedAds\Constants;
15 use AdvancedAds\Abstracts\Ad;
16 use Advanced_Ads_Admin_Notices;
17 use AdvancedAds\Frontend\Stats;
18 use Advanced_Ads_Ad_Blocker_Admin;
19 use Advanced_Ads_Ad_Health_Notices;
20 use Advanced_Ads_Display_Conditions;
21 use Advanced_Ads_Visitor_Conditions;
22 use AdvancedAds\Utilities\Conditional;
23 use AdvancedAds\Framework\Utilities\Arr;
24 use AdvancedAds\Framework\Utilities\Params;
25 use AdvancedAds\Framework\Interfaces\Integration_Interface;
26
27 defined( 'ABSPATH' ) || exit;
28
29 /**
30 * Frontend AJAX.
31 */
32 class AJAX implements Integration_Interface {
33
34 /**
35 * Hook into WordPress.
36 *
37 * @return void
38 */
39 public function hooks(): void {
40 add_action( 'wp_ajax_advads_ad_select', [ $this, 'ad_select' ] );
41 add_action( 'wp_ajax_nopriv_advads_ad_select', [ $this, 'ad_select' ] );
42 add_action( 'wp_ajax_advads-ad-health-notice-push', [ $this, 'ad_health_notice_push' ] );
43 add_action( 'wp_ajax_nopriv_advads-ad-health-notice-push', [ $this, 'ad_health_notice_push' ] );
44 add_action( 'wp_ajax_advads_dismiss_welcome', [ $this, 'dismiss_welcome' ] );
45 add_action( 'wp_ajax_advads_newsletter', [ $this, 'subscribe_to_newsletter' ] );
46 add_action( 'wp_ajax_advads_activate_addon', [ $this, 'activate_add_on' ] );
47 add_action( 'wp_ajax_advads-multiple-subscribe', [ $this, 'multiple_subscribe' ] );
48
49 add_action( 'wp_ajax_load_ad_parameters_metabox', [ $this, 'load_ad_parameters_metabox' ] );
50 add_action( 'wp_ajax_load_visitor_conditions_metabox', [ $this, 'load_visitor_condition' ] );
51 add_action( 'wp_ajax_load_display_conditions_metabox', [ $this, 'load_display_condition' ] );
52 add_action( 'wp_ajax_advads-terms-search', [ $this, 'search_terms' ] );
53 add_action( 'wp_ajax_advads-authors-search', [ $this, 'search_authors' ] );
54 add_action( 'wp_ajax_advads-close-notice', [ $this, 'close_notice' ] );
55 add_action( 'wp_ajax_advads-hide-notice', [ $this, 'hide_notice' ] );
56 add_action( 'wp_ajax_advads-subscribe-notice', [ $this, 'subscribe' ] );
57 add_action( 'wp_ajax_advads-adblock-rebuild-assets', [ $this, 'adblock_rebuild_assets' ] );
58 add_action( 'wp_ajax_advads-post-search', [ $this, 'post_search' ] );
59 add_action( 'wp_ajax_advads-ad-injection-content', [ $this, 'inject_placement' ] );
60 add_action( 'wp_ajax_advads-save-hide-wizard-state', [ $this, 'save_wizard_state' ] );
61 add_action( 'wp_ajax_advads-adsense-enable-pla', [ $this, 'adsense_enable_pla' ] );
62 add_action( 'wp_ajax_advads-ad-health-notice-display', [ $this, 'ad_health_notice_display' ] );
63 add_action( 'wp_ajax_advads-ad-health-notice-push-adminui', [ $this, 'ad_health_notice_push_adminui' ] );
64 add_action( 'wp_ajax_advads-ad-health-notice-hide', [ $this, 'ad_health_notice_hide' ] );
65 add_action( 'wp_ajax_advads-ad-health-notice-unignore', [ $this, 'ad_health_notice_unignore' ] );
66 add_action( 'wp_ajax_advads-ad-health-notice-solved', [ $this, 'ad_health_notice_solved' ] );
67 add_action( 'wp_ajax_advads-update-frontend-element', [ $this, 'update_frontend_element' ] );
68 add_action( 'wp_ajax_advads-get-block-hints', [ $this, 'get_block_hints' ] );
69 }
70
71 /**
72 * Background plugin activation from the add-on box
73 *
74 * @return void
75 */
76 public function activate_add_on(): void {
77 wp_ajax_activate_plugin();
78 }
79
80 /**
81 * Subscribe to the newsletter
82 *
83 * @return void
84 */
85 public function subscribe_to_newsletter(): void {
86 if ( ! wp_verify_nonce( sanitize_text_field( Params::post( 'nonce' ), '' ), 'advads-newsletter-subscribe' ) ) {
87 wp_send_json_error( 'Not Authorized', 401 );
88 }
89 if ( ! Conditional::user_can( 'advanced_ads_see_interface' ) ) {
90 wp_send_json_error(
91 [
92 /* translators: %s is a URL. */
93 'message' => sprintf( __( 'An error occurred. Please use <a href="%s" target="_blank">this form</a> to sign up.', 'advanced-ads' ), 'http://eepurl.com/bk4z4P' ),
94 ],
95 403
96 );
97 }
98
99 wp_send_json_success( \Advanced_Ads_Admin_Notices::get_instance()->subscribe( 'nl_free_addons' ), 200 );
100 }
101
102 /**
103 * Stop showing the welcome after a click on the dismiss icon
104 *
105 * @return void
106 */
107 public function dismiss_welcome(): void {
108 Welcome::get()->dismiss();
109 wp_send_json_success( 'OK', 200 );
110 }
111
112 /**
113 * Simple wp ajax interface for ad selection.
114 *
115 * @return void
116 */
117 public function ad_select(): void {
118 add_filter( 'advanced-ads-output-inline-css', '__return_false' );
119
120 // Allow modules / add-ons to test (this is rather late but should happen before anything important is called).
121 do_action( 'advanced-ads-ajax-ad-select-init' );
122
123 $ad_ids = Params::request( 'ad_ids', [], FILTER_VALIDATE_INT, FILTER_REQUIRE_ARRAY );
124 $defered_ads = Params::request( 'deferedAds', [], FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
125
126 if ( is_array( $ad_ids ) ) {
127 foreach ( $ad_ids as $ad_id ) {
128 Stats::get()->add_entity( 'ad', is_array( $ad_id ) ? $ad_id['id'] : $ad_id, '' );
129 }
130 }
131
132 if ( $defered_ads ) {
133 $response = [];
134
135 $requests_by_blog = [];
136 foreach ( $defered_ads as $request ) {
137 $blog_id = $request['blog_id'] ?? get_current_blog_id();
138 $requests_by_blog[ $blog_id ][] = $request;
139 }
140
141 foreach ( $requests_by_blog as $blog_id => $requests ) {
142 if ( get_current_blog_id() !== $blog_id && is_multisite() ) {
143 switch_to_blog( $blog_id );
144 }
145
146 foreach ( $requests as $request ) {
147 $result = $this->select_one( $request );
148 $result['elementId'] = $request['elementId'] ?? null;
149 $response[] = $result;
150 }
151
152 if ( get_current_blog_id() !== $blog_id && is_multisite() ) {
153 restore_current_blog();
154 }
155 }
156
157 wp_send_json( $response );
158 }
159
160 $response = $this->select_one( $_REQUEST ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
161 wp_send_json( $response );
162 }
163
164 /**
165 * Push an Ad Health notice to the queue in the backend
166 *
167 * @return void
168 */
169 public function ad_health_notice_push(): void {
170 check_ajax_referer( 'advanced-ads-ad-health-ajax-nonce', 'nonce' );
171
172 if ( ! Conditional::user_can( 'advanced_ads_edit_ads' ) ) {
173 return;
174 }
175
176 $key = ! empty( $_REQUEST['key'] ) ? esc_attr( Params::request( 'key' ) ) : false;
177 $attr = Params::request( 'attr', [], FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
178
179 // Update or new entry?
180 if ( isset( $attr['mode'] ) && 'update' === $attr['mode'] ) {
181 Advanced_Ads_Ad_Health_Notices::get_instance()->update( $key, $attr );
182 } else {
183 Advanced_Ads_Ad_Health_Notices::get_instance()->add( $key, $attr );
184 }
185
186 die();
187 }
188
189 /**
190 * Check if AJAX ad can be displayed, with consent information sent in request.
191 *
192 * @param bool $can_display Whether this ad can be displayed.
193 * @param Ad $ad The ad object.
194 *
195 * @return bool
196 */
197 public function can_display_by_consent( $can_display, $ad ) {
198
199 // Early bail!!
200 if ( ! $can_display ) {
201 return $can_display;
202 }
203
204 // If consent is overridden for the ad.
205 $privacy_props = $ad->get_prop( 'privacy' );
206 if ( ! empty( $privacy_props['ignore-consent'] ) ) {
207 return true;
208 }
209
210 // If privacy module is not active, we can display.
211 if ( empty( Advanced_Ads_Privacy::get_instance()->options()['enabled'] ) ) {
212 return true;
213 }
214
215 $consent_state = Params::request( 'consent', 'not_allowed' );
216
217 // Consent is either given or not needed.
218 if ( in_array( $consent_state, [ 'not_needed', 'accepted' ], true ) ) {
219 return true;
220 }
221
222 if ( 'not_allowed' === $consent_state ) {
223 // Allow image ads without custom code.
224 if ( $ad->get_type() === 'image' ) {
225 $has_custom_code = class_exists( 'Advanced_Ads_Pro' )
226 && ! empty( Advanced_Ads_Pro::get_instance()->get_custom_code( $ad ) );
227
228 if ( ! $has_custom_code ) {
229 return true;
230 }
231
232 return false;
233 }
234 }
235
236 // If there is custom code, don't display the ad (unless it's a group).
237 if (
238 class_exists( 'Advanced_Ads_Pro' ) &&
239 ! empty( Advanced_Ads_Pro::get_instance()->get_custom_code( $ad ) ) &&
240 ! $ad->is_type( 'group' )
241 ) {
242 return false;
243 }
244
245 if ( $can_display && $ad->get_type() === 'adsense' ) {
246 return true;
247 }
248
249 // See if this ad type needs consent.
250 return ! Advanced_Ads_Privacy::get_instance()->ad_type_needs_consent( $ad->get_type() );
251 }
252
253 /**
254 * Subscribe to multiple newsletters
255 */
256 public function multiple_subscribe() {
257 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
258
259 $groups = ! empty( Params::post( 'groups' ) ) ? json_decode( Params::post( 'groups' ), true ) : [];
260
261 if ( ! Conditional::user_can( 'advanced_ads_see_interface' ) || empty( $groups ) ) {
262 wp_send_json_error(
263 [
264 /* translators: %s is a URL. */
265 'message' => sprintf( __( 'An error occurred. Please use <a href="%s" target="_blank">this form</a> to sign up.', 'advanced-ads' ), 'http://eepurl.com/bk4z4P' ),
266 ],
267 400
268 );
269 }
270
271 foreach ( $groups as $group ) {
272 $message = Advanced_Ads_Admin_Notices::get_instance()->subscribe( $group );
273 }
274
275 wp_send_json_success( [ 'message' => $message ?? '' ] );
276 }
277
278 /**
279 * Provides a single ad (ad, group, placement) given ID and selection method.
280 *
281 * @param array $request Request.
282 *
283 * @return array
284 */
285 private function select_one( $request ) {
286 $method = (string) $request['ad_method'] ?? null;
287 if ( 'id' === $method ) {
288 $method = 'ad';
289 }
290
291 // Early bail!!
292 if ( ! Conditional::is_entity_allowed( $method ) ) {
293 return [
294 'status' => 'error',
295 'message' => __( 'The method is not allowed to render.', 'advanced-ads' ),
296 ];
297 }
298
299 $function = "get_the_$method";
300 $id = (string) $request['ad_id'] ?? null;
301 $arguments = $request['ad_args'] ?? [];
302
303 if ( is_string( $arguments ) ) {
304 $arguments = stripslashes( $arguments );
305 $arguments = json_decode( $arguments, true );
306 }
307
308 if ( ! empty( $request['elementId'] ) ) {
309 $arguments['cache_busting_elementid'] = $request['elementId'];
310 }
311
312 // Report error.
313 if ( empty( $id ) || ! function_exists( $function ) ) {
314 return [
315 'status' => 'error',
316 'message' => 'No valid ID or METHOD found.',
317 ];
318 }
319
320 /**
321 * Filters the received arguments before passing them to ads/groups/placements.
322 *
323 * @param array $arguments Existing arguments.
324 * @param array $request Request data.
325 */
326 $arguments = apply_filters( 'advanced-ads-ajax-ad-select-arguments', $arguments, $request );
327 $previous_ads = Stats::get()->entities;
328 add_filter( 'advanced-ads-can-display-ad', [ $this, 'can_display_by_consent' ], 10, 2 );
329 $content = $function( (int) $id, '', $arguments );
330
331 if ( empty( $content ) ) {
332 return [
333 'status' => 'error',
334 'message' => 'No displayable ad found for privacy settings.',
335 ];
336 }
337
338 $response = [
339 'status' => 'success',
340 'item' => $content,
341 'id' => $id,
342 'method' => $method,
343 'ads' => array_slice( Stats::get()->entities, count( $previous_ads ) ),
344 'blog_id' => get_current_blog_id(),
345 ];
346
347 return apply_filters(
348 'advanced-ads-cache-busting-item',
349 $response,
350 [
351 'id' => $id,
352 'method' => $method,
353 'args' => $arguments,
354 ]
355 );
356 }
357
358 /**
359 * Load content of the ad parameter metabox
360 *
361 * @since 1.0.0
362 */
363 public function load_ad_parameters_metabox() {
364
365 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
366 if ( ! Conditional::user_can( 'advanced_ads_edit_ads' ) ) {
367 return;
368 }
369
370 $type_string = Params::post( 'ad_type' );
371 $ad_id = Params::post( 'ad_id', 0, FILTER_VALIDATE_INT );
372 if ( empty( $ad_id ) ) {
373 die();
374 }
375
376 if ( wp_advads_has_ad_type( $type_string ) ) {
377 $ad = wp_advads_get_ad( $ad_id, $type_string );
378 $ad_type = wp_advads_get_ad_type( $type_string );
379 if ( method_exists( $ad_type, 'render_parameters' ) ) {
380 $ad_type->render_parameters( $ad );
381 }
382
383 if ( $ad_type->has_size() ) {
384 include ADVADS_ABSPATH . 'views/admin/metaboxes/ads/ad-parameters-size.php';
385 }
386
387 // Extend the AJAX-loaded parameters form by ad type.
388 do_action( "advanced-ads-ad-params-after-{$ad->get_type()}", $ad );
389 }
390
391 die();
392 }
393
394 /**
395 * Load interface for single visitor condition
396 *
397 * @since 1.5.4
398 */
399 public function load_visitor_condition() {
400
401 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
402
403 if ( ! Conditional::user_can( 'advanced_ads_edit_ads' ) ) {
404 return;
405 }
406
407 // get visitor condition types.
408 $visitor_conditions = Advanced_Ads_Visitor_Conditions::get_instance()->conditions;
409 $condition = [];
410 $condition['type'] = Params::post( 'type', '' );
411 $index = Params::post( 'index', 0, FILTER_VALIDATE_INT );
412
413 $form_name = Params::post( 'form_name', Advanced_Ads_Visitor_Conditions::FORM_NAME );
414
415 if ( ! isset( $visitor_conditions[ $condition['type'] ] ) ) {
416 die();
417 }
418
419 $metabox = $visitor_conditions[ $condition['type'] ]['metabox'];
420 if ( method_exists( $metabox[0], $metabox[1] ) ) {
421 call_user_func( [ $metabox[0], $metabox[1] ], $condition, $index, $form_name );
422 }
423
424 die();
425 }
426
427 /**
428 * Load interface for single display condition
429 *
430 * @since 1.7
431 */
432 public function load_display_condition() {
433
434 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
435
436 if ( ! Conditional::user_can( 'advanced_ads_edit_ads' ) ) {
437 return;
438 }
439
440 // get display condition types.
441 $conditions = Advanced_Ads_Display_Conditions::get_instance()->conditions;
442 $condition = [];
443 $condition['type'] = Params::post( 'type', '' );
444 $index = Params::post( 'index', 0, FILTER_VALIDATE_INT );
445 $form_name = Params::post( 'form_name', Advanced_Ads_Display_Conditions::FORM_NAME );
446
447 if ( ! isset( $conditions[ $condition['type'] ] ) ) {
448 die();
449 }
450
451 $metabox = $conditions[ $condition['type'] ]['metabox'];
452 if ( method_exists( $metabox[0], $metabox[1] ) ) {
453 call_user_func( [ $metabox[0], $metabox[1] ], $condition, $index, $form_name );
454 }
455
456 die();
457 }
458
459 /**
460 * Search terms belonging to a specific taxonomy
461 *
462 * @since 1.4.7
463 */
464 public function search_terms() {
465
466 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
467
468 if ( ! Conditional::user_can( 'advanced_ads_edit_ads' ) ) {
469 return;
470 }
471
472 $args = [
473 'taxonomy' => Params::post( 'tax', '' ),
474 'hide_empty' => false,
475 'number' => 20,
476 ];
477
478 $search = Params::post( 'search', '' );
479 if ( '' === $search ) {
480 die();
481 }
482
483 // if search is an id, search for the term id, else do a full text search.
484 if ( 0 !== absint( $search ) && strlen( $search ) === strlen( absint( $search ) ) ) {
485 $args['include'] = [ absint( $search ) ];
486 } else {
487 $args['search'] = $search;
488 }
489
490 $results = get_terms( $args );
491 echo wp_json_encode( $results );
492 echo "\n";
493 die();
494 }
495
496 /**
497 * Search authors
498 *
499 * @since 1.47.5
500 */
501 public function search_authors() {
502 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
503
504 if ( ! Conditional::user_can( 'advanced_ads_edit_ads' ) ) {
505 return;
506 }
507
508 $args['search_columns'] = [ 'ID', 'user_login', 'user_nicename', 'display_name' ];
509
510 if ( version_compare( get_bloginfo( 'version' ), '5.9' ) > -1 ) {
511 $args['capability'] = [ 'edit_posts' ];
512 } else {
513 $args['who'] = 'authors';
514 }
515
516 $search = Params::post( 'search', '' );
517 if ( '' === $search ) {
518 die();
519 }
520
521 $args['search'] = '*' . sanitize_text_field( wp_unslash( $search ) ) . '*';
522
523 $results = get_users( $args );
524
525 echo wp_json_encode( $results );
526 die();
527 }
528
529 /**
530 * Close a notice for good
531 *
532 * @since 1.5.3
533 */
534 public function close_notice() {
535
536 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
537 $notice = Params::request( 'notice' );
538
539 if (
540 ! Conditional::user_can( 'advanced_ads_manage_options' )
541 || empty( $notice )
542 ) {
543 die();
544 }
545
546 Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue( $notice );
547
548 // permanent dismissed.
549 if ( 'monetize_wizard' === Params::request( 'notice' ) ) {
550 update_user_meta( get_current_user_id(), Constants::USER_WIZARD_DISMISS, true );
551 }
552
553 $redirect = Params::request( 'redirect' );
554 if ( $redirect && wp_safe_redirect( $redirect ) ) {
555 exit();
556 }
557
558 die();
559 }
560
561 /**
562 * Hide a notice for some time (7 days right now)
563 *
564 * @since 1.8.17
565 */
566 public function hide_notice() {
567 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
568 $notice = Params::request( 'notice' );
569
570 if ( ! Conditional::user_can( 'advanced_ads_manage_options' )
571 || empty( $notice )
572 ) {
573 die();
574 }
575
576 Advanced_Ads_Admin_Notices::get_instance()->hide_notice( $notice );
577 die();
578 }
579
580 /**
581 * Subscribe to newsletter
582 *
583 * @since 1.5.3
584 */
585 public function subscribe() {
586 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
587 $notice = Params::request( 'notice' );
588
589 if (
590 ! Conditional::user_can( 'advanced_ads_see_interface' )
591 || empty( $notice )
592 ) {
593 wp_send_json_error(
594 [
595 /* translators: %s is a URL. */
596 'message' => sprintf( __( 'An error occurred. Please use <a href="%s" target="_blank">this form</a> to sign up.', 'advanced-ads' ), 'http://eepurl.com/bk4z4P' ),
597 ],
598 400
599 );
600 }
601
602 wp_send_json_success( [ 'message' => Advanced_Ads_Admin_Notices::get_instance()->subscribe( $notice ) ] );
603 }
604
605 /**
606 * Rebuild assets for ad-blocker module
607 */
608 public function adblock_rebuild_assets() {
609
610 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
611
612 if ( ! Conditional::user_can( 'advanced_ads_manage_options' ) ) {
613 return;
614 }
615
616 Advanced_Ads_Ad_Blocker_Admin::get_instance()->add_asset_rebuild_form();
617 die();
618 }
619
620 /**
621 * Post search (used in Display conditions)
622 */
623 public function post_search() {
624
625 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
626
627 if ( ! Conditional::user_can( 'advanced_ads_edit_ads' ) ) {
628 return;
629 }
630
631 add_filter( 'wp_link_query_args', [ 'Advanced_Ads_Display_Conditions', 'modify_post_search' ] );
632 add_filter( 'posts_search', [ 'Advanced_Ads_Display_Conditions', 'modify_post_search_sql' ] );
633
634 wp_ajax_wp_link_ajax();
635 }
636
637 /**
638 * Inject an ad and a placement
639 *
640 * @since 1.7.3
641 */
642 public function inject_placement() {
643 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
644
645 $ad_id = Params::request( 'ad_id', 0, FILTER_VALIDATE_INT );
646
647 // Early bail!!
648 if ( ! Conditional::user_can( 'advanced_ads_edit_ads' ) || ! $ad_id ) {
649 die();
650 }
651
652 // use existing placement.
653 $placement_id = Params::request( 'placement_id', 0, FILTER_VALIDATE_INT );
654 if ( $placement_id ) {
655 $placement = wp_advads_get_placement( $placement_id );
656
657 if ( $placement ) {
658 $current_item = $placement->get_item();
659 // Check if current item is a group and new item is an ad.
660 if ( is_string( $current_item ) && strpos( $current_item, 'group_' ) === 0 ) {
661 $group = wp_advads_get_group( (int) str_replace( 'group_', '', $current_item ) );
662 if ( $group ) {
663 $ad_weights = $group->get_ad_weights();
664 $ad_weights[ $ad_id ] = Constants::GROUP_AD_DEFAULT_WEIGHT;
665 $group->set_ad_weights( $ad_weights );
666 $group->save();
667 }
668 } else {
669 $placement->set_item( 'ad_' . $ad_id );
670 $placement->save();
671 }
672 echo esc_attr( $placement_id );
673 }
674
675 die();
676 }
677
678 $type = esc_attr( Params::request( 'placement_type' ) );
679 if ( ! wp_advads_has_placement_type( $type ) ) {
680 die();
681 }
682
683 $new_placement = wp_advads_create_new_placement( $type );
684
685 $props = [
686 'item' => 'ad_' . $ad_id,
687 'title' => wp_advads_get_placement_type( $type )->get_title(),
688 ];
689
690 // set content specific options.
691 if ( $new_placement->is_type( 'post_content' ) ) {
692 $options = Params::request( 'options', [], FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
693 $index = (int) Arr::get( $options, 'index', 1 );
694 $props['position'] = 'after';
695 $props['index'] = $index;
696 $props['tag'] = 'p';
697 }
698
699 $new_placement->set_props( $props );
700 echo $new_placement->save();; // phpcs:ignore
701 }
702
703 /**
704 * Save ad wizard state for each user individually
705 *
706 * @since 1.7.4
707 */
708 public function save_wizard_state() {
709
710 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
711
712 if ( ! Conditional::user_can( 'advanced_ads_edit_ads' ) ) {
713 return;
714 }
715
716 $user_id = get_current_user_id();
717
718 if ( ! $user_id ) {
719 die();
720 }
721
722 $state = 'true' === Params::request( 'hideWizard' ) ? 'true' : 'false';
723 update_user_meta( $user_id, 'advanced-ads-hide-wizard', $state );
724
725 die();
726 }
727
728 /**
729 * Enable Adsense Auto ads, previously "Page-Level ads"
730 */
731 public function adsense_enable_pla() {
732
733 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
734
735 if ( ! Conditional::user_can( 'advanced_ads_manage_options' ) ) {
736 return;
737 }
738
739 $options = get_option( GADSENSE_OPT_NAME, [] );
740 $options['page-level-enabled'] = true;
741 update_option( GADSENSE_OPT_NAME, $options );
742 die();
743 }
744
745 /**
746 * Display list of Ad Health notices
747 */
748 public function ad_health_notice_display() {
749
750 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
751
752 if ( ! Conditional::user_can( 'advanced_ads_manage_options' ) ) {
753 return;
754 }
755
756 Advanced_Ads_Ad_Health_Notices::get_instance()->render_widget();
757 die();
758 }
759
760 /**
761 * Push an Ad Health notice to the queue
762 */
763 public function ad_health_notice_push_adminui() {
764
765 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
766
767 if ( ! Conditional::user_can( 'advanced_ads_manage_options' ) ) {
768 return;
769 }
770
771 $key = Params::request( 'key' );
772 $attr = Params::request( 'attr', [], FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
773 $attr = ! empty( $attr ) && is_array( $attr ) ? $attr : [];
774
775 // update or new entry?
776 if ( isset( $attr['mode'] ) && 'update' === $attr['mode'] ) {
777 Advanced_Ads_Ad_Health_Notices::get_instance()->update( $key, $attr );
778 } else {
779 Advanced_Ads_Ad_Health_Notices::get_instance()->add( $key, $attr );
780 }
781
782 die();
783 }
784
785 /**
786 * Hide Ad Health notice
787 */
788 public function ad_health_notice_hide() {
789 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
790
791 if ( ! Conditional::user_can( 'advanced_ads_manage_options' ) ) {
792 return;
793 }
794
795 $notice = Params::request( 'notice', '' );
796 $notice_key = ! empty( $notice ) ? esc_attr( $notice ) : false;
797
798 Advanced_Ads_Ad_Health_Notices::get_instance()->hide( $notice_key );
799 die();
800 }
801
802 /**
803 * Show all ignored notices of a given type
804 */
805 public function ad_health_notice_unignore() {
806 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
807
808 if ( ! Conditional::user_can( 'advanced_ads_manage_options' ) ) {
809 return;
810 }
811
812 Advanced_Ads_Ad_Health_Notices::get_instance()->unignore();
813 die();
814 }
815
816 /**
817 * After the user has selected a new frontend element, update the corresponding placement.
818 */
819 public function update_frontend_element() {
820 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
821
822 if ( ! Conditional::user_can( 'advanced_ads_manage_placements' ) ) {
823 return;
824 }
825
826 $return = wp_update_post( $_POST );
827
828 if ( is_wp_error( $return ) ) {
829 wp_send_json_error( [ 'error' => $return->get_error_message() ], 400 );
830 }
831
832 wp_send_json_success( [ 'id' => $return ] );
833 }
834
835 /**
836 * Get hints related to the Gutenberg block.
837 */
838 public function get_block_hints() {
839 check_ajax_referer( 'advanced-ads-admin-ajax-nonce', 'nonce' );
840
841 $item = Params::post( 'itemID' );
842 if ( ! $item || ! Conditional::user_can( 'advanced_ads_edit_ads' ) ) {
843 die;
844 }
845
846 $item = explode( '_', $item );
847 if ( ! isset( $item[0] ) || 'group' !== $item[0] ) {
848 die;
849 }
850
851 $group = wp_advads_get_group( absint( $item[1] ) );
852 if ( ! $group ) {
853 die;
854 }
855
856 wp_send_json_success( $group->get_hints() );
857 }
858 }
859