PluginProbe
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More / 2.6.1
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More v2.6.1
trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.10 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 47 releases
← All changes | classes/Models/Restriction.php +181 -218 2.0.22.6.1 View file →
@@ -8,8 +8,10 @@
8 8
9 9 namespace ContentControl\Models;
10 10
11 11 use ContentControl\Models\RuleEngine\Query;
12 +
13 +use function ContentControl\fetch_key_from_array;
12 14 use function ContentControl\get_default_restriction_settings;
13 15
14 16 defined( 'ABSPATH' ) || exit;
15 17
@@ -15,13 +17,23 @@
15 17
16 18 /**
17 19 * Model for restriction sets.
18 20 *
21 + * @version 3.0.0
22 + * @since 2.1.0
23 + *
19 24 * @package ContentControl\Models
20 25 */
21 26 class Restriction {
22 27
23 28 /**
29 + * Current model version.
30 + *
31 + * @var int
32 + */
33 + const MODEL_VERSION = 3;
34 +
35 + /**
24 36 * Post object.
25 37 *
26 38 * @var \WP_Post
27 39 */
@@ -50,9 +62,9 @@
50 62
51 63 /**
52 64 * Restriction description.
53 65 *
54 - * @var string
66 + * @var string|null
55 67 */
56 68 public $description;
57 69
58 70 /**
@@ -57,9 +69,9 @@
57 69
58 70 /**
59 71 * Restriction Message.
60 72 *
61 - * @var string
73 + * @var string|null
62 74 */
63 75 public $message;
64 76
65 77 /**
@@ -76,146 +88,32 @@
76 88 */
77 89 public $priority;
78 90
79 91 /**
80 - * Restriction Setting: Required user status.
92 + * Restriction Condition Query.
81 93 *
82 - * @var string 'logged_in' | 'logged_out';
94 + * @var Query
83 95 */
84 - public $user_status;
96 + public $query;
85 97
86 98 /**
87 - * Restriction Setting: Which roles.
99 + * Restriction Settings.
88 100 *
89 - * @deprecated 2.0.0 Use user_roles instead.
90 - *
91 - * @var string[]
101 + * @var array<string,mixed>
92 102 */
93 - public $roles;
103 + public $settings;
94 104
95 105 /**
96 - * Restriction Setting: Chosen user roles.
106 + * Data version.
97 107 *
98 - * @var string[]
99 - */
100 - public $user_roles;
101 -
102 - /**
103 - * Restriction Setting: Role match method.
104 - *
105 - * @var string 'any' | 'match' | 'exclude';
106 - */
107 - public $role_match;
108 -
109 - /**
110 - * Restriction Setting: Protection method.
111 - *
112 - * @var string 'redirect' | 'replace'
113 - */
114 - public $protection_method;
115 -
116 - /**
117 - * Restriction Setting: Redirect type.
118 - *
119 - * @var string 'login' | 'home' | 'custom'
120 - */
121 - public $redirect_type;
122 -
123 - /**
124 - * Restriction Setting: Redirect url.
125 - *
126 - * @var string
127 - */
128 - public $redirect_url;
129 -
130 - /**
131 - * Restriction Setting: Replacement type.
132 - *
133 - * @var string 'message' | 'page'
134 - */
135 - public $replacement_type;
136 -
137 - /**
138 - * Restriction Setting: Replacement page.
139 - *
140 108 * @var int
141 109 */
142 - public $replacement_page = 0;
110 + public $data_version;
143 111
144 112 /**
145 - * Restriction Setting: Archive handling.
146 - *
147 - * @var string 'filter_post_content' | 'replace_archive_page' | 'redirect' | 'hide'
148 - */
149 - public $archive_handling;
150 -
151 - /**
152 - * Restriction Setting: Archive replacement page.
153 - *
154 - * @var int
155 - */
156 - public $archive_replacement_page = 0;
157 -
158 - /**
159 - * Restriction Setting: Redirect type.
160 - *
161 - * @var string 'login' | 'home' | 'custom'
162 - */
163 - public $archive_redirect_type;
164 -
165 - /**
166 - * Restriction Setting: Redirect url.
167 - *
168 - * @var string
169 - */
170 - public $archive_redirect_url;
171 -
172 - /**
173 - * Restriction Setting: Additional query handling.
174 - *
175 - * @var string 'filter_post_content' | 'hide'
176 - */
177 - public $additional_query_handling;
178 -
179 - /**
180 - * Restriction Settings: Show Excerpts.
181 - *
182 - * @var bool
183 - */
184 - public $show_excerpts;
185 -
186 - /**
187 - * Restriction Settings: Override Default Message.
188 - *
189 - * @var bool
190 - */
191 - public $override_message;
192 -
193 - /**
194 - * Restriction Settings: Custom Message.
195 - *
196 - * @var string
197 - */
198 - public $custom_message;
199 -
200 - /**
201 - * Restriction Settings: Conditions.
202 - *
203 - * @var array
204 - */
205 - public $conditions;
206 -
207 - /**
208 - * Restriction Condition Query.
209 - *
210 - * @var Query
211 - */
212 - public $query;
213 -
214 - /**
215 113 * Build a restriction.
216 114 *
217 - * @param \WP_Post $restriction Restriction data.
115 + * @param \WP_Post|array<string,mixed> $restriction Restriction data.
218 116 */
219 117 public function __construct( $restriction ) {
220 118 if ( ! is_a( $restriction, '\WP_Post' ) ) {
221 119 $this->setup_v1_restriction( $restriction );
@@ -221,40 +119,49 @@
221 119 $this->setup_v1_restriction( $restriction );
222 120 } else {
223 121 $this->post = $restriction;
224 122
123 + /**
124 + * Restriction settings.
125 + *
126 + * @var array<string,mixed>|false $settings
127 + */
225 128 $settings = get_post_meta( $restriction->ID, 'restriction_settings', true );
226 129
130 + if ( ! $settings ) {
131 + $settings = [];
132 + }
133 +
227 134 $settings = wp_parse_args(
228 - is_array( $settings ) ? $settings : [],
135 + $settings,
229 136 get_default_restriction_settings()
230 137 );
231 138
232 - // Convert keys to snake_case using camel_case_to_snake_case().
233 - $settings = array_combine(
234 - array_map( 'ContentControl\camel_case_to_snake_case', array_keys( $settings ) ),
235 - array_values( $settings )
236 - );
139 + $this->settings = $settings;
237 140
238 - $properties = array_merge(
239 - [
240 - 'id' => $restriction->ID,
241 - 'slug' => $restriction->post_name,
242 - 'title' => $restriction->post_title,
243 - 'status' => $restriction->post_status,
244 - 'priority' => $restriction->menu_order,
245 - // We set this late.. on first use.
246 - 'description' => null,
247 - 'message' => null,
248 - ],
249 - $settings
250 - );
141 + $properties = [
142 + 'id' => $restriction->ID,
143 + 'slug' => $restriction->post_name,
144 + 'title' => $restriction->post_title,
145 + 'status' => $restriction->post_status,
146 + 'priority' => $restriction->menu_order,
147 + // We set this late.. on first use.
148 + 'description' => null,
149 + 'message' => null,
150 + ];
251 151
252 152 foreach ( $properties as $key => $value ) {
253 153 $this->$key = $value;
254 154 }
255 155
256 - $this->query = new Query( $this->conditions );
156 + $this->data_version = get_post_meta( $restriction->ID, 'data_version', true );
157 +
158 + if ( ! $this->data_version ) {
159 + $this->data_version = 2;
160 + update_post_meta( $restriction->ID, 'data_version', 2 );
161 + }
162 +
163 + $this->query = new Query( $this->get_setting( 'conditions' ) );
257 164 }
258 165 }
259 166
260 167 /**
@@ -259,9 +166,11 @@
259 166
260 167 /**
261 168 * Map old v1 restriction to new v2 restriction object.
262 169 *
263 - * @param array $restriction Restriction data.
170 + * @param array<string,mixed> $restriction Restriction data.
171 + *
172 + * @return void
264 173 */
265 174 public function setup_v1_restriction( $restriction ) {
266 175 static $index = 0;
267 176
@@ -277,8 +186,10 @@
277 186 'redirect_url' => '',
278 187 'conditions' => '',
279 188 ] );
280 189
190 + $this->data_version = 1;
191 +
281 192 $this->id = 0;
282 193 $this->slug = '';
283 194 $this->title = $restriction['title'];
284 195 $this->description = '';
@@ -286,32 +197,79 @@
286 197 $this->priority = $index;
287 198
288 199 $user_roles = is_array( $restriction['roles'] ) ? $restriction['roles'] : [];
289 200
290 - $this->user_status = $restriction['who'];
291 - $this->role_match = count( $user_roles ) > 0 ? 'match' : 'any';
292 - $this->user_roles = $user_roles;
293 - $this->protection_method = 'custom_message' === $restriction['protection_method'] ? 'replace' : 'redirect';
294 - $this->redirect_type = $restriction['redirect_type'];
295 - $this->redirect_url = $restriction['redirect_url'];
296 - $this->replacement_type = 'message';
297 - $this->replacement_page = 0;
298 - $this->archive_handling = 'filter_post_content';
299 - $this->archive_replacement_page = 0;
300 - $this->archive_redirect_type = $restriction['redirect_type'];
301 - $this->archive_redirect_url = $restriction['redirect_url'];
302 - $this->additional_query_handling = 'filter_post_content';
303 - $this->override_message = $restriction['override_default_message'];
304 - $this->custom_message = $restriction['custom_message'];
305 - $this->show_excerpts = $restriction['show_excerpts'];
306 - $this->conditions = \ContentControl\remap_conditions_to_query( $restriction['conditions'] );
201 + $settings = [
202 + 'userStatus' => $restriction['who'],
203 + 'roleMatch' => count( $user_roles ) > 0 ? 'match' : 'any',
204 + 'userRoles' => $user_roles,
205 + 'protectionMethod' => 'custom_message' === $restriction['protection_method'] ? 'replace' : 'redirect',
206 + 'redirectType' => $restriction['redirect_type'],
207 + 'redirectUrl' => $restriction['redirect_url'],
208 + 'replacementType' => 'message',
209 + 'replacementPage' => 0,
210 + 'archiveHandling' => 'filter_post_content',
211 + 'archiveReplacementPage' => 0,
212 + 'archiveRedirectType' => $restriction['redirect_type'],
213 + 'archiveRedirectUrl' => $restriction['redirect_url'],
214 + 'additionalQueryHandling' => 'filter_post_content',
215 + 'overrideMessage' => $restriction['override_default_message'],
216 + 'customMessage' => $restriction['custom_message'],
217 + 'showExcerpts' => $restriction['show_excerpts'],
218 + 'conditions' => \ContentControl\remap_conditions_to_query( $restriction['conditions'] ),
219 + ];
307 220
308 - $this->query = new Query( $this->conditions );
221 + $this->settings = $settings;
309 222
223 + $this->query = new Query( $settings['conditions'] );
224 +
310 225 ++$index;
311 226 }
312 227
313 228 /**
229 + * Get the restriction settings array.
230 + *
231 + * @return array<string,mixed>
232 + */
233 + public function get_settings() {
234 + return $this->settings;
235 + }
236 +
237 + /**
238 + * Get a restriction setting.
239 + *
240 + * Settings are stored in JS based camelCase. But WP prefers snake_case.
241 + *
242 + * This method supports camelCase based dot.notation, as well as snake_case.
243 + *
244 + * @param string $key Setting key.
245 + * @param mixed $default_value Default value.
246 + *
247 + * @return mixed|false
248 + */
249 + public function get_setting( $key, $default_value = false ) {
250 + // Support camelCase, snake_case, and dot.notation.
251 + // Check for camelKeys & dot.notation.
252 + $value = \ContentControl\fetch_key_from_array( $key, $this->settings, 'camelCase' );
253 +
254 + if ( null === $value ) {
255 + $value = $default_value;
256 + }
257 +
258 + /**
259 + * Filter the option.
260 + *
261 + * @param mixed $value Option value.
262 + * @param string $key Option key.
263 + * @param mixed $default_value Default value.
264 + * @param int $restriction_id Restriction ID.
265 + *
266 + * @return mixed
267 + */
268 + return apply_filters( 'content_control/get_restriction_setting', $value, $key, $default_value, $this->id );
269 + }
270 +
271 + /**
314 272 * Check if this set has JS based rules.
315 273 *
316 274 * @return bool
317 275 */
@@ -338,9 +296,16 @@
338 296 *
339 297 * @return bool
340 298 */
341 299 public function user_meets_requirements() {
342 - return \ContentControl\user_meets_requirements( $this->user_status, $this->user_roles, $this->role_match );
300 + // Filter to allow override user status check early.
301 + $bypass = \apply_filters( 'content_control/restriction/bypass_user_requirements', null, $this );
302 +
303 + if ( null !== $bypass ) {
304 + return $bypass;
305 + }
306 +
307 + return \ContentControl\user_meets_requirements( $this->get_setting( 'userStatus' ), $this->get_setting( 'userRoles' ), $this->get_setting( 'roleMatch' ) );
343 308 }
344 309
345 310 /**
346 311 * Get the description for this restriction.
@@ -364,26 +329,28 @@
364 329 *
365 330 * @uses \get_the_content()
366 331 * @uses \ContentControl\get_default_denial_message()
367 332 *
333 + * @param string $context Context. 'display' or 'raw'.
334 + *
368 335 * @return string
369 336 */
370 - public function get_message() {
337 + public function get_message( $context = 'display' ) {
371 338 if ( ! isset( $this->message ) ) {
372 - if ( ! empty( $this->post->post_content ) ) {
373 - $message = \get_the_content( null, false, $this->id );
374 - } elseif ( 'message' === $this->replacement_type && $this->override_message && ! empty( $this->custom_message ) ) {
375 - $message = $this->custom_message;
376 - } else {
377 - $message = \ContentControl\get_default_denial_message();
339 + $message = '';
340 +
341 + if ( ! empty( $this->get_setting( 'customMessage' ) ) ) {
342 + $message = $this->get_setting( 'customMessage' );
343 + } elseif ( ! empty( $this->post->post_content ) ) {
344 + $message = 'display' === $context
345 + ? \get_the_content( null, false, $this->id )
346 + : $this->post->post_content;
378 347 }
379 348
380 - $this->message = ! empty( $message ) ?
381 - $message :
382 - __( 'This content is restricted.', 'content-control' );
349 + $this->message = $message;
383 350 }
384 351
385 - return $this->message;
352 + return sanitize_post_field( 'post_content', $this->message, $this->id, $context );
386 353 }
387 354
388 355 /**
389 356 * Whether to show excerpts for posts that are restricted.
@@ -390,9 +357,9 @@
390 357 *
391 358 * @return bool
392 359 */
393 360 public function show_excerpts() {
394 - return (bool) $this->show_excerpts;
361 + return (bool) $this->get_setting( 'showExcerpts' );
395 362 }
396 363
397 364 /**
398 365 * Check if this uses the redirect method.
@@ -399,9 +366,9 @@
399 366 *
400 367 * @return bool
401 368 */
402 369 public function uses_redirect_method() {
403 - return 'redirect' === $this->protection_method;
370 + return 'redirect' === $this->get_setting( 'protectionMethod' );
404 371 }
405 372
406 373 /**
407 374 * Check if this uses the replace method.
@@ -408,64 +375,60 @@
408 375 *
409 376 * @return bool
410 377 */
411 378 public function uses_replace_method() {
412 - return 'replace' === $this->protection_method;
379 + return 'replace' === $this->get_setting( 'protectionMethod' );
413 380 }
414 381
415 382 /**
383 + * Get edit link.
384 + *
385 + * @return string
386 + */
387 + public function get_edit_link() {
388 + if ( current_user_can( 'edit_post', $this->id ) ) {
389 + return admin_url( 'options-general.php?page=content-control-settings&view=restrictions&edit=' . $this->id );
390 + }
391 +
392 + return '';
393 + }
394 +
395 + /**
416 396 * Convert this restriction to an array.
417 397 *
418 - * @return array
398 + * @return array<string,mixed>
419 399 */
420 400 public function to_array() {
421 - return [
422 - 'id' => $this->id,
423 - 'slug' => $this->slug,
424 - 'title' => $this->title,
425 - 'description' => $this->get_description(),
426 - 'message' => $this->get_message(),
427 - 'status' => $this->status,
428 - 'priority' => $this->priority,
429 - // Options include logged_in, logged_out.
430 - 'userStatus' => $this->user_status,
431 - // Options include any, match, exclude.
432 - 'roleMatch' => $this->role_match,
433 - 'userRoles' => $this->user_roles,
434 - 'protectionMethod' => $this->protection_method,
435 - 'redirectType' => $this->redirect_type,
436 - 'redirectUrl' => $this->redirect_url,
437 - 'replacementType' => $this->replacement_type,
438 - 'replacementPage' => $this->replacement_page,
439 - 'archiveHandling' => $this->archive_handling,
440 - 'archiveReplacementPage' => $this->archive_replacement_page,
441 - 'archiveRedirectType' => $this->archive_redirect_type,
442 - 'archiveRedirectUrl' => $this->archive_redirect_url,
443 - 'additionalQueryHandling' => $this->additional_query_handling,
444 - 'overrideMessage' => $this->override_message,
445 - 'customMessage' => $this->custom_message,
446 - 'showExcerpts' => $this->show_excerpts,
447 - 'conditions' => $this->conditions,
448 - ];
401 + $settings = $this->get_settings();
402 +
403 + return array_merge( [
404 + 'id' => $this->id,
405 + 'slug' => $this->slug,
406 + 'title' => $this->title,
407 + 'description' => $this->get_description(),
408 + 'message' => $this->get_message(),
409 + 'status' => $this->status,
410 + 'priority' => $this->priority,
411 + ], $settings );
449 412 }
450 413
451 414 /**
452 415 * Convert this restriction to a v1 array.
453 416 *
454 - * @return array
417 + * @return array<string,mixed>
455 418 */
456 419 public function to_v1_array() {
457 420 return [
458 421 'id' => $this->id,
459 422 'title' => $this->title,
460 - 'who' => $this->user_status,
461 - 'roles' => $this->user_roles,
462 - 'protection_method' => $this->protection_method,
463 - 'show_excerpts' => $this->show_excerpts,
464 - 'override_default_message' => $this->override_message,
465 - 'custom_message' => $this->custom_message,
466 - 'redirect_type' => $this->redirect_type,
467 - 'redirect_url' => $this->redirect_url,
468 - 'conditions' => $this->conditions,
423 + 'who' => $this->get_setting( 'userStatus' ),
424 + 'roles' => $this->get_setting( 'userRoles' ),
425 + 'protection_method' => $this->get_setting( 'protectionMethod' ),
426 + 'show_excerpts' => $this->get_setting( 'showExcerpts' ),
427 + 'override_default_message' => $this->get_setting( 'overrideMessage' ),
428 + 'custom_message' => $this->get_setting( 'customMessage' ),
429 + 'redirect_type' => $this->get_setting( 'redirectType' ),
430 + 'redirect_url' => $this->get_setting( 'redirectUrl' ),
431 + 'conditions' => $this->get_setting( 'conditions' ),
469 432 ];
470 433 }
471 434 }