Descripción
A multisite-compatible booking plugin for house tours. Features:
- Global available dates & bookings (one booking per slot network-wide)
- Morning and afternoon time slots
- Optional meal add-on for morning tours
- Simple CAPTCHA protection
- Email verification for bookings & subscriptions
- Uses WordPress native wp_mail() for emails
- Admin email selectable from all network users
- All settings sync across network
- QR code generation for booking confirmations
- Optional online payment for verified bookings, through the separately installed EffortLess Easy Online Payment plugin
Instalación
- Upload the plugin folder to
/wp-content/plugins/ - Network Activate the plugin
- Go to Network Admin > Bookings > Settings to configure
- Use shortcodes
[elsbh_booking]or[elsbh_booking_button] - For SMTP configuration, use a dedicated SMTP plugin (e.g., WP Mail SMTP)
Preguntas frecuentes
-
How do I add available dates?
-
Go to Bookings > Available Dates in the WordPress admin and use the date picker to add dates.
-
Can I customize the booking form?
-
The form uses CSS classes that can be styled. The templates are in
public/views/. -
How do I let customers pay for their booking online?
-
Install and activate the separately available EffortLess Easy Online Payment plugin, configure at least one of its payment gateways, then turn on “Enable payment integration” in ELSBH Settings. A verified booking’s confirmation page then shows a “Pay Now” button. This plugin never modifies the payment plugin — it only creates data through its own documented product model and embeds its own checkout shortcode. Which gateways are offered, and in which currency, is controlled entirely by that plugin’s own settings; ELSBH always charges in TWD.
Reseñas
No hay reseñas para este plugin.
Colaboradores y desarrolladores
Este software es de código abierto. Las siguientes personas han contribuido a este plugin.
ColaboradoresTraduce “EffortLess Simple House Booking” a tu idioma.
¿Interesado en el desarrollo?
Revisa el código, echa un vistazo al repositorio SVN o suscríbete al registro de desarrollo por RSS.
Registro de cambios
1.0.89
- Completed the bundled translation files: a template (.pot) and translations for Spanish, Traditional Chinese, Korean, French, Japanese, German, Italian and Brazilian Portuguese.
1.0.88
- The check that recreates missing email templates now runs only for users who can manage bookings, and no longer runs during AJAX requests.
1.0.87
- Database queries on the Bookings screen and in the legacy table migration now bind table and column names with the
%iidentifier placeholder instead of building them into the SQL string. Minimum WordPress version raised to 6.2, which introduced%i.
1.0.86
- Removed the manual
load_plugin_textdomain()call; translations are loaded by WordPress.
1.0.85
- Added the call that loads the bundled translations (French, Spanish, Japanese, Korean, Traditional Chinese), which were not being loaded.
1.0.84
- Renamed the plugin folder and main file to
effortless-simple-house-bookingso they match the text domain.
1.0.83
- Changed the text domain to
effortless-simple-house-bookingin all translatable strings, the plugin header and the bundled translation files.
1.0.82
- Fix: several form fields and boxes (the booking form’s text/email/phone/number fields and date/slot dropdown, the CAPTCHA field, the subscribe form’s email field, the slot-selection options, and the verification/unsubscribe confirmation overlay) had no explicit text color of their own, so they silently inherited the active theme’s body text color — on a theme with light/white body text, they could render nearly invisible text on their fixed light backgrounds. All now set their own explicit text color instead of relying on the theme.
1.0.81
- Security/Fix: an actual, real-database upgrade test from a genuine 1.0.72 install (not just a fresh install) surfaced a bug in the 1.0.78 table-prefix migration — if the one-time table rename ever failed (a hosting account whose database user lacks rename privileges, a locked table, a read-only replica), the plugin silently marked the migration complete anyway, permanently leaving every query targeting a table that was never renamed with no way to recover short of manual database intervention. It now correctly keeps retrying on every future request until the rename actually succeeds.
1.0.80
- Fix: translations updated for all 5 bundled languages (Spanish, French, Japanese, Korean, Traditional Chinese) — around 60 strings added since the previous 1.0.7x feature/security work (payment integration, access control, rate-limit messages, and more) had never been translated; a handful of pre-existing translations that had drifted onto the wrong English source string after a prior merge were also corrected.
- Fix: several text/background color combinations across the admin list tables, the frontend booking form, and the customer-facing booking recap page did not meet WCAG AA’s 4.5:1 contrast minimum (some as low as ~1.7:1) — status badges, success/error messages, and disabled-slot labels were darkened for readability; rows are no longer dimmed with CSS
opacity(which reduced text legibility along with the background).
1.0.79
- Security/Fix: fixed two critical regressions from the 1.0.78 fix round — on a multisite network, the legacy-table cleanup could duplicate and then delete the live, current bookings/subscribers tables (the “old per-site table” name for the main site had become identical to the new global table name); and the payment-reconciliation cron was never actually being scheduled, because the code that registers its interval ran after the code that schedules it. Also: the table-prefix migration now runs immediately for every request rather than waiting for an admin to visit wp-admin after an upgrade; the legacy-total backfill keeps running in small batches until it’s fully caught up, instead of processing only one batch per plugin version; the booking-form rate limit is now only counted on attempts that pass basic validation, so trying a couple of unavailable dates in a row no longer locks a real visitor out for a day; a min/max settings pair is now rejected (with a notice) instead of being silently swapped; deleting an available date no longer gets permanently blocked by an invisible, long-abandoned booking attempt; and several smaller hardening fixes (rate-limit window accounting, a null-safety fix in unsubscribe token validation, admin notification email can no longer be silently blanked by a typo, and more).
1.0.78
- Security/Fix: full code-review fix round covering the database layer, the payment integration, and the admin/public forms. Highlights: the plugin’s own database tables now include the site’s own table prefix (matching WordPress’s own tables), so two WordPress installs sharing one database can no longer read or write each other’s bookings/subscribers/dates; a legacy per-site upgrade path now copies data into the shared tables instead of dropping it; payment confirmation now has a server-side fallback sweep (not only the customer’s browser tab) so a closed tab or a slow gateway can no longer leave a completed payment unreconciled; a booking’s total can no longer be changed once it has already been paid, closing a path that could otherwise orphan the completed payment; a rare stuck state in the payment product creation now self-heals; booking/subscription forms are now rate-limited per IP and per email address; the unsubscribe link now requires an explicit confirmation click rather than acting on a plain GET (so an email client’s link-prescanning can no longer unsubscribe someone automatically); deleting an available date is now refused while it still has active bookings; the admin conflict check when editing a booking now uses the exact same “is this slot taken” rule as the public booking form; several date/time comparisons now use the site’s own timezone instead of UTC; and a handful of smaller hardening and consistency fixes throughout.
- Trimmed older changelog entries to keep this file under the WordPress.org readme length limit.
1.0.77
- Feature: optional online payment for verified bookings through the separately installed EffortLess Easy Online Payment plugin. Turn on “Enable payment integration” in Settings (only available when that plugin is active) and a verified booking’s recap page shows a “Pay Now” button, which creates a one-off product in the payment plugin (using its own documented data model, never by modifying its code) priced at that exact booking’s total in TWD, and embeds its own checkout form. Since the payment plugin confirms payment client-side with no page it navigates back to, this plugin polls its own status endpoint in the background and marks the booking paid — and sends the existing payment-confirmation email — as soon as that payment plugin’s own order record shows the payment completed.
- Removed the “Enable Payment Integration” setting’s dead state from 1.0.76 (it stopped doing anything once the vulnerable self-service payment endpoint was removed); it now does what its label always said, via the integration above.
- Fixed frontend assets (booking form CSS/JS) only loading when a shortcode was found in a page’s raw content; they now also load correctly when a shortcode renders from a widget or a block template.
1.0.76
- Security/Fix: full code-review fix round. An Editor-role user (a role this plugin can grant plugin access to) could redirect the network-wide booking-notification email address, which carries customer name/email/phone, to an address of their choosing; propagating that address network-wide now requires a network administrator. The subscribers admin list and delete action were not scoped to the current site, exposing another site’s subscriber emails; both are now site-scoped, matching how subscription itself already worked. The booking-form CAPTCHA could be solved once and replayed indefinitely; it is now single-use (the expected answer is held in a short-lived transient keyed by a random, single-use challenge id, never derived from WordPress’s own salts) and the subscription forms now require the same CAPTCHA, which they previously skipped entirely.
- Fixed a multisite access-scope gap: switching Roles With Access from Global to Per-site left every site but the current one holding whatever role list Global scope had last pushed to it, until that site’s next version-triggered sync; the switch now re-syncs every site immediately.
- Fixed a booking-slot race condition: two near-simultaneous submissions for the same date/slot could both pass the availability check and both be inserted; the second insert is now detected and rolled back with a “slot already booked” response instead of silently double-booking.
- Fixed missing required-field and email-format validation on booking submission; a request missing a field or supplying an invalid email previously created an unreachable booking that permanently held its slot.
- Removed the “payment success” self-service endpoint, which had no real payment gateway behind it and authenticated only on a token the customer already legitimately holds — any customer could mark their own booking paid. The pricing/settings fields it did not gate are unaffected.
- Fixed the admin hook suffixes used to load this plugin’s admin CSS/JS: they were hardcoded to their English-language form, so on a non-English site the Settings screen’s “Send Test Email” button silently never worked (no localized script was ever enqueued).
- Fixed a double-notification race: two near-simultaneous visits to the same booking-verification link could both send the admin the “booking verified” notification; only the request that actually transitions the booking’s status now sends it.
- “Notify subscribers” on adding a new date is now an explicit, unticked-by-default checkbox instead of firing automatically on every date added, and only emails the current site’s own verified subscribers (previously it queried every site’s subscribers regardless of which site added the date).
- The available-dates cache is now a single network-wide cache entry instead of one per site, matching the fact that the underlying dates/bookings tables are already shared network-wide; previously a booking made on one site could leave another site advertising the same slot as available for up to an hour.
- A subscription to an email already on file but never verified (e.g. the original confirmation email was lost) now rotates the token and resends it, instead of just reporting “already subscribed” with no way to recover.
- Removed a dead code path (
ELSBH_Email::send(), no callers) whose unsubscribe link had no token, and fixed an undefined-variable edge case in the booking-modification email’s error handling. - Moved the subscribers list’s Delete action from running during page render (also meant a refresh re-submitted it) to the same admin_init hook every other admin action here already uses.
- Moved an inline
<style>block out of the booking-recap page into an enqueued stylesheet, and gave every admin screen the standard.wrapmargin override so this plugin’s cards sit centered like the rest of wp-admin. - Removed two files that should never have shipped in the release package: a build script (
languages/po-to-mo.py) and this project’s ownCLAUDE.md. Fixed twophpcs:ignoreannotations that referenced a sniff code from a different toolchain, which silently voided the rest of the annotation.
1.0.75
- Fixed the Donate link, which pointed at the author’s own site instead of the designated donate destination, and added the reusable donate notice on the Settings screen.
- Removed the Plugin URI and Author URI headers, which pointed at the author’s own promotional site.
- Updated “Tested up to” to WordPress 7.1.
- Removed a leftover build script (
languages/po-to-mo.py) and a stray generically-named compiled translation file (languages/messages.mo) that were not needed at runtime.
1.0.74
- Feature: Access Control scope on multisite — choose “Global” (one role selection applied to every site on the network) or “Per site” (each site manages its own). The scope and the global role list are managed by network administrators only; the capability is synced network-wide on save. Defaults to Global.
1.0.73
- Feature: Administrators can choose which user roles may access the booking admin pages — new “Access Control” section on the Settings page (visible only to administrators); selection syncs the
elsbh_manage_bookingscapability across roles. Administrators always have access.
1.0.72
- Feature: Editors can now access all plugin admin pages — new
elsbh_manage_bookingscapability granted to the Administrator and Editor roles on activation and on upgrade; admin menus and action handlers gated on it instead ofmanage_options
1.0.71
- Fix: Slot selection broken after moving JS to separate file — jQuery .data() returns integer 1, not string ‘1’; changed strict === to loose == comparison
1.0.70
- Fix: dates-page add/delete handlers moved to admin_post/admin_init hooks (same fix as bookings in v1.0.62) — prevents state mutation after headers sent and eliminates delete-by-GET CSRF risk
- Fix: booking-recap double DOCTYPE removed — template owns the full HTML document
- Fix: notify_subscribers() loop wrapped in try/finally to guarantee restore_current_blog() on exception
- Fix: send_verification() blog restore moved into finally block
- Fix: handle_edit_booking() now validates booking exists and is not in the past (server-side enforcement of UI restriction)
- Fix: pagination/sortable helpers extracted to ELSBH_Admin::pagination_links() and ELSBH_Admin::sortable_column() — removes duplication between bookings-page and dates-page
- Fix: booking-form slot-toggle JS moved to dedicated public/js/booking-form-init.js — replaces inline script block, enables browser caching
1.0.69
- Fix: Booking recap page no longer shows theme header/footer — renders a minimal standalone HTML page with only the plugin CSS
1.0.68
- Fix: Removed {name} from subscription_verification template — subscribers only provide email, name is never collected
1.0.67
- Feature: Added {name} to subscription_verification template; added {booking_link} to admin_notification, booking_cancellation, booking_modified_admin, and post_visit_thanks templates
1.0.66
- Fix: All email link placeholders ({link}, {booking_link}, {review_link}) revert to plain URLs — anchor text is set directly in the template editor
1.0.65
- Fix: All email link placeholders now use descriptive anchor text — {link} shows “Click here to verify” / “View available dates”, {booking_link} shows “View your booking details”, {review_link} shows “this link” — raw URLs no longer visible in email body
1.0.64
- Fix: {review_link} placeholder now expands to a plain clickable URL instead of the full “We would love your feedback” sentence — surrounding copy belongs in the email template
1.0.63
- Fix: Subscription insert failure on upgraded sites — auto-run DB schema migrations on version change via maybe_update_db_schema() (adds missing unsubscribe_token column without requiring deactivate/reactivate)
1.0.62
- Fix: Admin booking row actions (verify, mark_paid, cancel, send_thanks, edit) moved to admin_init / admin_post hooks — fires before HTML output so redirect works; replaced empty-page issue with proper admin notice at top of bookings page
1.0.61
- Fix: Admin action redirects now include show_cancelled=1 so cancelled bookings remain visible after any action
1.0.60
- Fix: Remaining Plugin Check DirectDB warnings — esc_sql() on $order_dir, $column; suppress comment on $where_sql (built from wpdb->prepare fragments)
1.0.59
- Fix: Removed load_plugin_textdomain() calls — WordPress 4.6+ auto-loads translations; Plugin Check warning resolved
- Fix: All table name variables wrapped with esc_sql() to satisfy Plugin Check DirectDB sniff
1.0.58
- Security: Add current_user_can() check to admin booking edit POST handler (C1)
- Fix: Cancel action redirects with notice when booking is already cancelled (C2)
- Fix: Booking recap page now renders inside the active theme (get_header/get_footer) (C3)
- Fix: Past dates rejected in process_booking() even if still in available_dates (I2)
- Fix: Subscribers table gets UNIQUE KEY (email, site_id) to prevent race-condition duplicates (I3)
- Fix: Plugin assets enqueued only after token validation in handle_verification() and handle_unsubscribe() (I5)
- Fix: remove_action(‘wp_mail_failed’) moved into finally block in send_booking_modified() (I6)
- Fix: (int) casts on DB values in backfill_booking_totals(); skip rows with zero persons (I7)
- Fix: Admin email not propagated to network sites if sanitize_email() returns empty string (I8)
- Fix: elsbh_message removed from URL after display via history.replaceState (I1)
- Fix: mark_past_bookings_completed() guarded by daily transient — runs at most once per day (M1)
- Fix: Redundant elsbh_load_classes() call removed from activation hook (M4)
- Security: CAPTCHA range widened to 1–50 and per-request nonce added to hash (M5)
- Fix: get_404_template() used instead of get_template_part(‘404’) for block-theme compatibility (M6)
- Security: Separate unsubscribe_token column added; verification token no longer reused in unsubscribe links (M7)
- Fix: Deprecated $GLOBALS[‘phpmailer’] access removed; rely on wp_mail_failed hook exclusively (M8)
- Fix: clean_email_content() HTML nesting fix applied only to Gutenberg-generated content (M3)
Older changelog entries (1.0.56 and earlier, back to 0.9.13) have been trimmed from this file to stay within the readme length limit. See the plugin’s git history for the full history.
