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