PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 1.4.4
Advanced Ads – Ad Manager & AdSense v1.4.4
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 12 years ago ad_type_content.php 11 years ago ad_type_plain.php 11 years ago widget.php 11 years ago
ad.php
970 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 == 1 && (!is_front_page() && !is_home))
419 || ($_cond_value == 0 && (is_front_page() || is_home())))
420 return false;
421 break;
422 // check is_singular
423 // @link https://codex.wordpress.org/Conditional_Tags#A_Post_Type
424 case 'is_singular' :
425 if(($_cond_value == 1 && !is_singular())
426 || ($_cond_value == 0 && is_singular()))
427 return false;
428 break;
429 // check is_archive
430 // @link https://codex.wordpress.org/Conditional_Tags#Any_Archive_Page
431 case 'is_archive' :
432 if(($_cond_value == 1 && !is_archive())
433 || ($_cond_value == 0 && is_archive()))
434 return false;
435 break;
436 // check is_search
437 // @link https://codex.wordpress.org/Conditional_Tags#A_Search_Result_Page
438 case 'is_search' :
439 if(($_cond_value == 1 && !is_search())
440 || ($_cond_value == 0 && is_search()))
441 return false;
442 break;
443 // check is_404
444 // @link https://codex.wordpress.org/Conditional_Tags#A_404_Not_Found_Page
445 case 'is_404' :
446 if(($_cond_value == 1 && !is_404())
447 || ($_cond_value == 0 && is_404()))
448 return false;
449 break;
450 // check is_attachment
451 // @link https://codex.wordpress.org/Conditional_Tags#An_Attachment
452 case 'is_attachment' :
453 if(($_cond_value == 1 && !is_attachment())
454 || ($_cond_value == 0 && is_attachment()))
455 return false;
456 break;
457 }
458 }
459
460 return true;
461 }
462
463 /**
464 * get all terms of a specific post or post type
465 *
466 * @param int $post_id id of the post
467 * @return arr $out ids of terms this post belongs to
468 */
469 private function get_object_terms($post_id = 0){
470
471 $post_id = absint($post_id);
472 if(!$post_id) return array();
473
474 // get post by post id
475 $post = get_post( $post_id );
476
477 // get post type by post
478 $post_type = $post->post_type;
479
480 // get post type taxonomies
481 $taxonomies = get_object_taxonomies( $post_type, 'objects' );
482
483 $term_ids = array();
484 foreach ( $taxonomies as $taxonomy_slug => $taxonomy ){
485
486 // get the terms related to post
487 $terms = get_the_terms( $post->ID, $taxonomy_slug );
488
489 if ( !empty( $terms ) ) {
490 foreach ( $terms as $term ) {
491 $term_ids[] = $term->term_id;
492 }
493 }
494 }
495
496 return $term_ids;
497 }
498
499 /**
500 * check visitor conditions
501 *
502 * @since 1.1.0
503 * @return bool $can_display true if can be displayed in frontend based on visitor settings
504 */
505 public function can_display_by_visitor(){
506
507 if(empty($this->options['visitor']) ||
508 !is_array($this->options['visitor'])) return true;
509
510 $visitor_conditions = $this->options('visitor');
511
512 // check mobile condition
513 if(!empty($visitor_conditions['mobile'])){
514 switch($visitor_conditions['mobile']){
515 case 'only' :
516 if(!wp_is_mobile()) return false;
517 break;
518 case 'no' :
519 if(wp_is_mobile()) return false;
520 break;
521 }
522 }
523
524 return true;
525 }
526
527 /**
528 * check expiry date
529 *
530 * @since 1.3.15
531 * @return bool $can_display true if can be displayed in frontend based on expiry date
532 */
533 public function can_display_by_expiry_date(){
534
535 if(empty($this->options['expiry_date'])) return true;
536
537 $expiry_date = absint($this->options('expiry_date'));
538
539 if($expiry_date == 0) return true;
540
541 // create blog specific timestamp
542 $blog_expiry_date = $expiry_date + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
543
544 // check blog time against current time
545 if($blog_expiry_date <= time()) return false;
546
547 return true;
548 }
549
550 /**
551 * save an ad to the database
552 * takes values from the current state
553 */
554 public function save(){
555 global $wpdb;
556
557 // remove slashes from content
558 $content = $this->prepare_content_to_save();
559
560 $where = array('ID' => $this->id);
561 $wpdb->update( $wpdb->posts, array( 'post_content' => $content ), $where );
562
563 // sanitize conditions
564 // see sanitize_conditions function for example on using this filter
565 $conditions = self::sanitize_conditions_on_save($this->conditions);
566
567 // save other options to post meta field
568 $options = $this->options();
569
570 $options['type'] = $this->type;
571 $options['width'] = $this->width;
572 $options['height'] = $this->height;
573 $options['conditions'] = $conditions;
574 $options['expiry_date'] = $this->expiry_date;
575 $options['description'] = $this->description;
576
577 // filter to manipulate options or add more to be saved
578 $options = apply_filters('advanced-ads-save-options', $options, $this);
579
580 // update global settings
581 $this->update_general_ad_conditions($conditions);
582
583 update_post_meta($this->id, self::$options_meta_field, $options);
584
585 }
586
587 /**
588 * native filter for content field before being saved
589 *
590 * @return string $content ad content
591 * @since 1.0.0
592 */
593 public function prepare_content_to_save() {
594
595 $content = $this->content;
596
597 // load ad type specific parameter filter
598 $content = $this->type_obj->sanitize_content($content);
599 // apply a custom filter by ad type
600 $content = apply_filters('advanced-ads-pre-ad-save-' . $this->type, $content);
601
602 return $content;
603 }
604
605 /**
606 * native filter for ad parameters before being saved
607 *
608 * @return arr $parameters sanitized parameters
609 */
610 public function prepare_parameters_to_save() {
611
612 $parameters = $this->parameters;
613 // load ad type specific parameter filter
614 $parameters = $this->type_obj->sanitize_parameters($parameters);
615
616 // apply native WP filter for content fields
617 return $parameters;
618 }
619
620 /**
621 * prepare ads output
622 *
623 * @param string $content ad content
624 * @param obj $ad ad object
625 */
626 public function prepare_frontend_output(){
627
628 // load ad type specific content filter
629 $output = $this->type_obj->prepare_output($this);
630
631 // build wrapper around the ad
632 $output = $this->add_wrapper($output);
633
634 // add a clearfix, if set
635 if(isset($this->output['clearfix']) && $this->output['clearfix']){
636 $output .= '<br style="clear: both; display: block; float: none;"/>';
637 }
638
639 // apply a custom filter by ad type
640 $output = apply_filters('advanced-ads-ad-output', $output, $this);
641
642 return $output;
643 }
644
645 /**
646 * sanitize ad display conditions when saving the ad
647 *
648 * @param array $conditions conditions array send via the dashboard form for an ad
649 * @return array with sanitized conditions
650 * @since 1.0.0
651 */
652 public function sanitize_conditions_on_save($conditions = array()){
653
654 global $advanced_ads_ad_conditions;
655
656 if(!is_array($conditions) || $conditions == array()) return array();
657
658 foreach($conditions as $_key => $_condition){
659 if($_key == 'postids'){
660 // sanitize single post conditions
661 if(empty($_condition['ids'])){ // remove, if empty
662 $_condition['include'] = array();
663 $_condition['exclude'] = array();
664 } else {
665 switch($_condition['method']){
666 case 'include' :
667 $_condition['include'] = $_condition['ids'];
668 $_condition['exclude'] = array();
669 break;
670 case 'exclude' :
671 $_condition['include'] = array();
672 $_condition['exclude'] = $_condition['ids'];
673 break;
674 }
675 }
676 } else {
677 if(!is_array($_condition))
678 $_condition = trim($_condition);
679 if($_condition == '') {
680 $conditions[$_key] = $_condition;
681 continue;
682 }
683 }
684 $type = !empty($advanced_ads_ad_conditions[$_key]['type']) ? $advanced_ads_ad_conditions[$_key]['type'] : 0;
685 if(empty($type)) continue;
686
687 // dynamically apply filters for each condition used
688 $conditions[$_key] = apply_filters('advanced-ads-sanitize-condition-' . $type, $_condition);
689 }
690
691 return $conditions;
692 }
693
694 /**
695 * sanitize id input field(s) for pattern /1,2,3,4/
696 *
697 * @pararm array/string $cond input string/array
698 * @return array/string $cond sanitized string/array
699 */
700 public static function sanitize_condition_idfield($cond = ''){
701 // strip anything that is not comma or number
702
703 if(is_array($cond)){
704 foreach($cond as $_key => $_cond){
705 $cond[$_key] = preg_replace('#[^0-9,]#', '', $_cond);
706 }
707 } else {
708 $cond = preg_replace('#[^0-9,]#', '', $cond);
709 }
710 return $cond;
711 }
712
713 /**
714 * sanitize radio input field
715 *
716 * @pararm string $string input string
717 * @return string $string sanitized string
718 */
719 public static function sanitize_condition_radio($string = ''){
720 // only allow 0, 1 and empty
721 return $string = preg_replace('#[^01]#', '', $string);
722 }
723
724 /**
725 * sanitize comma seperated text input field
726 *
727 * @pararm array/string $cond input string/array
728 * @return array/string $cond sanitized string/array
729 */
730 public static function sanitize_condition_textvalues($cond = ''){
731 // strip anything that is not comma, alphanumeric, minus and underscore
732 if(is_array($cond)){
733 foreach($cond as $_key => $_cond){
734 $cond[$_key] = preg_replace('#[^0-9,A-Za-z-_]#', '', $_cond);
735 }
736 } else {
737 $cond = preg_replace('#[^0-9,A-Za-z-_]#', '', $cond);
738 }
739 return $cond;
740 }
741
742 /**
743 * update general ad conditions with conditions for the current ad
744 *
745 * @param array $conditions ad display conditions from ad form
746 * @since 1.0.0
747 * @todo make those condition checks extendible
748 */
749 public function update_general_ad_conditions($conditions){
750 global $advanced_ads_ad_conditions;
751
752 $plugin = Advanced_Ads::get_instance();
753 $ads_by_conditions = $plugin->get_ads_by_conditions_array();
754
755 // remove current ad from general ad condition array
756 $ads_by_conditions = $this->remove_ad_from_general_ad_conditions($this->id, $ads_by_conditions);
757
758 // only run conditions if ad is publically visible
759 if($this->status == 'publish')
760 // iterate through the ads display condition
761 foreach($conditions as $_condition_key => $_condition){
762 if(!isset($advanced_ads_ad_conditions[$_condition_key]['type'])) {
763 $plugin->log(sprintf(__('A "%s" display condition does not exist', ADVADS_SLUG), $_condition_key));
764 return;
765 }
766 // add conditions based on type
767 switch($advanced_ads_ad_conditions[$_condition_key]['type']){
768 case 'idfield' :
769 if(isset($_condition['include']) && $_condition['include'] != ''){
770 if(is_array($_condition['include'])){
771 $_ids = $_condition['include'];
772 } else {
773 $_ids = explode(',', $_condition['include']);
774 }
775 if(is_array($_ids)) foreach($_ids as $_id){
776 $ads_by_conditions[$_condition_key][$_id]['include'][] = $this->id;
777 }
778 }
779 if(isset($_condition['exclude']) && $_condition['exclude'] != ''){
780 if(is_array($_condition['exclude'])){
781 $_ids = $_condition['exclude'];
782 } else {
783 $_ids = explode(',', $_condition['exclude']);
784 }
785 if(is_array($_ids)) foreach($_ids as $_id){
786 $ads_by_conditions[$_condition_key][$_id]['exclude'][] = $this->id;
787 }
788 }
789 break;
790 case 'textvalues' :
791 if(isset($_condition['include']) && $_condition['include'] != ''){
792 if(is_array($_condition['include'])){
793 $_ids = $_condition['include'];
794 } else {
795 $_ids = explode(',', $_condition['include']);
796 }
797 if(is_array($_ids)) foreach($_ids as $_id){
798 $ads_by_conditions[$_condition_key][$_id]['include'][] = $this->id;
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 break;
812 case 'radio' :
813 if($_condition == 1)
814 $ads_by_conditions[$_condition_key]['include'][] = $this->id;
815 elseif($_condition == 0)
816 $ads_by_conditions[$_condition_key]['exclude'][] = $this->id;
817 break;
818 case 'other' :
819 $ads_by_conditions[$_condition_key][$this->id] = $_condition;
820 } // switch
821 } // forearch
822
823 update_option('advads-ads-by-conditions', $ads_by_conditions);
824 }
825
826 /**
827 * remove ad id from ad conditions array
828 *
829 * @param int $ad_id id of the ad (=post id)
830 * @param arr $conditions array with the general, global ad conditions
831 * @since 1.0.0
832 */
833 static function remove_ad_from_general_ad_conditions($ad_id = 0, $conditions = array()){
834 $ad_id = absint($ad_id);
835 if(empty($ad_id) || !is_array($conditions) || $conditions == array()) return;
836
837 foreach($conditions as $_key => $_cond){
838 // remove single elements
839 if(!is_array($_cond) && $_cond == $ad_id){
840 unset($conditions[$_key]);
841 } elseif(empty($_cond)){
842 unset($conditions[$_key]);
843 }
844 // check recursively
845 elseif(is_array($_cond)){
846 $new_cond = self::remove_ad_from_general_ad_conditions($ad_id, $_cond);
847
848 if($new_cond == array() || $new_cond == ''){
849 // remove empty arrays
850 unset($conditions[$_key]);
851 } else {
852 $conditions[$_key] = $new_cond;
853 }
854 }
855 }
856
857 return $conditions;
858 }
859
860 /**
861 * load wrapper options set with the ad
862 *
863 * @since 1.3
864 * @return arr $wrapper options array ready to be use in add_wrapper() function
865 */
866 protected function load_wrapper_options(){
867 $wrapper = array();
868
869 // print_r($this->output);
870
871 if(!empty($this->output['position'])) {
872 switch($this->output['position']) {
873 case 'left' :
874 $wrapper['style']['float'] = 'left';
875 break;
876 case 'right' :
877 $wrapper['style']['float'] = 'right';
878 break;
879 case 'center' :
880 $wrapper['style']['text-align'] = 'center';
881 break;
882 case 'clearfix' :
883 $wrapper['style']['clear'] = 'both';
884 break;
885 }
886 }
887
888 if(!empty($this->output['class']) && is_array($this->output['class'])) {
889 $wrapper['class'] = $this->output['class'];
890 }
891
892 if(!empty($this->output['margin']['top'])) {
893 $wrapper['style']['margin-top'] = intval($this->output['margin']['top']) . 'px';
894 }
895 if(!empty($this->output['margin']['right'])) {
896 $wrapper['style']['margin-right'] = intval($this->output['margin']['right']) . 'px';
897 }
898 if(!empty($this->output['margin']['bottom'])) {
899 $wrapper['style']['margin-bottom'] = intval($this->output['margin']['bottom']) . 'px';
900 }
901 if(!empty($this->output['margin']['left'])) {
902 $wrapper['style']['margin-left'] = intval($this->output['margin']['left']) . 'px';
903 }
904
905 return $wrapper;
906 }
907
908 /**
909 * add a wrapper arount the ad content if wrapper information are given
910 *
911 * @since 1.1.4
912 * @param str $ad_content content of the ad
913 * @return str $wrapper ad within the wrapper
914 */
915 protected function add_wrapper($ad_content = ''){
916
917 $wrapper_options = apply_filters('advanced-ads-output-wrapper-options', $this->wrapper, $this);
918
919 if($wrapper_options == array() || !is_array($wrapper_options) || empty($wrapper_options)) return $ad_content;
920
921 $wrapper = $ad_content;
922
923 // create unique id if not yet given
924 if(empty($wrapper_options['id'])){
925 $wrapper_options['id'] = $this->create_wrapper_id();
926 }
927
928 // build the box
929 $wrapper = "<div";
930 foreach($wrapper_options as $_html_attr => $_values){
931 if($_html_attr == 'style'){
932 $_style_values_string = '';
933 foreach($_values as $_style_attr => $_style_values){
934 if(is_array($_style_values))
935 $_style_values_string .= $_style_attr . ': ' .implode(' ', $_style_values). '; ';
936 else
937 $_style_values_string .= $_style_attr . ': ' .$_style_values. '; ';
938 }
939 $wrapper .= " style=\"$_style_values_string\"";
940 } else {
941 if(is_array($_values))
942 $_values_string = implode(' ', $_values);
943 else
944 $_values_string = sanitize_title($_values);
945 $wrapper .= " $_html_attr=\"$_values_string\"";
946 }
947
948
949 }
950 $wrapper .= '>';
951 $wrapper .= apply_filters('advanced-ads-output-wrapper-before-content', '', $this);
952 $wrapper .= $ad_content;
953 $wrapper .= apply_filters('advanced-ads-output-wrapper-after-content', '', $this);
954 $wrapper .= '</div>';
955
956 return $wrapper;
957 }
958
959 /**
960 * create a random wrapper id
961 *
962 * @since 1.1.4
963 * @return string $id random id string
964 */
965 private function create_wrapper_id(){
966 return 'advads-' . mt_rand();
967 }
968
969 }
970