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