Decryption key:
gAppointments - Appointment booking addon for Gravity Forms v1.24.0
Version 1.24 ( 12 Sep 2026 )
============================
- Fixed bug: Clicking Cancel, Confirm or Reschedule in the front-end appointments list opened no
modal and scrolled the page to the top instead. Since 1.21, main.js is only enqueued from
gform_enqueue_form_scripts(), which fires on pages containing a booking form. The
[ga_appointments] and [ga_provider_appointments] shortcode pages have no booking form, so
main.js never loaded and the modal handlers were missing. Both shortcodes now enqueue main.js
themselves. Booking-form pages keep the 1.21 load order unchanged.
- Fixed bug: Prevent Double Bookings did not block a client from re-booking a time slot they
already held. The client's email was escaped once for raw SQL interpolation and then escaped
again by $wpdb->prepare(), so the query looked for a literal backslash before every dot. Every
email address contains a dot, so the check never matched. The serialized length pattern
also used [1-9]+, which missed any email or phone whose length contains a zero (10, 20, 30).
- Security: Fixed an SQL injection vulnerability in the date-only double booking check and the
per-client max bookings check, reachable from the public booking form. All three client
matching queries now pass the submitted email and phone to the database as prepared
parameters. Updating is strongly recommended.
- Security: Fixed a reflected XSS vulnerability. When a booking failed validation the form
re-rendered the submitted date, time and cost values into hidden inputs without escaping, so a
crafted request could run script in the visitor's (or a logged-in admin's) browser. All echoed
field values are now escaped.
- Security: The admin appointment status-change action (used on the Appointments list) required
only that the caller be logged in with edit_posts and had no CSRF token. A Contributor, or any
site the admin visited, could cancel or confirm any booking. It now verifies a nonce and
requires edit rights on the specific appointment.
- Security: Front-end cancel, reschedule and "set to pending" actions, and the reschedule
calendar loader, could be triggered cross-site because their nonces were optional or missing.
The nonces are now created, sent and required. Loading another client's reschedule calendar,
or reading another appointment's date/time, is now blocked by an ownership check.
- Security: Client-chosen reschedule dates and times were saved without checking availability, so
a client could move a booking to a closed day or an already-full slot. Reschedules are now
validated against the calendar the same way a new booking is.
- Security: Google Calendar sync no longer disables TLS certificate verification, and no longer
trusts a post ID returned in calendar data to decide which post to write (which could overwrite
an unrelated page). The sync debug log now redacts OAuth tokens and escapes event text before
an admin views it.
- Security: The provider title lookup AJAX action is now registered explicitly for logged-in
users with edit rights, instead of being auto-exposed to logged-out visitors.
- Fixed bug: A trashed provider retained front-end provider access to client contact details and
to cancelling or confirming bookings. Provider lookups now match published providers only.
- Fixed bug: Editing an appointment in the admin could shrink a long custom-slot booking (for
example 08:00-18:00) to the first duration in the list, freeing the slot for double booking.
The stored start time and duration are now always available in the dropdowns, so re-saving
an appointment keeps its existing times.
- Fixed bug: A single-service form whose service field was hidden could not be submitted after
1.20/1.23, because the "Select a service" placeholder left the field empty. The placeholder is
now only shown when more than one service exists. The provider placeholder likewise no longer
overrides a valid "No preference" (0) choice.
- Update: The booking script is now also enqueued directly by the calendar field, so forms
rendered by page builders or loaded after the page still work. A
gappointments_load_scripts_everywhere filter can force it onto every page for AJAX-injected
forms.
- Update: The public calendar AJAX endpoints (service/provider selection, month navigation, time
slots) no longer require a nonce. The nonce added no protection on these read-only, logged-out
endpoints and broke booking pages served from full-page cache after the nonce expired.
- Update: Blank email and phone values are now skipped when matching earlier bookings, so a
client who leaves the phone field empty is never matched against unrelated appointments that
also have no phone number stored.
- Fixed bug: Confirming a Cancel, Confirm or Reschedule from the appointment list pages always
returned "Something went wrong." The server required a security token that the front end never
sent. The same missing token broke loading the Reschedule calendar, saving a provider's work
schedule from the front end, and deleting a service category in the admin. All four now send
the token the server expects.
- Fixed bug: Per-form gAppointments settings (booking category, review page, form translations)
never saved, because the settings page did not render its security token. Once that was fixed,
saving would also have erased every form translation; translations now save correctly and are
kept if missing from the request.
- Fixed bug: Changing an appointment's start time in the admin did not update its end time, so an
appointment moved from 09:00 to 14:00 was stored as 14:00 to 10:00. The end time is now
recalculated on save (see the custom-slot note above for the safeguard against shrinking long
slots).
- Fixed: WordPress 6.7+ "translation loading for the gappointments domain was triggered too early"
notice logged on every request.
- Fixed bug: Booking a service with "Multiple slots selection" enabled ended in a critical error
on PHP 8. The bulk booking routine referenced an undefined constant, so the appointments were
created but the confirmation and notification emails never ran. Multi-slot bookings now
complete normally.
- Fixed bug: Submitting a booking form with unexpected field values (an array where a date or
time was expected) caused a critical error on the public form. All submitted calendar values
are now type-checked before use.
- Fixed bug: The Reschedule window offered days the appointment's own provider does not work,
because it was built from the global schedule instead of that provider's. It now shows the
same availability the booking validation enforces.
- Fixed bug: Editing an appointment in the admin no longer leaves the end time stale when only
the Duration is changed. The stored start time and duration are also kept in the dropdowns, so
re-saving a long custom-slot booking (for example 08:00-18:00) cannot shrink it.
- Fixed bug: Services with no providers assigned showed "Select a provider" with only "No
preference" available, which could block submission on forms where the provider is required.
The placeholder is no longer added when there is nothing to choose.
- Fixed bug: Appointment list bulk actions (Confirm, Cancel, Resend Notifications) acted on any
submitted post ID. They are now limited to appointments the current user may edit.
- Fixed bug: Several plugin files could be loaded twice under different paths, which could cause
a "class already in use" critical error. All internal includes now use one consistent path.
- Fixed bug: The Activity screen printed two of its headings in the wrong place.
- Security: The "add to calendar" download link accepted any ID and is now limited to the signed
in client's own appointment.
- Security: Colour and translation settings are sanitised before being saved and printed.
- Security: Email template fields in the settings screens are escaped correctly for use inside
HTML attributes.
- Update: Removed a runtime PHP configuration change (max execution time) from the booking
submission path.
- Update: Added the Text Domain plugin header and corrected translation calls that could never
be translated, so the plugin can now be translated properly.
- Update: Front-end and admin asset version raised to 1.3.1. main.js changed in 1.20 and
admin.js in 1.22 without a version bump, so browsers could keep serving the old cached files.