-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathclass-permissions.php
More file actions
215 lines (191 loc) · 6 KB
/
class-permissions.php
File metadata and controls
215 lines (191 loc) · 6 KB
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
<?php
/**
* Permissions Class
*
* @package Parsely
* @since 3.16.0
*/
declare(strict_types=1);
namespace Parsely;
/**
* Class implementing user/role permissions functionality.
*
* @since 3.16.0
*
* @phpstan-import-type Parsely_Options_Content_Helper from Parsely
* @phpstan-import-type Parsely_Options_Content_Helper_Feature from Parsely
*/
class Permissions {
/**
* Returns all user roles (custom roles included) that have the edit_posts
* capability.
*
* The return value is an associative array with role keys and names, e.g.
* `array( 'administrator' => 'Administrator', 'editor' => 'Editor' )`.
*
* @since 3.16.0
*
* @return array<string, string> The user roles having the edit_posts capability.
*/
public static function get_user_roles_with_edit_posts_cap(): array {
$result = array();
$roles = wp_roles()->roles;
foreach ( $roles as $key => $role ) {
if ( isset( $role['capabilities']['edit_posts'] ) ) {
$result[ $key ] = $role['name'];
}
}
return $result;
}
/**
* Returns whether the current user has the permission to access the
* specified Content Intelligence feature.
*
* @since 3.16.0
*
* @param string $feature_name The feature's name.
* @param Parsely_Options_Content_Helper $pch_options The Content Intelligence options.
* @param int|false $post_id The post ID, if the check is for a specific post.
* @return bool Whether the current user can access the specified feature.
*/
public static function current_user_can_use_pch_feature(
string $feature_name,
$pch_options,
$post_id = false
): bool {
if ( isset( $pch_options[ $feature_name ] ) ) {
/**
* The feature's options.
*
* @var Parsely_Options_Content_Helper_Feature $feature_options
*/
$feature_options = $pch_options[ $feature_name ];
} else {
return false;
}
$current_user = wp_get_current_user();
$user_roles = $current_user->roles;
/**
* Filters whether the current user can use the specified Content
* Intelligence feature.
*
* This filter can be used to override the default permissions check.
*
* @since 3.16.2
*
* @param ?bool $current_user_can_use_pch_feature Whether the current user can use the feature.
* Is null when the filter isn't being used.
* @param string $feature_name The feature's name.
* @param \WP_User $current_user The current user object.
* @param int|false $post_id The post ID, if the check is for a specific post.
*/
$filtered_current_user_can_use_pch_feature = apply_filters(
'wp_parsely_current_user_can_use_pch_feature',
null,
$feature_name,
$current_user,
$post_id
);
// When $wp_parsely_current_user_can_use_pch_feature's value is set,
// return it without further processing.
if ( null !== $filtered_current_user_can_use_pch_feature ) {
if ( true === $filtered_current_user_can_use_pch_feature ) {
return true;
}
return false;
}
// All AI features are disabled.
if ( true !== $pch_options['ai_features_enabled'] ) {
return false;
}
// The specific AI feature is disabled.
if ( true !== $feature_options['enabled'] ) {
return false;
}
// If the user is a super admin, they can access the feature.
if ( is_multisite() && is_super_admin( $current_user->ID ) ) {
return true;
}
// Current user's role is not yet set.
if ( 0 === count( $user_roles ) ) {
return false;
}
// Get the roles with the capability to edit posts.
$valid_roles = array_keys( self::get_user_roles_with_edit_posts_cap() );
// Check that at least one of the user's roles has the capability to edit posts.
if ( 0 === count( array_intersect( $user_roles, $valid_roles ) ) ) {
return false;
}
// Check that at least one of the user's roles has access to the specific feature/post.
$allowed_roles = $feature_options['allowed_user_roles'];
if ( 0 === count( array_intersect( $user_roles, $allowed_roles ) ) ) {
return false;
}
// Check if the user can edit the post.
if ( (int) $post_id > 0 ) {
return current_user_can( 'edit_post', $post_id );
}
return true;
}
/**
* Returns a JSON-encoded string with the Content Intelligence permissions
* for the current user.
*
* @since 3.16.0
*
* @param Parsely_Options_Content_Helper $pch_options The options to check against.
* @return string The JSON-encoded permissions string.
*/
public static function get_pch_permissions_json( $pch_options ): string {
$permissions = array();
$features = array(
'SmartLinking' => 'smart_linking',
'TitleSuggestions' => 'title_suggestions',
'ExcerptSuggestions' => 'excerpt_suggestions',
'TrafficBoost' => 'traffic_boost',
);
foreach ( $features as $key => $value ) {
$permissions[ $key ] = self::current_user_can_use_pch_feature(
$value,
$pch_options,
get_the_ID()
);
}
$result = wp_json_encode( $permissions );
return is_string( $result ) ? $result : '{}';
}
/**
* Builds and returns a permissions settings array for Content Intelligence,
* based on the passed values.
*
* @since 3.16.0
*
* @param bool $enabled Whether to enable the features.
* @param array<int, string> $allowed_user_roles The allowed user roles.
* @return Parsely_Options_Content_Helper The resulting permissions settings.
*/
public static function build_pch_permissions_settings_array(
bool $enabled,
array $allowed_user_roles
) {
return array(
'ai_features_enabled' => $enabled,
'smart_linking' => array(
'enabled' => $enabled,
'allowed_user_roles' => $allowed_user_roles,
),
'title_suggestions' => array(
'enabled' => $enabled,
'allowed_user_roles' => $allowed_user_roles,
),
'excerpt_suggestions' => array(
'enabled' => $enabled,
'allowed_user_roles' => $allowed_user_roles,
),
'traffic_boost' => array(
'enabled' => $enabled,
'allowed_user_roles' => $allowed_user_roles,
),
);
}
}