PluginProbe
Parse.ly / 3.20.3
Parse.ly v3.20.3
3.24.1 3.24.0 3.23.7 3.23.6 3.23.5 3.23.4 3.23.3 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.17.0 3.18.0 3.18.1 3.19.0 3.19.1 3.19.2 3.19.3 3.2.0 3.2.1 3.20.0 3.20.1 3.20.2 3.20.3 All 105 releases
wp-parsely / src / class-permissions.php

class-permissions.php in Parse.ly 3.20.3, at src/class-permissions.php

216 lines 6.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Permissions Class
4 *
5 * @package Parsely
6 * @since 3.16.0
7 */
8
9 declare(strict_types=1);
10
11 namespace Parsely;
12
13 /**
14 * Class implementing user/role permissions functionality.
15 *
16 * @since 3.16.0
17 *
18 * @phpstan-import-type Parsely_Options_Content_Helper from Parsely
19 * @phpstan-import-type Parsely_Options_Content_Helper_Feature from Parsely
20 */
21 class Permissions {
22 /**
23 * Returns all user roles (custom roles included) that have the edit_posts
24 * capability.
25 *
26 * The return value is an associative array with role keys and names, e.g.
27 * `array( 'administrator' => 'Administrator', 'editor' => 'Editor' )`.
28 *
29 * @since 3.16.0
30 *
31 * @return array<string, string> The user roles having the edit_posts capability.
32 */
33 public static function get_user_roles_with_edit_posts_cap(): array {
34 $result = array();
35 $roles = wp_roles()->roles;
36
37 foreach ( $roles as $key => $role ) {
38 if ( isset( $role['capabilities']['edit_posts'] ) ) {
39 $result[ $key ] = $role['name'];
40 }
41 }
42
43 return $result;
44 }
45
46 /**
47 * Returns whether the current user has the permission to access the
48 * specified Content Helper feature.
49 *
50 * @since 3.16.0
51 *
52 * @param string $feature_name The feature's name.
53 * @param Parsely_Options_Content_Helper $pch_options The Content Helper options.
54 * @param int|false $post_id The post ID, if the check is for a specific post.
55 * @return bool Whether the current user can access the specified feature.
56 */
57 public static function current_user_can_use_pch_feature(
58 string $feature_name,
59 $pch_options,
60 $post_id = false
61 ): bool {
62 if ( isset( $pch_options[ $feature_name ] ) ) {
63 /**
64 * The feature's options.
65 *
66 * @var Parsely_Options_Content_Helper_Feature $feature_options
67 */
68 $feature_options = $pch_options[ $feature_name ];
69 } else {
70 return false;
71 }
72
73 $current_user = wp_get_current_user();
74 $user_roles = $current_user->roles;
75
76 /**
77 * Filters whether the current user can use the specified Content Helper
78 * feature.
79 *
80 * This filter can be used to override the default permissions check.
81 *
82 * @since 3.16.2
83 *
84 * @param ?bool $current_user_can_use_pch_feature Whether the current user can use the feature.
85 * Is null when the filter isn't being used.
86 * @param string $feature_name The feature's name.
87 * @param \WP_User $current_user The current user object.
88 * @param int|false $post_id The post ID, if the check is for a specific post.
89 */
90 $filtered_current_user_can_use_pch_feature = apply_filters(
91 'wp_parsely_current_user_can_use_pch_feature',
92 null,
93 $feature_name,
94 $current_user,
95 $post_id
96 );
97
98 // When $wp_parsely_current_user_can_use_pch_feature's value is set,
99 // return it without further processing.
100 if ( null !== $filtered_current_user_can_use_pch_feature ) {
101 if ( true === $filtered_current_user_can_use_pch_feature ) {
102 return true;
103 }
104
105 return false;
106 }
107
108 // All AI features are disabled.
109 if ( true !== $pch_options['ai_features_enabled'] ) {
110 return false;
111 }
112
113 // The specific AI feature is disabled.
114 if ( true !== $feature_options['enabled'] ) {
115 return false;
116 }
117
118 // If the user is a super admin, they can access the feature.
119 if ( is_multisite() && is_super_admin( $current_user->ID ) ) {
120 return true;
121 }
122
123 // Current user's role is not yet set.
124 if ( 0 === count( $user_roles ) ) {
125 return false;
126 }
127
128 // Get the roles with the capability to edit posts.
129 $valid_roles = array_keys( self::get_user_roles_with_edit_posts_cap() );
130
131 // Check that at least one of the user's roles has the capability to edit posts.
132 if ( 0 === count( array_intersect( $user_roles, $valid_roles ) ) ) {
133 return false;
134 }
135
136 // Check that at least one of the user's roles has access to the specific feature/post.
137 $allowed_roles = $feature_options['allowed_user_roles'];
138 if ( 0 === count( array_intersect( $user_roles, $allowed_roles ) ) ) {
139 return false;
140 }
141
142 // Check if the user can edit the post.
143 if ( (int) $post_id > 0 ) {
144 return current_user_can( 'edit_post', $post_id );
145 }
146
147 return true;
148 }
149
150 /**
151 * Returns a JSON-encoded string with the Content Helper permissions for the
152 * current user.
153 *
154 * @since 3.16.0
155 *
156 * @param Parsely_Options_Content_Helper $pch_options The options to check against.
157 * @return string The JSON-encoded permissions string.
158 */
159 public static function get_pch_permissions_json( $pch_options ): string {
160 $permissions = array();
161 $features = array(
162 'SmartLinking' => 'smart_linking',
163 'TitleSuggestions' => 'title_suggestions',
164 'ExcerptSuggestions' => 'excerpt_suggestions',
165 'TrafficBoost' => 'traffic_boost',
166 );
167
168 foreach ( $features as $key => $value ) {
169 $permissions[ $key ] = self::current_user_can_use_pch_feature(
170 $value,
171 $pch_options,
172 get_the_ID()
173 );
174 }
175
176 $result = wp_json_encode( $permissions );
177
178 return is_string( $result ) ? $result : '{}';
179 }
180
181 /**
182 * Builds and returns a permissions settings array for the Content Helper,
183 * based on the passed values.
184 *
185 * @since 3.16.0
186 *
187 * @param bool $enabled Whether to enable the features.
188 * @param array<int, string> $allowed_user_roles The allowed user roles.
189 * @return Parsely_Options_Content_Helper The resulting permissions settings.
190 */
191 public static function build_pch_permissions_settings_array(
192 bool $enabled,
193 array $allowed_user_roles
194 ) {
195 return array(
196 'ai_features_enabled' => $enabled,
197 'smart_linking' => array(
198 'enabled' => $enabled,
199 'allowed_user_roles' => $allowed_user_roles,
200 ),
201 'title_suggestions' => array(
202 'enabled' => $enabled,
203 'allowed_user_roles' => $allowed_user_roles,
204 ),
205 'excerpt_suggestions' => array(
206 'enabled' => $enabled,
207 'allowed_user_roles' => $allowed_user_roles,
208 ),
209 'traffic_boost' => array(
210 'enabled' => $enabled,
211 'allowed_user_roles' => $allowed_user_roles,
212 ),
213 );
214 }
215 }
216