PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 1.7.4.2
Advanced Ads – Ad Manager & AdSense v1.7.4.2
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 / admin / class-advanced-ads-admin.php
advanced-ads / admin Last commit date
assets 10 years ago includes 10 years ago views 10 years ago class-advanced-ads-admin.php 10 years ago
class-advanced-ads-admin.php
2182 lines
1 <?php
2
3 /**
4 * Advanced Ads.
5 *
6 * @package Advanced_Ads_Admin
7 * @author Thomas Maier <thomas.maier@webgilde.com>
8 * @license GPL-2.0+
9 * @link http://webgilde.com
10 * @copyright 2013-2015 Thomas Maier, webgilde GmbH
11 */
12
13 /**
14 * Plugin class. This class should ideally be used to work with the
15 * administrative side of the WordPress site.
16 *
17 * @package Advanced_Ads_Admin
18 * @author Thomas Maier <thomas.maier@webgilde.com>
19 */
20 class Advanced_Ads_Admin {
21
22 /**
23 * Instance of this class.
24 *
25 * @since 1.0.0
26 * @var object
27 */
28 protected static $instance = null;
29
30 /**
31 * Instance of admin notice class.
32 *
33 * @since 1.5.2
34 * @var object
35 */
36 protected $notices = null;
37
38 /**
39 * Slug of the settings page
40 *
41 * @since 1.0.0
42 * @var string
43 */
44 public $plugin_screen_hook_suffix = null;
45
46 /**
47 * Slug of the ad group page
48 *
49 * @since 1.0.0
50 * @var string
51 */
52 protected $ad_group_hook_suffix = null;
53
54 /**
55 * general plugin slug
56 *
57 * @since 1.0.0
58 * @var string
59 */
60 protected $plugin_slug = '';
61
62 /**
63 * post type slug
64 *
65 * @since 1.0.0
66 * @var string
67 */
68 protected $post_type = '';
69
70 /**
71 * meta box ids
72 *
73 * @since 1.7.4.2
74 * @var array
75 */
76 protected $meta_box_ids = array();
77
78 /**
79 * Initialize the plugin by loading admin scripts & styles and adding a
80 * settings page and menu.
81 *
82 * @since 1.0.0
83 */
84 private function __construct() {
85 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
86 new Advanced_Ads_Ad_Ajax_Callbacks;
87 } else {
88 add_action( 'plugins_loaded', array( $this, 'wp_plugins_loaded' ) );
89 }
90 // add shortcode creator to TinyMCE
91 Advanced_Ads_Shortcode_Creator::get_instance();
92 // registering custom columns needs to work with and without DOING_AJAX
93 add_filter( 'manage_advanced_ads_posts_columns', array($this, 'ad_list_columns_head') ); // extra column
94 add_filter( 'manage_advanced_ads_posts_custom_column', array($this, 'ad_list_columns_content'), 10, 2 ); // extra column
95 add_filter( 'manage_advanced_ads_posts_custom_column', array($this, 'ad_list_columns_timing'), 10, 2 ); // extra column
96 add_action( 'restrict_manage_posts', array( $this, 'ad_list_add_filters') );
97 }
98
99 public function wp_plugins_loaded() {
100 /*
101 * Call $plugin_slug from public plugin class.
102 *
103 */
104 $plugin = Advanced_Ads::get_instance();
105 $this->plugin_slug = $plugin->get_plugin_slug();
106 $this->post_type = constant( 'Advanced_Ads::POST_TYPE_SLUG' );
107
108 // Load admin style sheet and JavaScript.
109 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
110 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ), 9 );
111
112 // Add menu items
113 add_action( 'admin_menu', array($this, 'add_plugin_admin_menu') );
114 add_action( 'admin_head', array( $this, 'highlight_menu_item' ) );
115
116 // on post/ad edit screen
117 add_action( 'edit_form_top', array($this, 'edit_form_above_title') );
118 add_action( 'edit_form_after_title', array($this, 'edit_form_below_title') );
119 add_action( 'dbx_post_sidebar', array($this, 'edit_form_end') );
120 add_action( 'admin_init', array($this, 'add_meta_boxes') );
121 add_action( 'post_submitbox_misc_actions', array($this, 'add_submit_box_meta') );
122
123 // save ads post type
124 add_action( 'save_post', array($this, 'save_ad') );
125 // delete ads post type
126 add_action( 'delete_post', array($this, 'delete_ad') );
127
128 // ad updated messages
129 add_filter( 'post_updated_messages', array($this, 'ad_update_messages') );
130 add_filter( 'bulk_post_updated_messages', array($this, 'ad_bulk_update_messages'), 10, 2 );
131
132 // handling (ad) lists
133 add_filter( 'request', array($this, 'ad_list_request') ); // order ads by title, not ID
134
135 // settings handling
136 add_action( 'admin_init', array($this, 'settings_init') );
137 // update placements
138 add_action( 'admin_init', array('Advanced_Ads_Placements', 'update_placements') );
139 // check for add-on updates
140 add_action( 'admin_init', array($this, 'add_on_updater'), 1 );
141
142 // check for update logic
143 add_action( 'admin_notices', array($this, 'admin_notices') );
144
145 // Add an action link pointing to the options page.
146 $plugin_basename = plugin_basename( plugin_dir_path( '__DIR__' ) . $this->plugin_slug . '.php' );
147 add_filter( 'plugin_action_links_' . $plugin_basename, array($this, 'add_action_links') );
148
149 // add meta box for post types edit pages
150 add_action( 'add_meta_boxes', array( $this, 'add_post_meta_box' ) );
151 add_action( 'save_post', array( $this, 'save_post_meta_box' ) );
152
153 // register dashboard widget
154 add_action( 'wp_dashboard_setup', array($this, 'add_dashboard_widget') );
155
156 // set 1 column layout on overview page as user and page option
157 add_filter( 'screen_layout_columns', array('Advanced_Ads_Overview_Widgets_Callbacks', 'one_column_overview_page') );
158 add_filter( 'get_user_option_screen_layout_toplevel_page_advanced', array( 'Advanced_Ads_Overview_Widgets_Callbacks', 'one_column_overview_page_user') );
159
160 // add links to plugin page
161 add_filter( 'plugin_action_links_' . ADVADS_BASE, array( $this, 'add_plugin_links' ) );
162 // display information when user is going to disable the plugin
163 // add_filter( 'after_plugin_row_' . ADVADS_BASE, array( $this, 'display_deactivation_message' ) );
164 }
165
166 /**
167 * Return an instance of this class.
168 *
169 * @since 1.0.0
170 *
171 * @return object A single instance of this class.
172 */
173 public static function get_instance() {
174
175 // If the single instance hasn't been set, set it now.
176 if ( null == self::$instance ) {
177 self::$instance = new self;
178 }
179
180 return self::$instance;
181 }
182
183 /**
184 * Register and enqueue admin-specific style sheet.
185 *
186 * @since 1.0.0
187 */
188 public function enqueue_admin_styles() {
189 wp_enqueue_style( $this->plugin_slug . '-admin-styles', plugins_url( 'assets/css/admin.css', __FILE__ ), array(), ADVADS_VERSION );
190 if( self::screen_belongs_to_advanced_ads() ){
191 // jQuery ui smoothness style 1.11.4
192 wp_enqueue_style( $this->plugin_slug . '-jquery-ui-styles', plugins_url( 'assets/jquery-ui/jquery-ui.min.css', __FILE__ ), array(), '1.11.4' );
193 }
194 //wp_enqueue_style( 'jquery-style', '//code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css' );
195 }
196
197 /**
198 * Register and enqueue admin-specific JavaScript.
199 *
200 * @since 1.0.0
201 *
202 * @return null Return early if no settings page is registered.
203 */
204 public function enqueue_admin_scripts() {
205
206 // global js script
207 wp_enqueue_script( $this->plugin_slug . '-admin-global-script', plugins_url( 'assets/js/admin-global.js', __FILE__ ), array('jquery'), ADVADS_VERSION );
208
209 if( self::screen_belongs_to_advanced_ads() ){
210 wp_register_script( $this->plugin_slug . '-admin-script', plugins_url( 'assets/js/admin.js', __FILE__ ), array('jquery', 'jquery-ui-autocomplete'), ADVADS_VERSION );
211 wp_register_script( $this->plugin_slug . '-wizard-script', plugins_url( 'assets/js/wizard.js', __FILE__ ), array('jquery'), ADVADS_VERSION );
212
213 // jquery ui
214 wp_enqueue_script( 'jquery-ui-accordion' );
215 wp_enqueue_script( 'jquery-ui-button' );
216 wp_enqueue_script( 'jquery-ui-tooltip' );
217
218 // just register this script for later inclusion on ad group list page
219 wp_register_script( 'inline-edit-group-ads', plugins_url( 'assets/js/inline-edit-group-ads.js', __FILE__ ), array('jquery'), ADVADS_VERSION );
220
221 // register admin.js translations
222 $translation_array = array(
223 'condition_or' => __( 'or', 'advanced-ads' ),
224 'condition_and' => __( 'and', 'advanced-ads' ),
225 'after_paragraph_promt' => __( 'After which paragraph?', 'advanced-ads' ),
226 );
227 wp_localize_script( $this->plugin_slug . '-admin-script', 'advadstxt', $translation_array );
228
229 wp_enqueue_script( $this->plugin_slug . '-admin-script' );
230 wp_enqueue_script( $this->plugin_slug . '-wizard-script' );
231 }
232
233 //call media manager for image upload only on ad edit pages
234 $screen = get_current_screen();
235 if( isset( $screen->id ) && Advanced_Ads::POST_TYPE_SLUG === $screen->id ) {
236 // the 'wp_enqueue_media' function can be executed only once and should be called with the 'post' parameter
237 // in this case, the '_wpMediaViewsL10n' js object inside html will contain id of the post, that is necessary to view oEmbed priview inside tinyMCE editor.
238 // since other plugins can call the 'wp_enqueue_media' function without the 'post' parameter, Advanced Ads should call it earlier.
239 global $post;
240 wp_enqueue_media( array( 'post' => $post ) );
241 }
242
243 }
244
245 /**
246 * check if the current screen belongs to Advanced Ads
247 *
248 * @since 1.6.6
249 * @return bool true if screen belongs to Advanced Ads
250 */
251 static function screen_belongs_to_advanced_ads(){
252
253 if( ! function_exists( 'get_current_screen' ) ){
254 return false;
255 }
256
257 $screen = get_current_screen();
258 //echo $screen->id;
259 if( !isset( $screen->id ) ) {
260 return false;
261 }
262
263 $advads_pages = apply_filters( 'advanced-ads-dashboard-screens', array(
264 'advanced-ads_page_advanced-ads-groups', // ad groups
265 'edit-advanced_ads', // ads overview
266 'advanced_ads', // ad edit page
267 'advanced-ads_page_advanced-ads-placements', // placements
268 'advanced-ads_page_advanced-ads-settings', // settings
269 'toplevel_page_advanced-ads', // overview
270 'admin_page_advanced-ads-debug', // debug
271 'advanced-ads_page_advanced-ads-support', // support
272 'admin_page_advanced-ads-intro', // intro
273 'admin_page_advanced-ads-import-export', // import & export
274 ));
275
276 if( in_array( $screen->id, $advads_pages )){
277 return true;
278 }
279
280 return false;
281 }
282
283 /**
284 * Register the administration menu for this plugin into the WordPress Dashboard menu.
285 *
286 * @since 1.0.0
287 */
288 public function add_plugin_admin_menu() {
289
290 // add main menu item with overview page
291 add_menu_page(
292 __( 'Overview', 'advanced-ads' ), 'Advanced Ads', Advanced_Ads_Plugin::user_cap( 'advanced_ads_see_interface'), $this->plugin_slug, array($this, 'display_overview_page'), 'dashicons-chart-line', '58.74'
293 );
294
295 add_submenu_page(
296 $this->plugin_slug, __( 'Ads', 'advanced-ads' ), __( 'Ads', 'advanced-ads' ), Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads'), 'edit.php?post_type=' . Advanced_Ads::POST_TYPE_SLUG
297 );
298
299 // hidden by css; not placed in 'options.php' in order to highlight the correct item, see the 'highlight_menu_item()'
300 if ( ! current_user_can( 'edit_posts' ) ) {
301 add_submenu_page(
302 $this->plugin_slug, __( 'Add New Ad', 'advanced-ads' ), __( 'New Ad', 'advanced-ads' ), Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads'), 'post-new.php?post_type=' . Advanced_Ads::POST_TYPE_SLUG
303 );
304 }
305
306 $this->ad_group_hook_suffix = add_submenu_page(
307 $this->plugin_slug, __( 'Ad Groups', 'advanced-ads' ), __( 'Groups', 'advanced-ads' ), Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads'), $this->plugin_slug . '-groups', array($this, 'ad_group_admin_page')
308 );
309
310 // add placements page
311 add_submenu_page(
312 $this->plugin_slug, __( 'Ad Placements', 'advanced-ads' ), __( 'Placements', 'advanced-ads' ), Advanced_Ads_Plugin::user_cap( 'advanced_ads_manage_placements'), $this->plugin_slug . '-placements', array($this, 'display_placements_page')
313 );
314 // add settings page
315 $this->plugin_screen_hook_suffix = add_submenu_page(
316 $this->plugin_slug, __( 'Advanced Ads Settings', 'advanced-ads' ), __( 'Settings', 'advanced-ads' ), Advanced_Ads_Plugin::user_cap( 'advanced_ads_manage_options'), $this->plugin_slug . '-settings', array($this, 'display_plugin_settings_page')
317 );
318 add_submenu_page(
319 'options.php', __( 'Advanced Ads Debugging', 'advanced-ads' ), __( 'Debug', 'advanced-ads' ), Advanced_Ads_Plugin::user_cap( 'advanced_ads_manage_options'), $this->plugin_slug . '-debug', array($this, 'display_plugin_debug_page')
320 );
321 // intro page
322 add_submenu_page(
323 'options.php', __( 'Advanced Ads Intro', 'advanced-ads' ), __( 'Advanced Ads Intro', 'advanced-ads' ), Advanced_Ads_Plugin::user_cap( 'advanced_ads_manage_options'), $this->plugin_slug . '-intro', array($this, 'display_plugin_intro_page')
324 );
325 // add support page
326 add_submenu_page(
327 $this->plugin_slug, __( 'Support', 'advanced-ads' ), __( 'Support', 'advanced-ads' ), Advanced_Ads_Plugin::user_cap( 'advanced_ads_manage_options'), $this->plugin_slug . '-support', array($this, 'display_support_page')
328 );
329
330 // allows extensions to insert sub menu pages
331 do_action( 'advanced-ads-submenu-pages', $this->plugin_slug );
332 }
333
334 /**
335 * Highlights the 'Advanced Ads->Ads' item in the menu when an ad edit page is open
336 * @see the 'parent_file' and the 'submenu_file' filters for reference
337 */
338 public function highlight_menu_item() {
339 global $parent_file, $submenu_file, $post_type;
340 if ( $post_type === $this->post_type ) {
341 $parent_file = $this->plugin_slug;
342 $submenu_file = 'edit.php?post_type=' . $this->post_type;
343 }
344 }
345
346 /**
347 * Render the overview page
348 *
349 * @since 1.2.2
350 */
351 public function display_overview_page() {
352
353 $screen = get_current_screen();
354
355 // set up overview widgets
356 Advanced_Ads_Overview_Widgets_Callbacks::setup_overview_widgets( $screen );
357
358 // convert from vertical order to horizontal
359 $screen->add_option( 'layout_columns', 1 );
360
361 include ADVADS_BASE_PATH . 'admin/views/overview.php';
362 }
363
364 /**
365 * Render the settings page
366 *
367 * @since 1.0.0
368 */
369 public function display_plugin_settings_page() {
370 include ADVADS_BASE_PATH . 'admin/views/settings.php';
371 }
372
373 /**
374 * Render the placements page
375 *
376 * @since 1.1.0
377 */
378 public function display_placements_page() {
379 $placement_types = Advanced_Ads_Placements::get_placement_types();
380 $placements = Advanced_Ads::get_ad_placements_array(); // -TODO use model
381 $items = Advanced_Ads_Placements::items_for_select();
382 // load ads and groups for select field
383
384 // display view
385 include ADVADS_BASE_PATH . 'admin/views/placements.php';
386 }
387
388 /**
389 * Render the debug page
390 *
391 * @since 1.0.1
392 */
393 public function display_plugin_debug_page() {
394 // load array with ads by condition
395 $plugin = Advanced_Ads::get_instance();
396 $plugin_options = $plugin->options();
397 $ad_placements = Advanced_Ads::get_ad_placements_array(); // -TODO use model
398
399 include ADVADS_BASE_PATH . 'admin/views/debug.php';
400 }
401
402 /**
403 * Render intro page
404 *
405 * @since 1.6.8.2
406 */
407 public function display_plugin_intro_page() {
408 // load array with ads by condition
409
410 // remove intro message from queue
411 Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue('nl_intro');
412
413 include ADVADS_BASE_PATH . 'admin/views/intro.php';
414 }
415
416 /**
417 * Render the support page
418 *
419 * @since 1.6.8.1
420 */
421 public function display_support_page() {
422 // process email
423
424 $mail_sent = false;
425 $sent_errors = array();
426 global $current_user;
427 $user = wp_get_current_user();
428
429 $email = $user->user_email !== '' ? $user->user_email : '';
430 $name = $user->first_name !== '' ? $user->first_name . ' ' . $user->last_name : $user->user_login;
431 $message = '';
432
433 if( isset( $_POST['advads_support']['email'] ) ){
434
435 $email = trim( $_POST['advads_support']['email'] );
436 $name = trim( $_POST['advads_support']['name'] );
437 $message = trim( $_POST['advads_support']['message'] );
438 if( '' === $message ){
439 $sent_errors[] = __('Please enter a message', 'advanced-ads');
440 }
441 if( is_email( $email ) ){
442 $headers = 'From: '. $name .' <' . $email . '>' . "\r\n";
443 $content = $message;
444 $content .= "\r\n\r\n Name: " . $name;
445 $content .= "\r\n URL: " . home_url();
446
447 $mail_sent = wp_mail( 'support@wpadvancedads.com', 'Support for ' . home_url(), $content, $headers );
448 if( ! $mail_sent ){
449 $sent_errors[] = sprintf(__('Email could NOT be sent. Please contact us directly at %s.', 'advanced-ads'), '<a href="mailto:support@wpadvancedads.com">support@wpadvancedads.com</a>');
450 }
451 } else {
452 $sent_errors[] = __('Please enter a valid email address', 'advanced-ads');
453 }
454 }
455
456 include ADVADS_BASE_PATH . 'admin/views/support.php';
457 }
458
459 /**
460 * Render the ad group page
461 *
462 * @since 1.0.0
463 */
464 public function ad_group_admin_page() {
465
466 $taxonomy = Advanced_Ads::AD_GROUP_TAXONOMY;
467 $post_type = Advanced_Ads::POST_TYPE_SLUG;
468 $tax = get_taxonomy( $taxonomy );
469
470 $action = $this->current_action();
471
472 // handle new and updated groups
473 if ( 'editedgroup' == $action ) {
474 $group_id = (int) $_POST['group_id'];
475 check_admin_referer( 'update-group_' . $group_id );
476
477 if ( ! current_user_can( $tax->cap->edit_terms ) ) {
478 wp_die( __( 'Sorry, you are not allowed to access this feature.', 'advanced-ads' ) ); }
479
480 // handle new groups
481 if ( 0 == $group_id ) {
482 $ret = wp_insert_term( $_POST['name'], $taxonomy, $_POST );
483 if ( $ret && ! is_wp_error( $ret ) ) {
484 $forced_message = 1; }
485 else {
486 $forced_message = 4; }
487 // handle group updates
488 } else {
489 $tag = get_term( $group_id, $taxonomy );
490 if ( ! $tag ) {
491 wp_die( __( 'You attempted to edit an ad group that doesn&#8217;t exist. Perhaps it was deleted?', 'advanced-ads' ) ); }
492
493 $ret = wp_update_term( $group_id, $taxonomy, $_POST );
494 if ( $ret && ! is_wp_error( $ret ) ) {
495 $forced_message = 3; }
496 else {
497 $forced_message = 5; }
498 }
499 // deleting items
500 } elseif ( $action == 'delete' ){
501 $group_id = (int) $_REQUEST['group_id'];
502 check_admin_referer( 'delete-tag_' . $group_id );
503
504 if ( ! current_user_can( $tax->cap->delete_terms ) ) {
505 wp_die( __( 'Sorry, you are not allowed to access this feature.', 'advanced-ads' ) ); }
506
507 wp_delete_term( $group_id, $taxonomy );
508
509 $forced_message = 2;
510 }
511
512 // handle views
513 switch ( $action ) {
514 case 'edit' :
515 $title = $tax->labels->edit_item;
516 if ( isset($_REQUEST['group_id']) ) {
517 $group_id = absint( $_REQUEST['group_id'] );
518 $tag = get_term( $group_id, $taxonomy, OBJECT, 'edit' );
519 } else {
520 $group_id = 0;
521 $tag = false;
522 }
523
524 include ADVADS_BASE_PATH . 'admin/views/ad-group-edit.php';
525 break;
526
527 default :
528 $title = $tax->labels->name;
529 $wp_list_table = _get_list_table( 'WP_Terms_List_Table' );
530
531 // load template
532 include ADVADS_BASE_PATH . 'admin/views/ad-group.php';
533 }
534 }
535
536 /**
537 * returns a link to the ad group list page
538 *
539 * @since 1.0.0
540 * @param arr $args additional arguments, e.g. action or group_id
541 * @return string admin url
542 */
543 static function group_page_url($args = array()) {
544 $plugin = Advanced_Ads::get_instance();
545
546 $defaultargs = array(
547 // 'post_type' => constant("Advanced_Ads::POST_TYPE_SLUG"),
548 'page' => 'advanced-ads-groups',
549 );
550 $args = $args + $defaultargs;
551
552 return add_query_arg( $args, admin_url( 'admin.php' ) );
553 }
554
555 /**
556 * Add settings action link to the plugins page.
557 *
558 * @since 1.0.0
559 */
560 public function add_action_links($links) {
561
562 return array_merge(
563 array(
564 'settings' => '<a href="' . admin_url( 'edit.php?post_type=advanced_ads&page=advanced-ads-settings' ) . '">' . __( 'Settings', 'advanced-ads' ) . '</a>'
565 ), $links
566 );
567 }
568
569 /**
570 * add information above the ad title
571 *
572 * @since 1.5.6
573 * @param obj $post
574 */
575 public function edit_form_above_title($post){
576 if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
577 return;
578 }
579 $ad = new Advanced_Ads_Ad( $post->ID );
580
581 include ADVADS_BASE_PATH . 'admin/views/ad-info-top.php';
582 }
583
584 /**
585 * add information about the ad below the ad title
586 *
587 * @since 1.1.0
588 * @param obj $post
589 */
590 public function edit_form_below_title($post){
591 if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
592 return;
593 }
594 $ad = new Advanced_Ads_Ad( $post->ID );
595
596 include ADVADS_BASE_PATH . 'admin/views/ad-info.php';
597 }
598
599 /**
600 * add information below the ad edit form
601 *
602 * @since 1.7.3
603 * @param obj $post
604 */
605 public function edit_form_end($post){
606 if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
607 return;
608 }
609
610 include ADVADS_BASE_PATH . 'admin/views/ad-info-bottom.php';
611 }
612
613 /**
614 * whether to show the wizard welcome message or not
615 *
616 * @since 1.7.4
617 * @return bool true, if wizard welcome message should be displayed
618 */
619 public function show_wizard_welcome(){
620
621 $user_id = get_current_user_id();
622 if( ! $user_id ) {
623 return true;
624 }
625
626 $hide_wizard = get_user_meta( $user_id, 'advanced-ads-hide-wizard', true );
627 global $post;
628
629 return ( ! $hide_wizard && 'edit' !== $post->filter ) ? true : false;
630 }
631
632 /**
633 * whether to start the wizard by default or not
634 *
635 * @since 1.7.4
636 * return bool true, if wizard should start automatically
637 */
638 public function start_wizard_automatically(){
639
640 $user_id = get_current_user_id();
641 if( ! $user_id ) {
642 return true;
643 }
644
645 $hide_wizard = get_user_meta( $user_id, 'advanced-ads-hide-wizard', true );
646 global $post;
647
648 // true if the wizard was never started or closed
649 return ( ( ! $hide_wizard && 'edit' !== $post->filter ) || 'false'=== $hide_wizard ) ? true : false;
650 }
651
652 /**
653 * Add meta boxes
654 *
655 * @since 1.0.0
656 */
657 public function add_meta_boxes() {
658 add_meta_box(
659 'ad-main-box', __( 'Ad Type', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
660 );
661 // use dynamic filter from to add close class to ad type meta box after saved first time
662 add_filter( 'postbox_classes_advanced_ads_ad-main-box', array( $this, 'close_ad_type_metabox' ) );
663
664 add_meta_box(
665 'ad-parameters-box', __( 'Ad Parameters', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
666 );
667 add_meta_box(
668 'ad-output-box', __( 'Layout / Output', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
669 );
670 add_meta_box(
671 'ad-display-box', __( 'Display Conditions', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
672 );
673 add_meta_box(
674 'ad-visitor-box', __( 'Visitor Conditions', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
675 );
676
677 // register meta box ids
678 $this->meta_box_ids = array(
679 'ad-main-box',
680 'ad-parameters-box',
681 'ad-output-box',
682 'ad-display-box',
683 'ad-visitor-box',
684 'advanced_ads_groupsdiv' // automatically added by ad groups taxonomy
685 );
686
687 // force AA meta boxes to never be completely hidden by screen options
688 add_filter( 'hidden_meta_boxes', array( $this, 'unhide_meta_boxes' ), 10, 2 );
689
690 }
691
692 /**
693 * force all AA related meta boxes to stay visible
694 *
695 * @since 1.7.4.2
696 * @param
697 */
698 public function unhide_meta_boxes( $hidden, $screen ){
699
700 // only check on Advanced Ads edit screen
701 if ( ! isset( $screen->id ) || $screen->id !== 'advanced_ads' || !is_array( $this->meta_box_ids ) ) {
702 return $hidden;
703 }
704
705 // return only hidden elements which are not among the Advanced Ads meta box ids
706 return array_diff( $hidden, $this->meta_box_ids );
707 }
708
709 /**
710 * add "close" class to collapse the ad-type metabox after ad was saved first
711 *
712 * @since 1.7.2
713 * @param arr $classes
714 * @return arr $classes
715 */
716 public function close_ad_type_metabox( $classes = array() ){
717 global $post;
718 if( isset( $post->ID ) && 'edit' === $post->filter ){
719 if( !in_array( 'closed', $classes ) ){
720 $classes[] = 'closed';
721 }
722 } else {
723 $classes = array();
724 }
725 return $classes;
726 }
727
728 /**
729 * add meta values below submit box
730 *
731 * @since 1.3.15
732 */
733 public function add_submit_box_meta(){
734 global $post, $wp_locale;
735
736 if ( $post->post_type !== Advanced_Ads::POST_TYPE_SLUG ) { return; }
737
738 $ad = new Advanced_Ads_Ad( $post->ID );
739
740 // get time set for ad or current timestamp (both GMT)
741 $utc_ts = $ad->expiry_date ? $ad->expiry_date : time();
742 $utc_time = date_create( '@' . $utc_ts );
743 $tz_option = get_option( 'timezone_string' );
744 $exp_time = clone( $utc_time );
745
746 if ( $tz_option ) {
747 $exp_time->setTimezone( self::get_wp_timezone() );
748 } else {
749 $tz_name = self::timezone_get_name( self::get_wp_timezone() );
750 $tz_offset = substr( $tz_name, 3 );
751 $off_time = date_create( $utc_time->format( 'Y-m-d\TH:i:s' ) . $tz_offset );
752 $offset_in_sec = date_offset_get( $off_time );
753 $exp_time = date_create( '@' . ( $utc_ts + $offset_in_sec ) );
754 }
755
756 list( $curr_year, $curr_month, $curr_day, $curr_hour, $curr_minute ) = explode( '-', $exp_time->format( 'Y-m-d-H-i' ) );
757 $enabled = 1 - empty($ad->expiry_date);
758
759 include ADVADS_BASE_PATH . 'admin/views/ad-submitbox-meta.php';
760 }
761
762 /**
763 * load templates for all meta boxes
764 *
765 * @since 1.0.0
766 * @param obj $post
767 * @param array $box
768 * @todo move ad initialization to main function and just global it
769 */
770 public function markup_meta_boxes($post, $box) {
771 $ad = new Advanced_Ads_Ad( $post->ID );
772
773 switch ( $box['id'] ) {
774 case 'ad-main-box':
775 $view = 'ad-main-metabox.php';
776 $hndlelinks = '<a href="' . ADVADS_URL . 'manual/ad-types#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-ad-type" target="_blank">' . __('Manual', 'advanced-ads') . '</a>';
777 break;
778 case 'ad-parameters-box':
779 $view = 'ad-parameters-metabox.php';
780 break;
781 case 'ad-output-box':
782 $view = 'ad-output-metabox.php';
783 break;
784 case 'ad-display-box':
785 $view = 'ad-display-metabox.php';
786 $hndlelinks = '<a href="#" class="advads-video-link">' . __('Video', 'advanced-ads') . '</a>';
787 $hndlelinks .= '<a href="' . ADVADS_URL . 'manual/display-conditions#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-display" target="_blank">' . __('Manual', 'advanced-ads') . '</a>';
788 $videomarkup = '<iframe width="420" height="315" src="https://www.youtube-nocookie.com/embed/wVB6UpeyWNA?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe>';
789 break;
790 case 'ad-visitor-box':
791 $view = 'ad-visitor-metabox.php';
792 $hndlelinks = '<a href="' . ADVADS_URL . 'manual/visitor-conditions#utm_source=advanced-ads&utm_medium=link&utm_campaign=edit-visitor" target="_blank">' . __('Manual', 'advanced-ads') . '</a>';
793 break;
794 }
795
796 if ( ! isset( $view ) ) {
797 return;
798 }
799 // markup moved to handle headline of the metabox
800 if( isset( $hndlelinks ) ){
801 ?><span class="advads-hndlelinks hidden"><?php echo $hndlelinks; ?></span>
802 <?php
803
804 }
805 // show video markup
806 if( isset( $videomarkup ) ){
807 echo '<div class="advads-video-link-container" data-videolink=\'' . $videomarkup . '\'></div>';
808 }
809 include ADVADS_BASE_PATH . 'admin/views/' . $view;
810 }
811
812 /**
813 * prepare the ad post type to be saved
814 *
815 * @since 1.0.0
816 * @param int $post_id id of the post
817 * @todo handling this more dynamic based on ad type
818 */
819 public function save_ad($post_id) {
820
821 // only use for ads, no other post type
822 if ( ! isset($_POST['post_type']) || $this->post_type != $_POST['post_type'] || ! isset($_POST['advanced_ad']['type']) ) {
823 return;
824 }
825
826 // don’t do this on revisions
827 if ( wp_is_post_revision( $post_id ) ) {
828 return;
829 }
830
831 // get ad object
832 $ad = new Advanced_Ads_Ad( $post_id );
833 if ( ! $ad instanceof Advanced_Ads_Ad ) {
834 return;
835 }
836
837 // filter to allow change of submitted ad settings
838 $_POST['advanced_ad'] = apply_filters( 'advanced-ads-ad-settings-pre-save', $_POST['advanced_ad'] );
839
840 $ad->type = $_POST['advanced_ad']['type'];
841 if ( isset($_POST['advanced_ad']['output']) ) {
842 $ad->set_option( 'output', $_POST['advanced_ad']['output'] );
843 } else {
844 $ad->set_option( 'output', array() );
845 }
846 /**
847 * deprecated since introduction of "visitors" in 1.5.4
848 */
849 if ( isset($_POST['advanced_ad']['visitor']) ) {
850 $ad->set_option( 'visitor', $_POST['advanced_ad']['visitor'] );
851 } else {
852 $ad->set_option( 'visitor', array() );
853 }
854 // visitor conditions
855 if ( isset($_POST['advanced_ad']['visitors']) ) {
856 $ad->set_option( 'visitors', $_POST['advanced_ad']['visitors'] );
857 } else {
858 $ad->set_option( 'visitors', array() );
859 }
860 $ad->url = 0;
861 if ( isset($_POST['advanced_ad']['url']) ) {
862 $ad->url = esc_url( $_POST['advanced_ad']['url'] );
863 }
864 // save size
865 $ad->width = 0;
866 if ( isset($_POST['advanced_ad']['width']) ) {
867 $ad->width = absint( $_POST['advanced_ad']['width'] );
868 }
869 $ad->height = 0;
870 if ( isset($_POST['advanced_ad']['height']) ) {
871 $ad->height = absint( $_POST['advanced_ad']['height'] );
872 }
873
874 if ( ! empty($_POST['advanced_ad']['description']) ) {
875 $ad->description = esc_textarea( $_POST['advanced_ad']['description'] ); }
876 else { $ad->description = ''; }
877
878 if ( ! empty($_POST['advanced_ad']['content']) ) {
879 $ad->content = $_POST['advanced_ad']['content']; }
880 else { $ad->content = ''; }
881
882 if ( ! empty($_POST['advanced_ad']['conditions']) ){
883 $ad->conditions = $_POST['advanced_ad']['conditions'];
884 } else {
885 $ad->conditions = array();
886 }
887 // prepare expiry date
888 if ( isset($_POST['advanced_ad']['expiry_date']['enabled']) ) {
889 $year = absint( $_POST['advanced_ad']['expiry_date']['year'] );
890 $month = absint( $_POST['advanced_ad']['expiry_date']['month'] );
891 $day = absint( $_POST['advanced_ad']['expiry_date']['day'] );
892 $hour = absint( $_POST['advanced_ad']['expiry_date']['hour'] );
893 $minute = absint( $_POST['advanced_ad']['expiry_date']['minute'] );
894
895 $expiration_date = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $year, $month, $day, $hour, $minute, '00' );
896 $valid_date = wp_checkdate( $month, $day, $year, $expiration_date );
897
898 if ( !$valid_date ) {
899 $ad->expiry_date = 0;
900 } else {
901 $_gmDate = date_create( $expiration_date, self::get_wp_timezone() );
902 $_gmDate->setTimezone( new DateTimeZone( 'UTC' ) );
903 $gmDate = $_gmDate->format( 'Y-m-d-H-i' );
904 list( $year, $month, $day, $hour, $minute ) = explode( '-', $gmDate );
905 $ad->expiry_date = gmmktime($hour, $minute, 0, $month, $day, $year);
906 }
907 } else {
908 $ad->expiry_date = 0;
909 }
910
911 $image_id = ( isset( $_POST['advanced_ad']['output']['image_id'] ) ) ? absint( $_POST['advanced_ad']['output']['image_id'] ) : 0;
912 if ( $image_id ) {
913 $all_posts_id = get_post_meta( $image_id, '_advanced-ads_parent_id' );
914
915 if ( ! in_array ( $post_id, $all_posts_id ) ) {
916 add_post_meta( $image_id, '_advanced-ads_parent_id', $post_id, false );
917 }
918 }
919
920 $ad->save();
921 }
922
923 /**
924 * prepare the ad post type to be removed
925 *
926 * @param int $post_id id of the post
927 */
928 public function delete_ad( $post_id ) {
929 global $wpdb;
930
931 if ( ! current_user_can( 'delete_posts' ) ) {
932 return;
933 }
934
935 if ( $post_id > 0 ) {
936 $post_type = get_post_type( $post_id );
937 if ( $post_type == $this->post_type ) {
938 $wpdb->query(
939 $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %d", '_advanced-ads_parent_id', $post_id )
940 );
941 }
942 }
943 }
944
945 /**
946 * edit ad update messages
947 *
948 * @since 1.4.7
949 * @param arr $messages existing post update messages
950 * @return arr $messages
951 *
952 * @see wp-admin/edit-form-advanced.php
953 */
954 public function ad_update_messages($messages = array()){
955 $post = get_post();
956
957 // added to hide error message caused by third party code that uses post_updated_messages filter wrong
958 if( ! is_array( $messages )){
959 return $messages;
960 }
961
962 $messages[Advanced_Ads::POST_TYPE_SLUG] = array(
963 0 => '', // Unused. Messages start at index 1.
964 1 => __( 'Ad updated.', 'advanced-ads' ),
965 4 => __( 'Ad updated.', 'advanced-ads' ),
966 /* translators: %s: date and time of the revision */
967 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Ad restored to revision from %s', 'advanced-ads' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
968 6 => __( 'Ad published.', 'advanced-ads' ),
969 7 => __( 'Ad saved.', 'advanced-ads' ),
970 8 => __( 'Ad submitted.', 'advanced-ads' ),
971 9 => sprintf(
972 __( 'Ad scheduled for: <strong>%1$s</strong>.', 'advanced-ads' ),
973 // translators: Publish box date format, see http://php.net/date
974 date_i18n( __( 'M j, Y @ G:i', 'advanced-ads' ), strtotime( $post->post_date ) )
975 ),
976 10 => __( 'Ad draft updated.', 'advanced-ads' )
977 );
978 return $messages;
979 }
980
981 /**
982 * edit ad bulk update messages
983 *
984 * @since 1.4.7
985 * @param arr $messages existing bulk update messages
986 * @param arr $counts numbers of updated ads
987 * @return arr $messages
988 *
989 * @see wp-admin/edit.php
990 */
991 public function ad_bulk_update_messages(array $messages, array $counts){
992 $post = get_post();
993
994 $messages[Advanced_Ads::POST_TYPE_SLUG] = array(
995 'updated' => _n( '%s ad updated.', '%s ads updated.', $counts['updated'] ),
996 'locked' => _n( '%s ad not updated, somebody is editing it.', '%s ads not updated, somebody is editing them.', $counts['locked'] ),
997 'deleted' => _n( '%s ad permanently deleted.', '%s ads permanently deleted.', $counts['deleted'] ),
998 'trashed' => _n( '%s ad moved to the Trash.', '%s ads moved to the Trash.', $counts['trashed'] ),
999 'untrashed' => _n( '%s ad restored from the Trash.', '%s ads restored from the Trash.', $counts['untrashed'] ),
1000 );
1001
1002 return $messages;
1003 }
1004
1005 /**
1006 * get action from the params
1007 *
1008 * @since 1.0.0
1009 */
1010 public function current_action() {
1011 if ( isset($_REQUEST['action']) && -1 != $_REQUEST['action'] ) {
1012 return $_REQUEST['action'];
1013 }
1014
1015 return false;
1016 }
1017
1018 /**
1019 * initialize settings
1020 *
1021 * @since 1.0.1
1022 */
1023 public function settings_init(){
1024
1025 // get settings page hook
1026 $hook = $this->plugin_screen_hook_suffix;
1027
1028 // register settings
1029 register_setting( ADVADS_SLUG, ADVADS_SLUG, array($this, 'sanitize_settings') );
1030
1031 // general settings section
1032 add_settings_section(
1033 'advanced_ads_setting_section',
1034 __( 'General', 'advanced-ads' ),
1035 array($this, 'render_settings_section_callback'),
1036 $hook
1037 );
1038
1039 // licenses section only for main blog
1040 if( is_main_site( get_current_blog_id() ) ){
1041 // register license settings
1042 register_setting( ADVADS_SLUG . '-licenses', ADVADS_SLUG . '-licenses' );
1043
1044 add_settings_section(
1045 'advanced_ads_settings_license_section',
1046 __( 'Licenses', 'advanced-ads' ),
1047 array($this, 'render_settings_licenses_section_callback'),
1048 'advanced-ads-settings-license-page'
1049 );
1050
1051 add_filter( 'advanced-ads-setting-tabs', array( $this, 'license_tab') );
1052 }
1053
1054 // add setting fields to disable ads
1055 add_settings_field(
1056 'disable-ads',
1057 __( 'Disable ads', 'advanced-ads' ),
1058 array($this, 'render_settings_disable_ads'),
1059 $hook,
1060 'advanced_ads_setting_section'
1061 );
1062 // add setting fields for user role
1063 add_settings_field(
1064 'hide-for-user-role',
1065 __( 'Hide ads for logged in users', 'advanced-ads' ),
1066 array($this, 'render_settings_hide_for_users'),
1067 $hook,
1068 'advanced_ads_setting_section'
1069 );
1070 // add setting fields for advanced js
1071 add_settings_field(
1072 'activate-advanced-js',
1073 __( 'Use advanced JavaScript', 'advanced-ads' ),
1074 array($this, 'render_settings_advanced_js'),
1075 $hook,
1076 'advanced_ads_setting_section'
1077 );
1078 // add setting fields for content injection protection
1079 add_settings_field(
1080 'content-injection-everywhere',
1081 __( 'Unlimited ad injection', 'advanced-ads' ),
1082 array($this, 'render_settings_content_injection_everywhere'),
1083 $hook,
1084 'advanced_ads_setting_section'
1085 );
1086 // add setting fields for content injection priority
1087 add_settings_field(
1088 'content-injection-priority',
1089 __( 'Priority of content injection filter', 'advanced-ads' ),
1090 array($this, 'render_settings_content_injection_priority'),
1091 $hook,
1092 'advanced_ads_setting_section'
1093 );
1094 // add setting fields for content injection priority
1095 add_settings_field(
1096 'block-bots',
1097 __( 'Hide ads from bots', 'advanced-ads' ),
1098 array($this, 'render_settings_block_bots'),
1099 $hook,
1100 'advanced_ads_setting_section'
1101 );
1102 // opt out from internal notices
1103 add_settings_field(
1104 'disable-notices',
1105 __( 'Disable notices', 'advanced-ads' ),
1106 array($this, 'render_settings_disabled_notices'),
1107 $hook,
1108 'advanced_ads_setting_section'
1109 );
1110 // opt out from internal notices
1111 add_settings_field(
1112 'front-prefix',
1113 __( 'ID prefix', 'advanced-ads' ),
1114 array($this, 'render_settings_front_prefix'),
1115 $hook,
1116 'advanced_ads_setting_section'
1117 );
1118 // remove id from widgets
1119 add_settings_field(
1120 'remove-widget-id',
1121 __( 'Remove Widget ID', 'advanced-ads' ),
1122 array($this, 'render_settings_remove_widget_id'),
1123 $hook,
1124 'advanced_ads_setting_section'
1125 );
1126 // allow editors to manage ads
1127 add_settings_field(
1128 'editors-manage-ads',
1129 __( 'Allow editors to manage ads', 'advanced-ads' ),
1130 array($this, 'render_settings_editors_manage_ads'),
1131 $hook,
1132 'advanced_ads_setting_section'
1133 );
1134
1135 add_settings_field(
1136 'add-custom-label',
1137 __( 'Ad label', 'advanced-ads' ),
1138 array( $this, 'render_settings_add_custom_label' ),
1139 $hook,
1140 'advanced_ads_setting_section'
1141 );
1142
1143 // hook for additional settings from add-ons
1144 do_action( 'advanced-ads-settings-init', $hook );
1145 }
1146
1147 /**
1148 * add license tab
1149 *
1150 * arr $tabs setting tabs
1151 */
1152 public function license_tab( array $tabs ){
1153
1154 $tabs['licenses'] = array(
1155 'page' => 'advanced-ads-settings-license-page',
1156 'group' => ADVADS_SLUG . '-licenses',
1157 'tabid' => 'licenses',
1158 'title' => __( 'Licenses', 'advanced-ads' )
1159 );
1160
1161 return $tabs;
1162 }
1163
1164 /**
1165 * render settings section
1166 *
1167 * @since 1.1.1
1168 */
1169 public function render_settings_section_callback(){
1170 // for whatever purpose there might come
1171 }
1172
1173 /**
1174 * render licenses settings section
1175 *
1176 * @since 1.5.1
1177 */
1178 public function render_settings_licenses_section_callback(){
1179 echo '<p>'. __( 'Enter license keys for our powerful <a href="'.ADVADS_URL.'add-ons/#utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-licenses" target="_blank">add-ons</a>.', 'advanced-ads' );
1180 echo ' ' . __( 'See also <a href="'.ADVADS_URL.'manual-category/purchase-licenses/#utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-licenses" target="_blank">Issues and questions about licenses</a>', 'advanced-ads' ) .'.</p>';
1181 // nonce field
1182 echo '<input type="hidden" id="advads-licenses-ajax-referrer" value="' . wp_create_nonce( "advads_ajax_license_nonce" ) . '"/>';
1183 }
1184
1185 /**
1186 * options to disable ads
1187 *
1188 * @since 1.3.11
1189 */
1190 public function render_settings_disable_ads(){
1191 $options = Advanced_Ads::get_instance()->options();
1192
1193 // set the variables
1194 $disable_all = isset($options['disabled-ads']['all']) ? 1 : 0;
1195 $disable_404 = isset($options['disabled-ads']['404']) ? 1 : 0;
1196 $disable_archives = isset($options['disabled-ads']['archives']) ? 1 : 0;
1197 $disable_secondary = isset($options['disabled-ads']['secondary']) ? 1 : 0;
1198 $disable_feed = ( ! isset( $options['disabled-ads']['feed'] ) || $options['disabled-ads']['feed'] ) ? 1 : 0;
1199
1200 // load the template
1201 include ADVADS_BASE_PATH . 'admin/views/settings-disable-ads.php';
1202 }
1203
1204 /**
1205 * render setting to hide ads from logged in users
1206 *
1207 * @since 1.1.1
1208 */
1209 public function render_settings_hide_for_users(){
1210 $options = Advanced_Ads::get_instance()->options();
1211 $current_capability_role = isset($options['hide-for-user-role']) ? $options['hide-for-user-role'] : 0;
1212
1213 $capability_roles = array(
1214 '' => __( '(display to all)', 'advanced-ads' ),
1215 'read' => __( 'Subscriber', 'advanced-ads' ),
1216 'delete_posts' => __( 'Contributor', 'advanced-ads' ),
1217 'edit_posts' => __( 'Author', 'advanced-ads' ),
1218 'edit_pages' => __( 'Editor', 'advanced-ads' ),
1219 'activate_plugins' => __( 'Admin', 'advanced-ads' ),
1220 );
1221 echo '<select name="'.ADVADS_SLUG.'[hide-for-user-role]">';
1222 foreach ( $capability_roles as $_capability => $_role ) {
1223 echo '<option value="'.$_capability.'" '.selected( $_capability, $current_capability_role, false ).'>'.$_role.'</option>';
1224 }
1225 echo '</select>';
1226
1227 echo '<p class="description">'. __( 'Choose the lowest role a user must have in order to not see any ads.', 'advanced-ads' ) .'</p>';
1228 }
1229
1230 /**
1231 * render setting to display advanced js file
1232 *
1233 * @since 1.2.3
1234 */
1235 public function render_settings_advanced_js(){
1236 $options = Advanced_Ads::get_instance()->options();
1237 $checked = ( ! empty($options['advanced-js'])) ? 1 : 0;
1238
1239 // display notice if js file was overridden
1240 if( ! $checked && apply_filters( 'advanced-ads-activate-advanced-js', $checked ) ){
1241 echo '<p>' . __( '<strong>notice: </strong>the file is currently enabled by an add-on that needs it.', 'advanced-ads' ) . '</p>';
1242 }
1243 echo '<input id="advanced-ads-advanced-js" type="checkbox" value="1" name="'.ADVADS_SLUG.'[advanced-js]" '.checked( $checked, 1, false ).'>';
1244 echo '<p class="description">'. sprintf( __( 'Enable advanced JavaScript functions (<a href="%s" target="_blank">here</a>). Some features and add-ons might override this setting if they need features from this file.', 'advanced-ads' ), ADVADS_URL . 'javascript-functions/#utm_source=advanced-ads&utm_medium=link&utm_campaign=settings' ) .'</p>';
1245 }
1246
1247 /**
1248 * render setting for content injection protection
1249 *
1250 * @since 1.4.1
1251 */
1252 public function render_settings_content_injection_everywhere(){
1253 $options = Advanced_Ads::get_instance()->options();
1254 $everywhere = ( isset($options['content-injection-everywhere']) ) ? true : false;
1255
1256 echo '<input id="advanced-ads-injection-everywhere" type="checkbox" value="true" name="'.ADVADS_SLUG.'[content-injection-everywhere]" '.checked( $everywhere, true, false ).'>';
1257 echo '<p class="description">'. __( 'Some plugins and themes trigger ad injection where it shouldn’t happen. Therefore, Advanced Ads ignores injected placements on non-singular pages and outside the loop. However, this can cause problems with some themes. You can enable this option if you don’t see ads or want to enable ad injections on archive pages AT YOUR OWN RISK.', 'advanced-ads' ) .'</p>';
1258
1259 }
1260
1261 /**
1262 * render setting for content injection priority
1263 *
1264 * @since 1.4.1
1265 */
1266 public function render_settings_content_injection_priority(){
1267 $options = Advanced_Ads::get_instance()->options();
1268 $priority = ( isset($options['content-injection-priority'])) ? intval( $options['content-injection-priority'] ) : 100;
1269
1270 echo '<input id="advanced-ads-content-injection-priority" type="number" value="'.$priority.'" name="'.ADVADS_SLUG.'[content-injection-priority]" size="3"/>';
1271 echo '<p class="description">';
1272 if ( $priority < 11 ) {
1273 echo '<span class="advads-error-message">' . __( 'Please check your post content. A priority of 10 and below might cause issues (wpautop function might run twice).', 'advanced-ads' ) . '</span><br />';
1274 }
1275 _e( 'Play with this value in order to change the priority of the injected ads compared to other auto injected elements in the post content.', 'advanced-ads' );
1276 echo '</p>';
1277 }
1278
1279 /**
1280 * render setting for blocking bots
1281 *
1282 * @since 1.4.9
1283 */
1284 public function render_settings_block_bots(){
1285 $options = Advanced_Ads::get_instance()->options();
1286 $checked = ( ! empty($options['block-bots'])) ? 1 : 0;
1287
1288 echo '<input id="advanced-ads-block-bots" type="checkbox" value="1" name="'.ADVADS_SLUG.'[block-bots]" '.checked( $checked, 1, false ).'>';
1289 echo '<p class="description">'. sprintf( __( 'Hide ads from crawlers, bots and empty user agents. Also prevents counting impressions for bots when using the <a href="%s" target="_blank">Tracking Add-On</a>.', 'advanced-ads' ), ADVADS_URL . 'add-ons/tracking/#utm_source=advanced-ads&utm_medium=link&utm_campaign=settings' ) .'<br/>'
1290 . __( 'Disabling this option only makes sense if your ads contain content you want to display to bots (like search engines) or your site is cached and bots could create a cached version without the ads.', 'advanced-ads' ) . '</p>';
1291 }
1292
1293 /**
1294 * render setting to disable notices
1295 *
1296 * @since 1.5.3
1297 */
1298 public function render_settings_disabled_notices(){
1299 $options = Advanced_Ads::get_instance()->options();
1300 $checked = ( ! empty($options['disable-notices'])) ? 1 : 0;
1301
1302 echo '<input id="advanced-ads-disabled-notices" type="checkbox" value="1" name="'.ADVADS_SLUG.'[disable-notices]" '.checked( $checked, 1, false ).'>';
1303 echo '<p class="description">'. __( 'Disable internal notices like tips, tutorials, email newsletters and update notices. Disabling notices is recommended if you run multiple blogs with Advanced Ads already.', 'advanced-ads' ) . '</p>';
1304 }
1305
1306 /**
1307 * render setting for frontend prefix
1308 *
1309 * @since 1.6.8
1310 */
1311 public function render_settings_front_prefix(){
1312 $options = Advanced_Ads::get_instance()->options();
1313
1314 $prefix = Advanced_Ads_Plugin::get_instance()->get_frontend_prefix();
1315 $old_prefix = ( isset($options['id-prefix'])) ? esc_attr( $options['id-prefix'] ) : '';
1316
1317 echo '<input id="advanced-ads-front-prefix" type="text" value="' .$prefix .'" name="'.ADVADS_SLUG.'[front-prefix]" />';
1318 // deprecated
1319 echo '<input type="hidden" value="' .$old_prefix .'" name="'.ADVADS_SLUG.'[id-prefix]" />';
1320 echo '<p class="description">'. __( 'Prefix of class or id attributes in the frontend. Change it if you don’t want <strong>ad blockers</strong> to mark these blocks as ads.<br/>You might need to <strong>rewrite css rules afterwards</strong>.', 'advanced-ads' ) .'</p>';
1321 }
1322
1323 /**
1324 * render setting to remove the id from advanced ads widgets
1325 *
1326 * @since 1.6.8.2
1327 */
1328 public function render_settings_remove_widget_id(){
1329 $options = Advanced_Ads::get_instance()->options();
1330
1331 // is true by default if no options where previously set
1332 if( ! isset($options['remove-widget-id']) && $options !== array() ){
1333 $remove = false;
1334 } elseif( $options === array() ){
1335 $remove = true;
1336 } else {
1337 $remove = true;
1338 }
1339
1340 echo '<input id="advanced-ads-remove-widget-id" type="checkbox" ' . checked( $remove, true, false ) . ' name="'.ADVADS_SLUG.'[remove-widget-id]" />';
1341 echo '<p class="description">' . __( 'Remove the ID attribute from widgets in order to not make them an easy target of ad blockers.', 'advanced-ads' );
1342
1343 if ( class_exists( 'q2w3_fixed_widget', false ) ) {
1344 echo '<br />' . __( 'If checked, the Advanced Ads Widget will not work with the fixed option of the <strong>Q2W3 Fixed Widget</strong> plugin.', 'advanced-ads' );
1345 }
1346
1347 echo '</p>';
1348 }
1349
1350 /**
1351 * render setting to allow editors to manage ads
1352 *
1353 * @since 1.6.14
1354 */
1355 public function render_settings_editors_manage_ads(){
1356 $options = Advanced_Ads::get_instance()->options();
1357
1358 // is false by default if no options where previously set
1359 if( isset($options['editors-manage-ads']) && $options['editors-manage-ads'] ){
1360 $allow = true;
1361 } else {
1362 $allow = false;
1363 }
1364
1365 echo '<input id="advanced-ads-editors-manage-ads" type="checkbox" ' . checked( $allow, true, false ) . ' name="'.ADVADS_SLUG.'[editors-manage-ads]" />';
1366 echo '<p class="description">'. __( 'Allow editors to also manage and publish ads.', 'advanced-ads' ) .
1367 ' ' . sprintf(__( 'You can assign different ad-related roles on a user basis with <a href="%s" target="_blank">Advanced Ads Pro</a>.', 'advanced-ads' ), ADVADS_URL . 'add-ons/advanced-ads-pro/#utm_source=advanced-ads&utm_medium=link&utm_campaign=settings') . '</p>';
1368
1369 }
1370
1371 /**
1372 * render setting to add an "Advertisement" label before ads
1373 *
1374 */
1375 public function render_settings_add_custom_label(){
1376 $options = Advanced_Ads::get_instance()->options();
1377
1378 $enabled = isset( $options['custom-label']['enabled'] );
1379 $label = ! empty ( $options['custom-label']['text'] ) ? esc_html( $options['custom-label']['text'] ) : _x( 'Advertisements', 'label before ads' );
1380 ?>
1381
1382 <fieldset>
1383 <input type="checkbox" <?php checked( $enabled, true ); ?> value="1" onclick="advads_toggle_box( this, '#advads-custom-label' );" name="<?php echo ADVADS_SLUG . '[custom-label][enabled]'; ?>" />
1384 <input <?php if ( ! $enabled ) echo 'style="display:none;"' ?> id="advads-custom-label" type="text" value="<?php echo $label; ?>" name="<?php echo ADVADS_SLUG . '[custom-label][text]'; ?>" />
1385 </fieldset>
1386 <p class="description"><?php _e( 'Displayed above ads.', 'advanced-ads' ); ?>&nbsp;<a target="_blank" href="<?php echo ADVADS_URL . 'manual/advertisement-label/#utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-advertisement-label'?>"><?php _e( 'Manual', 'advanced-ads' ); ?></a></p>
1387
1388 <?php
1389 }
1390
1391 /**
1392 * sanitize plugin settings
1393 *
1394 * @since 1.5.1
1395 * @param array $options all the options
1396 */
1397 public function sanitize_settings($options){
1398
1399 // sanitize whatever option one wants to sanitize
1400
1401 if ( isset( $options['front-prefix'] ) ) {
1402 $options['front-prefix'] = sanitize_html_class( $options['front-prefix'], Advanced_Ads_Plugin::DEFAULT_FRONTEND_PREFIX );
1403 }
1404
1405 $options = apply_filters( 'advanced-ads-sanitize-settings', $options );
1406
1407 // check if editors can edit ads now and set the rights
1408 // else, remove that right
1409 $editor_role = get_role( 'editor' );
1410 if( null == $editor_role ){
1411 return $options;
1412 }
1413 if( isset($options['editors-manage-ads']) && $options['editors-manage-ads'] ){
1414 $editor_role->add_cap( 'advanced_ads_see_interface' );
1415 $editor_role->add_cap( 'advanced_ads_edit_ads' );
1416 $editor_role->add_cap( 'advanced_ads_manage_placements' );
1417 $editor_role->add_cap( 'advanced_ads_place_ads' );
1418 } else {
1419 $editor_role->remove_cap( 'advanced_ads_see_interface' );
1420 $editor_role->remove_cap( 'advanced_ads_edit_ads' );
1421 $editor_role->remove_cap( 'advanced_ads_manage_placements' );
1422 $editor_role->remove_cap( 'advanced_ads_place_ads' );
1423 }
1424
1425 // we need 3 states: ! isset, 1, 0
1426 $options['disabled-ads']['feed'] = isset( $options['disabled-ads']['feed'] ) ? 1 : 0;
1427
1428 return $options;
1429 }
1430
1431 /**
1432 * add heading for extra column of ads list
1433 * remove the date column
1434 *
1435 * @since 1.3.3
1436 * @param arr $columns
1437 */
1438 public function ad_list_columns_head( $columns ){
1439
1440 $new_columns = array();
1441 foreach( $columns as $key => $value ) {
1442 $new_columns[ $key ] = $value;
1443 if ( $key == 'title' ){
1444 $new_columns[ 'ad_details' ] = __( 'Ad Details', 'advanced-ads' );
1445 $new_columns[ 'ad_timing' ] = __( 'Ad Planning', 'advanced-ads' );
1446 }
1447 }
1448
1449 // white-listed columns
1450 $whitelist = apply_filters( 'advanced-ads-ad-list-allowed-columns', array(
1451 'cb', // checkbox
1452 'title',
1453 'ad_details',
1454 'ad_timing',
1455 'taxonomy-advanced_ads_groups',
1456 ) );
1457
1458 // remove non-white-listed columns
1459 foreach( $new_columns as $_key => $_value ){
1460 if( ! in_array( $_key, $whitelist ) ){
1461 unset( $new_columns[ $_key ] );
1462 }
1463 }
1464
1465 return $new_columns;
1466 }
1467
1468 /**
1469 * order ads by title on ads list
1470 *
1471 * @since 1.3.18
1472 * @param arr $vars array with request vars
1473 */
1474 public function ad_list_request($vars){
1475
1476 // order ads by title on ads list
1477 if ( is_admin() && empty( $vars['orderby'] ) && $this->post_type == $vars['post_type'] ) {
1478 $vars = array_merge( $vars, array(
1479 'orderby' => 'title',
1480 'order' => 'ASC'
1481 ) );
1482 }
1483
1484 return $vars;
1485 }
1486
1487 /**
1488 * display ad details in ads list
1489 *
1490 * @since 1.3.3
1491 * @param string $column_name name of the column
1492 * @param int $ad_id id of the ad
1493 */
1494 public function ad_list_columns_content($column_name, $ad_id) {
1495 if ( $column_name == 'ad_details' ) {
1496 $ad = new Advanced_Ads_Ad( $ad_id );
1497
1498 // load ad type title
1499 $types = Advanced_Ads::get_instance()->ad_types;
1500 $type = ( ! empty($types[$ad->type]->title)) ? $types[$ad->type]->title : 0;
1501
1502 // load ad size
1503 $size = 0;
1504 if ( ! empty($ad->width) || ! empty($ad->height) ) {
1505 $size = sprintf( '%d x %d', $ad->width, $ad->height );
1506 }
1507
1508 $size = apply_filters( 'advanced-ads-list-ad-size', $size, $ad );
1509
1510 include ADVADS_BASE_PATH . 'admin/views/ad-list-details-column.php';
1511 }
1512 }
1513
1514 /**
1515 * display ad details in ads list
1516 *
1517 * @since 1.6.11
1518 * @param string $column_name name of the column
1519 * @param int $ad_id id of the ad
1520 */
1521 public function ad_list_columns_timing($column_name, $ad_id) {
1522
1523 if ( $column_name == 'ad_timing' ) {
1524 $ad = new Advanced_Ads_Ad( $ad_id );
1525
1526 $expiry = false;
1527 $post_future = false;
1528 $post_start = get_the_date('U', $ad->id );
1529 $html_classes = 'advads-filter-timing';
1530 $expiry_date_format = get_option( 'date_format' ). ', ' . get_option( 'time_format' );
1531
1532 if( isset( $ad->expiry_date ) && $ad->expiry_date ){
1533 $html_classes .= ' advads-filter-any-exp-date';
1534
1535 $expiry = $ad->expiry_date;
1536 if( $ad->expiry_date < time() ){
1537 $html_classes .= ' advads-filter-expired';
1538 }
1539 }
1540 if( $post_start > time() ){
1541 $post_future = $post_start;
1542 $html_classes .= ' advads-filter-future';
1543 }
1544
1545 include ADVADS_BASE_PATH . 'admin/views/ad-list-timing-column.php';
1546 }
1547 }
1548
1549 /**
1550 * adds filter dropdowns before the 'Filter' button on the ad list table
1551 */
1552 function ad_list_add_filters() {
1553 $screen = get_current_screen();
1554 if ( ! isset( $screen->id ) || $screen->id !== 'edit-advanced_ads' ) {
1555 return;
1556 }
1557
1558 include ADVADS_BASE_PATH . 'admin/views/ad-list-filters.php';
1559 }
1560
1561 /**
1562 * add a meta box to post type edit screens with ad settings
1563 *
1564 * @since 1.3.10
1565 * @param string $post_type current post type
1566 */
1567 public function add_post_meta_box($post_type = ''){
1568 // don’t display for non admins
1569 if( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads') ) ) {
1570 return;
1571 }
1572
1573 // get public post types
1574 $public_post_types = get_post_types( array('public' => true, 'publicly_queryable' => true), 'names', 'or' );
1575
1576 //limit meta box to public post types
1577 if ( in_array( $post_type, $public_post_types ) ) {
1578 add_meta_box(
1579 'advads-ad-settings',
1580 __( 'Ad Settings', 'advanced-ads' ),
1581 array( $this, 'render_post_meta_box' ),
1582 $post_type,
1583 'advanced',
1584 'low'
1585 );
1586 }
1587 }
1588
1589 /**
1590 * render meta box for ad settings on a per post basis
1591 *
1592 * @since 1.3.10
1593 * @param WP_Post $post The post object.
1594 */
1595 public function render_post_meta_box( $post ) {
1596
1597 // nonce field to check when we save the values
1598 wp_nonce_field( 'advads_post_meta_box', 'advads_post_meta_box_nonce' );
1599
1600 // retrieve an existing value from the database.
1601 $values = get_post_meta( $post->ID, '_advads_ad_settings', true );
1602
1603 // load the view
1604 include ADVADS_BASE_PATH . 'admin/views/post-ad-settings-metabox.php';
1605 }
1606
1607 /**
1608 * save the ad meta when the post is saved.
1609 *
1610 * @since 1.3.10
1611 * @param int $post_id The ID of the post being saved.
1612 */
1613 public function save_post_meta_box( $post_id ) {
1614
1615 if( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads') ) ) {
1616 return;
1617 }
1618
1619 // check nonce
1620 if ( ! isset( $_POST['advads_post_meta_box_nonce'] ) ) {
1621 return $post_id; }
1622
1623 $nonce = $_POST['advads_post_meta_box_nonce'];
1624
1625 // Verify that the nonce is valid.
1626 if ( ! wp_verify_nonce( $nonce, 'advads_post_meta_box' ) ) {
1627 return $post_id; }
1628
1629 // don’t save on autosave
1630 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
1631 return $post_id; }
1632
1633 // check the user's permissions.
1634 if ( 'page' == $_POST['post_type'] ) {
1635 if ( ! current_user_can( 'edit_page', $post_id ) ) {
1636 return $post_id; }
1637 } else {
1638 if ( ! current_user_can( 'edit_post', $post_id ) ) {
1639 return $post_id; }
1640 }
1641
1642 // Sanitize the user input.
1643 $_data['disable_ads'] = isset($_POST['advanced_ads']['disable_ads']) ? absint( $_POST['advanced_ads']['disable_ads'] ) : 0;
1644
1645 // Update the meta field.
1646 update_post_meta( $post_id, '_advads_ad_settings', $_data );
1647 }
1648
1649 /**
1650 * add dashboard widget with ad stats and additional information
1651 *
1652 * @since 1.3.12
1653 */
1654 public function add_dashboard_widget(){
1655 // display dashboard widget only to authors and higher roles
1656 if( ! current_user_can('publish_posts') ) {
1657 return;
1658 }
1659 add_meta_box( 'advads_dashboard_widget', __( 'Ads Dashboard', 'advanced-ads' ), array($this, 'dashboard_widget_function'), 'dashboard', 'side', 'high' );
1660 }
1661
1662 /**
1663 * display widget functions
1664 */
1665 public static function dashboard_widget_function($post, $callback_args){
1666 // load ad optimization feed
1667 $feeds = array(
1668 array(
1669 'link' => 'http://webgilde.com/en/ad-optimization/',
1670 'url' => 'http://webgilde.com/en/ad-optimization/feed/',
1671 'title' => __( 'From the ad optimization universe', 'advanced-ads' ),
1672 'items' => 2,
1673 'show_summary' => 0,
1674 'show_author' => 0,
1675 'show_date' => 0,
1676 ),
1677 array(
1678 'link' => ADVADS_URL,
1679 'url' => ADVADS_URL . 'feed/',
1680 'title' => __( 'Advanced Ads Tutorials', 'advanced-ads' ),
1681 'items' => 2,
1682 'show_summary' => 0,
1683 'show_author' => 0,
1684 'show_date' => 0,
1685 ),
1686 );
1687
1688 // get number of ads
1689 $recent_ads = Advanced_Ads::get_instance()->get_model()->get_ads();
1690 echo '<p>';
1691 printf(__( '%d ads – <a href="%s">manage</a> - <a href="%s">new</a>', 'advanced-ads' ),
1692 count( $recent_ads ),
1693 'edit.php?post_type='. Advanced_Ads::POST_TYPE_SLUG,
1694 'post-new.php?post_type='. Advanced_Ads::POST_TYPE_SLUG);
1695 echo '</p>';
1696
1697 // get and display plugin version
1698 $advads_plugin_data = get_plugin_data( ADVADS_BASE_PATH . 'advanced-ads.php' );
1699 if ( isset($advads_plugin_data['Version']) ){
1700 $version = $advads_plugin_data['Version'];
1701 echo '<p><a href="'.ADVADS_URL.'#utm_source=advanced-ads&utm_medium=link&utm_campaign=dashboard" target="_blank" title="'.
1702 __( 'plugin manual and homepage', 'advanced-ads' ).'">Advanced Ads</a> '. $version .'</p>';
1703 }
1704
1705 $notice_options = Advanced_Ads_Admin_Notices::get_instance()->options();
1706 $_notice = 'nl_first_steps';
1707 if ( ! isset($notice_options['closed'][ $_notice ] ) ) {
1708 ?><div class="advads-admin-notice">
1709 <p><button type="button" class="button-primary advads-notices-button-subscribe" data-notice="<?php echo $_notice ?>"><?php _e('Get the tutorial via email', 'advanced-ads'); ?></button></p>
1710 </div><?php
1711 }
1712
1713 $_notice = 'nl_adsense';
1714 if ( ! isset($notice_options['closed'][ $_notice ] ) ) {
1715 ?><div class="advads-admin-notice">
1716 <p><button type="button" class="button-primary advads-notices-button-subscribe" data-notice="<?php echo $_notice ?>"><?php _e('Get AdSense tips via email', 'advanced-ads'); ?></button></p>
1717 </div><?php
1718 }
1719
1720 // rss feed
1721 // $this->dashboard_widget_function_output('advads_dashboard_widget', $feed);
1722 self::dashboard_cached_rss_widget( 'advads_dashboard_widget', array('Advanced_Ads_Admin', 'dashboard_widget_function_output'), array('advads' => $feeds) );
1723 }
1724
1725 /**
1726 * checks to see if there are feed urls in transient cache; if not, load them
1727 * built using a lot of https://developer.wordpress.org/reference/functions/wp_dashboard_cached_rss_widget/
1728 *
1729 * @since 1.3.12
1730 * @param string $widget_id
1731 * @param callback $callback
1732 * @param array $check_urls RSS feeds
1733 * @return bool False on failure. True on success.
1734 */
1735 static function dashboard_cached_rss_widget( $widget_id, $callback, $feeds = array() ) {
1736 if ( empty($feeds) ) {
1737 return;
1738 }
1739
1740 $cache_key = 'dash_' . md5( $widget_id );
1741 if ( false !== ( $output = get_transient( $cache_key ) ) ) {
1742 echo $output;
1743 return true;
1744 }
1745 if ( $callback && is_callable( $callback ) ) {
1746 ob_start();
1747 call_user_func_array( $callback, $feeds );
1748 set_transient( $cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS ); // Default lifetime in cache of 12 hours (same as the feeds)
1749 }
1750
1751 return true;
1752 }
1753
1754 /**
1755 * create the rss output of the widget
1756 *
1757 * @param string $widget_id Widget ID.
1758 * @param array $feeds Array of RSS feeds.
1759 */
1760 static function dashboard_widget_function_output( $feeds ) {
1761 foreach ( $feeds as $_feed ){
1762 echo '<div class="rss-widget">';
1763 echo '<h4>'.$_feed['title'].'</h4>';
1764 wp_widget_rss_output( $_feed['url'], $_feed );
1765 echo '</div>';
1766 }
1767 }
1768
1769 /**
1770 * get DateTimeZone object for the WP installation
1771 */
1772 public static function get_wp_timezone() {
1773 $_time_zone = get_option( 'timezone_string' );
1774 $time_zone = new DateTimeZone( 'UTC' );
1775 if ( $_time_zone ) {
1776 $time_zone = new DateTimeZone( $_time_zone );
1777 } else {
1778 $gmt_offset = floatval( get_option( 'gmt_offset' ) );
1779 $sign = ( 0 > $gmt_offset )? '-' : '+';
1780 $int = floor( abs( $gmt_offset ) );
1781 $frac = abs( $gmt_offset ) - $int;
1782
1783 $gmt = '';
1784 if ( $gmt_offset ) {
1785 $gmt .= $sign . zeroise( $int, 2 ) . ':' . zeroise( 60 * $frac, 2 );
1786 $time_zone = date_create( '2017-10-01T12:00:00' . $gmt )->getTimezone();
1787 }
1788
1789 }
1790 return $time_zone;
1791 }
1792
1793 /**
1794 * get literal expression of timezone
1795 */
1796 public static function timezone_get_name( $DTZ ) {
1797 if ( $DTZ instanceof DateTimeZone ) {
1798 $TZ = timezone_name_get( $DTZ );
1799 if ( 'UTC' == $TZ ) {
1800 return 'UTC+0';
1801 }
1802 if ( false === strpos( $TZ, '/' ) ) {
1803 $TZ = 'UTC' . $TZ;
1804 } else {
1805 $TZ = sprintf( __( 'time of %s', 'advanced-ads' ), $TZ );
1806 }
1807 return $TZ;
1808 }
1809 return 'UTC+0';
1810 }
1811
1812 /**
1813 * initiate the admin notices class
1814 *
1815 * @since 1.5.3
1816 */
1817 public function admin_notices(){
1818 // display ad block warning to everyone who can edit ads
1819 if( current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads') ) ) {
1820 if ( $this->screen_belongs_to_advanced_ads() ){
1821 include ADVADS_BASE_PATH . 'admin/views/notices/adblock.php';
1822 include ADVADS_BASE_PATH . 'admin/views/notices/jqueryui_error.php';
1823 }
1824 }
1825
1826 if( current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads') ) ) {
1827 $this->notices = Advanced_Ads_Admin_Notices::get_instance()->notices;
1828 Advanced_Ads_Admin_Notices::get_instance()->display_notices();
1829 }
1830 }
1831
1832 /**
1833 * save license key
1834 *
1835 * @since 1.2.0
1836 * @param string $addon string with addon identifier
1837 */
1838 public function activate_license( $addon = '', $plugin_name = '', $options_slug = '', $license_key = '' ) {
1839
1840 if ( '' === $addon || '' === $plugin_name || '' === $options_slug ) {
1841 return __( 'Error while trying to register the license. Please contact support.', 'advanced-ads' );
1842 }
1843
1844 $license_key = esc_attr( trim( $license_key ) );
1845 if ( '' == $license_key ) {
1846 return __( 'Please enter a valid license key', 'advanced-ads' );
1847 }
1848
1849 // check if license was already activated and abort activation if so
1850 /*if( $this->check_license($license_key, $plugin_name, $options_slug)){
1851 return 1;
1852 }*/
1853
1854 $api_params = array(
1855 'edd_action'=> 'activate_license',
1856 'license' => $license_key,
1857 'item_name' => urlencode( $plugin_name ),
1858 'url' => home_url()
1859 );
1860 // Call the custom API.
1861 $response = wp_remote_post( ADVADS_URL, array(
1862 'timeout' => 15,
1863 'sslverify' => false,
1864 'body' => $api_params
1865 ) );
1866
1867 if ( is_wp_error( $response ) ) {
1868 $body = wp_remote_retrieve_body( $response );
1869 if ( $body ){
1870 return $body;
1871 } else {
1872 return __( 'License couldn’t be activated. Please try again later.', 'advanced-ads' );
1873 }
1874 }
1875
1876 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
1877 // save license status
1878 update_option($options_slug . '-license-status', $license_data->license, false);
1879
1880 // display activation problem
1881 if( !empty( $license_data->error )) {
1882 // user friendly texts for errors
1883 $errors = array(
1884 'license_not_activable' => __( 'This is the bundle license key.', 'advanced-ads' ),
1885 'item_name_mismatch' => __( 'This is not the correct key for this add-on.', 'advanced-ads' ),
1886 'no_activations_left' => __( 'There are no activations left.', 'advanced-ads' )
1887 );
1888 $error = isset( $errors[ $license_data->error ] ) ? $errors[ $license_data->error ] : $license_data->error;
1889 if( 'expired' === $license_data->error ){
1890 return 'ex';
1891 } else {
1892 if( isset($errors[ $license_data->error ] ) ) {
1893 return $error;
1894 } else {
1895 return sprintf( __('License is invalid. Reason: %s'), $error);
1896 }
1897 }
1898 } else {
1899 // save license value time
1900 update_option($options_slug . '-license-expires', $license_data->expires, false);
1901 // reset license_expires admin notification
1902 Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue( 'license_expires' );
1903 Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue( 'license_expired' );
1904 Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue( 'license_invalid' );
1905 // save license key
1906 $licenses = $this->get_licenses();
1907 $licenses[ $addon ] = $license_key;
1908 $this->save_licenses( $licenses );
1909 }
1910
1911 return 1;
1912 }
1913
1914 /**
1915 * check if a specific license key was already activated for the current page
1916 *
1917 * @since 1.6.17
1918 * @return bool true if already activated
1919 * @deprecated since version 1.7.2 because it only checks if a key is valid, not if the url registered with that key
1920 */
1921 public function check_license( $license_key = '', $plugin_name = '', $options_slug = '' ){
1922
1923 $api_params = array(
1924 'edd_action' => 'check_license',
1925 'license' => $license_key,
1926 'item_name' => urlencode( $plugin_name )
1927 );
1928 $response = wp_remote_get( add_query_arg( $api_params, ADVADS_URL ), array( 'timeout' => 15, 'sslverify' => false ) );
1929 if ( is_wp_error( $response ) ) {
1930 return false;
1931 }
1932 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
1933
1934 // if this license is still valid
1935 if( $license_data->license == 'valid' ) {
1936 update_option($options_slug . '-license-expires', $license_data->expires, false);
1937 update_option($options_slug . '-license-status', $license_data->license, false);
1938
1939 return true;
1940 }
1941 return false;
1942 }
1943
1944 /**
1945 * deactivate license key
1946 *
1947 * @since 1.6.11
1948 * @param string $addon string with addon identifier
1949 */
1950 public function deactivate_license( $addon = '', $plugin_name = '', $options_slug = '' ) {
1951
1952 if ( '' === $addon || '' === $plugin_name || '' === $options_slug ) {
1953 return __( 'Error while trying to disable the license. Please contact support.', 'advanced-ads' );
1954 }
1955
1956 $licenses = $this->get_licenses();
1957 $license_key = isset($licenses[$addon]) ? $licenses[$addon] : '';
1958
1959 $api_params = array(
1960 'edd_action' => 'deactivate_license',
1961 'license' => $license_key,
1962 'item_name' => urlencode( $plugin_name )
1963 );
1964 // Send the remote request
1965 $response = wp_remote_post( ADVADS_URL, array(
1966 'body' => $api_params,
1967 'timeout' => 15,
1968 'sslverify' => false,
1969 ) );
1970
1971 if ( is_wp_error( $response ) ) {
1972 $body = wp_remote_retrieve_body( $response );
1973 if ( $body ){
1974 return $body;
1975 } else {
1976 return __( 'License couldn’t be deactivated. Please try again later.', 'advanced-ads' );
1977 }
1978 }
1979
1980 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
1981
1982 // save license status
1983
1984 // remove data
1985 if( 'deactivated' === $license_data->license ) {
1986 delete_option( $options_slug . '-license-status' );
1987 delete_option( $options_slug . '-license-expires' );
1988 Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue( 'license_expires' );
1989 } elseif( 'failed' === $license_data->license ) {
1990 update_option($options_slug . '-license-expires', $license_data->expires, false);
1991 update_option($options_slug . '-license-status', $license_data->license, false);
1992 return 'ex';
1993 } else {
1994 return __( 'License couldn’t be deactivated. Please try again later.', 'advanced-ads' );
1995 }
1996
1997 return 1;
1998 }
1999
2000 /**
2001 * get license keys for all add-ons
2002 *
2003 * @since 1.6.15
2004 * @return arr $licenses licenses
2005 */
2006 public function get_licenses(){
2007
2008 $licenses = array();
2009
2010 if( is_multisite() ){
2011 // if multisite, get option from main blog
2012 global $current_site;
2013 $licenses = get_blog_option( $current_site->blog_id, ADVADS_SLUG . '-licenses', array() );
2014
2015 } else {
2016 $licenses = get_option( ADVADS_SLUG . '-licenses', array() );
2017 }
2018
2019 return $licenses;
2020 }
2021
2022 /**
2023 * save license keys for all add-ons
2024 *
2025 * @since 1.7.2
2026 * @return arr $licenses licenses
2027 */
2028 public function save_licenses( $licenses = array() ){
2029
2030 if( is_multisite() ){
2031 // if multisite, get option from main blog
2032 global $current_site;
2033 update_blog_option( $current_site->blog_id, ADVADS_SLUG . '-licenses', $licenses );
2034 } else {
2035 update_option( ADVADS_SLUG . '-licenses', $licenses );
2036 }
2037 }
2038
2039 /**
2040 * get license status of an add-on
2041 *
2042 * @since 1.6.15
2043 * @param str $slug slug of the add-on
2044 * @return str $status license status, e.g. "valid" or "invalid"
2045 */
2046 public function get_license_status( $slug = '' ){
2047
2048 $status = false;
2049
2050 if( is_multisite() ){
2051 // if multisite, get option from main blog
2052 global $current_site;
2053 $status = get_blog_option( $current_site->blog_id, $slug . '-license-status', false);
2054 } else {
2055 $status = get_option( $slug . '-license-status', false);
2056 }
2057
2058 return $status;
2059 }
2060
2061 /**
2062 * get license expired value of an add-on
2063 *
2064 * @since 1.6.15
2065 * @param str $slug slug of the add-on
2066 * @return str $date expiry date of an add-on
2067 */
2068 public function get_license_expires( $slug = '' ){
2069
2070 $date = false;
2071
2072 if( is_multisite() ){
2073 // if multisite, get option from main blog
2074 global $current_site;
2075 $date = get_blog_option( $current_site->blog_id, $slug . '-license-expires', false);
2076 } else {
2077 $date = get_option( $slug . '-license-expires', false);
2078 }
2079
2080 return $date;
2081 }
2082
2083
2084 /*
2085 * add-on updater
2086 *
2087 * @since 1.5.7
2088 */
2089 public function add_on_updater(){
2090
2091 // ignore, if not main blog
2092 if( is_multisite() && ! is_main_site() ){
2093 return;
2094 }
2095
2096 /**
2097 * list of registered add ons
2098 * contains:
2099 * name
2100 * version
2101 * path
2102 * options_slug
2103 * short option slug (=key)
2104 */
2105 $add_ons = apply_filters( 'advanced-ads-add-ons', array() );
2106
2107 if( $add_ons === array() ) {
2108 return;
2109 }
2110
2111 foreach( $add_ons as $_add_on_key => $_add_on ){
2112
2113 // check if a license expired over time
2114 $expiry_date = $this->get_license_expires( $_add_on['options_slug'] );
2115 $now = time();
2116 if( $expiry_date && strtotime( $expiry_date ) < $now ){
2117 // remove license status
2118 delete_option( $_add_on['options_slug'] . '-license-status' );
2119 continue;
2120 }
2121
2122 // check status
2123 if( $this->get_license_status( $_add_on['options_slug'] ) !== 'valid' ) {
2124 continue;
2125 }
2126
2127 // retrieve our license key from the DB
2128 $licenses = get_option(ADVADS_SLUG . '-licenses', array());
2129 $license_key = isset($licenses[$_add_on_key]) ? $licenses[$_add_on_key] : '';
2130
2131 // setup the updater
2132 if( $license_key ){
2133 new EDD_SL_Plugin_Updater( ADVADS_URL, $_add_on['path'], array(
2134 'version' => $_add_on['version'],
2135 'license' => $license_key,
2136 'item_name' => $_add_on['name'],
2137 'author' => 'Thomas Maier'
2138 )
2139 );
2140 }
2141 }
2142 }
2143
2144 /**
2145 * add links to the plugins list
2146 *
2147 * @since 1.6.14
2148 * @param arr $links array of links for the plugins, adapted when the current plugin is found.
2149 * @param str $file the filename for the current plugin, which the filter loops through.
2150 * @return array $links
2151 */
2152 function add_plugin_links( $links ) {
2153 // add link to support page
2154 $support_link = '<a href="' . esc_url( admin_url( 'admin.php?page=advanced-ads-support' ) ) . '">' . __( 'Support', 'advanced-ads' ) . '</a>';
2155 array_unshift( $links, $support_link );
2156
2157 // add link to add-ons
2158 $extend_link = '<a href="' . ADVADS_URL . 'add-ons/#utm_source=advanced-ads&utm_medium=link&utm_campaign=plugin-page" target="_blank">' . __( 'Add-Ons', 'advanced-ads' ) . '</a>';
2159 array_unshift( $links, $extend_link );
2160
2161 return $links;
2162 }
2163
2164 /**
2165 * display message when someone is going to disable the plugin
2166 *
2167 * @since 1.6.14
2168 */
2169 function display_deactivation_message(){
2170
2171 // get email address
2172 $current_user = wp_get_current_user();
2173 if ( !($current_user instanceof WP_User) ){
2174 $email = '';
2175 } else {
2176 $email = trim( $current_user->user_email );
2177 }
2178
2179 include ADVADS_BASE_PATH . 'admin/views/feedback_disable.php';
2180 }
2181 }
2182