ATX BusyRooms Bridge
Reworked Busyrooms wordpress plugin - Redirect user constructed URL
Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/siko001/atx-busyrooms/archive/refs/heads/main.zipA reusable WordPress integration layer for the BusyRooms IBE v3.5 advanced search redirect. The plugin deliberately contains no front-end design. Themes and blocks own the form markup; this plugin owns provider settings, validation, room mapping, and the final redirect URL.
Requirements
- WordPress 6.2+
- PHP 8.1+
- ACF PRO is optional. When active, the plugin adds a BusyRooms Room ID field to configured Room post types.
Configuration
Activate the plugin and open Settings → BusyRooms. Site connection, room/campaign mapping, and search limits are organized into separate WordPress-style tabs.
Configure the values supplied by BusyRooms:
- Website ID (required)
- Hotel/establishment ID(s)
- Optional destination code(s)
- Language and currency
- Optional default rate plans and meal plans
- Optional marketing and affiliate campaign codes
- Occupancy limits used by validation and custom blocks
- WordPress Room post type slug(s)
The Website ID, Hotel ID, currency, and other account values belong to each WordPress installation. Configure them separately on each hotel site.
Room IDs normally belong to individual Room posts. The plugin registers the ACF field name atx_busyrooms_room_id for every post type listed in Room post type(s). The optional global Default Room ID setting is only a fallback.
Building a search block
Post a form to the plugin's redirect handler. The block never needs to know the BusyRooms Website ID or Hotel ID.
<?php $limits = atx_busyrooms_settings(); ?>
<form method="post" action="<?= esc_url(atx_busyrooms_form_action()); ?>" target="<?= esc_attr(atx_busyrooms_form_target()); ?>">
<?= atx_busyrooms_form_hidden_fields(get_the_ID()); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<label>
Check in
<input type="date" name="date_from" required>
</label>
<label>
Check out
<input type="date" name="date_to" required>
</label>
<label>
Adults
<select name="adults[]">
<?php for ($i = 1; $i <= $limits['max_adults_per_room']; $i++) : ?>
<option value="<?= esc_attr((string) $i); ?>"><?= esc_html((string) $i); ?></option>
<?php endfor; ?>
</select>
</label>
<!-- One nested group per room. Empty groups are valid. -->
<select name="children_ages[0][]">
<option value="">No child</option>
<option value="5">Age 5</option>
</select>
<input type="text" name="promo_code" autocomplete="off">
<button type="submit">Check availability</button>
</form>
For multiple rooms, add one adults[] value and one children_ages[ROOM_INDEX][] group per room. The handler converts these to BusyRooms' hyphen-delimited multi-room format.
The public redirect handler does not accept Website IDs, Hotel IDs, campaign settings, or raw Room IDs from the browser. It only derives room mapping from a published Room post supplied as context_post_id. A server-rendered block can use atx_busyrooms_booking_url() when it needs a trusted programmatic override.
Validation failures return the guest to the referring page with ?busyrooms_error=ERROR_CODE. A block may translate that code into an inline message.
PHP API
Build a URL directly:
$url = atx_busyrooms_booking_url([
'date_from' => '2026-09-16',
'date_to' => '2026-09-18',
'adults' => [2, 1],
'children_ages' => [[], [4, 3]],
'promo_code' => 'SUMMER',
], get_the_ID());
if (! is_wp_error($url)) {
echo esc_url($url);
}
Other helpers:
$settings = atx_busyrooms_settings();
$roomIds = atx_busyrooms_room_ids(get_the_ID());
$formAction = atx_busyrooms_form_action();
$formTarget = atx_busyrooms_form_target();
Extension points
atxBusyRooms/settingsatxBusyRooms/admin_capabilityatxBusyRooms/register_settings_fieldsatxBusyRooms/room_post_typesatxBusyRooms/room_meta_keyatxBusyRooms/room_idsatxBusyRooms/query_parameters(receives the immutableSearchRequestobject)atxBusyRooms/base_urlatxBusyRooms/booking_urlatxBusyRooms/redirect_input
Do not put agency usernames or passwords into a public search form or URL. The integration intentionally does not support those credential parameters.
Per-site behavior belongs in a child theme or a small site plugin. For example, a site can append a provider parameter without changing this shared plugin:
add_filter('atxBusyRooms/query_parameters', static function (array $parameters): array {
$parameters['customProviderParameter'] = 'site-specific-value';
return $parameters;
});
The same approach can change the Room post type, derive room IDs from another data source, or adjust the final URL. This keeps updates to ATX BusyRooms Bridge safe across every hotel site.
An extension that needs additional admin fields can hook atxBusyRooms/register_settings_fields. It should register a separate, prefixed option in the supplied option group and add its fields to the supplied Room & Campaigns tab page slug. Keeping extension data in a separate option ensures the core plugin never stores unknown or unsanitized settings.
Releases and updates
The plugin checks public releases from siko001/atx-busyrooms through WordPress' safe HTTP API and only accepts the specifically named atx-busyrooms.zip asset from GitHub. An update is downloaded through WordPress and must match the release's SHA-256 checksum before extraction. Missing, malformed, or mismatched checksums fail closed. Failed checks are cached briefly and successful checks for six hours.
The quality workflow lints every PHP file on PHP 8.1 and 8.4. To publish an update, push a semantic tag such as v1.1.0. The release workflow validates and stamps the version, lints the source, builds an installable single-root ZIP, tests the archive, produces a SHA-256 checksum, and attaches both files to the GitHub Release.
Run the repeatable WordPress integration checks from an installation where the plugin is active:
wp eval-file wp-content/plugins/atx-busyrooms/tests/integration.php