Version Description
- Add a 'Switch To' link to bbPress profile screens.
=
Download this release
Release Info
Developer | johnbillion |
Plugin | User Switching |
Version | 0.8.5 |
Comparing to | |
See all releases |
Code changes from version 0.8.4 to 0.8.5
- readme.txt +13 -7
- user-switching.php +653 -645
readme.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
=== User Switching ===
|
2 |
|
3 |
Contributors: johnbillion
|
4 |
-
Tags: user, users, profiles, switching, wpmu, multisite, buddypress, become, user control, user management, user access, developer
|
5 |
Requires at least: 3.1
|
6 |
-
Tested up to: 3.
|
7 |
-
Stable tag: 0.8.
|
8 |
License: GPL v2 or later
|
9 |
|
10 |
Instant switching between user accounts in WordPress.
|
@@ -19,7 +19,7 @@ This plugin allows you to quickly swap between user accounts in WordPress at the
|
|
19 |
* Switch back: Instantly switch back to your originating account.
|
20 |
* Switch off: Log out of your account but retain the ability to instantly switch back in again.
|
21 |
* It's completely secure (see the *Security* section below).
|
22 |
-
* Compatible with WordPress, WordPress Multisite and
|
23 |
|
24 |
= Security =
|
25 |
|
@@ -80,6 +80,10 @@ Yes, and you'll also be able to switch users from the Users screen in Network Ad
|
|
80 |
|
81 |
Yes, and you'll also be able to switch users from member profile screens and the member listing screen.
|
82 |
|
|
|
|
|
|
|
|
|
83 |
= Does this work as a mu-plugin? =
|
84 |
|
85 |
Yes, but you'll need to install `user-switching.php` into the root of your `mu-plugins` directory, not in the `user-switching` subdirectory. This is a restriction of WordPress.
|
@@ -102,12 +106,14 @@ When a user switches off, the `switch_off_user` hook is called with the old user
|
|
102 |
|
103 |
== Upgrade Notice ==
|
104 |
|
105 |
-
= 0.8.
|
106 |
-
*
|
107 |
-
* Tweak the redirect location for BuddyPress user profiles.
|
108 |
|
109 |
== Changelog ==
|
110 |
|
|
|
|
|
|
|
111 |
= 0.8.4 =
|
112 |
* Revert a change in 0.8.3 which switched to using the `login_init` hook. This hook is fired too late.
|
113 |
|
1 |
=== User Switching ===
|
2 |
|
3 |
Contributors: johnbillion
|
4 |
+
Tags: user, users, profiles, switching, wpmu, multisite, buddypress, bbpress, become, user control, user management, user access, developer
|
5 |
Requires at least: 3.1
|
6 |
+
Tested up to: 3.8
|
7 |
+
Stable tag: 0.8.5
|
8 |
License: GPL v2 or later
|
9 |
|
10 |
Instant switching between user accounts in WordPress.
|
19 |
* Switch back: Instantly switch back to your originating account.
|
20 |
* Switch off: Log out of your account but retain the ability to instantly switch back in again.
|
21 |
* It's completely secure (see the *Security* section below).
|
22 |
+
* Compatible with WordPress, WordPress Multisite, BuddyPress and bbPress.
|
23 |
|
24 |
= Security =
|
25 |
|
80 |
|
81 |
Yes, and you'll also be able to switch users from member profile screens and the member listing screen.
|
82 |
|
83 |
+
= Does this plugin work with bbPress? =
|
84 |
+
|
85 |
+
Yes, and you'll also be able to switch users from member profile screens.
|
86 |
+
|
87 |
= Does this work as a mu-plugin? =
|
88 |
|
89 |
Yes, but you'll need to install `user-switching.php` into the root of your `mu-plugins` directory, not in the `user-switching` subdirectory. This is a restriction of WordPress.
|
106 |
|
107 |
== Upgrade Notice ==
|
108 |
|
109 |
+
= 0.8.5 =
|
110 |
+
* Add a 'Switch To' link to bbPress profile screens.
|
|
|
111 |
|
112 |
== Changelog ==
|
113 |
|
114 |
+
= 0.8.5 =
|
115 |
+
* Add a 'Switch To' link to bbPress profile screens.
|
116 |
+
|
117 |
= 0.8.4 =
|
118 |
* Revert a change in 0.8.3 which switched to using the `login_init` hook. This hook is fired too late.
|
119 |
|
user-switching.php
CHANGED
@@ -1,645 +1,653 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Plugin Name:
|
4 |
-
Description:
|
5 |
-
Version:
|
6 |
-
Plugin URI:
|
7 |
-
Author:
|
8 |
-
Author URI:
|
9 |
-
Text Domain:
|
10 |
-
Domain Path:
|
11 |
-
License:
|
12 |
-
|
13 |
-
Copyright © 2013 John Blackbourn
|
14 |
-
|
15 |
-
This program is free software; you can redistribute it and/or modify
|
16 |
-
it under the terms of the GNU General Public License as published by
|
17 |
-
the Free Software Foundation; either version 2 of the License, or
|
18 |
-
(at your option) any later version.
|
19 |
-
|
20 |
-
This program is distributed in the hope that it will be useful,
|
21 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
22 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
23 |
-
GNU General Public License for more details.
|
24 |
-
|
25 |
-
*/
|
26 |
-
|
27 |
-
class user_switching {
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Class constructor. Set up some filters and actions.
|
31 |
-
*/
|
32 |
-
public function __construct() {
|
33 |
-
|
34 |
-
# Required functionality:
|
35 |
-
add_filter( 'user_has_cap',
|
36 |
-
add_filter( 'map_meta_cap',
|
37 |
-
add_filter( 'user_row_actions',
|
38 |
-
add_action( 'plugins_loaded',
|
39 |
-
add_action( 'init',
|
40 |
-
add_action( 'all_admin_notices',
|
41 |
-
add_action( 'wp_logout',
|
42 |
-
add_action( 'wp_login',
|
43 |
-
|
44 |
-
# Nice-to-haves:
|
45 |
-
add_filter( 'ms_user_row_actions',
|
46 |
-
|
47 |
-
add_action( '
|
48 |
-
add_action( '
|
49 |
-
add_action( '
|
50 |
-
add_action( 'bp_member_header_actions',
|
51 |
-
|
52 |
-
add_action( '
|
53 |
-
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Define the name of the old user cookie. Uses WordPress' cookie hash for increased security.
|
58 |
-
*
|
59 |
-
* @return null
|
60 |
-
*/
|
61 |
-
public function action_plugins_loaded() {
|
62 |
-
if ( !defined( 'OLDUSER_COOKIE' ) )
|
63 |
-
define( 'OLDUSER_COOKIE', 'wordpress_olduser_' . COOKIEHASH );
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Output the 'Switch To' link on the user editing screen if we have permission to switch to this user.
|
68 |
-
*
|
69 |
-
* @param WP_User $user User object for this screen
|
70 |
-
* @return null
|
71 |
-
*/
|
72 |
-
public function action_personal_options( WP_User $user ) {
|
73 |
-
|
74 |
-
if ( ! $link = self::maybe_switch_url( $user->ID ) )
|
75 |
-
return;
|
76 |
-
|
77 |
-
?>
|
78 |
-
<tr>
|
79 |
-
<th scope="row"><?php _ex( 'User Switching', 'User Switching title on user profile screen', 'user-switching' ); ?></th>
|
80 |
-
<td><a href="<?php echo $link; ?>"><?php _e( 'Switch To', 'user-switching' ); ?></a></td>
|
81 |
-
</tr>
|
82 |
-
<?php
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Return whether or not the current logged in user is being remembered in the form of a persistent browser
|
87 |
-
* cookie (ie. they checked the 'Remember Me' check box when they logged in). This is used to persist the
|
88 |
-
* 'remember me' value when the user switches to another user.
|
89 |
-
*
|
90 |
-
* @return bool Whether the current user is being 'remembered' or not.
|
91 |
-
*/
|
92 |
-
public static function remember() {
|
93 |
-
|
94 |
-
$current = wp_parse_auth_cookie( '', 'logged_in' );
|
95 |
-
$cookie_life = apply_filters( 'auth_cookie_expiration', 172800, get_current_user_id(), false );
|
96 |
-
|
97 |
-
# Here we calculate the expiration length of the current auth cookie and compare it to the default expiration.
|
98 |
-
# If it's greater than this, then we know the user checked 'Remember Me' when they logged in.
|
99 |
-
return ( ( $current['expiration'] - time() ) > $cookie_life );
|
100 |
-
|
101 |
-
}
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Load localisation files and route actions depending on the 'action' query var.
|
105 |
-
*
|
106 |
-
* @return null
|
107 |
-
*/
|
108 |
-
public function action_init() {
|
109 |
-
|
110 |
-
load_plugin_textdomain( 'user-switching', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
|
111 |
-
|
112 |
-
if ( !isset( $_REQUEST['action'] ) )
|
113 |
-
return;
|
114 |
-
|
115 |
-
if ( isset( $_REQUEST['redirect_to'] ) and !empty( $_REQUEST['redirect_to'] ) )
|
116 |
-
$redirect_to =
|
117 |
-
else
|
118 |
-
$redirect_to = false;
|
119 |
-
|
120 |
-
switch ( $_REQUEST['action'] ) {
|
121 |
-
|
122 |
-
# We're attempting to switch to another user:
|
123 |
-
case 'switch_to_user':
|
124 |
-
$user_id = absint( $_REQUEST['user_id'] );
|
125 |
-
|
126 |
-
check_admin_referer( "switch_to_user_{$user_id}" );
|
127 |
-
|
128 |
-
# Switch user:
|
129 |
-
if ( switch_to_user( $user_id, self::remember() ) ) {
|
130 |
-
|
131 |
-
# Redirect to the dashboard or the home URL depending on capabilities:
|
132 |
-
if ( $redirect_to )
|
133 |
-
wp_safe_redirect( add_query_arg( array( 'user_switched' => 'true' ), $redirect_to ) );
|
134 |
-
else if ( !current_user_can( 'read' ) )
|
135 |
-
wp_redirect( add_query_arg( array( 'user_switched' => 'true' ), home_url() ) );
|
136 |
-
else
|
137 |
-
wp_redirect( add_query_arg( array( 'user_switched' => 'true' ), admin_url() ) );
|
138 |
-
die();
|
139 |
-
|
140 |
-
} else {
|
141 |
-
wp_die( __( 'Could not switch users.', 'user-switching' ) );
|
142 |
-
}
|
143 |
-
break;
|
144 |
-
|
145 |
-
# We're attempting to switch back to the originating user:
|
146 |
-
case 'switch_to_olduser':
|
147 |
-
|
148 |
-
check_admin_referer( 'switch_to_olduser' );
|
149 |
-
|
150 |
-
# Fetch the originating user data:
|
151 |
-
if ( !$old_user = self::get_old_user() )
|
152 |
-
wp_die( __( 'Could not switch users.', 'user-switching' ) );
|
153 |
-
|
154 |
-
# Switch user:
|
155 |
-
if ( switch_to_user( $old_user->ID, self::remember(), false ) ) {
|
156 |
-
if ( $redirect_to )
|
157 |
-
wp_safe_redirect( add_query_arg( array( 'user_switched' => 'true', 'switched_back' => 'true' ), $redirect_to ) );
|
158 |
-
else
|
159 |
-
wp_redirect( add_query_arg( array( 'user_switched' => 'true', 'switched_back' => 'true' ), admin_url( 'users.php' ) ) );
|
160 |
-
die();
|
161 |
-
} else {
|
162 |
-
wp_die( __( 'Could not switch users.', 'user-switching' ) );
|
163 |
-
}
|
164 |
-
break;
|
165 |
-
|
166 |
-
# We're attempting to switch off the current user:
|
167 |
-
case 'switch_off':
|
168 |
-
|
169 |
-
check_admin_referer( 'switch_off' );
|
170 |
-
|
171 |
-
# Switch off:
|
172 |
-
if ( switch_off_user() ) {
|
173 |
-
if ( $redirect_to )
|
174 |
-
wp_safe_redirect( add_query_arg( array( 'switched_off' => 'true' ), $redirect_to ) );
|
175 |
-
else
|
176 |
-
wp_redirect( add_query_arg( array( 'switched_off' => 'true' ), home_url() ) );
|
177 |
-
die();
|
178 |
-
} else {
|
179 |
-
wp_die( __( 'Could not switch off.', 'user-switching' ) );
|
180 |
-
}
|
181 |
-
break;
|
182 |
-
|
183 |
-
}
|
184 |
-
|
185 |
-
}
|
186 |
-
|
187 |
-
/**
|
188 |
-
* Display the 'Switched to {user}' and 'Switch back to {user}' messages in the admin area.
|
189 |
-
*
|
190 |
-
* @return null
|
191 |
-
*/
|
192 |
-
public function action_admin_notices() {
|
193 |
-
$user = wp_get_current_user();
|
194 |
-
|
195 |
-
if ( $old_user = self::get_old_user() ) {
|
196 |
-
|
197 |
-
?>
|
198 |
-
<div id="user_switching" class="updated">
|
199 |
-
<p><?php
|
200 |
-
if ( isset( $_GET['user_switched'] ) )
|
201 |
-
printf( __( 'Switched to %1$s (%2$s).', 'user-switching' ), $user->display_name, $user->user_login );
|
202 |
-
$url = add_query_arg( array(
|
203 |
-
'redirect_to' => urlencode( self::current_url() )
|
204 |
-
), self::switch_back_url() );
|
205 |
-
printf( ' <a href="%s">%s</a>.', $url, sprintf( __( 'Switch back to %1$s (%2$s)', 'user-switching' ), $old_user->display_name, $old_user->user_login ) );
|
206 |
-
?></p>
|
207 |
-
</div>
|
208 |
-
<?php
|
209 |
-
|
210 |
-
} else if ( isset( $_GET['user_switched'] ) ) {
|
211 |
-
|
212 |
-
?>
|
213 |
-
<div id="user_switching" class="updated">
|
214 |
-
<p><?php
|
215 |
-
if ( isset( $_GET['switched_back'] ) )
|
216 |
-
printf( __( 'Switched back to %1$s (%2$s).', 'user-switching' ), $user->display_name, $user->user_login );
|
217 |
-
else
|
218 |
-
printf( __( 'Switched to %1$s (%2$s).', 'user-switching' ), $user->display_name, $user->user_login );
|
219 |
-
?></p>
|
220 |
-
</div>
|
221 |
-
<?php
|
222 |
-
|
223 |
-
}
|
224 |
-
}
|
225 |
-
|
226 |
-
/**
|
227 |
-
* Validate the latest item in the old_user cookie and return its user data.
|
228 |
-
*
|
229 |
-
* @return bool|WP_User False if there's no old user cookie or it's invalid, WP_User object if it's present and valid.
|
230 |
-
*/
|
231 |
-
public static function get_old_user() {
|
232 |
-
$cookie = wp_get_olduser_cookie();
|
233 |
-
if ( !empty( $cookie ) ) {
|
234 |
-
if ( $old_user_id = wp_validate_auth_cookie( end( $cookie ), 'old_user' ) )
|
235 |
-
return get_userdata( $old_user_id );
|
236 |
-
}
|
237 |
-
return false;
|
238 |
-
}
|
239 |
-
|
240 |
-
/**
|
241 |
-
* Adds a 'Switch back to {user}' link to the account menu in WordPress' admin bar.
|
242 |
-
*
|
243 |
-
* @param WP_Admin_Bar $wp_admin_bar The admin bar object
|
244 |
-
* @return null
|
245 |
-
*/
|
246 |
-
public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) {
|
247 |
-
|
248 |
-
if ( !function_exists( 'is_admin_bar_showing' ) )
|
249 |
-
return;
|
250 |
-
if ( !is_admin_bar_showing() )
|
251 |
-
return;
|
252 |
-
|
253 |
-
if ( method_exists( $wp_admin_bar, 'get_node' ) and $wp_admin_bar->get_node( 'user-actions' ) )
|
254 |
-
$parent = 'user-actions';
|
255 |
-
else if ( get_option( 'show_avatars' ) )
|
256 |
-
$parent = 'my-account-with-avatar';
|
257 |
-
else
|
258 |
-
$parent = 'my-account';
|
259 |
-
|
260 |
-
if ( $old_user = self::get_old_user() ) {
|
261 |
-
|
262 |
-
$wp_admin_bar->add_menu( array(
|
263 |
-
'parent' => $parent,
|
264 |
-
'id' => 'switch-back',
|
265 |
-
'title' => sprintf( __( 'Switch back to %1$s (%2$s)', 'user-switching' ), $old_user->display_name, $old_user->user_login ),
|
266 |
-
'href' => add_query_arg( array(
|
267 |
-
'redirect_to' => urlencode( self::current_url() )
|
268 |
-
), self::switch_back_url() )
|
269 |
-
) );
|
270 |
-
|
271 |
-
}
|
272 |
-
|
273 |
-
if ( current_user_can( 'switch_off' ) ) {
|
274 |
-
|
275 |
-
$url = self::switch_off_url();
|
276 |
-
if ( !is_admin() ) {
|
277 |
-
$url = add_query_arg( array(
|
278 |
-
'redirect_to' => urlencode( self::current_url() )
|
279 |
-
), $url );
|
280 |
-
}
|
281 |
-
|
282 |
-
$wp_admin_bar->add_menu( array(
|
283 |
-
'parent' => $parent,
|
284 |
-
'id' => 'switch-off',
|
285 |
-
'title' => __( 'Switch Off', 'user-switching' ),
|
286 |
-
'href' => $url
|
287 |
-
) );
|
288 |
-
|
289 |
-
}
|
290 |
-
|
291 |
-
}
|
292 |
-
|
293 |
-
/**
|
294 |
-
* Adds a 'Switch back to {user}' link to the WordPress footer if the admin toolbar isn't showing.
|
295 |
-
*
|
296 |
-
* @return null
|
297 |
-
*/
|
298 |
-
public function action_wp_footer() {
|
299 |
-
|
300 |
-
if ( !is_admin_bar_showing() and $old_user = self::get_old_user() ) {
|
301 |
-
$link = sprintf( __( 'Switch back to %1$s (%2$s)', 'user-switching' ), $old_user->display_name, $old_user->user_login );
|
302 |
-
$url = add_query_arg( array(
|
303 |
-
'redirect_to' => urlencode( self::current_url() )
|
304 |
-
), self::switch_back_url() );
|
305 |
-
echo '<p id="user_switching_switch_on"><a href="' . $url . '">' . $link . '</a></p>';
|
306 |
-
}
|
307 |
-
|
308 |
-
}
|
309 |
-
|
310 |
-
/**
|
311 |
-
* Adds a 'Switch back to {user}' link to the WordPress login screen.
|
312 |
-
*
|
313 |
-
* @param string $message The login screen message
|
314 |
-
* @return string The login screen message
|
315 |
-
*/
|
316 |
-
public function filter_login_message( $message ) {
|
317 |
-
|
318 |
-
if ( $old_user = self::get_old_user() ) {
|
319 |
-
$link = sprintf( __( 'Switch back to %1$s (%2$s)', 'user-switching' ), $old_user->display_name, $old_user->user_login );
|
320 |
-
$url = self::switch_back_url();
|
321 |
-
if ( isset( $_REQUEST['redirect_to'] ) and !empty( $_REQUEST['redirect_to'] ) ) {
|
322 |
-
$url = add_query_arg( array(
|
323 |
-
'redirect_to' => $_REQUEST['redirect_to']
|
324 |
-
), $url );
|
325 |
-
}
|
326 |
-
$message .= '<p class="message"><a href="' . $url . '">' . $link . '</a></p>';
|
327 |
-
}
|
328 |
-
|
329 |
-
return $message;
|
330 |
-
|
331 |
-
}
|
332 |
-
|
333 |
-
/**
|
334 |
-
* Adds a 'Switch To' link to each list of user actions on the Users screen.
|
335 |
-
*
|
336 |
-
* @param array $actions The actions to display for this user row
|
337 |
-
* @param WP_User $user The user object displayed in this row
|
338 |
-
* @return array The actions to display for this user row
|
339 |
-
*/
|
340 |
-
public function filter_user_row_actions( array $actions, WP_User $user ) {
|
341 |
-
|
342 |
-
if ( ! $link = self::maybe_switch_url( $user->ID ) )
|
343 |
-
return $actions;
|
344 |
-
|
345 |
-
$actions['switch_to_user'] = '<a href="' . $link . '">' . __( 'Switch To', 'user-switching' ) . '</a>';
|
346 |
-
|
347 |
-
return $actions;
|
348 |
-
}
|
349 |
-
|
350 |
-
/**
|
351 |
-
* Adds a 'Switch
|
352 |
-
*
|
353 |
-
* @return null
|
354 |
-
*/
|
355 |
-
public function
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
*
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
*
|
491 |
-
*
|
492 |
-
*
|
493 |
-
*
|
494 |
-
*
|
495 |
-
*
|
496 |
-
*
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
*
|
516 |
-
*
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: User Switching
|
4 |
+
Description: Instant switching between user accounts in WordPress
|
5 |
+
Version: 0.8.5
|
6 |
+
Plugin URI: https://lud.icro.us/wordpress-plugin-user-switching/
|
7 |
+
Author: John Blackbourn
|
8 |
+
Author URI: https://johnblackbourn.com/
|
9 |
+
Text Domain: user-switching
|
10 |
+
Domain Path: /languages/
|
11 |
+
License: GPL v2 or later
|
12 |
+
|
13 |
+
Copyright © 2013 John Blackbourn
|
14 |
+
|
15 |
+
This program is free software; you can redistribute it and/or modify
|
16 |
+
it under the terms of the GNU General Public License as published by
|
17 |
+
the Free Software Foundation; either version 2 of the License, or
|
18 |
+
(at your option) any later version.
|
19 |
+
|
20 |
+
This program is distributed in the hope that it will be useful,
|
21 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
22 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
23 |
+
GNU General Public License for more details.
|
24 |
+
|
25 |
+
*/
|
26 |
+
|
27 |
+
class user_switching {
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Class constructor. Set up some filters and actions.
|
31 |
+
*/
|
32 |
+
public function __construct() {
|
33 |
+
|
34 |
+
# Required functionality:
|
35 |
+
add_filter( 'user_has_cap', array( $this, 'filter_user_has_cap' ), 10, 3 );
|
36 |
+
add_filter( 'map_meta_cap', array( $this, 'filter_map_meta_cap' ), 10, 4 );
|
37 |
+
add_filter( 'user_row_actions', array( $this, 'filter_user_row_actions' ), 10, 2 );
|
38 |
+
add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ) );
|
39 |
+
add_action( 'init', array( $this, 'action_init' ) );
|
40 |
+
add_action( 'all_admin_notices', array( $this, 'action_admin_notices' ), 1 );
|
41 |
+
add_action( 'wp_logout', 'wp_clear_olduser_cookie' );
|
42 |
+
add_action( 'wp_login', 'wp_clear_olduser_cookie' );
|
43 |
+
|
44 |
+
# Nice-to-haves:
|
45 |
+
add_filter( 'ms_user_row_actions', array( $this, 'filter_user_row_actions' ), 10, 2 );
|
46 |
+
add_filter( 'login_message', array( $this, 'filter_login_message' ), 1 );
|
47 |
+
add_action( 'wp_footer', array( $this, 'action_wp_footer' ) );
|
48 |
+
add_action( 'personal_options', array( $this, 'action_personal_options' ) );
|
49 |
+
add_action( 'admin_bar_menu', array( $this, 'action_admin_bar_menu' ), 11 );
|
50 |
+
add_action( 'bp_member_header_actions', array( $this, 'action_bp_button' ), 11 );
|
51 |
+
add_action( 'bp_directory_members_actions', array( $this, 'action_bp_button' ), 11 );
|
52 |
+
add_action( 'bbp_template_after_user_details', array( $this, 'action_bbpress_button' ) );
|
53 |
+
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Define the name of the old user cookie. Uses WordPress' cookie hash for increased security.
|
58 |
+
*
|
59 |
+
* @return null
|
60 |
+
*/
|
61 |
+
public function action_plugins_loaded() {
|
62 |
+
if ( !defined( 'OLDUSER_COOKIE' ) )
|
63 |
+
define( 'OLDUSER_COOKIE', 'wordpress_olduser_' . COOKIEHASH );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Output the 'Switch To' link on the user editing screen if we have permission to switch to this user.
|
68 |
+
*
|
69 |
+
* @param WP_User $user User object for this screen
|
70 |
+
* @return null
|
71 |
+
*/
|
72 |
+
public function action_personal_options( WP_User $user ) {
|
73 |
+
|
74 |
+
if ( ! $link = self::maybe_switch_url( $user->ID ) )
|
75 |
+
return;
|
76 |
+
|
77 |
+
?>
|
78 |
+
<tr>
|
79 |
+
<th scope="row"><?php _ex( 'User Switching', 'User Switching title on user profile screen', 'user-switching' ); ?></th>
|
80 |
+
<td><a href="<?php echo $link; ?>"><?php _e( 'Switch To', 'user-switching' ); ?></a></td>
|
81 |
+
</tr>
|
82 |
+
<?php
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Return whether or not the current logged in user is being remembered in the form of a persistent browser
|
87 |
+
* cookie (ie. they checked the 'Remember Me' check box when they logged in). This is used to persist the
|
88 |
+
* 'remember me' value when the user switches to another user.
|
89 |
+
*
|
90 |
+
* @return bool Whether the current user is being 'remembered' or not.
|
91 |
+
*/
|
92 |
+
public static function remember() {
|
93 |
+
|
94 |
+
$current = wp_parse_auth_cookie( '', 'logged_in' );
|
95 |
+
$cookie_life = apply_filters( 'auth_cookie_expiration', 172800, get_current_user_id(), false );
|
96 |
+
|
97 |
+
# Here we calculate the expiration length of the current auth cookie and compare it to the default expiration.
|
98 |
+
# If it's greater than this, then we know the user checked 'Remember Me' when they logged in.
|
99 |
+
return ( ( $current['expiration'] - time() ) > $cookie_life );
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Load localisation files and route actions depending on the 'action' query var.
|
105 |
+
*
|
106 |
+
* @return null
|
107 |
+
*/
|
108 |
+
public function action_init() {
|
109 |
+
|
110 |
+
load_plugin_textdomain( 'user-switching', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
|
111 |
+
|
112 |
+
if ( !isset( $_REQUEST['action'] ) )
|
113 |
+
return;
|
114 |
+
|
115 |
+
if ( isset( $_REQUEST['redirect_to'] ) and !empty( $_REQUEST['redirect_to'] ) )
|
116 |
+
$redirect_to = self::remove_query_args( $_REQUEST['redirect_to'] );
|
117 |
+
else
|
118 |
+
$redirect_to = false;
|
119 |
+
|
120 |
+
switch ( $_REQUEST['action'] ) {
|
121 |
+
|
122 |
+
# We're attempting to switch to another user:
|
123 |
+
case 'switch_to_user':
|
124 |
+
$user_id = absint( $_REQUEST['user_id'] );
|
125 |
+
|
126 |
+
check_admin_referer( "switch_to_user_{$user_id}" );
|
127 |
+
|
128 |
+
# Switch user:
|
129 |
+
if ( switch_to_user( $user_id, self::remember() ) ) {
|
130 |
+
|
131 |
+
# Redirect to the dashboard or the home URL depending on capabilities:
|
132 |
+
if ( $redirect_to )
|
133 |
+
wp_safe_redirect( add_query_arg( array( 'user_switched' => 'true' ), $redirect_to ) );
|
134 |
+
else if ( !current_user_can( 'read' ) )
|
135 |
+
wp_redirect( add_query_arg( array( 'user_switched' => 'true' ), home_url() ) );
|
136 |
+
else
|
137 |
+
wp_redirect( add_query_arg( array( 'user_switched' => 'true' ), admin_url() ) );
|
138 |
+
die();
|
139 |
+
|
140 |
+
} else {
|
141 |
+
wp_die( __( 'Could not switch users.', 'user-switching' ) );
|
142 |
+
}
|
143 |
+
break;
|
144 |
+
|
145 |
+
# We're attempting to switch back to the originating user:
|
146 |
+
case 'switch_to_olduser':
|
147 |
+
|
148 |
+
check_admin_referer( 'switch_to_olduser' );
|
149 |
+
|
150 |
+
# Fetch the originating user data:
|
151 |
+
if ( !$old_user = self::get_old_user() )
|
152 |
+
wp_die( __( 'Could not switch users.', 'user-switching' ) );
|
153 |
+
|
154 |
+
# Switch user:
|
155 |
+
if ( switch_to_user( $old_user->ID, self::remember(), false ) ) {
|
156 |
+
if ( $redirect_to )
|
157 |
+
wp_safe_redirect( add_query_arg( array( 'user_switched' => 'true', 'switched_back' => 'true' ), $redirect_to ) );
|
158 |
+
else
|
159 |
+
wp_redirect( add_query_arg( array( 'user_switched' => 'true', 'switched_back' => 'true' ), admin_url( 'users.php' ) ) );
|
160 |
+
die();
|
161 |
+
} else {
|
162 |
+
wp_die( __( 'Could not switch users.', 'user-switching' ) );
|
163 |
+
}
|
164 |
+
break;
|
165 |
+
|
166 |
+
# We're attempting to switch off the current user:
|
167 |
+
case 'switch_off':
|
168 |
+
|
169 |
+
check_admin_referer( 'switch_off' );
|
170 |
+
|
171 |
+
# Switch off:
|
172 |
+
if ( switch_off_user() ) {
|
173 |
+
if ( $redirect_to )
|
174 |
+
wp_safe_redirect( add_query_arg( array( 'switched_off' => 'true' ), $redirect_to ) );
|
175 |
+
else
|
176 |
+
wp_redirect( add_query_arg( array( 'switched_off' => 'true' ), home_url() ) );
|
177 |
+
die();
|
178 |
+
} else {
|
179 |
+
wp_die( __( 'Could not switch off.', 'user-switching' ) );
|
180 |
+
}
|
181 |
+
break;
|
182 |
+
|
183 |
+
}
|
184 |
+
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Display the 'Switched to {user}' and 'Switch back to {user}' messages in the admin area.
|
189 |
+
*
|
190 |
+
* @return null
|
191 |
+
*/
|
192 |
+
public function action_admin_notices() {
|
193 |
+
$user = wp_get_current_user();
|
194 |
+
|
195 |
+
if ( $old_user = self::get_old_user() ) {
|
196 |
+
|
197 |
+
?>
|
198 |
+
<div id="user_switching" class="updated">
|
199 |
+
<p><?php
|
200 |
+
if ( isset( $_GET['user_switched'] ) )
|
201 |
+
printf( __( 'Switched to %1$s (%2$s).', 'user-switching' ), $user->display_name, $user->user_login );
|
202 |
+
$url = add_query_arg( array(
|
203 |
+
'redirect_to' => urlencode( self::current_url() )
|
204 |
+
), self::switch_back_url() );
|
205 |
+
printf( ' <a href="%s">%s</a>.', $url, sprintf( __( 'Switch back to %1$s (%2$s)', 'user-switching' ), $old_user->display_name, $old_user->user_login ) );
|
206 |
+
?></p>
|
207 |
+
</div>
|
208 |
+
<?php
|
209 |
+
|
210 |
+
} else if ( isset( $_GET['user_switched'] ) ) {
|
211 |
+
|
212 |
+
?>
|
213 |
+
<div id="user_switching" class="updated">
|
214 |
+
<p><?php
|
215 |
+
if ( isset( $_GET['switched_back'] ) )
|
216 |
+
printf( __( 'Switched back to %1$s (%2$s).', 'user-switching' ), $user->display_name, $user->user_login );
|
217 |
+
else
|
218 |
+
printf( __( 'Switched to %1$s (%2$s).', 'user-switching' ), $user->display_name, $user->user_login );
|
219 |
+
?></p>
|
220 |
+
</div>
|
221 |
+
<?php
|
222 |
+
|
223 |
+
}
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Validate the latest item in the old_user cookie and return its user data.
|
228 |
+
*
|
229 |
+
* @return bool|WP_User False if there's no old user cookie or it's invalid, WP_User object if it's present and valid.
|
230 |
+
*/
|
231 |
+
public static function get_old_user() {
|
232 |
+
$cookie = wp_get_olduser_cookie();
|
233 |
+
if ( !empty( $cookie ) ) {
|
234 |
+
if ( $old_user_id = wp_validate_auth_cookie( end( $cookie ), 'old_user' ) )
|
235 |
+
return get_userdata( $old_user_id );
|
236 |
+
}
|
237 |
+
return false;
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Adds a 'Switch back to {user}' link to the account menu in WordPress' admin bar.
|
242 |
+
*
|
243 |
+
* @param WP_Admin_Bar $wp_admin_bar The admin bar object
|
244 |
+
* @return null
|
245 |
+
*/
|
246 |
+
public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) {
|
247 |
+
|
248 |
+
if ( !function_exists( 'is_admin_bar_showing' ) )
|
249 |
+
return;
|
250 |
+
if ( !is_admin_bar_showing() )
|
251 |
+
return;
|
252 |
+
|
253 |
+
if ( method_exists( $wp_admin_bar, 'get_node' ) and $wp_admin_bar->get_node( 'user-actions' ) )
|
254 |
+
$parent = 'user-actions';
|
255 |
+
else if ( get_option( 'show_avatars' ) )
|
256 |
+
$parent = 'my-account-with-avatar';
|
257 |
+
else
|
258 |
+
$parent = 'my-account';
|
259 |
+
|
260 |
+
if ( $old_user = self::get_old_user() ) {
|
261 |
+
|
262 |
+
$wp_admin_bar->add_menu( array(
|
263 |
+
'parent' => $parent,
|
264 |
+
'id' => 'switch-back',
|
265 |
+
'title' => sprintf( __( 'Switch back to %1$s (%2$s)', 'user-switching' ), $old_user->display_name, $old_user->user_login ),
|
266 |
+
'href' => add_query_arg( array(
|
267 |
+
'redirect_to' => urlencode( self::current_url() )
|
268 |
+
), self::switch_back_url() )
|
269 |
+
) );
|
270 |
+
|
271 |
+
}
|
272 |
+
|
273 |
+
if ( current_user_can( 'switch_off' ) ) {
|
274 |
+
|
275 |
+
$url = self::switch_off_url();
|
276 |
+
if ( !is_admin() ) {
|
277 |
+
$url = add_query_arg( array(
|
278 |
+
'redirect_to' => urlencode( self::current_url() )
|
279 |
+
), $url );
|
280 |
+
}
|
281 |
+
|
282 |
+
$wp_admin_bar->add_menu( array(
|
283 |
+
'parent' => $parent,
|
284 |
+
'id' => 'switch-off',
|
285 |
+
'title' => __( 'Switch Off', 'user-switching' ),
|
286 |
+
'href' => $url
|
287 |
+
) );
|
288 |
+
|
289 |
+
}
|
290 |
+
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Adds a 'Switch back to {user}' link to the WordPress footer if the admin toolbar isn't showing.
|
295 |
+
*
|
296 |
+
* @return null
|
297 |
+
*/
|
298 |
+
public function action_wp_footer() {
|
299 |
+
|
300 |
+
if ( !is_admin_bar_showing() and $old_user = self::get_old_user() ) {
|
301 |
+
$link = sprintf( __( 'Switch back to %1$s (%2$s)', 'user-switching' ), $old_user->display_name, $old_user->user_login );
|
302 |
+
$url = add_query_arg( array(
|
303 |
+
'redirect_to' => urlencode( self::current_url() )
|
304 |
+
), self::switch_back_url() );
|
305 |
+
echo '<p id="user_switching_switch_on"><a href="' . $url . '">' . $link . '</a></p>';
|
306 |
+
}
|
307 |
+
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Adds a 'Switch back to {user}' link to the WordPress login screen.
|
312 |
+
*
|
313 |
+
* @param string $message The login screen message
|
314 |
+
* @return string The login screen message
|
315 |
+
*/
|
316 |
+
public function filter_login_message( $message ) {
|
317 |
+
|
318 |
+
if ( $old_user = self::get_old_user() ) {
|
319 |
+
$link = sprintf( __( 'Switch back to %1$s (%2$s)', 'user-switching' ), $old_user->display_name, $old_user->user_login );
|
320 |
+
$url = self::switch_back_url();
|
321 |
+
if ( isset( $_REQUEST['redirect_to'] ) and !empty( $_REQUEST['redirect_to'] ) ) {
|
322 |
+
$url = add_query_arg( array(
|
323 |
+
'redirect_to' => $_REQUEST['redirect_to']
|
324 |
+
), $url );
|
325 |
+
}
|
326 |
+
$message .= '<p class="message"><a href="' . $url . '">' . $link . '</a></p>';
|
327 |
+
}
|
328 |
+
|
329 |
+
return $message;
|
330 |
+
|
331 |
+
}
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Adds a 'Switch To' link to each list of user actions on the Users screen.
|
335 |
+
*
|
336 |
+
* @param array $actions The actions to display for this user row
|
337 |
+
* @param WP_User $user The user object displayed in this row
|
338 |
+
* @return array The actions to display for this user row
|
339 |
+
*/
|
340 |
+
public function filter_user_row_actions( array $actions, WP_User $user ) {
|
341 |
+
|
342 |
+
if ( ! $link = self::maybe_switch_url( $user->ID ) )
|
343 |
+
return $actions;
|
344 |
+
|
345 |
+
$actions['switch_to_user'] = '<a href="' . $link . '">' . __( 'Switch To', 'user-switching' ) . '</a>';
|
346 |
+
|
347 |
+
return $actions;
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Adds a 'Switch To' link to each member's profile page and profile listings in BuddyPress.
|
352 |
+
*
|
353 |
+
* @return null
|
354 |
+
*/
|
355 |
+
public function action_bp_button() {
|
356 |
+
|
357 |
+
global $bp, $members_template;
|
358 |
+
|
359 |
+
if ( !empty( $members_template ) and empty( $bp->displayed_user->id ) )
|
360 |
+
$id = absint( $members_template->member->id );
|
361 |
+
else
|
362 |
+
$id = absint( $bp->displayed_user->id );
|
363 |
+
|
364 |
+
if ( ! $link = self::maybe_switch_url( $id ) )
|
365 |
+
return;
|
366 |
+
|
367 |
+
$link = add_query_arg( array(
|
368 |
+
'redirect_to' => urlencode( bp_core_get_user_domain( $id ) )
|
369 |
+
), $link );
|
370 |
+
|
371 |
+
# Workaround for https://buddypress.trac.wordpress.org/ticket/4212
|
372 |
+
$components = array_keys( $bp->active_components );
|
373 |
+
if ( !empty( $components ) )
|
374 |
+
$component = reset( $components );
|
375 |
+
else
|
376 |
+
$component = 'core';
|
377 |
+
|
378 |
+
echo bp_get_button( array(
|
379 |
+
'id' => 'user_switching',
|
380 |
+
'component' => $component,
|
381 |
+
'link_href' => $link,
|
382 |
+
'link_text' => __( 'Switch To', 'user-switching' )
|
383 |
+
) );
|
384 |
+
|
385 |
+
}
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Adds a 'Switch To' link to each member's profile page in bbPress.
|
389 |
+
*
|
390 |
+
* @return null
|
391 |
+
*/
|
392 |
+
public function action_bbpress_button() {
|
393 |
+
|
394 |
+
$id = bbp_get_user_id();
|
395 |
+
|
396 |
+
if ( ! $link = self::maybe_switch_url( $id ) )
|
397 |
+
return;
|
398 |
+
|
399 |
+
$link = add_query_arg( array(
|
400 |
+
'redirect_to' => urlencode( bbp_get_user_profile_url( $id ) )
|
401 |
+
), $link );
|
402 |
+
|
403 |
+
?>
|
404 |
+
<ul>
|
405 |
+
<li><a href="<?php echo $link; ?>"><?php _e( 'Switch To', 'user-switching' ); ?></a></li>
|
406 |
+
</ul>
|
407 |
+
<?php
|
408 |
+
|
409 |
+
}
|
410 |
+
|
411 |
+
/**
|
412 |
+
* Helper function. Returns the switch to or switch back URL for a given user ID.
|
413 |
+
*
|
414 |
+
* @param int $user_id The user ID to be switched to.
|
415 |
+
* @return string|bool The required URL, or false if there's no old user or the user doesn't have the required capability.
|
416 |
+
*/
|
417 |
+
public static function maybe_switch_url( $user_id ) {
|
418 |
+
|
419 |
+
$old_user = self::get_old_user();
|
420 |
+
|
421 |
+
if ( $old_user and ( $old_user->ID == $user_id ) )
|
422 |
+
return self::switch_back_url();
|
423 |
+
else if ( current_user_can( 'switch_to_user', $user_id ) )
|
424 |
+
return self::switch_to_url( $user_id );
|
425 |
+
else
|
426 |
+
return false;
|
427 |
+
|
428 |
+
}
|
429 |
+
|
430 |
+
/**
|
431 |
+
* Helper function. Returns the nonce-secured URL needed to switch to a given user ID.
|
432 |
+
*
|
433 |
+
* @param int $user_id The user ID to be switched to.
|
434 |
+
* @return string The required URL
|
435 |
+
*/
|
436 |
+
public static function switch_to_url( $user_id ) {
|
437 |
+
return wp_nonce_url( add_query_arg( array(
|
438 |
+
'action' => 'switch_to_user',
|
439 |
+
'user_id' => $user_id
|
440 |
+
), wp_login_url() ), "switch_to_user_{$user_id}" );
|
441 |
+
}
|
442 |
+
|
443 |
+
/**
|
444 |
+
* Helper function. Returns the nonce-secured URL needed to switch back to the originating user.
|
445 |
+
*
|
446 |
+
* @return string The required URL
|
447 |
+
*/
|
448 |
+
public static function switch_back_url() {
|
449 |
+
return wp_nonce_url( add_query_arg( array(
|
450 |
+
'action' => 'switch_to_olduser'
|
451 |
+
), wp_login_url() ), 'switch_to_olduser' );
|
452 |
+
}
|
453 |
+
|
454 |
+
/**
|
455 |
+
* Helper function. Returns the nonce-secured URL needed to switch off the current user.
|
456 |
+
*
|
457 |
+
* @return string The required URL
|
458 |
+
*/
|
459 |
+
public static function switch_off_url() {
|
460 |
+
return wp_nonce_url( add_query_arg( array(
|
461 |
+
'action' => 'switch_off'
|
462 |
+
), wp_login_url() ), 'switch_off' );
|
463 |
+
}
|
464 |
+
|
465 |
+
/**
|
466 |
+
* Helper function. Returns the current URL.
|
467 |
+
*
|
468 |
+
* @return string The current URL
|
469 |
+
*/
|
470 |
+
public static function current_url() {
|
471 |
+
return ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
472 |
+
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Helper function. Removes a list of common confirmation-style query args from a URL.
|
476 |
+
*
|
477 |
+
* @param string $url A URL
|
478 |
+
* @return string The URL with the listed query args removed
|
479 |
+
*/
|
480 |
+
public static function remove_query_args( $url ) {
|
481 |
+
return remove_query_arg( array(
|
482 |
+
'user_switched', 'switched_off', 'switched_back',
|
483 |
+
'message', 'updated', 'settings-updated', 'saved',
|
484 |
+
'activated', 'activate', 'deactivate',
|
485 |
+
'locked', 'skipped', 'deleted', 'trashed', 'untrashed'
|
486 |
+
), $url );
|
487 |
+
}
|
488 |
+
|
489 |
+
/**
|
490 |
+
* Filter the user's capabilities so they can be added/removed on the fly.
|
491 |
+
*
|
492 |
+
* This is used to grant the 'switch_to_user' capability to a user if they have the ability to edit the user
|
493 |
+
* they're trying to switch to (and that user is not themselves), and to grant the 'switch_off' capability to
|
494 |
+
* a user if they can edit users.
|
495 |
+
*
|
496 |
+
* Important: This does not get called for Super Admins. See filter_map_meta_cap() below.
|
497 |
+
*
|
498 |
+
* @param array $user_caps User's capabilities
|
499 |
+
* @param array $required_caps Actual required capabilities for the requested capability
|
500 |
+
* @param array $args Arguments that accompany the requested capability check:
|
501 |
+
* [0] => Requested capability from current_user_can()
|
502 |
+
* [1] => Current user ID
|
503 |
+
* [2] => Optional second parameter from current_user_can()
|
504 |
+
* @return array User's capabilities
|
505 |
+
*/
|
506 |
+
public function filter_user_has_cap( array $user_caps, array $required_caps, array $args ) {
|
507 |
+
if ( 'switch_to_user' == $args[0] )
|
508 |
+
$user_caps['switch_to_user'] = ( user_can( $args[1], 'edit_user', $args[2] ) and ( $args[2] != $args[1] ) );
|
509 |
+
else if ( 'switch_off' == $args[0] )
|
510 |
+
$user_caps['switch_off'] = user_can( $args[1], 'edit_users' );
|
511 |
+
return $user_caps;
|
512 |
+
}
|
513 |
+
|
514 |
+
/**
|
515 |
+
* Filters the actual required capabilities for a given capability or meta capability.
|
516 |
+
*
|
517 |
+
* This is used to add the 'do_not_allow' capability to the list of required capabilities when a super admin
|
518 |
+
* is trying to switch to themselves. It affects nothing else as super admins can do everything by default.
|
519 |
+
*
|
520 |
+
* @param array $required_caps Actual required capabilities for the requested action
|
521 |
+
* @param string $cap Capability or meta capability being checked
|
522 |
+
* @param string $user_id Current user ID
|
523 |
+
* @param array $args Arguments that accompany this capability check
|
524 |
+
* @return array Required capabilities for the requested action
|
525 |
+
*/
|
526 |
+
public function filter_map_meta_cap( array $required_caps, $cap, $user_id, array $args ) {
|
527 |
+
if ( ( 'switch_to_user' == $cap ) and ( $args[0] == $user_id ) )
|
528 |
+
$required_caps[] = 'do_not_allow';
|
529 |
+
return $required_caps;
|
530 |
+
}
|
531 |
+
|
532 |
+
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Sets an authorisation cookie containing the originating user, or appends it if there's more than one.
|
536 |
+
*
|
537 |
+
* @param int $old_user_id The ID of the originating user, usually the current logged in user.
|
538 |
+
* @return null
|
539 |
+
*/
|
540 |
+
if ( !function_exists( 'wp_set_olduser_cookie' ) ) {
|
541 |
+
function wp_set_olduser_cookie( $old_user_id ) {
|
542 |
+
$expiration = time() + 172800; # 48 hours
|
543 |
+
$cookie = wp_get_olduser_cookie();
|
544 |
+
$cookie[] = wp_generate_auth_cookie( $old_user_id, $expiration, 'old_user' );
|
545 |
+
setcookie( OLDUSER_COOKIE, json_encode( $cookie ), $expiration, COOKIEPATH, COOKIE_DOMAIN, false );
|
546 |
+
}
|
547 |
+
}
|
548 |
+
|
549 |
+
/**
|
550 |
+
* Clears the cookie containing the originating user, or pops the latest item off the end if there's more than one.
|
551 |
+
*
|
552 |
+
* @param bool $clear_all Whether to clear the cookie or just pop the last user information off the end.
|
553 |
+
* @return null
|
554 |
+
*/
|
555 |
+
if ( !function_exists( 'wp_clear_olduser_cookie' ) ) {
|
556 |
+
function wp_clear_olduser_cookie( $clear_all = true ) {
|
557 |
+
$cookie = wp_get_olduser_cookie();
|
558 |
+
if ( $clear_all or empty( $cookie ) ) {
|
559 |
+
setcookie( OLDUSER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN );
|
560 |
+
} else {
|
561 |
+
array_pop( $cookie );
|
562 |
+
$expiration = time() + 172800; # 48 hours
|
563 |
+
setcookie( OLDUSER_COOKIE, json_encode( $cookie ), $expiration, COOKIEPATH, COOKIE_DOMAIN, false );
|
564 |
+
}
|
565 |
+
}
|
566 |
+
}
|
567 |
+
|
568 |
+
/**
|
569 |
+
* Gets the value of the cookie containing the list of originating users.
|
570 |
+
*
|
571 |
+
* @return array Array of originating user authentication cookies. @see wp_generate_auth_cookie()
|
572 |
+
*/
|
573 |
+
if ( !function_exists( 'wp_get_olduser_cookie' ) ) {
|
574 |
+
function wp_get_olduser_cookie() {
|
575 |
+
if ( isset( $_COOKIE[OLDUSER_COOKIE] ) )
|
576 |
+
$cookie = json_decode( stripslashes( $_COOKIE[OLDUSER_COOKIE] ) );
|
577 |
+
if ( !isset( $cookie ) or !is_array( $cookie ) )
|
578 |
+
$cookie = array();
|
579 |
+
return $cookie;
|
580 |
+
}
|
581 |
+
}
|
582 |
+
|
583 |
+
/**
|
584 |
+
* Switches the current logged in user to the specified user.
|
585 |
+
*
|
586 |
+
* @param int $user_id The ID of the user to switch to.
|
587 |
+
* @param bool $remember Whether to 'remember' the user in the form of a persistent browser cookie. Optional.
|
588 |
+
* @param bool $set_old_user Whether to set the old user cookie. Optional.
|
589 |
+
* @return bool True on success, false on failure.
|
590 |
+
*/
|
591 |
+
if ( !function_exists( 'switch_to_user' ) ) {
|
592 |
+
function switch_to_user( $user_id, $remember = false, $set_old_user = true ) {
|
593 |
+
if ( !$user = get_userdata( $user_id ) )
|
594 |
+
return false;
|
595 |
+
|
596 |
+
if ( $set_old_user and is_user_logged_in() ) {
|
597 |
+
$old_user_id = get_current_user_id();
|
598 |
+
wp_set_olduser_cookie( $old_user_id );
|
599 |
+
} else {
|
600 |
+
$old_user_id = false;
|
601 |
+
wp_clear_olduser_cookie( false );
|
602 |
+
}
|
603 |
+
|
604 |
+
wp_clear_auth_cookie();
|
605 |
+
wp_set_auth_cookie( $user_id, $remember );
|
606 |
+
wp_set_current_user( $user_id );
|
607 |
+
|
608 |
+
if ( $set_old_user )
|
609 |
+
do_action( 'switch_to_user', $user_id, $old_user_id );
|
610 |
+
else
|
611 |
+
do_action( 'switch_back_user', $user_id, $old_user_id );
|
612 |
+
|
613 |
+
return true;
|
614 |
+
}
|
615 |
+
}
|
616 |
+
|
617 |
+
/**
|
618 |
+
* Switches off the current logged in user. This logs the current user out while retaining a cookie allowing them to log straight
|
619 |
+
* back in using the 'Switch back to {user}' system.
|
620 |
+
*
|
621 |
+
* @return bool True on success, false on failure.
|
622 |
+
*/
|
623 |
+
if ( !function_exists( 'switch_off_user' ) ) {
|
624 |
+
function switch_off_user() {
|
625 |
+
if ( !$old_user_id = get_current_user_id() )
|
626 |
+
return false;
|
627 |
+
|
628 |
+
wp_set_olduser_cookie( $old_user_id );
|
629 |
+
wp_clear_auth_cookie();
|
630 |
+
|
631 |
+
do_action( 'switch_off_user', $old_user_id );
|
632 |
+
|
633 |
+
return true;
|
634 |
+
}
|
635 |
+
}
|
636 |
+
|
637 |
+
/**
|
638 |
+
* Helper function. Did the current user switch into their account?
|
639 |
+
*
|
640 |
+
* @return bool|object False if the user isn't logged in or they didn't switch in; old user object (which evalutes to true) if the user switched into the current user account.
|
641 |
+
*/
|
642 |
+
if ( !function_exists( 'current_user_switched' ) ) {
|
643 |
+
function current_user_switched() {
|
644 |
+
if ( !is_user_logged_in() )
|
645 |
+
return false;
|
646 |
+
|
647 |
+
return user_switching::get_old_user();
|
648 |
+
}
|
649 |
+
}
|
650 |
+
|
651 |
+
global $user_switching;
|
652 |
+
|
653 |
+
$user_switching = new user_switching;
|