PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / trunk
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder vtrunk
2.12.0 2.11.1 2.11.0 2.10.0 2.9.0 2.7.4 2.7.5 2.7.6 2.7.7 2.8.0 2.8.1 2.9.1 trunk 1.0 1.0-beta1 1.0-beta2 1.0-beta3 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 All 78 releases
ablocks / includes / permissions / settings-guard.php

settings-guard.php in aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder trunk, at includes/permissions/settings-guard.php

123 lines 3.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Field-level enforcement for the Settings screen.
4 *
5 * Ajax\Settings::save_settings takes the whole settings blob in one request, so
6 * a single capability on the endpoint would mean "design system" and "site
7 * configuration" can never be separate permissions. This partitions the payload
8 * instead: keys the user may not change are replaced with what is already
9 * saved, so the save succeeds and simply does not move them.
10 *
11 * Replacing with the *saved* value matters. save_settings falls back to
12 * defaults for any missing key, so dropping a key would silently reset it.
13 *
14 * @package ABlocks
15 */
16
17 namespace ABlocks\Permissions;
18
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit;
21 }
22
23 use ABlocks\Admin\Settings\Base as BaseSettings;
24 use ABlocks\Permissions;
25
26 class SettingsGuard {
27
28 /**
29 * Which capability owns which settings keys.
30 *
31 * Anything not matched here belongs to ablocks_manage_settings — the safe
32 * default, since that is the most restrictive of the three and new keys
33 * should not become editable by a designer without somebody deciding so.
34 *
35 * @return array
36 */
37 public static function key_map() {
38 return apply_filters('ablocks/permissions/settings_key_map', [
39 'ablocks_manage_global_styles' => [
40 'prefixes' => [ 'global_', 'lock_global_' ],
41 'keys' => [
42 'default_container_width',
43 'container_padding',
44 'container_element_gap',
45 'enabled_block_copy_paste_style',
46 'enabled_load_google_font_locally',
47 'enabled_only_selected_fonts',
48 'selected_fonts',
49 'font_metric_fallback',
50 ],
51 ],
52 'ablocks_manage_performance' => [
53 'prefixes' => [ 'perf_' ],
54 'keys' => [
55 'enabled_assets_file_generation',
56 ],
57 ],
58 ]);
59 }
60
61 /**
62 * The capability required to change a given settings key.
63 *
64 * @param string $key
65 *
66 * @return string
67 */
68 public static function capability_for_key( $key ) {
69 foreach ( self::key_map() as $capability => $match ) {
70 if ( in_array( $key, $match['keys'], true ) ) {
71 return $capability;
72 }
73 foreach ( $match['prefixes'] as $prefix ) {
74 if ( 0 === strpos( $key, $prefix ) ) {
75 return $capability;
76 }
77 }
78 }
79
80 return 'ablocks_manage_settings';
81 }
82
83 /**
84 * Replace values the current user may not change with the saved ones.
85 *
86 * @param array $payload
87 *
88 * @return array
89 */
90 public static function filter_payload( array $payload ) {
91 // Real administrators, and anyone holding all three, change everything.
92 if ( Permissions::is_real_admin() ) {
93 return $payload;
94 }
95
96 $saved = BaseSettings::get_saved_data();
97 $default = BaseSettings::get_default_data();
98 $allowed = [];
99
100 foreach ( $payload as $key => $value ) {
101 $capability = self::capability_for_key( $key );
102
103 if ( ! isset( $allowed[ $capability ] ) ) {
104 $allowed[ $capability ] = current_user_can( $capability );
105 }
106
107 if ( $allowed[ $capability ] ) {
108 continue;
109 }
110
111 if ( array_key_exists( $key, $saved ) ) {
112 $payload[ $key ] = $saved[ $key ];
113 } elseif ( array_key_exists( $key, $default ) ) {
114 $payload[ $key ] = $default[ $key ];
115 } else {
116 unset( $payload[ $key ] );
117 }
118 }
119
120 return $payload;
121 }
122 }
123