PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 1.4.7
Advanced Ads – Ad Manager & AdSense v1.4.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
ad.php 11 years ago ad_ajax_callbacks.php 11 years ago ad_group.php 11 years ago ad_placements.php 11 years ago ad_type_abstract.php 11 years ago ad_type_content.php 11 years ago ad_type_plain.php 11 years ago widget.php 11 years ago
ad.php
969 lines
1 <?php
2
3 /**
4 * Advanced Ads.
5 *
6 * @package Advads_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 Advads_Ad
17 * @author Thomas Maier <thomas.maier@webgilde.com>
18 */
19 class Advads_Ad {
20
21 /**
22 * id of the post type for this ad
23 */
24 public $id = 0;
25
26 /**
27 * true, if this is an Advanced Ads Ad post type
28 */
29 protected $is_ad = false;
30
31 /**
32 * ad type
33 */
34 public $type = 'content';
35
36 /**
37 * ad width
38 */
39 public $width = 0;
40
41 /**
42 * ad height
43 */
44 public $height = 0;
45
46 /**
47 * object of current ad type
48 */
49 protected $type_obj;
50
51 /**
52 * content of the ad
53 *
54 * only needed for ad types using the post content field
55 */
56 public $content = '';
57
58 /**
59 * conditions of the ad display
60 */
61 public $conditions = array();
62
63 /**
64 * status of the ad (e.g. publish, pending)
65 */
66 public $status = array();
67
68 /**
69 * array with meta field options aka parameters
70 */
71 protected $options = array();
72
73 /**
74 * name of the meta field to save options to
75 */
76 static $options_meta_field = 'advanced_ads_ad_options';
77
78 /**
79 * additional arguments set when ad is loaded, overwrites or extends options
80 */
81 public $args = array();
82
83 /**
84 * multidimensional array contains information about the wrapper
85 * each possible html attribute is an array with possible multiple elements
86 */
87 public $wrapper = array();
88
89 /**
90 * init ad object
91 *
92 * @param int $id id of the ad (= post id)
93 * @param arr $args additional arguments
94 */
95 public function __construct($id, $args = array()) {
96 global $advanced_ads_ad_conditions;
97 $id = absint( $id );
98 $this->id = $id;
99 $this->args = is_array( $args ) ? $args : array();
100
101 if ( ! empty($id) ) { $this->load( $id ); }
102
103 // dynamically add sanitize filters for condition types
104 $_types = array();
105 foreach ( $advanced_ads_ad_conditions as $_condition ) {
106 // add unique
107 $_types[$_condition['type']] = false;
108 }
109 // iterate types
110 foreach ( array_keys( $_types ) as $_type ) {
111 // -TODO might be faster to use __call() method or isset()-test class method array
112 $method_name = 'sanitize_condition_'. $_type;
113 if ( method_exists( $this, $method_name ) ) {
114 add_filter( 'advanced-ads-sanitize-condition-' . $_type, array($this, $method_name), 10, 1 );
115 } elseif ( function_exists( 'advads_sanitize_condition_' . $_type ) ) {
116 // check for public function to sanitize this
117 add_filter( 'advanced-ads-sanitize-condition-' . $_type, 'advads_sanitize_condition_' . $_type, 10, 1 );
118
119 }
120 }
121 }
122
123 /**
124 * load an ad object by id based on its ad type
125 *
126 * @since 1.0.0
127 */
128 private function load($id = 0){
129
130 $_data = get_post( $id );
131 if ( $_data == null ) { return false; }
132
133 // return, if not an ad
134 if ( $_data->post_type != Advanced_Ads::POST_TYPE_SLUG ) {
135 return false;
136 } else {
137 $this->is_ad = true;
138 }
139
140 $this->type = $this->options( 'type' );
141 $this->title = $_data->post_title;
142 /* load ad type object */
143 $types = Advanced_Ads::get_instance()->ad_types;
144 if ( isset($types[$this->type]) ){
145 $this->type_obj = $types[$this->type];
146 } else {
147 $this->type_obj = new Advads_Ad_Type_Abstract;
148 }
149 $this->width = $this->options( 'width' );
150 $this->height = $this->options( 'height' );
151 $this->conditions = $this->options( 'conditions' );
152 $this->description = $this->options( 'description' );
153 $this->output = $this->options( 'output' );
154 $this->status = $_data->post_status;
155 $this->wrapper = $this->load_wrapper_options();
156 $this->expiry_date = $this->options( 'expiry_date' );
157
158 // load content based on ad type
159 $this->content = $this->type_obj->load_content( $_data );
160
161 // set wrapper conditions
162 $this->wrapper = apply_filters( 'advanced-ads-set-wrapper', $this->wrapper, $this );
163 // add unique wrapper id, if options given
164 if ( is_array( $this->wrapper ) && $this->wrapper !== array() && ! isset($this->wrapper['id']) ){
165 // create unique id if not yet given
166 $this->wrapper['id'] = $this->create_wrapper_id();
167 }
168 }
169
170 /**
171 * get options from meta field and return specific field
172 *
173 * @param string $field post meta key to be returned
174 * @return mixed meta field content
175 * @since 1.0.0
176 * @todo check against default values
177 */
178 public function options($field = ''){
179 // retrieve options, if not given yet
180 if ( $this->options === array() ) {
181 // load arguments given on ad load
182 $this->options = $this->args;
183 // get_post_meta() may return false
184 $meta = get_post_meta( $this->id, self::$options_meta_field, true );
185 if ( $meta ){
186 $this->options = array_merge_recursive( $this->options, $meta );
187 }
188 }
189
190 // return specific option
191 if ( $field != '' ) {
192 if ( isset($this->options[$field]) ) {
193 return $this->options[$field]; }
194 } else { // return all options
195 if ( ! empty($this->options) ) {
196 return $this->options; }
197 }
198 }
199
200 /**
201 * set an option of the ad
202 *
203 * @since 1.1.0
204 * @param string $option name of the option
205 * @param mixed $value value of the option
206 */
207 public function set_option($option = '', $value = ''){
208 if ( $option == '' ) { return; }
209
210 // get current options
211 $options = $this->options();
212
213 // set options
214 $options[$option] = $value;
215
216 // save options
217 $this->options = $options;
218
219 }
220
221
222 /**
223 * return ad content for frontend output
224 *
225 * @since 1.0.0
226 * @return string $output ad output
227 */
228 public function output(){
229 if ( ! $this->is_ad ) { return ''; }
230
231 $output = $this->prepare_frontend_output();
232
233 // add the ad to the global output array
234 $advads = Advanced_Ads::get_instance();
235 $advads->current_ads[] = array('type' => 'ad', 'id' => $this->id, 'title' => $this->title);
236
237 // action when output is created
238 do_action( 'advanced-ads-output', $this, $output );
239
240 return $output;
241 }
242
243 /**
244 * check if the ad can be displayed in frontend due to its conditions
245 *
246 * @since 1.0.0
247 * @return bool $can_display true if can be displayed in frontend
248 */
249 public function can_display(){
250
251 $options = Advanced_Ads::get_instance()->options();
252 $see_ads_capability = ( ! empty($options['hide-for-user-role'])) ? $options['hide-for-user-role'] : 0;
253
254 // check global constant if ads are enabled or disabled
255 if ( defined( 'ADVADS_ADS_DISABLED' ) ) { return false; }
256
257 // don’t display ads that are not published or private for users not logged in
258 if ( $this->status !== 'publish' && ! ($this->status === 'private' && ! is_user_logged_in()) ){
259 return false;
260 }
261
262 // check if user is logged in and if so if users with his rights can see ads
263 if ( is_user_logged_in() && $see_ads_capability && current_user_can( $see_ads_capability ) ) {
264 return false;
265 }
266
267 if ( ! $this->can_display_by_conditions()
268 || ! $this->can_display_by_visitor()
269 || ! $this->can_display_by_expiry_date() ) {
270 return false;
271 }
272
273 // add own conditions to flag output as possible or not
274 $can_display = apply_filters( 'advanced-ads-can-display', true, $this );
275
276 return $can_display;
277 }
278
279 /**
280 * check display conditions
281 *
282 * @since 1.1.0 moved here from can_display()
283 * @return bool $can_display true if can be displayed in frontend
284 */
285 public function can_display_by_conditions(){
286 global $post, $wp_query;
287
288 $query = $wp_query->get_queried_object();
289
290 if ( empty($this->options['conditions']) ||
291 ! is_array( $this->options['conditions'] ) ) { return true; }
292
293 // display ad if conditions are explicitely disabled
294 if ( isset($this->options['conditions']['enabled']) && ! $this->options['conditions']['enabled'] ) { return true; }
295
296 $conditions = $this->options['conditions'];
297 foreach ( $conditions as $_cond_key => $_cond_value ) {
298 switch ( $_cond_key ){
299 // check for post ids
300 case 'postids' :
301 if ( is_singular() && empty($_cond_value['all']) ){
302 // included posts
303 if ( ! empty($_cond_value['include']) ){
304 if ( is_string( $_cond_value['include'] ) ){
305 $post_ids = explode( ',', $_cond_value['include'] );
306 } else {
307 $post_ids = $_cond_value['include'];
308 }
309 if ( is_array( $post_ids )
310 && isset($post->ID)
311 && ! in_array( $post->ID, $post_ids ) ) {
312 return false; }
313 }
314 // excluded posts
315 if ( ! empty($_cond_value['exclude']) ){
316 if ( is_string( $_cond_value['exclude'] ) ){
317 $post_ids = explode( ',', $_cond_value['exclude'] );
318 } else {
319 $post_ids = $_cond_value['exclude'];
320 }
321 if ( is_array( $post_ids ) && isset($post->ID) && in_array( $post->ID, $post_ids ) ){
322 return false;
323 }
324 }
325 }
326 break;
327 // check for category ids
328 case 'categoryids' :
329 // included
330 if ( is_singular() && empty($_cond_value['all']) ){
331 // get all taxonomies of the post
332 $term_ids = $this->get_object_terms( $post->ID );
333
334 if ( ! empty($_cond_value['include']) ){
335 if ( is_string( $_cond_value['include'] ) ){
336 $category_ids = explode( ',', $_cond_value['include'] );
337 } else {
338 $category_ids = $_cond_value['include'];
339 }
340
341 // check if currently in a post (not post page, but also posts in loops)
342 if ( is_array( $category_ids ) && isset($post->ID)
343 && ! count( array_intersect( $category_ids, $term_ids ) ) ) { // is there any taxonomy the same?
344 return false;
345 }
346 }
347 // check for excluded category ids
348 if ( ! empty($_cond_value['exclude']) ){
349 if ( is_string( $_cond_value['exclude'] ) ){
350 $category_ids = explode( ',', $_cond_value['exclude'] );
351 } else {
352 $category_ids = $_cond_value['exclude'];
353 }
354 // check if currently in a post (not post page, but also posts in loops)
355 if ( is_array( $category_ids ) && isset($post->ID)
356 && count( array_intersect( $category_ids, $term_ids ) ) ) { // is there any taxonomy the same
357 // being only in one excluded category is enough to not display the ad
358 return false;
359 }
360 }
361 }
362 break;
363 // check for included category archive ids
364 // @link http://codex.wordpress.org/Conditional_Tags#A_Category_Page
365 case 'categoryarchiveids' :
366 if ( isset($query->term_id) && is_archive() && empty($_cond_value['all']) ){
367 if ( ! empty($_cond_value['include']) ){
368 if ( is_string( $_cond_value['include'] ) ){
369 $category_ids = explode( ',', $_cond_value['include'] );
370 } else {
371 $category_ids = $_cond_value['include'];
372 }
373 if ( is_array( $category_ids ) && ! in_array( $query->term_id, $category_ids ) ) {
374 return false; }
375 }
376 // check for excluded category archive ids
377 if ( ! empty($_cond_value['exclude']) ){
378 if ( is_string( $_cond_value['exclude'] ) ){
379 $category_ids = explode( ',', $_cond_value['exclude'] );
380 } else {
381 $category_ids = $_cond_value['exclude'];
382 }
383 if ( is_array( $category_ids ) && in_array( $query->term_id, $category_ids ) ) {
384 return false; }
385 }
386 }
387 break;
388 // check for included post types
389 case 'posttypes' :
390 // display everywhere, if include not set (= all is checked)
391 // TODO remove condition check for string; deprecated since 1.2.2
392 if ( empty($_cond_value['all']) ){
393 if ( ! empty($_cond_value['include']) ){
394 if ( is_string( $_cond_value['include'] ) ){
395 $post_types = explode( ',', $_cond_value['include'] );
396 } else {
397 $post_types = $_cond_value['include'];
398 }
399 // check if currently in a post (not post page, but also posts in loops)
400 if ( is_array( $post_types ) && ! in_array( get_post_type(), $post_types ) ) {
401 return false;
402 }
403 }
404 // check for excluded post types
405 // TODO remove in a later version, deprecated since 1.2.2
406 if ( ! empty($_cond_value['exclude']) ){
407 $post_types = explode( ',', $_cond_value['exclude'] );
408 // check if currently in a post (not post page, but also posts in loops)
409 if ( is_array( $post_types ) && in_array( get_post_type(), $post_types ) ) {
410 return false;
411 }
412 }
413 }
414 break;
415 // check is_front_page
416 // @link https://codex.wordpress.org/Conditional_Tags#The_Front_Page
417 case 'is_front_page' :
418 if ( $_cond_value == 0 && (is_front_page() || is_home()) ) {
419 return false; }
420 break;
421 // check is_singular
422 // @link https://codex.wordpress.org/Conditional_Tags#A_Post_Type
423 case 'is_singular' :
424 if ( $_cond_value == 0 && is_singular() ) {
425 return false; }
426 break;
427 // check is_archive
428 // @link https://codex.wordpress.org/Conditional_Tags#Any_Archive_Page
429 case 'is_archive' :
430 if ( $_cond_value == 0 && is_archive() ) {
431 return false; }
432 break;
433 // check is_search
434 // @link https://codex.wordpress.org/Conditional_Tags#A_Search_Result_Page
435 case 'is_search' :
436 if ( $_cond_value == 0 && is_search() ) {
437 return false; }
438 break;
439 // check is_404
440 // @link https://codex.wordpress.org/Conditional_Tags#A_404_Not_Found_Page
441 case 'is_404' :
442 if ( $_cond_value == 0 && is_404() ) {
443 return false; }
444 break;
445 // check is_attachment
446 // @link https://codex.wordpress.org/Conditional_Tags#An_Attachment
447 case 'is_attachment' :
448 if ( $_cond_value == 0 && is_attachment() ) {
449 return false; }
450 break;
451 }
452 }
453
454 return true;
455 }
456
457 /**
458 * get all terms of a specific post or post type
459 *
460 * @param int $post_id id of the post
461 * @return arr $out ids of terms this post belongs to
462 */
463 private function get_object_terms($post_id = 0){
464
465 $post_id = absint( $post_id );
466 if ( ! $post_id ) { return array(); }
467
468 // get post by post id
469 $post = get_post( $post_id );
470
471 // get post type by post
472 $post_type = $post->post_type;
473
474 // get post type taxonomies
475 $taxonomies = get_object_taxonomies( $post_type, 'objects' );
476
477 $term_ids = array();
478 foreach ( $taxonomies as $taxonomy_slug => $taxonomy ){
479
480 // get the terms related to post
481 $terms = get_the_terms( $post->ID, $taxonomy_slug );
482
483 if ( ! empty( $terms ) ) {
484 foreach ( $terms as $term ) {
485 $term_ids[] = $term->term_id;
486 }
487 }
488 }
489
490 return $term_ids;
491 }
492
493 /**
494 * check visitor conditions
495 *
496 * @since 1.1.0
497 * @return bool $can_display true if can be displayed in frontend based on visitor settings
498 */
499 public function can_display_by_visitor(){
500
501 if ( empty($this->options['visitor']) ||
502 ! is_array( $this->options['visitor'] ) ) { return true; }
503
504 $visitor_conditions = $this->options( 'visitor' );
505
506 // check mobile condition
507 if ( ! empty($visitor_conditions['mobile']) ){
508 switch ( $visitor_conditions['mobile'] ){
509 case 'only' :
510 if ( ! wp_is_mobile() ) { return false; }
511 break;
512 case 'no' :
513 if ( wp_is_mobile() ) { return false; }
514 break;
515 }
516 }
517
518 return true;
519 }
520
521 /**
522 * check expiry date
523 *
524 * @since 1.3.15
525 * @return bool $can_display true if can be displayed in frontend based on expiry date
526 */
527 public function can_display_by_expiry_date(){
528
529 if ( !isset($this->options['expiry_date']) ) { return true; }
530
531 $ad_expiry_date = absint($this->options( 'expiry_date' ));
532
533 if ( $ad_expiry_date == 0 ) { return true; }
534
535 // create blog specific timestamp
536 $blog_expiry_date = time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
537
538 // check blog time against current time
539 if ( $blog_expiry_date >= $ad_expiry_date ) { return false; }
540
541 return true;
542 }
543
544 /**
545 * save an ad to the database
546 * takes values from the current state
547 */
548 public function save(){
549 global $wpdb;
550
551 // remove slashes from content
552 $content = $this->prepare_content_to_save();
553
554 $where = array('ID' => $this->id);
555 $wpdb->update( $wpdb->posts, array( 'post_content' => $content ), $where );
556
557 // sanitize conditions
558 // see sanitize_conditions function for example on using this filter
559 $conditions = self::sanitize_conditions_on_save( $this->conditions );
560
561 // save other options to post meta field
562 $options = $this->options();
563
564 $options['type'] = $this->type;
565 $options['width'] = $this->width;
566 $options['height'] = $this->height;
567 $options['conditions'] = $conditions;
568 $options['expiry_date'] = $this->expiry_date;
569 $options['description'] = $this->description;
570
571 // filter to manipulate options or add more to be saved
572 $options = apply_filters( 'advanced-ads-save-options', $options, $this );
573
574 // update global settings
575 $this->update_general_ad_conditions( $conditions );
576
577 update_post_meta( $this->id, self::$options_meta_field, $options );
578
579 }
580
581 /**
582 * native filter for content field before being saved
583 *
584 * @return string $content ad content
585 * @since 1.0.0
586 */
587 public function prepare_content_to_save() {
588
589 $content = $this->content;
590
591 // load ad type specific parameter filter
592 $content = $this->type_obj->sanitize_content( $content );
593 // apply a custom filter by ad type
594 $content = apply_filters( 'advanced-ads-pre-ad-save-' . $this->type, $content );
595
596 return $content;
597 }
598
599 /**
600 * native filter for ad parameters before being saved
601 *
602 * @return arr $parameters sanitized parameters
603 */
604 public function prepare_parameters_to_save() {
605
606 $parameters = $this->parameters;
607 // load ad type specific parameter filter
608 $parameters = $this->type_obj->sanitize_parameters( $parameters );
609
610 // apply native WP filter for content fields
611 return $parameters;
612 }
613
614 /**
615 * prepare ads output
616 *
617 * @param string $content ad content
618 * @param obj $ad ad object
619 */
620 public function prepare_frontend_output(){
621
622 // load ad type specific content filter
623 $output = $this->type_obj->prepare_output( $this );
624
625 // filter to manipulate the output before the wrapper is added
626 $output = apply_filters( 'advanced-ads-output-inside-wrapper', $output, $this );
627
628 // build wrapper around the ad
629 $output = $this->add_wrapper( $output );
630
631 // add a clearfix, if set
632 if ( isset($this->output['clearfix']) && $this->output['clearfix'] ){
633 $output .= '<br style="clear: both; display: block; float: none;"/>';
634 }
635
636 // apply a custom filter by ad type
637 $output = apply_filters( 'advanced-ads-ad-output', $output, $this );
638
639 return $output;
640 }
641
642 /**
643 * sanitize ad display conditions when saving the ad
644 *
645 * @param array $conditions conditions array send via the dashboard form for an ad
646 * @return array with sanitized conditions
647 * @since 1.0.0
648 */
649 public function sanitize_conditions_on_save($conditions = array()){
650
651 global $advanced_ads_ad_conditions;
652
653 if ( ! is_array( $conditions ) || $conditions == array() ) { return array(); }
654
655 foreach ( $conditions as $_key => $_condition ){
656 if ( $_key == 'postids' ){
657 // sanitize single post conditions
658 if ( empty($_condition['ids']) ){ // remove, if empty
659 $_condition['include'] = array();
660 $_condition['exclude'] = array();
661 } else {
662 switch ( $_condition['method'] ){
663 case 'include' :
664 $_condition['include'] = $_condition['ids'];
665 $_condition['exclude'] = array();
666 break;
667 case 'exclude' :
668 $_condition['include'] = array();
669 $_condition['exclude'] = $_condition['ids'];
670 break;
671 }
672 }
673 } else {
674 if ( ! is_array( $_condition ) ) {
675 $_condition = trim( $_condition ); }
676 if ( $_condition == '' ) {
677 $conditions[$_key] = $_condition;
678 continue;
679 }
680 }
681 $type = ! empty($advanced_ads_ad_conditions[$_key]['type']) ? $advanced_ads_ad_conditions[$_key]['type'] : 0;
682 if ( empty($type) ) { continue; }
683
684 // dynamically apply filters for each condition used
685 $conditions[$_key] = apply_filters( 'advanced-ads-sanitize-condition-' . $type, $_condition );
686 }
687
688 return $conditions;
689 }
690
691 /**
692 * sanitize id input field(s) for pattern /1,2,3,4/
693 *
694 * @pararm array/string $cond input string/array
695 * @return array/string $cond sanitized string/array
696 */
697 public static function sanitize_condition_idfield($cond = ''){
698 // strip anything that is not comma or number
699
700 if ( is_array( $cond ) ){
701 foreach ( $cond as $_key => $_cond ){
702 $cond[$_key] = preg_replace( '#[^0-9,]#', '', $_cond );
703 }
704 } else {
705 $cond = preg_replace( '#[^0-9,]#', '', $cond );
706 }
707 return $cond;
708 }
709
710 /**
711 * sanitize radio input field
712 *
713 * @pararm string $string input string
714 * @return string $string sanitized string
715 */
716 public static function sanitize_condition_radio($string = ''){
717 // only allow 0, 1 and empty
718 return $string = preg_replace( '#[^01]#', '', $string );
719 }
720
721 /**
722 * sanitize comma seperated text input field
723 *
724 * @pararm array/string $cond input string/array
725 * @return array/string $cond sanitized string/array
726 */
727 public static function sanitize_condition_textvalues($cond = ''){
728 // strip anything that is not comma, alphanumeric, minus and underscore
729 if ( is_array( $cond ) ){
730 foreach ( $cond as $_key => $_cond ){
731 $cond[$_key] = preg_replace( '#[^0-9,A-Za-z-_]#', '', $_cond );
732 }
733 } else {
734 $cond = preg_replace( '#[^0-9,A-Za-z-_]#', '', $cond );
735 }
736 return $cond;
737 }
738
739 /**
740 * update general ad conditions with conditions for the current ad
741 *
742 * @param array $conditions ad display conditions from ad form
743 * @since 1.0.0
744 * @todo make those condition checks extendible
745 */
746 public function update_general_ad_conditions($conditions){
747 global $advanced_ads_ad_conditions;
748
749 $plugin = Advanced_Ads::get_instance();
750 $ads_by_conditions = $plugin->get_ads_by_conditions_array();
751
752 // remove current ad from general ad condition array
753 $ads_by_conditions = $this->remove_ad_from_general_ad_conditions( $this->id, $ads_by_conditions );
754
755 // only run conditions if ad is publically visible
756 if ( $this->status == 'publish' ) {
757 // iterate through the ads display condition
758 foreach ( $conditions as $_condition_key => $_condition ){
759 if ( ! isset($advanced_ads_ad_conditions[$_condition_key]['type']) ) {
760 $plugin->log( sprintf( __( 'A "%s" display condition does not exist', ADVADS_SLUG ), $_condition_key ) );
761 return;
762 }
763 // add conditions based on type
764 switch ( $advanced_ads_ad_conditions[$_condition_key]['type'] ){
765 case 'idfield' :
766 if ( isset($_condition['include']) && $_condition['include'] != '' ){
767 if ( is_array( $_condition['include'] ) ){
768 $_ids = $_condition['include'];
769 } else {
770 $_ids = explode( ',', $_condition['include'] );
771 }
772 if ( is_array( $_ids ) ) { foreach ( $_ids as $_id ){
773 $ads_by_conditions[$_condition_key][$_id]['include'][] = $this->id;
774 }
775 }
776 }
777 if ( isset($_condition['exclude']) && $_condition['exclude'] != '' ){
778 if ( is_array( $_condition['exclude'] ) ){
779 $_ids = $_condition['exclude'];
780 } else {
781 $_ids = explode( ',', $_condition['exclude'] );
782 }
783 if ( is_array( $_ids ) ) { foreach ( $_ids as $_id ){
784 $ads_by_conditions[$_condition_key][$_id]['exclude'][] = $this->id;
785 }
786 }
787 }
788 break;
789 case 'textvalues' :
790 if ( isset($_condition['include']) && $_condition['include'] != '' ){
791 if ( is_array( $_condition['include'] ) ){
792 $_ids = $_condition['include'];
793 } else {
794 $_ids = explode( ',', $_condition['include'] );
795 }
796 if ( is_array( $_ids ) ) { foreach ( $_ids as $_id ){
797 $ads_by_conditions[$_condition_key][$_id]['include'][] = $this->id;
798 }
799 }
800 }
801 if ( isset($_condition['exclude']) && $_condition['exclude'] != '' ){
802 if ( is_array( $_condition['exclude'] ) ){
803 $_ids = $_condition['exclude'];
804 } else {
805 $_ids = explode( ',', $_condition['exclude'] );
806 }
807 if ( is_array( $_ids ) ) { foreach ( $_ids as $_id ){
808 $ads_by_conditions[$_condition_key][$_id]['exclude'][] = $this->id;
809 }
810 }
811 }
812 break;
813 case 'radio' :
814 if ( $_condition == 1 ) {
815 $ads_by_conditions[$_condition_key]['include'][] = $this->id; }
816 elseif ($_condition == 0)
817 $ads_by_conditions[$_condition_key]['exclude'][] = $this->id;
818 break;
819 case 'other' :
820 $ads_by_conditions[$_condition_key][$this->id] = $_condition;
821 } // switch
822 } // forearch
823 }
824 update_option( 'advads-ads-by-conditions', $ads_by_conditions );
825 }
826
827 /**
828 * remove ad id from ad conditions array
829 *
830 * @param int $ad_id id of the ad (=post id)
831 * @param arr $conditions array with the general, global ad conditions
832 * @since 1.0.0
833 */
834 static function remove_ad_from_general_ad_conditions($ad_id = 0, $conditions = array()){
835 $ad_id = absint( $ad_id );
836 if ( empty($ad_id) || ! is_array( $conditions ) || $conditions == array() ) { return; }
837
838 foreach ( $conditions as $_key => $_cond ){
839 // remove single elements
840 if ( ! is_array( $_cond ) && $_cond == $ad_id ){
841 unset($conditions[$_key]);
842 } elseif ( empty($_cond) ){
843 unset($conditions[$_key]);
844 }
845 // check recursively
846 elseif ( is_array( $_cond ) ){
847 $new_cond = self::remove_ad_from_general_ad_conditions( $ad_id, $_cond );
848
849 if ( $new_cond == array() || $new_cond == '' ){
850 // remove empty arrays
851 unset($conditions[$_key]);
852 } else {
853 $conditions[$_key] = $new_cond;
854 }
855 }
856 }
857
858 return $conditions;
859 }
860
861 /**
862 * load wrapper options set with the ad
863 *
864 * @since 1.3
865 * @return arr $wrapper options array ready to be use in add_wrapper() function
866 */
867 protected function load_wrapper_options(){
868 $wrapper = array();
869
870 // print_r($this->output);
871
872 if ( ! empty($this->output['position']) ) {
873 switch ( $this->output['position'] ) {
874 case 'left' :
875 $wrapper['style']['float'] = 'left';
876 break;
877 case 'right' :
878 $wrapper['style']['float'] = 'right';
879 break;
880 case 'center' :
881 $wrapper['style']['text-align'] = 'center';
882 break;
883 case 'clearfix' :
884 $wrapper['style']['clear'] = 'both';
885 break;
886 }
887 }
888
889 if ( ! empty($this->output['class']) && is_array( $this->output['class'] ) ) {
890 $wrapper['class'] = $this->output['class'];
891 }
892
893 if ( ! empty($this->output['margin']['top']) ) {
894 $wrapper['style']['margin-top'] = intval( $this->output['margin']['top'] ) . 'px';
895 }
896 if ( ! empty($this->output['margin']['right']) ) {
897 $wrapper['style']['margin-right'] = intval( $this->output['margin']['right'] ) . 'px';
898 }
899 if ( ! empty($this->output['margin']['bottom']) ) {
900 $wrapper['style']['margin-bottom'] = intval( $this->output['margin']['bottom'] ) . 'px';
901 }
902 if ( ! empty($this->output['margin']['left']) ) {
903 $wrapper['style']['margin-left'] = intval( $this->output['margin']['left'] ) . 'px';
904 }
905
906 return $wrapper;
907 }
908
909 /**
910 * add a wrapper arount the ad content if wrapper information are given
911 *
912 * @since 1.1.4
913 * @param str $ad_content content of the ad
914 * @return str $wrapper ad within the wrapper
915 */
916 protected function add_wrapper($ad_content = ''){
917
918 $wrapper_options = apply_filters( 'advanced-ads-output-wrapper-options', $this->wrapper, $this );
919
920 if ( $wrapper_options == array() || ! is_array( $wrapper_options ) || empty($wrapper_options) ) { return $ad_content; }
921
922 $wrapper = $ad_content;
923
924 // create unique id if not yet given
925 if ( empty($wrapper_options['id']) ){
926 $wrapper_options['id'] = $this->create_wrapper_id();
927 }
928
929 // build the box
930 $wrapper = '<div';
931 foreach ( $wrapper_options as $_html_attr => $_values ){
932 if ( $_html_attr == 'style' ){
933 $_style_values_string = '';
934 foreach ( $_values as $_style_attr => $_style_values ){
935 if ( is_array( $_style_values ) ) {
936 $_style_values_string .= $_style_attr . ': ' .implode( ' ', $_style_values ). '; '; }
937 else {
938 $_style_values_string .= $_style_attr . ': ' .$_style_values. '; '; }
939 }
940 $wrapper .= " style=\"$_style_values_string\"";
941 } else {
942 if ( is_array( $_values ) ) {
943 $_values_string = implode( ' ', $_values ); }
944 else {
945 $_values_string = sanitize_title( $_values ); }
946 $wrapper .= " $_html_attr=\"$_values_string\"";
947 }
948 }
949 $wrapper .= '>';
950 $wrapper .= apply_filters( 'advanced-ads-output-wrapper-before-content', '', $this );
951 $wrapper .= $ad_content;
952 $wrapper .= apply_filters( 'advanced-ads-output-wrapper-after-content', '', $this );
953 $wrapper .= '</div>';
954
955 return $wrapper;
956 }
957
958 /**
959 * create a random wrapper id
960 *
961 * @since 1.1.4
962 * @return string $id random id string
963 */
964 private function create_wrapper_id(){
965 return 'advads-' . mt_rand();
966 }
967
968 }
969