PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 1.0.3
Advanced Ads – Ad Manager & AdSense v1.0.3
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_type_abstract.php 12 years ago ad_type_content.php 12 years ago ad_type_plain.php 12 years ago
ad.php
561 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 protected $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 * object of current ad type
38 */
39 protected $type_obj;
40
41 /**
42 * content of the ad
43 *
44 * only needed for ad types using the post content field
45 */
46 public $content = '';
47
48 /**
49 * conditions of the ad display
50 */
51 public $conditions = array();
52
53 /**
54 * status of the ad (e.g. publish, pending)
55 */
56 public $status = array();
57
58 /**
59 * array with meta field options aka parameters
60 */
61 protected $options = array();
62
63 /**
64 * name of the meta field to save options to
65 */
66 static $options_meta_field = 'advanced_ads_ad_options';
67
68 /**
69 * init ad object
70 *
71 * @param int $id id of the ad (= post id)
72 */
73 public function __construct($id) {
74 global $advanced_ads_ad_conditions;
75 $id = absint($id);
76 $this->id = $id;
77
78 if(!empty($id)) $this->load($id);
79
80 // dynamically add sanitize filters for condition types
81 $_types = array();
82 foreach($advanced_ads_ad_conditions as $_condition) {
83 $_types[] = $_condition['type'];
84 }
85 $_types = array_unique($_types);
86 foreach($_types as $_type) {
87 $method_name = 'sanitize_condition_'. $_type;
88 if(method_exists($this, $method_name)) {
89 add_filter('advanced-ads-sanitize-condition-' . $_type, array($this, $method_name), 10, 1);
90 } elseif(function_exists('advads_sanitize_condition_' . $_type)) {
91 // check for public function to sanitize this
92 add_filter('advanced-ads-sanitize-condition-' . $_type, 'advads_sanitize_condition_' . $_type, 10, 1);
93
94 }
95 }
96 }
97
98 /**
99 * load an ad object by id based on its ad type
100 *
101 * @since 1.0.0
102 */
103 private function load($id = 0){
104
105 $_data = get_post($id);
106 if($_data == null) return false;
107
108 // return, if not an ad
109 if($_data->post_type != Advanced_Ads::POST_TYPE_SLUG) {
110 return false;
111 } else {
112 $this->is_ad = true;
113 }
114
115 $this->type = $this->options('type');
116 /* load ad type object */
117 $types = Advanced_Ads::get_instance()->ad_types;
118 if(isset($types[$this->type])){
119 $this->type_obj = $types[$this->type];
120 } else {
121 $this->type_obj = new Advads_Ad_Type_Abstract;
122 }
123
124 $this->conditions = $this->options('conditions');
125 $this->status = $_data->post_status;
126
127 // load content based on ad type
128 $this->content = $this->type_obj->load_content($_data);
129 }
130
131 /**
132 * get options from meta field and return specific field
133 *
134 * @param string $field post meta key to be returned
135 * @return mixed meta field content
136 * @since 1.0.0
137 * @todo check against default values
138 */
139 public function options($field = ''){
140 // retrieve options, if not given yet
141 if($this->options == array()) {
142 $this->options = get_post_meta($this->id, self::$options_meta_field, true);
143 }
144
145 // return specific option
146 if($field != '') {
147 if(!empty($this->options[$field]))
148 return $this->options[$field];
149 } else { // return all options
150 if(!empty($this->options))
151 return $this->options;
152 }
153 }
154
155 /**
156 * return ad content for frontend output
157 */
158 public function output(){
159 if(!$this->is_ad) return '';
160
161 $output = $this->prepare_frontend_output();
162 return $output;
163 }
164
165 /**
166 * check if the ad can be displayed in frontend due to its conditions
167 *
168 * @return bool $can_display true if can be displayed in frontend
169 */
170 public function can_display(){
171 global $post;
172
173 if(empty($this->options['conditions']) ||
174 !is_array($this->options['conditions'])) return true;
175
176 $conditions = $this->options['conditions'];
177 foreach($conditions as $_cond_key => $_cond_value) {
178 switch($_cond_key){
179 // check for post ids
180 case 'postids' :
181 // included posts
182 if(!empty($_cond_value['include'])){
183 $post_ids = explode(',', $_cond_value['include']);
184 if(is_array($post_ids)
185 && isset($post->ID)
186 && !in_array($post->ID, $post_ids))
187 return false;
188 }
189 // excluded posts
190 if(!empty($_cond_value['exclude'])){
191 $post_ids = explode(',', $_cond_value['exclude']);
192 if(is_array($post_ids)
193 && isset($post->ID)
194 && in_array($post->ID, $post_ids))
195 return false;
196 }
197 break;
198 // check for category ids
199 case 'categoryids' :
200 // included
201 if(!empty($_cond_value['include'])){
202 $category_ids = explode(',', $_cond_value['include']);
203 // check if currently in a post (not post page, but also posts in loops)
204 if(is_array($category_ids) && isset($post->ID)
205 && !in_category($category_ids, $post)) {
206 return false;
207 }
208 }
209 // check for excluded category ids
210 if(!empty($_cond_value['exclude'])){
211 $category_ids = explode(',', $_cond_value['exclude']);
212 // check if currently in a post (not post page, but also posts in loops)
213 if(is_array($category_ids) && isset($post->ID)
214 && in_category($category_ids, $post) ) {
215 // being only in one excluded category is enough to not display the ad
216 return false;
217 }
218 }
219 break;
220 // check for included category archive ids
221 // @link http://codex.wordpress.org/Conditional_Tags#A_Category_Page
222 case 'categoryarchiveids' :
223 if(!empty($_cond_value['include'])){
224 $category_ids = explode(',', $_cond_value['include']);
225 if(is_array($category_ids) && !is_category($category_ids))
226 return false;
227 }
228 // check for excluded category archive ids
229 if(!empty($_cond_value['exclude'])){
230 $category_ids = explode(',', $_cond_value['exclude']);
231 if(is_array($category_ids) && is_category($category_ids))
232 return false;
233 }
234 break;
235 // check for included post types
236 case 'posttypes' :
237 if(!empty($_cond_value['include'])){
238 $post_types = explode(',', $_cond_value['include']);
239 // check if currently in a post (not post page, but also posts in loops)
240 if(is_array($post_types) && !in_array(get_post_type(), $post_types)) {
241 return false;
242 }
243 }
244 // check for excluded post types
245 if(!empty($_cond_value['include'])){
246 $post_types = explode(',', $_cond_value['exclude']);
247 // check if currently in a post (not post page, but also posts in loops)
248 if(is_array($post_types) && in_array(get_post_type(), $post_types)) {
249 return false;
250 }
251 }
252 break;
253 // check is_front_page
254 // @link https://codex.wordpress.org/Conditional_Tags#The_Front_Page
255 case 'is_front_page' :
256 if(($_cond_value == 1 && !is_front_page())
257 || ($_cond_value == 0 && is_front_page()))
258 return false;
259 break;
260 // check is_singular
261 // @link https://codex.wordpress.org/Conditional_Tags#A_Post_Type
262 case 'is_singular' :
263 if(($_cond_value == 1 && !is_singular())
264 || ($_cond_value == 0 && is_singular()))
265 return false;
266 break;
267 // check is_archive
268 // @link https://codex.wordpress.org/Conditional_Tags#Any_Archive_Page
269 case 'is_archive' :
270 if(($_cond_value == 1 && !is_archive())
271 || ($_cond_value == 0 && is_archive()))
272 return false;
273 break;
274 // check is_search
275 // @link https://codex.wordpress.org/Conditional_Tags#A_Search_Result_Page
276 case 'is_search' :
277 if(($_cond_value == 1 && !is_search())
278 || ($_cond_value == 0 && is_search()))
279 return false;
280 break;
281 // check is_404
282 // @link https://codex.wordpress.org/Conditional_Tags#A_404_Not_Found_Page
283 case 'is_404' :
284 if(($_cond_value == 1 && !is_404())
285 || ($_cond_value == 0 && is_404()))
286 return false;
287 break;
288 // check is_attachment
289 // @link https://codex.wordpress.org/Conditional_Tags#An_Attachment
290 case 'is_attachment' :
291 if(($_cond_value == 1 && !is_attachment())
292 || ($_cond_value == 0 && is_attachment()))
293 return false;
294 break;
295 }
296 }
297
298 return true;
299 }
300
301 /**
302 * save an ad to the database
303 * takes values from the current state
304 */
305 public function save(){
306 global $wpdb;
307
308 // remove slashes from content
309 $content = $this->prepare_content_to_save();
310
311 $where = array('ID' => $this->id);
312 $wpdb->update( $wpdb->posts, array( 'post_content' => $content ), $where );
313
314 // sanitize conditions
315 // see sanitize_conditions function for example on using this filter
316 $conditions = self::sanitize_conditions_on_save($this->conditions);
317
318 // save other options to post meta field
319 $options = array(
320 'type' => $this->type,
321 'conditions' => $conditions,
322 );
323
324 // filter to manipulate options or add more to be saved
325 $options = apply_filters('advanced-ads-save-options', $options, $this);
326
327 $this->update_general_ad_conditions($conditions);
328
329 update_post_meta($this->id, self::$options_meta_field, $options);
330
331 }
332
333 /**
334 * native filter for content field before being saved
335 *
336 * @return string $content ad content
337 * @since 1.0.0
338 */
339 public function prepare_content_to_save() {
340
341 $content = $this->content;
342
343 // load ad type specific parameter filter
344 $content = $this->type_obj->sanitize_content($content);
345 // apply a custom filter by ad type
346 $content = apply_filters('advanced-ads-pre-ad-save-' . $this->type, $content);
347
348 return $content;
349 }
350
351 /**
352 * native filter for ad parameters before being saved
353 *
354 * @return arr $parameters sanitized parameters
355 */
356 public function prepare_parameters_to_save() {
357
358 $parameters = $this->parameters;
359 // load ad type specific parameter filter
360 $parameters = $this->type_obj->sanitize_parameters($parameters);
361
362 // apply native WP filter for content fields
363 return $parameters;
364 }
365
366 /**
367 * prepare ads output
368 *
369 * @param string $content ad content
370 * @param obj $ad ad object
371 */
372 public function prepare_frontend_output(){
373
374 // load ad type specific content filter
375 $output = $this->type_obj->prepare_output($this);
376
377 // apply a custom filter by ad type
378 $output = apply_filters('advanced-ads-ad-output', $output, $this);
379
380 return $output;
381 }
382
383 /**
384 * sanitize ad display conditions when saving the ad
385 *
386 * @param array $conditions conditions array send via the dashboard form for an ad
387 * @return array with sanitized conditions
388 * @since 1.0.0
389 */
390 public function sanitize_conditions_on_save($conditions = array()){
391
392 global $advanced_ads_ad_conditions;
393
394 if(!is_array($conditions) || $conditions == array()) return array();
395
396 foreach($conditions as $_key => $_condition){
397 if(!is_array($_condition))
398 $_condition = trim($_condition);
399 if($_condition == '') {
400 $conditions[$_key] = $_condition;
401 continue;
402 }
403 $type = $advanced_ads_ad_conditions[$_key]['type'];
404 if(empty($type)) continue;
405
406 // dynamically apply filters for each condition used
407 $conditions[$_key] = apply_filters('advanced-ads-sanitize-condition-' . $type, $_condition);
408 }
409
410 return $conditions;
411 }
412
413 /**
414 * sanitize id input field(s) for pattern /1,2,3,4/
415 *
416 * @pararm array/string $cond input string/array
417 * @return array/string $cond sanitized string/array
418 */
419 public static function sanitize_condition_idfield($cond = ''){
420 // strip anything that is not comma or number
421 if(is_array($cond)){
422 foreach($cond as $_key => $_cond){
423 $cond[$_key] = preg_replace('#[^0-9,]#', '', $_cond);
424 }
425 } else {
426 $cond = preg_replace('#[^0-9,]#', '', $cond);
427 }
428 return $cond;
429 }
430
431 /**
432 * sanitize radio input field
433 *
434 * @pararm string $string input string
435 * @return string $string sanitized string
436 */
437 public static function sanitize_condition_radio($string = ''){
438 // only allow 0, 1 and empty
439 return $string = preg_replace('#[^01]#', '', $string);
440 }
441
442 /**
443 * sanitize comma seperated text input field
444 *
445 * @pararm array/string $cond input string/array
446 * @return array/string $cond sanitized string/array
447 */
448 public static function sanitize_condition_textvalues($cond = ''){
449 // strip anything that is not comma, alphanumeric, minus and underscore
450 if(is_array($cond)){
451 foreach($cond as $_key => $_cond){
452 $cond[$_key] = preg_replace('#[^0-9,A-Za-z-_]#', '', $_cond);
453 }
454 } else {
455 $cond = preg_replace('#[^0-9,A-Za-z-_]#', '', $cond);
456 }
457 return $cond;
458 }
459
460 /**
461 * update general ad conditions with conditions for the current ad
462 *
463 * @param array $conditions ad display conditions from ad form
464 * @since 1.0.0
465 * @todo make those condition checks extendible
466 */
467 public function update_general_ad_conditions($conditions){
468 global $advanced_ads_ad_conditions;
469
470 $plugin = Advanced_Ads::get_instance();
471 $ads_by_conditions = $plugin->get_ads_by_conditions_array();
472 $plugin_slug = $plugin->get_plugin_slug();
473
474 // remove current ad from general ad condition array
475 $ads_by_conditions = $this->remove_ad_from_general_ad_conditions($this->id, $ads_by_conditions);
476
477 // only run conditions if ad is publically visible
478 if($this->status == 'publish')
479 // iterate through the ads display condition
480 foreach($conditions as $_condition_key => $_condition){
481 if(!isset($advanced_ads_ad_conditions[$_condition_key]['type'])) {
482 $plugin->log(sprintf(__('A "%s" display condition does not exist', $plugin_slug), $_condition_key));
483 return;
484 }
485 // add conditions based on type
486 switch($advanced_ads_ad_conditions[$_condition_key]['type']){
487 case 'idfield' :
488 if(isset($_condition['include']) && $_condition['include'] != ''){
489 $_ids = explode(',', $_condition['include']);
490 if(is_array($_ids)) foreach($_ids as $_id){
491 $ads_by_conditions[$_condition_key][$_id]['include'][] = $this->id;
492 }
493 }
494 if(isset($_condition['exclude']) && $_condition['exclude'] != ''){
495 $_ids = explode(',', $_condition['exclude']);
496 if(is_array($_ids)) foreach($_ids as $_id){
497 $ads_by_conditions[$_condition_key][$_id]['exclude'][] = $this->id;
498 }
499 }
500 break;
501 case 'textvalues' :
502 if(isset($_condition['include']) && $_condition['include'] != ''){
503 $_ids = explode(',', $_condition['include']);
504 if(is_array($_ids)) foreach($_ids as $_id){
505 $ads_by_conditions[$_condition_key][$_id]['include'][] = $this->id;
506 }
507 }
508 if(isset($_condition['exclude']) && $_condition['exclude'] != ''){
509 $_ids = explode(',', $_condition['exclude']);
510 if(is_array($_ids)) foreach($_ids as $_id){
511 $ads_by_conditions[$_condition_key][$_id]['exclude'][] = $this->id;
512 }
513 }
514 break;
515 case 'radio' :
516 if($_condition == 1)
517 $ads_by_conditions[$_condition_key]['include'][] = $this->id;
518 elseif($_condition == 0)
519 $ads_by_conditions[$_condition_key]['exclude'][] = $this->id;
520 break;
521 } // switch
522 } // forearch
523
524 update_option('advads-ads-by-conditions', $ads_by_conditions);
525 }
526
527 /**
528 * remove ad id from ad conditions array
529 *
530 * @param int $ad_id id of the ad (=post id)
531 * @param arr $conditions array with the general, global ad conditions
532 * @since 1.0.0
533 */
534 static function remove_ad_from_general_ad_conditions($ad_id = 0, $conditions = array()){
535 $ad_id = absint($ad_id);
536 if(empty($ad_id) || !is_array($conditions) || $conditions == array()) return;
537
538 foreach($conditions as $_key => $_cond){
539 // remove single elements
540 if(!is_array($_cond) && $_cond == $ad_id){
541 unset($conditions[$_key]);
542 } elseif(empty($_cond)){
543 unset($conditions[$_key]);
544 }
545 // check recursively
546 elseif(is_array($_cond)){
547 $new_cond = self::remove_ad_from_general_ad_conditions($ad_id, $_cond);
548
549 if($new_cond == array() || $new_cond == ''){
550 // remove empty arrays
551 unset($conditions[$_key]);
552 } else {
553 $conditions[$_key] = $new_cond;
554 }
555 }
556 }
557
558 return $conditions;
559 }
560
561 }