PluginProbe
WP Approve User / 8
WP Approve User v8
13 12 trunk 1.0 1.1.0 1.1.1 10 11 2.0.0 2.1.0 2.1.1 2.2.0 2.2.1 2.2.2 2.2.3 2.4.0 3 4 5 6 7 8 9
wp-approve-user / wp-approve-user.php

wp-approve-user.php in WP Approve User 8, at wp-approve-user.php

1,140 lines 30.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: WP Approve User
4 * Plugin URI: http://en.wp.obenland.it/wp-approve-user/#utm_source=wordpress&utm_medium=plugin&utm_campaign=wp-approve-user
5 * Description: Adds action links to user table to approve or unapprove user registrations.
6 * Version: 8
7 * Author: Konstantin Obenland
8 * Author URI: http://en.wp.obenland.it/#utm_source=wordpress&utm_medium=plugin&utm_campaign=wp-approve-user
9 * Text Domain: wp-approve-user
10 * Domain Path: /lang
11 * License: GPLv2
12 *
13 * @package WP Approve User
14 */
15
16 if ( ! get_option( 'users_can_register' ) ) {
17 require_once 'noop.php';
18 return;
19 }
20
21
22 if ( ! class_exists( 'Obenland_Wp_Plugins_V4' ) ) {
23 require_once 'obenland-wp-plugins.php';
24 }
25
26 /**
27 * Class Obenland_Wp_Approve_User.
28 */
29 class Obenland_Wp_Approve_User extends Obenland_Wp_Plugins_V4 {
30
31 /**
32 * Class instance.
33 *
34 * @since 1.1.0 - 12.02.2012
35 * @access public
36 * @static
37 *
38 * @var Obenland_Wp_Approve_User
39 */
40 public static $instance;
41
42 /**
43 * The plugin options.
44 *
45 * @author Konstantin Obenland
46 * @since 2.0.0 - 31.03.2012
47 * @access protected
48 *
49 * @var array
50 */
51 protected $options;
52
53 /**
54 * Users flagged as unapproved.
55 *
56 * @author Konstantin Obenland
57 * @since 2.2.0 - 30.03.2013
58 * @access protected
59 *
60 * @var array
61 */
62 protected $unapproved_users = array();
63
64
65 /**
66 * Constructor
67 *
68 * @author Konstantin Obenland
69 * @since 1.0 - 29.01.2012
70 * @access public
71 */
72 public function __construct() {
73 parent::__construct( array(
74 'textdomain' => 'wp-approve-user',
75 'plugin_path' => __FILE__,
76 'donate_link_id' => 'G65Y5CM3HVRNY',
77 ) );
78
79 self::$instance = $this;
80 $this->options = wp_parse_args(
81 get_option( $this->textdomain, array() ),
82 $this->default_options()
83 );
84
85 if ( is_admin() ) {
86 $args = array(
87 'meta_key' => 'wp-approve-user',
88 'meta_value' => false,
89 );
90
91 if ( is_multisite() ) {
92 $args['blog_id'] = is_network_admin() ? 0 : get_current_blog_id();
93 }
94
95 $this->unapproved_users = get_users( $args );
96 }
97
98 load_plugin_textdomain( 'wp-approve-user', false, 'wp-approve-user/lang' );
99
100 $this->hook( 'plugins_loaded' );
101 }
102
103
104 /**
105 * Approves all existing users.
106 *
107 * @author Konstantin Obenland
108 * @since 1.0 - 29.01.2012
109 * @access public
110 * @static
111 *
112 * @return void
113 */
114 public function activation() {
115 $user_ids = get_users( array(
116 'blog_id' => '',
117 'fields' => 'ID',
118 ) );
119
120 foreach ( $user_ids as $user_id ) {
121 add_user_meta( $user_id, 'wp-approve-user', true, true );
122 add_user_meta( $user_id, 'wp-approve-user-mail-sent', true, true );
123 }
124 }
125
126
127 /**
128 * Hooks in all the hooks :)
129 *
130 * @author Konstantin Obenland
131 * @since 1.1 - 12.02.2012
132 * @access public
133 *
134 * @return void
135 */
136 public function plugins_loaded() {
137 $this->hook( 'user_row_actions' );
138 $this->hook( 'ms_user_row_actions', 'user_row_actions' );
139 $this->hook( 'wp_authenticate_user' );
140 $this->hook( 'user_register' );
141 $this->hook( 'register_new_user', 0 );
142 $this->hook( 'wp_login_errors' );
143 $this->hook( 'shake_error_codes' );
144
145 $this->hook( 'admin_print_scripts-users.php' );
146 $this->hook( 'admin_print_scripts-site-users.php', 'admin_print_scripts_users_php' );
147 $this->hook( 'admin_print_styles-settings_page_wp-approve-user' );
148
149 $this->hook( 'load-users.php', 'map_action2' );
150 $this->hook( 'load-site-users.php', 'map_action2' );
151 $this->hook( 'admin_action_wpau_approve' );
152 $this->hook( 'admin_action_wpau_bulk_approve' );
153 $this->hook( 'admin_action_wpau_unapprove' );
154 $this->hook( 'admin_action_wpau_bulk_unapprove' );
155 $this->hook( 'admin_action_wpau_update' );
156
157 $this->hook( 'wpau_approve' );
158 $this->hook( 'delete_user' );
159 $this->hook( 'admin_init' );
160
161 if ( is_admin() ) {
162 $this->hook( 'views_users' );
163 $this->hook( 'views_users-network', 'views_users' );
164 $this->hook( 'views_site-users-network', 'views_users' );
165 $this->hook( 'pre_user_query' );
166 }
167
168 if ( is_multisite() ) {
169 $this->hook( 'network_admin_menu', 'admin_menu' );
170 } else {
171 $this->hook( 'admin_menu' );
172 }
173 }
174
175
176 /**
177 * Enqueues the script
178 *
179 * @author Konstantin Obenland
180 * @since 1.1 - 12.02.2012
181 * @access public
182 *
183 * @return void
184 */
185 public function admin_print_scripts_users_php() {
186 $plugin_data = get_plugin_data( __FILE__, false, false );
187 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
188
189 wp_enqueue_script(
190 $this->textdomain,
191 plugins_url( "/js/{$this->textdomain}{$suffix}.js", __FILE__ ),
192 array( 'jquery' ),
193 $plugin_data['Version'],
194 true
195 );
196
197 wp_localize_script( $this->textdomain, 'wp_approve_user', array(
198 'approve' => __( 'Approve', 'wp-approve-user' ),
199 'unapprove' => __( 'Unapprove', 'wp-approve-user' ),
200 ) );
201 }
202
203
204 /**
205 * Enqueues the style on the settings page
206 *
207 * @author Konstantin Obenland
208 * @since 2.0.0 - 10.04.2012
209 * @access public
210 *
211 * @return void
212 */
213 public function admin_print_styles_settings_page_wp_approve_user() {
214 $plugin_data = get_plugin_data( __FILE__, false, false );
215 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
216
217 wp_enqueue_style(
218 $this->textdomain,
219 plugins_url( "/css/settings-page{$suffix}.css", __FILE__ ),
220 array(),
221 $plugin_data['Version']
222 );
223 }
224
225
226 /**
227 * Adds a link to a list view of unapproved users.
228 *
229 * @author Konstantin Obenland
230 * @since 2.2.0 - 30.03.2013
231 * @access public
232 *
233 * @param array $views List of registered user list views.
234 *
235 * @return array
236 */
237 public function views_users( $views ) {
238 if ( $this->unapproved_users ) {
239 // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
240 $site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
241 $url = 'site-users-network' === get_current_screen()->id ? add_query_arg( array( 'id' => $site_id ), 'site-users.php' ) : 'users.php';
242
243 $views['unapproved'] = sprintf(
244 '<a href="%1$s" class="%2$s">%3$s <span class="count">(%4$s)</span></a>',
245 esc_url( add_query_arg( array( 'role' => 'wpau_unapproved' ), $url ) ),
246 // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
247 'wpau_unapproved' === $this->get_role() ? 'current' : '',
248 esc_html__( 'Unapproved', 'wp-approve-users' ),
249 count( $this->unapproved_users )
250 );
251 }
252
253 return $views;
254 }
255
256
257 /**
258 * Resets the user query to handle request for unapproved users only.
259 *
260 * @author Konstantin Obenland
261 * @since 2.2.0 - 30.03.2013
262 * @access public
263 *
264 * @param WP_User_Query $query User query object.
265 *
266 * @return void
267 */
268 public function pre_user_query( $query ) {
269 // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification, WordPress.Security.ValidatedSanitizedInput
270 $role = empty( $query->query_vars['role'] ) && isset( $_REQUEST['role'] ) ? $_REQUEST['role'] : $query->query_vars['role'];
271
272 if ( 'wpau_unapproved' === $role ) {
273 unset( $query->query_vars['meta_query'] );
274 $query->query_vars['role'] = '';
275 $query->query_vars['meta_key'] = 'wp-approve-user';
276 $query->query_vars['meta_value'] = false;
277
278 remove_filter( 'pre_user_query', array( $this, 'pre_user_query' ) );
279 $query->prepare_query();
280 }
281 }
282
283
284 /**
285 * Adds the plugin's row actions to the existing ones.
286 *
287 * @author Konstantin Obenland
288 * @since 1.0 - 29.01.2012
289 * @access public
290 *
291 * @param array $actions User action links.
292 * @param WP_User $user_object User object.
293 *
294 * @return array
295 */
296 public function user_row_actions( $actions, $user_object ) {
297 if ( get_current_user_id() !== $user_object->ID && current_user_can( 'edit_user', $user_object->ID ) ) {
298 // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
299 $site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
300 $url = 'site-users-network' === get_current_screen()->id ? add_query_arg( array( 'id' => $site_id ), 'site-users.php' ) : 'users.php';
301
302 if ( get_user_meta( $user_object->ID, 'wp-approve-user', true ) ) {
303 $url = wp_nonce_url( add_query_arg( array(
304 'action' => 'wpau_unapprove',
305 'user' => $user_object->ID,
306 ), $url ), 'wpau-unapprove-users' );
307
308 $actions['wpau-unapprove'] = sprintf( '<a class="submitunapprove" href="%1$s">%2$s</a>', esc_url( $url ), esc_html__( 'Unapprove', 'wp-approve-user' ) );
309
310 } else {
311 $url = wp_nonce_url( add_query_arg( array(
312 'action' => 'wpau_approve',
313 'user' => $user_object->ID,
314 'role' => $this->get_role(),
315 ), $url ), 'wpau-approve-users' );
316
317 $actions['wpau-approve'] = sprintf( '<a class="submitapprove" href="%1$s">%2$s</a>', esc_url( $url ), esc_html__( 'Approve', 'wp-approve-user' ) );
318 }
319 }
320
321 return $actions;
322 }
323
324
325 /**
326 * Checks whether the user is approved. Throws error if not.
327 *
328 * @author Konstantin Obenland
329 * @since 1.0 - 29.01.2012
330 * @access public
331 *
332 * @param WP_User|WP_Error $userdata User object.
333 *
334 * @return WP_User|WP_Error
335 */
336 public function wp_authenticate_user( $userdata ) {
337 if ( ! is_wp_error( $userdata ) && ! get_user_meta( $userdata->ID, 'wp-approve-user', true ) && get_bloginfo( 'admin_email' ) !== $userdata->user_email ) {
338 $userdata = new WP_Error(
339 'wpau_confirmation_error',
340 wp_kses_post( __( '<strong>ERROR:</strong> Your account has to be confirmed by an administrator before you can login.', 'wp-approve-user' ) )
341 );
342 }
343
344 return $userdata;
345 }
346
347
348 /**
349 * Updates user_meta to approve user when created by an Administrator.
350 *
351 * @author Konstantin Obenland
352 * @since 1.1 - 12.02.2012
353 * @access public
354 *
355 * @param int $id User ID.
356 *
357 * @return void
358 */
359 public function user_register( $id ) {
360 update_user_meta( $id, 'wp-approve-user', current_user_can( 'create_users' ) );
361 update_user_meta( $id, 'wp-approve-user-new-registration', true );
362 }
363
364 /**
365 * Fires after a new user registration has been recorded.
366 *
367 * @author Konstantin Obenland
368 * @since 6 - 04.03.2019
369 * @access public
370 *
371 * @param int $user_id ID of the newly registered user.
372 */
373 public function register_new_user( $user_id ) {
374 if ( ! get_user_meta( $user_id, 'wp-approve-user', true ) ) {
375 remove_action( 'register_new_user', 'wp_send_new_user_notifications' );
376 add_action( 'register_new_user', 'wp_new_user_notification' );
377 }
378 }
379
380 /**
381 * Calls actions that depend on the `action` parameter.
382 *
383 * @author Konstantin Obenland
384 * @since 3 - 21.12.2017
385 * @access public
386 */
387 public function map_action2() {
388 // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification, WordPress.Security.ValidatedSanitizedInput
389
390 if ( ! empty( $_REQUEST['action2'] ) && false !== stripos( $_REQUEST['action2'], 'wpau_' ) ) {
391 do_action( "admin_action_{$_REQUEST['action2']}" );
392 }
393
394 // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification, WordPress.Security.ValidatedSanitizedInput
395 }
396
397
398 /**
399 * Updates user_meta to approve user.
400 *
401 * @author Konstantin Obenland
402 * @since 1.1 - 12.02.2012
403 * @access public
404 *
405 * @return void
406 */
407 public function admin_action_wpau_approve() {
408 check_admin_referer( 'wpau-approve-users' );
409 $this->approve();
410 }
411
412
413 /**
414 * Bulkupdates user_meta to approve user.
415 *
416 * @author Konstantin Obenland
417 * @since 1.1 - 12.02.2012
418 * @access public
419 *
420 * @return void
421 */
422 public function admin_action_wpau_bulk_approve() {
423 $action = 'users-network' === get_current_screen()->id ? 'bulk-users-network' : 'bulk-users';
424 check_admin_referer( $action );
425
426 $this->set_up_role_context();
427 $this->approve();
428 }
429
430
431 /**
432 * Updates user_meta to unapprove user.
433 *
434 * @author Konstantin Obenland
435 * @since 1.1 - 12.02.2012
436 * @access public
437 *
438 * @return void
439 */
440 public function admin_action_wpau_unapprove() {
441 check_admin_referer( 'wpau-unapprove-users' );
442 $this->unapprove();
443 }
444
445
446 /**
447 * Bulkupdates user_meta to unapprove user.
448 *
449 * @author Konstantin Obenland
450 * @since 1.1 - 12.02.2012
451 * @access public
452 *
453 * @return void
454 */
455 public function admin_action_wpau_bulk_unapprove() {
456 $action = 'users-network' === get_current_screen()->id ? 'bulk-users-network' : 'bulk-users';
457 check_admin_referer( $action );
458
459 $this->set_up_role_context();
460 $this->unapprove();
461 }
462
463
464 /**
465 * Adds the update message to the admin notices queue.
466 *
467 * @author Konstantin Obenland
468 * @since 1.1 - 12.02.2012
469 * @access public
470 *
471 * @return void
472 */
473 public function admin_action_wpau_update() {
474 // phpcs:disable WordPress.Security.ValidatedSanitizedInput, WordPress.CSRF.NonceVerification.NoNonceVerification
475 if ( empty( $_REQUEST['update'] ) ) {
476 return;
477 }
478
479 $count = absint( $_REQUEST['count'] );
480
481 switch ( $_REQUEST['update'] ) {
482 case 'wpau-approved':
483 /* translators: Number of users. */
484 $message = esc_html( _n( '%d User approved.', '%d users approved.', $count, 'wp-approve-user' ) );
485 break;
486
487 case 'wpau-unapproved':
488 /* translators: Number of users. */
489 $message = esc_html( _n( '%d User unapproved.', '%d users unapproved.', $count, 'wp-approve-user' ) );
490 break;
491
492 default:
493 $message = apply_filters( 'wpau_update_message_handler', '', $_REQUEST['update'] );
494 }
495
496 if ( isset( $message ) ) {
497 add_settings_error(
498 $this->textdomain,
499 esc_attr( $_REQUEST['update'] ),
500 sprintf( $message, $count ),
501 'updated'
502 );
503
504 $this->hook( 'all_admin_notices' );
505 }
506
507 // Prevent other admin action handlers from trying to handle our action.
508 $_REQUEST['action'] = -1;
509
510 // phpcs:enable WordPress.Security.ValidatedSanitizedInput, WordPress.CSRF.NonceVerification.NoNonceVerification
511 }
512
513 /**
514 * Filters the login page errors.
515 *
516 * @author Konstantin Obenland
517 * @since 6 - 04.03.2019
518 * @access public
519 *
520 * @param \WP_Error $errors WP Error object.
521 * @return \WP_Error
522 */
523 public function wp_login_errors( $errors ) {
524 if ( in_array( 'registered', $errors->get_error_codes(), true ) ) {
525 $message = __( 'Registration complete. You will receive an email once your registration was confirmed by an administrator.', 'wp-approve-user' );
526 $errors->remove( 'registered' );
527 $errors->add( 'registered', $message, 'message' );
528 }
529
530 return $errors;
531 }
532
533
534 /**
535 * Adds our error code to make the login form shake :)
536 *
537 * @author Konstantin Obenland
538 * @since 1.0 - 29.01.2012
539 * @access public
540 *
541 * @param array $shake_error_codes Error codes that trigger form shaking.
542 *
543 * @return array Shake error codes
544 */
545 public function shake_error_codes( $shake_error_codes ) {
546 $shake_error_codes[] = 'wpau_confirmation_error';
547
548 return $shake_error_codes;
549 }
550
551
552 /**
553 * Enhances the User menu item to reflect the amount of unapproved users.
554 *
555 * @author Konstantin Obenland
556 * @since 1.1 - 12.02.2012
557 * @access public
558 *
559 * @return void
560 */
561 public function admin_menu() {
562 if ( current_user_can( 'list_users' ) && version_compare( get_bloginfo( 'version' ), '3.2', '>=' ) ) {
563 global $menu;
564
565 foreach ( $menu as $key => $menu_item ) {
566 if ( array_search( 'users.php', $menu_item, true ) ) {
567
568 // No need for number formatting, count() always returns an integer.
569 $awaiting_mod = count( $this->unapproved_users );
570
571 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
572 $menu[ $key ][0] .= " <span class='update-plugins count-{$awaiting_mod}'><span class='plugin-count'>{$awaiting_mod}</span></span>";
573
574 break; // Bail on success.
575 }
576 }
577 }
578
579 add_submenu_page(
580 is_multisite() ? 'settings.php' : 'options-general.php',
581 esc_html__( 'Approve User', 'wp-approve-user' ), // Page Title.
582 esc_html__( 'Approve User', 'wp-approve-user' ), // Menu Title.
583 'promote_users', // Capability.
584 $this->textdomain, // Menu Slug.
585 array( $this, 'settings_page' ) // Function.
586 );
587 }
588
589
590 /**
591 * Registers the plugins' settings.
592 *
593 * @author Konstantin Obenland
594 * @since 1.0.0 - 02.03.2012
595 * @access public
596 *
597 * return void
598 */
599 public function admin_init() {
600 register_setting(
601 $this->textdomain,
602 'wp-approve-user',
603 array( &$this, 'sanitize' )
604 );
605
606 add_settings_section(
607 $this->textdomain,
608 esc_html__( 'Email contents', 'wp-approve-user' ),
609 array( $this, 'section_description_cb' ),
610 $this->textdomain
611 );
612
613 add_settings_field(
614 'wp-approve-user[send-approve-email]',
615 esc_html__( 'Send Approve Email', 'wp-approve-user' ),
616 array( $this, 'checkbox_cb' ),
617 $this->textdomain,
618 $this->textdomain,
619 array(
620 'name' => 'wpau-send-approve-email',
621 'description' => __( 'Send email on approval.', 'wp-approve-user' ),
622 )
623 );
624
625 add_settings_field(
626 'wp-approve-user[approve-email]',
627 esc_html__( 'Approve Email', 'wp-approve-user' ),
628 array( $this, 'textarea_cb' ),
629 $this->textdomain,
630 $this->textdomain,
631 array(
632 'label_for' => 'wpau-approve-email',
633 'name' => 'wpau-approve-email',
634 'setting' => 'wpau-send-approve-email',
635 )
636 );
637
638 add_settings_field(
639 'wp-approve-user[send-unapprove-email]',
640 esc_html__( 'Send Unapprove Email', 'wp-approve-user' ),
641 array( $this, 'checkbox_cb' ),
642 $this->textdomain,
643 $this->textdomain,
644 array(
645 'name' => 'wpau-send-unapprove-email',
646 'description' => __( 'Send email on unapproval.', 'wp-approve-user' ),
647 )
648 );
649 add_settings_field(
650 'wp-approve-user[unapprove-email]',
651 esc_html__( 'Unapprove Email', 'wp-approve-user' ),
652 array( $this, 'textarea_cb' ),
653 $this->textdomain,
654 $this->textdomain,
655 array(
656 'label_for' => 'wpau-unapprove-email',
657 'name' => 'wpau-unapprove-email',
658 'setting' => 'wpau-send-unapprove-email',
659 )
660 );
661 }
662
663
664 /**
665 * Displays the options page.
666 *
667 * @author Konstantin Obenland
668 * @since 2.0.0 - 31.03.2012
669 * @access public
670 *
671 * @return void
672 */
673 public function settings_page() {
674 ?>
675 <div class="wrap">
676 <?php screen_icon(); ?>
677 <h2><?php esc_html_e( 'Approve User Settings', 'wp-approve-user' ); ?></h2>
678
679 <div id="poststuff">
680 <div id="post-body" class="obenland-wp columns-2">
681 <div id="post-body-content">
682 <form method="post" action="options.php">
683 <?php
684 settings_fields( $this->textdomain );
685 do_settings_sections( $this->textdomain );
686 submit_button();
687 ?>
688 </form>
689 </div>
690 <div id="postbox-container-1">
691 <div id="side-info-column">
692 <?php do_action( 'obenland_side_info_column' ); ?>
693 </div>
694 </div>
695 </div>
696 </div>
697 </div>
698 <?php
699 }
700
701
702 /**
703 * Prints the section description.
704 *
705 * @author Konstantin Obenland
706 * @since 2.0.0 - 31.03.2012
707 * @access public
708 *
709 * @return void
710 */
711 public function section_description_cb() {
712 $tags = array( 'USERNAME', 'BLOG_TITLE', 'BLOG_URL', 'LOGINLINK' );
713 if ( is_multisite() ) {
714 $tags[] = 'SITE_NAME';
715 }
716
717 printf(
718 /* translators: Placeholders. */
719 esc_html_x( 'To take advantage of dynamic data, you can use the following placeholders: %s. Username will be the user login in most cases.', 'Placeholders', 'wp-approve-user' ),
720 sprintf( '<code>%s</code>', implode( '</code>, <code>', $tags ) ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
721 );
722 }
723
724
725 /**
726 * Populates the setting field.
727 *
728 * @author Konstantin Obenland
729 * @since 2.0.0 - 31.03.2012
730 * @access public
731 *
732 * @param array $option Settings option.
733 *
734 * @return void
735 */
736 public function checkbox_cb( $option ) {
737 $option = (object) $option;
738 ?>
739 <label for="<?php echo esc_attr( sanitize_title_with_dashes( $option->name ) ); ?>">
740 <input type="checkbox" name="wp-approve-user[<?php echo esc_attr( $option->name ); ?>]" id="<?php echo esc_attr( sanitize_title_with_dashes( $option->name ) ); ?>" value="1" <?php checked( $this->options[ $option->name ] ); ?> />
741 <?php echo esc_html( $option->description ); ?>
742 </label><br />
743 <?php
744 }
745
746
747 /**
748 * Populates the setting field.
749 *
750 * @author Konstantin Obenland
751 * @since 2.0.0 - 31.03.2012
752 * @access public
753 *
754 * @param array $option Settings option.
755 *
756 * @return void
757 */
758 public function textarea_cb( $option ) {
759 $option = (object) $option;
760 ?>
761 <textarea id="<?php echo esc_attr( sanitize_title_with_dashes( $option->name ) ); ?>" class="large-text code" name="wp-approve-user[<?php echo esc_attr( $option->name ); ?>]" rows="10" cols="50" ><?php echo esc_textarea( $this->options[ $option->name ] ); ?></textarea>
762 <?php
763 }
764
765
766 /**
767 * Sanitizes the settings input.
768 *
769 * @author Konstantin Obenland
770 * @since 2.0.0 - 31.03.2012
771 * @access public
772 *
773 * @param array $input Form input.
774 *
775 * @return array The sanitized settings
776 */
777 public function sanitize( $input ) {
778 return array(
779 'wpau-send-approve-email' => (bool) isset( $input['wpau-send-approve-email'] ),
780 'wpau-send-unapprove-email' => (bool) isset( $input['wpau-send-unapprove-email'] ),
781 'wpau-approve-email' => isset( $input['wpau-approve-email'] ) ? trim( $input['wpau-approve-email'] ) : '',
782 'wpau-unapprove-email' => isset( $input['wpau-unapprove-email'] ) ? trim( $input['wpau-unapprove-email'] ) : '',
783 );
784 }
785
786
787 /**
788 * Sends the approval email.
789 *
790 * @author Konstantin Obenland
791 * @since 2.0.0 - 31.03.2012
792 * @access public
793 *
794 * @param int $user_id User ID.
795 *
796 * @return void
797 */
798 public function wpau_approve( $user_id ) {
799 if ( get_user_meta( $user_id, 'wp-approve-user-new-registration', true ) ) {
800 wp_new_user_notification( $user_id, null, 'user' );
801 delete_user_meta( $user_id, 'wp-approve-user-new-registration' );
802 }
803
804 // Check user meta if mail has been sent already.
805 if ( $this->options['wpau-send-approve-email'] && ! get_user_meta( $user_id, 'wp-approve-user-mail-sent', true ) ) {
806 $user = new WP_User( $user_id );
807 $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
808
809 // Send mail.
810 $sent = wp_mail(
811 $user->user_email,
812 /* translators: Blog name. */
813 sprintf( esc_html_x( '[%s] Registration approved', 'Blogname', 'wp-approve-user' ), $blogname ),
814 $this->populate_message( $this->options['wpau-approve-email'], $user )
815 );
816
817 if ( $sent ) {
818 update_user_meta( $user_id, 'wp-approve-user-mail-sent', true );
819 }
820 }
821 }
822
823
824 /**
825 * Sends the rejection email.
826 *
827 * @author Konstantin Obenland
828 * @since 2.0.0 - 31.03.2012
829 * @access public
830 *
831 * @param int $user_id User ID.
832 *
833 * @return void
834 */
835 public function delete_user( $user_id ) {
836 $is_new_registration = get_user_meta( $user_id, 'wp-approve-user-new-registration', true );
837 $is_approved = get_user_meta( $user_id, 'wp-approve-user', true );
838
839 if ( $is_new_registration && ! $is_approved && $this->options['wpau-send-unapprove-email'] ) {
840 $user = new WP_User( $user_id );
841 $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
842
843 // Send mail.
844 wp_mail(
845 $user->user_email,
846 /* translators: Blog name. */
847 sprintf( esc_html_x( '[%s] Registration unapproved', 'Blogname', 'wp-approve-user' ), $blogname ),
848 $this->populate_message( $this->options['wpau-unapprove-email'], $user )
849 );
850
851 // No need to delete user_meta, since this user will be GONE.
852 }
853 }
854
855
856 /**
857 * Display all messages registered to this plugin.
858 *
859 * @author Konstantin Obenland
860 * @since 2.0.0 - 30.03.2012
861 * @access public
862 *
863 * @return void
864 */
865 public function all_admin_notices() {
866 settings_errors( $this->textdomain );
867 }
868
869
870 /**
871 * Updates user_meta to approve user.
872 *
873 * @author Konstantin Obenland
874 * @since 1.1 - 12.02.2012
875 * @access protected
876 *
877 * @return void
878 */
879 protected function approve() {
880 list( $user_ids, $url ) = $this->check_user();
881
882 foreach ( (array) $user_ids as $id ) {
883 $id = (int) $id;
884
885 if ( ! current_user_can( 'edit_user', $id ) ) {
886 wp_die( esc_html__( 'You can&#8217;t edit that user.' ), '', array(
887 'back_link' => true,
888 ) );
889 }
890
891 update_user_meta( $id, 'wp-approve-user', true );
892 do_action( 'wpau_approve', $id );
893 }
894
895 wp_safe_redirect( add_query_arg( array(
896 'action' => 'wpau_update',
897 'update' => 'wpau-approved',
898 'count' => count( $user_ids ),
899 'role' => $this->get_role(),
900 ), $url ) );
901 exit();
902 }
903
904
905 /**
906 * Updates user_meta to unapprove user.
907 *
908 * @author Konstantin Obenland
909 * @since 1.1 - 12.02.2012
910 * @access protected
911 *
912 * @return void
913 */
914 protected function unapprove() {
915 list( $user_ids, $url ) = $this->check_user();
916
917 foreach ( (array) $user_ids as $id ) {
918 $id = (int) $id;
919
920 if ( ! current_user_can( 'edit_user', $id ) ) {
921 wp_die( esc_html__( 'You can&#8217;t edit that user.' ), '', array(
922 'back_link' => true,
923 ) );
924 }
925
926 update_user_meta( $id, 'wp-approve-user', false );
927 do_action( 'wpau_unapprove', $id );
928 }
929
930 wp_safe_redirect( add_query_arg( array(
931 'action' => 'wpau_update',
932 'update' => 'wpau-unapproved',
933 'count' => count( $user_ids ),
934 'role' => $this->get_role(),
935 ), $url ) );
936 exit();
937 }
938
939
940 /**
941 * Checks permissions and assembles User IDs.
942 *
943 * @author Konstantin Obenland
944 * @since 2.0.0 - 15.03.2012
945 * @access protected
946 *
947 * @return array User IDs and URL
948 */
949 protected function check_user() {
950 // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
951
952 $screen_id = get_current_screen()->id;
953 $users_key = 'user';
954
955 if ( false !== stripos( current_action(), 'wpau_bulk_' ) ) {
956 $users_key = 'users-network' === $screen_id ? 'allusers' : 'users';
957 }
958
959 $site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
960 $url = 'site-users-network' === $screen_id ? add_query_arg( array( 'id' => $site_id ), 'site-users.php' ) : 'users.php';
961
962 if ( empty( $_REQUEST[ $users_key ] ) && empty( $_REQUEST[ $users_key ] ) ) {
963 wp_safe_redirect( $url );
964 exit();
965 }
966
967 if ( ! current_user_can( 'promote_users' ) ) {
968 wp_die( esc_html__( 'You can&#8217;t unapprove users.', 'wp-approve-user' ), '', array(
969 'back_link' => true,
970 ) );
971 }
972
973 $user_ids = array_map( 'intval', (array) $_REQUEST[ $users_key ] );
974 $user_ids = array_diff( $user_ids, array( get_user_by( 'email', get_bloginfo( 'admin_email' ) )->ID ) );
975
976 return array( $user_ids, $url );
977
978 // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
979 }
980
981
982 /**
983 * Replaces all the placeholders with their content.
984 *
985 * @author Konstantin Obenland
986 * @since 2.0.0 - 15.03.2012
987 * @access protected
988 *
989 * @param string $message Email body.
990 * @param WP_User $user User object.
991 *
992 * @return string
993 */
994 protected function populate_message( $message, $user ) {
995 $placeholders = array(
996 'BLOG_TITLE' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ),
997 'BLOG_URL' => home_url(),
998 'LOGINLINK' => wp_login_url(),
999 'USERNAME' => $user->user_nicename,
1000 );
1001
1002 if ( is_multisite() ) {
1003 $placeholders['SITE_NAME'] = $GLOBALS['current_site']->site_name;
1004 }
1005
1006 /**
1007 * Filters the placeholders in approve/unapprove emails.
1008 *
1009 * @since 7
1010 *
1011 * @param array $placeholders Key => Value pair of placeholders and the value they're replaced with.
1012 * @param string $message Message that will have its placeholders replaced. Note: This will not change the message.
1013 * Use `option_wp-approve-user` to filter message bodies.
1014 * @param WP_User $user WP_User object of the user being approved/unapproved.
1015 */
1016 $placeholders = apply_filters( 'wpau_message_placeholders', $placeholders, $message, $user );
1017
1018 foreach ( $placeholders as $placeholder => $replacement ) {
1019 $message = str_replace( $placeholder, $replacement, $message );
1020 }
1021
1022 return $message;
1023 }
1024
1025
1026 /**
1027 * Returns the default options.
1028 *
1029 * @author Konstantin Obenland
1030 * @since 2.0.0 - 15.03.2012
1031 * @access protected
1032 *
1033 * @return array
1034 */
1035 protected function default_options() {
1036 $options = array(
1037 'wpau-send-approve-email' => false,
1038 'wpau-approve-email' => '
1039 Hi USERNAME,
1040 Your registration for BLOG_TITLE has now been approved.
1041
1042 You can log in, using your username and password that you created when registering for our website, at the following URL: LOGINLINK
1043
1044 If you have any questions, or problems, then please do not hesitate to contact us.
1045
1046 Name,
1047 Company,
1048 Contact details',
1049 'wpau-send-unapprove-email' => false,
1050 'wpau-unapprove-email' => '',
1051 );
1052
1053 return apply_filters( 'wpau_default_options', $options );
1054 }
1055
1056 /**
1057 * Sets the role context on bulk actions.
1058 *
1059 * On bulk actions the role parameter is not passed, since we're using a form
1060 * to submit information. The information is only available through the
1061 * `_wp_http_referer` parameter, so we get it from there and make it available
1062 * for the request.
1063 *
1064 * @author Konstantin Obenland
1065 * @since 3 - 04.09.2014
1066 * @access protected
1067 */
1068 protected function set_up_role_context() {
1069 // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification, WordPress.Security.ValidatedSanitizedInput
1070
1071 if ( empty( $_REQUEST['role'] ) && ! empty( $_REQUEST['_wp_http_referer'] ) ) {
1072 $referrer = parse_url( $_REQUEST['_wp_http_referer'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url
1073
1074 if ( ! empty( $referrer['query'] ) ) {
1075 $args = wp_parse_args( $referrer['query'] );
1076
1077 if ( ! empty( $args['role'] ) ) {
1078 $_REQUEST['role'] = $args['role'];
1079 }
1080 }
1081 }
1082 }
1083
1084 /**
1085 * Returns the current role.
1086 *
1087 * If the user list is in the context of a specific role, this function makes
1088 * sure that the requested role is valid. By returning `false` otherwise, we
1089 * make sure that parameter gets removed from the activation link.
1090 *
1091 * @author Konstantin Obenland
1092 * @since 3 - 04.09.2014
1093 * @access protected
1094 *
1095 * @return string|bool The role key if set, false otherwise.
1096 */
1097 protected function get_role() {
1098 $roles = array_keys( get_editable_roles() );
1099 $roles[] = 'wpau_unapproved';
1100 $role = false;
1101
1102 if ( isset( $_REQUEST['role'] ) && in_array( $_REQUEST['role'], $roles, true ) ) {
1103 $role = $_REQUEST['role'];
1104 }
1105
1106 return $role;
1107
1108 // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification, WordPress.Security.ValidatedSanitizedInput
1109 }
1110
1111 /**
1112 * Re-runs the activation hook when registration is activated.
1113 *
1114 * If the plugin is activated and user registration is disabled, the plugin
1115 * activation hook never gets added, let alone fired. This a secondary
1116 * measure to make sure all existing users are approved on activation.
1117 *
1118 * @author Konstantin Obenland
1119 * @deprecated 2.3.0 - 13.08.2013
1120 * @access public
1121 *
1122 * @param string $old Old settings value.
1123 * @param int $new New settings value.
1124 *
1125 * @return void
1126 */
1127 public function update_option_users_can_register( $old, $new ) {
1128 _deprecated_function( __FUNCTION__, '2.3' );
1129 }
1130 } // End of class Obenland_Wp_Approve_User
1131
1132
1133 new Obenland_Wp_Approve_User();
1134
1135
1136 register_activation_hook( __FILE__, array(
1137 Obenland_Wp_Approve_User::$instance,
1138 'activation',
1139 ) );
1140