PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 1.7.7
Advanced Ads – Ad Manager & AdSense v1.7.7
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 / ad.php
advanced-ads / classes Last commit date
EDD_SL_Plugin_Updater.php 9 years ago ad-ajax.php 9 years ago ad-model.php 9 years ago ad-select.php 9 years ago ad.php 9 years ago ad_ajax_callbacks.php 9 years ago ad_group.php 9 years ago ad_placements.php 9 years ago ad_type_abstract.php 11 years ago ad_type_content.php 10 years ago ad_type_group.php 10 years ago ad_type_image.php 10 years ago ad_type_plain.php 10 years ago checks.php 9 years ago display-conditions.php 9 years ago plugin.php 9 years ago upgrades.php 10 years ago visitor-conditions.php 10 years ago widget.php 9 years ago
ad.php
890 lines
1 <?php
2
3 /**
4 * Advanced Ads Ad.
5 *
6 * @package Advanced_Ads_Ad
7 * @author Thomas Maier <thomas.maier@webgilde.com>
8 * @license GPL-2.0+
9 * @link http://webgilde.com
10 * @copyright 2013 Thomas Maier, webgilde GmbH
11 */
12
13 /**
14 * an ad object
15 *
16 * @package Advanced_Ads_Ad
17 * @author Thomas Maier <thomas.maier@webgilde.com>
18 * @deprecated since version 1.5.3 (May 6th 2015)
19 * might still be needed if some old add-ons are running somewhere
20 */
21 if( ! class_exists ( 'Advads_Ad', false ) ){
22 class Advads_Ad extends Advanced_Ads_Ad {
23
24 }
25 }
26
27 /**
28 * an ad object
29 *
30 * @package Advanced_Ads_Ad
31 * @author Thomas Maier <thomas.maier@webgilde.com>
32 */
33 class Advanced_Ads_Ad {
34
35 /**
36 * id of the post type for this ad
37 */
38 public $id = 0;
39
40 /**
41 * true, if this is an Advanced Ads Ad post type
42 */
43 protected $is_ad = false;
44
45 /**
46 * ad type
47 */
48 public $type = 'content';
49
50 /**
51 * ad width
52 */
53 public $width = 0;
54
55 /**
56 * target url
57 *
58 * @since 1.6.10
59 */
60 public $url = '';
61
62 /**
63 * ad height
64 */
65 public $height = 0;
66
67 /**
68 * object of current ad type
69 */
70 protected $type_obj;
71
72 /**
73 * content of the ad
74 *
75 * only needed for ad types using the post content field
76 */
77 public $content = '';
78
79 /**
80 * conditions of the ad display
81 */
82 public $conditions = array();
83
84 /**
85 * status of the ad (e.g. publish, pending)
86 */
87 public $status = array();
88
89 /**
90 * array with meta field options aka parameters
91 */
92 protected $options = array();
93
94 /**
95 * name of the meta field to save options to
96 */
97 static $options_meta_field = 'advanced_ads_ad_options';
98
99 /**
100 * additional arguments set when ad is loaded, overwrites or extends options
101 */
102 public $args = array();
103
104 /**
105 * multidimensional array contains information about the wrapper
106 * each possible html attribute is an array with possible multiple elements
107 */
108 public $wrapper = array();
109
110 /**
111 * init ad object
112 *
113 * @param int $id id of the ad (= post id)
114 * @param arr $args additional arguments
115 */
116 public function __construct($id, $args = array()) {
117 $id = absint( $id );
118 $this->id = $id;
119 $this->args = is_array( $args ) ? $args : array();
120
121 // whether the ad will be tracked
122 $this->global_output = isset( $this->args['global_output'] ) ? (bool) $this->args['global_output'] : true;
123
124 if ( ! empty($id) ) { $this->load( $id ); }
125
126 // dynamically add sanitize filters for condition types
127 $_types = array();
128 // -TODO use model
129 $advanced_ads_ad_conditions = Advanced_Ads::get_ad_conditions();
130 foreach ( $advanced_ads_ad_conditions as $_condition ) {
131 // add unique
132 $_types[$_condition['type']] = false;
133 }
134 // iterate types
135 foreach ( array_keys( $_types ) as $_type ) {
136 // -TODO might be faster to use __call() method or isset()-test class method array
137 $method_name = 'sanitize_condition_'. $_type;
138 if ( method_exists( $this, $method_name ) ) {
139 add_filter( 'advanced-ads-sanitize-condition-' . $_type, array($this, $method_name), 10, 1 );
140 } elseif ( function_exists( 'advads_sanitize_condition_' . $_type ) ) {
141 // check for public function to sanitize this
142 add_filter( 'advanced-ads-sanitize-condition-' . $_type, 'advads_sanitize_condition_' . $_type, 10, 1 );
143
144 }
145 }
146 }
147
148 /**
149 * load an ad object by id based on its ad type
150 *
151 * @since 1.0.0
152 */
153 private function load($id = 0){
154
155 $_data = get_post( $id );
156 if ( $_data == null ) { return false; }
157
158 // return, if not an ad
159 if ( $_data->post_type != Advanced_Ads::POST_TYPE_SLUG ) {
160 return false;
161 } else {
162 $this->is_ad = true;
163 }
164
165 $this->type = $this->options( 'type' );
166 $this->title = $_data->post_title;
167 /* load ad type object */
168 $types = Advanced_Ads::get_instance()->ad_types;
169 if ( isset($types[$this->type]) ){
170 $this->type_obj = $types[$this->type];
171 } else {
172 $this->type_obj = new Advanced_Ads_Ad_Type_Abstract;
173 }
174 $this->url = $this->options( 'url' );
175 $this->width = $this->options( 'width' );
176 $this->height = $this->options( 'height' );
177 $this->conditions = $this->options( 'conditions' );
178 $this->description = $this->options( 'description' );
179 $this->output = $this->options( 'output' );
180 $this->status = $_data->post_status;
181 $this->wrapper = $this->load_wrapper_options();
182 $this->expiry_date = $this->options( 'expiry_date' );
183
184 // load content based on ad type
185 $this->content = $this->type_obj->load_content( $_data );
186
187 // set wrapper conditions
188 $this->wrapper = apply_filters( 'advanced-ads-set-wrapper', $this->wrapper, $this );
189 // add unique wrapper id, if options given
190 if ( is_array( $this->wrapper ) && $this->wrapper !== array() && ! isset( $this->wrapper['id'] ) ){
191 // create unique id if not yet given
192 $this->wrapper['id'] = $this->create_wrapper_id();
193 }
194 }
195
196 /**
197 * get options from meta field and return specific field
198 *
199 * @param string $field post meta key to be returned
200 * @return mixed meta field content
201 * @since 1.0.0
202 * @todo check against default values
203 */
204 public function options( $field = '', $default = null ) {
205 // retrieve options, if not given yet
206 // -TODO may execute multiple times (if empty); bad design and risk to access unintialised data with direct access to $this->options property.
207 if ( $this->options === array() ) {
208 // load arguments given on ad load
209 $this->options = $this->args;
210 // get_post_meta() may return false
211 $meta = get_post_meta( $this->id, self::$options_meta_field, true );
212 if ( $meta ){
213 $this->options = array_merge_recursive( $this->options, $meta );
214 }
215 }
216
217 // return specific option
218 if ( $field != '' ) {
219 if ( isset($this->options[$field]) ) {
220 return $this->options[$field];
221 }
222 } else { // return all options
223 if ( ! empty($this->options) ) {
224 return $this->options;
225 }
226 }
227
228 return $default;
229 }
230
231 /**
232 * set an option of the ad
233 *
234 * @since 1.1.0
235 * @param string $option name of the option
236 * @param mixed $value value of the option
237 */
238 public function set_option($option = '', $value = ''){
239 if ( $option == '' ) { return; }
240
241 // get current options
242 $options = $this->options();
243
244 // set options
245 $options[$option] = $value;
246
247 // save options
248 $this->options = $options;
249
250 }
251
252
253 /**
254 * return ad content for frontend output
255 *
256 * @since 1.0.0
257 * @param array $output_options output options
258 * @return string $output ad output
259 */
260 public function output( $output_options = array() ){
261 if ( ! $this->is_ad ) { return ''; }
262
263 $output_options['global_output'] = $this->global_output = isset( $output_options['global_output'] ) ? $output_options['global_output'] : $this->global_output;
264
265 // switch between normal and debug mode
266 if( isset( $this->output['debugmode'] ) ){
267 $output = $this->prepare_debug_output();
268 } else {
269 $output = $this->prepare_frontend_output();
270 }
271
272 // add the ad to the global output array
273 $advads = Advanced_Ads::get_instance();
274 if ( $output_options['global_output'] ) {
275 $advads->current_ads[] = array('type' => 'ad', 'id' => $this->id, 'title' => $this->title, 'output' => $output);
276 }
277
278 // action when output is created
279 do_action( 'advanced-ads-output', $this, $output, $output_options );
280
281 return $output;
282 }
283
284 /**
285 * check if the ad can be displayed in frontend due to its own conditions
286 *
287 * @since 1.0.0
288 * @param array $check_options check options
289 * @return bool $can_display true if can be displayed in frontend
290 */
291 public function can_display( $check_options = array() ) {
292 $check_options = wp_parse_args( $check_options, array( 'passive_cache_busting' => false ) );
293
294 // force ad display if debug mode is enabled
295 if( isset( $this->output['debugmode'] )){
296 return true;
297 }
298
299 // prevent ad to show up through wp_head, if this is not a header placement
300 if( doing_action( 'wp_head' ) && isset( $this->options['placement_type'] ) && 'header' !== $this->options['placement_type'] ){
301 return false;
302 }
303
304 if ( ! $check_options['passive_cache_busting'] ) {
305 // don’t display ads that are not published or private for users not logged in
306 if ( $this->status !== 'publish' && ! ($this->status === 'private' && is_user_logged_in() ) ) {
307 return false;
308 }
309
310 if ( ! $this->can_display_by_visitor() || ! $this->can_display_by_expiry_date() ) {
311 return false;
312 }
313 } else {
314 if ( $this->status !== 'publish' || ! $this->can_display_by_expiry_date() ) {
315 return false;
316 }
317 }
318
319 // add own conditions to flag output as possible or not
320 $can_display = apply_filters( 'advanced-ads-can-display', true, $this, $check_options );
321
322 return $can_display;
323 }
324
325 /**
326 * check visitor conditions
327 *
328 * @since 1.1.0
329 * @return bool $can_display true if can be displayed in frontend based on visitor settings
330 */
331 public function can_display_by_visitor(){
332 if ( ! empty( $this->options['wp_the_query']['is_feed'] ) ) {
333 return true;
334 }
335
336 // check old "visitor" and new "visitors" conditions
337 if ( ( empty($this->options['visitors']) ||
338 ! is_array( $this->options['visitors'] ) )
339 && ( empty($this->options['visitor']) ||
340 ! is_array( $this->options['visitor'] )
341 )) { return true; }
342
343 if ( isset( $this->options['visitors'] ) && is_array( $this->options['visitors'] ) ) {
344
345 $visitor_conditions = $this->options['visitors'];
346
347 $last_result = false;
348 $length = count( $visitor_conditions );
349
350 for($i = 0; $i < $length; ++$i) {
351 $_condition = current( $visitor_conditions );
352 // ignore OR if last result was true
353 if( $last_result && isset( $_condition['connector'] ) && 'or' === $_condition['connector'] ){
354 next( $visitor_conditions );
355 continue;
356 }
357 $last_result = $result = Advanced_Ads_Visitor_Conditions::frontend_check( $_condition, $this );
358 if( ! $result ) {
359 // return false only, if the next condition doesn’t have an OR operator
360 $next = next( $visitor_conditions );
361 if( ! isset( $next['connector'] ) || $next['connector'] !== 'or' ) {
362 return false;
363 }
364 } else {
365 next( $visitor_conditions );
366 }
367 }
368 }
369
370 /**
371 * "old" visitor conditions
372 *
373 * @deprecated since version 1.5.4
374 */
375
376 if ( empty($this->options['visitor']) ||
377 ! is_array( $this->options['visitor'] ) ) { return true; }
378 $visitor_conditions = $this->options( 'visitor' );
379
380 // check mobile condition
381 if ( isset($visitor_conditions['mobile']) ){
382 switch ( $visitor_conditions['mobile'] ){
383 case 'only' :
384 if ( ! wp_is_mobile() ) { return false; }
385 break;
386 case 'no' :
387 if ( wp_is_mobile() ) { return false; }
388 break;
389 }
390 }
391
392 return true;
393 }
394
395 /**
396 * check expiry date
397 *
398 * @since 1.3.15
399 * @return bool $can_display true if can be displayed in frontend based on expiry date
400 */
401 public function can_display_by_expiry_date(){
402
403 // if expiry_date is not set null is returned
404 $ad_expiry_date = (int) $this->options( 'expiry_date' );
405
406 if ( $ad_expiry_date <= 0 || $ad_expiry_date > time() ) {
407 return true;
408 }
409
410 // set status to 'draft' if the ad is expired
411 if ( $this->status !== 'draft' ) {
412 wp_update_post( array( 'ID' => $this->id, 'post_status' => 'draft' ) );
413 }
414
415 return false;
416 }
417
418 /**
419 * save an ad to the database
420 * takes values from the current state
421 */
422 public function save(){
423 global $wpdb;
424
425 // remove slashes from content
426 $content = $this->prepare_content_to_save();
427
428 $where = array('ID' => $this->id);
429 $wpdb->update( $wpdb->posts, array( 'post_content' => $content ), $where );
430
431 // clean post from object cache
432 clean_post_cache( $this->id );
433
434 // sanitize conditions
435 // see sanitize_conditions function for example on using this filter
436 $conditions = self::sanitize_conditions_on_save( $this->conditions );
437
438 // save other options to post meta field
439 $options = $this->options();
440
441 $options['type'] = $this->type;
442 $options['url'] = $this->url;
443 $options['width'] = $this->width;
444 $options['height'] = $this->height;
445 $options['conditions'] = $conditions;
446 $options['expiry_date'] = $this->expiry_date;
447 $options['description'] = $this->description;
448
449 // filter to manipulate options or add more to be saved
450 $options = apply_filters( 'advanced-ads-save-options', $options, $this );
451
452 update_post_meta( $this->id, self::$options_meta_field, $options );
453 }
454
455 /**
456 * native filter for content field before being saved
457 *
458 * @return string $content ad content
459 * @since 1.0.0
460 */
461 public function prepare_content_to_save() {
462
463 $content = $this->content;
464
465 // load ad type specific parameter filter
466 // @todo this is just a hotfix for type_obj not set, yet the cause is still unknown
467 if(is_object( $this->type_obj )){
468 $content = $this->type_obj->sanitize_content( $content );
469 }
470 // apply a custom filter by ad type
471 $content = apply_filters( 'advanced-ads-pre-ad-save-' . $this->type, $content );
472
473 return $content;
474 }
475
476 /**
477 * native filter for ad parameters before being saved
478 *
479 * @return arr $parameters sanitized parameters
480 */
481 public function prepare_parameters_to_save() {
482
483 $parameters = $this->parameters;
484 // load ad type specific parameter filter
485 $parameters = $this->type_obj->sanitize_parameters( $parameters );
486
487 // apply native WP filter for content fields
488 return $parameters;
489 }
490
491 /**
492 * prepare ads output
493 *
494 */
495 public function prepare_frontend_output() {
496
497 // load ad type specific content filter
498 $output = $this->type_obj->prepare_output( $this );
499 // don’t deliver anything, if main ad content is empty
500 if( $output == '' ) {
501 return;
502 }
503
504 // filter to manipulate the output before the wrapper is added
505 $output = apply_filters( 'advanced-ads-output-inside-wrapper', $output, $this );
506
507 $output = $this->maybe_add_label ( $output );
508
509 // build wrapper around the ad
510 $output = $this->add_wrapper( $output );
511
512 // add a clearfix, if set
513 if ( isset($this->output['clearfix']) && $this->output['clearfix'] ){
514 $output .= '<br style="clear: both; display: block; float: none;"/>';
515 }
516
517 // apply a custom filter by ad type
518 $output = apply_filters( 'advanced-ads-ad-output', $output, $this );
519
520 return $output;
521 }
522
523 /**
524 * prepare debug mode output
525 *
526 * @since 1.7.0.3
527 */
528 public function prepare_debug_output() {
529
530 global $post, $wp_query;
531
532 // set size
533 if( $this->width && $this->height ){
534 $width = $this->width;
535 $height = $this->height;
536 } else {
537 $width = 300;
538 $height = 250;
539 }
540
541 $style = "width:{$width}px;height:{$height}px;background-color:#ddd;overflow:scroll;";
542
543 $prefix = Advanced_Ads_Plugin::get_instance()->get_frontend_prefix();
544
545 $content = array();
546
547 // display notice that debug doesn’t work with cache-busting
548 if( class_exists( 'Advanced_Ads_Pro_Module_Cache_Busting', false ) && isset ( $this->args['cache-busting'] ) && 'off' !== $this->args['cache-busting'] ){
549 $content[] = '<span style="color: red;">Debug mode does not work properly with cache-busting enabled for this ad.</span>';
550 }
551
552 // compare current wp_query with global wp_main_query
553 if( ! $wp_query->is_main_query() ){
554 $content[] = '<span style="color: red;">Current query is not identical to main query.</span>';
555 // output differences
556 $content[] = $this->build_query_diff_table();
557 }
558
559 // compare current post with global post
560 if( $wp_query->post !== $post ){
561 $error = '<span style="color: red;">Current post is not identical to main post.</span>';
562 // output differences
563 if( isset( $post->post_title ) && $post->ID ){
564 $error .= '<br/>current post: ' . $post->post_title . ', ID: ' . $post->ID;
565 }
566 if( isset( $wp_query->post->post_title ) && $wp_query->post->ID ){
567 $error .= '<br/>main post: ' . $wp_query->post->post_title . ', ID: ' . $wp_query->post->ID;
568 }
569 $content[] = $error;
570 }
571
572 ob_start();
573
574 include( ADVADS_BASE_PATH . '/public/views/ad-debug.php' );
575
576 $output = ob_get_clean();
577
578 // apply a custom filter by ad type
579 $output = apply_filters( 'advanced-ads-ad-output-debug', $output, $this );
580
581 return $output;
582
583 }
584
585 /**
586 * build table with differences between current and main query
587 *
588 * @since 1.7.0.3
589 */
590 private function build_query_diff_table(){
591
592 global $wp_query, $wp_the_query;
593
594 $diff_current = array_diff_assoc( $wp_query->query_vars, $wp_the_query->query_vars );
595 $diff_main = array_diff_assoc( $wp_the_query->query_vars, $wp_query->query_vars );
596
597 if( ! is_array( $diff_current ) || ! is_array( $diff_main ) ){
598 return '';
599 }
600
601 ob_start();
602
603 ?><table><thead><tr><th></th><th>current query</th><th>main query</th></tr></thead><?php
604 foreach( $diff_current as $_key => $_value ){
605 ?><tr><td><?php echo $_key; ?></td><td><?php echo $_value; ?></td><td><?php if( isset( $diff_main[$_key] ) ) echo $diff_main[$_key]; ?></td></tr><?php
606 }
607 ?></table><?php
608
609 return ob_get_clean();
610 }
611
612 /**
613 * sanitize ad display conditions when saving the ad
614 *
615 * @param array $conditions conditions array send via the dashboard form for an ad
616 * @return array with sanitized conditions
617 * @since 1.0.0
618 */
619 public function sanitize_conditions_on_save($conditions = array()){
620
621 global $advanced_ads_ad_conditions;
622
623 if ( ! is_array( $conditions ) || $conditions == array() ) { return array(); }
624
625 foreach ( $conditions as $_key => $_condition ){
626 if ( $_key == 'postids' ){
627 // sanitize single post conditions
628 if ( empty($_condition['ids']) ){ // remove, if empty
629 $_condition['include'] = array();
630 $_condition['exclude'] = array();
631 } elseif( isset( $_condition['method'] ) ) {
632 switch ( $_condition['method'] ){
633 case 'include' :
634 $_condition['include'] = $_condition['ids'];
635 $_condition['exclude'] = array();
636 break;
637 case 'exclude' :
638 $_condition['include'] = array();
639 $_condition['exclude'] = $_condition['ids'];
640 break;
641 }
642 }
643 } else {
644 if ( ! is_array( $_condition ) ) {
645 $_condition = trim( $_condition ); }
646 if ( $_condition == '' ) {
647 $conditions[$_key] = $_condition;
648 continue;
649 }
650 }
651 $type = ! empty($advanced_ads_ad_conditions[$_key]['type']) ? $advanced_ads_ad_conditions[$_key]['type'] : 0;
652 if ( empty($type) ) { continue; }
653
654 // dynamically apply filters for each condition used
655 $conditions[$_key] = apply_filters( 'advanced-ads-sanitize-condition-' . $type, $_condition );
656 }
657 return $conditions;
658 }
659
660 /**
661 * sanitize id input field(s) for pattern /1,2,3,4/
662 *
663 * @pararm array/string $cond input string/array
664 * @return array/string $cond sanitized string/array
665 */
666 public static function sanitize_condition_idfield($cond = ''){
667 // strip anything that is not comma or number
668
669 if ( is_array( $cond ) ){
670 foreach ( $cond as $_key => $_cond ){
671 $cond[$_key] = preg_replace( '#[^0-9,]#', '', $_cond );
672 }
673 } else {
674 $cond = preg_replace( '#[^0-9,]#', '', $cond );
675 }
676 return $cond;
677 }
678
679 /**
680 * sanitize radio input field
681 *
682 * @pararm string $string input string
683 * @return string $string sanitized string
684 */
685 public static function sanitize_condition_radio($string = ''){
686 // only allow 0, 1 and empty
687 return $string = preg_replace( '#[^01]#', '', $string );
688 }
689
690 /**
691 * sanitize comma seperated text input field
692 *
693 * @pararm array/string $cond input string/array
694 * @return array/string $cond sanitized string/array
695 */
696 public static function sanitize_condition_textvalues($cond = ''){
697 // strip anything that is not comma, alphanumeric, minus and underscore
698 if ( is_array( $cond ) ){
699 foreach ( $cond as $_key => $_cond ){
700 $cond[$_key] = preg_replace( '#[^0-9,A-Za-z-_]#', '', $_cond );
701 }
702 } else {
703 $cond = preg_replace( '#[^0-9,A-Za-z-_]#', '', $cond );
704 }
705 return $cond;
706 }
707
708 /**
709 * load wrapper options set with the ad
710 *
711 * @since 1.3
712 * @return arr $wrapper options array ready to be use in add_wrapper() function
713 */
714 protected function load_wrapper_options(){
715 $wrapper = array();
716
717 // print_r($this->output);
718
719 if ( ! empty($this->output['position']) ) {
720 switch ( $this->output['position'] ) {
721 case 'left' :
722 $wrapper['style']['float'] = 'left';
723 break;
724 case 'right' :
725 $wrapper['style']['float'] = 'right';
726 break;
727 case 'center' :
728 $wrapper['style']['text-align'] = 'center';
729 // add css rule after wrapper to center the ad
730 // add_filter( 'advanced-ads-output-wrapper-after-content', array( $this, 'center_ad_content' ), 10, 2 );
731 break;
732 case 'clearfix' :
733 $wrapper['style']['clear'] = 'both';
734 break;
735 }
736 }
737
738 if ( isset($this->output['class']) && is_array( $this->output['class'] ) ) {
739 $wrapper['class'] = $this->output['class'];
740 }
741
742 // add manual classes
743 if ( isset($this->output['wrapper-class']) && '' !== $this->output['wrapper-class'] ) {
744 $classes = explode( ' ', $this->output['wrapper-class'] );
745
746 foreach( $classes as $_class ){
747 $wrapper['class'][] = sanitize_text_field( $_class );
748 }
749 }
750
751 if ( ! empty($this->output['margin']['top']) ) {
752 $wrapper['style']['margin-top'] = intval( $this->output['margin']['top'] ) . 'px';
753 }
754 if ( ! empty($this->output['margin']['right']) ) {
755 $wrapper['style']['margin-right'] = intval( $this->output['margin']['right'] ) . 'px';
756 }
757 if ( ! empty($this->output['margin']['bottom']) ) {
758 $wrapper['style']['margin-bottom'] = intval( $this->output['margin']['bottom'] ) . 'px';
759 }
760 if ( ! empty($this->output['margin']['left']) ) {
761 $wrapper['style']['margin-left'] = intval( $this->output['margin']['left'] ) . 'px';
762 }
763
764 if ( ! empty ($this->output['add_wrapper_sizes'] ) ) {
765 $wrapper['style']['width'] = intval( $this->width ) . 'px';
766 $wrapper['style']['height'] = intval( $this->height ) . 'px';
767 }
768
769 $wrapper['data-id'] = $this->id;
770
771 return $wrapper;
772 }
773
774 /**
775 * add a wrapper arount the ad content if wrapper information are given
776 *
777 * @since 1.1.4
778 * @param str $ad_content content of the ad
779 * @return str $wrapper ad within the wrapper
780 */
781 protected function add_wrapper($ad_content = ''){
782
783 $wrapper_options = apply_filters( 'advanced-ads-output-wrapper-options', $this->wrapper, $this );
784
785 if ( ( ! isset( $this->output['wrapper-id'] ) || '' === $this->output['wrapper-id'] )
786 && $wrapper_options == array() || ! is_array( $wrapper_options ) ) { return $ad_content; }
787
788 // create unique id if not yet given
789 if ( empty($wrapper_options['id']) ){
790 $this->wrapper['id'] = $wrapper_options['id'] = $this->create_wrapper_id();
791 }
792
793 // build the box
794 $wrapper = '<div';
795 foreach ( $wrapper_options as $_html_attr => $_values ){
796 if ( $_html_attr == 'style' ){
797 $_style_values_string = '';
798 foreach ( $_values as $_style_attr => $_style_values ){
799 if ( is_array( $_style_values ) ) {
800 $_style_values_string .= $_style_attr . ': ' .implode( ' ', $_style_values ). '; '; }
801 else {
802 $_style_values_string .= $_style_attr . ': ' .$_style_values. '; '; }
803 }
804 $wrapper .= " style=\"$_style_values_string\"";
805 } else {
806 if ( is_array( $_values ) ) {
807 $_values_string = implode( ' ', $_values ); }
808 else {
809 $_values_string = sanitize_title( $_values ); }
810 $wrapper .= " $_html_attr=\"$_values_string\"";
811 }
812 }
813 $wrapper .= '>';
814 $wrapper .= apply_filters( 'advanced-ads-output-wrapper-before-content', '', $this );
815 $wrapper .= $ad_content;
816 $wrapper .= apply_filters( 'advanced-ads-output-wrapper-after-content', '', $this );
817 $wrapper .= '</div>';
818
819 return $wrapper;
820 }
821
822 /**
823 * function to add css rule after the ad to center its content
824 *
825 * @since 1.6.9.5
826 * @param str $output additional output in wrapper after content
827 * @param obj $ad Advanced_Ads_Ad object
828 * @return str $output
829 *
830 */
831 /*public function center_ad_content( $output, Advanced_Ads_Ad $ad ){
832
833 // no additional check needed, because the hook is only called when the ad is centered
834 if( isset( $ad->wrapper['id'] )){
835 // does not work with most div elements, so actually not used now
836 $output .= '<style type="text/css">#'. $ad->wrapper['id'] . ' img, #'. $ad->wrapper['id'] . ' div { display: inline !important; }</style>';
837 }
838
839 return $output;
840 }*/
841
842 /**
843 * create a random wrapper id
844 *
845 * @since 1.1.4
846 * @return string $id random id string
847 */
848 private function create_wrapper_id(){
849
850 if( isset( $this->output['wrapper-id'] )){
851 $id = sanitize_key( $this->output['wrapper-id'] );
852 if( '' !== $id ){
853 return $id;
854 }
855 }
856
857 $prefix = Advanced_Ads_Plugin::get_instance()->get_frontend_prefix();
858
859 return $prefix . mt_rand();
860 }
861
862 /**
863 * add an "Advertisement" label if conditions are met
864 *
865 * @param str $output
866 * @return str $output
867 */
868 public function maybe_add_label( &$output ) {
869 if ( isset( $this->args['placement_type'] ) && $this->args['placement_type'] !== 'header' &&
870 $this->type !== 'group' &&
871 $label = Advanced_Ads::get_instance()->get_label()
872 ) {
873 // ignore slider and group with refresh
874 if ( isset( $this->args['group_info']['type'] ) &&
875 $this->args['group_info']['type'] === 'slider' &&
876 ! empty( $this->args['group_info']['refresh_enabled'] )
877 ) {
878 return $output;
879 }
880 // first ad in a group or single ad without group, and not group output for passive cb
881 if ( empty( $this->args['group_info']['ads_displayed'] ) && empty( $this->args['group_info']['passive_cb'] ) ) {
882 $output = $label . $output;
883 }
884 }
885
886 return $output;
887 }
888
889 }
890