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