booking
/
includes
/
page-catalog-booking-resources
/
class-wpbc-catalog-booking-resources-request.php
class-wpbc-catalog-booking-resources-request.php in Booking Calendar 11.9, at includes/page-catalog-booking-resources/class-wpbc-catalog-booking-resources-request.php
| 1 | <?php |
| 2 | /** |
| 3 | * Booking Resources-specific catalog request validation. |
| 4 | * |
| 5 | * @package Booking Calendar |
| 6 | * @since 11.6.0 |
| 7 | */ |
| 8 | |
| 9 | if ( ! defined( 'ABSPATH' ) ) { |
| 10 | exit; |
| 11 | } |
| 12 | |
| 13 | /** |
| 14 | * Validate filters that the domain-neutral shared request must not interpret. |
| 15 | */ |
| 16 | final class WPBC_Catalog_Booking_Resources_Request { |
| 17 | |
| 18 | /** |
| 19 | * Normalized Resource filter values. |
| 20 | * |
| 21 | * @var array |
| 22 | */ |
| 23 | private $values = array(); |
| 24 | |
| 25 | /** |
| 26 | * Prevent direct construction; callers must use create(). |
| 27 | * |
| 28 | * @param array $values Normalized Resource filter values. |
| 29 | */ |
| 30 | private function __construct( $values ) { |
| 31 | $this->values = $values; |
| 32 | } |
| 33 | |
| 34 | /** |
| 35 | * Create a validated Booking Resources request. |
| 36 | * |
| 37 | * Unknown keys are rejected so arbitrary endpoint input cannot cross into |
| 38 | * the repository. The default `all` view preserves hierarchy groups, while |
| 39 | * explicit type filters intentionally return flat matching Resources in |
| 40 | * Business Large and higher. Lower editions normalize every valid type to |
| 41 | * `all`, which prevents stale paid-edition preferences from hiding rows |
| 42 | * after an edition downgrade. |
| 43 | * |
| 44 | * @param mixed $request_values Untrusted Resource filter values. |
| 45 | * |
| 46 | * @return WPBC_Catalog_Booking_Resources_Request|WP_Error Valid request or safe error. |
| 47 | */ |
| 48 | public static function create( $request_values = array() ) { |
| 49 | if ( ! is_array( $request_values ) ) { |
| 50 | return self::get_error( 'malformed_request', __( 'The Booking Resources request is malformed.', 'booking' ) ); |
| 51 | } |
| 52 | |
| 53 | $allowed_keys = array( 'resource_type', 'hierarchy_state' ); |
| 54 | if ( array_diff( array_keys( $request_values ), $allowed_keys ) ) { |
| 55 | return self::get_error( 'unsupported_filter', __( 'The Booking Resources request contains an unsupported filter.', 'booking' ) ); |
| 56 | } |
| 57 | |
| 58 | $resource_type = 'all'; |
| 59 | if ( array_key_exists( 'resource_type', $request_values ) ) { |
| 60 | if ( ! is_scalar( $request_values['resource_type'] ) ) { |
| 61 | return self::get_error( 'invalid_resource_type', __( 'The requested Booking Resource type is invalid.', 'booking' ) ); |
| 62 | } |
| 63 | |
| 64 | $resource_type = sanitize_key( (string) $request_values['resource_type'] ); |
| 65 | if ( ! in_array( $resource_type, array( 'all', 'single', 'parent', 'child' ), true ) ) { |
| 66 | return self::get_error( 'invalid_resource_type', __( 'The requested Booking Resource type is invalid.', 'booking' ) ); |
| 67 | } |
| 68 | } |
| 69 | if ( ! class_exists( 'wpdev_bk_biz_l' ) ) { |
| 70 | $resource_type = 'all'; |
| 71 | } |
| 72 | |
| 73 | $hierarchy_state = WPBC_UI_Catalog_Hierarchy::normalize_preference_state( |
| 74 | array_key_exists( 'hierarchy_state', $request_values ) ? $request_values['hierarchy_state'] : '' |
| 75 | ); |
| 76 | if ( is_wp_error( $hierarchy_state ) ) { |
| 77 | return $hierarchy_state; |
| 78 | } |
| 79 | |
| 80 | return new self( |
| 81 | array( |
| 82 | 'resource_type' => $resource_type, |
| 83 | 'hierarchy_state' => $hierarchy_state, |
| 84 | ) |
| 85 | ); |
| 86 | } |
| 87 | |
| 88 | /** |
| 89 | * Return one normalized Resource filter. |
| 90 | * |
| 91 | * @param string $request_key Resource filter key. |
| 92 | * @param mixed $default Value returned when the key is unavailable. |
| 93 | * |
| 94 | * @return mixed Normalized value or the supplied default. |
| 95 | */ |
| 96 | public function get( $request_key, $default = null ) { |
| 97 | $request_key = is_scalar( $request_key ) ? sanitize_key( (string) $request_key ) : ''; |
| 98 | |
| 99 | return array_key_exists( $request_key, $this->values ) ? $this->values[ $request_key ] : $default; |
| 100 | } |
| 101 | |
| 102 | /** |
| 103 | * Export normalized Resource filters. |
| 104 | * |
| 105 | * @return array<string,mixed> Normalized filter values. |
| 106 | */ |
| 107 | public function to_array() { |
| 108 | return $this->values; |
| 109 | } |
| 110 | |
| 111 | /** |
| 112 | * Return hierarchy state as a stable JSON preference scalar. |
| 113 | * |
| 114 | * @return string JSON-encoded normalized hierarchy state. |
| 115 | */ |
| 116 | public function get_hierarchy_state_json() { |
| 117 | return (string) wp_json_encode( $this->get( 'hierarchy_state', array() ) ); |
| 118 | } |
| 119 | |
| 120 | /** |
| 121 | * Create a namespaced, non-sensitive domain request error. |
| 122 | * |
| 123 | * @param string $error_code Short error code. |
| 124 | * @param string $error_message Safe localized message. |
| 125 | * |
| 126 | * @return WP_Error Request error. |
| 127 | */ |
| 128 | private static function get_error( $error_code, $error_message ) { |
| 129 | return new WP_Error( 'wpbc_catalog_booking_resources_' . sanitize_key( $error_code ), $error_message ); |
| 130 | } |
| 131 | } |
| 132 |