PluginProbe
Booking Calendar / 11.8
Booking Calendar v11.8
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 10.10.2 All 205 releases
booking / includes / booking_modes_v3 / class-wpbc-booking-modes-v3-storage.php

class-wpbc-booking-modes-v3-storage.php in Booking Calendar 11.8, at includes/booking_modes_v3/class-wpbc-booking-modes-v3-storage.php

138 lines 4.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Owner-scoped Booking Modes V3 persistence.
4 *
5 * @package Booking Calendar
6 * @since 11.8.0
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Preserve the released booking_admin_mode user option without write-on-read.
15 */
16 final class WPBC_Booking_Modes_V3_Storage {
17
18 const OPTION_NAME = 'booking_admin_mode';
19
20 /** @var WPBC_Booking_Modes_V3_Storage|null */
21 private static $instance = null;
22
23 /** @var array<int,string> */
24 private $selected_modes = array();
25
26 /** @var int */
27 private $read_count = 0;
28
29 /**
30 * Prevent direct construction.
31 */
32 private function __construct() {}
33
34 /**
35 * Return the shared persistence instance.
36 *
37 * @return WPBC_Booking_Modes_V3_Storage Storage instance.
38 */
39 public static function get_instance() {
40 if ( null === self::$instance ) {
41 self::$instance = new self();
42 }
43
44 return self::$instance;
45 }
46
47 /**
48 * Resolve the effective Booking Calendar owner for this request.
49 *
50 * @return int Owner user ID, or zero when signed out.
51 */
52 public function get_owner_user_id() {
53 $context = WPBC_Booking_Modes_V3_Context::get_instance()->get_context();
54 $owner_user_id = isset( $context['owner_user_id'] ) ? absint( $context['owner_user_id'] ) : 0;
55
56 /**
57 * Filter the owner used by released Booking Modes persistence.
58 *
59 * @param int $owner_user_id Effective Booking Calendar owner.
60 * @param array $context Cached request context.
61 */
62 $owner_user_id = apply_filters( 'wpbc_booking_modes_owner_user_id', $owner_user_id, $context );
63
64 return is_scalar( $owner_user_id ) ? absint( $owner_user_id ) : 0;
65 }
66
67 /**
68 * Read one owner's selected mode, defaulting to Classic without writing.
69 *
70 * @param int $owner_user_id Optional explicit owner; zero uses context.
71 *
72 * @return string Allowed mode identifier.
73 */
74 public function get_selected_mode_id( $owner_user_id = 0 ) {
75 $owner_user_id = absint( $owner_user_id );
76 $owner_user_id = $owner_user_id > 0 ? $owner_user_id : $this->get_owner_user_id();
77
78 if ( $owner_user_id <= 0 ) {
79 return 'classic';
80 }
81 if ( isset( $this->selected_modes[ $owner_user_id ] ) ) {
82 return $this->selected_modes[ $owner_user_id ];
83 }
84
85 ++$this->read_count;
86 $stored_mode_id = get_user_option( self::OPTION_NAME, $owner_user_id );
87 $stored_mode_id = is_scalar( $stored_mode_id ) ? sanitize_key( (string) $stored_mode_id ) : '';
88 $allowed_mode_ids = wpbc_booking_modes_get_allowed_mode_ids();
89 $selected_mode_id = in_array( $stored_mode_id, $allowed_mode_ids, true ) ? $stored_mode_id : 'classic';
90 $this->selected_modes[ $owner_user_id ] = $selected_mode_id;
91
92 return $selected_mode_id;
93 }
94
95 /**
96 * Save an explicit selection after an external authorization boundary.
97 *
98 * @param string $mode_id Requested mode ID.
99 * @param int $owner_user_id Optional explicit owner; zero uses context.
100 *
101 * @return bool|WP_Error True on success, otherwise a validation/storage error.
102 */
103 public function set_selected_mode_id( $mode_id, $owner_user_id = 0 ) {
104 $mode_id = is_scalar( $mode_id ) ? sanitize_key( (string) $mode_id ) : '';
105 $current_owner_user_id = $this->get_owner_user_id();
106 $requested_owner_user_id = absint( $owner_user_id );
107 $owner_user_id = $requested_owner_user_id > 0 ? $requested_owner_user_id : $current_owner_user_id;
108
109 if ( $owner_user_id <= 0 || $owner_user_id !== $current_owner_user_id ) {
110 return new WP_Error( 'wpbc_booking_mode_owner_mismatch', __( 'The administration mode can be saved only for the active Booking Calendar owner.', 'booking' ) );
111 }
112 if ( ! in_array( $mode_id, wpbc_booking_modes_get_allowed_mode_ids(), true ) ) {
113 return new WP_Error( 'wpbc_booking_mode_invalid', __( 'The selected Booking Calendar administration mode is not available.', 'booking' ) );
114 }
115
116 $is_updated = update_user_option( $owner_user_id, self::OPTION_NAME, $mode_id );
117 if ( false === $is_updated ) {
118 $stored_mode_id = get_user_option( self::OPTION_NAME, $owner_user_id );
119 $stored_mode_id = is_scalar( $stored_mode_id ) ? sanitize_key( (string) $stored_mode_id ) : '';
120 if ( $mode_id !== $stored_mode_id ) {
121 return new WP_Error( 'wpbc_booking_mode_not_saved', __( 'The Booking Calendar administration mode could not be saved.', 'booking' ) );
122 }
123 }
124
125 $this->selected_modes[ $owner_user_id ] = $mode_id;
126 return true;
127 }
128
129 /**
130 * Return user-option reads performed in this request.
131 *
132 * @return int Read count.
133 */
134 public function get_read_count() {
135 return $this->read_count;
136 }
137 }
138