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