PluginProbe
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More / 2.6.2
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More v2.6.2
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
content-control / classes / Models / Restriction.php

Restriction.php in Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More 2.6.2, at classes/Models/Restriction.php

435 lines 10.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Restriction model.
4 *
5 * @package ContentControl\RuleEngine
6 * @subpackage Models
7 */
8
9 namespace ContentControl\Models;
10
11 use ContentControl\Models\RuleEngine\Query;
12
13 use function ContentControl\fetch_key_from_array;
14 use function ContentControl\get_default_restriction_settings;
15
16 defined( 'ABSPATH' ) || exit;
17
18 /**
19 * Model for restriction sets.
20 *
21 * @version 3.0.0
22 * @since 2.1.0
23 *
24 * @package ContentControl\Models
25 */
26 class Restriction {
27
28 /**
29 * Current model version.
30 *
31 * @var int
32 */
33 const MODEL_VERSION = 3;
34
35 /**
36 * Post object.
37 *
38 * @var \WP_Post
39 */
40 private $post;
41
42 /**
43 * Restriction id.
44 *
45 * @var int
46 */
47 public $id = 0;
48
49 /**
50 * Restriction slug.
51 *
52 * @var string
53 */
54 public $slug;
55
56 /**
57 * Restriction label.
58 *
59 * @var string
60 */
61 public $title;
62
63 /**
64 * Restriction description.
65 *
66 * @var string|null
67 */
68 public $description;
69
70 /**
71 * Restriction Message.
72 *
73 * @var string|null
74 */
75 public $message;
76
77 /**
78 * Restriction status.
79 *
80 * @var string
81 */
82 public $status;
83
84 /**
85 * Restriction priority.
86 *
87 * @var int
88 */
89 public $priority;
90
91 /**
92 * Restriction Condition Query.
93 *
94 * @var Query
95 */
96 public $query;
97
98 /**
99 * Restriction Settings.
100 *
101 * @var array<string,mixed>
102 */
103 public $settings;
104
105 /**
106 * Data version.
107 *
108 * @var int
109 */
110 public $data_version;
111
112 /**
113 * Build a restriction.
114 *
115 * @param \WP_Post|array<string,mixed> $restriction Restriction data.
116 */
117 public function __construct( $restriction ) {
118 if ( ! is_a( $restriction, '\WP_Post' ) ) {
119 $this->setup_v1_restriction( $restriction );
120 } else {
121 $this->post = $restriction;
122
123 /**
124 * Restriction settings.
125 *
126 * @var array<string,mixed>|false $settings
127 */
128 $settings = get_post_meta( $restriction->ID, 'restriction_settings', true );
129
130 if ( ! $settings ) {
131 $settings = [];
132 }
133
134 $settings = wp_parse_args(
135 $settings,
136 get_default_restriction_settings()
137 );
138
139 $this->settings = $settings;
140
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 ];
151
152 foreach ( $properties as $key => $value ) {
153 $this->$key = $value;
154 }
155
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' ) );
164 }
165 }
166
167 /**
168 * Map old v1 restriction to new v2 restriction object.
169 *
170 * @param array<string,mixed> $restriction Restriction data.
171 *
172 * @return void
173 */
174 public function setup_v1_restriction( $restriction ) {
175 static $index = 0;
176
177 $restriction = \wp_parse_args( $restriction, [
178 'title' => '',
179 'who' => '',
180 'roles' => [],
181 'protection_method' => 'redirect',
182 'show_excerpts' => false,
183 'override_default_message' => false,
184 'custom_message' => '',
185 'redirect_type' => 'login',
186 'redirect_url' => '',
187 'conditions' => '',
188 ] );
189
190 $this->data_version = 1;
191
192 $this->id = 0;
193 $this->slug = '';
194 $this->title = $restriction['title'];
195 $this->description = '';
196 $this->status = 'publish';
197 $this->priority = $index;
198
199 $user_roles = is_array( $restriction['roles'] ) ? $restriction['roles'] : [];
200
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 ];
220
221 $this->settings = $settings;
222
223 $this->query = new Query( $settings['conditions'] );
224
225 ++$index;
226 }
227
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 /**
272 * Check if this set has JS based rules.
273 *
274 * @return bool
275 */
276 public function has_js_rules() {
277 return $this->query->has_js_rules();
278 }
279
280 /**
281 * Check this sets rules.
282 *
283 * @return bool
284 */
285 public function check_rules() {
286 if ( ! $this->query->has_rules() ) {
287 // No rules should be treated as no restrictions.
288 return false;
289 }
290
291 return $this->query->check_rules();
292 }
293
294 /**
295 * Check if this restriction applies to the current user.
296 *
297 * @return bool
298 */
299 public function user_meets_requirements() {
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' ) );
308 }
309
310 /**
311 * Get the description for this restriction.
312 *
313 * @return string
314 */
315 public function get_description() {
316 if ( ! isset( $this->description ) ) {
317 $this->description = get_the_excerpt( $this->id );
318
319 if ( empty( $this->description ) ) {
320 $this->description = __( 'This content is restricted.', 'content-control' );
321 }
322 }
323
324 return $this->description;
325 }
326
327 /**
328 * Get the message for this restriction.
329 *
330 * @uses \get_the_content()
331 * @uses \ContentControl\get_default_denial_message()
332 *
333 * @param string $context Context. 'display' or 'raw'.
334 *
335 * @return string
336 */
337 public function get_message( $context = 'display' ) {
338 if ( ! isset( $this->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;
347 }
348
349 $this->message = $message;
350 }
351
352 return sanitize_post_field( 'post_content', $this->message, $this->id, $context );
353 }
354
355 /**
356 * Whether to show excerpts for posts that are restricted.
357 *
358 * @return bool
359 */
360 public function show_excerpts() {
361 return (bool) $this->get_setting( 'showExcerpts' );
362 }
363
364 /**
365 * Check if this uses the redirect method.
366 *
367 * @return bool
368 */
369 public function uses_redirect_method() {
370 return 'redirect' === $this->get_setting( 'protectionMethod' );
371 }
372
373 /**
374 * Check if this uses the replace method.
375 *
376 * @return bool
377 */
378 public function uses_replace_method() {
379 return 'replace' === $this->get_setting( 'protectionMethod' );
380 }
381
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 /**
396 * Convert this restriction to an array.
397 *
398 * @return array<string,mixed>
399 */
400 public function to_array() {
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 );
412 }
413
414 /**
415 * Convert this restriction to a v1 array.
416 *
417 * @return array<string,mixed>
418 */
419 public function to_v1_array() {
420 return [
421 'id' => $this->id,
422 'title' => $this->title,
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' ),
432 ];
433 }
434 }
435