PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 1.17.3
Advanced Ads – Ad Manager & AdSense v1.17.3
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 / classes / display-conditions.php
advanced-ads / classes Last commit date
EDD_SL_Plugin_Updater.php 6 years ago ad-ajax.php 6 years ago ad-debug.php 8 years ago ad-health-notices.php 6 years ago ad-model.php 6 years ago ad-select.php 9 years ago ad.php 6 years ago ad_ajax_callbacks.php 6 years ago ad_group.php 6 years ago ad_placements.php 6 years ago ad_type_abstract.php 6 years ago ad_type_content.php 6 years ago ad_type_dummy.php 6 years ago ad_type_group.php 6 years ago ad_type_image.php 6 years ago ad_type_plain.php 6 years ago checks.php 6 years ago compatibility.php 6 years ago display-conditions.php 6 years ago filesystem.php 8 years ago frontend-notices.php 6 years ago frontend_checks.php 6 years ago plugin.php 6 years ago upgrades.php 7 years ago utils.php 6 years ago visitor-conditions.php 6 years ago widget.php 6 years ago
display-conditions.php
1397 lines
1 <?php
2
3 /**
4 * Display Conditions under which to (not) show an ad
5 *
6 * @since 1.7
7 *
8 */
9 class Advanced_Ads_Display_Conditions {
10
11 /**
12 * Advanced_Ads_Display_Conditions
13 *
14 * @var Advanced_Ads_Display_Conditions
15 */
16 protected static $instance;
17
18 /**
19 * Conditonis
20 *
21 * Registered display conditions.
22 *
23 * @var $conditions
24 */
25 public $conditions;
26
27 /**
28 * Start of name in form elements
29 */
30 const FORM_NAME = 'advanced_ad[conditions]';
31
32 /**
33 * List of query var values
34 *
35 * @var array
36 */
37 protected static $query_var_keys = array(
38 // 'is_single',
39 'is_archive',
40 'is_search',
41 'is_home',
42 'is_404',
43 'is_attachment',
44 'is_singular',
45 'is_front_page',
46 'is_feed',
47 );
48
49 /**
50 * List of options for the General Conditions
51 *
52 * @var array
53 */
54
55 protected static $default_general_keys = array(
56 'is_front_page',
57 'is_singular',
58 'is_archive',
59 'is_search',
60 'is_404',
61 'is_attachment',
62 'is_main_query',
63 'is_feed',
64 );
65
66 /**
67 * Constructor
68 */
69 private function __construct() {
70
71 // register filter.
72 add_filter( 'advanced-ads-ad-select-args', array( $this, 'ad_select_args_callback' ) );
73 add_filter( 'advanced-ads-can-display', array( $this, 'can_display' ), 10, 2 );
74
75 // register conditions with init hook, register as late as possible so other plugins can use the same hook to add new taxonomies.
76 add_action( 'init', array( $this, 'register_conditions' ), 100 );
77 }
78
79 /**
80 * Register display conditions
81 *
82 * @since 1.7.1.4
83 */
84 public function register_conditions() {
85 $conditions = array(
86 // post types condition.
87 'posttypes' => array(
88 'label' => __( 'post type', 'advanced-ads' ),
89 'description' => __( 'Choose the public post types on which to display the ad.', 'advanced-ads' ),
90 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_post_type' ), // callback to generate the metabox.
91 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_post_type' ), // callback for frontend check.
92 ),
93 // post id condition.
94 'postids' => array(
95 'label' => __( 'specific pages', 'advanced-ads' ),
96 'description' => __( 'Choose on which individual posts, pages and public post type pages you want to display or hide ads.', 'advanced-ads' ),
97 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_post_ids' ), // callback to generate the metabox.
98 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_post_ids' ), // callback for frontend check.
99 ),
100 // general conditions.
101 'general' => array(
102 'label' => __( 'general conditions', 'advanced-ads' ),
103 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_general' ), // callback to generate the metabox.
104 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_general' ), // callback for frontend check.
105 ),
106 // author conditions.
107 'author' => array(
108 'label' => __( 'author', 'advanced-ads' ),
109 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_author' ), // callback to generate the metabox.
110 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_author' ), // callback for frontend check.
111 ),
112 // display ads only in content older or younger than a specific age.
113 'content_age' => array(
114 'label' => __( 'content age', 'advanced-ads' ),
115 'description' => __( 'Display ads based on age of the page.', 'advanced-ads' ),
116 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_content_age' ), // callback to generate the metabox.
117 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_content_age' ), // callback for frontend check.
118 ),
119 // condition for taxonomies in general.
120 'taxonomy' => array(
121 'label' => __( 'taxonomy', 'advanced-ads' ),
122 'description' => __( 'Display ads based on the taxonomy of an archive page.', 'advanced-ads' ),
123 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_taxonomies' ), // callback to generate the metabox.
124 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_taxonomy' ), // callback for frontend check.
125 ),
126 );
127
128 // register a condition for each taxonomy for posts.
129 $taxonomies = get_taxonomies(
130 array(
131 'public' => true,
132 'publicly_queryable' => true,
133 ),
134 'objects',
135 'or'
136 );
137
138 $tax_label_counts = array();
139
140 foreach ( $taxonomies as $_tax ) :
141 if ( in_array( $_tax->name, array( 'advanced_ads_groups' ), true ) ) {
142 continue;
143 }
144
145 /**
146 * Count names of taxonomies and adjust label if there are duplicates.
147 * we can’t use `array_count_values` here because "label" might not always be a simple string (though it should be)
148 */
149 $tax_label_counts[ $_tax->label ] = isset( $tax_label_counts[ $_tax->label ] ) ? $tax_label_counts[ $_tax->label ] + 1 : $tax_label_counts[ $_tax->label ] = 1;
150
151 // add tax type to label if we find it multiple times.
152 if ( $tax_label_counts[ $_tax->label ] < 2 ) {
153 $archive_label = $_tax->label;
154 $label = $archive_label;
155 } else {
156 $label = sprintf( '%s (%s)', $_tax->label, $_tax->name );
157 $archive_label = sprintf( '%s (%s)', $_tax->labels->singular_name, $_tax->name );
158 }
159
160 $conditions[ 'taxonomy_' . $_tax->name ] = array(
161 'label' => $label,
162 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_taxonomy_terms' ), // callback to generate the metabox.
163 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_taxonomies' ), // callback for frontend check.
164 'taxonomy' => $_tax->name, // unique for this type: the taxonomy name.
165 );
166
167 $conditions[ 'archive_' . $_tax->name ] = array(
168 'label' => sprintf(
169 // translators: %s is a label of an archive page.
170 __( 'archive: %s', 'advanced-ads' ),
171 $archive_label
172 ),
173 'metabox' => array( 'Advanced_Ads_Display_Conditions', 'metabox_taxonomy_terms' ), // callback to generate the metabox.
174 'check' => array( 'Advanced_Ads_Display_Conditions', 'check_taxonomy_archive' ), // callback for frontend check.
175 'taxonomy' => $_tax->name, // unique for this type: the taxonomy name.
176 );
177 endforeach;
178
179 $this->conditions = apply_filters( 'advanced-ads-display-conditions', $conditions );
180 }
181
182 /**
183 * Instance of Advanced_Ads_Display_Conditions
184 *
185 * @return Advanced_Ads_Display_Conditions
186 */
187 public static function get_instance() {
188 // If the single instance hasn't been set, set it now.
189 if ( null === self::$instance ) {
190 self::$instance = new self();
191 }
192
193 return self::$instance;
194 }
195
196
197 /**
198 * Get the conditions array alphabetically by label
199 *
200 * @since 1.8.12
201 */
202 public function get_conditions() {
203 uasort( $this->conditions, 'Advanced_Ads_Admin::sort_condition_array_by_label' );
204
205 return $this->conditions;
206 }
207
208 /**
209 * Controls frontend checks for conditions
210 *
211 * @param array $options options of the condition.
212 * @param mixed $ad false or Advanced_Ads_Ad object.
213 *
214 * @return bool false, if ad can’t be delivered
215 */
216 public static function frontend_check( $options = array(), $ad = false ) {
217 $display_conditions = self::get_instance()->conditions;
218
219 if ( is_array( $options ) && isset( $options['type'] ) && isset( $display_conditions[ $options['type'] ]['check'] ) ) {
220 $check = $display_conditions[ $options['type'] ]['check'];
221 } else {
222 return true;
223 }
224
225 // call frontend check callback.
226 if ( method_exists( $check[0], $check[1] ) ) {
227 return call_user_func( array( $check[0], $check[1] ), $options, $ad );
228 }
229
230 return true;
231 }
232
233 /**
234 * Render the list of set display conditions
235 *
236 * @param array $set_conditions array of existing conditions.
237 * @param string $list_target ID of the list with the conditions.
238 * @param string $form_name prefix of the form field name attribute.
239 */
240 public static function render_condition_list( array $set_conditions, $list_target = '', $form_name = '' ) {
241
242 $conditions = self::get_instance()->get_conditions();
243
244 // use default form name if not given explicitly.
245 // @todo create a random form name, in case we have more than one form per page and the parameter is not given.
246 $form_name = ! $form_name ? self::FORM_NAME : $form_name;
247
248 include ADVADS_BASE_PATH . 'admin/views/conditions/display-conditions-list.php';
249
250 /**
251 * Prepare condition form
252 *
253 * @todo if needed, allow to disable the form to add new conditions
254 */
255
256 // add mockup conditions if add-ons are missing.
257 $pro_conditions = array();
258 if ( ! defined( 'AAP_VERSION' ) ) {
259 $pro_conditions[] = __( 'parent page', 'advanced-ads' );
260 $pro_conditions[] = __( 'post meta', 'advanced-ads' );
261 $pro_conditions[] = __( 'page template', 'advanced-ads' );
262 $pro_conditions[] = __( 'url parameters', 'advanced-ads' );
263 }
264 if ( ! defined( 'AAR_VERSION' ) ) {
265 $pro_conditions[] = __( 'accelerated mobile pages', 'advanced-ads' );
266 }
267 asort( $pro_conditions );
268
269 // the action to call using AJAX.
270 $action = 'load_display_conditions_metabox';
271 $connector_default = 'or';
272
273 include ADVADS_BASE_PATH . 'admin/views/conditions/display-conditions-form-top.php';
274 include ADVADS_BASE_PATH . 'admin/views/conditions/conditions-form.php';
275 }
276
277 /**
278 * Render connector option
279 *
280 * @param int $index incremental index of the options.
281 * @param string $value connector value.
282 * @param string $form_name name of the form, falls back to class constant.
283 *
284 * @return string HTML for connector option.
285 * @since 1.7.0.4
286 */
287 public static function render_connector_option( $index = 0, $value = 'or', $form_name ) {
288
289 $label = ( 'or' === $value ) ? __( 'or', 'advanced-ads' ) : __( 'and', 'advanced-ads' );
290
291 $name = self::get_form_name_with_index( $form_name, $index );
292
293 // create random value to identify the form field.
294 $rand = md5( $form_name );
295
296 return '<input style="display:none;" type="checkbox" name="' . $name . '[connector]' . '" value="or"
297 id="advads-conditions-' . $index . '-connector-' . $rand . '"' . checked( 'or', $value, false ) . '>
298 <label for="advads-conditions-' . $index . '-connector-' . $rand . '">' . $label . '</label>';
299 }
300
301 /**
302 * Render type field
303 *
304 * @param string $type type of the current condition.
305 * @param string $name name of the form, falls back to class constant.
306 */
307 public static function render_type_field( $type, $name ) {
308
309 ?>
310 <input type="hidden" name="<?php echo esc_attr( $name ); ?>[type]" value="<?php echo esc_attr( $type ); ?>"/>
311 <?php
312
313 }
314
315 /**
316 * Helper function to the name of a form field.
317 * falls back to default
318 *
319 * @param string $form_name form name if submitted.
320 * @param int $index index of the condition.
321 *
322 * @return string
323 */
324 public static function get_form_name_with_index( $form_name = '', $index = 0 ) {
325 return ! empty( $form_name ) ? $form_name . '[' . $index . ']' : self::FORM_NAME . '[' . $index . ']';
326 }
327
328 /**
329 * Callback to display the metabox for the post type condition
330 *
331 * @param array $options options of the condition.
332 * @param int $index index of the condition.
333 * @param string $form_name name of the form, falls back to class constant.
334 */
335 public static function metabox_post_type( $options, $index = 0, $form_name = '' ) {
336 if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
337 return;
338 }
339
340 $type_options = self::get_instance()->conditions;
341
342 if ( ! isset( $type_options[ $options['type'] ] ) ) {
343 return;
344 }
345
346 // get values and select operator based on previous settings.
347 $operator = ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) ? 'is_not' : 'is';
348 $values = ( isset( $options['value'] ) && is_array( $options['value'] ) ) ? $options['value'] : array();
349
350 // form name basis.
351 $name = self::get_form_name_with_index( $form_name, $index );
352 $rand = md5( $name );
353
354 self::render_type_field( $options['type'], $name );
355
356 // load operator template.
357 include ADVADS_BASE_PATH . 'admin/views/conditions/condition-operator.php';
358
359 // set defaults.
360 $post_types = get_post_types(
361 array(
362 'public' => true,
363 'publicly_queryable' => true,
364 ),
365 'object',
366 'or'
367 );
368 ?>
369 <div class="advads-conditions-single advads-buttonset"><?php
370 $type_label_counts = array_count_values( wp_list_pluck( $post_types, 'label' ) );
371
372 foreach ( $post_types as $_type_id => $_type ) {
373 if ( in_array( $_type_id, $values, true ) ) {
374 $_val = 1;
375 } else {
376 $_val = 0;
377 }
378
379 if ( $type_label_counts[ $_type->label ] < 2 ) {
380 $_label = $_type->label;
381 } else {
382 $_label = sprintf( '%s (%s)', $_type->label, $_type_id );
383 }
384 $field_id = "advads-conditions-$_type_id-$rand";
385 ?><label class="button" for="<?php echo $field_id;
386 ?>"><?php echo $_label ?></label><input type="checkbox"
387 id="<?php echo $field_id; ?>"
388 name="<?php echo $name; ?>[value][]" <?php checked( $_val, 1 ); ?>
389 value="<?php echo $_type_id; ?>"><?php
390 }
391 include ADVADS_BASE_PATH . 'admin/views/conditions/not-selected.php';
392 ?>
393 </div><?php
394 }
395
396 /**
397 * Callback to display the metabox for the author condition
398 *
399 * @param array $options options of the condition.
400 * @param int $index index of the condition.
401 * @param string $form_name name of the form, falls back to class constant.
402 */
403 public static function metabox_author( $options, $index = 0, $form_name = '' ) {
404
405 if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
406 return;
407 }
408
409 $type_options = self::get_instance()->conditions;
410
411 if ( ! isset( $type_options[ $options['type'] ] ) ) {
412 return;
413 }
414
415 // get values and select operator based on previous settings.
416 $operator = ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) ? 'is_not' : 'is';
417 $values = ( isset( $options['value'] ) && is_array( $options['value'] ) ) ? $options['value'] : array();
418
419 // form name basis.
420 $name = self::get_form_name_with_index( $form_name, $index );
421 $rand = md5( $name );
422
423 self::render_type_field( $options['type'], $name );
424
425 // load operator template.
426 include ADVADS_BASE_PATH . 'admin/views/conditions/condition-operator.php';
427
428 // set defaults.
429 $max_authors = absint( apply_filters( 'advanced-ads-admin-max-terms', 50 ) );
430 $authors = get_users(
431 array(
432 'who' => 'authors',
433 'orderby' => 'nicename',
434 'number' => $max_authors,
435 )
436 );
437
438 include ADVADS_BASE_PATH . 'admin/views/conditions/condition-author.php';
439 }
440
441 /**
442 * Callback to display the metabox for the taxonomy archive pages
443 *
444 * @param array $options options of the condition.
445 * @param int $index index of the condition.
446 * @param string $form_name name of the form, falls back to class constant.
447 */
448 public static function metabox_taxonomy_terms( $options, $index = 0, $form_name = '' ) {
449
450 if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
451 return;
452 }
453
454 $type_options = self::get_instance()->conditions;
455
456 // don’t use if this is not a taxonomy.
457 if ( ! isset( $type_options[ $options['type'] ] ) || ! isset( $type_options[ $options['type'] ]['taxonomy'] ) ) {
458 return;
459 }
460
461 $taxonomy = get_taxonomy( $type_options[ $options['type'] ]['taxonomy'] );
462 if ( false === $taxonomy ) {
463 return;
464 }
465
466 // get values and select operator based on previous settings.
467 $operator = ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) ? 'is_not' : 'is';
468 $values = ( isset( $options['value'] ) && is_array( $options['value'] ) ) ? $options['value'] : array();
469
470 // limit the number of terms so many terms don’t break the admin page.
471 $max_terms = absint( apply_filters( 'advanced-ads-admin-max-terms', 50 ) );
472
473 // form name basis.
474 $name = self::get_form_name_with_index( $form_name, $index );
475
476 self::render_type_field( $options['type'], $name );
477
478 // load operator template.
479 include ADVADS_BASE_PATH . 'admin/views/conditions/condition-operator.php';
480
481 ?>
482 <div class="advads-conditions-single advads-buttonset">
483 <?php
484 $terms = self::display_term_list( $taxonomy, $values, $name . '[value][]', $max_terms, $index );
485 if ( empty( $terms ) ) {
486 include ADVADS_BASE_PATH . 'admin/views/conditions/no-option.php';
487 }
488 ?>
489 </div>
490 <?php
491 }
492
493 /**
494 * Callback to display the metabox for the taxonomies
495 *
496 * @param array $options options of the condition.
497 * @param int $index index of the condition.
498 * @param string $form_name name of the form, falls back to class constant.
499 */
500 public static function metabox_taxonomies( $options, $index = 0, $form_name = '' ) {
501
502 if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
503 return;
504 }
505
506 $taxonomies = get_taxonomies( array( 'public' => 1 ), 'objects' );
507
508 $name = self::get_form_name_with_index( $form_name, $index );
509 $rand = md5( $name );
510
511 // get values and select operator based on previous settings.
512 $operator = ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) ? 'is_not' : 'is';
513 $values = ( isset( $options['value'] ) && is_array( $options['value'] ) ) ? $options['value'] : array();
514
515 self::render_type_field( $options['type'], $name );
516
517 ?>
518 <div class="advads-conditions-single advads-buttonset">
519 <?php
520 $tax_label_counts = array_count_values( wp_list_pluck( $taxonomies, 'label' ) );
521
522 foreach ( $taxonomies as $_taxonomy_id => $_taxonomy ) :
523
524 if ( in_array( $_taxonomy_id, $values ) ) {
525 $_val = 1;
526 } else {
527 $_val = 0;
528 }
529
530 if ( $tax_label_counts[ $_taxonomy->label ] < 2 ) {
531 $_label = $_taxonomy->label;
532 } else {
533 $_label = sprintf( '%s (%s)', $_taxonomy->label, $_taxonomy_id );
534 }
535
536 $field_id = "advads-conditions-$_taxonomy_id-$rand";
537 ?><label class="button" for="<?php echo $field_id
538 ?>"><?php echo $_label ?></label><input type="checkbox"
539 id="<?php echo $field_id; ?>"
540 name="<?php echo $name; ?>[value][]" <?php checked( $_val, 1 ); ?>
541 value="<?php echo $_taxonomy_id; ?>"><?php
542 endforeach;
543 include ADVADS_BASE_PATH . 'admin/views/conditions/not-selected.php';
544 ?>
545 </div>
546 <?php
547 }
548
549 /**
550 * Display terms of a taxonomy for choice
551 *
552 * @param object $taxonomy taxonomy object.
553 * @param array $checked ids of checked terms.
554 * @param string $inputname name of the input field.
555 * @param int $max_terms maximum number of terms to show.
556 * @param int $index index of the conditions group.
557 *
558 * @return array|int|WP_Error
559 */
560 public static function display_term_list( $taxonomy, $checked = array(), $inputname = '', $max_terms = 50, $index = 0 ) {
561
562 $terms = get_terms(
563 $taxonomy->name,
564 array(
565 'hide_empty' => false,
566 'number' => $max_terms,
567 )
568 );
569 $rand = md5( $inputname );
570
571 if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) :
572 // display search field if the term limit is reached.
573 if ( count( $terms ) == $max_terms ) :
574
575 // query active terms.
576 if ( is_array( $checked ) && count( $checked ) ) {
577 $args = array( 'hide_empty' => false );
578 $args['include'] = $checked;
579 $checked_terms = get_terms( $taxonomy->name, $args );
580 ?>
581 <div class="advads-conditions-terms-buttons dynamic-search"><?php
582 foreach ( $checked_terms as $_checked_term ) :
583 ?><label class="button ui-state-active"><?php echo $_checked_term->name;
584 ?><input type="hidden" name="<?php echo $inputname; ?>"
585 value="<?php echo $_checked_term->term_id; ?>"></label><?php
586 endforeach;
587 ?></div><?php
588 } else {
589 ?>
590 <div class="advads-conditions-terms-buttons dynamic-search"></div><?php
591 }
592 ?><span class="advads-conditions-terms-show-search button" title="<?php
593 _ex( 'add more terms', 'display the terms search field on ad edit page', 'advanced-ads' );
594 ?>">+</span><br/><input type="text" class="advads-conditions-terms-search"
595 data-tag-name="<?php echo $taxonomy->name;
596 ?>" data-input-name="<?php echo $inputname; ?>"
597 placeholder="<?php _e( 'term name or id', 'advanced-ads' ); ?>"/><?php
598 else :
599 ?>
600 <div class="advads-conditions-terms-buttons advads-buttonset"><?php
601 foreach ( $terms as $_term ) :
602 $field_id = "advads-conditions-$_term->term_id-$rand";
603 ?><input type="checkbox" id="<?php echo $field_id; ?>" name="<?php echo $inputname; ?>"
604 value="<?php echo $_term->term_id; ?>" <?php checked( in_array( $_term->term_id, $checked ), true );
605 ?>><label for="<?php echo $field_id; ?>"><?php echo $_term->name; ?></label><?php
606 endforeach;
607 include ADVADS_BASE_PATH . 'admin/views/conditions/not-selected.php';
608 ?>
609 </div><?php
610 endif;
611 endif;
612
613 return $terms;
614 }
615
616 /**
617 * Callback to display the metabox for the taxonomy archive pages
618 *
619 * @param array $options options of the condition.
620 * @param int $index index of the condition.
621 * @param string $form_name name of the form, falls back to class constant.
622 */
623 public static function metabox_post_ids( $options, $index = 0, $form_name = '' ) {
624
625 if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
626 return;
627 }
628
629 // get values and select operator based on previous settings.
630 $operator = ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) ? 'is_not' : 'is';
631 $values = ( isset( $options['value'] ) && is_array( $options['value'] ) ) ? $options['value'] : array();
632
633 // form name basis.
634 $name = self::get_form_name_with_index( $form_name, $index );
635
636 self::render_type_field( $options['type'], $name );
637
638 // load operator template.
639 include ADVADS_BASE_PATH . 'admin/views/conditions/condition-operator.php';
640
641 ?>
642 <div class="advads-conditions-single advads-buttonset advads-conditions-postid-buttons">
643 <?php
644 // query active post ids.
645 if ( array() !== $values ) {
646 $args = array(
647 'post_type' => 'any',
648 'post__in' => $values,
649 'posts_per_page' => - 1,
650 'order' => 'ASC',
651 'order_by' => 'title',
652
653 );
654
655 $the_query = new WP_Query( $args );
656 while ( $the_query->have_posts() ) {
657 $the_query->next_post();
658 ?><label
659 class="button ui-state-active"><?php echo get_the_title( $the_query->post->ID ) . ' (' . $the_query->post->post_type . ')';
660 ?><input type="hidden" name="<?php echo $name; ?>[value][]" value="<?php echo $the_query->post->ID; ?>">
661 </label><?php
662 }
663 }
664 ?><span class="advads-conditions-postids-show-search button" <?php
665 if ( ! count( $values ) ) {
666 echo 'style="display:none;"';
667 }
668 ?>>+</span>
669 <p class="advads-conditions-postids-search-line">
670 <input type="text" class="advads-display-conditions-individual-post" <?php if ( count( $values ) ) {
671 echo 'style="display:none;"';
672 } ?>
673 placeholder="<?php _e( 'title or id', 'advanced-ads' ); ?>"
674 data-field-name="<?php echo $name; ?>"/><?php
675 wp_nonce_field( 'internal-linking', '_ajax_linking_nonce', false );
676 ?></p></div><?php
677 }
678
679 /**
680 * Callback to display the metabox for the general display conditions
681 *
682 * @param array $options options of the condition.
683 * @param int $index index of the condition.
684 * @param string $form_name name of the form, falls back to class constant.
685 */
686 public static function metabox_general( $options, $index = 0, $form_name = '' ) {
687
688 // general conditions array.
689 $conditions = self::get_instance()->general_conditions();
690 if ( ! isset( $options['type'] ) || '' === $options['type'] ) {
691 return;
692 }
693
694 $name = self::get_form_name_with_index( $form_name, $index );
695 $values = isset( $options['value'] ) ? $options['value'] : array();
696 ?>
697 <div class="advads-conditions-single advads-buttonset">
698 <?php
699
700 self::render_type_field( $options['type'], $name );
701
702 $rand = md5( $form_name );
703 foreach ( $conditions as $_key => $_condition ) :
704
705 // activate by default.
706 $value = ( array() === $values || in_array( $_key, $values, true ) ) ? 1 : 0;
707
708 $field_id = "advads-conditions-$_key-$rand";
709 ?><input type="checkbox" id="<?php echo $field_id; ?>" name="<?php echo $name; ?>[value][]"
710 value="<?php echo $_key; ?>" <?php checked( 1, $value ); ?>><label
711 for="<?php echo $field_id; ?>"><?php echo $_condition['label']; ?></label><?php
712 endforeach;
713 include ADVADS_BASE_PATH . 'admin/views/conditions/not-selected.php';
714 ?></div><?php
715 return;
716 }
717
718 /**
719 * Retrieve the array with general conditions
720 *
721 * @return array $conditions
722 */
723 public static function general_conditions() {
724 return $conditions = apply_filters( 'advanced-ads-display-conditions-general',
725 array(
726 'is_front_page' => array(
727 'label' => __( 'Home Page', 'advanced-ads' ),
728 'description' => __( 'show on Home page', 'advanced-ads' ),
729 'type' => 'radio',
730 ),
731 'is_singular' => array(
732 'label' => __( 'Singular Pages', 'advanced-ads' ),
733 'description' => __( 'show on singular pages/posts', 'advanced-ads' ),
734 'type' => 'radio',
735 ),
736 'is_archive' => array(
737 'label' => __( 'Archive Pages', 'advanced-ads' ),
738 'description' => __( 'show on any type of archive page (category, tag, author and date)', 'advanced-ads' ),
739 'type' => 'radio',
740 ),
741 'is_search' => array(
742 'label' => __( 'Search Results', 'advanced-ads' ),
743 'description' => __( 'show on search result pages', 'advanced-ads' ),
744 'type' => 'radio',
745 ),
746 'is_404' => array(
747 'label' => __( '404 Page', 'advanced-ads' ),
748 'description' => __( 'show on 404 error page', 'advanced-ads' ),
749 'type' => 'radio',
750 ),
751 'is_attachment' => array(
752 'label' => __( 'Attachment Pages', 'advanced-ads' ),
753 'description' => __( 'show on attachment pages', 'advanced-ads' ),
754 'type' => 'radio',
755 ),
756 'is_main_query' => array(
757 'label' => __( 'Secondary Queries', 'advanced-ads' ),
758 'description' => __( 'allow ads in secondary queries', 'advanced-ads' ),
759 'type' => 'radio',
760 ),
761 'is_feed' => array(
762 'label' => __( 'RSS Feed', 'advanced-ads' ),
763 'description' => __( 'allow ads in RSS Feed', 'advanced-ads' ),
764 'type' => 'radio',
765 ),
766 )
767 );
768 }
769
770 /**
771 * Callback to display the 'content age' condition
772 *
773 * @param array $options options of the condition.
774 * @param int $index index of the condition.
775 * @param string $form_name name of the form, falls back to class constant.
776 */
777 public static function metabox_content_age( $options, $index = 0, $form_name = '' ) {
778 if ( ! isset ( $options['type'] ) || '' === $options['type'] ) {
779 return;
780 }
781
782 $type_options = self::get_instance()->conditions;
783
784 if ( ! isset( $type_options[ $options['type'] ] ) ) {
785 return;
786 }
787
788 // form name basis.
789 $name = self::get_form_name_with_index( $form_name, $index );
790
791 $operator = isset( $options['operator'] ) ? $options['operator'] : 'older_than';
792 $value = ( isset( $options['value'] ) && is_numeric( $options['value'] ) ) ? floatval( $options['value'] ) : 0;
793
794 self::render_type_field( $options['type'], $name );
795
796 ?>
797 <select name="<?php echo $name; ?>[operator]">
798 <option value="older_than" <?php selected( 'older_than', $operator ); ?>><?php _e( 'older than', 'advanced-ads' ); ?></option>
799 <option value="younger_than" <?php selected( 'younger_than', $operator ); ?>><?php _e( 'younger than', 'advanced-ads' ); ?></option>
800 </select><input type="text" name="<?php echo $name; ?>[value]"
801 value="<?php echo $value; ?>"/>&nbsp;<?php _e( 'days', 'advanced-ads' );
802 }
803
804 /**
805 * Check post type display condition in frontend
806 *
807 * @param array $options options of the condition.
808 * @param Advanced_Ads_Ad $ad Advanced_Ads_Ad.
809 *
810 * @return bool true if can be displayed
811 */
812 public static function check_post_type( $options = array(), Advanced_Ads_Ad $ad ) {
813 if ( ! isset( $options['value'] ) || ! is_array( $options['value'] ) ) {
814 return false;
815 }
816
817 if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
818 $operator = 'is_not';
819 } else {
820 $operator = 'is';
821 }
822
823 $ad_options = $ad->options();
824 $query = $ad_options['wp_the_query'];
825 $post = isset( $ad_options['post'] ) ? $ad_options['post'] : null;
826 $post_type = isset( $post['post_type'] ) ? $post['post_type'] : false;
827
828 if ( ! self::can_display_ids( $post_type, $options['value'], $operator ) ) {
829 return false;
830 }
831
832 return true;
833 }
834
835 /**
836 * Check author display condition in frontend
837 *
838 * @param array $options options of the condition.
839 * @param Advanced_Ads_Ad $ad Advanced_Ads_Ad.
840 *
841 * @return bool true if can be displayed
842 */
843 public static function check_author( $options = array(), Advanced_Ads_Ad $ad ) {
844
845 if ( ! isset( $options['value'] ) || ! is_array( $options['value'] ) ) {
846 return false;
847 }
848
849 if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
850 $operator = 'is_not';
851 } else {
852 $operator = 'is';
853 }
854
855 $ad_options = $ad->options();
856 $post = isset( $ad_options['post'] ) ? $ad_options['post'] : null;
857 $post_author = isset( $post['author'] ) ? $post['author'] : false;
858
859 if ( ! self::can_display_ids( $post_author, $options['value'], $operator ) ) {
860 return false;
861 }
862
863 return true;
864 }
865
866 /**
867 * Check taxonomies display condition in frontend
868 *
869 * @param array $options options of the condition.
870 * @param Advanced_Ads_Ad $ad ad.
871 *
872 * @return bool true if can be displayed
873 */
874 public static function check_taxonomies( $options = array(), Advanced_Ads_Ad $ad ) {
875
876 if ( ! isset( $options['value'] ) ) {
877 return false;
878 }
879
880 if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
881 $operator = 'is_not';
882 } else {
883 $operator = 'is';
884 }
885
886 $ad_options = $ad->options();
887 $query = $ad_options['wp_the_query'];
888 $post_id = isset( $ad_options['post']['id'] ) ? $ad_options['post']['id'] : null;
889
890 // get terms of the current taxonomy.
891 $type_options = self::get_instance()->conditions;
892 if ( ! isset( $options['type'] ) || ! isset( $type_options[ $options['type'] ]['taxonomy'] ) ) {
893 return true;
894 }
895 $taxonomy = $type_options[ $options['type'] ]['taxonomy'];
896
897 $terms = get_the_terms( $post_id, $taxonomy );
898
899 if ( is_array( $terms ) ) {
900 foreach ( $terms as $term ) {
901 $term_ids[] = $term->term_id;
902 }
903 } elseif ( false === $terms && 'is' === $operator ) {
904 // don’t show if should show only for a specific tag.
905 return false;
906 } else {
907 return true;
908 }
909
910 if ( 'is' === $operator && ( ! isset( $query['is_singular'] ) || ! $query['is_singular'] ) ) {
911 return false;
912 } elseif ( isset( $query['is_singular'] ) && $query['is_singular'] && ! self::can_display_ids( $options['value'], $term_ids, $operator )
913 ) {
914 return false;
915 }
916
917 return true;
918 }
919
920 /**
921 * Check taxonomy archive display condition in frontend
922 *
923 * @param array $options options of the condition.
924 * @param Advanced_Ads_Ad $ad ad.
925 *
926 * @return bool true if can be displayed
927 */
928 public static function check_taxonomy_archive( $options = array(), Advanced_Ads_Ad $ad ) {
929
930 if ( ! isset( $options['value'] ) ) {
931 return false;
932 }
933
934 if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
935 $operator = 'is_not';
936 } else {
937 $operator = 'is';
938 }
939
940 $ad_options = $ad->options();
941 $query = $ad_options['wp_the_query'];
942
943 // return false if operator is "is", but important query vars are not given.
944 if ( 'is' === $operator && ( empty( $query['term_id'] ) || empty( $query['is_archive'] ) ) ) {
945 return false;
946 } elseif ( isset( $query['term_id'] ) && isset( $query['is_archive'] ) && $query['is_archive'] && ! self::can_display_ids( $query['term_id'], $options['value'], $operator )
947 ) {
948 return false;
949 }
950
951 return true;
952 }
953
954 /**
955 * Check if a specific archive belongs to a taxonomy in general (not a specific term)
956 *
957 * @param array $options options of the condition.
958 * @param Advanced_Ads_Ad $ad ad.
959 *
960 * @return bool true if can be displayed
961 */
962 public static function check_taxonomy( $options = array(), Advanced_Ads_Ad $ad ) {
963
964 if ( ! isset( $options['value'] ) ) {
965 return false;
966 }
967
968 if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
969 $operator = 'is_not';
970 } else {
971 $operator = 'is';
972 }
973
974 $ad_options = $ad->options();
975 $query = $ad_options['wp_the_query'];
976
977 // return false if operator is "is", but important query vars are not given.
978 if ( 'is' === $operator && ( empty( $query['taxonomy'] ) || empty( $query['is_archive'] ) ) ) {
979 return false;
980 } elseif ( isset( $query['taxonomy'] ) && isset( $query['is_archive'] ) && $query['is_archive'] && ! self::can_display_ids( $query['taxonomy'], $options['value'], $operator )
981 ) {
982 return false;
983 }
984
985 return true;
986 }
987
988 /**
989 * Check post ids display condition in frontend
990 *
991 * @param array $options options of the condition.
992 * @param Advanced_Ads_Ad $ad ad.
993 *
994 * @return bool true if can be displayed
995 */
996 public static function check_post_ids( $options = array(), Advanced_Ads_Ad $ad ) {
997
998 if ( isset( $options['operator'] ) && 'is_not' === $options['operator'] ) {
999 $operator = 'is_not';
1000 } else {
1001 $operator = 'is';
1002 }
1003
1004 $ad_options = $ad->options();
1005 $query = $ad_options['wp_the_query'];
1006 $post_id = isset( $ad_options['post']['id'] ) ? $ad_options['post']['id'] : null;
1007
1008 // ixes page id on BuddyPress pages.
1009 if ( 0 === $post_id && class_exists( 'BuddyPress' ) && function_exists( 'bp_current_component' ) ) {
1010 $component = bp_current_component();
1011 $bp_pages = get_option( 'bp-pages' );
1012 if ( isset( $bp_pages[ $component ] ) ) {
1013 $post_id = $bp_pages[ $component ];
1014 }
1015 }
1016
1017 /**
1018 * WooCommerce Store page fix
1019 * since WooCommerce changes the post ID of the static page selected to be the product overview page, we need to get the original page id from the WC options
1020 */
1021 if ( function_exists( 'is_shop' ) && is_shop() && isset( $options['value'] ) && is_array( $options['value'] ) ) {
1022 $post_id = get_option( 'woocommerce_shop_page_id' );
1023
1024 return self::can_display_ids( $post_id, $options['value'], $operator );
1025 }
1026
1027 if ( empty( $ad_options['wp_the_query']['is_singular'] ) ) {
1028 if ( 'is_not' === $operator ) {
1029 return true;
1030 } else {
1031 return false;
1032 }
1033 }
1034
1035 if ( ! isset( $options['value'] ) || ! is_array( $options['value'] ) || ! $post_id ) {
1036 return true;
1037 }
1038
1039 return self::can_display_ids( $post_id, $options['value'], $operator );
1040 }
1041
1042 /**
1043 * Check general display conditions in frontend
1044 *
1045 * @param array $options options of the condition.
1046 * @param Advanced_Ads_Ad $ad ad.
1047 *
1048 * @return bool true if can be displayed
1049 */
1050 public static function check_general( $options = array(), Advanced_Ads_Ad $ad ) {
1051
1052 // display by default.
1053 if ( ! isset( $options['value'] ) || ! is_array( $options['value'] ) || ! count( $options['value'] ) ) {
1054 return true;
1055 }
1056
1057 // check general conditions added by other add-ons.
1058 if ( null !== ( $result = apply_filters( 'advanced-ads-display-conditions-check-general', null, $options['value'] ) ) ) {
1059 return $result;
1060 }
1061
1062 // skip checks, if general conditions are unchanged.
1063 if ( self::$default_general_keys === $options['value'] ) {
1064 return true;
1065 }
1066
1067 // get plugin options.
1068 $ad_options = $ad->options();
1069 $query = $ad_options['wp_the_query'];
1070
1071 // check main query.
1072 if ( isset( $query['is_main_query'] ) && ! $query['is_main_query'] && ! in_array( 'is_main_query', $options['value'], true ) ) {
1073 return false;
1074 }
1075
1076 // check home page.
1077 if ( ( ( isset( $query['is_front_page'] ) && $query['is_front_page'] )
1078 || ( isset( $query['is_home'] ) && $query['is_home'] ) )
1079 && in_array( 'is_front_page', $options['value'], true )
1080 ) {
1081 return true;
1082 } elseif ( isset( $query['is_front_page'] ) && $query['is_front_page'] && (
1083 ! in_array( 'is_front_page', $options['value'], true )
1084 ) ) {
1085 return false;
1086 }
1087
1088 // check common tests.
1089 foreach ( self::$query_var_keys as $_type ) {
1090 if ( 'is_main_query' !== $_type && isset( $query[ $_type ] ) && $query[ $_type ] &&
1091 in_array( $_type, $options['value'], true ) ) {
1092 return true;
1093 }
1094 }
1095
1096 return false;
1097 }
1098
1099 /**
1100 * Check 'content age' condition in frontend.
1101 *
1102 * @param array $options options of the condition.
1103 * @param Advanced_Ads_Ad $ad ad.
1104 *
1105 * @return bool true if can be displayed
1106 */
1107 public static function check_content_age( $options = array(), Advanced_Ads_Ad $ad ) {
1108 global $post;
1109
1110 $operator = ( isset( $options['operator'] ) && 'younger_than' === $options['operator'] ) ? 'younger_than' : 'older_than';
1111 $value = isset( $options['value'] ) ? $options['value'] : '';
1112
1113 if ( empty( $post->ID ) || empty( $value ) ) {
1114 return true;
1115 }
1116
1117 // get post publish date in unix timestamp.
1118 $publish_time = get_the_time( 'U', $post->ID );
1119
1120 // get difference from now.
1121 $diff_from_now = time() - $publish_time;
1122
1123 // check against entered age.
1124 $value_in_seconds = DAY_IN_SECONDS * $value;
1125
1126 if ( 'younger_than' === $operator ) {
1127 return $diff_from_now < $value_in_seconds;
1128 } else {
1129 return $diff_from_now > $value_in_seconds;
1130 }
1131 }
1132
1133 /**
1134 * Helper function to check for in array values
1135 *
1136 * @param mixed $id scalar (key) or array of keys as needle.
1137 * @param array $ids haystack.
1138 *
1139 * @return boolean void if either argument is empty
1140 */
1141 public static function in_array( $id, $ids ) {
1142 // empty?
1143 if ( ! isset( $id ) || array() === $id ) {
1144 return;
1145 }
1146
1147 // invalid?
1148 if ( ! is_array( $ids ) ) {
1149 return;
1150 }
1151
1152 return is_array( $id ) ? array() !== array_intersect( $id, $ids ) : in_array( $id, $ids );
1153 }
1154
1155 /**
1156 * Helper to compare ids.
1157 *
1158 * @param array $needle ids that should be searched for in haystack.
1159 * @param array $haystack reference ids.
1160 * @param string $operator whether it should be included or not.
1161 *
1162 * @return boolean
1163 */
1164 public static function can_display_ids( $needle, $haystack, $operator = 'is' ) {
1165
1166 if ( 'is' === $operator && self::in_array( $needle, $haystack ) === false ) {
1167 return false;
1168 }
1169
1170 if ( 'is_not' === $operator && self::in_array( $needle, $haystack ) === true ) {
1171 return false;
1172 }
1173
1174 return true;
1175 }
1176
1177 /**
1178 * Check display conditions
1179 *
1180 * @param bool $can_display whether the current ad can be displayed based on the checks that ran by now.
1181 * @param Advanced_Ads_Ad $ad ad object.
1182 *
1183 * @return bool $can_display true if can be displayed in frontend
1184 * @since 1.1.0 moved here from can_display()
1185 *
1186 * @since 1.7.0 moved here from display-by-query module
1187 */
1188 public function can_display( $can_display, $ad ) {
1189 if ( ! $can_display ) {
1190 return false;
1191 }
1192
1193 $options = $ad->options();
1194 if (
1195 // test if anything is to be limited at all.
1196 ! isset( $options['conditions'] ) || ! is_array( $options['conditions'] )
1197 // query arguments required.
1198 || ! isset( $options['wp_the_query'] )
1199 ) {
1200 return true;
1201 }
1202 // get conditions with rebased index keys.
1203 $conditions = array_values( $options['conditions'] );
1204 $query = $options['wp_the_query'];
1205 $post = isset( $options['post'] ) ? $options['post'] : null;
1206
1207
1208 $last_result = false;
1209 $length = count( $conditions );
1210
1211 for ( $i = 0; $i < $length; ++ $i ) {
1212 $_condition = current( $conditions );
1213 $next = next( $conditions );
1214 $next_key = key( $conditions );
1215
1216 /**
1217 * Force next condition’s connector to OR if
1218 * not set to OR already
1219 * this condition and the next are from the same taxonomy
1220 * the conditions don’t have the same condition type
1221 * they are both set to SHOW
1222 */
1223 $tax = ( isset( $_condition['type'] ) && isset( $this->conditions[ $_condition['type'] ]['taxonomy'] ) ) ? $this->conditions[ $_condition['type'] ]['taxonomy'] : false;
1224 $next_tax = ( isset( $next['type'] ) && isset( $this->conditions[ $next['type'] ]['taxonomy'] ) ) ? $this->conditions[ $next['type'] ]['taxonomy'] : false;
1225 if ( $tax && $next_tax && $next_key
1226 && $next_tax === $tax
1227 && ( ! isset( $next['connector'] ) || 'or' !== $next['connector'] )
1228 && 'is' === $_condition['operator'] && 'is' === $next['operator']
1229 && $_condition['type'] !== $next['type'] ) {
1230 $next['connector'] = 'or';
1231 $conditions[ $next_key ]['connector'] = 'or';
1232 }
1233
1234 // ignore OR if last result was true.
1235 if ( $last_result && isset( $_condition['connector'] ) && 'or' === $_condition['connector'] ) {
1236 continue;
1237 }
1238
1239 $result = self::frontend_check( $_condition, $ad );
1240 $last_result = $result;
1241 if ( ! $result ) {
1242 // return false only, if the next condition doesn’t have an OR operator.
1243 if ( ! isset( $next['connector'] ) || 'or' !== $next['connector'] ) {
1244 return false;
1245 }
1246 }
1247 }
1248
1249 return true;
1250 }
1251
1252 /**
1253 * On demand provide current query arguments to ads.
1254 *
1255 * Existing arguments must not be overridden.
1256 * Some arguments might be cachable.
1257 *
1258 * @param array $args arguments.
1259 *
1260 * @return array
1261 */
1262 public function ad_select_args_callback( $args ) {
1263 global $post, $wp_the_query, $wp_query, $numpages;
1264
1265 if ( isset( $post ) ) {
1266 if ( ! isset( $args['post'] ) ) {
1267 $args['post'] = array();
1268 }
1269 if ( ! isset( $args['post']['id'] ) ) {
1270
1271 // if currently on a single site, use the main query information just in case a custom query is broken.
1272 if ( isset( $wp_the_query->post->ID ) && $wp_the_query->is_single() ) {
1273 $args['post']['id'] = $wp_the_query->post->ID;
1274 } else {
1275 $args['post']['id'] = $post->ID;
1276 }
1277 }
1278 if ( ! isset( $args['post']['author'] ) ) {
1279 // if currently on a single site, use the main query information just in case a custom query is broken.
1280 if ( isset( $wp_the_query->post->post_author ) && $wp_the_query->is_single() ) {
1281 $args['post']['author'] = $wp_the_query->post->post_author;
1282 } else {
1283 // a user reported that the missing $post_author property issue appeared so let’s check if it exists.
1284 $args['post']['author'] = isset( $post->post_author ) ? $post->post_author : '';
1285 }
1286 }
1287 if ( ! isset( $args['post']['post_type'] ) ) {
1288 // if currently on a single site, use the main query information just in case a custom query is broken.
1289 if ( isset( $wp_the_query->post->post_type ) && $wp_the_query->is_single() ) {
1290 $args['post']['post_type'] = $wp_the_query->post->post_type;
1291 } else {
1292 // a user reported that the missing $post_type property issue appeared so let’s check if it exists.
1293 $args['post']['post_type'] = isset( $post->post_type ) ? $post->post_type : '';
1294 }
1295 }
1296 }
1297
1298 // pass query arguments.
1299 if ( isset( $wp_the_query ) ) {
1300 if ( ! isset( $args['wp_the_query'] ) ) {
1301 $args['wp_the_query'] = array();
1302 }
1303 $query = $wp_the_query->get_queried_object();
1304 // term_id exists only for taxonomy archive pages.
1305 if ( ! isset( $args['wp_the_query']['term_id'] ) && $query ) {
1306 $args['wp_the_query']['term_id'] = isset( $query->term_id ) ? $query->term_id : '';
1307 }
1308 // taxonomy.
1309 if ( ! isset( $args['wp_the_query']['taxonomy'] ) && $query ) {
1310 $args['wp_the_query']['taxonomy'] = isset( $query->taxonomy ) ? $query->taxonomy : '';
1311 }
1312
1313 // query type/ context.
1314 if ( ! isset( $args['wp_the_query']['is_main_query'] ) ) {
1315 $args['wp_the_query']['is_main_query'] = Advanced_Ads::get_instance()->is_main_query();
1316 }
1317
1318 // `<!-- nextpage -->` tags.
1319 if ( ! isset( $args['wp_the_query']['page'] ) ) {
1320 $args['wp_the_query']['page'] = isset( $wp_the_query->query_vars['page'] ) && $wp_the_query->query_vars['page'] ? $wp_the_query->query_vars['page'] : 1;
1321 $args['wp_the_query']['numpages'] = isset( $numpages ) ? $numpages : 1;
1322 }
1323
1324 // query vars.
1325 foreach ( self::$query_var_keys as $key ) {
1326 if ( ! isset( $args['wp_the_query'][ $key ] ) ) {
1327 $args['wp_the_query'][ $key ] = $wp_the_query->$key();
1328 }
1329 }
1330 }
1331
1332 return $args;
1333 }
1334
1335 /**
1336 * ;odify post search query to search by post_title or ID
1337 *
1338 * @param array $query post search query.
1339 *
1340 * @return array
1341 */
1342 public static function modify_post_search( $query ) {
1343
1344 // use ID and not search field if ID given.
1345 if ( 0 !== absint( $query['s'] ) && strlen( $query['s'] ) === strlen( absint( $query['s'] ) ) ) {
1346 $query['post__in'] = array( absint( $query['s'] ) );
1347 unset( $query['s'] );
1348 }
1349
1350 $query['suppress_filters'] = false;
1351 $query['orderby'] = 'post_title';
1352 $query['post_status'] = array( 'publish', 'pending', 'draft', 'future' );
1353
1354 return $query;
1355 }
1356
1357 /**
1358 * Modify post search SQL to search only in post title
1359 *
1360 * @param string $sql SQL statement.
1361 *
1362 * @return string
1363 */
1364 public static function modify_post_search_sql( $sql ) {
1365 global $wpdb;
1366
1367 // $sql = preg_replace_callback( "/{$wpdb->posts}.post_(content|excerpt)( NOT)? LIKE '%(.*?)%'/", array( 'Advanced_Ads_Display_Conditions', 'modify_post_search_sql_callback' ), $sql );
1368
1369 // removes the search in content and excerpt columns.
1370 $sql = preg_replace( "/OR \({$wpdb->posts}.post_(content|excerpt)( NOT)? LIKE '(.*?)'\)/", '', $sql );
1371
1372 return $sql;
1373 }
1374
1375 /**
1376 * Preg_replace callback used in modify_post_search_sql()
1377 *
1378 * @param array $matches results for post search.
1379 *
1380 * @return string
1381 * @deprecated since version 1.8.16
1382 */
1383 public static function modify_post_search_sql_callback( $matches ) {
1384 global $wpdb;
1385 if ( 'content' === $matches[1] && preg_match( '@^([0-9]+)$@', $matches[3], $matches_id ) ) {
1386 $equals_op = ' NOT' === $matches[2] ? '!=' : '=';
1387
1388 return "{$wpdb->posts}.ID$equals_op$matches_id[1]";
1389 } elseif ( ' NOT' === $matches[2] ) {
1390 return '1=1';
1391 } else {
1392 return '1=0';
1393 }
1394 }
1395
1396 }
1397