Advanced Ads - Version 1.7.5.1

Version Description

  • add and remove ads in groups in the group overview page
  • separated admin code into multiple files for better overview
  • log possible content injection errors only for admin users in the frontend
  • double error messages hidden on plugin support page
Download this release

Release Info

Developer webzunft
Plugin Icon 128x128 Advanced Ads
Version 1.7.5.1
Comparing to
See all releases

Code changes from version 1.7.5 to 1.7.5.1

admin/assets/css/admin.css CHANGED
@@ -165,6 +165,7 @@ select + .advads-conditions-single { display: inline-block; }
165
  #advads-ad-group-list .row-actions span + span::before { content: '|'; padding: 0 3px; }
166
  #advads-ad-group-list ul, #advads-ad-group-list ol { margin: 0; list-style-position: inside; }
167
  #advads-ad-group-list tbody tr:nth-child(4n+1) { background: #f9f9f9; }
 
168
  .advads-ad-group-list-ads li { margin: 0; padding: 3px 0; }
169
  .advads-ad-group-list-ads li:hover { background: #eee; }
170
  .advads-ad-group-list-ads i { margin-left: 1em; font-style: italic; }
@@ -178,6 +179,7 @@ select + .advads-conditions-single { display: inline-block; }
178
  .advads-ad-group-form strong { float: left; width: 180px; }
179
  .advads-ad-group-form ul { float: left; }
180
  .advads-ad-group-list-ads li { padding-bottom: 10px; }
 
181
 
182
  /**
183
  AD PLACEMENTS
165
  #advads-ad-group-list .row-actions span + span::before { content: '|'; padding: 0 3px; }
166
  #advads-ad-group-list ul, #advads-ad-group-list ol { margin: 0; list-style-position: inside; }
167
  #advads-ad-group-list tbody tr:nth-child(4n+1) { background: #f9f9f9; }
168
+ #advads-ad-group-list .advads-group-ads tr:nth-child(odd) { background: #f9f9f9; }
169
  .advads-ad-group-list-ads li { margin: 0; padding: 3px 0; }
170
  .advads-ad-group-list-ads li:hover { background: #eee; }
171
  .advads-ad-group-list-ads i { margin-left: 1em; font-style: italic; }
179
  .advads-ad-group-form strong { float: left; width: 180px; }
180
  .advads-ad-group-form ul { float: left; }
181
  .advads-ad-group-list-ads li { padding-bottom: 10px; }
182
+ fieldset.advads-group-add-ad { margin-top: 1em; }
183
 
184
  /**
185
  AD PLACEMENTS
admin/assets/js/admin.js CHANGED
@@ -219,9 +219,41 @@ jQuery( document ).ready(function ($) {
219
  }
220
  });
221
 
222
- /**
223
- * SETTINGS PAGE
224
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
 
226
  // activate licenses
227
  $('.advads-license-activate').click(function(){
@@ -312,10 +344,13 @@ jQuery( document ).ready(function ($) {
312
  }
313
  });
314
  });
 
 
 
315
 
316
  /**
317
- * PLACEMENTS
318
- */
319
 
320
  // show image tooltips
321
  if ( $.fn.tooltip ) {
219
  }
220
  });
221
 
222
+ // group page: add ad to group
223
+ $( '.advads-group-add-ad button' ).click( function() {
224
+ var $settings_row = $( this ).closest( '.advads-ad-group-form' ),
225
+ $ad = $settings_row.find( '.advads-group-add-ad-list-ads option:selected' )
226
+ $weight_selector = $settings_row.find( '.advads-group-add-ad-list-weights' ).last(),
227
+ $ad_table = $settings_row.find( '.advads-group-ads tbody' );
228
+ // add new row if does not already exist
229
+ if ( $ad.length && $weight_selector.length && ! $ad_table.find( '[name="' + $ad.val() + '"]' ).length ) {
230
+ $ad_table.append(
231
+ $( '<tr></tr>' ).append(
232
+ $( '<td></td>' ).html( $ad.text() ),
233
+ $( '<td></td>' ).append( $weight_selector.clone().val( $weight_selector.val() ).prop( 'name', $ad.val() ) ),
234
+ '<td><button type="button" class="advads-remove-ad-from-group button">x</button></td>'
235
+ )
236
+ );
237
+ }
238
+ });
239
+ // group page: remove ad from group
240
+ $( '#advads-ad-group-list' ).on( 'click', '.advads-remove-ad-from-group', function() {
241
+ var $ad_row = $( this ).closest( 'tr' );
242
+
243
+ if ( $ad_row.data( 'ad-id' ) ) {
244
+ // save the ad id, it is needed when this ad is not included in any other group
245
+ $( '#advads-ad-group-list form' ).append(
246
+ '<input type="hidden" name="advads-groups-removed-ads[]" value="' + $ad_row.data( 'ad-id' ) + '">'
247
+ );
248
+ }
249
+ $ad_row.remove();
250
+ });
251
+
252
+
253
+
254
+ /**
255
+ * SETTINGS PAGE
256
+ */
257
 
258
  // activate licenses
259
  $('.advads-license-activate').click(function(){
344
  }
345
  });
346
  });
347
+
348
+
349
+
350
 
351
  /**
352
+ * PLACEMENTS
353
+ */
354
 
355
  // show image tooltips
356
  if ( $.fn.tooltip ) {
admin/class-advanced-ads-admin.php CHANGED
@@ -43,1759 +43,201 @@ class Advanced_Ads_Admin {
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
- add_action( 'all_admin_notices', array($this, 'no_ads_yet_notice') );
145
-
146
- // Add an action link pointing to the options page.
147
- $plugin_basename = plugin_basename( plugin_dir_path( '__DIR__' ) . $this->plugin_slug . '.php' );
148
- add_filter( 'plugin_action_links_' . $plugin_basename, array($this, 'add_action_links') );
149
-
150
- // add meta box for post types edit pages
151
- add_action( 'add_meta_boxes', array( $this, 'add_post_meta_box' ) );
152
- add_action( 'save_post', array( $this, 'save_post_meta_box' ) );
153
-
154
- // register dashboard widget
155
- add_action( 'wp_dashboard_setup', array($this, 'add_dashboard_widget') );
156
-
157
- // set 1 column layout on overview page as user and page option
158
- add_filter( 'screen_layout_columns', array('Advanced_Ads_Overview_Widgets_Callbacks', 'one_column_overview_page') );
159
- add_filter( 'get_user_option_screen_layout_toplevel_page_advanced', array( 'Advanced_Ads_Overview_Widgets_Callbacks', 'one_column_overview_page_user') );
160
-
161
- // add links to plugin page
162
- add_filter( 'plugin_action_links_' . ADVADS_BASE, array( $this, 'add_plugin_links' ) );
163
- // display information when user is going to disable the plugin
164
- // add_filter( 'after_plugin_row_' . ADVADS_BASE, array( $this, 'display_deactivation_message' ) );
165
- }
166
-
167
- /**
168
- * Return an instance of this class.
169
- *
170
- * @since 1.0.0
171
- *
172
- * @return object A single instance of this class.
173
- */
174
- public static function get_instance() {
175
-
176
- // If the single instance hasn't been set, set it now.
177
- if ( null == self::$instance ) {
178
- self::$instance = new self;
179
- }
180
-
181
- return self::$instance;
182
- }
183
-
184
- /**
185
- * Register and enqueue admin-specific style sheet.
186
- *
187
- * @since 1.0.0
188
- */
189
- public function enqueue_admin_styles() {
190
- wp_enqueue_style( $this->plugin_slug . '-admin-styles', plugins_url( 'assets/css/admin.css', __FILE__ ), array(), ADVADS_VERSION );
191
- if( self::screen_belongs_to_advanced_ads() ){
192
- // jQuery ui smoothness style 1.11.4
193
- wp_enqueue_style( $this->plugin_slug . '-jquery-ui-styles', plugins_url( 'assets/jquery-ui/jquery-ui.min.css', __FILE__ ), array(), '1.11.4' );
194
- }
195
- //wp_enqueue_style( 'jquery-style', '//code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css' );
196
- }
197
-
198
- /**
199
- * Register and enqueue admin-specific JavaScript.
200
- *
201
- * @since 1.0.0
202
- *
203
- * @return null Return early if no settings page is registered.
204
- */
205
- public function enqueue_admin_scripts() {
206
-
207
- // global js script
208
- wp_enqueue_script( $this->plugin_slug . '-admin-global-script', plugins_url( 'assets/js/admin-global.js', __FILE__ ), array('jquery'), ADVADS_VERSION );
209
-
210
- if( self::screen_belongs_to_advanced_ads() ){
211
- wp_register_script( $this->plugin_slug . '-admin-script', plugins_url( 'assets/js/admin.js', __FILE__ ), array( 'jquery', 'jquery-ui-autocomplete' , 'jquery-ui-button' ), ADVADS_VERSION );
212
- wp_register_script( $this->plugin_slug . '-wizard-script', plugins_url( 'assets/js/wizard.js', __FILE__ ), array('jquery'), ADVADS_VERSION );
213
-
214
- // jquery ui
215
- wp_enqueue_script( 'jquery-ui-accordion' );
216
- wp_enqueue_script( 'jquery-ui-button' );
217
- wp_enqueue_script( 'jquery-ui-tooltip' );
218
-
219
- // just register this script for later inclusion on ad group list page
220
- wp_register_script( 'inline-edit-group-ads', plugins_url( 'assets/js/inline-edit-group-ads.js', __FILE__ ), array('jquery'), ADVADS_VERSION );
221
-
222
- // register admin.js translations
223
- $translation_array = array(
224
- 'condition_or' => __( 'or', 'advanced-ads' ),
225
- 'condition_and' => __( 'and', 'advanced-ads' ),
226
- 'after_paragraph_promt' => __( 'After which paragraph?', 'advanced-ads' ),
227
- );
228
- wp_localize_script( $this->plugin_slug . '-admin-script', 'advadstxt', $translation_array );
229
-
230
- wp_enqueue_script( $this->plugin_slug . '-admin-script' );
231
- wp_enqueue_script( $this->plugin_slug . '-wizard-script' );
232
- }
233
-
234
- //call media manager for image upload only on ad edit pages
235
- $screen = get_current_screen();
236
- if( isset( $screen->id ) && Advanced_Ads::POST_TYPE_SLUG === $screen->id ) {
237
- // the 'wp_enqueue_media' function can be executed only once and should be called with the 'post' parameter
238
- // 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.
239
- // since other plugins can call the 'wp_enqueue_media' function without the 'post' parameter, Advanced Ads should call it earlier.
240
- global $post;
241
- wp_enqueue_media( array( 'post' => $post ) );
242
- }
243
-
244
- }
245
-
246
- /**
247
- * check if the current screen belongs to Advanced Ads
248
- *
249
- * @since 1.6.6
250
- * @return bool true if screen belongs to Advanced Ads
251
- */
252
- static function screen_belongs_to_advanced_ads(){
253
-
254
- if( ! function_exists( 'get_current_screen' ) ){
255
- return false;
256
- }
257
-
258
- $screen = get_current_screen();
259
- //echo $screen->id;
260
- if( !isset( $screen->id ) ) {
261
- return false;
262
- }
263
-
264
- $advads_pages = apply_filters( 'advanced-ads-dashboard-screens', array(
265
- 'advanced-ads_page_advanced-ads-groups', // ad groups
266
- 'edit-advanced_ads', // ads overview
267
- 'advanced_ads', // ad edit page
268
- 'advanced-ads_page_advanced-ads-placements', // placements
269
- 'advanced-ads_page_advanced-ads-settings', // settings
270
- 'toplevel_page_advanced-ads', // overview
271
- 'admin_page_advanced-ads-debug', // debug
272
- 'advanced-ads_page_advanced-ads-support', // support
273
- 'admin_page_advanced-ads-intro', // intro
274
- 'admin_page_advanced-ads-import-export', // import & export
275
- ));
276
-
277
- if( in_array( $screen->id, $advads_pages )){
278
- return true;
279
- }
280
-
281
- return false;
282
- }
283
-
284
- /**
285
- * Register the administration menu for this plugin into the WordPress Dashboard menu.
286
- *
287
- * @since 1.0.0
288
- */
289
- public function add_plugin_admin_menu() {
290
-
291
- // add main menu item with overview page
292
- add_menu_page(
293
- __( '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'
294
- );
295
-
296
- add_submenu_page(
297
- $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
298
- );
299
-
300
- // hidden by css; not placed in 'options.php' in order to highlight the correct item, see the 'highlight_menu_item()'
301
- if ( ! current_user_can( 'edit_posts' ) ) {
302
- add_submenu_page(
303
- $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
304
- );
305
- }
306
-
307
- $this->ad_group_hook_suffix = add_submenu_page(
308
- $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')
309
- );
310
-
311
- // add placements page
312
- add_submenu_page(
313
- $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')
314
- );
315
- // add settings page
316
- $this->plugin_screen_hook_suffix = add_submenu_page(
317
- $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')
318
- );
319
- add_submenu_page(
320
- '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')
321
- );
322
- // intro page
323
- add_submenu_page(
324
- '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')
325
- );
326
- // add support page
327
- add_submenu_page(
328
- $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')
329
- );
330
-
331
- // allows extensions to insert sub menu pages
332
- do_action( 'advanced-ads-submenu-pages', $this->plugin_slug );
333
- }
334
-
335
- /**
336
- * Highlights the 'Advanced Ads->Ads' item in the menu when an ad edit page is open
337
- * @see the 'parent_file' and the 'submenu_file' filters for reference
338
- */
339
- public function highlight_menu_item() {
340
- global $parent_file, $submenu_file, $post_type;
341
- if ( $post_type === $this->post_type ) {
342
- $parent_file = $this->plugin_slug;
343
- $submenu_file = 'edit.php?post_type=' . $this->post_type;
344
- }
345
- }
346
-
347
- /**
348
- * Render the overview page
349
- *
350
- * @since 1.2.2
351
- */
352
- public function display_overview_page() {
353
-
354
- $screen = get_current_screen();
355
-
356
- // set up overview widgets
357
- Advanced_Ads_Overview_Widgets_Callbacks::setup_overview_widgets( $screen );
358
-
359
- // convert from vertical order to horizontal
360
- $screen->add_option( 'layout_columns', 1 );
361
-
362
- include ADVADS_BASE_PATH . 'admin/views/overview.php';
363
- }
364
-
365
- /**
366
- * Render the settings page
367
- *
368
- * @since 1.0.0
369
- */
370
- public function display_plugin_settings_page() {
371
- include ADVADS_BASE_PATH . 'admin/views/settings.php';
372
- }
373
-
374
- /**
375
- * Render the placements page
376
- *
377
- * @since 1.1.0
378
- */
379
- public function display_placements_page() {
380
- $placement_types = Advanced_Ads_Placements::get_placement_types();
381
- $placements = Advanced_Ads::get_ad_placements_array(); // -TODO use model
382
- $items = Advanced_Ads_Placements::items_for_select();
383
- // load ads and groups for select field
384
-
385
- // display view
386
- include ADVADS_BASE_PATH . 'admin/views/placements.php';
387
- }
388
-
389
- /**
390
- * Render the debug page
391
- *
392
- * @since 1.0.1
393
- */
394
- public function display_plugin_debug_page() {
395
- // load array with ads by condition
396
- $plugin = Advanced_Ads::get_instance();
397
- $plugin_options = $plugin->options();
398
- $ad_placements = Advanced_Ads::get_ad_placements_array(); // -TODO use model
399
-
400
- include ADVADS_BASE_PATH . 'admin/views/debug.php';
401
- }
402
-
403
- /**
404
- * Render intro page
405
- *
406
- * @since 1.6.8.2
407
- */
408
- public function display_plugin_intro_page() {
409
- // load array with ads by condition
410
-
411
- // remove intro message from queue
412
- Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue('nl_intro');
413
-
414
- include ADVADS_BASE_PATH . 'admin/views/intro.php';
415
- }
416
-
417
- /**
418
- * Render the support page
419
- *
420
- * @since 1.6.8.1
421
- */
422
- public function display_support_page() {
423
- // process email
424
-
425
- $mail_sent = false;
426
- $sent_errors = array();
427
- global $current_user;
428
- $user = wp_get_current_user();
429
-
430
- $email = $user->user_email !== '' ? $user->user_email : '';
431
- $name = $user->first_name !== '' ? $user->first_name . ' ' . $user->last_name : $user->user_login;
432
- $message = '';
433
-
434
- if( isset( $_POST['advads_support']['email'] ) ){
435
-
436
- $email = trim( $_POST['advads_support']['email'] );
437
- $name = trim( $_POST['advads_support']['name'] );
438
- $message = trim( $_POST['advads_support']['message'] );
439
- if( '' === $message ){
440
- $sent_errors[] = __('Please enter a message', 'advanced-ads');
441
- }
442
- if( is_email( $email ) ){
443
- $headers = 'From: '. $name .' <' . $email . '>' . "\r\n";
444
- $content = $message;
445
- $content .= "\r\n\r\n Name: " . $name;
446
- $content .= "\r\n URL: " . home_url();
447
-
448
- $mail_sent = wp_mail( 'support@wpadvancedads.com', 'Support for ' . home_url(), $content, $headers );
449
- if( ! $mail_sent ){
450
- $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>');
451
- }
452
- } else {
453
- $sent_errors[] = __('Please enter a valid email address', 'advanced-ads');
454
- }
455
- }
456
-
457
- include ADVADS_BASE_PATH . 'admin/views/support.php';
458
- }
459
-
460
- /**
461
- * Render the ad group page
462
- *
463
- * @since 1.0.0
464
- */
465
- public function ad_group_admin_page() {
466
-
467
- $taxonomy = Advanced_Ads::AD_GROUP_TAXONOMY;
468
- $post_type = Advanced_Ads::POST_TYPE_SLUG;
469
- $tax = get_taxonomy( $taxonomy );
470
-
471
- $action = $this->current_action();
472
-
473
- // handle new and updated groups
474
- if ( 'editedgroup' == $action ) {
475
- $group_id = (int) $_POST['group_id'];
476
- check_admin_referer( 'update-group_' . $group_id );
477
-
478
- if ( ! current_user_can( $tax->cap->edit_terms ) ) {
479
- wp_die( __( 'Sorry, you are not allowed to access this feature.', 'advanced-ads' ) ); }
480
-
481
- // handle new groups
482
- if ( 0 == $group_id ) {
483
- $ret = wp_insert_term( $_POST['name'], $taxonomy, $_POST );
484
- if ( $ret && ! is_wp_error( $ret ) ) {
485
- $forced_message = 1; }
486
- else {
487
- $forced_message = 4; }
488
- // handle group updates
489
- } else {
490
- $tag = get_term( $group_id, $taxonomy );
491
- if ( ! $tag ) {
492
- wp_die( __( 'You attempted to edit an ad group that doesn&#8217;t exist. Perhaps it was deleted?', 'advanced-ads' ) ); }
493
-
494
- $ret = wp_update_term( $group_id, $taxonomy, $_POST );
495
- if ( $ret && ! is_wp_error( $ret ) ) {
496
- $forced_message = 3; }
497
- else {
498
- $forced_message = 5; }
499
- }
500
- // deleting items
501
- } elseif ( $action == 'delete' ){
502
- $group_id = (int) $_REQUEST['group_id'];
503
- check_admin_referer( 'delete-tag_' . $group_id );
504
-
505
- if ( ! current_user_can( $tax->cap->delete_terms ) ) {
506
- wp_die( __( 'Sorry, you are not allowed to access this feature.', 'advanced-ads' ) ); }
507
-
508
- wp_delete_term( $group_id, $taxonomy );
509
-
510
- $forced_message = 2;
511
- }
512
-
513
- // handle views
514
- switch ( $action ) {
515
- case 'edit' :
516
- $title = $tax->labels->edit_item;
517
- if ( isset($_REQUEST['group_id']) ) {
518
- $group_id = absint( $_REQUEST['group_id'] );
519
- $tag = get_term( $group_id, $taxonomy, OBJECT, 'edit' );
520
- } else {
521
- $group_id = 0;
522
- $tag = false;
523
- }
524
-
525
- include ADVADS_BASE_PATH . 'admin/views/ad-group-edit.php';
526
- break;
527
-
528
- default :
529
- $title = $tax->labels->name;
530
- $wp_list_table = _get_list_table( 'WP_Terms_List_Table' );
531
-
532
- // load template
533
- include ADVADS_BASE_PATH . 'admin/views/ad-group.php';
534
- }
535
- }
536
-
537
- /**
538
- * returns a link to the ad group list page
539
- *
540
- * @since 1.0.0
541
- * @param arr $args additional arguments, e.g. action or group_id
542
- * @return string admin url
543
- */
544
- static function group_page_url($args = array()) {
545
- $plugin = Advanced_Ads::get_instance();
546
-
547
- $defaultargs = array(
548
- // 'post_type' => constant("Advanced_Ads::POST_TYPE_SLUG"),
549
- 'page' => 'advanced-ads-groups',
550
- );
551
- $args = $args + $defaultargs;
552
-
553
- return add_query_arg( $args, admin_url( 'admin.php' ) );
554
- }
555
-
556
- /**
557
- * Add settings action link to the plugins page.
558
- *
559
- * @since 1.0.0
560
- */
561
- public function add_action_links($links) {
562
-
563
- return array_merge(
564
- array(
565
- 'settings' => '<a href="' . admin_url( 'edit.php?post_type=advanced_ads&page=advanced-ads-settings' ) . '">' . __( 'Settings', 'advanced-ads' ) . '</a>'
566
- ), $links
567
- );
568
- }
569
-
570
- /**
571
- * add information above the ad title
572
- *
573
- * @since 1.5.6
574
- * @param obj $post
575
- */
576
- public function edit_form_above_title($post){
577
- if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
578
- return;
579
- }
580
- $ad = new Advanced_Ads_Ad( $post->ID );
581
-
582
- include ADVADS_BASE_PATH . 'admin/views/ad-info-top.php';
583
- }
584
-
585
- /**
586
- * add information about the ad below the ad title
587
- *
588
- * @since 1.1.0
589
- * @param obj $post
590
- */
591
- public function edit_form_below_title($post){
592
- if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
593
- return;
594
- }
595
- $ad = new Advanced_Ads_Ad( $post->ID );
596
-
597
- include ADVADS_BASE_PATH . 'admin/views/ad-info.php';
598
- }
599
-
600
- /**
601
- * add information below the ad edit form
602
- *
603
- * @since 1.7.3
604
- * @param obj $post
605
- */
606
- public function edit_form_end($post){
607
- if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
608
- return;
609
- }
610
-
611
- include ADVADS_BASE_PATH . 'admin/views/ad-info-bottom.php';
612
- }
613
-
614
- /**
615
- * whether to show the wizard welcome message or not
616
- *
617
- * @since 1.7.4
618
- * @return bool true, if wizard welcome message should be displayed
619
- */
620
- public function show_wizard_welcome(){
621
-
622
- $user_id = get_current_user_id();
623
- if( ! $user_id ) {
624
- return true;
625
- }
626
-
627
- $hide_wizard = get_user_meta( $user_id, 'advanced-ads-hide-wizard', true );
628
- global $post;
629
-
630
- return ( ! $hide_wizard && 'edit' !== $post->filter ) ? true : false;
631
- }
632
-
633
- /**
634
- * whether to start the wizard by default or not
635
- *
636
- * @since 1.7.4
637
- * return bool true, if wizard should start automatically
638
- */
639
- public function start_wizard_automatically(){
640
-
641
- $user_id = get_current_user_id();
642
- if( ! $user_id ) {
643
- return true;
644
- }
645
-
646
- $hide_wizard = get_user_meta( $user_id, 'advanced-ads-hide-wizard', true );
647
- global $post;
648
-
649
- // true if the wizard was never started or closed
650
- return ( ( ! $hide_wizard && 'edit' !== $post->filter ) || 'false'=== $hide_wizard ) ? true : false;
651
- }
652
-
653
- /**
654
- * Add meta boxes
655
- *
656
- * @since 1.0.0
657
- */
658
- public function add_meta_boxes() {
659
- add_meta_box(
660
- 'ad-main-box', __( 'Ad Type', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
661
- );
662
- // use dynamic filter from to add close class to ad type meta box after saved first time
663
- add_filter( 'postbox_classes_advanced_ads_ad-main-box', array( $this, 'close_ad_type_metabox' ) );
664
-
665
- add_meta_box(
666
- 'ad-parameters-box', __( 'Ad Parameters', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
667
- );
668
- add_meta_box(
669
- 'ad-output-box', __( 'Layout / Output', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
670
- );
671
- add_meta_box(
672
- 'ad-display-box', __( 'Display Conditions', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
673
- );
674
- add_meta_box(
675
- 'ad-visitor-box', __( 'Visitor Conditions', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
676
- );
677
-
678
- // register meta box ids
679
- $this->meta_box_ids = array(
680
- 'ad-main-box',
681
- 'ad-parameters-box',
682
- 'ad-output-box',
683
- 'ad-display-box',
684
- 'ad-visitor-box',
685
- 'advanced_ads_groupsdiv' // automatically added by ad groups taxonomy
686
- );
687
-
688
- // force AA meta boxes to never be completely hidden by screen options
689
- add_filter( 'hidden_meta_boxes', array( $this, 'unhide_meta_boxes' ), 10, 2 );
690
-
691
- }
692
-
693
- /**
694
- * force all AA related meta boxes to stay visible
695
- *
696
- * @since 1.7.4.2
697
- * @param
698
- */
699
- public function unhide_meta_boxes( $hidden, $screen ){
700
-
701
- // only check on Advanced Ads edit screen
702
- if ( ! isset( $screen->id ) || $screen->id !== 'advanced_ads' || !is_array( $this->meta_box_ids ) ) {
703
- return $hidden;
704
- }
705
-
706
- // return only hidden elements which are not among the Advanced Ads meta box ids
707
- return array_diff( $hidden, $this->meta_box_ids );
708
- }
709
-
710
- /**
711
- * add "close" class to collapse the ad-type metabox after ad was saved first
712
- *
713
- * @since 1.7.2
714
- * @param arr $classes
715
- * @return arr $classes
716
- */
717
- public function close_ad_type_metabox( $classes = array() ){
718
- global $post;
719
- if( isset( $post->ID ) && 'edit' === $post->filter ){
720
- if( !in_array( 'closed', $classes ) ){
721
- $classes[] = 'closed';
722
- }
723
- } else {
724
- $classes = array();
725
- }
726
- return $classes;
727
- }
728
-
729
- /**
730
- * add meta values below submit box
731
- *
732
- * @since 1.3.15
733
- */
734
- public function add_submit_box_meta(){
735
- global $post, $wp_locale;
736
-
737
- if ( $post->post_type !== Advanced_Ads::POST_TYPE_SLUG ) { return; }
738
-
739
- $ad = new Advanced_Ads_Ad( $post->ID );
740
-
741
- // get time set for ad or current timestamp (both GMT)
742
- $utc_ts = $ad->expiry_date ? $ad->expiry_date : time();
743
- $utc_time = date_create( '@' . $utc_ts );
744
- $tz_option = get_option( 'timezone_string' );
745
- $exp_time = clone( $utc_time );
746
-
747
- if ( $tz_option ) {
748
- $exp_time->setTimezone( self::get_wp_timezone() );
749
- } else {
750
- $tz_name = self::timezone_get_name( self::get_wp_timezone() );
751
- $tz_offset = substr( $tz_name, 3 );
752
- $off_time = date_create( $utc_time->format( 'Y-m-d\TH:i:s' ) . $tz_offset );
753
- $offset_in_sec = date_offset_get( $off_time );
754
- $exp_time = date_create( '@' . ( $utc_ts + $offset_in_sec ) );
755
- }
756
-
757
- list( $curr_year, $curr_month, $curr_day, $curr_hour, $curr_minute ) = explode( '-', $exp_time->format( 'Y-m-d-H-i' ) );
758
- $enabled = 1 - empty($ad->expiry_date);
759
-
760
- include ADVADS_BASE_PATH . 'admin/views/ad-submitbox-meta.php';
761
- }
762
-
763
- /**
764
- * load templates for all meta boxes
765
- *
766
- * @since 1.0.0
767
- * @param obj $post
768
- * @param array $box
769
- * @todo move ad initialization to main function and just global it
770
- */
771
- public function markup_meta_boxes($post, $box) {
772
- $ad = new Advanced_Ads_Ad( $post->ID );
773
-
774
- switch ( $box['id'] ) {
775
- case 'ad-main-box':
776
- $view = 'ad-main-metabox.php';
777
- $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>';
778
- break;
779
- case 'ad-parameters-box':
780
- $view = 'ad-parameters-metabox.php';
781
- break;
782
- case 'ad-output-box':
783
- $view = 'ad-output-metabox.php';
784
- break;
785
- case 'ad-display-box':
786
- $view = 'ad-display-metabox.php';
787
- $hndlelinks = '<a href="#" class="advads-video-link">' . __('Video', 'advanced-ads') . '</a>';
788
- $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>';
789
- $videomarkup = '<iframe width="420" height="315" src="https://www.youtube-nocookie.com/embed/wVB6UpeyWNA?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe>';
790
- break;
791
- case 'ad-visitor-box':
792
- $view = 'ad-visitor-metabox.php';
793
- $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>';
794
- break;
795
- }
796
-
797
- if ( ! isset( $view ) ) {
798
- return;
799
- }
800
- // markup moved to handle headline of the metabox
801
- if( isset( $hndlelinks ) ){
802
- ?><span class="advads-hndlelinks hidden"><?php echo $hndlelinks; ?></span>
803
- <?php
804
-
805
- }
806
- // show video markup
807
- if( isset( $videomarkup ) ){
808
- echo '<div class="advads-video-link-container" data-videolink=\'' . $videomarkup . '\'></div>';
809
- }
810
- include ADVADS_BASE_PATH . 'admin/views/' . $view;
811
- }
812
-
813
- /**
814
- * prepare the ad post type to be saved
815
- *
816
- * @since 1.0.0
817
- * @param int $post_id id of the post
818
- * @todo handling this more dynamic based on ad type
819
- */
820
- public function save_ad($post_id) {
821
-
822
- // only use for ads, no other post type
823
- if ( ! isset($_POST['post_type']) || $this->post_type != $_POST['post_type'] || ! isset($_POST['advanced_ad']['type']) ) {
824
- return;
825
- }
826
-
827
- // don’t do this on revisions
828
- if ( wp_is_post_revision( $post_id ) ) {
829
- return;
830
- }
831
-
832
- // get ad object
833
- $ad = new Advanced_Ads_Ad( $post_id );
834
- if ( ! $ad instanceof Advanced_Ads_Ad ) {
835
- return;
836
- }
837
-
838
- // filter to allow change of submitted ad settings
839
- $_POST['advanced_ad'] = apply_filters( 'advanced-ads-ad-settings-pre-save', $_POST['advanced_ad'] );
840
-
841
- $ad->type = $_POST['advanced_ad']['type'];
842
- if ( isset($_POST['advanced_ad']['output']) ) {
843
- $ad->set_option( 'output', $_POST['advanced_ad']['output'] );
844
- } else {
845
- $ad->set_option( 'output', array() );
846
- }
847
- /**
848
- * deprecated since introduction of "visitors" in 1.5.4
849
- */
850
- if ( isset($_POST['advanced_ad']['visitor']) ) {
851
- $ad->set_option( 'visitor', $_POST['advanced_ad']['visitor'] );
852
- } else {
853
- $ad->set_option( 'visitor', array() );
854
- }
855
- // visitor conditions
856
- if ( isset($_POST['advanced_ad']['visitors']) ) {
857
- $ad->set_option( 'visitors', $_POST['advanced_ad']['visitors'] );
858
- } else {
859
- $ad->set_option( 'visitors', array() );
860
- }
861
- $ad->url = 0;
862
- if ( isset($_POST['advanced_ad']['url']) ) {
863
- $ad->url = esc_url( $_POST['advanced_ad']['url'] );
864
- }
865
- // save size
866
- $ad->width = 0;
867
- if ( isset($_POST['advanced_ad']['width']) ) {
868
- $ad->width = absint( $_POST['advanced_ad']['width'] );
869
- }
870
- $ad->height = 0;
871
- if ( isset($_POST['advanced_ad']['height']) ) {
872
- $ad->height = absint( $_POST['advanced_ad']['height'] );
873
- }
874
-
875
- if ( ! empty($_POST['advanced_ad']['description']) ) {
876
- $ad->description = esc_textarea( $_POST['advanced_ad']['description'] ); }
877
- else { $ad->description = ''; }
878
-
879
- if ( ! empty($_POST['advanced_ad']['content']) ) {
880
- $ad->content = $_POST['advanced_ad']['content']; }
881
- else { $ad->content = ''; }
882
-
883
- if ( ! empty($_POST['advanced_ad']['conditions']) ){
884
- $ad->conditions = $_POST['advanced_ad']['conditions'];
885
- } else {
886
- $ad->conditions = array();
887
- }
888
- // prepare expiry date
889
- if ( isset($_POST['advanced_ad']['expiry_date']['enabled']) ) {
890
- $year = absint( $_POST['advanced_ad']['expiry_date']['year'] );
891
- $month = absint( $_POST['advanced_ad']['expiry_date']['month'] );
892
- $day = absint( $_POST['advanced_ad']['expiry_date']['day'] );
893
- $hour = absint( $_POST['advanced_ad']['expiry_date']['hour'] );
894
- $minute = absint( $_POST['advanced_ad']['expiry_date']['minute'] );
895
-
896
- $expiration_date = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $year, $month, $day, $hour, $minute, '00' );
897
- $valid_date = wp_checkdate( $month, $day, $year, $expiration_date );
898
-
899
- if ( !$valid_date ) {
900
- $ad->expiry_date = 0;
901
- } else {
902
- $_gmDate = date_create( $expiration_date, self::get_wp_timezone() );
903
- $_gmDate->setTimezone( new DateTimeZone( 'UTC' ) );
904
- $gmDate = $_gmDate->format( 'Y-m-d-H-i' );
905
- list( $year, $month, $day, $hour, $minute ) = explode( '-', $gmDate );
906
- $ad->expiry_date = gmmktime($hour, $minute, 0, $month, $day, $year);
907
- }
908
- } else {
909
- $ad->expiry_date = 0;
910
- }
911
-
912
- $image_id = ( isset( $_POST['advanced_ad']['output']['image_id'] ) ) ? absint( $_POST['advanced_ad']['output']['image_id'] ) : 0;
913
- if ( $image_id ) {
914
- $all_posts_id = get_post_meta( $image_id, '_advanced-ads_parent_id' );
915
-
916
- if ( ! in_array ( $post_id, $all_posts_id ) ) {
917
- add_post_meta( $image_id, '_advanced-ads_parent_id', $post_id, false );
918
- }
919
- }
920
-
921
- $ad->save();
922
- }
923
-
924
- /**
925
- * prepare the ad post type to be removed
926
- *
927
- * @param int $post_id id of the post
928
- */
929
- public function delete_ad( $post_id ) {
930
- global $wpdb;
931
-
932
- if ( ! current_user_can( 'delete_posts' ) ) {
933
- return;
934
- }
935
-
936
- if ( $post_id > 0 ) {
937
- $post_type = get_post_type( $post_id );
938
- if ( $post_type == $this->post_type ) {
939
- $wpdb->query(
940
- $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %d", '_advanced-ads_parent_id', $post_id )
941
- );
942
- }
943
- }
944
- }
945
-
946
- /**
947
- * edit ad update messages
948
- *
949
- * @since 1.4.7
950
- * @param arr $messages existing post update messages
951
- * @return arr $messages
952
- *
953
- * @see wp-admin/edit-form-advanced.php
954
- */
955
- public function ad_update_messages($messages = array()){
956
- $post = get_post();
957
-
958
- // added to hide error message caused by third party code that uses post_updated_messages filter wrong
959
- if( ! is_array( $messages )){
960
- return $messages;
961
- }
962
-
963
- $messages[Advanced_Ads::POST_TYPE_SLUG] = array(
964
- 0 => '', // Unused. Messages start at index 1.
965
- 1 => __( 'Ad updated.', 'advanced-ads' ),
966
- 4 => __( 'Ad updated.', 'advanced-ads' ),
967
- /* translators: %s: date and time of the revision */
968
- 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Ad restored to revision from %s', 'advanced-ads' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
969
- 6 => __( 'Ad published.', 'advanced-ads' ),
970
- 7 => __( 'Ad saved.', 'advanced-ads' ),
971
- 8 => __( 'Ad submitted.', 'advanced-ads' ),
972
- 9 => sprintf(
973
- __( 'Ad scheduled for: <strong>%1$s</strong>.', 'advanced-ads' ),
974
- // translators: Publish box date format, see http://php.net/date
975
- date_i18n( __( 'M j, Y @ G:i', 'advanced-ads' ), strtotime( $post->post_date ) )
976
- ),
977
- 10 => __( 'Ad draft updated.', 'advanced-ads' )
978
- );
979
- return $messages;
980
- }
981
-
982
- /**
983
- * edit ad bulk update messages
984
- *
985
- * @since 1.4.7
986
- * @param arr $messages existing bulk update messages
987
- * @param arr $counts numbers of updated ads
988
- * @return arr $messages
989
- *
990
- * @see wp-admin/edit.php
991
- */
992
- public function ad_bulk_update_messages(array $messages, array $counts){
993
- $post = get_post();
994
-
995
- $messages[Advanced_Ads::POST_TYPE_SLUG] = array(
996
- 'updated' => _n( '%s ad updated.', '%s ads updated.', $counts['updated'] ),
997
- 'locked' => _n( '%s ad not updated, somebody is editing it.', '%s ads not updated, somebody is editing them.', $counts['locked'] ),
998
- 'deleted' => _n( '%s ad permanently deleted.', '%s ads permanently deleted.', $counts['deleted'] ),
999
- 'trashed' => _n( '%s ad moved to the Trash.', '%s ads moved to the Trash.', $counts['trashed'] ),
1000
- 'untrashed' => _n( '%s ad restored from the Trash.', '%s ads restored from the Trash.', $counts['untrashed'] ),
1001
- );
1002
-
1003
- return $messages;
1004
- }
1005
-
1006
- /**
1007
- * get action from the params
1008
- *
1009
- * @since 1.0.0
1010
- */
1011
- public function current_action() {
1012
- if ( isset($_REQUEST['action']) && -1 != $_REQUEST['action'] ) {
1013
- return $_REQUEST['action'];
1014
- }
1015
-
1016
- return false;
1017
- }
1018
-
1019
- /**
1020
- * initialize settings
1021
- *
1022
- * @since 1.0.1
1023
- */
1024
- public function settings_init(){
1025
-
1026
- // get settings page hook
1027
- $hook = $this->plugin_screen_hook_suffix;
1028
-
1029
- // register settings
1030
- register_setting( ADVADS_SLUG, ADVADS_SLUG, array($this, 'sanitize_settings') );
1031
-
1032
- // general settings section
1033
- add_settings_section(
1034
- 'advanced_ads_setting_section',
1035
- __( 'General', 'advanced-ads' ),
1036
- array($this, 'render_settings_section_callback'),
1037
- $hook
1038
- );
1039
-
1040
- // licenses section only for main blog
1041
- if( is_main_site( get_current_blog_id() ) ){
1042
- // register license settings
1043
- register_setting( ADVADS_SLUG . '-licenses', ADVADS_SLUG . '-licenses' );
1044
-
1045
- add_settings_section(
1046
- 'advanced_ads_settings_license_section',
1047
- __( 'Licenses', 'advanced-ads' ),
1048
- array($this, 'render_settings_licenses_section_callback'),
1049
- 'advanced-ads-settings-license-page'
1050
- );
1051
-
1052
- add_filter( 'advanced-ads-setting-tabs', array( $this, 'license_tab') );
1053
- }
1054
-
1055
- // add setting fields to disable ads
1056
- add_settings_field(
1057
- 'disable-ads',
1058
- __( 'Disable ads', 'advanced-ads' ),
1059
- array($this, 'render_settings_disable_ads'),
1060
- $hook,
1061
- 'advanced_ads_setting_section'
1062
- );
1063
- // add setting fields for user role
1064
- add_settings_field(
1065
- 'hide-for-user-role',
1066
- __( 'Hide ads for logged in users', 'advanced-ads' ),
1067
- array($this, 'render_settings_hide_for_users'),
1068
- $hook,
1069
- 'advanced_ads_setting_section'
1070
- );
1071
- // add setting fields for advanced js
1072
- add_settings_field(
1073
- 'activate-advanced-js',
1074
- __( 'Use advanced JavaScript', 'advanced-ads' ),
1075
- array($this, 'render_settings_advanced_js'),
1076
- $hook,
1077
- 'advanced_ads_setting_section'
1078
- );
1079
- // add setting fields for content injection protection
1080
- add_settings_field(
1081
- 'content-injection-everywhere',
1082
- __( 'Unlimited ad injection', 'advanced-ads' ),
1083
- array($this, 'render_settings_content_injection_everywhere'),
1084
- $hook,
1085
- 'advanced_ads_setting_section'
1086
- );
1087
- // add setting fields for content injection priority
1088
- add_settings_field(
1089
- 'content-injection-priority',
1090
- __( 'Priority of content injection filter', 'advanced-ads' ),
1091
- array($this, 'render_settings_content_injection_priority'),
1092
- $hook,
1093
- 'advanced_ads_setting_section'
1094
- );
1095
- // add setting fields for content injection priority
1096
- add_settings_field(
1097
- 'block-bots',
1098
- __( 'Hide ads from bots', 'advanced-ads' ),
1099
- array($this, 'render_settings_block_bots'),
1100
- $hook,
1101
- 'advanced_ads_setting_section'
1102
- );
1103
- // opt out from internal notices
1104
- add_settings_field(
1105
- 'disable-notices',
1106
- __( 'Disable notices', 'advanced-ads' ),
1107
- array($this, 'render_settings_disabled_notices'),
1108
- $hook,
1109
- 'advanced_ads_setting_section'
1110
- );
1111
- // opt out from internal notices
1112
- add_settings_field(
1113
- 'front-prefix',
1114
- __( 'ID prefix', 'advanced-ads' ),
1115
- array($this, 'render_settings_front_prefix'),
1116
- $hook,
1117
- 'advanced_ads_setting_section'
1118
- );
1119
- // remove id from widgets
1120
- add_settings_field(
1121
- 'remove-widget-id',
1122
- __( 'Remove Widget ID', 'advanced-ads' ),
1123
- array($this, 'render_settings_remove_widget_id'),
1124
- $hook,
1125
- 'advanced_ads_setting_section'
1126
- );
1127
- // allow editors to manage ads
1128
- add_settings_field(
1129
- 'editors-manage-ads',
1130
- __( 'Allow editors to manage ads', 'advanced-ads' ),
1131
- array($this, 'render_settings_editors_manage_ads'),
1132
- $hook,
1133
- 'advanced_ads_setting_section'
1134
- );
1135
-
1136
- add_settings_field(
1137
- 'add-custom-label',
1138
- __( 'Ad label', 'advanced-ads' ),
1139
- array( $this, 'render_settings_add_custom_label' ),
1140
- $hook,
1141
- 'advanced_ads_setting_section'
1142
- );
1143
-
1144
- // hook for additional settings from add-ons
1145
- do_action( 'advanced-ads-settings-init', $hook );
1146
- }
1147
-
1148
- /**
1149
- * add license tab
1150
- *
1151
- * arr $tabs setting tabs
1152
- */
1153
- public function license_tab( array $tabs ){
1154
-
1155
- $tabs['licenses'] = array(
1156
- 'page' => 'advanced-ads-settings-license-page',
1157
- 'group' => ADVADS_SLUG . '-licenses',
1158
- 'tabid' => 'licenses',
1159
- 'title' => __( 'Licenses', 'advanced-ads' )
1160
- );
1161
-
1162
- return $tabs;
1163
- }
1164
-
1165
- /**
1166
- * render settings section
1167
- *
1168
- * @since 1.1.1
1169
- */
1170
- public function render_settings_section_callback(){
1171
- // for whatever purpose there might come
1172
- }
1173
-
1174
- /**
1175
- * render licenses settings section
1176
- *
1177
- * @since 1.5.1
1178
- */
1179
- public function render_settings_licenses_section_callback(){
1180
- 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' );
1181
- 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>';
1182
- // nonce field
1183
- echo '<input type="hidden" id="advads-licenses-ajax-referrer" value="' . wp_create_nonce( "advads_ajax_license_nonce" ) . '"/>';
1184
- }
1185
-
1186
- /**
1187
- * options to disable ads
1188
- *
1189
- * @since 1.3.11
1190
- */
1191
- public function render_settings_disable_ads(){
1192
- $options = Advanced_Ads::get_instance()->options();
1193
-
1194
- // set the variables
1195
- $disable_all = isset($options['disabled-ads']['all']) ? 1 : 0;
1196
- $disable_404 = isset($options['disabled-ads']['404']) ? 1 : 0;
1197
- $disable_archives = isset($options['disabled-ads']['archives']) ? 1 : 0;
1198
- $disable_secondary = isset($options['disabled-ads']['secondary']) ? 1 : 0;
1199
- $disable_feed = ( ! isset( $options['disabled-ads']['feed'] ) || $options['disabled-ads']['feed'] ) ? 1 : 0;
1200
-
1201
- // load the template
1202
- include ADVADS_BASE_PATH . 'admin/views/settings-disable-ads.php';
1203
- }
1204
-
1205
- /**
1206
- * render setting to hide ads from logged in users
1207
- *
1208
- * @since 1.1.1
1209
- */
1210
- public function render_settings_hide_for_users(){
1211
- $options = Advanced_Ads::get_instance()->options();
1212
- $current_capability_role = isset($options['hide-for-user-role']) ? $options['hide-for-user-role'] : 0;
1213
-
1214
- $capability_roles = array(
1215
- '' => __( '(display to all)', 'advanced-ads' ),
1216
- 'read' => __( 'Subscriber', 'advanced-ads' ),
1217
- 'delete_posts' => __( 'Contributor', 'advanced-ads' ),
1218
- 'edit_posts' => __( 'Author', 'advanced-ads' ),
1219
- 'edit_pages' => __( 'Editor', 'advanced-ads' ),
1220
- 'activate_plugins' => __( 'Admin', 'advanced-ads' ),
1221
- );
1222
- echo '<select name="'.ADVADS_SLUG.'[hide-for-user-role]">';
1223
- foreach ( $capability_roles as $_capability => $_role ) {
1224
- echo '<option value="'.$_capability.'" '.selected( $_capability, $current_capability_role, false ).'>'.$_role.'</option>';
1225
- }
1226
- echo '</select>';
1227
-
1228
- echo '<p class="description">'. __( 'Choose the lowest role a user must have in order to not see any ads.', 'advanced-ads' ) .'</p>';
1229
- }
1230
-
1231
- /**
1232
- * render setting to display advanced js file
1233
- *
1234
- * @since 1.2.3
1235
- */
1236
- public function render_settings_advanced_js(){
1237
- $options = Advanced_Ads::get_instance()->options();
1238
- $checked = ( ! empty($options['advanced-js'])) ? 1 : 0;
1239
-
1240
- // display notice if js file was overridden
1241
- if( ! $checked && apply_filters( 'advanced-ads-activate-advanced-js', $checked ) ){
1242
- echo '<p>' . __( '<strong>notice: </strong>the file is currently enabled by an add-on that needs it.', 'advanced-ads' ) . '</p>';
1243
- }
1244
- echo '<input id="advanced-ads-advanced-js" type="checkbox" value="1" name="'.ADVADS_SLUG.'[advanced-js]" '.checked( $checked, 1, false ).'>';
1245
- 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>';
1246
- }
1247
-
1248
- /**
1249
- * render setting for content injection protection
1250
- *
1251
- * @since 1.4.1
1252
- */
1253
- public function render_settings_content_injection_everywhere(){
1254
- $options = Advanced_Ads::get_instance()->options();
1255
- $everywhere = ( isset($options['content-injection-everywhere']) ) ? true : false;
1256
-
1257
- echo '<input id="advanced-ads-injection-everywhere" type="checkbox" value="true" name="'.ADVADS_SLUG.'[content-injection-everywhere]" '.checked( $everywhere, true, false ).'>';
1258
- 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>';
1259
-
1260
- }
1261
-
1262
- /**
1263
- * render setting for content injection priority
1264
- *
1265
- * @since 1.4.1
1266
- */
1267
- public function render_settings_content_injection_priority(){
1268
- $options = Advanced_Ads::get_instance()->options();
1269
- $priority = ( isset($options['content-injection-priority'])) ? intval( $options['content-injection-priority'] ) : 100;
1270
-
1271
- echo '<input id="advanced-ads-content-injection-priority" type="number" value="'.$priority.'" name="'.ADVADS_SLUG.'[content-injection-priority]" size="3"/>';
1272
- echo '<p class="description">';
1273
- if ( $priority < 11 ) {
1274
- 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 />';
1275
- }
1276
- _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' );
1277
- echo '</p>';
1278
- }
1279
-
1280
- /**
1281
- * render setting for blocking bots
1282
- *
1283
- * @since 1.4.9
1284
- */
1285
- public function render_settings_block_bots(){
1286
- $options = Advanced_Ads::get_instance()->options();
1287
- $checked = ( ! empty($options['block-bots'])) ? 1 : 0;
1288
-
1289
- echo '<input id="advanced-ads-block-bots" type="checkbox" value="1" name="'.ADVADS_SLUG.'[block-bots]" '.checked( $checked, 1, false ).'>';
1290
- 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/>'
1291
- . __( '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>';
1292
- }
1293
-
1294
- /**
1295
- * render setting to disable notices
1296
- *
1297
- * @since 1.5.3
1298
- */
1299
- public function render_settings_disabled_notices(){
1300
- $options = Advanced_Ads::get_instance()->options();
1301
- $checked = ( ! empty($options['disable-notices'])) ? 1 : 0;
1302
-
1303
- echo '<input id="advanced-ads-disabled-notices" type="checkbox" value="1" name="'.ADVADS_SLUG.'[disable-notices]" '.checked( $checked, 1, false ).'>';
1304
- 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>';
1305
- }
1306
-
1307
- /**
1308
- * render setting for frontend prefix
1309
- *
1310
- * @since 1.6.8
1311
- */
1312
- public function render_settings_front_prefix(){
1313
- $options = Advanced_Ads::get_instance()->options();
1314
-
1315
- $prefix = Advanced_Ads_Plugin::get_instance()->get_frontend_prefix();
1316
- $old_prefix = ( isset($options['id-prefix'])) ? esc_attr( $options['id-prefix'] ) : '';
1317
-
1318
- echo '<input id="advanced-ads-front-prefix" type="text" value="' .$prefix .'" name="'.ADVADS_SLUG.'[front-prefix]" />';
1319
- // deprecated
1320
- echo '<input type="hidden" value="' .$old_prefix .'" name="'.ADVADS_SLUG.'[id-prefix]" />';
1321
- 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>';
1322
- }
1323
-
1324
- /**
1325
- * render setting to remove the id from advanced ads widgets
1326
- *
1327
- * @since 1.6.8.2
1328
- */
1329
- public function render_settings_remove_widget_id(){
1330
- $options = Advanced_Ads::get_instance()->options();
1331
-
1332
- // is true by default if no options where previously set
1333
- if( ! isset($options['remove-widget-id']) && $options !== array() ){
1334
- $remove = false;
1335
- } elseif( $options === array() ){
1336
- $remove = true;
1337
- } else {
1338
- $remove = true;
1339
- }
1340
-
1341
- echo '<input id="advanced-ads-remove-widget-id" type="checkbox" ' . checked( $remove, true, false ) . ' name="'.ADVADS_SLUG.'[remove-widget-id]" />';
1342
- echo '<p class="description">' . __( 'Remove the ID attribute from widgets in order to not make them an easy target of ad blockers.', 'advanced-ads' );
1343
 
1344
- if ( class_exists( 'q2w3_fixed_widget', false ) ) {
1345
- 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' );
1346
- }
1347
 
1348
- echo '</p>';
1349
- }
1350
-
1351
- /**
1352
- * render setting to allow editors to manage ads
1353
- *
1354
- * @since 1.6.14
1355
- */
1356
- public function render_settings_editors_manage_ads(){
1357
- $options = Advanced_Ads::get_instance()->options();
1358
 
1359
- // is false by default if no options where previously set
1360
- if( isset($options['editors-manage-ads']) && $options['editors-manage-ads'] ){
1361
- $allow = true;
1362
- } else {
1363
- $allow = false;
1364
- }
1365
 
1366
- echo '<input id="advanced-ads-editors-manage-ads" type="checkbox" ' . checked( $allow, true, false ) . ' name="'.ADVADS_SLUG.'[editors-manage-ads]" />';
1367
- echo '<p class="description">'. __( 'Allow editors to also manage and publish ads.', 'advanced-ads' ) .
1368
- ' ' . 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>';
1369
-
 
 
 
 
 
 
 
1370
  }
 
 
1371
 
1372
- /**
1373
- * render setting to add an "Advertisement" label before ads
1374
- *
1375
- */
1376
- public function render_settings_add_custom_label(){
1377
- $options = Advanced_Ads::get_instance()->options();
1378
-
1379
- $enabled = isset( $options['custom-label']['enabled'] );
1380
- $label = ! empty ( $options['custom-label']['text'] ) ? esc_html( $options['custom-label']['text'] ) : _x( 'Advertisements', 'label before ads' );
1381
- ?>
1382
-
1383
- <fieldset>
1384
- <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]'; ?>" />
1385
- <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]'; ?>" />
1386
- </fieldset>
1387
- <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>
1388
 
1389
- <?php
1390
- }
 
 
 
 
 
1391
 
1392
- /**
1393
- * sanitize plugin settings
1394
- *
1395
- * @since 1.5.1
1396
- * @param array $options all the options
1397
- */
1398
- public function sanitize_settings($options){
1399
-
1400
- // sanitize whatever option one wants to sanitize
1401
-
1402
- if ( isset( $options['front-prefix'] ) ) {
1403
- $options['front-prefix'] = sanitize_html_class( $options['front-prefix'], Advanced_Ads_Plugin::DEFAULT_FRONTEND_PREFIX );
1404
- }
1405
-
1406
- $options = apply_filters( 'advanced-ads-sanitize-settings', $options );
1407
-
1408
- // check if editors can edit ads now and set the rights
1409
- // else, remove that right
1410
- $editor_role = get_role( 'editor' );
1411
- if( null == $editor_role ){
1412
- return $options;
1413
- }
1414
- if( isset($options['editors-manage-ads']) && $options['editors-manage-ads'] ){
1415
- $editor_role->add_cap( 'advanced_ads_see_interface' );
1416
- $editor_role->add_cap( 'advanced_ads_edit_ads' );
1417
- $editor_role->add_cap( 'advanced_ads_manage_placements' );
1418
- $editor_role->add_cap( 'advanced_ads_place_ads' );
1419
- } else {
1420
- $editor_role->remove_cap( 'advanced_ads_see_interface' );
1421
- $editor_role->remove_cap( 'advanced_ads_edit_ads' );
1422
- $editor_role->remove_cap( 'advanced_ads_manage_placements' );
1423
- $editor_role->remove_cap( 'advanced_ads_place_ads' );
1424
- }
1425
-
1426
- // we need 3 states: ! isset, 1, 0
1427
- $options['disabled-ads']['feed'] = isset( $options['disabled-ads']['feed'] ) ? 1 : 0;
1428
-
1429
- return $options;
1430
- }
1431
 
1432
- /**
1433
- * add heading for extra column of ads list
1434
- * remove the date column
1435
- *
1436
- * @since 1.3.3
1437
- * @param arr $columns
1438
- */
1439
- public function ad_list_columns_head( $columns ){
1440
 
1441
- $new_columns = array();
1442
- if( is_array( $columns ) ){
1443
- foreach( $columns as $key => $value ) {
1444
- $new_columns[ $key ] = $value;
1445
- if ( $key == 'title' ){
1446
- $new_columns[ 'ad_details' ] = __( 'Ad Details', 'advanced-ads' );
1447
- $new_columns[ 'ad_timing' ] = __( 'Ad Planning', 'advanced-ads' );
1448
- }
1449
- }
1450
- } else {
1451
- $new_columns[ 'ad_details' ] = __( 'Ad Details', 'advanced-ads' );
1452
- $new_columns[ 'ad_timing' ] = __( 'Ad Planning', 'advanced-ads' );
1453
- }
1454
 
1455
- // white-listed columns
1456
- $whitelist = apply_filters( 'advanced-ads-ad-list-allowed-columns', array(
1457
- 'cb', // checkbox
1458
- 'title',
1459
- 'ad_details',
1460
- 'ad_timing',
1461
- 'taxonomy-advanced_ads_groups',
1462
- ) );
1463
 
1464
- // remove non-white-listed columns
1465
- foreach( $new_columns as $_key => $_value ){
1466
- if( ! in_array( $_key, $whitelist ) ){
1467
- unset( $new_columns[ $_key ] );
1468
- }
1469
- }
1470
 
1471
- return $new_columns;
 
 
 
 
 
 
 
 
 
 
 
1472
  }
1473
-
1474
- /**
1475
- * order ads by title on ads list
 
 
1476
  *
1477
- * @since 1.3.18
1478
- * @param arr $vars array with request vars
1479
  */
1480
- public function ad_list_request($vars){
1481
-
1482
- // order ads by title on ads list
1483
- if ( is_admin() && empty( $vars['orderby'] ) && $this->post_type == $vars['post_type'] ) {
1484
- $vars = array_merge( $vars, array(
1485
- 'orderby' => 'title',
1486
- 'order' => 'ASC'
1487
- ) );
1488
  }
1489
 
1490
- return $vars;
1491
  }
1492
 
1493
  /**
1494
- * display ad details in ads list
1495
  *
1496
- * @since 1.3.3
1497
- * @param string $column_name name of the column
1498
- * @param int $ad_id id of the ad
1499
  */
1500
- public function ad_list_columns_content($column_name, $ad_id) {
1501
- if ( $column_name == 'ad_details' ) {
1502
- $ad = new Advanced_Ads_Ad( $ad_id );
1503
-
1504
- // load ad type title
1505
- $types = Advanced_Ads::get_instance()->ad_types;
1506
- $type = ( ! empty($types[$ad->type]->title)) ? $types[$ad->type]->title : 0;
1507
-
1508
- // load ad size
1509
- $size = 0;
1510
- if ( ! empty($ad->width) || ! empty($ad->height) ) {
1511
- $size = sprintf( '%d x %d', $ad->width, $ad->height );
1512
- }
1513
-
1514
- $size = apply_filters( 'advanced-ads-list-ad-size', $size, $ad );
1515
-
1516
- include ADVADS_BASE_PATH . 'admin/views/ad-list-details-column.php';
1517
  }
 
1518
  }
1519
-
1520
  /**
1521
- * display ad details in ads list
1522
  *
1523
- * @since 1.6.11
1524
- * @param string $column_name name of the column
1525
- * @param int $ad_id id of the ad
1526
  */
1527
- public function ad_list_columns_timing($column_name, $ad_id) {
1528
-
1529
- if ( $column_name == 'ad_timing' ) {
1530
- $ad = new Advanced_Ads_Ad( $ad_id );
1531
-
1532
- $expiry = false;
1533
- $post_future = false;
1534
- $post_start = get_the_date('U', $ad->id );
1535
- $html_classes = 'advads-filter-timing';
1536
- $expiry_date_format = get_option( 'date_format' ). ', ' . get_option( 'time_format' );
1537
 
1538
- if( isset( $ad->expiry_date ) && $ad->expiry_date ){
1539
- $html_classes .= ' advads-filter-any-exp-date';
1540
 
1541
- $expiry = $ad->expiry_date;
1542
- if( $ad->expiry_date < time() ){
1543
- $html_classes .= ' advads-filter-expired';
1544
- }
1545
- }
1546
- if( $post_start > time() ){
1547
- $post_future = $post_start;
1548
- $html_classes .= ' advads-filter-future';
1549
- }
1550
 
1551
- include ADVADS_BASE_PATH . 'admin/views/ad-list-timing-column.php';
1552
- }
1553
- }
 
1554
 
1555
- /**
1556
- * adds filter dropdowns before the 'Filter' button on the ad list table
1557
- */
1558
- function ad_list_add_filters() {
1559
- $screen = get_current_screen();
1560
- if ( ! isset( $screen->id ) || $screen->id !== 'edit-advanced_ads' ) {
1561
- return;
 
 
 
 
 
 
1562
  }
1563
 
1564
- include ADVADS_BASE_PATH . 'admin/views/ad-list-filters.php';
1565
- }
1566
-
1567
- /**
1568
- * show instructions to create first ad above the ad list
1569
- *
1570
- * @return type
1571
- */
1572
- public function no_ads_yet_notice(){
1573
  $screen = get_current_screen();
1574
- if ( ! isset( $screen->id ) || $screen->id !== 'edit-advanced_ads' ) {
1575
- return;
1576
- }
1577
-
1578
- // get number of ads
1579
- $recent_ads = Advanced_Ads::get_instance()->get_model()->get_ads();
1580
-
1581
- // only display if there are no more than 2 ads
1582
- if( 3 > count( $recent_ads ) ){
1583
- include ADVADS_BASE_PATH . 'admin/views/ad-list-no-ads.php';
1584
  }
1585
- }
1586
 
 
1587
 
1588
  /**
1589
- * add a meta box to post type edit screens with ad settings
1590
  *
1591
- * @since 1.3.10
1592
- * @param string $post_type current post type
1593
  */
1594
- public function add_post_meta_box($post_type = ''){
1595
- // don’t display for non admins
1596
- if( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads') ) ) {
1597
- return;
1598
- }
1599
-
1600
- // get public post types
1601
- $public_post_types = get_post_types( array('public' => true, 'publicly_queryable' => true), 'names', 'or' );
1602
 
1603
- //limit meta box to public post types
1604
- if ( in_array( $post_type, $public_post_types ) ) {
1605
- add_meta_box(
1606
- 'advads-ad-settings',
1607
- __( 'Ad Settings', 'advanced-ads' ),
1608
- array( $this, 'render_post_meta_box' ),
1609
- $post_type,
1610
- 'advanced',
1611
- 'low'
1612
- );
1613
- }
1614
  }
1615
-
1616
- /**
1617
- * render meta box for ad settings on a per post basis
1618
- *
1619
- * @since 1.3.10
1620
- * @param WP_Post $post The post object.
1621
- */
1622
- public function render_post_meta_box( $post ) {
1623
-
1624
- // nonce field to check when we save the values
1625
- wp_nonce_field( 'advads_post_meta_box', 'advads_post_meta_box_nonce' );
1626
-
1627
- // retrieve an existing value from the database.
1628
- $values = get_post_meta( $post->ID, '_advads_ad_settings', true );
1629
-
1630
- // load the view
1631
- include ADVADS_BASE_PATH . 'admin/views/post-ad-settings-metabox.php';
1632
  }
1633
 
1634
- /**
1635
- * save the ad meta when the post is saved.
1636
- *
1637
- * @since 1.3.10
1638
- * @param int $post_id The ID of the post being saved.
1639
- */
1640
- public function save_post_meta_box( $post_id ) {
1641
-
1642
- if( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads') ) ) {
1643
- return;
1644
- }
1645
-
1646
- // check nonce
1647
- if ( ! isset( $_POST['advads_post_meta_box_nonce'] ) ) {
1648
- return $post_id; }
1649
-
1650
- $nonce = $_POST['advads_post_meta_box_nonce'];
1651
-
1652
- // Verify that the nonce is valid.
1653
- if ( ! wp_verify_nonce( $nonce, 'advads_post_meta_box' ) ) {
1654
- return $post_id; }
1655
-
1656
- // don’t save on autosave
1657
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
1658
- return $post_id; }
1659
-
1660
- // check the user's permissions.
1661
- if ( 'page' == $_POST['post_type'] ) {
1662
- if ( ! current_user_can( 'edit_page', $post_id ) ) {
1663
- return $post_id; }
1664
- } else {
1665
- if ( ! current_user_can( 'edit_post', $post_id ) ) {
1666
- return $post_id; }
1667
- }
1668
-
1669
- // Sanitize the user input.
1670
- $_data['disable_ads'] = isset($_POST['advanced_ads']['disable_ads']) ? absint( $_POST['advanced_ads']['disable_ads'] ) : 0;
1671
-
1672
- // Update the meta field.
1673
- update_post_meta( $post_id, '_advads_ad_settings', $_data );
1674
- }
1675
 
1676
- /**
1677
- * add dashboard widget with ad stats and additional information
1678
- *
1679
- * @since 1.3.12
1680
- */
1681
- public function add_dashboard_widget(){
1682
- // display dashboard widget only to authors and higher roles
1683
- if( ! current_user_can('publish_posts') ) {
1684
- return;
1685
- }
1686
- add_meta_box( 'advads_dashboard_widget', __( 'Ads Dashboard', 'advanced-ads' ), array($this, 'dashboard_widget_function'), 'dashboard', 'side', 'high' );
1687
  }
1688
 
1689
- /**
1690
- * display widget functions
1691
- */
1692
- public static function dashboard_widget_function($post, $callback_args){
1693
- // load ad optimization feed
1694
- $feeds = array(
1695
- array(
1696
- 'link' => 'http://webgilde.com/en/ad-optimization/',
1697
- 'url' => 'http://webgilde.com/en/ad-optimization/feed/',
1698
- 'title' => __( 'From the ad optimization universe', 'advanced-ads' ),
1699
- 'items' => 2,
1700
- 'show_summary' => 0,
1701
- 'show_author' => 0,
1702
- 'show_date' => 0,
1703
- ),
1704
- array(
1705
- 'link' => ADVADS_URL,
1706
- 'url' => ADVADS_URL . 'feed/',
1707
- 'title' => __( 'Advanced Ads Tutorials', 'advanced-ads' ),
1708
- 'items' => 2,
1709
- 'show_summary' => 0,
1710
- 'show_author' => 0,
1711
- 'show_date' => 0,
1712
- ),
1713
- );
1714
-
1715
- // get number of ads
1716
- $recent_ads = Advanced_Ads::get_instance()->get_model()->get_ads();
1717
- echo '<p>';
1718
- printf(__( '%d ads – <a href="%s">manage</a> - <a href="%s">new</a>', 'advanced-ads' ),
1719
- count( $recent_ads ),
1720
- 'edit.php?post_type='. Advanced_Ads::POST_TYPE_SLUG,
1721
- 'post-new.php?post_type='. Advanced_Ads::POST_TYPE_SLUG);
1722
- echo '</p>';
1723
-
1724
- // get and display plugin version
1725
- $advads_plugin_data = get_plugin_data( ADVADS_BASE_PATH . 'advanced-ads.php' );
1726
- if ( isset($advads_plugin_data['Version']) ){
1727
- $version = $advads_plugin_data['Version'];
1728
- echo '<p><a href="'.ADVADS_URL.'#utm_source=advanced-ads&utm_medium=link&utm_campaign=dashboard" target="_blank" title="'.
1729
- __( 'plugin manual and homepage', 'advanced-ads' ).'">Advanced Ads</a> '. $version .'</p>';
1730
- }
1731
-
1732
- $notice_options = Advanced_Ads_Admin_Notices::get_instance()->options();
1733
- $_notice = 'nl_first_steps';
1734
- if ( ! isset($notice_options['closed'][ $_notice ] ) ) {
1735
- ?><div class="advads-admin-notice">
1736
- <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>
1737
- </div><?php
1738
- }
1739
-
1740
- $_notice = 'nl_adsense';
1741
- if ( ! isset($notice_options['closed'][ $_notice ] ) ) {
1742
- ?><div class="advads-admin-notice">
1743
- <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>
1744
- </div><?php
1745
- }
1746
 
1747
- // rss feed
1748
- // $this->dashboard_widget_function_output('advads_dashboard_widget', $feed);
1749
- self::dashboard_cached_rss_widget( 'advads_dashboard_widget', array('Advanced_Ads_Admin', 'dashboard_widget_function_output'), array('advads' => $feeds) );
1750
-
1751
- // add markup for utm variables
1752
- // todo: move to js file
1753
- ?><script>jQuery('#advads_dashboard_widget .rss-widget a').each(function(){ this.href = this.href + '#utm_source=advanced-ads&utm_medium=rss-link&utm_campaign=dashboard'; })</script><?php
1754
- }
1755
 
1756
- /**
1757
- * checks to see if there are feed urls in transient cache; if not, load them
1758
- * built using a lot of https://developer.wordpress.org/reference/functions/wp_dashboard_cached_rss_widget/
1759
  *
1760
- * @since 1.3.12
1761
- * @param string $widget_id
1762
- * @param callback $callback
1763
- * @param array $check_urls RSS feeds
1764
- * @return bool False on failure. True on success.
1765
  */
1766
- static function dashboard_cached_rss_widget( $widget_id, $callback, $feeds = array() ) {
1767
- if ( empty($feeds) ) {
1768
- return;
1769
- }
1770
-
1771
- $cache_key = 'dash_' . md5( $widget_id );
1772
- if ( false !== ( $output = get_transient( $cache_key ) ) ) {
1773
- echo $output;
1774
- return true;
1775
- }
1776
- if ( $callback && is_callable( $callback ) ) {
1777
- ob_start();
1778
- call_user_func_array( $callback, $feeds );
1779
- set_transient( $cache_key, ob_get_flush(), 48 * HOUR_IN_SECONDS ); // Default lifetime in cache of 48 hours
1780
- }
1781
-
1782
- return true;
1783
  }
1784
 
1785
- /**
1786
- * create the rss output of the widget
1787
- *
1788
- * @param string $widget_id Widget ID.
1789
- * @param array $feeds Array of RSS feeds.
1790
- */
1791
- static function dashboard_widget_function_output( $feeds ) {
1792
- foreach ( $feeds as $_feed ){
1793
- echo '<div class="rss-widget">';
1794
- echo '<h4>'.$_feed['title'].'</h4>';
1795
- wp_widget_rss_output( $_feed['url'], $_feed );
1796
- echo '</div>';
1797
- }
1798
- }
1799
 
1800
  /**
1801
  * get DateTimeZone object for the WP installation
@@ -2192,6 +634,10 @@ class Advanced_Ads_Admin {
2192
  * @return array $links
2193
  */
2194
  function add_plugin_links( $links ) {
 
 
 
 
2195
  // add link to support page
2196
  $support_link = '<a href="' . esc_url( admin_url( 'admin.php?page=advanced-ads-support' ) ) . '">' . __( 'Support', 'advanced-ads' ) . '</a>';
2197
  array_unshift( $links, $support_link );
@@ -2221,34 +667,6 @@ class Advanced_Ads_Admin {
2221
  include ADVADS_BASE_PATH . 'admin/views/feedback_disable.php';
2222
  }
2223
 
2224
- /**
2225
- * Check if an ad is not valid for 'Post Content' placement
2226
- *
2227
- * @param obj $ad Advanced_Ads_Ad object
2228
- * @return string with error if not valid, bool false if valid
2229
- */
2230
- public function check_ad_dom_is_not_valid( Advanced_Ads_Ad $ad ) {
2231
- $adContent = ( isset( $ad->content ) ) ? $ad->content : '';
2232
- if ( ! $adContent ) {
2233
- return false;
2234
- }
2235
-
2236
- $wpCharset = get_bloginfo('charset');
2237
- $adDom = new DOMDocument('1.0', $wpCharset);
2238
 
2239
- $libxml_previous_state = libxml_use_internal_errors( true );
2240
- // clear existing errors
2241
- libxml_clear_errors();
2242
- // source for this regex: http://stackoverflow.com/questions/17852537/preg-replace-only-specific-part-of-string
2243
- $adContent = preg_replace('#(document.write.+)</(.*)#', '$1<\/$2', $adContent); // escapes all closing html tags
2244
- $adDom->loadHtml('<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=' . $wpCharset . '" /><body>' . $adContent);
2245
- // log errors
2246
- if( libxml_get_last_error() instanceof LibXMLError ) {
2247
- return print_r( libxml_get_last_error(), true );
2248
- }
2249
-
2250
- libxml_use_internal_errors( $libxml_previous_state );
2251
- return false;
2252
- }
2253
 
2254
  }
43
  */
44
  public $plugin_screen_hook_suffix = null;
45
 
 
 
 
 
 
 
 
 
46
  /**
47
  * general plugin slug
48
  *
49
+ * @since 1.0.0
50
+ * @var string
51
+ */
52
+ protected $plugin_slug = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
 
 
 
54
 
55
+
 
 
 
 
 
 
 
 
 
56
 
 
 
 
 
 
 
57
 
58
+ /**
59
+ * Initialize the plugin by loading admin scripts & styles and adding a
60
+ * settings page and menu.
61
+ *
62
+ * @since 1.0.0
63
+ */
64
+ private function __construct() {
65
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
66
+ new Advanced_Ads_Ad_Ajax_Callbacks;
67
+ } else {
68
+ add_action( 'plugins_loaded', array( $this, 'wp_plugins_loaded' ) );
69
  }
70
+ // add shortcode creator to TinyMCE
71
+ Advanced_Ads_Shortcode_Creator::get_instance();
72
 
73
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
+ public function wp_plugins_loaded() {
76
+ /*
77
+ * Call $plugin_slug from public plugin class.
78
+ *
79
+ */
80
+ $plugin = Advanced_Ads::get_instance();
81
+ $this->plugin_slug = $plugin->get_plugin_slug();
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
+ // Load admin style sheet and JavaScript.
85
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
86
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ), 9 );
 
 
 
 
 
87
 
88
+ // update placements
89
+ add_action( 'admin_init', array('Advanced_Ads_Placements', 'update_placements') );
90
+ // check for add-on updates
91
+ add_action( 'admin_init', array($this, 'add_on_updater'), 1 );
 
 
 
 
 
 
 
 
 
92
 
93
+ // check for update logic
94
+ add_action( 'admin_notices', array($this, 'admin_notices') );
 
 
 
 
 
 
95
 
 
 
 
 
 
 
96
 
97
+ // set 1 column layout on overview page as user and page option
98
+ add_filter( 'screen_layout_columns', array('Advanced_Ads_Overview_Widgets_Callbacks', 'one_column_overview_page') );
99
+ add_filter( 'get_user_option_screen_layout_toplevel_page_advanced', array( 'Advanced_Ads_Overview_Widgets_Callbacks', 'one_column_overview_page_user') );
100
+
101
+ // add links to plugin page
102
+ add_filter( 'plugin_action_links_' . ADVADS_BASE, array( $this, 'add_plugin_links' ) );
103
+ // display information when user is going to disable the plugin
104
+ // add_filter( 'after_plugin_row_' . ADVADS_BASE, array( $this, 'display_deactivation_message' ) );
105
+ Advanced_Ads_Admin_Meta_Boxes::get_instance();
106
+ Advanced_Ads_Admin_Menu::get_instance();
107
+ Advanced_Ads_Admin_Ad_Type::get_instance();
108
+ Advanced_Ads_Admin_Settings::get_instance();
109
  }
110
+
111
+ /**
112
+ * Return an instance of this class.
113
+ *
114
+ * @since 1.0.0
115
  *
116
+ * @return object A single instance of this class.
 
117
  */
118
+ public static function get_instance() {
119
+ // If the single instance hasn't been set, set it now.
120
+ if ( null == self::$instance ) {
121
+ self::$instance = new self;
 
 
 
 
122
  }
123
 
124
+ return self::$instance;
125
  }
126
 
127
  /**
128
+ * Register and enqueue admin-specific style sheet.
129
  *
130
+ * @since 1.0.0
 
 
131
  */
132
+ public function enqueue_admin_styles() {
133
+ wp_enqueue_style( $this->plugin_slug . '-admin-styles', plugins_url( 'assets/css/admin.css', __FILE__ ), array(), ADVADS_VERSION );
134
+ if( self::screen_belongs_to_advanced_ads() ){
135
+ // jQuery ui smoothness style 1.11.4
136
+ wp_enqueue_style( $this->plugin_slug . '-jquery-ui-styles', plugins_url( 'assets/jquery-ui/jquery-ui.min.css', __FILE__ ), array(), '1.11.4' );
 
 
 
 
 
 
 
 
 
 
 
 
137
  }
138
+ //wp_enqueue_style( 'jquery-style', '//code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css' );
139
  }
140
+
141
  /**
142
+ * Register and enqueue admin-specific JavaScript.
143
  *
144
+ * @since 1.0.0
145
+ *
146
+ * @return null Return early if no settings page is registered.
147
  */
148
+ public function enqueue_admin_scripts() {
 
 
 
 
 
 
 
 
 
149
 
150
+ // global js script
151
+ wp_enqueue_script( $this->plugin_slug . '-admin-global-script', plugins_url( 'assets/js/admin-global.js', __FILE__ ), array('jquery'), ADVADS_VERSION );
152
 
153
+ if( self::screen_belongs_to_advanced_ads() ){
154
+ wp_register_script( $this->plugin_slug . '-admin-script', plugins_url( 'assets/js/admin.js', __FILE__ ), array( 'jquery', 'jquery-ui-autocomplete' , 'jquery-ui-button' ), ADVADS_VERSION );
155
+ wp_register_script( $this->plugin_slug . '-wizard-script', plugins_url( 'assets/js/wizard.js', __FILE__ ), array('jquery'), ADVADS_VERSION );
 
 
 
 
 
 
156
 
157
+ // jquery ui
158
+ wp_enqueue_script( 'jquery-ui-accordion' );
159
+ wp_enqueue_script( 'jquery-ui-button' );
160
+ wp_enqueue_script( 'jquery-ui-tooltip' );
161
 
162
+ // just register this script for later inclusion on ad group list page
163
+ wp_register_script( 'inline-edit-group-ads', plugins_url( 'assets/js/inline-edit-group-ads.js', __FILE__ ), array('jquery'), ADVADS_VERSION );
164
+
165
+ // register admin.js translations
166
+ $translation_array = array(
167
+ 'condition_or' => __( 'or', 'advanced-ads' ),
168
+ 'condition_and' => __( 'and', 'advanced-ads' ),
169
+ 'after_paragraph_promt' => __( 'After which paragraph?', 'advanced-ads' ),
170
+ );
171
+ wp_localize_script( $this->plugin_slug . '-admin-script', 'advadstxt', $translation_array );
172
+
173
+ wp_enqueue_script( $this->plugin_slug . '-admin-script' );
174
+ wp_enqueue_script( $this->plugin_slug . '-wizard-script' );
175
  }
176
 
177
+ //call media manager for image upload only on ad edit pages
 
 
 
 
 
 
 
 
178
  $screen = get_current_screen();
179
+ if( isset( $screen->id ) && Advanced_Ads::POST_TYPE_SLUG === $screen->id ) {
180
+ // the 'wp_enqueue_media' function can be executed only once and should be called with the 'post' parameter
181
+ // 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.
182
+ // since other plugins can call the 'wp_enqueue_media' function without the 'post' parameter, Advanced Ads should call it earlier.
183
+ global $post;
184
+ wp_enqueue_media( array( 'post' => $post ) );
 
 
 
 
185
  }
 
186
 
187
+ }
188
 
189
  /**
190
+ * check if the current screen belongs to Advanced Ads
191
  *
192
+ * @since 1.6.6
193
+ * @return bool true if screen belongs to Advanced Ads
194
  */
195
+ static function screen_belongs_to_advanced_ads(){
 
 
 
 
 
 
 
196
 
197
+ if( ! function_exists( 'get_current_screen' ) ){
198
+ return false;
 
 
 
 
 
 
 
 
 
199
  }
200
+
201
+ $screen = get_current_screen();
202
+ //echo $screen->id;
203
+ if( !isset( $screen->id ) ) {
204
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
205
  }
206
 
207
+ $advads_pages = apply_filters( 'advanced-ads-dashboard-screens', array(
208
+ 'advanced-ads_page_advanced-ads-groups', // ad groups
209
+ 'edit-advanced_ads', // ads overview
210
+ 'advanced_ads', // ad edit page
211
+ 'advanced-ads_page_advanced-ads-placements', // placements
212
+ 'advanced-ads_page_advanced-ads-settings', // settings
213
+ 'toplevel_page_advanced-ads', // overview
214
+ 'admin_page_advanced-ads-debug', // debug
215
+ 'advanced-ads_page_advanced-ads-support', // support
216
+ 'admin_page_advanced-ads-intro', // intro
217
+ 'admin_page_advanced-ads-import-export', // import & export
218
+ ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
 
220
+ if( in_array( $screen->id, $advads_pages )){
221
+ return true;
 
 
 
 
 
 
 
 
 
222
  }
223
 
224
+ return false;
225
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
 
 
 
 
 
 
 
 
 
227
 
228
+ /**
229
+ * get action from the params
 
230
  *
231
+ * @since 1.0.0
 
 
 
 
232
  */
233
+ public function current_action() {
234
+ if ( isset($_REQUEST['action']) && -1 != $_REQUEST['action'] ) {
235
+ return $_REQUEST['action'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  }
237
 
238
+ return false;
239
+ }
240
+
 
 
 
 
 
 
 
 
 
 
 
241
 
242
  /**
243
  * get DateTimeZone object for the WP installation
634
  * @return array $links
635
  */
636
  function add_plugin_links( $links ) {
637
+ // add link to settings
638
+ //$settings_link = '<a href="' . admin_url( 'admin.php?page=advanced_ads&page=advanced-ads-settings' ) . '">' . __( 'Settings', 'advanced-ads' ) . '</a>';
639
+ //array_unshift( $links, $settings_link );
640
+
641
  // add link to support page
642
  $support_link = '<a href="' . esc_url( admin_url( 'admin.php?page=advanced-ads-support' ) ) . '">' . __( 'Support', 'advanced-ads' ) . '</a>';
643
  array_unshift( $links, $support_link );
667
  include ADVADS_BASE_PATH . 'admin/views/feedback_disable.php';
668
  }
669
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
670
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
671
 
672
  }
admin/includes/class-ad-groups-list.php CHANGED
@@ -84,12 +84,13 @@ class Advanced_Ads_Groups_List {
84
  }
85
  }
86
 
 
87
  /**
88
  * render a single row
89
  *
90
  * @param obj $group the ad group object
91
  */
92
- public function render_row($group){
93
  $file = ADVADS_BASE_PATH . 'admin/views/ad-group-list-row.php';
94
  require($file);
95
  }
@@ -103,6 +104,7 @@ class Advanced_Ads_Groups_List {
103
 
104
  // query ads
105
  $ads = $this->get_ads( $group );
 
106
  $weights = $group->get_ad_weights();
107
  $ad_form_rows = $weights;
108
  arsort( $ad_form_rows );
@@ -112,13 +114,13 @@ class Advanced_Ads_Groups_List {
112
  foreach ( $ads->posts as $_ad ) {
113
  $row = '';
114
  $ad_id = $_ad->ID;
115
- $row .= '<tr><td>' . $_ad->post_title . '</td><td>';
116
  $row .= '<select name="advads-groups['. $group->id . '][ads]['.$_ad->ID.']">';
117
  $ad_weight = (isset($weights[$ad_id])) ? $weights[$ad_id] : Advanced_Ads_Group::MAX_AD_GROUP_WEIGHT;
118
  for ( $i = 0; $i <= Advanced_Ads_Group::MAX_AD_GROUP_WEIGHT; $i++ ) {
119
  $row .= '<option ' . selected( $ad_weight, $i, false ) . '>' . $i . '</option>';
120
  }
121
- $row .= '</select></td></tr>';
122
  $ad_form_rows[$_ad->ID] = $row;
123
  }
124
  }
@@ -126,6 +128,13 @@ class Advanced_Ads_Groups_List {
126
  // Restore original Post Data
127
  wp_reset_postdata();
128
 
 
 
 
 
 
 
 
129
  $file = ADVADS_BASE_PATH . 'admin/views/ad-group-list-form-row.php';
130
  require($file);
131
  }
@@ -240,6 +249,24 @@ class Advanced_Ads_Groups_List {
240
  return $ads = new WP_Query( $args );
241
  }
242
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  /**
244
  * return ad group types
245
  *
@@ -281,7 +308,7 @@ class Advanced_Ads_Groups_List {
281
  'action' => 'delete',
282
  'group_id' => $group->id
283
  );
284
- $delete_link = Advanced_Ads_Admin::group_page_url( $args );
285
  $actions['delete'] = "<a class='delete-tag' href='" . wp_nonce_url( $delete_link, 'delete-tag_' . $group->id ) . "'>" . __( 'Delete' ) . '</a>';
286
  }
287
 
@@ -316,6 +343,15 @@ class Advanced_Ads_Groups_List {
316
  // empty weights
317
  update_option( 'advads-ad-weights', array() );
318
 
 
 
 
 
 
 
 
 
 
319
  // iterate through groups
320
  if ( isset($_POST['advads-groups']) && count( $_POST['advads-groups'] ) ){
321
 
@@ -323,10 +359,15 @@ class Advanced_Ads_Groups_List {
323
  // save basic wp term
324
  wp_update_term( $_group_id, Advanced_Ads::AD_GROUP_TAXONOMY, $_group );
325
 
326
- // save ad weights
327
  $group = new Advanced_Ads_Group( $_group['id'] );
328
- if ( isset($_group['ads']) ) {
329
- $group->save_ad_weights( $_group['ads'] ); }
 
 
 
 
 
 
330
 
331
  // save other attributes
332
  $type = isset($_group['type']) ? $_group['type'] : 'default';
@@ -342,6 +383,11 @@ class Advanced_Ads_Groups_List {
342
 
343
  $group->save( $atts );
344
  }
 
 
 
 
 
345
  }
346
 
347
  // reload groups
@@ -350,4 +396,23 @@ class Advanced_Ads_Groups_List {
350
  return true;
351
  }
352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  }
84
  }
85
  }
86
 
87
+
88
  /**
89
  * render a single row
90
  *
91
  * @param obj $group the ad group object
92
  */
93
+ public function render_row( Advanced_Ads_Group $group ) {
94
  $file = ADVADS_BASE_PATH . 'admin/views/ad-group-list-row.php';
95
  require($file);
96
  }
104
 
105
  // query ads
106
  $ads = $this->get_ads( $group );
107
+
108
  $weights = $group->get_ad_weights();
109
  $ad_form_rows = $weights;
110
  arsort( $ad_form_rows );
114
  foreach ( $ads->posts as $_ad ) {
115
  $row = '';
116
  $ad_id = $_ad->ID;
117
+ $row .= '<tr data-ad-id="'. $ad_id . '"><td>' . $_ad->post_title . '</td><td>';
118
  $row .= '<select name="advads-groups['. $group->id . '][ads]['.$_ad->ID.']">';
119
  $ad_weight = (isset($weights[$ad_id])) ? $weights[$ad_id] : Advanced_Ads_Group::MAX_AD_GROUP_WEIGHT;
120
  for ( $i = 0; $i <= Advanced_Ads_Group::MAX_AD_GROUP_WEIGHT; $i++ ) {
121
  $row .= '<option ' . selected( $ad_weight, $i, false ) . '>' . $i . '</option>';
122
  }
123
+ $row .= '</select</td><td><button type="button" class="advads-remove-ad-from-group button">x</button></td></tr>';
124
  $ad_form_rows[$_ad->ID] = $row;
125
  }
126
  }
128
  // Restore original Post Data
129
  wp_reset_postdata();
130
 
131
+ $ads_for_select = $this->ads_for_select();
132
+ $new_ad_weights = '<select class="advads-group-add-ad-list-weights">';
133
+ for ( $i = 0; $i <= Advanced_Ads_Group::MAX_AD_GROUP_WEIGHT; $i++ ) {
134
+ $new_ad_weights .= '<option ' . selected( 10, $i, false ) . '>' . $i . '</option>';
135
+ }
136
+ $new_ad_weights .= '</select>';
137
+
138
  $file = ADVADS_BASE_PATH . 'admin/views/ad-group-list-form-row.php';
139
  require($file);
140
  }
249
  return $ads = new WP_Query( $args );
250
  }
251
 
252
+ /**
253
+ * list of all ads to display in select dropdown
254
+ *
255
+ * @return array
256
+ */
257
+ public function ads_for_select(){
258
+ $select = array();
259
+ $model = Advanced_Ads::get_instance()->get_model();
260
+
261
+ // load all ads
262
+ $ads = $model->get_ads( array('orderby' => 'title', 'order' => 'ASC') );
263
+ foreach ( $ads as $_ad ){
264
+ $select[ $_ad->ID ] = esc_html( $_ad->post_title );
265
+ }
266
+
267
+ return $select;
268
+ }
269
+
270
  /**
271
  * return ad group types
272
  *
308
  'action' => 'delete',
309
  'group_id' => $group->id
310
  );
311
+ $delete_link = self::group_page_url( $args );
312
  $actions['delete'] = "<a class='delete-tag' href='" . wp_nonce_url( $delete_link, 'delete-tag_' . $group->id ) . "'>" . __( 'Delete' ) . '</a>';
313
  }
314
 
343
  // empty weights
344
  update_option( 'advads-ad-weights', array() );
345
 
346
+ // ad_id => group_ids
347
+ $ad_groups_assoc = array();
348
+
349
+ if ( isset( $_POST['advads-groups-removed-ads'] ) && is_array( $_POST['advads-groups-removed-ads'] ) ) {
350
+ foreach ( $_POST['advads-groups-removed-ads'] as $ad_id ) {
351
+ $ad_groups_assoc[ $ad_id ] = array();
352
+ }
353
+ }
354
+
355
  // iterate through groups
356
  if ( isset($_POST['advads-groups']) && count( $_POST['advads-groups'] ) ){
357
 
359
  // save basic wp term
360
  wp_update_term( $_group_id, Advanced_Ads::AD_GROUP_TAXONOMY, $_group );
361
 
 
362
  $group = new Advanced_Ads_Group( $_group['id'] );
363
+ if ( isset( $_group['ads'] ) && is_array( $_group['ads'] ) ) {
364
+ // save ad weights
365
+ $group->save_ad_weights( $_group['ads'] );
366
+
367
+ foreach ( $_group['ads'] as $_ad_id => $_ad_weight ) {
368
+ $ad_groups_assoc[ $_ad_id ][] = (int) $_group_id;
369
+ }
370
+ }
371
 
372
  // save other attributes
373
  $type = isset($_group['type']) ? $_group['type'] : 'default';
383
 
384
  $group->save( $atts );
385
  }
386
+
387
+ foreach ( $ad_groups_assoc as $_ad_id => $group_ids ) {
388
+ wp_set_object_terms( $_ad_id, $group_ids, $this->taxonomy);
389
+ }
390
+
391
  }
392
 
393
  // reload groups
396
  return true;
397
  }
398
 
399
+ /**
400
+ * returns a link to the ad group list page
401
+ *
402
+ * @since 1.0.0
403
+ * @param arr $args additional arguments, e.g. action or group_id
404
+ * @return string admin url
405
+ */
406
+ public static function group_page_url($args = array()) {
407
+ $plugin = Advanced_Ads::get_instance();
408
+
409
+ $defaultargs = array(
410
+ // 'post_type' => constant("Advanced_Ads::POST_TYPE_SLUG"),
411
+ 'page' => 'advanced-ads-groups',
412
+ );
413
+ $args = $args + $defaultargs;
414
+
415
+ return add_query_arg( $args, admin_url( 'admin.php' ) );
416
+ }
417
+
418
  }
admin/includes/class-ad-type.php ADDED
@@ -0,0 +1,558 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined( 'ABSPATH' ) || exit;
3
+
4
+ class Advanced_Ads_Admin_Ad_Type {
5
+ /**
6
+ * Instance of this class.
7
+ *
8
+ * @var object
9
+ */
10
+ protected static $instance = null;
11
+
12
+ /**
13
+ * post type slug
14
+ *
15
+ * @since 1.0.0
16
+ * @var string
17
+ */
18
+ protected $post_type = '';
19
+
20
+ private function __construct() {
21
+ // registering custom columns needs to work with and without DOING_AJAX
22
+ add_filter( 'manage_advanced_ads_posts_columns', array($this, 'ad_list_columns_head') ); // extra column
23
+ add_filter( 'manage_advanced_ads_posts_custom_column', array($this, 'ad_list_columns_content'), 10, 2 ); // extra column
24
+ add_filter( 'manage_advanced_ads_posts_custom_column', array($this, 'ad_list_columns_timing'), 10, 2 ); // extra column
25
+ add_action( 'restrict_manage_posts', array( $this, 'ad_list_add_filters') );
26
+
27
+ // ad updated messages
28
+ add_filter( 'bulk_post_updated_messages', array($this, 'ad_bulk_update_messages'), 10, 2 );
29
+
30
+ // handling (ad) lists
31
+ add_filter( 'request', array($this, 'ad_list_request') ); // order ads by title, not ID
32
+ add_action( 'all_admin_notices', array($this, 'no_ads_yet_notice') );
33
+
34
+ // save ads post type
35
+ add_action( 'save_post', array($this, 'save_ad') );
36
+ // delete ads post type
37
+ add_action( 'delete_post', array($this, 'delete_ad') );
38
+
39
+ // on post/ad edit screen
40
+ add_action( 'edit_form_top', array($this, 'edit_form_above_title') );
41
+ add_action( 'edit_form_after_title', array($this, 'edit_form_below_title') );
42
+ add_action( 'dbx_post_sidebar', array($this, 'edit_form_end') );
43
+ add_action( 'post_submitbox_misc_actions', array($this, 'add_submit_box_meta') );
44
+
45
+ // ad updated messages
46
+ add_filter( 'post_updated_messages', array($this, 'ad_update_messages') );
47
+
48
+ $this->post_type = constant( 'Advanced_Ads::POST_TYPE_SLUG' );
49
+
50
+ }
51
+
52
+ /**
53
+ * Return an instance of this class.
54
+ *
55
+ * @return object A single instance of this class.
56
+ */
57
+ public static function get_instance() {
58
+ // If the single instance hasn't been set, set it now.
59
+ if ( null == self::$instance ) {
60
+ self::$instance = new self;
61
+ }
62
+
63
+ return self::$instance;
64
+ }
65
+
66
+ /**
67
+ * add heading for extra column of ads list
68
+ * remove the date column
69
+ *
70
+ * @since 1.3.3
71
+ * @param arr $columns
72
+ */
73
+ public function ad_list_columns_head( $columns ){
74
+ $new_columns = array();
75
+ if( is_array( $columns ) ){
76
+ foreach( $columns as $key => $value ) {
77
+ $new_columns[ $key ] = $value;
78
+ if ( $key == 'title' ){
79
+ $new_columns[ 'ad_details' ] = __( 'Ad Details', 'advanced-ads' );
80
+ $new_columns[ 'ad_timing' ] = __( 'Ad Planning', 'advanced-ads' );
81
+ }
82
+ }
83
+ } else {
84
+ $new_columns[ 'ad_details' ] = __( 'Ad Details', 'advanced-ads' );
85
+ $new_columns[ 'ad_timing' ] = __( 'Ad Planning', 'advanced-ads' );
86
+ }
87
+
88
+ // white-listed columns
89
+ $whitelist = apply_filters( 'advanced-ads-ad-list-allowed-columns', array(
90
+ 'cb', // checkbox
91
+ 'title',
92
+ 'ad_details',
93
+ 'ad_timing',
94
+ 'taxonomy-advanced_ads_groups',
95
+ ) );
96
+
97
+ // remove non-white-listed columns
98
+ foreach( $new_columns as $_key => $_value ){
99
+ if( ! in_array( $_key, $whitelist ) ){
100
+ unset( $new_columns[ $_key ] );
101
+ }
102
+ }
103
+
104
+ return $new_columns;
105
+ }
106
+
107
+ /**
108
+ * display ad details in ads list
109
+ *
110
+ * @since 1.3.3
111
+ * @param string $column_name name of the column
112
+ * @param int $ad_id id of the ad
113
+ */
114
+ public function ad_list_columns_content($column_name, $ad_id) {
115
+ if ( $column_name == 'ad_details' ) {
116
+ $ad = new Advanced_Ads_Ad( $ad_id );
117
+
118
+ // load ad type title
119
+ $types = Advanced_Ads::get_instance()->ad_types;
120
+ $type = ( ! empty($types[$ad->type]->title)) ? $types[$ad->type]->title : 0;
121
+
122
+ // load ad size
123
+ $size = 0;
124
+ if ( ! empty($ad->width) || ! empty($ad->height) ) {
125
+ $size = sprintf( '%d x %d', $ad->width, $ad->height );
126
+ }
127
+
128
+ $size = apply_filters( 'advanced-ads-list-ad-size', $size, $ad );
129
+
130
+ include ADVADS_BASE_PATH . 'admin/views/ad-list-details-column.php';
131
+ }
132
+ }
133
+
134
+ /**
135
+ * display ad details in ads list
136
+ *
137
+ * @since 1.6.11
138
+ * @param string $column_name name of the column
139
+ * @param int $ad_id id of the ad
140
+ */
141
+ public function ad_list_columns_timing($column_name, $ad_id) {
142
+ if ( $column_name == 'ad_timing' ) {
143
+ $ad = new Advanced_Ads_Ad( $ad_id );
144
+
145
+ $expiry = false;
146
+ $post_future = false;
147
+ $post_start = get_the_date('U', $ad->id );
148
+ $html_classes = 'advads-filter-timing';
149
+ $expiry_date_format = get_option( 'date_format' ). ', ' . get_option( 'time_format' );
150
+
151
+ if( isset( $ad->expiry_date ) && $ad->expiry_date ){
152
+ $html_classes .= ' advads-filter-any-exp-date';
153
+
154
+ $expiry = $ad->expiry_date;
155
+ if( $ad->expiry_date < time() ){
156
+ $html_classes .= ' advads-filter-expired';
157
+ }
158
+ }
159
+ if( $post_start > time() ){
160
+ $post_future = $post_start;
161
+ $html_classes .= ' advads-filter-future';
162
+ }
163
+
164
+ include ADVADS_BASE_PATH . 'admin/views/ad-list-timing-column.php';
165
+ }
166
+ }
167
+
168
+ /**
169
+ * adds filter dropdowns before the 'Filter' button on the ad list table
170
+ */
171
+ function ad_list_add_filters() {
172
+ $screen = get_current_screen();
173
+ if ( ! isset( $screen->id ) || $screen->id !== 'edit-advanced_ads' ) {
174
+ return;
175
+ }
176
+
177
+ include ADVADS_BASE_PATH . 'admin/views/ad-list-filters.php';
178
+ }
179
+
180
+ /**
181
+ * edit ad bulk update messages
182
+ *
183
+ * @since 1.4.7
184
+ * @param arr $messages existing bulk update messages
185
+ * @param arr $counts numbers of updated ads
186
+ * @return arr $messages
187
+ *
188
+ * @see wp-admin/edit.php
189
+ */
190
+ public function ad_bulk_update_messages(array $messages, array $counts){
191
+ $post = get_post();
192
+
193
+ $messages[Advanced_Ads::POST_TYPE_SLUG] = array(
194
+ 'updated' => _n( '%s ad updated.', '%s ads updated.', $counts['updated'] ),
195
+ 'locked' => _n( '%s ad not updated, somebody is editing it.', '%s ads not updated, somebody is editing them.', $counts['locked'] ),
196
+ 'deleted' => _n( '%s ad permanently deleted.', '%s ads permanently deleted.', $counts['deleted'] ),
197
+ 'trashed' => _n( '%s ad moved to the Trash.', '%s ads moved to the Trash.', $counts['trashed'] ),
198
+ 'untrashed' => _n( '%s ad restored from the Trash.', '%s ads restored from the Trash.', $counts['untrashed'] ),
199
+ );
200
+
201
+ return $messages;
202
+ }
203
+
204
+ /**
205
+ * order ads by title on ads list
206
+ *
207
+ * @since 1.3.18
208
+ * @param arr $vars array with request vars
209
+ */
210
+ public function ad_list_request($vars){
211
+
212
+ // order ads by title on ads list
213
+ if ( is_admin() && empty( $vars['orderby'] ) && $this->post_type == $vars['post_type'] ) {
214
+ $vars = array_merge( $vars, array(
215
+ 'orderby' => 'title',
216
+ 'order' => 'ASC'
217
+ ) );
218
+ }
219
+
220
+ return $vars;
221
+ }
222
+
223
+ /**
224
+ * show instructions to create first ad above the ad list
225
+ *
226
+ * @return type
227
+ */
228
+ public function no_ads_yet_notice(){
229
+ $screen = get_current_screen();
230
+ if ( ! isset( $screen->id ) || $screen->id !== 'edit-advanced_ads' ) {
231
+ return;
232
+ }
233
+
234
+ // get number of ads
235
+ $recent_ads = Advanced_Ads::get_instance()->get_model()->get_ads();
236
+
237
+ // only display if there are no more than 2 ads
238
+ if( 3 > count( $recent_ads ) ){
239
+ include ADVADS_BASE_PATH . 'admin/views/ad-list-no-ads.php';
240
+ }
241
+ }
242
+
243
+
244
+ /**
245
+ * prepare the ad post type to be saved
246
+ *
247
+ * @since 1.0.0
248
+ * @param int $post_id id of the post
249
+ * @todo handling this more dynamic based on ad type
250
+ */
251
+ public function save_ad($post_id) {
252
+
253
+ // only use for ads, no other post type
254
+ if ( ! isset($_POST['post_type']) || $this->post_type != $_POST['post_type'] || ! isset($_POST['advanced_ad']['type']) ) {
255
+ return;
256
+ }
257
+
258
+ // don’t do this on revisions
259
+ if ( wp_is_post_revision( $post_id ) ) {
260
+ return;
261
+ }
262
+
263
+ // get ad object
264
+ $ad = new Advanced_Ads_Ad( $post_id );
265
+ if ( ! $ad instanceof Advanced_Ads_Ad ) {
266
+ return;
267
+ }
268
+
269
+ // filter to allow change of submitted ad settings
270
+ $_POST['advanced_ad'] = apply_filters( 'advanced-ads-ad-settings-pre-save', $_POST['advanced_ad'] );
271
+
272
+ $ad->type = $_POST['advanced_ad']['type'];
273
+ if ( isset($_POST['advanced_ad']['output']) ) {
274
+ $ad->set_option( 'output', $_POST['advanced_ad']['output'] );
275
+ } else {
276
+ $ad->set_option( 'output', array() );
277
+ }
278
+ /**
279
+ * deprecated since introduction of "visitors" in 1.5.4
280
+ */
281
+ if ( isset($_POST['advanced_ad']['visitor']) ) {
282
+ $ad->set_option( 'visitor', $_POST['advanced_ad']['visitor'] );
283
+ } else {
284
+ $ad->set_option( 'visitor', array() );
285
+ }
286
+ // visitor conditions
287
+ if ( isset($_POST['advanced_ad']['visitors']) ) {
288
+ $ad->set_option( 'visitors', $_POST['advanced_ad']['visitors'] );
289
+ } else {
290
+ $ad->set_option( 'visitors', array() );
291
+ }
292
+ $ad->url = 0;
293
+ if ( isset($_POST['advanced_ad']['url']) ) {
294
+ $ad->url = esc_url( $_POST['advanced_ad']['url'] );
295
+ }
296
+ // save size
297
+ $ad->width = 0;
298
+ if ( isset($_POST['advanced_ad']['width']) ) {
299
+ $ad->width = absint( $_POST['advanced_ad']['width'] );
300
+ }
301
+ $ad->height = 0;
302
+ if ( isset($_POST['advanced_ad']['height']) ) {
303
+ $ad->height = absint( $_POST['advanced_ad']['height'] );
304
+ }
305
+
306
+ if ( ! empty($_POST['advanced_ad']['description']) ) {
307
+ $ad->description = esc_textarea( $_POST['advanced_ad']['description'] ); }
308
+ else { $ad->description = ''; }
309
+
310
+ if ( ! empty($_POST['advanced_ad']['content']) ) {
311
+ $ad->content = $_POST['advanced_ad']['content']; }
312
+ else { $ad->content = ''; }
313
+
314
+ if ( ! empty($_POST['advanced_ad']['conditions']) ){
315
+ $ad->conditions = $_POST['advanced_ad']['conditions'];
316
+ } else {
317
+ $ad->conditions = array();
318
+ }
319
+ // prepare expiry date
320
+ if ( isset($_POST['advanced_ad']['expiry_date']['enabled']) ) {
321
+ $year = absint( $_POST['advanced_ad']['expiry_date']['year'] );
322
+ $month = absint( $_POST['advanced_ad']['expiry_date']['month'] );
323
+ $day = absint( $_POST['advanced_ad']['expiry_date']['day'] );
324
+ $hour = absint( $_POST['advanced_ad']['expiry_date']['hour'] );
325
+ $minute = absint( $_POST['advanced_ad']['expiry_date']['minute'] );
326
+
327
+ $expiration_date = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $year, $month, $day, $hour, $minute, '00' );
328
+ $valid_date = wp_checkdate( $month, $day, $year, $expiration_date );
329
+
330
+ if ( !$valid_date ) {
331
+ $ad->expiry_date = 0;
332
+ } else {
333
+ $_gmDate = date_create( $expiration_date, Advanced_Ads_Admin::get_wp_timezone() );
334
+ $_gmDate->setTimezone( new DateTimeZone( 'UTC' ) );
335
+ $gmDate = $_gmDate->format( 'Y-m-d-H-i' );
336
+ list( $year, $month, $day, $hour, $minute ) = explode( '-', $gmDate );
337
+ $ad->expiry_date = gmmktime($hour, $minute, 0, $month, $day, $year);
338
+ }
339
+ } else {
340
+ $ad->expiry_date = 0;
341
+ }
342
+
343
+ $image_id = ( isset( $_POST['advanced_ad']['output']['image_id'] ) ) ? absint( $_POST['advanced_ad']['output']['image_id'] ) : 0;
344
+ if ( $image_id ) {
345
+ $all_posts_id = get_post_meta( $image_id, '_advanced-ads_parent_id' );
346
+
347
+ if ( ! in_array ( $post_id, $all_posts_id ) ) {
348
+ add_post_meta( $image_id, '_advanced-ads_parent_id', $post_id, false );
349
+ }
350
+ }
351
+
352
+ $ad->save();
353
+ }
354
+
355
+ /**
356
+ * prepare the ad post type to be removed
357
+ *
358
+ * @param int $post_id id of the post
359
+ */
360
+ public function delete_ad( $post_id ) {
361
+ global $wpdb;
362
+
363
+ if ( ! current_user_can( 'delete_posts' ) ) {
364
+ return;
365
+ }
366
+
367
+ if ( $post_id > 0 ) {
368
+ $post_type = get_post_type( $post_id );
369
+ if ( $post_type == $this->post_type ) {
370
+ $wpdb->query(
371
+ $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %d", '_advanced-ads_parent_id', $post_id )
372
+ );
373
+ }
374
+ }
375
+ }
376
+
377
+ /**
378
+ * add information above the ad title
379
+ *
380
+ * @since 1.5.6
381
+ * @param obj $post
382
+ */
383
+ public function edit_form_above_title($post){
384
+ if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
385
+ return;
386
+ }
387
+ $ad = new Advanced_Ads_Ad( $post->ID );
388
+
389
+ include ADVADS_BASE_PATH . 'admin/views/ad-info-top.php';
390
+ }
391
+
392
+ /**
393
+ * add information about the ad below the ad title
394
+ *
395
+ * @since 1.1.0
396
+ * @param obj $post
397
+ */
398
+ public function edit_form_below_title($post){
399
+ if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
400
+ return;
401
+ }
402
+ $ad = new Advanced_Ads_Ad( $post->ID );
403
+
404
+ include ADVADS_BASE_PATH . 'admin/views/ad-info.php';
405
+ }
406
+
407
+ /**
408
+ * add information below the ad edit form
409
+ *
410
+ * @since 1.7.3
411
+ * @param obj $post
412
+ */
413
+ public function edit_form_end($post){
414
+ if ( ! isset($post->post_type) || $post->post_type != $this->post_type ) {
415
+ return;
416
+ }
417
+
418
+ include ADVADS_BASE_PATH . 'admin/views/ad-info-bottom.php';
419
+ }
420
+
421
+ /**
422
+ * add meta values below submit box
423
+ *
424
+ * @since 1.3.15
425
+ */
426
+ public function add_submit_box_meta(){
427
+ global $post, $wp_locale;
428
+
429
+ if ( $post->post_type !== Advanced_Ads::POST_TYPE_SLUG ) { return; }
430
+
431
+ $ad = new Advanced_Ads_Ad( $post->ID );
432
+
433
+ // get time set for ad or current timestamp (both GMT)
434
+ $utc_ts = $ad->expiry_date ? $ad->expiry_date : time();
435
+ $utc_time = date_create( '@' . $utc_ts );
436
+ $tz_option = get_option( 'timezone_string' );
437
+ $exp_time = clone( $utc_time );
438
+
439
+ if ( $tz_option ) {
440
+ $exp_time->setTimezone( Advanced_Ads_Admin::get_wp_timezone() );
441
+ } else {
442
+ $tz_name = Advanced_Ads_Admin::timezone_get_name( Advanced_Ads_Admin::get_wp_timezone() );
443
+ $tz_offset = substr( $tz_name, 3 );
444
+ $off_time = date_create( $utc_time->format( 'Y-m-d\TH:i:s' ) . $tz_offset );
445
+ $offset_in_sec = date_offset_get( $off_time );
446
+ $exp_time = date_create( '@' . ( $utc_ts + $offset_in_sec ) );
447
+ }
448
+
449
+ list( $curr_year, $curr_month, $curr_day, $curr_hour, $curr_minute ) = explode( '-', $exp_time->format( 'Y-m-d-H-i' ) );
450
+ $enabled = 1 - empty($ad->expiry_date);
451
+
452
+ include ADVADS_BASE_PATH . 'admin/views/ad-submitbox-meta.php';
453
+ }
454
+
455
+ /**
456
+ * edit ad update messages
457
+ *
458
+ * @since 1.4.7
459
+ * @param arr $messages existing post update messages
460
+ * @return arr $messages
461
+ *
462
+ * @see wp-admin/edit-form-advanced.php
463
+ */
464
+ public function ad_update_messages($messages = array()){
465
+ $post = get_post();
466
+
467
+ // added to hide error message caused by third party code that uses post_updated_messages filter wrong
468
+ if( ! is_array( $messages )){
469
+ return $messages;
470
+ }
471
+
472
+ $messages[Advanced_Ads::POST_TYPE_SLUG] = array(
473
+ 0 => '', // Unused. Messages start at index 1.
474
+ 1 => __( 'Ad updated.', 'advanced-ads' ),
475
+ 4 => __( 'Ad updated.', 'advanced-ads' ),
476
+ /* translators: %s: date and time of the revision */
477
+ 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Ad restored to revision from %s', 'advanced-ads' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
478
+ 6 => __( 'Ad published.', 'advanced-ads' ),
479
+ 7 => __( 'Ad saved.', 'advanced-ads' ),
480
+ 8 => __( 'Ad submitted.', 'advanced-ads' ),
481
+ 9 => sprintf(
482
+ __( 'Ad scheduled for: <strong>%1$s</strong>.', 'advanced-ads' ),
483
+ // translators: Publish box date format, see http://php.net/date
484
+ date_i18n( __( 'M j, Y @ G:i', 'advanced-ads' ), strtotime( $post->post_date ) )
485
+ ),
486
+ 10 => __( 'Ad draft updated.', 'advanced-ads' )
487
+ );
488
+ return $messages;
489
+ }
490
+
491
+ /**
492
+ * whether to show the wizard welcome message or not
493
+ *
494
+ * @since 1.7.4
495
+ * @return bool true, if wizard welcome message should be displayed
496
+ */
497
+ public function show_wizard_welcome(){
498
+ $user_id = get_current_user_id();
499
+ if( ! $user_id ) {
500
+ return true;
501
+ }
502
+
503
+ $hide_wizard = get_user_meta( $user_id, 'advanced-ads-hide-wizard', true );
504
+ global $post;
505
+
506
+ return ( ! $hide_wizard && 'edit' !== $post->filter ) ? true : false;
507
+ }
508
+
509
+ /**
510
+ * whether to start the wizard by default or not
511
+ *
512
+ * @since 1.7.4
513
+ * return bool true, if wizard should start automatically
514
+ */
515
+ public function start_wizard_automatically(){
516
+ $user_id = get_current_user_id();
517
+ if( ! $user_id ) {
518
+ return true;
519
+ }
520
+
521
+ $hide_wizard = get_user_meta( $user_id, 'advanced-ads-hide-wizard', true );
522
+ global $post;
523
+
524
+ // true if the wizard was never started or closed
525
+ return ( ( ! $hide_wizard && 'edit' !== $post->filter ) || 'false'=== $hide_wizard ) ? true : false;
526
+ }
527
+
528
+ /**
529
+ * Check if an ad is not valid for 'Post Content' placement
530
+ *
531
+ * @param obj $ad Advanced_Ads_Ad object
532
+ * @return string with error if not valid, bool false if valid
533
+ */
534
+ public static function check_ad_dom_is_not_valid( Advanced_Ads_Ad $ad ) {
535
+ $adContent = ( isset( $ad->content ) ) ? $ad->content : '';
536
+ if ( ! $adContent ) {
537
+ return false;
538
+ }
539
+
540
+ $wpCharset = get_bloginfo('charset');
541
+ $adDom = new DOMDocument('1.0', $wpCharset);
542
+
543
+ $libxml_previous_state = libxml_use_internal_errors( true );
544
+ // clear existing errors
545
+ libxml_clear_errors();
546
+ // source for this regex: http://stackoverflow.com/questions/17852537/preg-replace-only-specific-part-of-string
547
+ $adContent = preg_replace('#(document.write.+)</(.*)#', '$1<\/$2', $adContent); // escapes all closing html tags
548
+ $adDom->loadHtml('<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=' . $wpCharset . '" /><body>' . $adContent);
549
+ // log errors
550
+ if( libxml_get_last_error() instanceof LibXMLError ) {
551
+ return print_r( libxml_get_last_error(), true );
552
+ }
553
+
554
+ libxml_use_internal_errors( $libxml_previous_state );
555
+ return false;
556
+ }
557
+
558
+ }
admin/includes/class-menu.php ADDED
@@ -0,0 +1,296 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined( 'ABSPATH' ) || exit;
3
+
4
+ class Advanced_Ads_Admin_Menu {
5
+ /**
6
+ * Instance of this class.
7
+ *
8
+ * @var object
9
+ */
10
+ protected static $instance = null;
11
+
12
+ /**
13
+ * Slug of the ad group page
14
+ *
15
+ * @since 1.0.0
16
+ * @var string
17
+ */
18
+ protected $ad_group_hook_suffix = null;
19
+
20
+ private function __construct() {
21
+ // Add menu items
22
+ add_action( 'admin_menu', array($this, 'add_plugin_admin_menu') );
23
+ add_action( 'admin_head', array( $this, 'highlight_menu_item' ) );
24
+
25
+ $this->plugin_slug = Advanced_Ads::get_instance()->get_plugin_slug();
26
+ $this->post_type = constant( 'Advanced_Ads::POST_TYPE_SLUG' );
27
+ }
28
+
29
+ /**
30
+ * Return an instance of this class.
31
+ *
32
+ * @return object A single instance of this class.
33
+ */
34
+ public static function get_instance() {
35
+ // If the single instance hasn't been set, set it now.
36
+ if ( null == self::$instance ) {
37
+ self::$instance = new self;
38
+ }
39
+
40
+ return self::$instance;
41
+ }
42
+
43
+ /**
44
+ * Register the administration menu for this plugin into the WordPress Dashboard menu.
45
+ *
46
+ * @since 1.0.0
47
+ */
48
+ public function add_plugin_admin_menu() {
49
+
50
+ // add main menu item with overview page
51
+ add_menu_page(
52
+ __( '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'
53
+ );
54
+
55
+ add_submenu_page(
56
+ $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
57
+ );
58
+
59
+ // hidden by css; not placed in 'options.php' in order to highlight the correct item, see the 'highlight_menu_item()'
60
+ if ( ! current_user_can( 'edit_posts' ) ) {
61
+ add_submenu_page(
62
+ $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
63
+ );
64
+ }
65
+
66
+ $this->ad_group_hook_suffix = add_submenu_page(
67
+ $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')
68
+ );
69
+
70
+ // add placements page
71
+ add_submenu_page(
72
+ $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')
73
+ );
74
+ // add settings page
75
+ Advanced_Ads_Admin::get_instance()->plugin_screen_hook_suffix = add_submenu_page(
76
+ $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')
77
+ );
78
+ add_submenu_page(
79
+ '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')
80
+ );
81
+ // intro page
82
+ add_submenu_page(
83
+ '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')
84
+ );
85
+ // add support page
86
+ add_submenu_page(
87
+ $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')
88
+ );
89
+
90
+ // allows extensions to insert sub menu pages
91
+ do_action( 'advanced-ads-submenu-pages', $this->plugin_slug );
92
+ }
93
+
94
+ /**
95
+ * Highlights the 'Advanced Ads->Ads' item in the menu when an ad edit page is open
96
+ * @see the 'parent_file' and the 'submenu_file' filters for reference
97
+ */
98
+ public function highlight_menu_item() {
99
+ global $parent_file, $submenu_file, $post_type;
100
+ if ( $post_type === $this->post_type ) {
101
+ $parent_file = $this->plugin_slug;
102
+ $submenu_file = 'edit.php?post_type=' . $this->post_type;
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Render the overview page
108
+ *
109
+ * @since 1.2.2
110
+ */
111
+ public function display_overview_page() {
112
+
113
+ $screen = get_current_screen();
114
+
115
+ // set up overview widgets
116
+ Advanced_Ads_Overview_Widgets_Callbacks::setup_overview_widgets( $screen );
117
+
118
+ // convert from vertical order to horizontal
119
+ $screen->add_option( 'layout_columns', 1 );
120
+
121
+ include ADVADS_BASE_PATH . 'admin/views/overview.php';
122
+ }
123
+
124
+ /**
125
+ * Render the settings page
126
+ *
127
+ * @since 1.0.0
128
+ */
129
+ public function display_plugin_settings_page() {
130
+ include ADVADS_BASE_PATH . 'admin/views/settings.php';
131
+ }
132
+
133
+ /**
134
+ * Render the placements page
135
+ *
136
+ * @since 1.1.0
137
+ */
138
+ public function display_placements_page() {
139
+ $placement_types = Advanced_Ads_Placements::get_placement_types();
140
+ $placements = Advanced_Ads::get_ad_placements_array(); // -TODO use model
141
+ $items = Advanced_Ads_Placements::items_for_select();
142
+ // load ads and groups for select field
143
+
144
+ // display view
145
+ include ADVADS_BASE_PATH . 'admin/views/placements.php';
146
+ }
147
+
148
+ /**
149
+ * Render the debug page
150
+ *
151
+ * @since 1.0.1
152
+ */
153
+ public function display_plugin_debug_page() {
154
+ // load array with ads by condition
155
+ $plugin = Advanced_Ads::get_instance();
156
+ $plugin_options = $plugin->options();
157
+ $ad_placements = Advanced_Ads::get_ad_placements_array(); // -TODO use model
158
+
159
+ include ADVADS_BASE_PATH . 'admin/views/debug.php';
160
+ }
161
+
162
+ /**
163
+ * Render intro page
164
+ *
165
+ * @since 1.6.8.2
166
+ */
167
+ public function display_plugin_intro_page() {
168
+ // load array with ads by condition
169
+
170
+ // remove intro message from queue
171
+ Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue('nl_intro');
172
+
173
+ include ADVADS_BASE_PATH . 'admin/views/intro.php';
174
+ }
175
+
176
+ /**
177
+ * Render the support page
178
+ *
179
+ * @since 1.6.8.1
180
+ */
181
+ public function display_support_page() {
182
+ // process email
183
+
184
+ $mail_sent = false;
185
+ $sent_errors = array();
186
+ global $current_user;
187
+ $user = wp_get_current_user();
188
+
189
+ $email = $user->user_email !== '' ? $user->user_email : '';
190
+ $name = $user->first_name !== '' ? $user->first_name . ' ' . $user->last_name : $user->user_login;
191
+ $message = '';
192
+
193
+ if( isset( $_POST['advads_support']['email'] ) ){
194
+
195
+ $email = trim( $_POST['advads_support']['email'] );
196
+ $name = trim( $_POST['advads_support']['name'] );
197
+ $message = trim( $_POST['advads_support']['message'] );
198
+ if( '' === $message ){
199
+ $sent_errors[] = __('Please enter a message', 'advanced-ads');
200
+ }
201
+ if( is_email( $email ) ){
202
+ $headers = 'From: '. $name .' <' . $email . '>' . "\r\n";
203
+ $content = $message;
204
+ $content .= "\r\n\r\n Name: " . $name;
205
+ $content .= "\r\n URL: " . home_url();
206
+
207
+ $mail_sent = wp_mail( 'support@wpadvancedads.com', 'Support for ' . home_url(), $content, $headers );
208
+ if( ! $mail_sent ){
209
+ $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>');
210
+ }
211
+ } else {
212
+ $sent_errors[] = __('Please enter a valid email address', 'advanced-ads');
213
+ }
214
+ }
215
+
216
+ include ADVADS_BASE_PATH . 'admin/views/support.php';
217
+ }
218
+
219
+ /**
220
+ * Render the ad group page
221
+ *
222
+ * @since 1.0.0
223
+ */
224
+ public function ad_group_admin_page() {
225
+
226
+ $taxonomy = Advanced_Ads::AD_GROUP_TAXONOMY;
227
+ $post_type = Advanced_Ads::POST_TYPE_SLUG;
228
+ $tax = get_taxonomy( $taxonomy );
229
+
230
+ $action = Advanced_Ads_Admin::get_instance()->current_action();
231
+
232
+ // handle new and updated groups
233
+ if ( 'editedgroup' == $action ) {
234
+ $group_id = (int) $_POST['group_id'];
235
+ check_admin_referer( 'update-group_' . $group_id );
236
+
237
+ if ( ! current_user_can( $tax->cap->edit_terms ) ) {
238
+ wp_die( __( 'Sorry, you are not allowed to access this feature.', 'advanced-ads' ) ); }
239
+
240
+ // handle new groups
241
+ if ( 0 == $group_id ) {
242
+ $ret = wp_insert_term( $_POST['name'], $taxonomy, $_POST );
243
+ if ( $ret && ! is_wp_error( $ret ) ) {
244
+ $forced_message = 1; }
245
+ else {
246
+ $forced_message = 4; }
247
+ // handle group updates
248
+ } else {
249
+ $tag = get_term( $group_id, $taxonomy );
250
+ if ( ! $tag ) {
251
+ wp_die( __( 'You attempted to edit an ad group that doesn&#8217;t exist. Perhaps it was deleted?', 'advanced-ads' ) ); }
252
+
253
+ $ret = wp_update_term( $group_id, $taxonomy, $_POST );
254
+ if ( $ret && ! is_wp_error( $ret ) ) {
255
+ $forced_message = 3; }
256
+ else {
257
+ $forced_message = 5; }
258
+ }
259
+ // deleting items
260
+ } elseif ( $action == 'delete' ){
261
+ $group_id = (int) $_REQUEST['group_id'];
262
+ check_admin_referer( 'delete-tag_' . $group_id );
263
+
264
+ if ( ! current_user_can( $tax->cap->delete_terms ) ) {
265
+ wp_die( __( 'Sorry, you are not allowed to access this feature.', 'advanced-ads' ) ); }
266
+
267
+ wp_delete_term( $group_id, $taxonomy );
268
+
269
+ $forced_message = 2;
270
+ }
271
+
272
+ // handle views
273
+ switch ( $action ) {
274
+ case 'edit' :
275
+ $title = $tax->labels->edit_item;
276
+ if ( isset($_REQUEST['group_id']) ) {
277
+ $group_id = absint( $_REQUEST['group_id'] );
278
+ $tag = get_term( $group_id, $taxonomy, OBJECT, 'edit' );
279
+ } else {
280
+ $group_id = 0;
281
+ $tag = false;
282
+ }
283
+
284
+ include ADVADS_BASE_PATH . 'admin/views/ad-group-edit.php';
285
+ break;
286
+
287
+ default :
288
+ $title = $tax->labels->name;
289
+ $wp_list_table = _get_list_table( 'WP_Terms_List_Table' );
290
+
291
+ // load template
292
+ include ADVADS_BASE_PATH . 'admin/views/ad-group.php';
293
+ }
294
+ }
295
+
296
+ }
admin/includes/class-meta-box.php ADDED
@@ -0,0 +1,380 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined( 'ABSPATH' ) || exit;
3
+
4
+ class Advanced_Ads_Admin_Meta_Boxes {
5
+ /**
6
+ * Instance of this class.
7
+ *
8
+ * @var object
9
+ */
10
+ protected static $instance = null;
11
+
12
+ /**
13
+ * meta box ids
14
+ *
15
+ * @since 1.7.4.2
16
+ * @var array
17
+ */
18
+ protected $meta_box_ids = array();
19
+
20
+
21
+ private function __construct() {
22
+ add_action( 'admin_init', array( $this, 'add_meta_boxes' ) );
23
+ // add meta box for post types edit pages
24
+ add_action( 'add_meta_boxes', array( $this, 'add_post_meta_box' ) );
25
+ add_action( 'save_post', array( $this, 'save_post_meta_box' ) );
26
+ // register dashboard widget
27
+ add_action( 'wp_dashboard_setup', array($this, 'add_dashboard_widget') );
28
+ }
29
+
30
+ /**
31
+ * Return an instance of this class.
32
+ *
33
+ * @return object A single instance of this class.
34
+ */
35
+ public static function get_instance() {
36
+ // If the single instance hasn't been set, set it now.
37
+ if ( null == self::$instance ) {
38
+ self::$instance = new self;
39
+ }
40
+
41
+ return self::$instance;
42
+ }
43
+
44
+ /**
45
+ * Add meta boxes
46
+ *
47
+ * @since 1.0.0
48
+ */
49
+ public function add_meta_boxes() {
50
+ add_meta_box(
51
+ 'ad-main-box', __( 'Ad Type', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
52
+ );
53
+ // use dynamic filter from to add close class to ad type meta box after saved first time
54
+ add_filter( 'postbox_classes_advanced_ads_ad-main-box', array( $this, 'close_ad_type_metabox' ) );
55
+
56
+ add_meta_box(
57
+ 'ad-parameters-box', __( 'Ad Parameters', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
58
+ );
59
+ add_meta_box(
60
+ 'ad-output-box', __( 'Layout / Output', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
61
+ );
62
+ add_meta_box(
63
+ 'ad-display-box', __( 'Display Conditions', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
64
+ );
65
+ add_meta_box(
66
+ 'ad-visitor-box', __( 'Visitor Conditions', 'advanced-ads' ), array($this, 'markup_meta_boxes'), Advanced_Ads::POST_TYPE_SLUG, 'normal', 'high'
67
+ );
68
+
69
+ // register meta box ids
70
+ $this->meta_box_ids = array(
71
+ 'ad-main-box',
72
+ 'ad-parameters-box',
73
+ 'ad-output-box',
74
+ 'ad-display-box',
75
+ 'ad-visitor-box',
76
+ 'advanced_ads_groupsdiv' // automatically added by ad groups taxonomy
77
+ );
78
+
79
+ // force AA meta boxes to never be completely hidden by screen options
80
+ add_filter( 'hidden_meta_boxes', array( $this, 'unhide_meta_boxes' ), 10, 2 );
81
+ }
82
+
83
+ /**
84
+ * load templates for all meta boxes
85
+ *
86
+ * @since 1.0.0
87
+ * @param obj $post
88
+ * @param array $box
89
+ * @todo move ad initialization to main function and just global it
90
+ */
91
+ public function markup_meta_boxes($post, $box) {
92
+ $ad = new Advanced_Ads_Ad( $post->ID );
93
+
94
+ switch ( $box['id'] ) {
95
+ case 'ad-main-box':
96
+ $view = 'ad-main-metabox.php';
97
+ $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>';
98
+ break;
99
+ case 'ad-parameters-box':
100
+ $view = 'ad-parameters-metabox.php';
101
+ break;
102
+ case 'ad-output-box':
103
+ $view = 'ad-output-metabox.php';
104
+ break;
105
+ case 'ad-display-box':
106
+ $view = 'ad-display-metabox.php';
107
+ $hndlelinks = '<a href="#" class="advads-video-link">' . __('Video', 'advanced-ads') . '</a>';
108
+ $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>';
109
+ $videomarkup = '<iframe width="420" height="315" src="https://www.youtube-nocookie.com/embed/wVB6UpeyWNA?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe>';
110
+ break;
111
+ case 'ad-visitor-box':
112
+ $view = 'ad-visitor-metabox.php';
113
+ $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>';
114
+ break;
115
+ }
116
+
117
+ if ( ! isset( $view ) ) {
118
+ return;
119
+ }
120
+ // markup moved to handle headline of the metabox
121
+ if( isset( $hndlelinks ) ){
122
+ ?><span class="advads-hndlelinks hidden"><?php echo $hndlelinks; ?></span>
123
+ <?php
124
+ }
125
+ // show video markup
126
+ if( isset( $videomarkup ) ){
127
+ echo '<div class="advads-video-link-container" data-videolink=\'' . $videomarkup . '\'></div>';
128
+ }
129
+ include ADVADS_BASE_PATH . 'admin/views/' . $view;
130
+ }
131
+
132
+ /**
133
+ * force all AA related meta boxes to stay visible
134
+ *
135
+ * @since 1.7.4.2
136
+ * @param array $hidden An array of hidden meta boxes
137
+ * @param WP_Screen $screen WP_Screen object of the current screen
138
+ */
139
+ public function unhide_meta_boxes( $hidden, $screen ){
140
+ // only check on Advanced Ads edit screen
141
+ if ( ! isset( $screen->id ) || $screen->id !== 'advanced_ads' || !is_array( $this->meta_box_ids ) ) {
142
+ return $hidden;
143
+ }
144
+
145
+ // return only hidden elements which are not among the Advanced Ads meta box ids
146
+ return array_diff( $hidden, $this->meta_box_ids );
147
+ }
148
+
149
+ /**
150
+ * add a meta box to post type edit screens with ad settings
151
+ *
152
+ * @since 1.3.10
153
+ * @param string $post_type current post type
154
+ */
155
+ public function add_post_meta_box($post_type = ''){
156
+ // don’t display for non admins
157
+ if( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads') ) ) {
158
+ return;
159
+ }
160
+
161
+ // get public post types
162
+ $public_post_types = get_post_types( array('public' => true, 'publicly_queryable' => true), 'names', 'or' );
163
+
164
+ //limit meta box to public post types
165
+ if ( in_array( $post_type, $public_post_types ) ) {
166
+ add_meta_box(
167
+ 'advads-ad-settings',
168
+ __( 'Ad Settings', 'advanced-ads' ),
169
+ array( $this, 'render_post_meta_box' ),
170
+ $post_type,
171
+ 'advanced',
172
+ 'low'
173
+ );
174
+ }
175
+ }
176
+
177
+ /**
178
+ * render meta box for ad settings on a per post basis
179
+ *
180
+ * @since 1.3.10
181
+ * @param WP_Post $post The post object.
182
+ */
183
+ public function render_post_meta_box( $post ) {
184
+
185
+ // nonce field to check when we save the values
186
+ wp_nonce_field( 'advads_post_meta_box', 'advads_post_meta_box_nonce' );
187
+
188
+ // retrieve an existing value from the database.
189
+ $values = get_post_meta( $post->ID, '_advads_ad_settings', true );
190
+
191
+ // load the view
192
+ include ADVADS_BASE_PATH . 'admin/views/post-ad-settings-metabox.php';
193
+ }
194
+
195
+ /**
196
+ * save the ad meta when the post is saved.
197
+ *
198
+ * @since 1.3.10
199
+ * @param int $post_id The ID of the post being saved.
200
+ */
201
+ public function save_post_meta_box( $post_id ) {
202
+
203
+ if( ! current_user_can( Advanced_Ads_Plugin::user_cap( 'advanced_ads_edit_ads') ) ) {
204
+ return;
205
+ }
206
+
207
+ // check nonce
208
+ if ( ! isset( $_POST['advads_post_meta_box_nonce'] ) ) {
209
+ return $post_id; }
210
+
211
+ $nonce = $_POST['advads_post_meta_box_nonce'];
212
+
213
+ // Verify that the nonce is valid.
214
+ if ( ! wp_verify_nonce( $nonce, 'advads_post_meta_box' ) ) {
215
+ return $post_id; }
216
+
217
+ // don’t save on autosave
218
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
219
+ return $post_id; }
220
+
221
+ // check the user's permissions.
222
+ if ( 'page' == $_POST['post_type'] ) {
223
+ if ( ! current_user_can( 'edit_page', $post_id ) ) {
224
+ return $post_id; }
225
+ } else {
226
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
227
+ return $post_id; }
228
+ }
229
+
230
+ // Sanitize the user input.
231
+ $_data['disable_ads'] = isset($_POST['advanced_ads']['disable_ads']) ? absint( $_POST['advanced_ads']['disable_ads'] ) : 0;
232
+
233
+ // Update the meta field.
234
+ update_post_meta( $post_id, '_advads_ad_settings', $_data );
235
+ }
236
+
237
+ /**
238
+ * add "close" class to collapse the ad-type metabox after ad was saved first
239
+ *
240
+ * @since 1.7.2
241
+ * @param arr $classes
242
+ * @return arr $classes
243
+ */
244
+ public function close_ad_type_metabox( $classes = array() ) {
245
+ global $post;
246
+ if ( isset( $post->ID ) && 'edit' === $post->filter ) {
247
+ if ( ! in_array( 'closed', $classes ) ) {
248
+ $classes[] = 'closed';
249
+ }
250
+ } else {
251
+ $classes = array();
252
+ }
253
+ return $classes;
254
+ }
255
+
256
+ /**
257
+ * add dashboard widget with ad stats and additional information
258
+ *
259
+ * @since 1.3.12
260
+ */
261
+ public function add_dashboard_widget(){
262
+ // display dashboard widget only to authors and higher roles
263
+ if( ! current_user_can('publish_posts') ) {
264
+ return;
265
+ }
266
+ add_meta_box( 'advads_dashboard_widget', __( 'Ads Dashboard', 'advanced-ads' ), array($this, 'dashboard_widget_function'), 'dashboard', 'side', 'high' );
267
+ }
268
+
269
+ /**
270
+ * display widget functions
271
+ */
272
+ public static function dashboard_widget_function($post, $callback_args){
273
+ // load ad optimization feed
274
+ $feeds = array(
275
+ array(
276
+ 'link' => 'http://webgilde.com/en/ad-optimization/',
277
+ 'url' => 'http://webgilde.com/en/ad-optimization/feed/',
278
+ 'title' => __( 'From the ad optimization universe', 'advanced-ads' ),
279
+ 'items' => 2,
280
+ 'show_summary' => 0,
281
+ 'show_author' => 0,
282
+ 'show_date' => 0,
283
+ ),
284
+ array(
285
+ 'link' => ADVADS_URL,
286
+ 'url' => ADVADS_URL . 'feed/',
287
+ 'title' => __( 'Advanced Ads Tutorials', 'advanced-ads' ),
288
+ 'items' => 2,
289
+ 'show_summary' => 0,
290
+ 'show_author' => 0,
291
+ 'show_date' => 0,
292
+ ),
293
+ );
294
+
295
+ // get number of ads
296
+ $recent_ads = Advanced_Ads::get_instance()->get_model()->get_ads();
297
+ echo '<p>';
298
+ printf(__( '%d ads – <a href="%s">manage</a> - <a href="%s">new</a>', 'advanced-ads' ),
299
+ count( $recent_ads ),
300
+ 'edit.php?post_type='. Advanced_Ads::POST_TYPE_SLUG,
301
+ 'post-new.php?post_type='. Advanced_Ads::POST_TYPE_SLUG);
302
+ echo '</p>';
303
+
304
+ // get and display plugin version
305
+ $advads_plugin_data = get_plugin_data( ADVADS_BASE_PATH . 'advanced-ads.php' );
306
+ if ( isset($advads_plugin_data['Version']) ){
307
+ $version = $advads_plugin_data['Version'];
308
+ echo '<p><a href="'.ADVADS_URL.'#utm_source=advanced-ads&utm_medium=link&utm_campaign=dashboard" target="_blank" title="'.
309
+ __( 'plugin manual and homepage', 'advanced-ads' ).'">Advanced Ads</a> '. $version .'</p>';
310
+ }
311
+
312
+ $notice_options = Advanced_Ads_Admin_Notices::get_instance()->options();
313
+ $_notice = 'nl_first_steps';
314
+ if ( ! isset($notice_options['closed'][ $_notice ] ) ) {
315
+ ?><div class="advads-admin-notice">
316
+ <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>
317
+ </div><?php
318
+ }
319
+
320
+ $_notice = 'nl_adsense';
321
+ if ( ! isset($notice_options['closed'][ $_notice ] ) ) {
322
+ ?><div class="advads-admin-notice">
323
+ <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>
324
+ </div><?php
325
+ }
326
+
327
+ // rss feed
328
+ // $this->dashboard_widget_function_output('advads_dashboard_widget', $feed);
329
+ self::dashboard_cached_rss_widget( 'advads_dashboard_widget', array( 'self', 'dashboard_widget_function_output' ), array( 'advads' => $feeds ) );
330
+
331
+ // add markup for utm variables
332
+ // todo: move to js file
333
+ ?><script>jQuery('#advads_dashboard_widget .rss-widget a').each(function(){ this.href = this.href + '#utm_source=advanced-ads&utm_medium=rss-link&utm_campaign=dashboard'; })</script><?php
334
+ }
335
+
336
+ /**
337
+ * checks to see if there are feed urls in transient cache; if not, load them
338
+ * built using a lot of https://developer.wordpress.org/reference/functions/wp_dashboard_cached_rss_widget/
339
+ *
340
+ * @since 1.3.12
341
+ * @param string $widget_id
342
+ * @param callback $callback
343
+ * @param array $check_urls RSS feeds
344
+ * @return bool False on failure. True on success.
345
+ */
346
+ static function dashboard_cached_rss_widget( $widget_id, $callback, $feeds = array() ) {
347
+ if ( empty($feeds) ) {
348
+ return;
349
+ }
350
+
351
+ $cache_key = 'dash_' . md5( $widget_id );
352
+ if ( false !== ( $output = get_transient( $cache_key ) ) ) {
353
+ echo $output;
354
+ return true;
355
+ }
356
+ if ( $callback && is_callable( $callback ) ) {
357
+ ob_start();
358
+ call_user_func_array( $callback, $feeds );
359
+ set_transient( $cache_key, ob_get_flush(), 48 * HOUR_IN_SECONDS ); // Default lifetime in cache of 48 hours
360
+ }
361
+
362
+ return true;
363
+ }
364
+
365
+ /**
366
+ * create the rss output of the widget
367
+ *
368
+ * @param string $widget_id Widget ID.
369
+ * @param array $feeds Array of RSS feeds.
370
+ */
371
+ static function dashboard_widget_function_output( $feeds ) {
372
+ foreach ( $feeds as $_feed ){
373
+ echo '<div class="rss-widget">';
374
+ echo '<h4>'.$_feed['title'].'</h4>';
375
+ wp_widget_rss_output( $_feed['url'], $_feed );
376
+ echo '</div>';
377
+ }
378
+ }
379
+
380
+ }
admin/includes/class-settings.php ADDED
@@ -0,0 +1,443 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined( 'ABSPATH' ) || exit;
3
+
4
+ class Advanced_Ads_Admin_Settings {
5
+ /**
6
+ * Instance of this class.
7
+ *
8
+ * @var object
9
+ */
10
+ protected static $instance = null;
11
+
12
+ private function __construct() {
13
+ // settings handling
14
+ add_action( 'admin_init', array( $this, 'settings_init' ) );
15
+ }
16
+
17
+ /**
18
+ * Return an instance of this class.
19
+ *
20
+ * @return object A single instance of this class.
21
+ */
22
+ public static function get_instance() {
23
+ // If the single instance hasn't been set, set it now.
24
+ if ( null == self::$instance ) {
25
+ self::$instance = new self;
26
+ }
27
+
28
+ return self::$instance;
29
+ }
30
+
31
+ /**
32
+ * initialize settings
33
+ *
34
+ * @since 1.0.1
35
+ */
36
+ public function settings_init(){
37
+
38
+ // get settings page hook
39
+ $hook = Advanced_Ads_Admin::get_instance()->plugin_screen_hook_suffix;
40
+
41
+ // register settings
42
+ register_setting( ADVADS_SLUG, ADVADS_SLUG, array($this, 'sanitize_settings') );
43
+
44
+ // general settings section
45
+ add_settings_section(
46
+ 'advanced_ads_setting_section',
47
+ __( 'General', 'advanced-ads' ),
48
+ array($this, 'render_settings_section_callback'),
49
+ $hook
50
+ );
51
+
52
+ // licenses section only for main blog
53
+ if( is_main_site( get_current_blog_id() ) ){
54
+ // register license settings
55
+ register_setting( ADVADS_SLUG . '-licenses', ADVADS_SLUG . '-licenses' );
56
+
57
+ add_settings_section(
58
+ 'advanced_ads_settings_license_section',
59
+ __( 'Licenses', 'advanced-ads' ),
60
+ array($this, 'render_settings_licenses_section_callback'),
61
+ 'advanced-ads-settings-license-page'
62
+ );
63
+
64
+ add_filter( 'advanced-ads-setting-tabs', array( $this, 'license_tab') );
65
+ }
66
+
67
+ // add setting fields to disable ads
68
+ add_settings_field(
69
+ 'disable-ads',
70
+ __( 'Disable ads', 'advanced-ads' ),
71
+ array($this, 'render_settings_disable_ads'),
72
+ $hook,
73
+ 'advanced_ads_setting_section'
74
+ );
75
+ // add setting fields for user role
76
+ add_settings_field(
77
+ 'hide-for-user-role',
78
+ __( 'Hide ads for logged in users', 'advanced-ads' ),
79
+ array($this, 'render_settings_hide_for_users'),
80
+ $hook,
81
+ 'advanced_ads_setting_section'
82
+ );
83
+ // add setting fields for advanced js
84
+ add_settings_field(
85
+ 'activate-advanced-js',
86
+ __( 'Use advanced JavaScript', 'advanced-ads' ),
87
+ array($this, 'render_settings_advanced_js'),
88
+ $hook,
89
+ 'advanced_ads_setting_section'
90
+ );
91
+ // add setting fields for content injection protection
92
+ add_settings_field(
93
+ 'content-injection-everywhere',
94
+ __( 'Unlimited ad injection', 'advanced-ads' ),
95
+ array($this, 'render_settings_content_injection_everywhere'),
96
+ $hook,
97
+ 'advanced_ads_setting_section'
98
+ );
99
+ // add setting fields for content injection priority
100
+ add_settings_field(
101
+ 'content-injection-priority',
102
+ __( 'Priority of content injection filter', 'advanced-ads' ),
103
+ array($this, 'render_settings_content_injection_priority'),
104
+ $hook,
105
+ 'advanced_ads_setting_section'
106
+ );
107
+ // add setting fields for content injection priority
108
+ add_settings_field(
109
+ 'block-bots',
110
+ __( 'Hide ads from bots', 'advanced-ads' ),
111
+ array($this, 'render_settings_block_bots'),
112
+ $hook,
113
+ 'advanced_ads_setting_section'
114
+ );
115
+ // opt out from internal notices
116
+ add_settings_field(
117
+ 'disable-notices',
118
+ __( 'Disable notices', 'advanced-ads' ),
119
+ array($this, 'render_settings_disabled_notices'),
120
+ $hook,
121
+ 'advanced_ads_setting_section'
122
+ );
123
+ // opt out from internal notices
124
+ add_settings_field(
125
+ 'front-prefix',
126
+ __( 'ID prefix', 'advanced-ads' ),
127
+ array($this, 'render_settings_front_prefix'),
128
+ $hook,
129
+ 'advanced_ads_setting_section'
130
+ );
131
+ // remove id from widgets
132
+ add_settings_field(
133
+ 'remove-widget-id',
134
+ __( 'Remove Widget ID', 'advanced-ads' ),
135
+ array($this, 'render_settings_remove_widget_id'),
136
+ $hook,
137
+ 'advanced_ads_setting_section'
138
+ );
139
+ // allow editors to manage ads
140
+ add_settings_field(
141
+ 'editors-manage-ads',
142
+ __( 'Allow editors to manage ads', 'advanced-ads' ),
143
+ array($this, 'render_settings_editors_manage_ads'),
144
+ $hook,
145
+ 'advanced_ads_setting_section'
146
+ );
147
+
148
+ add_settings_field(
149
+ 'add-custom-label',
150
+ __( 'Ad label', 'advanced-ads' ),
151
+ array( $this, 'render_settings_add_custom_label' ),
152
+ $hook,
153
+ 'advanced_ads_setting_section'
154
+ );
155
+
156
+ // hook for additional settings from add-ons
157
+ do_action( 'advanced-ads-settings-init', $hook );
158
+ }
159
+
160
+ /**
161
+ * add license tab
162
+ *
163
+ * arr $tabs setting tabs
164
+ */
165
+ public function license_tab( array $tabs ){
166
+
167
+ $tabs['licenses'] = array(
168
+ 'page' => 'advanced-ads-settings-license-page',
169
+ 'group' => ADVADS_SLUG . '-licenses',
170
+ 'tabid' => 'licenses',
171
+ 'title' => __( 'Licenses', 'advanced-ads' )
172
+ );
173
+
174
+ return $tabs;
175
+ }
176
+
177
+ /**
178
+ * render settings section
179
+ *
180
+ * @since 1.1.1
181
+ */
182
+ public function render_settings_section_callback(){
183
+ // for whatever purpose there might come
184
+ }
185
+
186
+ /**
187
+ * render licenses settings section
188
+ *
189
+ * @since 1.5.1
190
+ */
191
+ public function render_settings_licenses_section_callback(){
192
+ 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' );
193
+ 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>';
194
+ // nonce field
195
+ echo '<input type="hidden" id="advads-licenses-ajax-referrer" value="' . wp_create_nonce( "advads_ajax_license_nonce" ) . '"/>';
196
+ }
197
+
198
+ /**
199
+ * options to disable ads
200
+ *
201
+ * @since 1.3.11
202
+ */
203
+ public function render_settings_disable_ads(){
204
+ $options = Advanced_Ads::get_instance()->options();
205
+
206
+ // set the variables
207
+ $disable_all = isset($options['disabled-ads']['all']) ? 1 : 0;
208
+ $disable_404 = isset($options['disabled-ads']['404']) ? 1 : 0;
209
+ $disable_archives = isset($options['disabled-ads']['archives']) ? 1 : 0;
210
+ $disable_secondary = isset($options['disabled-ads']['secondary']) ? 1 : 0;
211
+ $disable_feed = ( ! isset( $options['disabled-ads']['feed'] ) || $options['disabled-ads']['feed'] ) ? 1 : 0;
212
+
213
+ // load the template
214
+ include ADVADS_BASE_PATH . 'admin/views/settings-disable-ads.php';
215
+ }
216
+
217
+ /**
218
+ * render setting to hide ads from logged in users
219
+ *
220
+ * @since 1.1.1
221
+ */
222
+ public function render_settings_hide_for_users(){
223
+ $options = Advanced_Ads::get_instance()->options();
224
+ $current_capability_role = isset($options['hide-for-user-role']) ? $options['hide-for-user-role'] : 0;
225
+
226
+ $capability_roles = array(
227
+ '' => __( '(display to all)', 'advanced-ads' ),
228
+ 'read' => __( 'Subscriber', 'advanced-ads' ),
229
+ 'delete_posts' => __( 'Contributor', 'advanced-ads' ),
230
+ 'edit_posts' => __( 'Author', 'advanced-ads' ),
231
+ 'edit_pages' => __( 'Editor', 'advanced-ads' ),
232
+ 'activate_plugins' => __( 'Admin', 'advanced-ads' ),
233
+ );
234
+ echo '<select name="'.ADVADS_SLUG.'[hide-for-user-role]">';
235
+ foreach ( $capability_roles as $_capability => $_role ) {
236
+ echo '<option value="'.$_capability.'" '.selected( $_capability, $current_capability_role, false ).'>'.$_role.'</option>';
237
+ }
238
+ echo '</select>';
239
+
240
+ echo '<p class="description">'. __( 'Choose the lowest role a user must have in order to not see any ads.', 'advanced-ads' ) .'</p>';
241
+ }
242
+
243
+ /**
244
+ * render setting to display advanced js file
245
+ *
246
+ * @since 1.2.3
247
+ */
248
+ public function render_settings_advanced_js(){
249
+ $options = Advanced_Ads::get_instance()->options();
250
+ $checked = ( ! empty($options['advanced-js'])) ? 1 : 0;
251
+
252
+ // display notice if js file was overridden
253
+ if( ! $checked && apply_filters( 'advanced-ads-activate-advanced-js', $checked ) ){
254
+ echo '<p>' . __( '<strong>notice: </strong>the file is currently enabled by an add-on that needs it.', 'advanced-ads' ) . '</p>';
255
+ }
256
+ echo '<input id="advanced-ads-advanced-js" type="checkbox" value="1" name="'.ADVADS_SLUG.'[advanced-js]" '.checked( $checked, 1, false ).'>';
257
+ 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>';
258
+ }
259
+
260
+ /**
261
+ * render setting for content injection protection
262
+ *
263
+ * @since 1.4.1
264
+ */
265
+ public function render_settings_content_injection_everywhere(){
266
+ $options = Advanced_Ads::get_instance()->options();
267
+ $everywhere = ( isset($options['content-injection-everywhere']) ) ? true : false;
268
+
269
+ echo '<input id="advanced-ads-injection-everywhere" type="checkbox" value="true" name="'.ADVADS_SLUG.'[content-injection-everywhere]" '.checked( $everywhere, true, false ).'>';
270
+ 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>';
271
+
272
+ }
273
+
274
+ /**
275
+ * render setting for content injection priority
276
+ *
277
+ * @since 1.4.1
278
+ */
279
+ public function render_settings_content_injection_priority(){
280
+ $options = Advanced_Ads::get_instance()->options();
281
+ $priority = ( isset($options['content-injection-priority'])) ? intval( $options['content-injection-priority'] ) : 100;
282
+
283
+ echo '<input id="advanced-ads-content-injection-priority" type="number" value="'.$priority.'" name="'.ADVADS_SLUG.'[content-injection-priority]" size="3"/>';
284
+ echo '<p class="description">';
285
+ if ( $priority < 11 ) {
286
+ 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 />';
287
+ }
288
+ _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' );
289
+ echo '</p>';
290
+ }
291
+
292
+ /**
293
+ * render setting for blocking bots
294
+ *
295
+ * @since 1.4.9
296
+ */
297
+ public function render_settings_block_bots(){
298
+ $options = Advanced_Ads::get_instance()->options();
299
+ $checked = ( ! empty($options['block-bots'])) ? 1 : 0;
300
+
301
+ echo '<input id="advanced-ads-block-bots" type="checkbox" value="1" name="'.ADVADS_SLUG.'[block-bots]" '.checked( $checked, 1, false ).'>';
302
+ 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/>'
303
+ . __( '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>';
304
+ }
305
+
306
+ /**
307
+ * render setting to disable notices
308
+ *
309
+ * @since 1.5.3
310
+ */
311
+ public function render_settings_disabled_notices(){
312
+ $options = Advanced_Ads::get_instance()->options();
313
+ $checked = ( ! empty($options['disable-notices'])) ? 1 : 0;
314
+
315
+ echo '<input id="advanced-ads-disabled-notices" type="checkbox" value="1" name="'.ADVADS_SLUG.'[disable-notices]" '.checked( $checked, 1, false ).'>';
316
+ 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>';
317
+ }
318
+
319
+ /**
320
+ * render setting for frontend prefix
321
+ *
322
+ * @since 1.6.8
323
+ */
324
+ public function render_settings_front_prefix(){
325
+ $options = Advanced_Ads::get_instance()->options();
326
+
327
+ $prefix = Advanced_Ads_Plugin::get_instance()->get_frontend_prefix();
328
+ $old_prefix = ( isset($options['id-prefix'])) ? esc_attr( $options['id-prefix'] ) : '';
329
+
330
+ echo '<input id="advanced-ads-front-prefix" type="text" value="' .$prefix .'" name="'.ADVADS_SLUG.'[front-prefix]" />';
331
+ // deprecated
332
+ echo '<input type="hidden" value="' .$old_prefix .'" name="'.ADVADS_SLUG.'[id-prefix]" />';
333
+ 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>';
334
+ }
335
+
336
+ /**
337
+ * render setting to remove the id from advanced ads widgets
338
+ *
339
+ * @since 1.6.8.2
340
+ */
341
+ public function render_settings_remove_widget_id(){
342
+ $options = Advanced_Ads::get_instance()->options();
343
+
344
+ // is true by default if no options where previously set
345
+ if( ! isset($options['remove-widget-id']) && $options !== array() ){
346
+ $remove = false;
347
+ } elseif( $options === array() ){
348
+ $remove = true;
349
+ } else {
350
+ $remove = true;
351
+ }
352
+
353
+ echo '<input id="advanced-ads-remove-widget-id" type="checkbox" ' . checked( $remove, true, false ) . ' name="'.ADVADS_SLUG.'[remove-widget-id]" />';
354
+ echo '<p class="description">' . __( 'Remove the ID attribute from widgets in order to not make them an easy target of ad blockers.', 'advanced-ads' );
355
+
356
+ if ( class_exists( 'q2w3_fixed_widget', false ) ) {
357
+ 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' );
358
+ }
359
+
360
+ echo '</p>';
361
+ }
362
+
363
+ /**
364
+ * render setting to allow editors to manage ads
365
+ *
366
+ * @since 1.6.14
367
+ */
368
+ public function render_settings_editors_manage_ads(){
369
+ $options = Advanced_Ads::get_instance()->options();
370
+
371
+ // is false by default if no options where previously set
372
+ if( isset($options['editors-manage-ads']) && $options['editors-manage-ads'] ){
373
+ $allow = true;
374
+ } else {
375
+ $allow = false;
376
+ }
377
+
378
+ echo '<input id="advanced-ads-editors-manage-ads" type="checkbox" ' . checked( $allow, true, false ) . ' name="'.ADVADS_SLUG.'[editors-manage-ads]" />';
379
+ echo '<p class="description">'. __( 'Allow editors to also manage and publish ads.', 'advanced-ads' ) .
380
+ ' ' . 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>';
381
+ }
382
+
383
+ /**
384
+ * render setting to add an "Advertisement" label before ads
385
+ *
386
+ */
387
+ public function render_settings_add_custom_label(){
388
+ $options = Advanced_Ads::get_instance()->options();
389
+
390
+ $enabled = isset( $options['custom-label']['enabled'] );
391
+ $label = ! empty ( $options['custom-label']['text'] ) ? esc_html( $options['custom-label']['text'] ) : _x( 'Advertisements', 'label before ads' );
392
+ ?>
393
+
394
+ <fieldset>
395
+ <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]'; ?>" />
396
+ <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]'; ?>" />
397
+ </fieldset>
398
+ <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>
399
+
400
+ <?php
401
+ }
402
+
403
+ /**
404
+ * sanitize plugin settings
405
+ *
406
+ * @since 1.5.1
407
+ * @param array $options all the options
408
+ */
409
+ public function sanitize_settings($options){
410
+
411
+ // sanitize whatever option one wants to sanitize
412
+
413
+ if ( isset( $options['front-prefix'] ) ) {
414
+ $options['front-prefix'] = sanitize_html_class( $options['front-prefix'], Advanced_Ads_Plugin::DEFAULT_FRONTEND_PREFIX );
415
+ }
416
+
417
+ $options = apply_filters( 'advanced-ads-sanitize-settings', $options );
418
+
419
+ // check if editors can edit ads now and set the rights
420
+ // else, remove that right
421
+ $editor_role = get_role( 'editor' );
422
+ if( null == $editor_role ){
423
+ return $options;
424
+ }
425
+ if( isset($options['editors-manage-ads']) && $options['editors-manage-ads'] ){
426
+ $editor_role->add_cap( 'advanced_ads_see_interface' );
427
+ $editor_role->add_cap( 'advanced_ads_edit_ads' );
428
+ $editor_role->add_cap( 'advanced_ads_manage_placements' );
429
+ $editor_role->add_cap( 'advanced_ads_place_ads' );
430
+ } else {
431
+ $editor_role->remove_cap( 'advanced_ads_see_interface' );
432
+ $editor_role->remove_cap( 'advanced_ads_edit_ads' );
433
+ $editor_role->remove_cap( 'advanced_ads_manage_placements' );
434
+ $editor_role->remove_cap( 'advanced_ads_place_ads' );
435
+ }
436
+
437
+ // we need 3 states: ! isset, 1, 0
438
+ $options['disabled-ads']['feed'] = isset( $options['disabled-ads']['feed'] ) ? 1 : 0;
439
+
440
+ return $options;
441
+ }
442
+
443
+ }
admin/views/ad-group-edit.php CHANGED
@@ -22,7 +22,7 @@ do_action( "{$taxonomy}_pre_edit_form", $tag, $taxonomy );
22
  <div class="wrap">
23
  <h1><?php echo $tax->labels->edit_item; ?></h1>
24
  <div id="ajax-response"></div>
25
- <form name="editgroup" id="editgroup" method="post" action="<?php echo Advanced_Ads_Admin::group_page_url(); ?>" class="validate"<?php do_action( $taxonomy . '_term_edit_form_tag' ); ?>>
26
  <input type="hidden" name="action" value="editedgroup" />
27
  <input type="hidden" name="group_id" value="<?php echo $group_id; ?>" />
28
  <input type="hidden" name="taxonomy" value="<?php echo esc_attr( $taxonomy ) ?>" />
22
  <div class="wrap">
23
  <h1><?php echo $tax->labels->edit_item; ?></h1>
24
  <div id="ajax-response"></div>
25
+ <form name="editgroup" id="editgroup" method="post" action="<?php echo Advanced_Ads_Groups_List::group_page_url(); ?>" class="validate"<?php do_action( $taxonomy . '_term_edit_form_tag' ); ?>>
26
  <input type="hidden" name="action" value="editedgroup" />
27
  <input type="hidden" name="group_id" value="<?php echo $group_id; ?>" />
28
  <input type="hidden" name="taxonomy" value="<?php echo esc_attr( $taxonomy ) ?>" />
admin/views/ad-group-list-form-row.php CHANGED
@@ -26,15 +26,31 @@
26
  </div>
27
  <?php do_action( 'advanced-ads-group-form-options', $group ); ?>
28
  <h3><?php _e( 'Ads', 'advanced-ads' ); ?></h3>
29
- <?php if ( count( $ad_form_rows ) ) : ?>
30
- <table>
31
  <thead><tr><th><?php _e( 'Ad', 'advanced-ads' );
32
- ?></th><th><?php _e( 'weight', 'advanced-ads' ); ?></th></tr></thead>
33
- <?php foreach ( $ad_form_rows as $_row ){
34
- echo $_row;
35
- } ?></table><?php
36
- else : ?>
37
- <p><?php _e( 'No ads assigned', 'advanced-ads' ); ?></p><?php
38
- endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  </td>
40
  </tr>
26
  </div>
27
  <?php do_action( 'advanced-ads-group-form-options', $group ); ?>
28
  <h3><?php _e( 'Ads', 'advanced-ads' ); ?></h3>
29
+
30
+ <table class="advads-group-ads">
31
  <thead><tr><th><?php _e( 'Ad', 'advanced-ads' );
32
+ ?></th><th colspan="2"><?php _e( 'weight', 'advanced-ads' ); ?></th></tr></thead>
33
+ <tbody>
34
+ <?php
35
+ if ( count( $ad_form_rows ) ) {
36
+ foreach ( $ad_form_rows as $_row ) {
37
+ echo $_row;
38
+ }
39
+ } ?>
40
+ </tbody>
41
+ </table>
42
+
43
+ <?php if ( $ads_for_select ): ?>
44
+ <fieldset class="advads-group-add-ad">
45
+ <legend><?php _e( 'New Ad', 'advanced-ads' ); ?></legend>
46
+ <select class="advads-group-add-ad-list-ads">
47
+ <?php foreach ( $ads_for_select as $_ad_id => $_ad_title ) {
48
+ echo '<option value="advads-groups[' . $group->id . '][ads][' . $_ad_id . ']">' . $_ad_title . '</option>';
49
+ } ?>
50
+ </select>
51
+ <?php echo $new_ad_weights; ?>
52
+ <button type="button" class="button"><?php _e( 'add', 'advanced-ads' ); ?></button>
53
+ </fieldset>
54
+ <?php endif; ?>
55
  </td>
56
  </tr>
admin/views/ad-group.php CHANGED
@@ -45,7 +45,7 @@ if ( isset($_REQUEST['message']) && ( $msg = (int) $_REQUEST['message'] ) || iss
45
  if ( ! empty($_REQUEST['s']) ) {
46
  printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;', 'advanced-ads' ) . '</span>', esc_html( wp_unslash( $_REQUEST['s'] ) ) );
47
  } else {
48
- echo ' <a href="' . Advanced_Ads_Admin::group_page_url( array('action' => 'edit') ) . '" class="add-new-h2">' . $tax->labels->add_new_item . '</a>';
49
  }
50
  ?>
51
  </h1>
45
  if ( ! empty($_REQUEST['s']) ) {
46
  printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;', 'advanced-ads' ) . '</span>', esc_html( wp_unslash( $_REQUEST['s'] ) ) );
47
  } else {
48
+ echo ' <a href="' . Advanced_Ads_Groups_List::group_page_url( array('action' => 'edit') ) . '" class="add-new-h2">' . $tax->labels->add_new_item . '</a>';
49
  }
50
  ?>
51
  </h1>
admin/views/ad-list-timing-column.php CHANGED
@@ -10,7 +10,7 @@
10
  if ( $tz_option ) {
11
  $expiry_date->setTimezone( Advanced_Ads_Admin::get_wp_timezone() );
12
  } else {
13
- $tz_name = self::timezone_get_name( self::get_wp_timezone() );
14
  $tz_offset = substr( $tz_name, 3 );
15
  $off_time = date_create( $expiry_date->format( 'Y-m-d\TH:i:s' ) . $tz_offset );
16
  $offset_in_sec = date_offset_get( $off_time );
10
  if ( $tz_option ) {
11
  $expiry_date->setTimezone( Advanced_Ads_Admin::get_wp_timezone() );
12
  } else {
13
+ $tz_name = Advanced_Ads_Admin::timezone_get_name( Advanced_Ads_Admin::get_wp_timezone() );
14
  $tz_offset = substr( $tz_name, 3 );
15
  $off_time = date_create( $expiry_date->format( 'Y-m-d\TH:i:s' ) . $tz_offset );
16
  $offset_in_sec = date_offset_get( $off_time );
admin/views/ad-parameters-metabox.php CHANGED
@@ -25,7 +25,7 @@ do_action( 'advanced-ads-ad-params-before', $ad, $types ); ?>
25
 
26
  <?php
27
  if ( defined ( 'WP_DEBUG' ) && WP_DEBUG &&
28
- ( $error = Advanced_Ads_Admin::get_instance()->check_ad_dom_is_not_valid( $ad ) ) ) : ?>
29
  <p class="advads-error-message">
30
  <?php _e( 'The code of this ad might not work properly with the <em>Content</em> placement.', 'advanced-ads' );
31
  ?>&nbsp;<?php printf(__( 'Reach out to <a href="%s">support</a> to get help.', 'advanced-ads' ), admin_url('admin.php?page=advanced-ads-support') );
25
 
26
  <?php
27
  if ( defined ( 'WP_DEBUG' ) && WP_DEBUG &&
28
+ ( $error = Advanced_Ads_Admin_Ad_Type::check_ad_dom_is_not_valid( $ad ) ) ) : ?>
29
  <p class="advads-error-message">
30
  <?php _e( 'The code of this ad might not work properly with the <em>Content</em> placement.', 'advanced-ads' );
31
  ?>&nbsp;<?php printf(__( 'Reach out to <a href="%s">support</a> to get help.', 'advanced-ads' ), admin_url('admin.php?page=advanced-ads-support') );
admin/views/ad-submitbox-meta.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- $TZ = self::timezone_get_name( self::get_wp_timezone() );
3
  ?><div id="advanced-ads-expiry-date" class="misc-pub-section curtime misc-pub-curtime">
4
  <label onclick="advads_toggle_box('#advanced-ads-expiry-date-enable', '#advanced-ads-expiry-date .inner')">
5
  <input type="checkbox" id="advanced-ads-expiry-date-enable" name="advanced_ad[expiry_date][enabled]"
1
  <?php
2
+ $TZ = Advanced_Ads_Admin::timezone_get_name( Advanced_Ads_Admin::get_wp_timezone() );
3
  ?><div id="advanced-ads-expiry-date" class="misc-pub-section curtime misc-pub-curtime">
4
  <label onclick="advads_toggle_box('#advanced-ads-expiry-date-enable', '#advanced-ads-expiry-date .inner')">
5
  <input type="checkbox" id="advanced-ads-expiry-date-enable" name="advanced_ad[expiry_date][enabled]"
admin/views/settings.php CHANGED
@@ -6,7 +6,7 @@
6
  // array with setting tabs for frontend
7
  $setting_tabs = apply_filters('advanced-ads-setting-tabs', array(
8
  'general' => array(
9
- 'page' => $this->plugin_screen_hook_suffix,
10
  'group' => ADVADS_SLUG,
11
  'tabid' => 'general',
12
  'title' => __( 'General', 'advanced-ads' )
6
  // array with setting tabs for frontend
7
  $setting_tabs = apply_filters('advanced-ads-setting-tabs', array(
8
  'general' => array(
9
+ 'page' => Advanced_Ads_Admin::get_instance()->plugin_screen_hook_suffix,
10
  'group' => ADVADS_SLUG,
11
  'tabid' => 'general',
12
  'title' => __( 'General', 'advanced-ads' )
admin/views/support.php CHANGED
@@ -21,12 +21,12 @@
21
  if( Advanced_Ads_Checks::plugin_updates_available() ) :
22
  $messages[] = __( 'There are <strong>plugin updates available</strong>. Please update.', 'advanced-ads' );
23
  endif;
24
- if( Advanced_Ads_Checks::licenses_invalid() ) :
25
  $messages[] = sprintf( __( 'One or more license keys for <strong>Advanced Ads add-ons are invalid or missing</strong>. Please add valid license keys <a href="%s">here</a>.', 'advanced-ads' ), admin_url( 'admin.php?page=advanced-ads-settings#top#licenses' ) );
26
  endif;
27
  if( Advanced_Ads_Checks::licenses_expired() ) :
28
  $messages[] = sprintf( __( '<strong>Advanced Ads</strong> license(s) expired. Support and updates are disabled. Please visit <a href="%s"> the license page</a> for more information.', 'advanced-ads' ), admin_url( 'admin.php?page=advanced-ads-settings#top#licenses' ) );
29
- endif;
30
  if( Advanced_Ads_Checks::active_autoptimize() && ! defined( 'AAP_VERSION' ) ) :
31
  $messages[] = sprintf(__( '<strong>Autoptimize plugin detected</strong>. While this plugin is great for site performance, it is known to alter code, including scripts from ad networks. <a href="%s" target="_blank">Advanced Ads Pro</a> has a build-in support for Autoptimize.', 'advanced-ads' ), ADVADS_URL . 'add-ons/advanced-ads-pro/#utm_source=advanced-ads&utm_medium=link&utm_campaign=support');
32
  endif;
21
  if( Advanced_Ads_Checks::plugin_updates_available() ) :
22
  $messages[] = __( 'There are <strong>plugin updates available</strong>. Please update.', 'advanced-ads' );
23
  endif;
24
+ /* if( Advanced_Ads_Checks::licenses_invalid() ) :
25
  $messages[] = sprintf( __( 'One or more license keys for <strong>Advanced Ads add-ons are invalid or missing</strong>. Please add valid license keys <a href="%s">here</a>.', 'advanced-ads' ), admin_url( 'admin.php?page=advanced-ads-settings#top#licenses' ) );
26
  endif;
27
  if( Advanced_Ads_Checks::licenses_expired() ) :
28
  $messages[] = sprintf( __( '<strong>Advanced Ads</strong> license(s) expired. Support and updates are disabled. Please visit <a href="%s"> the license page</a> for more information.', 'advanced-ads' ), admin_url( 'admin.php?page=advanced-ads-settings#top#licenses' ) );
29
+ endif;*/
30
  if( Advanced_Ads_Checks::active_autoptimize() && ! defined( 'AAP_VERSION' ) ) :
31
  $messages[] = sprintf(__( '<strong>Autoptimize plugin detected</strong>. While this plugin is great for site performance, it is known to alter code, including scripts from ad networks. <a href="%s" target="_blank">Advanced Ads Pro</a> has a build-in support for Autoptimize.', 'advanced-ads' ), ADVADS_URL . 'add-ons/advanced-ads-pro/#utm_source=advanced-ads&utm_medium=link&utm_campaign=support');
32
  endif;
advanced-ads.php CHANGED
@@ -12,7 +12,7 @@
12
  * Plugin Name: Advanced Ads
13
  * Plugin URI: https://wpadvancedads.com
14
  * Description: Manage and optimize your ads in WordPress
15
- * Version: 1.7.5
16
  * Author: Thomas Maier
17
  * Author URI: http://webgilde.com
18
  * Text Domain: advanced-ads
@@ -39,7 +39,7 @@ define( 'ADVADS_BASE_DIR', dirname( ADVADS_BASE ) ); // directory of the plugin
39
  // general and global slug, e.g. to store options in WP, textdomain
40
  define( 'ADVADS_SLUG', 'advanced-ads' );
41
  define( 'ADVADS_URL', 'https://wpadvancedads.com/' );
42
- define( 'ADVADS_VERSION', '1.7.5' );
43
 
44
  /*----------------------------------------------------------------------------*
45
  * Autoloading, modules and functions
12
  * Plugin Name: Advanced Ads
13
  * Plugin URI: https://wpadvancedads.com
14
  * Description: Manage and optimize your ads in WordPress
15
+ * Version: 1.7.5.1
16
  * Author: Thomas Maier
17
  * Author URI: http://webgilde.com
18
  * Text Domain: advanced-ads
39
  // general and global slug, e.g. to store options in WP, textdomain
40
  define( 'ADVADS_SLUG', 'advanced-ads' );
41
  define( 'ADVADS_URL', 'https://wpadvancedads.com/' );
42
+ define( 'ADVADS_VERSION', '1.7.5.1' );
43
 
44
  /*----------------------------------------------------------------------------*
45
  * Autoloading, modules and functions
classes/ad_group.php CHANGED
@@ -428,7 +428,7 @@ class Advanced_Ads_Group {
428
  public function save_ad_weights($weights = '') {
429
 
430
  // allow only arrays and empty string
431
- if ( ! is_array( $weights ) && $weights = '' ) {
432
  return; }
433
 
434
  $global_weights = get_option( 'advads-ad-weights', array() );
428
  public function save_ad_weights($weights = '') {
429
 
430
  // allow only arrays and empty string
431
+ if ( ! is_array( $weights ) && $weights !== '' ) {
432
  return; }
433
 
434
  $global_weights = get_option( 'advads-ad-weights', array() );
classes/ad_placements.php CHANGED
@@ -432,8 +432,8 @@ class Advanced_Ads_Placements {
432
  // $adContent = preg_replace('#(document.write[^<^)]+)</sc(.*)#', '$1<\/sc$2', $adContent); // too restrict, doesn’t work when beginning <script> tag is in the same line
433
  $adDom->loadHtml('<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=' . $wpCharset . '" /><body>' . $adContent);
434
  // log errors
435
- if ( defined ( 'WP_DEBUG' ) && WP_DEBUG && libxml_get_last_error() instanceof LibXMLError ){
436
- Advanced_Ads::log( 'content injection error for placement "' . $placement_id . '": ' . print_r( libxml_get_last_error(), true ) );
437
  }
438
 
439
  // inject
432
  // $adContent = preg_replace('#(document.write[^<^)]+)</sc(.*)#', '$1<\/sc$2', $adContent); // too restrict, doesn’t work when beginning <script> tag is in the same line
433
  $adDom->loadHtml('<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=' . $wpCharset . '" /><body>' . $adContent);
434
  // log errors
435
+ if ( defined ( 'WP_DEBUG' ) && WP_DEBUG && current_user_can( 'advanced_ads_manage_options') && libxml_get_last_error() instanceof LibXMLError ){
436
+ Advanced_Ads::log( 'possible content injection error for placement "' . $placement_id . '": ' . print_r( libxml_get_last_error(), true ) );
437
  }
438
 
439
  // inject
modules/gadsense/includes/class-ad-type-adsense.php CHANGED
@@ -160,7 +160,8 @@ class Advanced_Ads_Ad_Type_Adsense extends Advanced_Ads_Ad_Type_Abstract {
160
  $gadsense['google_loaded'] = true;
161
  }
162
 
163
- if ( isset($gadsense['adsense_count']) ) {
 
164
  $gadsense['adsense_count']++;
165
  } else {
166
  $gadsense['adsense_count'] = 1;
160
  $gadsense['google_loaded'] = true;
161
  }
162
 
163
+ //check if passive cb is used
164
+ if ( isset( $gadsense['adsense_count'] ) && $ad->global_output ) {
165
  $gadsense['adsense_count']++;
166
  } else {
167
  $gadsense['adsense_count'] = 1;
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: webzunft
3
  Donate link:https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5RRRCEBGN3UT2
4
  Tags: ads, ad, ad inserter, ad injection, ad manager, ads manager, ad widget, adrotate, adsense, advertise, advertisements, advertising, adverts, advert, amazon, banner, banners, buysellads, chitika, clickbank, dfp, doubleclick, geotarget, geolocation, geo location, google dfp, monetization, widget
5
  Requires at least: WP 4.2, PHP 5.3
6
- Tested up to: 4.5.3
7
- Stable tag: 1.7.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -204,6 +204,13 @@ There is no revenue share. Advanced Ads doesn’t alter your ad codes in a way t
204
 
205
  == Changelog ==
206
 
 
 
 
 
 
 
 
207
  = 1.7.5 =
208
 
209
  * prepared for [Advanced Ads Pro](https://wpadvancedads.com/add-ons/advanced-ads-pro/) 1.4 with ad reloads, single request mode and placement tests
3
  Donate link:https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5RRRCEBGN3UT2
4
  Tags: ads, ad, ad inserter, ad injection, ad manager, ads manager, ad widget, adrotate, adsense, advertise, advertisements, advertising, adverts, advert, amazon, banner, banners, buysellads, chitika, clickbank, dfp, doubleclick, geotarget, geolocation, geo location, google dfp, monetization, widget
5
  Requires at least: WP 4.2, PHP 5.3
6
+ Tested up to: 4.6
7
+ Stable tag: 1.7.5.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
204
 
205
  == Changelog ==
206
 
207
+ = 1.7.5.1 =
208
+
209
+ * add and remove ads in groups in the group overview page
210
+ * separated admin code into multiple files for better overview
211
+ * log possible content injection errors only for admin users in the frontend
212
+ * double error messages hidden on plugin support page
213
+
214
  = 1.7.5 =
215
 
216
  * prepared for [Advanced Ads Pro](https://wpadvancedads.com/add-ons/advanced-ads-pro/) 1.4 with ad reloads, single request mode and placement tests
vendor/autoload_52.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
- return ComposerAutoloaderInit21d32ce28702bd9dad809a84aec2ae91::getLoader();
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
+ return ComposerAutoloaderInit9fd37b3a8ae6882ef90ba1c057562c7c::getLoader();
vendor/composer/autoload_classmap.php CHANGED
@@ -16,7 +16,11 @@ return array(
16
  'Advanced_Ads_Ad_Type_Image' => $baseDir . '/classes/ad_type_image.php',
17
  'Advanced_Ads_Ad_Type_Plain' => $baseDir . '/classes/ad_type_plain.php',
18
  'Advanced_Ads_Admin' => $baseDir . '/admin/class-advanced-ads-admin.php',
 
 
 
19
  'Advanced_Ads_Admin_Notices' => $baseDir . '/admin/includes/class-notices.php',
 
20
  'Advanced_Ads_Ajax' => $baseDir . '/classes/ad-ajax.php',
21
  'Advanced_Ads_Checks' => $baseDir . '/classes/checks.php',
22
  'Advanced_Ads_Display_Conditions' => $baseDir . '/classes/display-conditions.php',
16
  'Advanced_Ads_Ad_Type_Image' => $baseDir . '/classes/ad_type_image.php',
17
  'Advanced_Ads_Ad_Type_Plain' => $baseDir . '/classes/ad_type_plain.php',
18
  'Advanced_Ads_Admin' => $baseDir . '/admin/class-advanced-ads-admin.php',
19
+ 'Advanced_Ads_Admin_Ad_Type' => $baseDir . '/admin/includes/class-ad-type.php',
20
+ 'Advanced_Ads_Admin_Menu' => $baseDir . '/admin/includes/class-menu.php',
21
+ 'Advanced_Ads_Admin_Meta_Boxes' => $baseDir . '/admin/includes/class-meta-box.php',
22
  'Advanced_Ads_Admin_Notices' => $baseDir . '/admin/includes/class-notices.php',
23
+ 'Advanced_Ads_Admin_Settings' => $baseDir . '/admin/includes/class-settings.php',
24
  'Advanced_Ads_Ajax' => $baseDir . '/classes/ad-ajax.php',
25
  'Advanced_Ads_Checks' => $baseDir . '/classes/checks.php',
26
  'Advanced_Ads_Display_Conditions' => $baseDir . '/classes/display-conditions.php',
vendor/composer/autoload_real_52.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
- class ComposerAutoloaderInit21d32ce28702bd9dad809a84aec2ae91 {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit21d32ce28702bd9dad809a84aec2ae91 {
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit21d32ce28702bd9dad809a84aec2ae91', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit21d32ce28702bd9dad809a84aec2ae91', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
+ class ComposerAutoloaderInit9fd37b3a8ae6882ef90ba1c057562c7c {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit9fd37b3a8ae6882ef90ba1c057562c7c', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit9fd37b3a8ae6882ef90ba1c057562c7c', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);