PluginProbe
Booking Calendar / 11.6.1
Booking Calendar v11.6.1
11.9.1 11.9 11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 All 206 releases
booking / includes / booking_modes / booking_modes-context.php

booking_modes-context.php in Booking Calendar 11.6.1, at includes/booking_modes/booking_modes-context.php

165 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Request and owner context for Booking Modes.
4 *
5 * @package Booking Calendar
6 * @since 11.5.0
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Resolve immutable request context once for the current PHP request.
15 */
16 final class WPBC_Booking_Mode_Context {
17
18 /**
19 * Shared context instance.
20 *
21 * @var WPBC_Booking_Mode_Context|null
22 */
23 private static $instance = null;
24
25 /**
26 * Normalized context, or null before first use.
27 *
28 * @var array|null
29 */
30 private $context = null;
31
32 /**
33 * Number of context builds in the current request.
34 *
35 * @var int
36 */
37 private $build_count = 0;
38
39 /**
40 * Prevent direct construction.
41 */
42 private function __construct() {}
43
44 /**
45 * Get the shared request instance.
46 *
47 * @return WPBC_Booking_Mode_Context Context instance.
48 */
49 public static function get_instance() {
50
51 if ( null === self::$instance ) {
52 self::$instance = new self();
53 }
54
55 return self::$instance;
56 }
57
58 /**
59 * Get normalized request and Booking Calendar owner context.
60 *
61 * Request values are presentation context only. They never authorize access
62 * or replace the existing page/controller capability checks.
63 *
64 * @return array Normalized context values.
65 */
66 public function get_context() {
67
68 if ( null !== $this->context ) {
69 return $this->context;
70 }
71
72 ++$this->build_count;
73
74 $page = $this->get_request_key( 'page' );
75 $real_user_id = get_current_user_id();
76 $owner_user_id = function_exists( 'wpbc_get_current_user_id' ) ? absint( wpbc_get_current_user_id() ) : absint( $real_user_id );
77 $is_multiuser = class_exists( 'wpdev_bk_multiuser' );
78 $is_real_super = $is_multiuser ? (bool) apply_bk_filter( 'is_user_super_admin', $real_user_id ) : current_user_can( 'activate_plugins' );
79 $is_owner_super = $is_multiuser ? (bool) apply_bk_filter( 'is_user_super_admin', $owner_user_id ) : $is_real_super;
80 $is_doing_ajax = function_exists( 'wp_doing_ajax' ) ? wp_doing_ajax() : ( defined( 'DOING_AJAX' ) && DOING_AJAX );
81
82 $context = array(
83 'feature_enabled' => true,
84 'is_admin' => is_admin(),
85 'is_ajax' => (bool) $is_doing_ajax,
86 'is_wpbc_page' => 0 === strpos( $page, 'wpbc' ),
87 'page' => $page,
88 'tab' => $this->get_request_key( 'tab' ),
89 'subtab' => $this->get_request_key( 'subtab' ),
90 'real_user_id' => absint( $real_user_id ),
91 'owner_user_id' => $owner_user_id,
92 'is_multiuser' => $is_multiuser,
93 'is_simulated_login' => $is_multiuser && $owner_user_id > 0 && $owner_user_id !== absint( $real_user_id ),
94 'is_real_booking_super_admin' => $is_real_super,
95 'is_owner_booking_super_admin' => $is_owner_super,
96 );
97
98 /**
99 * Filter the cached Booking Modes request and owner context.
100 *
101 * This filter runs once per request. It must not grant page access; existing
102 * Booking Calendar controllers remain authoritative for capabilities.
103 *
104 * @param array $context Normalized request and owner context.
105 */
106 $filtered_context = apply_filters( 'wpbc_booking_modes_context', $context );
107 $this->context = $this->normalize_context( $filtered_context, $context );
108
109 return $this->context;
110 }
111
112 /**
113 * Get the number of context builds in the current request.
114 *
115 * @return int Context build count.
116 */
117 public function get_build_count() {
118
119 return $this->build_count;
120 }
121
122 /**
123 * Read and sanitize a scalar request key.
124 *
125 * @param string $request_key Request parameter name.
126 *
127 * @return string Sanitized request value, or an empty string.
128 */
129 private function get_request_key( $request_key ) {
130
131 if ( ! isset( $_REQUEST[ $request_key ] ) || ! is_scalar( $_REQUEST[ $request_key ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
132 return '';
133 }
134
135 return sanitize_key( wp_unslash( $_REQUEST[ $request_key ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
136 }
137
138 /**
139 * Normalize filtered context without discarding extension metadata.
140 *
141 * @param mixed $filtered_context Context returned by the public filter.
142 * @param array $default_context Internally resolved fallback context.
143 *
144 * @return array Safe context values plus any additional extension keys.
145 */
146 private function normalize_context( $filtered_context, $default_context ) {
147
148 $context = is_array( $filtered_context ) ? wp_parse_args( $filtered_context, $default_context ) : $default_context;
149
150 foreach ( array( 'page', 'tab', 'subtab' ) as $request_key ) {
151 $context[ $request_key ] = is_scalar( $context[ $request_key ] ) ? sanitize_key( (string) $context[ $request_key ] ) : '';
152 }
153
154 foreach ( array( 'real_user_id', 'owner_user_id' ) as $user_id_key ) {
155 $context[ $user_id_key ] = is_scalar( $context[ $user_id_key ] ) ? absint( $context[ $user_id_key ] ) : 0;
156 }
157
158 foreach ( array( 'feature_enabled', 'is_admin', 'is_ajax', 'is_wpbc_page', 'is_multiuser', 'is_simulated_login', 'is_real_booking_super_admin', 'is_owner_booking_super_admin' ) as $boolean_key ) {
159 $context[ $boolean_key ] = (bool) $context[ $boolean_key ];
160 }
161
162 return $context;
163 }
164 }
165