PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.7.3
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.7.3
3.7.5 3.7.4 3.7.3 3.7.2 1-final 3.7.1 3.7.0 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.10 All 111 releases
← All changes | includes/Utils/Options.php +66 -8 3.6.23.7.3 View file →
@@ -21,8 +21,16 @@
21 21 */
22 22 private $has_api;
23 23
24 24 /**
25 + * Pin every derived read/write to the acting user, bypassing the
26 + * global-login fallback in user_id().
27 + *
28 + * @var bool
29 + */
30 + private $force_current_user = false;
31 +
32 + /**
25 33 * Automatically invoked and set up the properties.
26 34 */
27 35 public function __construct(){
28 36 $this->current_user = get_current_user_id();
@@ -30,11 +38,23 @@
30 38 }
31 39
32 40 /**
33 41 * Get the current user ID.
42 + *
43 + * `get_current_user_id()` can still be 0 when this singleton is built — a
44 + * wp-cli run before `wp_set_current_user()`, or a request whose auth has not
45 + * been resolved yet. Caching that 0 for the rest of the request made every
46 + * derived write bail in `can_write()`, so a connect could answer "Site
47 + * connected successfully" and persist nothing. Re-read while it is still
48 + * unknown; a resolved id is never overwritten.
49 + *
34 50 * @return int
35 51 */
36 52 public function current_user_id(): int {
53 + if ( $this->current_user <= 0 ) {
54 + $this->current_user = get_current_user_id();
55 + }
56 +
37 57 return $this->current_user;
38 58 }
39 59
40 60 /**
@@ -55,13 +75,13 @@
55 75 */
56 76 public function who_am_i(): string {
57 77 $_who_am_i = 'local';
58 78
59 - if( $this->is_global() > 0 && $this->is_global() === $this->current_user ) {
79 + if( $this->is_global() > 0 && $this->is_global() === $this->current_user_id() ) {
60 80 $_who_am_i = 'global';
61 81 }
62 82
63 - if( $this->is_global() > 0 && $this->is_global() !== $this->current_user ) {
83 + if( $this->is_global() > 0 && $this->is_global() !== $this->current_user_id() ) {
64 84 $_who_am_i = 'link';
65 85 }
66 86
67 87 if( $this->is_global() == 0 ) {
@@ -71,26 +91,42 @@
71 91 return $_who_am_i;
72 92 }
73 93
74 94 /**
95 + * Pin the acting user as the target for every derived read/write.
96 + *
97 + * @param bool $force Whether to force the current user.
98 + * @return Options
99 + */
100 + public function use_current_user( bool $force = true ): Options {
101 + $this->force_current_user = $force;
102 +
103 + return $this;
104 + }
105 +
106 + /**
75 107 * Get user id determine dynamically
76 108 * @return integer
77 109 */
78 110 private function user_id(): int {
111 + if ( $this->force_current_user ) {
112 + return $this->current_user_id();
113 + }
114 +
79 115 $_who_am_i = $this->who_am_i();
80 116
81 117 if( ! empty( $_SERVER['REQUEST_URI'] ) ) {
82 118 $parse_uri = explode( '/', substr( $_SERVER['REQUEST_URI'], 0, strpos( $_SERVER['REQUEST_URI'], '?' ) ) );
83 119 if( $_who_am_i === 'link' && array_pop( $parse_uri ) === 'login' ) {
84 - return $this->current_user;
120 + return $this->current_user_id();
85 121 }
86 122 }
87 123
88 124 if( $_who_am_i === 'link' && $this->has_api ) {
89 - return $this->current_user;
125 + return $this->current_user_id();
90 126 }
91 127
92 - return $_who_am_i === 'local' ? $this->current_user : $this->is_global();
128 + return $_who_am_i === 'local' ? $this->current_user_id() : $this->is_global();
93 129 }
94 130
95 131 /**
96 132 * Globally logged in and the User ID of globally logged-in user.
@@ -120,9 +156,9 @@
120 156 return $this->who_am_i() !== 'local';
121 157 }
122 158
123 159 public function signed_as_global(): bool {
124 - return $this->current_user === $this->is_global();
160 + return $this->current_user_id() === $this->is_global();
125 161 }
126 162
127 163 /**
128 164 * Set optional user meta or option data
@@ -184,10 +220,16 @@
184 220 return get_user_option( $key, $user_id );
185 221 }
186 222
187 223 public function update_user_meta($user_id, $meta_key, $meta_value) {
188 - $user_id = is_null( $user_id ) ? $this->user_id() : $user_id;
224 + if ( is_null( $user_id ) ) {
225 + if ( ! $this->can_write() ) {
226 + return false;
227 + }
189 228
229 + $user_id = $this->user_id();
230 + }
231 +
190 232 if( ! is_multisite() ) {
191 233 return update_user_meta( $user_id, $meta_key, $meta_value );
192 234 }
193 235
@@ -194,8 +236,12 @@
194 236 return update_user_option( $user_id, $meta_key, $meta_value, $this->_is_global() );
195 237 }
196 238
197 239 public function delete_user_meta( $meta_key ): bool {
240 + if ( ! $this->can_write() ) {
241 + return false;
242 + }
243 +
198 244 if( ! is_multisite() ) {
199 245 return delete_user_meta( $this->user_id(), $meta_key );
200 246 }
201 247
@@ -201,8 +247,20 @@
201 247
202 248 return delete_user_option( $this->user_id(), $meta_key, $this->_is_global() );
203 249 }
204 250
251 + /**
252 + * Whether the current request may write to a derived user target.
253 + *
254 + * Reads retain the global-login fallback for unauthenticated cloud callbacks,
255 + * but an anonymous request must never write through it to the administrator.
256 + *
257 + * @return bool
258 + */
259 + private function can_write(): bool {
260 + return $this->current_user_id() > 0;
261 + }
262 +
205 263 private function _is_global() {
206 264 return apply_filters( 'templately_multisite_is_global', false );
207 265 }
208 266
@@ -233,5 +291,5 @@
233 291 */
234 292 public function update_option( $key, $value, $autoload = 'no' ): bool {
235 293 return update_option( $key, $value, $autoload );
236 294 }
237 -}
295 +}