PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 1.5.1
Advanced Ads – Ad Manager & AdSense v1.5.1
2.0.23 2.0.22 2.0.21 1.38.0 1.39.0 1.39.1 1.39.2 1.39.3 1.39.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.40.0 1.40.1 1.40.2 1.41.0 1.42.0 1.42.1 1.42.2 1.43.0 1.44.0 1.44.1 1.45.0 1.45.1 1.46.0 1.47.0 1.47.1 1.47.2 1.47.3 1.47.4 1.47.5 1.48.0 1.48.1 1.49.0 1.5.0 1.5.0.1 1.5.1 1.5.2 1.5.2.1 1.5.4 1.5.4.1 1.5.5 1.50.0 1.51.0 1.51.1 1.51.2 1.51.3 1.52.0 1.52.1 1.52.2 1.52.3 1.52.4 1.53.0 1.53.1 1.53.2 1.54.0 1.54.1 1.55.0 1.56.0 1.56.1 1.56.2 1.56.3 1.56.4 1.6 1.6.1 1.6.10 1.6.10.1 1.6.10.2 1.6.11 1.6.11.1 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.17.1 1.6.17.2 1.6.2 1.6.2.1 1.6.3 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.6.1 1.6.7 1.6.7.1 1.6.8 1.6.8.1 1.6.8.2 1.6.8.3 1.6.9 1.6.9.1 1.6.9.2 1.6.9.3 1.6.9.4 1.7 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.1.1 1.7.1.2 1.7.1.3 1.7.1.4 1.7.1.5 1.7.10 trunk 1.7.11 1.0.1 1.7.12 1.0.2 1.7.13 1.0.3 1.7.14 1.1.0 1.7.15 1.1.1 1.7.16 1.1.2 1.7.17 1.1.3 1.7.18 1.10 1.7.19 1.10.1 1.7.2 1.10.10 1.7.2.1 1.10.11 1.7.20 1.10.12 1.7.21 1.10.2 1.7.22 1.10.3 1.7.23 1.10.4 1.7.24 1.10.5 1.7.25 1.10.6 1.7.3 1.10.7 1.7.4 1.10.8 1.7.4.1 1.10.9 1.7.4.2 1.11 1.7.4.3 1.11.1 1.7.4.4 1.11.2 1.7.4.5 1.12 1.7.5 1.13 1.7.5.1 1.13.1 1.7.6 1.13.2 1.7.7 1.13.3 1.7.8 1.13.4 1.7.9 1.13.5 1.7.9.1 1.13.6 1.7.9.2 1.13.7 1.7.9.3 1.13.8 1.8 1.14 1.8.1 1.14.1 1.8.10 1.14.10 1.8.11 1.14.11 1.8.12 1.14.2 1.8.13 1.14.3 1.8.14 1.14.4 1.8.15 1.14.5 1.8.16 1.14.6 1.8.17 1.14.7 1.8.18 1.14.8 1.8.19 1.14.9 1.8.2 1.15 1.8.20 1.16 1.8.21 1.16.1 1.8.22 1.17 1.8.23 1.17.1 1.8.24 1.17.10 1.8.25 1.17.10-rc.1 1.8.26 1.17.11 1.8.27 1.17.12 1.8.28 1.17.12-rc.1 1.8.29 1.17.2 1.8.3 1.17.3 1.8.30 1.17.4 1.8.4 1.17.5 1.8.5 1.17.6 1.8.6 1.17.7 1.8.7 1.17.8 1.8.8 1.17.9 1.8.9 1.17.9-beta.1 1.9 1.18.0 2.0.0 1.19.0 2.0.1 1.19.1 2.0.10 1.2 2.0.11 1.2.1 2.0.12 1.2.2 2.0.13 1.2.3 2.0.14 1.2.4 2.0.15 1.2.5 2.0.16 1.2.6 2.0.17 1.2.7 2.0.18 1.20.0 2.0.19 1.20.0-rc.1 2.0.2 1.20.0-rc.2 2.0.20 1.20.1 2.0.3 1.20.2 2.0.4 1.20.3 2.0.5 1.21.0 2.0.6 1.21.1 2.0.7 1.22.0 2.0.8 1.22.1 2.0.9 1.22.2 1.23.0 1.23.1 1.23.2 1.24.0 1.24.1 1.24.2 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.29.0 1.29.1 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.30.0 1.30.1 1.30.2 1.30.2-rc.1 1.30.3 1.30.4 1.30.4-rc.1 1.30.5 1.31.0 1.31.1 1.32.0 1.32.0-rc.1 1.33.0 1.33.1 1.33.2 1.34.0 1.35.0 1.35.1 1.36.0 1.36.1 1.36.2 1.36.3 1.37.0 1.37.1 1.37.2
advanced-ads / classes / ad.php
advanced-ads / classes Last commit date
ad-ajax.php 11 years ago ad-model.php 11 years ago ad-select.php 11 years ago 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 plugin.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 $id = absint( $id );
97 $this->id = $id;
98 $this->args = is_array( $args ) ? $args : array();
99
100 if ( ! empty($id) ) { $this->load( $id ); }
101
102 // dynamically add sanitize filters for condition types
103 $_types = array();
104 // -TODO use model
105 $advanced_ads_ad_conditions = Advanced_Ads::get_ad_conditions();
106 foreach ( $advanced_ads_ad_conditions as $_condition ) {
107 // add unique
108 $_types[$_condition['type']] = false;
109 }
110 // iterate types
111 foreach ( array_keys( $_types ) as $_type ) {
112 // -TODO might be faster to use __call() method or isset()-test class method array
113 $method_name = 'sanitize_condition_'. $_type;
114 if ( method_exists( $this, $method_name ) ) {
115 add_filter( 'advanced-ads-sanitize-condition-' . $_type, array($this, $method_name), 10, 1 );
116 } elseif ( function_exists( 'advads_sanitize_condition_' . $_type ) ) {
117 // check for public function to sanitize this
118 add_filter( 'advanced-ads-sanitize-condition-' . $_type, 'advads_sanitize_condition_' . $_type, 10, 1 );
119
120 }
121 }
122 }
123
124 /**
125 * load an ad object by id based on its ad type
126 *
127 * @since 1.0.0
128 */
129 private function load($id = 0){
130
131 $_data = get_post( $id );
132 if ( $_data == null ) { return false; }
133
134 // return, if not an ad
135 if ( $_data->post_type != Advanced_Ads::POST_TYPE_SLUG ) {
136 return false;
137 } else {
138 $this->is_ad = true;
139 }
140
141 $this->type = $this->options( 'type' );
142 $this->title = $_data->post_title;
143 /* load ad type object */
144 $types = Advanced_Ads::get_instance()->ad_types;
145 if ( isset($types[$this->type]) ){
146 $this->type_obj = $types[$this->type];
147 } else {
148 $this->type_obj = new Advads_Ad_Type_Abstract;
149 }
150 $this->width = $this->options( 'width' );
151 $this->height = $this->options( 'height' );
152 $this->conditions = $this->options( 'conditions' );
153 $this->description = $this->options( 'description' );
154 $this->output = $this->options( 'output' );
155 $this->status = $_data->post_status;
156 $this->wrapper = $this->load_wrapper_options();
157 $this->expiry_date = $this->options( 'expiry_date' );
158
159 // load content based on ad type
160 $this->content = $this->type_obj->load_content( $_data );
161
162 // set wrapper conditions
163 $this->wrapper = apply_filters( 'advanced-ads-set-wrapper', $this->wrapper, $this );
164 // add unique wrapper id, if options given
165 if ( is_array( $this->wrapper ) && $this->wrapper !== array() && ! isset($this->wrapper['id']) ){
166 // create unique id if not yet given
167 $this->wrapper['id'] = $this->create_wrapper_id();
168 }
169 }
170
171 /**
172 * get options from meta field and return specific field
173 *
174 * @param string $field post meta key to be returned
175 * @return mixed meta field content
176 * @since 1.0.0
177 * @todo check against default values
178 */
179 public function options($field = ''){
180 // retrieve options, if not given yet
181 if ( $this->options === array() ) {
182 // load arguments given on ad load
183 $this->options = $this->args;
184 // get_post_meta() may return false
185 $meta = get_post_meta( $this->id, self::$options_meta_field, true );
186 if ( $meta ){
187 $this->options = array_merge_recursive( $this->options, $meta );
188 }
189 }
190
191 // return specific option
192 if ( $field != '' ) {
193 if ( isset($this->options[$field]) ) {
194 return $this->options[$field]; }
195 } else { // return all options
196 if ( ! empty($this->options) ) {
197 return $this->options; }
198 }
199 }
200
201 /**
202 * set an option of the ad
203 *
204 * @since 1.1.0
205 * @param string $option name of the option
206 * @param mixed $value value of the option
207 */
208 public function set_option($option = '', $value = ''){
209 if ( $option == '' ) { return; }
210
211 // get current options
212 $options = $this->options();
213
214 // set options
215 $options[$option] = $value;
216
217 // save options
218 $this->options = $options;
219
220 }
221
222
223 /**
224 * return ad content for frontend output
225 *
226 * @since 1.0.0
227 * @return string $output ad output
228 */
229 public function output(){
230 if ( ! $this->is_ad ) { return ''; }
231
232 $output = $this->prepare_frontend_output();
233
234 // add the ad to the global output array
235 $advads = Advanced_Ads::get_instance();
236 $advads->current_ads[] = array('type' => 'ad', 'id' => $this->id, 'title' => $this->title);
237
238 // action when output is created
239 do_action( 'advanced-ads-output', $this, $output );
240
241 return $output;
242 }
243
244 /**
245 * check if the ad can be displayed in frontend due to its own conditions
246 *
247 * @since 1.0.0
248 * @return bool $can_display true if can be displayed in frontend
249 */
250 public function can_display(){
251
252 // don’t display ads that are not published or private for users not logged in
253 if ( $this->status !== 'publish' && ! ($this->status === 'private' && ! is_user_logged_in()) ){
254 return false;
255 }
256
257 if ( ! $this->can_display_by_conditions()
258 || ! $this->can_display_by_visitor()
259 || ! $this->can_display_by_expiry_date() ) {
260 return false;
261 }
262
263 // add own conditions to flag output as possible or not
264 $can_display = apply_filters( 'advanced-ads-can-display', true, $this );
265
266 return $can_display;
267 }
268
269 /**
270 * check display conditions
271 *
272 * @since 1.1.0 moved here from can_display()
273 * @return bool $can_display true if can be displayed in frontend
274 */
275 public function can_display_by_conditions(){
276 // use $wp_the_query to check the original query and not custom queries
277 global $post, $wp_the_query;
278
279 $query = $wp_the_query->get_queried_object();
280
281 if ( empty($this->options['conditions']) ||
282 ! is_array( $this->options['conditions'] ) ) { return true; }
283
284 // display ad if conditions are explicitely disabled
285 if ( isset($this->options['conditions']['enabled']) && ! $this->options['conditions']['enabled'] ) { return true; }
286
287 $conditions = $this->options['conditions'];
288 foreach ( $conditions as $_cond_key => $_cond_value ) {
289 switch ( $_cond_key ){
290 // check for post ids
291 case 'postids' :
292 if ( $wp_the_query->is_singular() && empty($_cond_value['all']) ){
293 // included posts
294 if ( ! empty($_cond_value['include']) ){
295 if ( is_string( $_cond_value['include'] ) ){
296 $post_ids = explode( ',', $_cond_value['include'] );
297 } else {
298 $post_ids = $_cond_value['include'];
299 }
300 if ( is_array( $post_ids )
301 && isset($post->ID)
302 && ! in_array( $post->ID, $post_ids ) ) {
303 return false; }
304 }
305 // excluded posts
306 if ( ! empty($_cond_value['exclude']) ){
307 if ( is_string( $_cond_value['exclude'] ) ){
308 $post_ids = explode( ',', $_cond_value['exclude'] );
309 } else {
310 $post_ids = $_cond_value['exclude'];
311 }
312 if ( is_array( $post_ids ) && isset($post->ID) && in_array( $post->ID, $post_ids ) ){
313 return false;
314 }
315 }
316 }
317 break;
318 // check for category ids
319 case 'categoryids' :
320 // included
321 if ( $wp_the_query->is_singular() && empty($_cond_value['all']) ){
322 // get all taxonomies of the post
323 $term_ids = $this->get_object_terms( $post->ID );
324
325 if ( ! empty($_cond_value['include']) ){
326 if ( is_string( $_cond_value['include'] ) ){
327 $category_ids = explode( ',', $_cond_value['include'] );
328 } else {
329 $category_ids = $_cond_value['include'];
330 }
331
332 // check if currently in a post (not post page, but also posts in loops)
333 if ( is_array( $category_ids ) && isset($post->ID)
334 && ! count( array_intersect( $category_ids, $term_ids ) ) ) { // is there any taxonomy the same?
335 return false;
336 }
337 }
338 // check for excluded category ids
339 if ( ! empty($_cond_value['exclude']) ){
340 if ( is_string( $_cond_value['exclude'] ) ){
341 $category_ids = explode( ',', $_cond_value['exclude'] );
342 } else {
343 $category_ids = $_cond_value['exclude'];
344 }
345 // check if currently in a post (not post page, but also posts in loops)
346 if ( is_array( $category_ids ) && isset($post->ID)
347 && count( array_intersect( $category_ids, $term_ids ) ) ) { // is there any taxonomy the same
348 // being only in one excluded category is enough to not display the ad
349 return false;
350 }
351 }
352 }
353 break;
354 // check for included category archive ids
355 // @link http://codex.wordpress.org/Conditional_Tags#A_Category_Page
356 case 'categoryarchiveids' :
357 if ( isset($query->term_id) && $wp_the_query->is_archive() && empty($_cond_value['all']) ){
358 if ( ! empty($_cond_value['include']) ){
359 if ( is_string( $_cond_value['include'] ) ){
360 $category_ids = explode( ',', $_cond_value['include'] );
361 } else {
362 $category_ids = $_cond_value['include'];
363 }
364 if ( is_array( $category_ids ) && ! in_array( $query->term_id, $category_ids ) ) {
365 return false; }
366 }
367 // check for excluded category archive ids
368 if ( ! empty($_cond_value['exclude']) ){
369 if ( is_string( $_cond_value['exclude'] ) ){
370 $category_ids = explode( ',', $_cond_value['exclude'] );
371 } else {
372 $category_ids = $_cond_value['exclude'];
373 }
374 if ( is_array( $category_ids ) && in_array( $query->term_id, $category_ids ) ) {
375 return false; }
376 }
377 }
378 break;
379 // check for included post types
380 case 'posttypes' :
381 // display everywhere, if include not set (= all is checked)
382 // TODO remove condition check for string; deprecated since 1.2.2
383 if ( empty($_cond_value['all']) ){
384 if ( ! empty($_cond_value['include']) ){
385 if ( is_string( $_cond_value['include'] ) ){
386 $post_types = explode( ',', $_cond_value['include'] );
387 } else {
388 $post_types = $_cond_value['include'];
389 }
390 // check if currently in a post (not post page, but also posts in loops)
391 if ( is_array( $post_types ) && ! in_array( get_post_type(), $post_types ) ) {
392 return false;
393 }
394 }
395 // check for excluded post types
396 // TODO remove in a later version, deprecated since 1.2.2
397 if ( ! empty($_cond_value['exclude']) ){
398 $post_types = explode( ',', $_cond_value['exclude'] );
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 }
405 break;
406 // check is_front_page
407 // @link https://codex.wordpress.org/Conditional_Tags#The_Front_Page
408 case 'is_front_page' :
409 if ( $_cond_value == 0 && $wp_the_query->is_front_page()) {
410 return false; }
411 break;
412 // check is_singular
413 // @link https://codex.wordpress.org/Conditional_Tags#A_Post_Type
414 case 'is_singular' :
415 if ( $_cond_value == 0 && $wp_the_query->is_singular() ) {
416 return false; }
417 break;
418 // check is_archive
419 // @link https://codex.wordpress.org/Conditional_Tags#Any_Archive_Page
420 case 'is_archive' :
421 if ( $_cond_value == 0 && $wp_the_query->is_archive() ) {
422 return false; }
423 break;
424 // check is_search
425 // @link https://codex.wordpress.org/Conditional_Tags#A_Search_Result_Page
426 case 'is_search' :
427 if ( $_cond_value == 0 && $wp_the_query->is_search() ) {
428 return false; }
429 break;
430 // check is_404
431 // @link https://codex.wordpress.org/Conditional_Tags#A_404_Not_Found_Page
432 case 'is_404' :
433 if ( $_cond_value == 0 && $wp_the_query->is_404() ) {
434 return false; }
435 break;
436 // check is_attachment
437 // @link https://codex.wordpress.org/Conditional_Tags#An_Attachment
438 case 'is_attachment' :
439 if ( $_cond_value == 0 && $wp_the_query->is_attachment() ) {
440 return false; }
441 break;
442 // check !is_main_query
443 // @link https://codex.wordpress.org/Function_Reference/is_main_query
444 case 'is_main_query' :
445 if ( $_cond_value == 0 && !is_main_query() ) {
446 return false; }
447 break;
448 }
449 }
450
451 return true;
452 }
453
454 /**
455 * get all terms of a specific post or post type
456 *
457 * @param int $post_id id of the post
458 * @return arr $out ids of terms this post belongs to
459 */
460 private function get_object_terms($post_id = 0){
461
462 $post_id = absint( $post_id );
463 if ( ! $post_id ) { return array(); }
464
465 // get post by post id
466 $post = get_post( $post_id );
467
468 // get post type by post
469 $post_type = $post->post_type;
470
471 // get post type taxonomies
472 $taxonomies = get_object_taxonomies( $post_type, 'objects' );
473
474 $term_ids = array();
475 foreach ( $taxonomies as $taxonomy_slug => $taxonomy ){
476
477 // get the terms related to post
478 $terms = get_the_terms( $post->ID, $taxonomy_slug );
479
480 if ( ! empty( $terms ) ) {
481 foreach ( $terms as $term ) {
482 $term_ids[] = $term->term_id;
483 }
484 }
485 }
486
487 return $term_ids;
488 }
489
490 /**
491 * check visitor conditions
492 *
493 * @since 1.1.0
494 * @return bool $can_display true if can be displayed in frontend based on visitor settings
495 */
496 public function can_display_by_visitor(){
497
498 if ( empty($this->options['visitor']) ||
499 ! is_array( $this->options['visitor'] ) ) { return true; }
500
501 $visitor_conditions = $this->options( 'visitor' );
502
503 // check mobile condition
504 if ( ! empty($visitor_conditions['mobile']) ){
505 switch ( $visitor_conditions['mobile'] ){
506 case 'only' :
507 if ( ! wp_is_mobile() ) { return false; }
508 break;
509 case 'no' :
510 if ( wp_is_mobile() ) { return false; }
511 break;
512 }
513 }
514
515 return true;
516 }
517
518 /**
519 * check expiry date
520 *
521 * @since 1.3.15
522 * @return bool $can_display true if can be displayed in frontend based on expiry date
523 */
524 public function can_display_by_expiry_date(){
525
526 if ( !isset($this->options['expiry_date']) ) { return true; }
527
528 $ad_expiry_date = absint($this->options( 'expiry_date' ));
529
530 if ( $ad_expiry_date == 0 ) { return true; }
531
532 // create blog specific timestamp
533 $blog_expiry_date = time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
534
535 // check blog time against current time
536 if ( $blog_expiry_date >= $ad_expiry_date ) { return false; }
537
538 return true;
539 }
540
541 /**
542 * save an ad to the database
543 * takes values from the current state
544 */
545 public function save(){
546 global $wpdb;
547
548 // remove slashes from content
549 $content = $this->prepare_content_to_save();
550
551 $where = array('ID' => $this->id);
552 $wpdb->update( $wpdb->posts, array( 'post_content' => $content ), $where );
553
554 // sanitize conditions
555 // see sanitize_conditions function for example on using this filter
556 $conditions = self::sanitize_conditions_on_save( $this->conditions );
557
558 // save other options to post meta field
559 $options = $this->options();
560
561 $options['type'] = $this->type;
562 $options['width'] = $this->width;
563 $options['height'] = $this->height;
564 $options['conditions'] = $conditions;
565 $options['expiry_date'] = $this->expiry_date;
566 $options['description'] = $this->description;
567
568 // filter to manipulate options or add more to be saved
569 $options = apply_filters( 'advanced-ads-save-options', $options, $this );
570
571 // update global settings
572 $this->update_general_ad_conditions( $conditions );
573
574 update_post_meta( $this->id, self::$options_meta_field, $options );
575
576 }
577
578 /**
579 * native filter for content field before being saved
580 *
581 * @return string $content ad content
582 * @since 1.0.0
583 */
584 public function prepare_content_to_save() {
585
586 $content = $this->content;
587
588 // load ad type specific parameter filter
589 $content = $this->type_obj->sanitize_content( $content );
590 // apply a custom filter by ad type
591 $content = apply_filters( 'advanced-ads-pre-ad-save-' . $this->type, $content );
592
593 return $content;
594 }
595
596 /**
597 * native filter for ad parameters before being saved
598 *
599 * @return arr $parameters sanitized parameters
600 */
601 public function prepare_parameters_to_save() {
602
603 $parameters = $this->parameters;
604 // load ad type specific parameter filter
605 $parameters = $this->type_obj->sanitize_parameters( $parameters );
606
607 // apply native WP filter for content fields
608 return $parameters;
609 }
610
611 /**
612 * prepare ads output
613 *
614 * @param string $content ad content
615 * @param obj $ad ad object
616 */
617 public function prepare_frontend_output(){
618
619 // load ad type specific content filter
620 $output = $this->type_obj->prepare_output( $this );
621
622 // filter to manipulate the output before the wrapper is added
623 $output = apply_filters( 'advanced-ads-output-inside-wrapper', $output, $this );
624
625 // build wrapper around the ad
626 $output = $this->add_wrapper( $output );
627
628 // add a clearfix, if set
629 if ( isset($this->output['clearfix']) && $this->output['clearfix'] ){
630 $output .= '<br style="clear: both; display: block; float: none;"/>';
631 }
632
633 // apply a custom filter by ad type
634 $output = apply_filters( 'advanced-ads-ad-output', $output, $this );
635
636 return $output;
637 }
638
639 /**
640 * sanitize ad display conditions when saving the ad
641 *
642 * @param array $conditions conditions array send via the dashboard form for an ad
643 * @return array with sanitized conditions
644 * @since 1.0.0
645 */
646 public function sanitize_conditions_on_save($conditions = array()){
647
648 global $advanced_ads_ad_conditions;
649
650 if ( ! is_array( $conditions ) || $conditions == array() ) { return array(); }
651
652 foreach ( $conditions as $_key => $_condition ){
653 if ( $_key == 'postids' ){
654 // sanitize single post conditions
655 if ( empty($_condition['ids']) ){ // remove, if empty
656 $_condition['include'] = array();
657 $_condition['exclude'] = array();
658 } else {
659 switch ( $_condition['method'] ){
660 case 'include' :
661 $_condition['include'] = $_condition['ids'];
662 $_condition['exclude'] = array();
663 break;
664 case 'exclude' :
665 $_condition['include'] = array();
666 $_condition['exclude'] = $_condition['ids'];
667 break;
668 }
669 }
670 } else {
671 if ( ! is_array( $_condition ) ) {
672 $_condition = trim( $_condition ); }
673 if ( $_condition == '' ) {
674 $conditions[$_key] = $_condition;
675 continue;
676 }
677 }
678 $type = ! empty($advanced_ads_ad_conditions[$_key]['type']) ? $advanced_ads_ad_conditions[$_key]['type'] : 0;
679 if ( empty($type) ) { continue; }
680
681 // dynamically apply filters for each condition used
682 $conditions[$_key] = apply_filters( 'advanced-ads-sanitize-condition-' . $type, $_condition );
683 }
684
685 return $conditions;
686 }
687
688 /**
689 * sanitize id input field(s) for pattern /1,2,3,4/
690 *
691 * @pararm array/string $cond input string/array
692 * @return array/string $cond sanitized string/array
693 */
694 public static function sanitize_condition_idfield($cond = ''){
695 // strip anything that is not comma or number
696
697 if ( is_array( $cond ) ){
698 foreach ( $cond as $_key => $_cond ){
699 $cond[$_key] = preg_replace( '#[^0-9,]#', '', $_cond );
700 }
701 } else {
702 $cond = preg_replace( '#[^0-9,]#', '', $cond );
703 }
704 return $cond;
705 }
706
707 /**
708 * sanitize radio input field
709 *
710 * @pararm string $string input string
711 * @return string $string sanitized string
712 */
713 public static function sanitize_condition_radio($string = ''){
714 // only allow 0, 1 and empty
715 return $string = preg_replace( '#[^01]#', '', $string );
716 }
717
718 /**
719 * sanitize comma seperated text input field
720 *
721 * @pararm array/string $cond input string/array
722 * @return array/string $cond sanitized string/array
723 */
724 public static function sanitize_condition_textvalues($cond = ''){
725 // strip anything that is not comma, alphanumeric, minus and underscore
726 if ( is_array( $cond ) ){
727 foreach ( $cond as $_key => $_cond ){
728 $cond[$_key] = preg_replace( '#[^0-9,A-Za-z-_]#', '', $_cond );
729 }
730 } else {
731 $cond = preg_replace( '#[^0-9,A-Za-z-_]#', '', $cond );
732 }
733 return $cond;
734 }
735
736 /**
737 * update general ad conditions with conditions for the current ad
738 *
739 * @param array $conditions ad display conditions from ad form
740 * @since 1.0.0
741 * @todo make those condition checks extendible
742 */
743 public function update_general_ad_conditions($conditions){
744 global $advanced_ads_ad_conditions;
745
746 $plugin = Advanced_Ads::get_instance();
747 $ads_by_conditions = $plugin->get_ads_by_conditions_array();
748
749 // remove current ad from general ad condition array
750 $ads_by_conditions = $this->remove_ad_from_general_ad_conditions( $this->id, $ads_by_conditions );
751
752 // only run conditions if ad is publically visible
753 if ( $this->status == 'publish' ) {
754 // iterate through the ads display condition
755 foreach ( $conditions as $_condition_key => $_condition ){
756 if ( ! isset($advanced_ads_ad_conditions[$_condition_key]['type']) ) {
757 $plugin->log( sprintf( __( 'A "%s" display condition does not exist', ADVADS_SLUG ), $_condition_key ) );
758 return;
759 }
760 // add conditions based on type
761 switch ( $advanced_ads_ad_conditions[$_condition_key]['type'] ){
762 case 'idfield' :
763 if ( isset($_condition['include']) && $_condition['include'] != '' ){
764 if ( is_array( $_condition['include'] ) ){
765 $_ids = $_condition['include'];
766 } else {
767 $_ids = explode( ',', $_condition['include'] );
768 }
769 if ( is_array( $_ids ) ) { foreach ( $_ids as $_id ){
770 $ads_by_conditions[$_condition_key][$_id]['include'][] = $this->id;
771 }
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 }
785 break;
786 case 'textvalues' :
787 if ( isset($_condition['include']) && $_condition['include'] != '' ){
788 if ( is_array( $_condition['include'] ) ){
789 $_ids = $_condition['include'];
790 } else {
791 $_ids = explode( ',', $_condition['include'] );
792 }
793 if ( is_array( $_ids ) ) { foreach ( $_ids as $_id ){
794 $ads_by_conditions[$_condition_key][$_id]['include'][] = $this->id;
795 }
796 }
797 }
798 if ( isset($_condition['exclude']) && $_condition['exclude'] != '' ){
799 if ( is_array( $_condition['exclude'] ) ){
800 $_ids = $_condition['exclude'];
801 } else {
802 $_ids = explode( ',', $_condition['exclude'] );
803 }
804 if ( is_array( $_ids ) ) { foreach ( $_ids as $_id ){
805 $ads_by_conditions[$_condition_key][$_id]['exclude'][] = $this->id;
806 }
807 }
808 }
809 break;
810 case 'radio' :
811 if ( $_condition == 1 ) {
812 $ads_by_conditions[$_condition_key]['include'][] = $this->id; }
813 elseif ($_condition == 0)
814 $ads_by_conditions[$_condition_key]['exclude'][] = $this->id;
815 break;
816 case 'other' :
817 $ads_by_conditions[$_condition_key][$this->id] = $_condition;
818 } // switch
819 } // forearch
820 }
821 update_option( 'advads-ads-by-conditions', $ads_by_conditions );
822 }
823
824 /**
825 * remove ad id from ad conditions array
826 *
827 * @param int $ad_id id of the ad (=post id)
828 * @param arr $conditions array with the general, global ad conditions
829 * @since 1.0.0
830 */
831 static function remove_ad_from_general_ad_conditions($ad_id = 0, $conditions = array()){
832 $ad_id = absint( $ad_id );
833 if ( empty($ad_id) || ! is_array( $conditions ) || $conditions == array() ) { return; }
834
835 foreach ( $conditions as $_key => $_cond ){
836 // remove single elements
837 if ( ! is_array( $_cond ) && $_cond == $ad_id ){
838 unset($conditions[$_key]);
839 } elseif ( empty($_cond) ){
840 unset($conditions[$_key]);
841 }
842 // check recursively
843 elseif ( is_array( $_cond ) ){
844 $new_cond = self::remove_ad_from_general_ad_conditions( $ad_id, $_cond );
845
846 if ( $new_cond == array() || $new_cond == '' ){
847 // remove empty arrays
848 unset($conditions[$_key]);
849 } else {
850 $conditions[$_key] = $new_cond;
851 }
852 }
853 }
854
855 return $conditions;
856 }
857
858 /**
859 * load wrapper options set with the ad
860 *
861 * @since 1.3
862 * @return arr $wrapper options array ready to be use in add_wrapper() function
863 */
864 protected function load_wrapper_options(){
865 $wrapper = array();
866
867 // print_r($this->output);
868
869 if ( ! empty($this->output['position']) ) {
870 switch ( $this->output['position'] ) {
871 case 'left' :
872 $wrapper['style']['float'] = 'left';
873 break;
874 case 'right' :
875 $wrapper['style']['float'] = 'right';
876 break;
877 case 'center' :
878 $wrapper['style']['text-align'] = 'center';
879 break;
880 case 'clearfix' :
881 $wrapper['style']['clear'] = 'both';
882 break;
883 }
884 }
885
886 if ( ! empty($this->output['class']) && is_array( $this->output['class'] ) ) {
887 $wrapper['class'] = $this->output['class'];
888 }
889
890 if ( ! empty($this->output['margin']['top']) ) {
891 $wrapper['style']['margin-top'] = intval( $this->output['margin']['top'] ) . 'px';
892 }
893 if ( ! empty($this->output['margin']['right']) ) {
894 $wrapper['style']['margin-right'] = intval( $this->output['margin']['right'] ) . 'px';
895 }
896 if ( ! empty($this->output['margin']['bottom']) ) {
897 $wrapper['style']['margin-bottom'] = intval( $this->output['margin']['bottom'] ) . 'px';
898 }
899 if ( ! empty($this->output['margin']['left']) ) {
900 $wrapper['style']['margin-left'] = intval( $this->output['margin']['left'] ) . 'px';
901 }
902
903 return $wrapper;
904 }
905
906 /**
907 * add a wrapper arount the ad content if wrapper information are given
908 *
909 * @since 1.1.4
910 * @param str $ad_content content of the ad
911 * @return str $wrapper ad within the wrapper
912 */
913 protected function add_wrapper($ad_content = ''){
914
915 $wrapper_options = apply_filters( 'advanced-ads-output-wrapper-options', $this->wrapper, $this );
916
917 if ( $wrapper_options == array() || ! is_array( $wrapper_options ) || empty($wrapper_options) ) { return $ad_content; }
918
919 $wrapper = $ad_content;
920
921 // create unique id if not yet given
922 if ( empty($wrapper_options['id']) ){
923 $wrapper_options['id'] = $this->create_wrapper_id();
924 }
925
926 // build the box
927 $wrapper = '<div';
928 foreach ( $wrapper_options as $_html_attr => $_values ){
929 if ( $_html_attr == 'style' ){
930 $_style_values_string = '';
931 foreach ( $_values as $_style_attr => $_style_values ){
932 if ( is_array( $_style_values ) ) {
933 $_style_values_string .= $_style_attr . ': ' .implode( ' ', $_style_values ). '; '; }
934 else {
935 $_style_values_string .= $_style_attr . ': ' .$_style_values. '; '; }
936 }
937 $wrapper .= " style=\"$_style_values_string\"";
938 } else {
939 if ( is_array( $_values ) ) {
940 $_values_string = implode( ' ', $_values ); }
941 else {
942 $_values_string = sanitize_title( $_values ); }
943 $wrapper .= " $_html_attr=\"$_values_string\"";
944 }
945 }
946 $wrapper .= '>';
947 $wrapper .= apply_filters( 'advanced-ads-output-wrapper-before-content', '', $this );
948 $wrapper .= $ad_content;
949 $wrapper .= apply_filters( 'advanced-ads-output-wrapper-after-content', '', $this );
950 $wrapper .= '</div>';
951
952 return $wrapper;
953 }
954
955 /**
956 * create a random wrapper id
957 *
958 * @since 1.1.4
959 * @return string $id random id string
960 */
961 private function create_wrapper_id(){
962 return 'advads-' . mt_rand();
963 }
964 }
965