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