Files
wp-bnb/src/PostTypes/Room.php
magdev dabfe1e826
All checks were successful
Create Release Package / build-release (push) Successful in 1m19s
Add pricing system with tiers, seasons, and calculator (v0.2.0)
- Create PricingTier enum for short/mid/long-term pricing
- Add Season class for seasonal pricing with date ranges
- Implement Calculator for price calculations with breakdown
- Add pricing meta box to Room post type
- Create Seasons admin page for managing seasonal pricing
- Add Pricing settings tab with tier thresholds
- Support weekend surcharges and configurable weekend days
- Add price column to room list admin

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 14:10:30 +01:00

781 lines
23 KiB
PHP

<?php
/**
* Room post type.
*
* Custom post type for BnB rooms.
*
* @package Magdev\WpBnb\PostTypes
*/
declare( strict_types=1 );
namespace Magdev\WpBnb\PostTypes;
use Magdev\WpBnb\Pricing\Calculator;
use Magdev\WpBnb\Pricing\PricingTier;
use Magdev\WpBnb\Taxonomies\Amenity;
use Magdev\WpBnb\Taxonomies\RoomType;
/**
* Room post type class.
*/
final class Room {
/**
* Post type slug.
*
* @var string
*/
public const POST_TYPE = 'bnb_room';
/**
* Meta key prefix.
*
* @var string
*/
private const META_PREFIX = '_bnb_room_';
/**
* Initialize the post type.
*
* @return void
*/
public static function init(): void {
add_action( 'init', array( self::class, 'register' ) );
add_action( 'add_meta_boxes', array( self::class, 'add_meta_boxes' ) );
add_action( 'save_post_' . self::POST_TYPE, array( self::class, 'save_meta' ), 10, 2 );
add_filter( 'manage_' . self::POST_TYPE . '_posts_columns', array( self::class, 'add_columns' ) );
add_action( 'manage_' . self::POST_TYPE . '_posts_custom_column', array( self::class, 'render_column' ), 10, 2 );
add_filter( 'manage_edit-' . self::POST_TYPE . '_sortable_columns', array( self::class, 'sortable_columns' ) );
add_action( 'restrict_manage_posts', array( self::class, 'add_building_filter' ) );
add_action( 'pre_get_posts', array( self::class, 'filter_by_building' ) );
add_filter( 'enter_title_here', array( self::class, 'change_title_placeholder' ), 10, 2 );
}
/**
* Register the post type.
*
* @return void
*/
public static function register(): void {
$labels = array(
'name' => _x( 'Rooms', 'post type general name', 'wp-bnb' ),
'singular_name' => _x( 'Room', 'post type singular name', 'wp-bnb' ),
'menu_name' => _x( 'Rooms', 'admin menu', 'wp-bnb' ),
'name_admin_bar' => _x( 'Room', 'add new on admin bar', 'wp-bnb' ),
'add_new' => _x( 'Add New', 'room', 'wp-bnb' ),
'add_new_item' => __( 'Add New Room', 'wp-bnb' ),
'new_item' => __( 'New Room', 'wp-bnb' ),
'edit_item' => __( 'Edit Room', 'wp-bnb' ),
'view_item' => __( 'View Room', 'wp-bnb' ),
'all_items' => __( 'Rooms', 'wp-bnb' ),
'search_items' => __( 'Search Rooms', 'wp-bnb' ),
'parent_item_colon' => __( 'Parent Rooms:', 'wp-bnb' ),
'not_found' => __( 'No rooms found.', 'wp-bnb' ),
'not_found_in_trash' => __( 'No rooms found in Trash.', 'wp-bnb' ),
'featured_image' => __( 'Room Image', 'wp-bnb' ),
'set_featured_image' => __( 'Set room image', 'wp-bnb' ),
'remove_featured_image' => __( 'Remove room image', 'wp-bnb' ),
'use_featured_image' => __( 'Use as room image', 'wp-bnb' ),
'archives' => __( 'Room archives', 'wp-bnb' ),
'insert_into_item' => __( 'Insert into room', 'wp-bnb' ),
'uploaded_to_this_item' => __( 'Uploaded to this room', 'wp-bnb' ),
'filter_items_list' => __( 'Filter rooms list', 'wp-bnb' ),
'items_list_navigation' => __( 'Rooms list navigation', 'wp-bnb' ),
'items_list' => __( 'Rooms list', 'wp-bnb' ),
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => 'wp-bnb',
'query_var' => true,
'rewrite' => array(
'slug' => 'room',
'with_front' => false,
),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => null,
'menu_icon' => 'dashicons-admin-home',
'supports' => array(
'title',
'editor',
'thumbnail',
'excerpt',
'revisions',
),
'show_in_rest' => true,
'rest_base' => 'rooms',
'rest_controller_class' => 'WP_REST_Posts_Controller',
'taxonomies' => array( RoomType::TAXONOMY, Amenity::TAXONOMY ),
);
register_post_type( self::POST_TYPE, $args );
}
/**
* Add meta boxes.
*
* @return void
*/
public static function add_meta_boxes(): void {
add_meta_box(
'bnb_room_building',
__( 'Building', 'wp-bnb' ),
array( self::class, 'render_building_meta_box' ),
self::POST_TYPE,
'side',
'high'
);
add_meta_box(
'bnb_room_details',
__( 'Room Details', 'wp-bnb' ),
array( self::class, 'render_details_meta_box' ),
self::POST_TYPE,
'normal',
'high'
);
add_meta_box(
'bnb_room_gallery',
__( 'Room Gallery', 'wp-bnb' ),
array( self::class, 'render_gallery_meta_box' ),
self::POST_TYPE,
'normal',
'default'
);
add_meta_box(
'bnb_room_pricing',
__( 'Room Pricing', 'wp-bnb' ),
array( self::class, 'render_pricing_meta_box' ),
self::POST_TYPE,
'normal',
'high'
);
}
/**
* Render building selection meta box.
*
* @param \WP_Post $post Current post object.
* @return void
*/
public static function render_building_meta_box( \WP_Post $post ): void {
wp_nonce_field( 'bnb_room_meta', 'bnb_room_meta_nonce' );
$building_id = get_post_meta( $post->ID, self::META_PREFIX . 'building_id', true );
$buildings = get_posts(
array(
'post_type' => Building::POST_TYPE,
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
)
);
?>
<p>
<label for="bnb_room_building_id"><?php esc_html_e( 'Select Building', 'wp-bnb' ); ?></label>
</p>
<select id="bnb_room_building_id" name="bnb_room_building_id" class="widefat" required>
<option value=""><?php esc_html_e( '— Select Building —', 'wp-bnb' ); ?></option>
<?php foreach ( $buildings as $building ) : ?>
<option value="<?php echo esc_attr( $building->ID ); ?>" <?php selected( $building_id, $building->ID ); ?>>
<?php echo esc_html( $building->post_title ); ?>
</option>
<?php endforeach; ?>
</select>
<?php if ( empty( $buildings ) ) : ?>
<p class="description">
<?php
printf(
/* translators: %s: Link to add new building */
esc_html__( 'No buildings found. %s first.', 'wp-bnb' ),
'<a href="' . esc_url( admin_url( 'post-new.php?post_type=' . Building::POST_TYPE ) ) . '">' . esc_html__( 'Add a building', 'wp-bnb' ) . '</a>'
);
?>
</p>
<?php endif; ?>
<?php
}
/**
* Render room details meta box.
*
* @param \WP_Post $post Current post object.
* @return void
*/
public static function render_details_meta_box( \WP_Post $post ): void {
$room_number = get_post_meta( $post->ID, self::META_PREFIX . 'room_number', true );
$floor = get_post_meta( $post->ID, self::META_PREFIX . 'floor', true );
$capacity = get_post_meta( $post->ID, self::META_PREFIX . 'capacity', true );
$max_adults = get_post_meta( $post->ID, self::META_PREFIX . 'max_adults', true );
$max_children = get_post_meta( $post->ID, self::META_PREFIX . 'max_children', true );
$size = get_post_meta( $post->ID, self::META_PREFIX . 'size', true );
$beds = get_post_meta( $post->ID, self::META_PREFIX . 'beds', true );
$bathrooms = get_post_meta( $post->ID, self::META_PREFIX . 'bathrooms', true );
$status = get_post_meta( $post->ID, self::META_PREFIX . 'status', true );
?>
<table class="form-table">
<tr>
<th scope="row">
<label for="bnb_room_room_number"><?php esc_html_e( 'Room Number', 'wp-bnb' ); ?></label>
</th>
<td>
<input type="text" id="bnb_room_room_number" name="bnb_room_room_number"
value="<?php echo esc_attr( $room_number ); ?>" class="regular-text">
<p class="description"><?php esc_html_e( 'Room identifier (e.g., 101, A-12, Suite B)', 'wp-bnb' ); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="bnb_room_floor"><?php esc_html_e( 'Floor', 'wp-bnb' ); ?></label>
</th>
<td>
<input type="number" id="bnb_room_floor" name="bnb_room_floor"
value="<?php echo esc_attr( $floor ); ?>" class="small-text" min="0">
</td>
</tr>
<tr>
<th scope="row">
<label for="bnb_room_size"><?php esc_html_e( 'Size (m²)', 'wp-bnb' ); ?></label>
</th>
<td>
<input type="number" id="bnb_room_size" name="bnb_room_size"
value="<?php echo esc_attr( $size ); ?>" class="small-text" min="1" step="0.1">
</td>
</tr>
<tr>
<th scope="row">
<?php esc_html_e( 'Capacity', 'wp-bnb' ); ?>
</th>
<td>
<label for="bnb_room_capacity"><?php esc_html_e( 'Total Guests', 'wp-bnb' ); ?></label>
<input type="number" id="bnb_room_capacity" name="bnb_room_capacity"
value="<?php echo esc_attr( $capacity ?: '2' ); ?>" class="small-text" min="1" max="20">
<br><br>
<label for="bnb_room_max_adults"><?php esc_html_e( 'Max Adults', 'wp-bnb' ); ?></label>
<input type="number" id="bnb_room_max_adults" name="bnb_room_max_adults"
value="<?php echo esc_attr( $max_adults ?: '2' ); ?>" class="small-text" min="1" max="10">
<br><br>
<label for="bnb_room_max_children"><?php esc_html_e( 'Max Children', 'wp-bnb' ); ?></label>
<input type="number" id="bnb_room_max_children" name="bnb_room_max_children"
value="<?php echo esc_attr( $max_children ?: '0' ); ?>" class="small-text" min="0" max="10">
</td>
</tr>
<tr>
<th scope="row">
<label for="bnb_room_beds"><?php esc_html_e( 'Beds', 'wp-bnb' ); ?></label>
</th>
<td>
<input type="text" id="bnb_room_beds" name="bnb_room_beds"
value="<?php echo esc_attr( $beds ); ?>" class="regular-text">
<p class="description"><?php esc_html_e( 'Description of beds (e.g., 1 King, 2 Singles)', 'wp-bnb' ); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="bnb_room_bathrooms"><?php esc_html_e( 'Bathrooms', 'wp-bnb' ); ?></label>
</th>
<td>
<input type="number" id="bnb_room_bathrooms" name="bnb_room_bathrooms"
value="<?php echo esc_attr( $bathrooms ?: '1' ); ?>" class="small-text" min="0" max="5" step="0.5">
</td>
</tr>
<tr>
<th scope="row">
<label for="bnb_room_status"><?php esc_html_e( 'Room Status', 'wp-bnb' ); ?></label>
</th>
<td>
<select id="bnb_room_status" name="bnb_room_status">
<?php foreach ( self::get_room_statuses() as $key => $label ) : ?>
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $status ?: 'available', $key ); ?>>
<?php echo esc_html( $label ); ?>
</option>
<?php endforeach; ?>
</select>
</td>
</tr>
</table>
<?php
}
/**
* Render gallery meta box.
*
* @param \WP_Post $post Current post object.
* @return void
*/
public static function render_gallery_meta_box( \WP_Post $post ): void {
$gallery_ids = get_post_meta( $post->ID, self::META_PREFIX . 'gallery', true );
$gallery_ids = $gallery_ids ? explode( ',', $gallery_ids ) : array();
?>
<div id="bnb-room-gallery" class="bnb-gallery-container">
<div class="bnb-gallery-images">
<?php foreach ( $gallery_ids as $image_id ) : ?>
<?php $image = wp_get_attachment_image_src( $image_id, 'thumbnail' ); ?>
<?php if ( $image ) : ?>
<div class="bnb-gallery-image" data-id="<?php echo esc_attr( $image_id ); ?>">
<img src="<?php echo esc_url( $image[0] ); ?>" alt="">
<button type="button" class="bnb-remove-image">&times;</button>
</div>
<?php endif; ?>
<?php endforeach; ?>
</div>
<input type="hidden" id="bnb_room_gallery" name="bnb_room_gallery"
value="<?php echo esc_attr( implode( ',', $gallery_ids ) ); ?>">
<button type="button" id="bnb-add-gallery-images" class="button">
<?php esc_html_e( 'Add Images', 'wp-bnb' ); ?>
</button>
</div>
<p class="description"><?php esc_html_e( 'Add additional images for this room. Drag to reorder.', 'wp-bnb' ); ?></p>
<?php
}
/**
* Render pricing meta box.
*
* @param \WP_Post $post Current post object.
* @return void
*/
public static function render_pricing_meta_box( \WP_Post $post ): void {
$pricing = Calculator::getRoomPricing( $post->ID );
$currency = get_option( 'wp_bnb_currency', 'CHF' );
?>
<table class="form-table bnb-pricing-table">
<tr>
<th scope="row" colspan="2">
<h4><?php esc_html_e( 'Base Prices', 'wp-bnb' ); ?></h4>
</th>
</tr>
<?php foreach ( PricingTier::cases() as $tier ) : ?>
<tr>
<th scope="row">
<label for="bnb_room_price_<?php echo esc_attr( $tier->value ); ?>">
<?php echo esc_html( $tier->label() ); ?>
</label>
</th>
<td>
<div class="bnb-price-input-wrapper">
<input type="number"
id="bnb_room_price_<?php echo esc_attr( $tier->value ); ?>"
name="bnb_room_price_<?php echo esc_attr( $tier->value ); ?>"
value="<?php echo esc_attr( $pricing[ $tier->value ]['price'] ?? '' ); ?>"
class="small-text"
min="0"
step="0.01">
<span class="bnb-price-unit">
<?php echo esc_html( $currency ); ?> <?php echo esc_html( $tier->unit() ); ?>
</span>
</div>
</td>
</tr>
<?php endforeach; ?>
<tr>
<th scope="row" colspan="2">
<h4><?php esc_html_e( 'Adjustments', 'wp-bnb' ); ?></h4>
</th>
</tr>
<tr>
<th scope="row">
<label for="bnb_room_price_weekend_surcharge">
<?php esc_html_e( 'Weekend Surcharge', 'wp-bnb' ); ?>
</label>
</th>
<td>
<div class="bnb-price-input-wrapper">
<input type="number"
id="bnb_room_price_weekend_surcharge"
name="bnb_room_price_weekend_surcharge"
value="<?php echo esc_attr( $pricing['weekend_surcharge']['price'] ?? '' ); ?>"
class="small-text"
min="0"
step="0.01">
<span class="bnb-price-unit">
<?php echo esc_html( $currency ); ?> <?php esc_html_e( 'per night', 'wp-bnb' ); ?>
</span>
</div>
<p class="description">
<?php esc_html_e( 'Additional amount charged for weekend nights (Friday/Saturday by default).', 'wp-bnb' ); ?>
</p>
</td>
</tr>
</table>
<p class="description">
<?php
printf(
/* translators: %s: Link to pricing settings */
esc_html__( 'Seasonal pricing and tier thresholds can be configured in %s.', 'wp-bnb' ),
'<a href="' . esc_url( admin_url( 'admin.php?page=wp-bnb-settings&tab=pricing' ) ) . '">' . esc_html__( 'Pricing Settings', 'wp-bnb' ) . '</a>'
);
?>
</p>
<?php
}
/**
* Save post meta.
*
* @param int $post_id Post ID.
* @param \WP_Post $post Post object.
* @return void
*/
public static function save_meta( int $post_id, \WP_Post $post ): void {
// Verify nonce.
if ( ! isset( $_POST['bnb_room_meta_nonce'] ) ||
! wp_verify_nonce( sanitize_key( $_POST['bnb_room_meta_nonce'] ), 'bnb_room_meta' ) ) {
return;
}
// Check autosave.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Check permissions.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
// Building ID.
if ( isset( $_POST['bnb_room_building_id'] ) ) {
update_post_meta(
$post_id,
self::META_PREFIX . 'building_id',
absint( $_POST['bnb_room_building_id'] )
);
}
// Text fields.
$text_fields = array( 'room_number', 'beds', 'status' );
foreach ( $text_fields as $field ) {
$key = 'bnb_room_' . $field;
if ( isset( $_POST[ $key ] ) ) {
update_post_meta(
$post_id,
self::META_PREFIX . $field,
sanitize_text_field( wp_unslash( $_POST[ $key ] ) )
);
}
}
// Numeric fields.
$numeric_fields = array( 'floor', 'capacity', 'max_adults', 'max_children' );
foreach ( $numeric_fields as $field ) {
$key = 'bnb_room_' . $field;
if ( isset( $_POST[ $key ] ) ) {
update_post_meta(
$post_id,
self::META_PREFIX . $field,
absint( $_POST[ $key ] )
);
}
}
// Float fields.
$float_fields = array( 'size', 'bathrooms' );
foreach ( $float_fields as $field ) {
$key = 'bnb_room_' . $field;
if ( isset( $_POST[ $key ] ) ) {
update_post_meta(
$post_id,
self::META_PREFIX . $field,
floatval( $_POST[ $key ] )
);
}
}
// Gallery.
if ( isset( $_POST['bnb_room_gallery'] ) ) {
$gallery_ids = sanitize_text_field( wp_unslash( $_POST['bnb_room_gallery'] ) );
// Validate that each ID is numeric.
$ids = array_filter( explode( ',', $gallery_ids ), 'is_numeric' );
update_post_meta(
$post_id,
self::META_PREFIX . 'gallery',
implode( ',', $ids )
);
}
// Pricing fields.
$pricing_data = array();
foreach ( PricingTier::cases() as $tier ) {
$key = 'bnb_room_price_' . $tier->value;
if ( isset( $_POST[ $key ] ) && '' !== $_POST[ $key ] ) {
$pricing_data[ $tier->value ] = floatval( $_POST[ $key ] );
}
}
if ( isset( $_POST['bnb_room_price_weekend_surcharge'] ) ) {
$pricing_data['weekend_surcharge'] = floatval( $_POST['bnb_room_price_weekend_surcharge'] );
}
if ( ! empty( $pricing_data ) ) {
Calculator::saveRoomPricing( $post_id, $pricing_data );
}
}
/**
* Add custom columns to the post list.
*
* @param array $columns Existing columns.
* @return array
*/
public static function add_columns( array $columns ): array {
$new_columns = array();
foreach ( $columns as $key => $value ) {
if ( 'taxonomy-bnb_room_type' === $key ) {
continue; // Will add after title.
}
if ( 'taxonomy-bnb_amenity' === $key ) {
continue; // Will add after room type.
}
$new_columns[ $key ] = $value;
if ( 'title' === $key ) {
$new_columns['building'] = __( 'Building', 'wp-bnb' );
$new_columns['room_number'] = __( 'Room #', 'wp-bnb' );
$new_columns['taxonomy-bnb_room_type'] = __( 'Room Type', 'wp-bnb' );
$new_columns['capacity'] = __( 'Capacity', 'wp-bnb' );
$new_columns['price'] = __( 'Price/Night', 'wp-bnb' );
$new_columns['status'] = __( 'Status', 'wp-bnb' );
}
}
return $new_columns;
}
/**
* Render custom column content.
*
* @param string $column Column name.
* @param int $post_id Post ID.
* @return void
*/
public static function render_column( string $column, int $post_id ): void {
switch ( $column ) {
case 'building':
$building_id = get_post_meta( $post_id, self::META_PREFIX . 'building_id', true );
if ( $building_id ) {
$building = get_post( $building_id );
if ( $building ) {
printf(
'<a href="%s">%s</a>',
esc_url( get_edit_post_link( $building_id ) ),
esc_html( $building->post_title )
);
} else {
echo '—';
}
} else {
echo '—';
}
break;
case 'room_number':
$room_number = get_post_meta( $post_id, self::META_PREFIX . 'room_number', true );
echo esc_html( $room_number ?: '—' );
break;
case 'capacity':
$capacity = get_post_meta( $post_id, self::META_PREFIX . 'capacity', true );
if ( $capacity ) {
printf(
'<span class="dashicons dashicons-groups"></span> %s',
esc_html( $capacity )
);
} else {
echo '—';
}
break;
case 'price':
$pricing = Calculator::getRoomPricing( $post_id );
$nightly = $pricing[ PricingTier::SHORT_TERM->value ]['price'] ?? null;
if ( $nightly ) {
echo esc_html( Calculator::formatPrice( $nightly ) );
} else {
echo '<span class="bnb-no-price">' . esc_html__( 'Not set', 'wp-bnb' ) . '</span>';
}
break;
case 'status':
$status = get_post_meta( $post_id, self::META_PREFIX . 'status', true ) ?: 'available';
$statuses = self::get_room_statuses();
$colors = self::get_status_colors();
?>
<span class="bnb-status-badge" style="background-color: <?php echo esc_attr( $colors[ $status ] ?? '#ccc' ); ?>">
<?php echo esc_html( $statuses[ $status ] ?? $status ); ?>
</span>
<?php
break;
}
}
/**
* Add sortable columns.
*
* @param array $columns Existing sortable columns.
* @return array
*/
public static function sortable_columns( array $columns ): array {
$columns['building'] = 'building';
$columns['room_number'] = 'room_number';
$columns['capacity'] = 'capacity';
return $columns;
}
/**
* Add building filter dropdown to admin list.
*
* @param string $post_type Current post type.
* @return void
*/
public static function add_building_filter( string $post_type ): void {
if ( self::POST_TYPE !== $post_type ) {
return;
}
$buildings = get_posts(
array(
'post_type' => Building::POST_TYPE,
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
)
);
if ( empty( $buildings ) ) {
return;
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Filter display only.
$selected = isset( $_GET['building_id'] ) ? absint( $_GET['building_id'] ) : 0;
?>
<select name="building_id">
<option value=""><?php esc_html_e( 'All Buildings', 'wp-bnb' ); ?></option>
<?php foreach ( $buildings as $building ) : ?>
<option value="<?php echo esc_attr( $building->ID ); ?>" <?php selected( $selected, $building->ID ); ?>>
<?php echo esc_html( $building->post_title ); ?>
</option>
<?php endforeach; ?>
</select>
<?php
}
/**
* Filter rooms by building in admin list.
*
* @param \WP_Query $query Current query.
* @return void
*/
public static function filter_by_building( \WP_Query $query ): void {
if ( ! is_admin() || ! $query->is_main_query() ) {
return;
}
if ( self::POST_TYPE !== $query->get( 'post_type' ) ) {
return;
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Filter query only.
if ( ! empty( $_GET['building_id'] ) ) {
$query->set(
'meta_query',
array(
array(
'key' => self::META_PREFIX . 'building_id',
'value' => absint( $_GET['building_id'] ),
),
)
);
}
}
/**
* Change title placeholder.
*
* @param string $placeholder Default placeholder.
* @param \WP_Post $post Current post.
* @return string
*/
public static function change_title_placeholder( string $placeholder, \WP_Post $post ): string {
if ( self::POST_TYPE === $post->post_type ) {
return __( 'Enter room name', 'wp-bnb' );
}
return $placeholder;
}
/**
* Get room status options.
*
* @return array<string, string>
*/
public static function get_room_statuses(): array {
return array(
'available' => __( 'Available', 'wp-bnb' ),
'occupied' => __( 'Occupied', 'wp-bnb' ),
'maintenance' => __( 'Maintenance', 'wp-bnb' ),
'blocked' => __( 'Blocked', 'wp-bnb' ),
);
}
/**
* Get status color codes.
*
* @return array<string, string>
*/
public static function get_status_colors(): array {
return array(
'available' => '#00a32a',
'occupied' => '#72aee6',
'maintenance' => '#dba617',
'blocked' => '#d63638',
);
}
/**
* Get building for a room.
*
* @param int $room_id Room post ID.
* @return \WP_Post|null
*/
public static function get_building( int $room_id ): ?\WP_Post {
$building_id = get_post_meta( $room_id, self::META_PREFIX . 'building_id', true );
if ( ! $building_id ) {
return null;
}
return get_post( $building_id );
}
/**
* Get rooms for a building.
*
* @param int $building_id Building post ID.
* @return array<\WP_Post>
*/
public static function get_rooms_for_building( int $building_id ): array {
return get_posts(
array(
'post_type' => self::POST_TYPE,
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => self::META_PREFIX . 'building_id',
'value' => $building_id,
),
),
'orderby' => 'meta_value',
'meta_key' => self::META_PREFIX . 'room_number',
'order' => 'ASC',
)
);
}
}