-
Notifications
You must be signed in to change notification settings - Fork 384
/
DevToolsUserAccess.php
196 lines (178 loc) · 6.04 KB
/
DevToolsUserAccess.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
<?php
/**
* Class DevToolsUserAccess.
*
* @since 2.0
*
* @package AMP
*/
namespace AmpProject\AmpWP\Admin;
use AmpProject\AmpWP\Infrastructure\Registerable;
use AmpProject\AmpWP\Infrastructure\Service;
use AmpProject\AmpWP\Option;
use AMP_Options_Manager;
use AMP_Theme_Support;
use AMP_Validation_Manager;
use WP_Error;
use WP_User;
/**
* Class DevToolsUserAccess
*
* @since 2.0
* @internal
*/
final class DevToolsUserAccess implements Service, Registerable {
/**
* User meta key enabling or disabling developer tools.
*
* @var string
*/
const USER_FIELD_DEVELOPER_TOOLS_ENABLED = 'amp_dev_tools_enabled';
/**
* Runs on instantiation.
*
* @action rest_api_init
*/
public function register() {
add_action( 'rest_api_init', [ $this, 'register_rest_field' ] );
add_action( 'personal_options', [ $this, 'print_personal_options' ] );
add_action( 'personal_options_update', [ $this, 'update_user_setting' ] );
add_action( 'edit_user_profile_update', [ $this, 'update_user_setting' ] );
}
/**
* Determine whether developer tools are enabled for the a user and whether they can access them.
*
* @param null|WP_User|int $user User. Defaults to the current user.
* @return bool Whether developer tools are enabled for the user.
*/
public function is_user_enabled( $user = null ) {
if ( null === $user ) {
$user = wp_get_current_user();
} elseif ( ! $user instanceof WP_User ) {
$user = new WP_User( $user );
}
if ( ! AMP_Validation_Manager::has_cap( $user ) ) {
return false;
}
return $this->get_user_enabled( $user );
}
/**
* Get user enabled (regardless of whether they have the required capability).
*
* @param int|WP_User $user User.
* @return bool Whether dev tools is enabled.
*/
public function get_user_enabled( $user ) {
if ( ! $user instanceof WP_User ) {
$user = new WP_User( $user );
}
$enabled = $user->get( self::USER_FIELD_DEVELOPER_TOOLS_ENABLED );
if ( '' === $enabled ) {
// Disable Developer Tools by default when in Reader mode.
$enabled = AMP_Theme_Support::READER_MODE_SLUG !== AMP_Options_Manager::get_option( Option::THEME_SUPPORT );
/**
* Filters whether Developer Tools is enabled by default for a user.
*
* When Reader mode is active, Developer Tools is currently disabled by default.
*
* @since 2.0.1
*
* @param bool $enabled DevTools enabled.
* @param int $user_id User ID.
*/
$enabled = (bool) apply_filters( 'amp_dev_tools_user_default_enabled', $enabled, $user->ID );
}
return rest_sanitize_boolean( $enabled );
}
/**
* Set user enabled.
*
* @param int|WP_User $user User.
* @param bool $enabled Whether enabled.
* @return bool Whether update was successful.
*/
public function set_user_enabled( $user, $enabled ) {
if ( $user instanceof WP_User ) {
$user = $user->ID;
}
return (bool) update_user_meta( (int) $user, self::USER_FIELD_DEVELOPER_TOOLS_ENABLED, wp_json_encode( (bool) $enabled ) );
}
/**
* Register REST field.
*/
public function register_rest_field() {
register_rest_field(
'user',
self::USER_FIELD_DEVELOPER_TOOLS_ENABLED,
[
'get_callback' => [ $this, 'rest_get_dev_tools_enabled' ],
'update_callback' => [ $this, 'rest_update_dev_tools_enabled' ],
'schema' => [
'description' => __( 'Whether the user has enabled dev tools.', 'amp' ),
'type' => 'boolean',
],
]
);
}
/**
* Add the developer tools checkbox to the user edit screen.
*
* @param WP_User $profile_user Current user being edited.
*/
public function print_personal_options( $profile_user ) {
if ( ! current_user_can( 'edit_user', $profile_user->ID ) || ! AMP_Validation_Manager::has_cap( $profile_user ) ) {
return;
}
?>
<tr>
<th scope="row"><?php esc_html_e( 'AMP Developer Tools', 'amp' ); ?></th>
<td>
<label for="amp_dev_tools_enabled">
<input name="<?php echo esc_attr( self::USER_FIELD_DEVELOPER_TOOLS_ENABLED ); ?>" type="checkbox" id="amp_dev_tools_enabled" value="true" <?php checked( $this->is_user_enabled( $profile_user ) ); ?> />
<?php esc_html_e( 'Enable AMP developer tools to surface validation errors when editing posts and viewing the site.', 'amp' ); ?>
</label>
<p class="description"><?php esc_html_e( 'This presumes you have some experience coding with HTML, CSS, JS, and PHP.', 'amp' ); ?></p>
</td>
</tr>
<?php
}
/**
* Update the user setting from the edit user screen).
*
* @param int $user_id User being edited.
* @return bool Whether update was successful.
*/
public function update_user_setting( $user_id ) {
if ( ! current_user_can( 'edit_user', $user_id ) || ! AMP_Validation_Manager::has_cap( $user_id ) ) {
return false;
}
$enabled = isset( $_POST[ self::USER_FIELD_DEVELOPER_TOOLS_ENABLED ] ) && rest_sanitize_boolean( wp_unslash( $_POST[ self::USER_FIELD_DEVELOPER_TOOLS_ENABLED ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
return $this->set_user_enabled( $user_id, $enabled );
}
/**
* Provides the user's dev tools enabled setting.
*
* @param array $user Array of user data prepared for REST.
* @return null|boolean Whether tools are enabled for the user, or null if the option has not been set.
*/
public function rest_get_dev_tools_enabled( $user ) {
return $this->is_user_enabled( $user['id'] );
}
/**
* Updates a user's dev tools enabled setting.
*
* @param bool $new_value New setting for whether dev tools are enabled for the user.
* @param WP_User $user The WP user to update.
* @return bool|WP_Error The result of update_user_meta, or WP_Error if the current user lacks permission.
*/
public function rest_update_dev_tools_enabled( $new_value, WP_User $user ) {
if ( ! AMP_Validation_Manager::has_cap( $user ) || ! current_user_can( 'edit_user', $user->ID ) ) {
return new WP_Error(
'amp_rest_cannot_edit_user',
__( 'Sorry, the current user is not allowed to make this change.', 'amp' ),
[ 'status' => rest_authorization_required_code() ]
);
}
return $this->set_user_enabled( $user->ID, $new_value );
}
}