PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 1.32.0
Advanced Ads – Ad Manager & AdSense v1.32.0
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 / plugin.php
advanced-ads / classes Last commit date
EDD_SL_Plugin_Updater.php 4 years ago ad-ajax.php 5 years ago ad-debug.php 6 years ago ad-expiration.php 4 years ago ad-health-notices.php 4 years ago ad-model.php 5 years ago ad-select.php 9 years ago ad.php 4 years ago ad_ajax_callbacks.php 5 years ago ad_group.php 4 years ago ad_placements.php 4 years ago ad_type_abstract.php 5 years ago ad_type_content.php 5 years ago ad_type_dummy.php 5 years ago ad_type_group.php 5 years ago ad_type_image.php 5 years ago ad_type_plain.php 4 years ago checks.php 4 years ago compatibility.php 4 years ago display-conditions.php 4 years ago filesystem.php 8 years ago frontend-notices.php 6 years ago frontend_checks.php 4 years ago in-content-injector.php 4 years ago inline-css.php 4 years ago plugin.php 4 years ago upgrades.php 6 years ago utils.php 4 years ago visitor-conditions.php 4 years ago widget.php 4 years ago
plugin.php
909 lines
1 <?php
2
3 /**
4 * WordPress integration and definitions:
5 *
6 * - posttypes
7 * - taxonomy
8 * - textdomain
9 */
10 class Advanced_Ads_Plugin {
11 /**
12 * Instance of Advanced_Ads_Plugin
13 *
14 * @var object Advanced_Ads_Plugin
15 */
16 protected static $instance;
17
18 /**
19 * Instance of Advanced_Ads_Model
20 *
21 * @var object Advanced_Ads_Model
22 */
23 protected $model;
24
25 /**
26 * Plugin options
27 *
28 * @var array $options
29 */
30 protected $options;
31
32 /**
33 * Interal plugin options – set by the plugin
34 *
35 * @var array $internal_options
36 */
37 protected $internal_options;
38
39 /**
40 * Default prefix of selectors (id, class) in the frontend
41 * can be changed by options
42 *
43 * @var Advanced_Ads_Plugin
44 */
45 const DEFAULT_FRONTEND_PREFIX = 'advads-';
46
47 /**
48 * Frontend prefix for classes and IDs
49 *
50 * @var string $frontend_prefix
51 */
52 private $frontend_prefix;
53
54 /**
55 * Advanced_Ads_Plugin constructor.
56 */
57 private function __construct() {
58 register_activation_hook( ADVADS_BASE, array( $this, 'activate' ) );
59 register_deactivation_hook( ADVADS_BASE, array( $this, 'deactivate' ) );
60 register_uninstall_hook( ADVADS_BASE, array( 'Advanced_Ads_Plugin', 'uninstall' ) );
61
62 add_action( 'plugins_loaded', array( $this, 'wp_plugins_loaded' ), 20 );
63 add_action( 'init', array( $this, 'run_upgrades' ), 9 );
64 }
65
66 /**
67 * Get instance of Advanced_Ads_Plugin
68 *
69 * @return Advanced_Ads_Plugin
70 */
71 public static function get_instance() {
72 // If the single instance hasn't been set, set it now.
73 if ( null === self::$instance ) {
74 self::$instance = new self();
75 }
76
77 return self::$instance;
78 }
79
80 /**
81 * Get instance of Advanced_Ads_Model
82 *
83 * @param Advanced_Ads_Model $model model to access data.
84 */
85 public function set_model( Advanced_Ads_Model $model ) {
86 $this->model = $model;
87 }
88
89 /**
90 * Execute various hooks after WordPress and all plugins are available
91 */
92 public function wp_plugins_loaded() {
93 // Load plugin text domain.
94 $this->load_plugin_textdomain();
95
96 // activate plugin when new blog is added on multisites // -TODO this is admin-only.
97 add_action( 'wpmu_new_blog', array( $this, 'activate_new_site' ) );
98
99 // Load public-facing style sheet and JavaScript.
100 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles' ) );
101 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
102 add_action( 'wp_head', array( $this, 'print_head_scripts' ), 7 );
103 // higher priority to make sure other scripts are printed before.
104 add_action( 'wp_footer', array( $this, 'print_footer_scripts' ), 100 );
105
106 // add short codes.
107 add_shortcode( 'the_ad', array( $this, 'shortcode_display_ad' ) );
108 add_shortcode( 'the_ad_group', array( $this, 'shortcode_display_ad_group' ) );
109 add_shortcode( 'the_ad_placement', array( $this, 'shortcode_display_ad_placement' ) );
110
111 // remove default ad group menu item // -TODO only for admin.
112 add_action( 'admin_menu', array( $this, 'remove_taxonomy_menu_item' ) );
113 // load widgets.
114 add_action( 'widgets_init', array( $this, 'widget_init' ) );
115
116 // Call action hooks for ad status changes.
117 add_action( 'transition_post_status', array( $this, 'transition_ad_status' ), 10, 3 );
118
119 // register expired post status.
120 Advanced_Ads_Ad_Expiration::register_post_status();
121
122 // if expired ad gets untrashed, revert it to expired status (instead of draft).
123 add_filter( 'wp_untrash_post_status', array( Advanced_Ads_Ad_Expiration::class, 'wp_untrash_post_status' ), 10, 3 );
124
125 // load display conditions.
126 Advanced_Ads_Display_Conditions::get_instance();
127 new Advanced_Ads_Frontend_Checks();
128 new Advanced_Ads_Compatibility();
129 Advanced_Ads_Ad_Health_Notices::get_instance(); // load to fetch notices.
130 }
131
132 /**
133 * Run upgrades.
134 *
135 * Compatibility with the Piklist plugin that has a function hooked to `posts_where` that access $GLOBALS['wp_query'].
136 * Since `Advanced_Ads_Upgrades` applies `posts_where`: (`Advanced_Ads_Admin_Notices::get_instance()` >
137 * `Advanced_Ads::get_number_of_ads()` > new WP_Query > ... 'posts_where') this function is hooked to `init` so that `$GLOBALS['wp_query']` is instantiated.
138 */
139 public function run_upgrades() {
140 /**
141 * Run upgrades, if this is a new version or version does not exist.
142 */
143 $internal_options = $this->internal_options();
144
145 if ( ! defined( 'DOING_AJAX' ) && ( ! isset( $internal_options['version'] ) || version_compare( $internal_options['version'], ADVADS_VERSION, '<' ) ) ) {
146 new Advanced_Ads_Upgrades();
147 }
148 }
149
150 /**
151 * Register and enqueue public-facing style sheet.
152 */
153 public function enqueue_styles() {
154 // wp_enqueue_style( $this->get_plugin_slug() . '-plugin-styles', plugins_url('assets/css/public.css', __FILE__), array(), ADVADS_VERSION);
155 }
156
157 /**
158 * Return the plugin slug.
159 *
160 * @return string plugin slug variable.
161 */
162 public function get_plugin_slug() {
163 return ADVADS_SLUG;
164 }
165
166 /**
167 * Register and enqueues public-facing JavaScript files.
168 */
169 public function enqueue_scripts() {
170 if ( advads_is_amp() ) {
171 return;
172 }
173 // wp_enqueue_script( $this->get_plugin_slug() . '-plugin-script', plugins_url('assets/js/public.js', __FILE__), array('jquery'), ADVADS_VERSION);
174 $activated_js = apply_filters( 'advanced-ads-activate-advanced-js', isset( $this->options()['advanced-js'] ) );
175
176 if ( $activated_js || ! empty( $_COOKIE['advads_frontend_picker'] ) ) {
177 wp_enqueue_script(
178 $this->get_plugin_slug() . '-advanced-js',
179 sprintf( '%spublic/assets/js/advanced%s.js', ADVADS_BASE_URL, defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ),
180 array( 'jquery' ),
181 ADVADS_VERSION,
182 false
183 );
184
185 $privacy = Advanced_Ads_Privacy::get_instance();
186 $privacy_options = $privacy->options();
187 $privacy_options['enabled'] = ! empty( $privacy_options['enabled'] );
188 $privacy_options['state'] = $privacy->get_state();
189
190 $data = array(
191 'blog_id' => get_current_blog_id(),
192 'privacy' => $privacy_options,
193 );
194
195 wp_localize_script( $this->get_plugin_slug() . '-advanced-js', 'advads_options', $data );
196 }
197 }
198
199 /**
200 * Print public-facing JavaScript in the HTML head.
201 */
202 public function print_head_scripts() {
203 $short_url = self::get_short_url();
204 $attribution = '<!-- ' . $short_url . ' is managing ads with Advanced Ads%1$s%2$s -->';
205 $version = self::is_new_user( 1585224000 ) ? ' ' . ADVADS_VERSION : '';
206 $plugin_url = self::get_group_by_url( $short_url, 'a' ) ? '' . ADVADS_URL : '';
207 // escaping would break HTML comment tags so we disable checks here.
208 // phpcs:ignore
209 echo apply_filters( 'advanced-ads-attribution', sprintf( $attribution, $version, $plugin_url ) );
210
211 if ( advads_is_amp() ) {
212 return;
213 }
214
215 ob_start();
216 ?>
217 <script id="<?php echo esc_attr( $this->get_frontend_prefix() ); ?>ready">
218 <?php
219 readfile( sprintf(
220 '%spublic/assets/js/ready%s.js',
221 ADVADS_BASE_PATH,
222 defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'
223 ) );
224 ?>
225 </script>
226 <?php
227 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaping would break the HTML
228 echo Advanced_Ads_Utils::get_inline_asset( ob_get_clean() );
229 }
230
231 /**
232 * Print inline scripts in wp_footer.
233 */
234 public function print_footer_scripts() {
235 if ( advads_is_amp() ) {
236 return;
237 }
238
239 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaping would break the HTML
240 echo Advanced_Ads_Utils::get_inline_asset(
241 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- we're getting the contents of a local file
242 sprintf( '<script>%s</script>', file_get_contents( sprintf(
243 '%spublic/assets/js/ready-queue%s.js',
244 ADVADS_BASE_PATH,
245 defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'
246 ) ) )
247 );
248 }
249
250 /**
251 * Register the Advanced Ads widget
252 */
253 public function widget_init() {
254 register_widget( 'Advanced_Ads_Widget' );
255 }
256
257 /**
258 * Fired when a new site is activated with a WPMU environment.
259 *
260 * @param int $blog_id ID of the new blog.
261 */
262 public function activate_new_site( $blog_id ) {
263
264 if ( 1 !== did_action( 'wpmu_new_blog' ) ) {
265 return;
266 }
267
268 switch_to_blog( $blog_id );
269 $this->single_activate();
270 restore_current_blog();
271 }
272
273 /**
274 * Fired for each blog when the plugin is activated.
275 */
276 protected function single_activate() {
277 // $this->post_types_rewrite_flush();
278 // -TODO inform modules
279 $this->create_capabilities();
280 }
281
282 /**
283 * Fired for each blog when the plugin is deactivated.
284 */
285 protected function single_deactivate() {
286 // -TODO inform modules
287 $this->remove_capabilities();
288 }
289
290 /**
291 * Load the plugin text domain for translation.
292 */
293 public function load_plugin_textdomain() {
294 load_plugin_textdomain( 'advanced-ads', false, ADVADS_BASE_DIR . '/languages' );
295 }
296
297 /**
298 * Fired when the plugin is activated.
299 *
300 * @param boolean $network_wide True if WPMU superadmin uses
301 * "Network Activate" action, false if
302 * WPMU is disabled or plugin is
303 * activated on an individual blog.
304 */
305 public function activate( $network_wide ) {
306 if ( function_exists( 'is_multisite' ) && is_multisite() ) {
307
308 if ( $network_wide ) {
309 // get all blog ids.
310 global $wpdb;
311 $blog_ids = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs}" );
312 $original_blog_id = $wpdb->blogid;
313
314 foreach ( $blog_ids as $blog_id ) {
315 switch_to_blog( $blog_id );
316 $this->single_activate();
317 }
318
319 switch_to_blog( $original_blog_id );
320 } else {
321 $this->single_activate();
322 }
323 } else {
324 $this->single_activate();
325 }
326 }
327
328 /**
329 * Fired when the plugin is deactivated.
330 *
331 * @param boolean $network_wide true if Advanced Ads should be disabled network-wide.
332 *
333 * True if WPMU superadmin uses
334 * "Network Deactivate" action, false if
335 * WPMU is disabled or plugin is
336 * deactivated on an individual blog.
337 */
338 public function deactivate( $network_wide ) {
339 if ( function_exists( 'is_multisite' ) && is_multisite() ) {
340
341 if ( $network_wide ) {
342 // get all blog ids.
343 global $wpdb;
344 $blog_ids = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs}" );
345 $original_blog_id = $wpdb->blogid;
346
347 foreach ( $blog_ids as $blog_id ) {
348 switch_to_blog( $blog_id );
349 $this->single_deactivate();
350 }
351
352 switch_to_blog( $original_blog_id );
353 } else {
354 $this->single_deactivate();
355 }
356 } else {
357 $this->single_deactivate();
358 }
359 }
360
361 /**
362 * Remove WP tag edit page for the ad group taxonomy
363 * needed, because we can’t remove it with `show_ui` without also removing the meta box
364 */
365 public function remove_taxonomy_menu_item() {
366 remove_submenu_page( 'edit.php?post_type=advanced_ads', 'edit-tags.php?taxonomy=advanced_ads_groups&amp;post_type=advanced_ads' );
367 }
368
369 /**
370 * Shortcode to include ad in frontend
371 *
372 * @param array $atts shortcode attributes.
373 *
374 * @return string ad content.
375 */
376 public function shortcode_display_ad( $atts ) {
377 $atts = is_array( $atts ) ? $atts : array();
378 $id = isset( $atts['id'] ) ? (int) $atts['id'] : 0;
379 // check if there is an inline attribute with or without value.
380 if ( isset( $atts['inline'] ) || in_array( 'inline', $atts, true ) ) {
381 $atts['inline_wrapper_element'] = true;
382 }
383 $atts = $this->prepare_shortcode_atts( $atts );
384
385 // use the public available function here.
386 return get_ad( $id, $atts );
387 }
388
389 /**
390 * Shortcode to include ad from an ad group in frontend
391 *
392 * @param array $atts shortcode attributes.
393 *
394 * @return string ad group content.
395 */
396 public function shortcode_display_ad_group( $atts ) {
397 $atts = is_array( $atts ) ? $atts : array();
398 $id = isset( $atts['id'] ) ? (int) $atts['id'] : 0;
399 $atts = $this->prepare_shortcode_atts( $atts );
400
401 // use the public available function here.
402 return get_ad_group( $id, $atts );
403 }
404
405 /**
406 * Shortcode to display content of an ad placement in frontend
407 *
408 * @param array $atts shortcode attributes.
409 *
410 * @return string ad placement content.
411 */
412 public function shortcode_display_ad_placement( $atts ) {
413 $atts = is_array( $atts ) ? $atts : array();
414 $id = isset( $atts['id'] ) ? (string) $atts['id'] : '';
415 $atts = $this->prepare_shortcode_atts( $atts );
416
417 // use the public available function here.
418 return get_ad_placement( $id, $atts );
419 }
420
421 /**
422 * Prepare shortcode attributes.
423 *
424 * @param array $atts array with strings.
425 *
426 * @return array
427 */
428 private function prepare_shortcode_atts( $atts ) {
429 $result = array();
430
431 /**
432 * Prepare attributes by converting strings to multi-dimensional array
433 * Example: [ 'output__margin__top' => 1 ] => ['output']['margin']['top'] = 1
434 */
435 if ( ! defined( 'ADVANCED_ADS_DISABLE_CHANGE' ) || ! ADVANCED_ADS_DISABLE_CHANGE ) {
436 foreach ( $atts as $attr => $data ) {
437 $levels = explode( '__', $attr );
438 $last = array_pop( $levels );
439
440 $cur_lvl = &$result;
441
442 foreach ( $levels as $lvl ) {
443 if ( ! isset( $cur_lvl[ $lvl ] ) ) {
444 $cur_lvl[ $lvl ] = array();
445 }
446
447 $cur_lvl = &$cur_lvl[ $lvl ];
448 }
449
450 $cur_lvl[ $last ] = $data;
451 }
452
453 $result = array_diff_key(
454 $result,
455 array(
456 'id' => false,
457 'blog_id' => false,
458 'ad_args' => false,
459 )
460 );
461 }
462
463 // Ad type: 'content' and a shortcode inside.
464 if ( isset( $atts['ad_args'] ) ) {
465 $result = array_merge( $result, json_decode( urldecode( $atts['ad_args'] ), true ) );
466
467 }
468
469 return $result;
470 }
471
472 /**
473 * Return plugin options
474 * these are the options updated by the user
475 *
476 * @return array $options
477 */
478 public function options() {
479 // we can’t store options if WPML String Translations is enabled, or it would not translate the "Ad Label" option.
480 if ( ! isset( $this->options ) || class_exists( 'WPML_ST_String' ) ) {
481 $this->options = get_option( ADVADS_SLUG, array() );
482 }
483
484 // allow to change options dynamically
485 $this->options = apply_filters( 'advanced-ads-options', $this->options );
486
487 return $this->options;
488 }
489
490 /**
491 * Update plugin options (not for settings page, but if automatic options are needed)
492 *
493 * @param array $options new options.
494 */
495 public function update_options( array $options ) {
496 // do not allow to clear options.
497 if ( array() === $options ) {
498 return;
499 }
500
501 $this->options = $options;
502 update_option( ADVADS_SLUG, $options );
503 }
504
505 /**
506 * Return internal plugin options
507 * these are options set by the plugin
508 *
509 * @return array $options
510 */
511 public function internal_options() {
512 if ( ! isset( $this->internal_options ) ) {
513 $defaults = array(
514 'version' => ADVADS_VERSION,
515 'installed' => time(), // when was this installed.
516 );
517 $this->internal_options = get_option( ADVADS_SLUG . '-internal', array() );
518
519 // save defaults.
520 if ( array() === $this->internal_options ) {
521 $this->internal_options = $defaults;
522 $this->update_internal_options( $this->internal_options );
523
524 self::get_instance()->create_capabilities();
525 }
526
527 // for versions installed prior to 1.5.3 set installed date for now.
528 if ( ! isset( $this->internal_options['installed'] ) ) {
529 $this->internal_options['installed'] = time();
530 $this->update_internal_options( $this->internal_options );
531 }
532 }
533
534 return $this->internal_options;
535 }
536
537 /**
538 * Update internal plugin options
539 *
540 * @param array $options new internal options.
541 */
542 public function update_internal_options( array $options ) {
543 // do not allow to clear options.
544 if ( array() === $options ) {
545 return;
546 }
547
548 $this->internal_options = $options;
549 update_option( ADVADS_SLUG . '-internal', $options );
550 }
551
552 /**
553 * Get prefix used for frontend elements
554 */
555 public function get_frontend_prefix() {
556 if ( ! $this->frontend_prefix ) {
557 $options = $this->options();
558
559 if ( ! isset( $options['front-prefix'] ) ) {
560 if ( isset( $options['id-prefix'] ) ) {
561 // deprecated: keeps widgets working that previously received an id based on the front-prefix.
562 $frontend_prefix = esc_attr( $options['id-prefix'] );
563 } else {
564 $host = parse_url( get_home_url(), PHP_URL_HOST );
565 $frontend_prefix = preg_match( '/[A-Za-z][A-Za-z0-9_]{4}/', $host, $result ) ? $result[0] . '-' : self::DEFAULT_FRONTEND_PREFIX;
566 }
567 } else {
568 $frontend_prefix = esc_attr( $options['front-prefix'] );
569 }
570 /**
571 * Applying the filter here makes sure that it is the same frontend prefix for all
572 * calls on this page impression
573 */
574 $this->frontend_prefix = apply_filters( 'advanced-ads-frontend-prefix', $frontend_prefix );
575 }
576
577 return $this->frontend_prefix;
578 }
579
580 /**
581 * Get priority used for injection inside content
582 */
583 public function get_content_injection_priority() {
584 $options = $this->options();
585
586 return isset( $options['content-injection-priority'] ) ? (int) $options['content-injection-priority'] : 100;
587 }
588
589 /**
590 * Returns the capability needed to perform an action
591 *
592 * @param string $capability a capability to check, can be internal to Advanced Ads.
593 *
594 * @return string $capability a valid WordPress capability.
595 */
596 public static function user_cap( $capability = 'manage_options' ) {
597
598 global $advanced_ads_capabilities;
599
600 // admins can do everything.
601 // is also a fallback if no option or more specific capability is given.
602 if ( current_user_can( 'manage_options' ) ) {
603 return 'manage_options';
604 }
605
606 return apply_filters( 'advanced-ads-capability', $capability );
607 }
608
609 /**
610 * Create roles and capabilities
611 */
612 public function create_capabilities() {
613 if ( $role = get_role( 'administrator' ) ) {
614 $role->add_cap( 'advanced_ads_manage_options' );
615 $role->add_cap( 'advanced_ads_see_interface' );
616 $role->add_cap( 'advanced_ads_edit_ads' );
617 $role->add_cap( 'advanced_ads_manage_placements' );
618 $role->add_cap( 'advanced_ads_place_ads' );
619 }
620 }
621
622 /**
623 * Remove roles and capabilities
624 */
625 public function remove_capabilities() {
626 if ( $role = get_role( 'administrator' ) ) {
627 $role->remove_cap( 'advanced_ads_manage_options' );
628 $role->remove_cap( 'advanced_ads_see_interface' );
629 $role->remove_cap( 'advanced_ads_edit_ads' );
630 $role->remove_cap( 'advanced_ads_manage_placements' );
631 $role->remove_cap( 'advanced_ads_place_ads' );
632 }
633 }
634
635 /**
636 * Fired when the plugin is uninstalled.
637 */
638 public static function uninstall() {
639 $advads_options = Advanced_Ads::get_instance()->options();
640
641 if ( ! empty( $advads_options['uninstall-delete-data'] ) ) {
642 global $wpdb;
643 $main_blog_id = $wpdb->blogid;
644
645 Advanced_Ads::get_instance()->create_post_types();
646
647 if ( ! is_multisite() ) {
648 self::get_instance()->uninstall_single();
649 } else {
650 $blog_ids = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs}" );
651
652 foreach ( $blog_ids as $blog_id ) {
653 switch_to_blog( $blog_id );
654 self::get_instance()->uninstall_single();
655 }
656 switch_to_blog( $main_blog_id );
657 }
658
659 // Delete assets (main blog).
660 Advanced_Ads_Ad_Blocker_Admin::get_instance()->clear_assets();
661 }
662
663 }
664
665 /**
666 * Fired for each blog when the plugin is uninstalled.
667 */
668 protected function uninstall_single() {
669 global $wpdb;
670
671 // Ads.
672 $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s", Advanced_Ads::POST_TYPE_SLUG ) );
673
674 if ( $post_ids ) {
675 $wpdb->delete(
676 $wpdb->posts,
677 array( 'post_type' => Advanced_Ads::POST_TYPE_SLUG ),
678 array( '%s' )
679 );
680
681 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE post_id IN( %s )", implode( ',', $post_ids ) ) );
682 }
683
684 // Groups.
685 $term_ids = $wpdb->get_col( $wpdb->prepare( "SELECT t.term_id FROM {$wpdb->terms} AS t INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = %s", Advanced_Ads::AD_GROUP_TAXONOMY ) );
686
687 foreach ( $term_ids as $term_id ) {
688 wp_delete_term( $term_id, Advanced_Ads::AD_GROUP_TAXONOMY );
689 }
690
691 delete_option( 'advads-ad-groups' );
692 delete_option( Advanced_Ads::AD_GROUP_TAXONOMY . '_children' );
693 delete_option( 'advads-ad-weights' );
694
695 // Placements.
696 delete_option( 'advads-ads-placements' );
697
698 // User metadata.
699 delete_metadata( 'user', null, 'advanced-ads-hide-wizard', '', true );
700 delete_metadata( 'user', null, 'advanced-ads-subscribed', '', true );
701
702 // Post metadata.
703 delete_metadata( 'post', null, '_advads_ad_settings', '', true );
704
705 // Transients.
706 delete_transient( ADVADS_SLUG . '_add-on-updates-checked' );
707
708 delete_option( GADSENSE_OPT_NAME );
709 delete_option( ADVADS_SLUG );
710 delete_option( ADVADS_SLUG . '-internal' );
711 delete_option( ADVADS_SLUG . '-notices' );
712
713 // Widget.
714 $base_widget_id = Advanced_Ads_Widget::get_base_id();
715 delete_option( 'widget_' . $base_widget_id );
716
717 // Ad blocker disquise.
718 delete_option( ADVADS_AB_SLUG );
719
720 do_action( 'advanced-ads-uninstall' );
721
722 wp_cache_flush();
723 }
724
725 /**
726 * Check if any add-on is activated
727 *
728 * @return bool true if there is any add-on activated
729 */
730 public static function any_activated_add_on() {
731 return ( defined( 'AAP_VERSION' ) // Advanced Ads Pro.
732 || defined( 'AAGAM_VERSION' ) // Google Ad Manager.
733 || defined( 'AASA_VERSION' ) // Selling Ads.
734 || defined( 'AAT_VERSION' ) // Tracking.
735 || defined( 'AASADS_VERSION' ) // Sticky Ads.
736 || defined( 'AAR_VERSION' ) // Responsive Ads.
737 || defined( 'AAPLDS_VERSION' ) // PopUp and Layer Ads.
738 || defined( 'AAGT_SLUG' ) // Geo-Targeting.
739 );
740 }
741
742 /**
743 * Get the correct support URL: wp.org for free users and website for those with any add-on installed
744 *
745 * @param string $utm add UTM parameter to the link leading to https://wpadvancedads.com, if given.
746 *
747 * @return string URL.
748 */
749 public static function support_url( $utm = '' ) {
750
751 $utm = empty( $utm ) ? '?utm_source=advanced-ads&utm_medium=link&utm_campaign=support' : $utm;
752 if ( self::any_activated_add_on() ) {
753 $url = ADVADS_URL . 'support/' . $utm . '-with-addons';
754 } else {
755 $url = ADVADS_URL . 'support/' . $utm . '-free-user';
756 }
757
758 return $url;
759 }
760
761 /**
762 * Create a random group
763 *
764 * @param string $url optional parameter.
765 * @param string $ex group.
766 *
767 * @return bool
768 */
769 public static function get_group_by_url( $url = '', $ex = 'a' ) {
770
771 $url = self::get_short_url( $url );
772
773 $code = intval( substr( md5( $url ), - 1 ), 16 );
774
775 switch ( $ex ) {
776 case 'b':
777 return ( $code & 2 ) >> 1; // returns 1 or 0.
778 case 'c':
779 return ( $code & 4 ) >> 2; // returns 1 or 0.
780 case 'd':
781 return ( $code & 8 ) >> 3; // returns 1 or 0.
782 default:
783 return $code & 1; // returns 1 or 0.
784 }
785 }
786
787 /**
788 * Check if user started after a given date
789 *
790 * @param integer $timestamp time stamp.
791 *
792 * @return bool true if user is added after timestamp.
793 */
794 public static function is_new_user( $timestamp = 0 ) {
795
796 // allow admins to see version for new users in any case.
797 if ( current_user_can( self::user_cap( 'advanced_ads_manage_options' ) )
798 && isset( $_REQUEST['advads-ignore-timestamp'] ) ) {
799 return true;
800 }
801
802 $timestamp = absint( $timestamp );
803
804 $options = self::get_instance()->internal_options();
805 $installed = isset( $options['installed'] ) ? $options['installed'] : 0;
806
807 return ( $installed >= $timestamp );
808 }
809
810 /**
811 * Show stuff to new users only.
812 *
813 * @param integer $timestamp time after which to show whatever.
814 * @param string $group optional group.
815 *
816 * @return bool true if user enabled after given timestamp.
817 */
818 public static function show_to_new_users( $timestamp, $group = 'a' ) {
819
820 return ( self::get_group_by_url( null, $group ) && self::is_new_user( $timestamp ) );
821 }
822
823 /**
824 * Get short version of home_url()
825 * remove protocol and www
826 * remove slash
827 *
828 * @param string $url URL to be shortened.
829 *
830 * @return string
831 */
832 public static function get_short_url( $url = '' ) {
833
834 $url = empty( $url ) ? home_url() : $url;
835
836 // strip protocols.
837 if ( preg_match( '/^(\w[\w\d]*:\/\/)?(www\.)?(.*)$/', trim( $url ), $matches ) ) {
838 $url = $matches[3];
839 }
840
841 // strip slashes.
842 $url = trim( $url, '/' );
843
844 return $url;
845 }
846
847 /**
848 * Return Advanced Ads logo in base64 format for use in WP Admin menu.
849 *
850 * @return string
851 */
852 public static function get_icon_svg() {
853 return 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE4LjEuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJFYmVuZV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCINCgkgdmlld0JveD0iMCAwIDY0Ljk5MyA2NS4wMjQiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDY0Ljk5MyA2NS4wMjQ7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIHN0eWxlPSJmaWxsOiNFNEU0RTQ7IiBkPSJNNDYuNTcxLDI3LjY0MXYyMy4xMzNIMTQuMjVWMTguNDUzaDIzLjExOGMtMC45NTYtMi4xODMtMS40OTQtNC41OS0xLjQ5NC03LjEyNg0KCWMwLTIuNTM1LDAuNTM4LTQuOTQyLDEuNDk0LTcuMTI0aC02Ljk1N0gwdjQ5LjQ5M2wxLjYxOCwxLjYxOEwwLDUzLjY5NmMwLDYuMjU2LDUuMDY4LDExLjMyNiwxMS4zMjQsMTEuMzI4djBoMTkuMDg3aDMwLjQxMlYyNy42MTENCgljLTIuMTkxLDAuOTY0LTQuNjA5LDEuNTA5LTcuMTU3LDEuNTA5QzUxLjE0MiwyOS4xMiw0OC43NDYsMjguNTg4LDQ2LjU3MSwyNy42NDF6Ii8+DQo8Y2lyY2xlIHN0eWxlPSJmaWxsOiM5ODk4OTg7IiBjeD0iNTMuNjY2IiBjeT0iMTEuMzI4IiByPSIxMS4zMjgiLz4NCjwvc3ZnPg0K';
854 }
855
856 /**
857 * Fires when a post is transitioned from one status to another.
858 *
859 * @param string $new_status New post status.
860 * @param string $old_status Old post status.
861 * @param WP_Post $post Post object.
862 */
863 public function transition_ad_status( $new_status, $old_status, $post ) {
864 if ( ! isset( $post->post_type ) || Advanced_Ads::POST_TYPE_SLUG !== $post->post_type || ! isset( $post->ID ) ) {
865 return;
866 }
867
868 $ad = new Advanced_Ads_Ad( $post->ID );
869
870 if ( $old_status !== $new_status ) {
871 /**
872 * Fires when an ad has transitioned from one status to another.
873 *
874 * @param Advanced_Ads_Ad $ad Ad object.
875 */
876 do_action( "advanced-ads-ad-status-{$old_status}-to-{$new_status}", $ad );
877 }
878
879 if ( 'publish' === $new_status && 'publish' !== $old_status ) {
880 /**
881 * Fires when an ad has transitioned from any other status to `publish`.
882 *
883 * @param Advanced_Ads_Ad $ad Ad object.
884 */
885 do_action( 'advanced-ads-ad-status-published', $ad );
886 }
887
888 if ( 'publish' === $old_status && 'publish' !== $new_status ) {
889 /**
890 * Fires when an ad has transitioned from `publish` to any other status.
891 *
892 * @param Advanced_Ads_Ad $ad Ad object.
893 */
894 do_action( 'advanced-ads-ad-status-unpublished', $ad );
895 }
896
897 if ( $old_status === 'publish' && $new_status === Advanced_Ads_Ad_Expiration::POST_STATUS ) {
898 /**
899 * Fires when an ad is expired.
900 *
901 * @param int $id
902 * @param Advanced_Ads_Ad $ad
903 */
904 do_action( 'advanced-ads-ad-expired', $ad->id, $ad );
905 }
906 }
907
908 }
909