PluginProbe
Leyka / 3.17
Leyka v3.17
3.32.3 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.6.1 2.3.7 2.3.8 2.3.9 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1 3.10 3.11 3.11.1 3.12 3.13 3.14 3.15 3.16 3.17 All 89 releases
leyka / inc / leyka-admin.php

leyka-admin.php in Leyka 3.17, at inc/leyka-admin.php

972 lines 38.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php if( !defined('WPINC') ) die;
2
3 /**
4 * Leyka Admin setup
5 **/
6
7 class Leyka_Admin_Setup extends Leyka_Singleton {
8
9 protected static $_instance = null;
10
11 /** @var WP_List_Table */
12 protected $_donors_list_table = null;
13 /** @var WP_List_Table */
14 protected $_recurring_subscriptions_list_table = null;
15
16 protected function __construct() {
17
18 require_once ABSPATH.'wp-admin/includes/meta-boxes.php';
19 require_once LEYKA_PLUGIN_DIR.'inc/leyka-admin-functions.php';
20 require_once LEYKA_PLUGIN_DIR.'inc/settings/leyka-admin-template-tags.php';
21 require_once LEYKA_PLUGIN_DIR.'inc/settings/leyka-class-settings-factory.php';
22
23 add_action('admin_menu', array($this, 'admin_menu_setup'), 9);
24
25 if(leyka_options()->opt('donor_management_available')) { // Save Donors pages custom options
26 add_filter('set-screen-option', function($status, $option, $value) {
27
28 if($option === 'donors_per_page' && (int)$value > 0) {
29 update_user_option(get_current_user_id(), 'donors_per_page', $value);
30 }
31
32 return $value;
33
34 }, 10, 3);
35 }
36
37 add_action('admin_enqueue_scripts', array($this, 'load_frontend_scripts'));
38
39 add_action('admin_init', array($this, 'pre_admin_actions'));
40
41 add_action('wp_ajax_leyka_send_feedback', array($this, 'ajax_send_feedback'));
42
43 add_filter('plugin_row_meta', array($this, 'set_plugin_meta'), 10, 2);
44
45 add_filter('plugin_action_links_'.LEYKA_PLUGIN_INNER_SHORT_NAME, array($this, 'add_plugins_list_links'));
46
47 // Metaboxes support where it is needed:
48 add_action('leyka_pre_help_actions', array($this, 'full_metaboxes_support'));
49 add_action('leyka_pre_donor_info_actions', array($this, 'full_metaboxes_support'));
50 add_action('leyka_pre_extension_settings_actions', array($this, 'full_metaboxes_support'));
51
52 add_action('leyka_post_admin_actions', array($this, 'show_footer'));
53
54 // Donors' tags on the user profile page:
55 if(leyka_options()->opt('donor_management_available') || leyka_options()->opt('donor_accounts_available')) {
56
57 add_action('show_user_profile', array($this, 'show_user_profile_donor_fields'));
58 add_action('edit_user_profile', array($this, 'show_user_profile_donor_fields'));
59
60 }
61
62 add_action('personal_options_update', array($this, 'save_user_profile_donor_fields'));
63 add_action('edit_user_profile_update', array($this, 'save_user_profile_donor_fields'));
64
65 // If template is disabled, remove its options:
66 add_filter('leyka_view_options_allocation', function($options_allocated){
67
68 if( !empty($options_allocated[0]['section']['tabs']) ) {
69 foreach($options_allocated[0]['section']['tabs'] as $tab_id => $tab_options) {
70 if(stristr($tab_id, 'template_options_') !== false) {
71
72 $template_id = str_replace('template_options_', '', $tab_id);
73 if(leyka()->template_is_disabled($template_id)) {
74 unset($options_allocated[0]['section']['tabs'][$tab_id]);
75 }
76
77 }
78 }
79 }
80 return $options_allocated;
81 });
82
83 require_once LEYKA_PLUGIN_DIR.'/inc/leyka-class-portlet-controller.php'; // Portlet controller API
84
85 }
86
87 public function set_plugin_meta($links, $file) {
88
89 if($file == LEYKA_PLUGIN_INNER_SHORT_NAME) {
90 $links[] = '<a href="https://github.com/Teplitsa/Leyka/">GitHub</a>';
91 }
92
93 return $links;
94
95 }
96
97 protected function _show_admin_template($template_id) {
98
99 if( !$template_id ) {
100 return;
101 }
102
103 $template_file = LEYKA_PLUGIN_DIR.'/inc/admin-templates/leyka-admin-'.$template_id.'.php';
104 if(file_exists($template_file)) {
105 require $template_file;
106 }
107
108 }
109
110 // Support the full abilities of the metaboxes on any plugin's page:
111 public function full_metaboxes_support($current_stage = false) {?>
112
113 <form style="display:none;" method="get" action="#">
114 <?php wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false); ?>
115 <?php wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false); ?>
116 </form>
117
118 <?php }
119
120 public function pre_admin_actions() {
121
122 function leyka_admin_title($admin_title) {
123
124 if(isset($_GET['page']) && $_GET['page'] === 'leyka_settings_new' && isset($_GET['screen'])) {
125
126 $screen_full_id = explode('-', $_GET['screen']);
127
128 // $screen_full_id[0] - view type (e.g. 'wizard' or 'control_panel')
129 // $screen_full_id[1] - settings area given (e.g. 'init').
130
131 require_once LEYKA_PLUGIN_DIR.'inc/settings/leyka-class-settings-factory.php';
132
133 $admin_title = get_bloginfo('name')
134 .' &#8212; '.Leyka_Settings_Factory::get_instance()->get_controller($screen_full_id[1])->title;
135
136 } else if(isset($_GET['page']) && $_GET['page'] === 'leyka_donor_info' && !empty($_GET['donor'])) {
137
138 try {
139 $donor = new Leyka_Donor(absint($_GET['donor']));
140 } catch(Exception $e) {
141 return $admin_title;
142 }
143
144 $admin_title = sprintf(__('Leyka: Donor %s', 'leyka'), $donor->name).' &lsaquo; '.get_bloginfo('name');
145
146 } else if(isset($_GET['page']) && $_GET['page'] === 'leyka_extension_settings' && isset($_GET['extension'])) {
147
148 $extension = leyka_get_extension_by_id($_GET['extension']);
149
150 $admin_title = ($extension ? sprintf(__('Leyka: %s', 'leyka'), $extension->title) : __('Leyka: unknown extension', 'leyka'))
151 .' &lsaquo; '.get_bloginfo('name');
152
153 }
154
155 return $admin_title;
156
157 }
158 add_filter('admin_title', 'leyka_admin_title');
159
160 // Leyka admin notices:
161 if(isset($_GET['leyka_reset_msg'])) {
162 update_option('leyka_admin_notice_'.$_GET['leyka_reset_msg'], 0);
163 }
164
165 if(isset($_GET['leyka-hide-notice']) && isset($_GET['_leyka_notice_nonce'])) {
166
167 if( !wp_verify_nonce($_GET['_leyka_notice_nonce'], 'leyka_hide_notice_nonce') ) {
168 wp_die(__('Action failed. Please refresh the page and retry.', 'leyka'));
169 }
170
171 if( !current_user_can('manage_options') ) {
172 wp_die(__('Action failed: insufficient permissions.', 'leyka'));
173 }
174
175 update_option('leyka_admin_notice_'.sanitize_text_field($_GET['leyka-hide-notice']), 1);
176
177 }
178
179 add_filter('leyka_admin_portlet_title', function($portlet_title, $portlet_id){
180 return $portlet_id === 'donations-dynamics' ? $portlet_title.',&nbsp;'.leyka_get_currency_label() : $portlet_title;
181 }, 10, 2);
182
183 // Add donor account column to the admin Users list if needed:
184 if(get_option('leyka_donor_management_available')) {
185
186 add_filter('manage_users_columns', function($column){
187
188 $column['donor_account_available'] = __("Donor's info", 'leyka');
189 return $column;
190
191 });
192
193 add_filter('manage_users_custom_column', function($value, $column_name, $user_id) {
194
195 if($column_name === 'donor_account_available') {
196
197 if(leyka_user_has_role(Leyka_Donor::DONOR_USER_ROLE, false, $user_id)) {
198
199 $donor_user = new Leyka_Donor($user_id);
200 $donor_info_page_link = '<a href="'.admin_url('?page=leyka_donor_info&donor='.$user_id).'">'.__('Info', 'leyka').'</a>';
201
202 return ($donor_user->has_account_access ? __('yes', 'leyka') : __('no', 'leyka'))
203 .' | '.$donor_info_page_link;
204
205 } else {
206 return __('not a donor', 'leyka');
207 }
208
209 } else {
210 return $value;
211 }
212
213 }, 10, 3);
214
215 }
216
217 }
218
219 public function admin_menu_setup() {
220
221 // Leyka menu root:
222 add_menu_page(__('Leyka Dashboard', 'leyka'), __('Leyka', 'leyka'), 'leyka_manage_donations', 'leyka', array($this, 'dashboard_screen'));
223
224 add_submenu_page('leyka', __('Leyka Dashboard', 'leyka'), __('Dashboard', 'leyka'), 'leyka_manage_donations', 'leyka', array($this, 'dashboard_screen'));
225
226 add_submenu_page('leyka', __('Campaigns', 'leyka'), __('Campaigns', 'leyka'), 'leyka_manage_donations', 'edit.php?post_type='.Leyka_Campaign_Management::$post_type);
227
228 add_submenu_page('leyka', __('Donations', 'leyka'), __('Donations', 'leyka'), 'leyka_manage_donations', 'edit.php?post_type='.Leyka_Donation_Management::$post_type);
229
230 // Recurring subscriptions list page:
231 $hook = add_submenu_page('leyka', __('Recurring subscriptions', 'leyka'), __('Recurring subscriptions', 'leyka'), 'leyka_manage_donations', 'leyka_recurring_subscriptions', array($this, 'recurring_subscriptions_list_screen'));
232 add_action("load-$hook", array($this, 'recurring_subscriptions_list_screen_options'));
233
234 if(leyka()->opt('donor_management_available')) {
235
236 // Donors list page:
237 $hook = add_submenu_page('leyka', __('Donors', 'leyka'), __('Donors', 'leyka'), 'leyka_manage_donations', 'leyka_donors', array($this, 'donors_list_screen'));
238 add_action("load-$hook", array($this, 'donors_list_screen_options'));
239
240 // Donors tags page:
241 $taxonomy = get_taxonomy(Leyka_Donor::DONORS_TAGS_TAXONOMY_NAME);
242
243 add_submenu_page('', esc_attr($taxonomy->labels->menu_name), esc_attr($taxonomy->labels->menu_name), $taxonomy->cap->manage_terms, 'edit-tags.php?taxonomy='.$taxonomy->name);
244
245 }
246
247 add_submenu_page('leyka', __('Leyka Settings', 'leyka'), __('Settings', 'leyka'), 'leyka_manage_options', 'leyka_settings', array($this, 'settings_screen'));
248
249 add_submenu_page('', __('Extensions', 'leyka'), __('Extensions', 'leyka'), 'leyka_manage_options', 'leyka_extensions', array($this, 'extensions_screen'));
250
251 add_submenu_page('leyka', __('Help', 'leyka'), __('Help', 'leyka'), 'leyka_manage_donations', 'leyka_help', array($this, 'help_screen'));
252
253 // Fake pages:
254 add_submenu_page(NULL, 'Leyka Wizard', 'Leyka Wizard', 'leyka_manage_options', 'leyka_settings_new', array($this, 'settings_new_screen'));
255
256 add_submenu_page(NULL, "Donor's info", "Donor's info", 'leyka_manage_options', 'leyka_donor_info', array($this, 'donor_info_screen'));
257
258 add_submenu_page(NULL, "Extension settings", "Extension settings", 'leyka_manage_options', 'leyka_extension_settings', array($this, 'leyka_extension_settings_screen'));
259 // Fake pages - END
260
261 do_action('leyka_admin_menu_setup');
262
263 global $submenu;
264
265 if( !empty($submenu['leyka']) ) {
266 $submenu['leyka'] = apply_filters('leyka_admin_menu_order', $submenu['leyka']);
267 }
268
269 }
270
271 /**
272 * Settings link in plugin list table.
273 *
274 * @param $links array
275 * @return array
276 */
277 public function add_plugins_list_links($links) {
278
279 $links[] = '<a href="'.admin_url('admin.php?page=leyka_settings').'">'.__( 'Settings', 'leyka').'</a>';
280 return $links;
281
282 }
283
284 public function dashboard_screen() {
285
286 if( !current_user_can('leyka_manage_donations') ) {
287 wp_die(__('Sorry, but you do not have permissions to access this page.', 'leyka'));
288 }
289
290 do_action('leyka_pre_dashboard_actions');
291
292 $this->_show_admin_template('dashboard-page');
293
294 do_action('leyka_post_dashboard_actions');
295 do_action('leyka_post_admin_actions');
296
297 }
298
299 public function show_admin_portlet($portlet_id, array $params = array()) {
300
301 $portlet_file = LEYKA_PLUGIN_DIR.'/inc/portlets/leyka-'.$portlet_id.'.php';
302 if( !file_exists($portlet_file) ) {
303 return;
304 }
305
306 $controller_file = LEYKA_PLUGIN_DIR.'/inc/portlets/'.$portlet_id.'/leyka-class-'.$portlet_id.'-portlet-controller.php';
307 if(file_exists($controller_file)) {
308 require_once $controller_file;
309 }
310
311 $portlet_data = get_file_data($portlet_file, array(
312 'name' => 'Leyka Portlet',
313 'description' => 'Description',
314 'title' => 'Title',
315 'subtitle' => 'Subtitle',
316 'thumbnail' => 'Thumbnail',
317 ));
318
319 $portlet_data['title'] = empty($params['title']) ? esc_attr__($portlet_data['title'], 'leyka') : $params['title'];
320 $portlet_data['subtitle'] = empty($params['subtitle']) ?
321 esc_attr__($portlet_data['subtitle'], 'leyka') : $params['subtitle'];
322 $portlet_data['thumbnail'] = empty($params['thumbnail']) ? $portlet_data['thumbnail'] : $params['thumbnail'];?>
323
324 <div class="leyka-admin-portlet portlet-<?php echo esc_attr($portlet_id);?>">
325
326 <div class="portlet-header">
327
328 <img src="<?php echo esc_url(LEYKA_PLUGIN_BASE_URL.trim($portlet_data['thumbnail'], '/'));?>" alt="">
329
330 <div class="portlet-title">
331
332 <?php if( !empty($portlet_data['subtitle'])) {?>
333 <h3><?php echo apply_filters('leyka_admin_portlet_subtitle', $portlet_data['subtitle'], $portlet_id);?></h3>
334 <?php }?>
335
336 <h2><?php echo apply_filters('leyka_admin_portlet_title', $portlet_data['title'], $portlet_id);?></h2>
337
338 </div>
339 </div>
340
341 <div class="portlet-content"><?php require $portlet_file;?></div>
342
343 </div>
344
345 <?php
346 }
347
348 public function has_banners($page = false, $location = false) {
349 return !get_user_meta(get_current_user_id(), 'leyka_dashboard_banner_closed-grade_plugin', true);
350 }
351
352 public function show_banner($page = false, $location = false) {?>
353
354 <div class="banner-wrapper">
355 <div class="banner-inner" data-banner-id="grade_plugin">
356 <a href="https://wordpress.org/support/plugin/leyka/reviews/#new-post" class="banner" target="_blank">
357 <div class="banner-text">
358 <div class="banner-subtitle"><?php _e('Like Leyka?', 'leyka');?></div>
359 <div class="banner-title"><?php _e('Give a mark to the plugin', 'leyka');?></div>
360 </div>
361 <div class="banner-thumbnail">
362 <img src="<?php echo LEYKA_PLUGIN_BASE_URL.'/img/dashboard/banner-grade-plugin.svg';?>" alt="">
363 </div>
364 </a>
365 <a class="close" href="#" title="<?php _e('Close permanently', 'leyka');?>"></a>
366 </div>
367 </div>
368
369 <?php
370 }
371
372 /**
373 * Display Donor related fields on the User profile admin page.
374 *
375 * @param $donor_user WP_User
376 */
377 public function show_user_profile_donor_fields(WP_User $donor_user) {
378
379 if( !current_user_can('administrator') ) {
380 return;
381 }
382
383 if( !leyka_options()->opt('donor_management_available') && !leyka_options()->opt('donor_accounts_available') ) {
384 return;
385 }?>
386
387 <table class="form-table">
388 <tr>
389 <th>
390 <label for="leyka-donors-tags-field"><?php _e('Donor tags', 'leyka');?></label>
391 </th>
392 <td>
393 <?php $all_donors_tags = get_terms(array(
394 'taxonomy' => Leyka_Donor::DONORS_TAGS_TAXONOMY_NAME,
395 'hide_empty' => false,
396 ));
397
398 $donor_user_tags = wp_get_object_terms(
399 $donor_user->ID,
400 Leyka_Donor::DONORS_TAGS_TAXONOMY_NAME,
401 array('fields' => 'ids')
402 );
403
404 if($all_donors_tags) {?>
405
406 <select id="leyka-donors-tags-field" multiple="multiple" name="leyka_donor_tags[]">
407 <?php foreach($all_donors_tags as $donor_tag) {?>
408 <option value="<?php echo esc_attr($donor_tag->term_id);?>" <?php echo in_array($donor_tag->term_id, $donor_user_tags) ? 'selected="selected"' : '';?>>
409 <?php echo esc_html($donor_tag->name);?>
410 </option>
411 <?php }?>
412
413 </select>
414
415 <?php } else {
416 _e('No Donor tags added yet.', 'leyka');
417 }?>
418 </td>
419 </tr>
420 </table>
421 <?php
422
423 }
424
425 /**
426 * Handle Donor related fields for the User profile admin page.
427 *
428 * @param $donor_user_id integer
429 * @return boolean True if fields values are saved, false otherwise.
430 */
431 public function save_user_profile_donor_fields($donor_user_id) {
432
433 if( !current_user_can('administrator') || empty($_POST['leyka_donor_tags']) || !is_array($_POST['leyka_donor_tags']) ) {
434 return false;
435 }
436
437 array_walk($_POST['leyka_donor_tags'], function( &$value ){
438 $value = (int)$value;
439 });
440
441 return !is_wp_error(wp_set_object_terms(
442 $donor_user_id,
443 $_POST['leyka_donor_tags'],
444 Leyka_Donor::DONORS_TAGS_TAXONOMY_NAME
445 ));
446
447 }
448
449 public function is_separate_forms_stage($stage) {
450 return in_array($stage, array('email', 'beneficiary', 'technical', 'view', 'additional'));
451 }
452
453 public function recurring_subscriptions_list_screen_options() {
454
455 add_screen_option('per_page', array(
456 'label' => __('Subscriptions per page', 'leyka'),
457 'default' => 20,
458 'option' => 'recurring_subscriptions_per_page',
459 ));
460
461 require_once LEYKA_PLUGIN_DIR.'inc/admin-lists/leyka-class-recurring-subscriptions-list-table.php';
462
463 $this->_recurring_subscriptions_list_table = new Leyka_Admin_Recurring_Subscriptions_List_Table();
464
465 }
466
467 public function recurring_subscriptions_list_screen() {
468
469 if( !current_user_can('leyka_manage_options') ) {
470 wp_die(__('You do not have permissions to access this page.', 'leyka'));
471 }
472
473 do_action('leyka_pre_recurring_subscriptions_list_actions');
474
475 $this->_show_admin_template('recurring-subscriptions-list-page');
476
477 do_action('leyka_post_recurring_subscriptions_list_actions');
478 do_action('leyka_post_admin_actions');
479
480 }
481
482 public function donors_list_screen_options() {
483
484 add_screen_option('per_page', array(
485 'label' => __('Donors per page', 'leyka'),
486 'default' => 20,
487 'option' => 'donors_per_page',
488 ));
489
490 require_once LEYKA_PLUGIN_DIR.'inc/admin-lists/leyka-class-donors-list-table.php';
491
492 $this->_donors_list_table = new Leyka_Admin_Donors_List_Table();
493
494 }
495
496 public function donors_list_screen() {
497
498 if( !current_user_can('leyka_manage_options') ) {
499 wp_die(__('You do not have permissions to access this page.', 'leyka'));
500 }
501
502 do_action('leyka_pre_donors_list_actions');
503
504 $this->_show_admin_template('donors-list-page');
505
506 do_action('leyka_post_donors_list_actions');
507 do_action('leyka_post_admin_actions');
508
509 }
510
511 public function settings_screen() {
512
513 if( !current_user_can('leyka_manage_options') ) {
514 wp_die(__('You do not have permissions to access this page.', 'leyka'));
515 }
516
517 add_filter('leyka_admin_settings_tabs_menu', function($settings_tabs_html){
518
519 $settings_tabs_html .= '<a href="'.admin_url('admin.php?page=leyka_extensions').'" class="nav-tab">'.__('Extensions', 'leyka').'</a>';
520
521 return $settings_tabs_html;
522
523 });
524
525 $current_stage = $this->get_current_settings_tab();
526
527 require_once LEYKA_PLUGIN_DIR.'inc/settings/leyka-class-settings-factory.php'; // Basic Controllers Factory class
528 require_once LEYKA_PLUGIN_DIR.'inc/settings-pages/leyka-settings-common.php';
529
530 do_action('leyka_pre_settings_actions', $current_stage);
531
532 if( // Process settings change
533 (
534 !empty($_POST["leyka_settings_{$current_stage}_submit"])
535 || !empty($_POST["leyka_settings_stage-{$current_stage}_submit"])
536 )
537 /** @todo Find what's wrong with the nonce check below: */
538 // && wp_verify_nonce('_leyka_nonce', "leyka_settings_{$current_stage}")
539 ) {
540
541 do_action('leyka_settings_submit', $current_stage);
542 do_action("leyka_settings_{$current_stage}_submit");
543
544 }
545
546 $this->_show_admin_template('settings-page');
547
548 do_action('leyka_post_settings_actions');
549 do_action('leyka_post_admin_actions');
550
551 }
552
553 /** Settings factory-controlled display. */
554 public function settings_new_screen() {
555
556 if(empty($_GET['screen']) || count(explode('-', $_GET['screen'])) < 2) {
557
558 $this->settings_screen();
559 return;
560
561 }
562
563 $screen_full_id = explode('-', $_GET['screen']);
564
565 // Normally, we'd constuct settings view based on
566 // - view type ([0], e.g. 'wizard' or 'options')
567 // - settings area given ([1], e.g. 'init').
568
569 try {
570
571 Leyka_Settings_Factory::get_instance()
572 ->get_render($screen_full_id[0])
573 ->set_controller(Leyka_Settings_Factory::get_instance()->get_controller($screen_full_id[1]))
574 ->render_content();
575
576 } catch(Exception $ex) {
577 echo '<pre>'.sprintf(__('Settings display error (code %s): %s', 'leyka'), $ex->getCode(), $ex->getMessage()).'</pre>';
578 }
579
580 do_action('leyka_post_admin_actions');
581
582 }
583
584 public function get_default_settings_tab() {
585 return apply_filters('leyka_default_settings_tab', 'payment');
586 }
587
588 public function get_current_settings_tab() {
589 return empty($_GET['stage']) ? $this->get_default_settings_tab() : trim($_GET['stage']);
590 }
591
592 public function settings_tabs_menu() {
593
594 $base_url = 'admin.php?page=leyka_settings';
595
596 $out = '';
597 foreach(leyka_opt_alloc()->get_tabs() as $tab_id => $tab_label) {
598 $out .= '<a href="'
599 .($this->get_default_settings_tab() === $tab_id ? $base_url : add_query_arg('stage', $tab_id, $base_url))
600 .'" class="'.($this->get_current_settings_tab() === $tab_id ? 'nav-tab nav-tab-active' : 'nav-tab').'">'
601 .$tab_label.'</a>';
602 }
603
604 $out = apply_filters('leyka_admin_settings_tabs_menu', $out); // To add some new tabs to the nav menu
605
606 $out .= '<a href="'.admin_url('/admin.php?page=leyka_settings_new&screen=wizard-init').'" class="init-wizard-tab"></a>';
607
608 return $out;
609
610 }
611
612 public function donor_info_screen() {
613
614 do_action('leyka_pre_donor_info_actions'); // Add collapsible to metaboxes
615
616 // Add all metaboxes:
617 add_meta_box('leyka_donor_info', __("Donor's data", 'leyka'), array($this, 'donor_data_metabox'), 'dashboard_page_leyka_donor_info', 'normal');
618 add_meta_box('leyka_donor_admin_comments', __('Comments', 'leyka'), array($this, 'donor_comments_metabox'), 'dashboard_page_leyka_donor_info', 'normal');
619 add_meta_box('leyka_donor_tags', __('Tags'), array($this, 'donor_tags_metabox'), 'dashboard_page_leyka_donor_info', 'normal');
620 add_meta_box('leyka_donor_donations', __('Donations', 'leyka'), array($this, 'donor_donations_metabox'), 'dashboard_page_leyka_donor_info', 'normal');
621
622 $this->_show_admin_template('donor-info-page');
623
624 do_action('leyka_post_donor_info_actions');
625 do_action('leyka_post_admin_actions');
626
627 }
628
629 public function donor_data_metabox() {
630 $this->_show_admin_template('metabox-donor-data');
631 }
632 public function donor_comments_metabox() {
633 $this->_show_admin_template('metabox-donor-comments');
634 }
635 public function donor_tags_metabox() {
636 $this->_show_admin_template('metabox-donor-tags');
637 }
638 public function donor_donations_metabox() {
639 $this->_show_admin_template('metabox-donor-donations');
640 }
641
642 public function extensions_screen() {
643
644 if( !current_user_can('leyka_manage_options') ) {
645 wp_die(__('You do not have permissions to access this page.', 'leyka'));
646 }
647
648 do_action('leyka_pre_extensions_actions');
649
650 $this->_show_admin_template('extensions-list-page');
651
652 do_action('leyka_post_extensions_actions');
653 do_action('leyka_post_admin_actions');
654
655 }
656
657 public function leyka_extension_settings_screen() {
658
659 if( !current_user_can('leyka_manage_options') && empty($_GET['extension']) ) {
660 wp_die(__('You do not have permissions to access this page.', 'leyka'));
661 }
662
663 do_action('leyka_pre_extension_settings_actions');
664
665 $this->_show_admin_template('extension-settings-page');
666
667 do_action('leyka_post_extension_settings_actions');
668 do_action('leyka_post_admin_actions');
669
670 }
671
672 public function help_screen() {
673
674 if( !current_user_can('leyka_manage_donations') ) {
675 wp_die(__('You do not have permissions to access this page.', 'leyka'));
676 }
677
678 do_action('leyka_pre_help_actions');
679
680 add_meta_box(
681 'leyka_docs_info',
682 __('Leyka documentation', 'leyka'),
683 function(){ $this->_show_admin_template('metabox-docs-info'); },
684 'dashboard_page_leyka_help',
685 'normal'
686 );
687 // Dark background for the metabox:
688 add_filter('postbox_classes_dashboard_page_leyka_help_leyka_docs_info', function($classes){
689 return array('leyka-metabox-dark');
690 });
691
692 add_meta_box(
693 'leyka_feedback',
694 __('Ask a question', 'leyka'),
695 function(){
696 $this->_show_admin_template('metabox-feedback');
697 },
698 'dashboard_page_leyka_help',
699 'lower'
700 );
701 // Dark background for the metabox:
702 add_filter('postbox_classes_dashboard_page_leyka_help_leyka_feedback', function($classes){
703 return array('leyka-metabox-dark');
704 });
705
706 $this->_show_admin_template('help-page');
707
708 do_action('leyka_post_help_actions');
709 do_action('leyka_post_admin_actions');
710
711 }
712
713 public function ajax_send_feedback() {
714
715 if( !wp_verify_nonce($_POST['nonce'], 'leyka_feedback_sending') ) {
716 die('1');
717 }
718
719 $_POST['topic'] = htmlentities(trim($_POST['topic']), ENT_COMPAT, 'UTF-8');
720 $_POST['name'] = htmlentities(trim($_POST['name']), ENT_COMPAT, 'UTF-8');
721 $_POST['email'] = htmlentities(trim($_POST['email']), ENT_COMPAT, 'UTF-8');
722 $_POST['text'] = htmlentities(trim($_POST['text']), ENT_COMPAT, 'UTF-8');
723
724 if( !$_POST['name'] || !$_POST['email'] || !$_POST['text'] || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) ) {
725 die('2');
726 }
727
728 add_filter('wp_mail_content_type', 'leyka_set_html_content_type');
729
730 $res = true;
731 $site_env = format_debug_data(humanaize_debug_data(leyka_get_env_and_options()));
732
733 foreach((array)explode(',', LEYKA_SUPPORT_EMAIL) as $email) {
734
735 $email = trim($email);
736 if( !$email || !is_email($email) ) {
737 continue;
738 }
739
740 $res &= wp_mail(
741 $email, __('Leyka: new feedback incoming', 'leyka'),
742 sprintf(
743 "Добрый день!<br><br>
744 Поступила новая обратная связь от пользователя Лейки.<br><br>
745 <strong>Тема:</strong> %s<br>
746 <strong>Имя пользователя:</strong> %s<br>
747 <strong>Почта пользователя:</strong> %s<br>
748 <strong>Текст сообщения:</strong><br>%s<br><br>
749 ---------------- Те�
750 нические данные сайта пользователя --------------<br><br>
751 <strong>Cайт пользователя:</strong> <a href='%s'>%s</a> (IP: %s)<br>
752 <strong>Версия WP:</strong> %s<br>
753 <strong>Версия Лейки:</strong> %s<br>
754 <strong>Параметр admin_email:</strong> %s<br>
755 <strong>Язык:</strong> %s (кодировка: %s)<br>
756 <strong>ПО веб-сервера:</strong> %s<br>
757 <strong>Браузер пользователя:</strong> %s<br>
758 ---------------------------------------------------------------------<br>
759 <pre>%s</pre>",
760 $_POST['topic'], $_POST['name'], $_POST['email'], nl2br($_POST['text']),
761 home_url(), get_bloginfo('name'), $_SERVER['SERVER_ADDR'],
762 get_bloginfo('version'), LEYKA_VERSION, get_bloginfo('admin_email'),
763 get_bloginfo('language'), get_bloginfo('charset'),
764 $_SERVER['SERVER_SOFTWARE'], $_SERVER['HTTP_USER_AGENT'],
765 $site_env
766 ),
767 array('From: '.$_POST['name'].' <'.$_POST['email'].'>', 'Return-path: '.$_POST['email'],)
768 );
769 }
770
771 // Reset content-type to avoid conflicts (http://core.trac.wordpress.org/ticket/23578):
772 remove_filter('wp_mail_content_type', 'leyka_set_html_content_type');
773
774 die($res ? '0' : '3');
775
776 }
777
778 public function show_footer() {
779 leyka_show_admin_footer();
780 }
781
782 protected function _load_data_tables() {
783
784 wp_enqueue_style('jquery-dataTables', LEYKA_PLUGIN_BASE_URL.'css/jquery.dataTables.css');
785 wp_enqueue_script('jquery-dataTables', LEYKA_PLUGIN_BASE_URL.'js/jquery.dataTables.min.js', array('jquery'), false, true);
786
787 wp_localize_script('jquery-dataTables', 'leyka_dt', array(
788 'processing' => __('Processing...', 'leyka'),
789 'search' => __('Search:', 'leyka'),
790 'lengthMenu' => __('Show _MENU_ entries', 'leyka'),
791 'info' => __('Showing _START_ to _END_ of _TOTAL_ entries', 'leyka'),
792 'infoEmpty' => __('Showing 0 to 0 of 0 entries', 'leyka'),
793 'infoFiltered' => __('(filtered from _MAX_ total entries)', 'leyka'),
794 'infoThousands' => __(',', 'leyka'),
795 'loadingRecords' => __('Loading...', 'leyka'),
796 'infoPostFix' => '',
797 'zeroRecords' => __('No matching records found', 'leyka'),
798 'emptyTable' => __('No data available in table', 'leyka'),
799 'paginate_first' => __('First', 'leyka'),
800 'paginate_previous' => __('Previous', 'leyka'),
801 'paginate_next' => __('Next', 'leyka'),
802 'paginate_last' => __('Last', 'leyka'),
803 'aria_sortAsc' => __(': activate to sort column ascending', 'leyka'),
804 'aria_sortDesc' => __(': activate to sort column descending', 'leyka'),
805 ));
806
807 return 'jquery-dataTables';
808
809 }
810
811 public function load_frontend_scripts() {
812
813 wp_enqueue_style('leyka-icon', LEYKA_PLUGIN_BASE_URL.'css/admin-icon.css', array(), LEYKA_VERSION);
814
815 $screen = get_current_screen();
816 if(false === stripos($screen->base, 'leyka') && false === stripos($screen->id, 'leyka')) {
817 return;
818 }
819
820 // Base admin area js/css:
821 $leyka_admin_new = (isset($_GET['screen']) && count(explode('-', $_GET['screen'])) >= 2) // New settings pages (from v3.0)
822 || (isset($_GET['page']) && $_GET['page'] === 'leyka_settings')
823 || ($screen->post_type === Leyka_Campaign_Management::$post_type && $screen->base === 'post')
824 || (isset($_GET['page']) && ($_GET['page'] === 'leyka' || $_GET['page'] === 'leyka_donors'))
825 || (isset($_GET['page']) && $_GET['page'] === 'leyka_donor_info' && !empty($_GET['donor']))
826 || (isset($_GET['page']) && ($_GET['page'] === 'leyka' || $_GET['page'] === 'leyka_recurring_subscriptions'))
827 || (isset($_GET['page']) && $_GET['page'] === 'leyka_extensions')
828 || (isset($_GET['page']) && $_GET['page'] === 'leyka_extension_settings' && !empty($_GET['extension']))
829 || (isset($_GET['page']) && $_GET['page'] === 'leyka_help');
830
831 $current_screen = get_current_screen();
832 $dependencies = array('jquery',);
833
834 if($leyka_admin_new) {
835
836 wp_enqueue_style(
837 'jqueryui',
838 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css',
839 false,
840 null
841 );
842
843 wp_enqueue_style('leyka-settings', LEYKA_PLUGIN_BASE_URL.'assets/css/admin.css', array('jqueryui'), LEYKA_VERSION);
844
845 // Colorpicker fields support:
846 wp_enqueue_script('wp-color-picker');
847 wp_enqueue_style('wp-color-picker');
848
849 if(function_exists('wp_enqueue_code_editor')) { // The function is available in WP v4.9.0+
850 wp_enqueue_code_editor(array('type' => 'text/css')); // Add the code editor lib
851 }
852
853 // WP admin metaboxes support:
854 $dependencies[] = 'postbox';
855 $dependencies[] = 'jquery-ui-accordion';
856 $dependencies[] = 'jquery-ui-sortable';
857 $dependencies[] = 'jquery-ui-selectmenu';
858 $dependencies[] = 'tags-box';
859
860 } else { // Old admin pages (before v3.0)
861 /** @todo ATM, the old admin.css is used only for New & Edit Donation pages (/css/admin.css, lines 502-730). Move their code to the /src/ , then remove the /css/admin.css */
862 wp_enqueue_style('leyka-admin', LEYKA_PLUGIN_BASE_URL.'css/admin.css', array(), LEYKA_VERSION);
863 wp_enqueue_style('leyka-settings', LEYKA_PLUGIN_BASE_URL.'assets/css/admin.css', array(), LEYKA_VERSION);
864 }
865
866 if($current_screen->id === 'dashboard_page_leyka_donor_info') {
867 $dependencies[] = $this->_load_data_tables();
868 }
869
870 // Settings pages:
871 if(stristr($current_screen->id, '_page_leyka_settings') !== false) {
872
873 $dependencies[] = 'jquery-ui-sortable';
874
875 wp_enqueue_script('leyka-sticky', LEYKA_PLUGIN_BASE_URL.'js/jquery.sticky.js', $dependencies, LEYKA_VERSION, true);
876 $dependencies[] = 'leyka-sticky';
877
878 }
879
880 if($current_screen->post_type === Leyka_Donation_Management::$post_type) {
881
882 $dependencies[] = 'jquery-ui-autocomplete';
883 $dependencies[] = 'jquery-ui-tooltip';
884
885 }
886
887 $js_data = apply_filters('leyka_admin_js_localized_strings', array(
888 'ajaxurl' => admin_url('admin-ajax.php'),
889 'ajax_loader_url' => LEYKA_PLUGIN_BASE_URL.'img/ajax-loader.gif',
890 'homeurl' => home_url('/'),
891 'plugin_url' => LEYKA_PLUGIN_BASE_URL,
892 'field_required' => __('This field is required to be filled', 'leyka'),
893 'field_x_required'=> __('%s value is mandatory', 'leyka'),
894 'email_invalid_msg' => __('You have entered an invalid email', 'leyka'),
895 'common_error_message' => __('Error while saving the data', 'leyka'),
896 'error_message' => __('Error!', 'leyka'),
897 'default_image_message' => __('Default', 'leyka'),
898 'disconnect_stats' => __('Disconnect statistics', 'leyka'),
899 'confirm_delete_comment' => __('Delete comment?', 'leyka'),
900 'first_donation_date_incomplete_message' => __('To correctly search for "First Payment Date", select the range of their two dates.', 'leyka'),
901 'last_donation_date_incomplete_message' => __('To correctly search for "Last Payment Date", select the range of their two dates.', 'leyka'),
902 'extension_deletion_confirm_text' => __('Are you sure you want to remove the extension completely?', 'leyka'),
903 'extensions_list_page_url' => admin_url('admin.php?page=leyka_extensions'),
904 'extension_colors_reset' => __('Reset settings', 'leyka'),
905 'extension_colors_make_change' => __('Make changes', 'leyka'),
906 ));
907
908 if(isset($_GET['page']) && $_GET['page'] === 'leyka') {
909
910 $dependencies[] = 'jquery-ui-dialog'; // wp_enqueue_script('jquery-ui-dialog');
911
912 wp_enqueue_script('leyka-admin', LEYKA_PLUGIN_BASE_URL.'assets/js/Chart.v2.8.0.min.js', $dependencies, LEYKA_VERSION, true);
913
914 }
915
916 leyka_localize_rich_html_text_tags();
917
918 // Campaign edit page:
919 if(
920 $screen->post_type === Leyka_Campaign_Management::$post_type
921 && $screen->base === 'post'
922 && ( !$screen->action || $screen->action === 'add' )
923 ) {
924
925 $dependencies[] = $this->_load_data_tables();
926
927 if(function_exists('wp_enqueue_code_editor')) { // The function is available in WP v4.9.0+
928 wp_enqueue_code_editor(array('type' => 'text/css')); // Add the code editor lib
929 }
930
931 wp_enqueue_script('jquery-ui-dialog');
932
933 }
934
935 $locale = get_locale();
936 wp_enqueue_script(
937 'jquery-ui-datepicker-locale',
938 LEYKA_PLUGIN_BASE_URL."js/jq-datepicker-locales/$locale.js",
939 array('jquery-ui-datepicker'), LEYKA_VERSION, true
940 );
941
942 // Donation edit page:
943 if($screen->post_type === Leyka_Donation_Management::$post_type && $screen->base === 'post') {
944
945 $dependencies[] = 'jquery-ui-datepicker-locale';
946
947 $js_data = $js_data + array(
948 'add_donation_button_text' => __('Add the donation', 'leyka'),
949 'field_required' => __('This field is required to be filled', 'leyka'),
950 'campaign_required' => __('Selecting a campaign is required', 'leyka'),
951 'email_invalid_msg' => __('You have entered an invalid email', 'leyka'),
952 'amount_incorrect_msg' => __('The amount must be filled with non-zero, non-negative number', 'leyka'),
953 'donation_source_required' => __('Please, set one of a payment methods or just type a few words to describe a source for this donation', 'leyka'),
954 );
955
956 }
957
958 $dependencies[] = 'jquery-ui-autocomplete';
959
960 wp_enqueue_script('leyka-easy-modal', LEYKA_PLUGIN_BASE_URL.'js/jquery.easyModal.min.js', array(), false, true);
961 wp_enqueue_script(
962 'leyka-settings',
963 LEYKA_PLUGIN_BASE_URL.'assets/js/admin.js',
964 $dependencies,
965 LEYKA_VERSION,
966 true
967 );
968 wp_localize_script('leyka-settings', 'leyka', $js_data);
969
970 }
971
972 }