Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Users_List_Table
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 4
210
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 add_magic_email_link
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 send_magic_email_link
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
42
 print_admin_notice
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2/**
3 * Add a "send magic link" button to the users list table
4 *
5 * @package brianhenryie/bh-wp-autologin-urls
6 */
7
8namespace BrianHenryIE\WP_Autologin_URLs\Admin;
9
10use BrianHenryIE\WP_Autologin_URLs\API_Interface;
11use BrianHenryIE\WP_Autologin_URLs\Settings_Interface;
12use WP_User;
13
14/**
15 * Hooks into WP_User_List_Table to add the link; handles sending the link on the page load.
16 */
17class Users_List_Table {
18
19    protected Settings_Interface $settings;
20
21    protected API_Interface $api;
22
23    /**
24     * Constructor.
25     *
26     * @param API_Interface      $api For sending the magic link email.
27     * @param Settings_Interface $settings The check is the setting enabled.
28     */
29    public function __construct( API_Interface $api, Settings_Interface $settings ) {
30        $this->api      = $api;
31        $this->settings = $settings;
32    }
33
34    /**
35     * Add the link under the user's name in the users list table.
36     *
37     * @hooked user_row_actions
38     * @see \WP_Users_List_Table::single_row()
39     *
40     * @param array<string,string> $actions An array of action links to be displayed.
41     *                   Default 'Edit', 'Delete' for single site, and 'Edit', 'Remove' for Multisite.
42     * @param WP_User              $user_object WP_User object for the currently listed user.
43     *
44     * @return array<string,string>
45     */
46    public function add_magic_email_link( array $actions, WP_User $user_object ): array {
47
48        // Add a link to send the user a reset password link by email.
49        if ( get_current_user_id() !== $user_object->ID
50            && current_user_can( 'edit_user', $user_object->ID )
51            && $this->settings->is_magic_link_enabled()
52        ) {
53            $actions['sendmagiclink'] = "<a class='sendmagiclink' href='" . wp_nonce_url( "users.php?action=sendmagiclink&amp;user=$user_object->ID", self::class ) . "'>" . __( 'Send magic login email' ) . '</a>';
54        }
55
56        return $actions;
57    }
58
59    /**
60     * Handle the page load where the magic link is sent.
61     *
62     * E.g. `/wp-admin/users.php?action=sendmagiclink&user=2&_wpnonce=20d555e577`.
63     *
64     * @hooked admin_init
65     *
66     * @see users.php:636
67     */
68    public function send_magic_email_link(): void {
69
70        global $pagenow;
71        if ( 'users.php' !== $pagenow ) {
72            return;
73        }
74
75        if ( ! check_ajax_referer( self::class, false, false ) ) {
76            return;
77        }
78
79        if ( ! isset( $_GET['action'], $_GET['user'] ) ) {
80            return;
81        }
82
83        if ( 'sendmagiclink' !== sanitize_key( $_GET['action'] ) ) {
84            return;
85        }
86
87        $user_id = absint( $_GET['user'] );
88
89        $user = get_user_by( 'id', $user_id );
90
91        if ( ! $user instanceof WP_User ) {
92            return;
93        }
94
95        $result = $this->api->send_magic_link( $user->user_email );
96
97        add_action(
98            'admin_notices',
99            function () use ( $result, $user ) {
100                $this->print_admin_notice( $result, $user );
101            }
102        );
103    }
104
105    /**
106     * Print the success/failure admin notice.
107     *
108     * @param array{username_or_email_address:string, expires_in:int, expires_in_friendly:string, wp_user?:WP_User, template_path?:string, success:bool, error?:bool, message?:string} $result
109     * @param WP_User                                                                                                                                                                  $user
110     */
111    public function print_admin_notice( array $result, WP_User $user ): void {
112
113        $notice_type = $result['success'] ? 'success' : 'error';
114        echo '<div id="message" class="updated ' . esc_attr( $notice_type ) . ' is-dismissible"><p>';
115
116        if ( $result['success'] ) {
117            echo 'Magic login email sent to ';
118        } else {
119            echo 'Error sending magic login email to ';
120        }
121
122        printf(
123            '<a href="%s">%s</a>',
124            esc_url( get_edit_user_link( $user->ID ) ),
125            esc_html( $user->display_name )
126        );
127
128        printf(
129            ' (<a href="mailto:%s">%s</a>).',
130            esc_url( $user->user_email ),
131            esc_html( $user->user_email ),
132        );
133
134        echo '</p></div>';
135    }
136}