{"id":319887,"date":"2026-09-22T20:34:18","date_gmt":"2026-09-22T20:34:18","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/gather-grove-booking\/"},"modified":"2026-09-23T15:57:50","modified_gmt":"2026-09-23T15:57:50","slug":"gather-grove-booking","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/gather-grove-booking\/","author":23506124,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.178.1","stable_tag":"1.178.1","tested":"7.1.2","requires":"6.8","requires_php":"8.2","requires_plugins":null,"header_name":"Gather Grove Booking","header_author":"Rob Hewitt \/ Gather Grove","header_description":"Class scheduling and booking for studios, wellness centers, and community programs.","assets_banners_color":"2a4436","last_updated":"2026-09-23 15:57:50","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/gathergrove.io\/docs\/booking","header_author_uri":"https:\/\/gathergrove.io","rating":0,"author_block_rating":0,"active_installs":0,"downloads":79,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.178.1":{"tag":"1.178.1","author":"gturtle108","date":"2026-09-23 15:57:50","revision":3709630},"1.95.9":{"tag":"1.95.9","author":"gturtle108","date":"2026-09-22 20:33:59","revision":3708059}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3708060,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3708060,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3709617,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3709617,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.178.1","1.95.9"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3709633,"resolution":"1","location":"assets","locale":"","width":1456,"height":730},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3709633,"resolution":"2","location":"assets","locale":"","width":1456,"height":730},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3709633,"resolution":"3","location":"assets","locale":"","width":1456,"height":730},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3709633,"resolution":"4","location":"assets","locale":"","width":1456,"height":730},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3709633,"resolution":"5","location":"assets","locale":"","width":1456,"height":730},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3709633,"resolution":"6","location":"assets","locale":"","width":1456,"height":730}},"screenshots":{"1":"The public schedule \u2014 month view, filterable by category, instructor and location, built as an Elementor widget.","2":"Sessions \u2014 every scheduled occurrence with capacity, instructor, location and status, with row actions.","3":"Packages &amp; Memberships \u2014 class packs, passes and monthly memberships on the public purchase page.","4":"Waiver Compliance \u2014 who has signed the current version of each waiver and who still owes one, with CSV export and paper-signature recording.","5":"Instructors \u2014 each instructor is a profile the schedule and class pages link to.","6":"Settings \u2014 currency, timezone, formats and page URLs, plus the Booking, Notifications, Brand, Email, Payments and Integrations tabs."}},"plugin_section":[],"plugin_tags":[8132,8162,76538,10449,10311],"plugin_category":[40],"plugin_contributors":[282128],"plugin_business_model":[],"class_list":["post-319887","plugin","type-plugin","status-publish","hentry","plugin_tags-appointments","plugin_tags-class-booking","plugin_tags-elementor","plugin_tags-studio","plugin_tags-yoga","plugin_category-calendar-and-events","plugin_contributors-gturtle108","plugin_committers-gturtle108"],"banners":{"banner":"https:\/\/ps.w.org\/gather-grove-booking\/assets\/banner-772x250.png?rev=3709617","banner_2x":"https:\/\/ps.w.org\/gather-grove-booking\/assets\/banner-1544x500.png?rev=3709617","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/gather-grove-booking\/assets\/icon-128x128.png?rev=3708060","icon_2x":"https:\/\/ps.w.org\/gather-grove-booking\/assets\/icon-256x256.png?rev=3708060","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/gather-grove-booking\/assets\/screenshot-1.png?rev=3709633","caption":"The public schedule \u2014 month view, filterable by category, instructor and location, built as an Elementor widget."},{"src":"https:\/\/ps.w.org\/gather-grove-booking\/assets\/screenshot-2.png?rev=3709633","caption":"Sessions \u2014 every scheduled occurrence with capacity, instructor, location and status, with row actions."},{"src":"https:\/\/ps.w.org\/gather-grove-booking\/assets\/screenshot-3.png?rev=3709633","caption":"Packages &amp; Memberships \u2014 class packs, passes and monthly memberships on the public purchase page."},{"src":"https:\/\/ps.w.org\/gather-grove-booking\/assets\/screenshot-4.png?rev=3709633","caption":"Waiver Compliance \u2014 who has signed the current version of each waiver and who still owes one, with CSV export and paper-signature recording."},{"src":"https:\/\/ps.w.org\/gather-grove-booking\/assets\/screenshot-5.png?rev=3709633","caption":"Instructors \u2014 each instructor is a profile the schedule and class pages link to."},{"src":"https:\/\/ps.w.org\/gather-grove-booking\/assets\/screenshot-6.png?rev=3709633","caption":"Settings \u2014 currency, timezone, formats and page URLs, plus the Booking, Notifications, Brand, Email, Payments and Integrations tabs."}],"raw_content":"<!--section=description-->\n<p>Gather Grove Booking runs the schedule for people who teach \u2014 yoga and fitness studios, dance and martial arts schools, music teachers, pottery and craft studios, wellness practitioners, and community programs. Design your booking pages visually with Elementor, take drop-in and appointment bookings, and accept card payments with Stripe.<\/p>\n\n<p>The free version is fully functional for running a real studio:<\/p>\n\n<ul>\n<li><strong>Classes &amp; sessions<\/strong> \u2014 recurring schedules, capacity limits, multiple locations and rooms.<\/li>\n<li><strong>Online booking<\/strong> \u2014 Elementor booking-form and schedule widgets your clients use to reserve a spot.<\/li>\n<li><strong>Appointments<\/strong> \u2014 bookable service slots with availability windows and optional deposits.<\/li>\n<li><strong>Waivers &amp; liability forms<\/strong> \u2014 collect a real signature as part of booking, then see your whole roster at a glance: who has signed the current version, who signed an older one, whose signature has expired, and who has never signed at all. Send reminders by hand, record a paper signature, or export the lot to CSV.<\/li>\n<li><strong>Passwordless sign-in<\/strong> \u2014 students can sign in with a link emailed to them instead of a password, so nobody is locked out of a booking by a password they never set. Optional, and you choose whether your site offers passwords, magic links, or both.<\/li>\n<li><strong>Waitlists<\/strong> \u2014 clients can join a waitlist when a class is full, and open spots are automatically offered to the next person in line.<\/li>\n<li><strong>Flexible schedules<\/strong> \u2014 a class can meet on multiple recurring schedule blocks (e.g. Mon\/Wed\/Fri at different times).<\/li>\n<li><strong>Bulk attendance marking<\/strong> \u2014 mark a whole roster present in one action.<\/li>\n<li><strong>Payments<\/strong> \u2014 accept cards through Stripe for drop-in bookings.<\/li>\n<li><strong>Client accounts<\/strong> \u2014 a self-service dashboard for bookings and profile.<\/li>\n<li><strong>Attendance<\/strong> \u2014 front-desk and instructor check-in.<\/li>\n<li><strong>Instructors &amp; locations<\/strong> \u2014 profiles, assignments, and per-location schedules.<\/li>\n<\/ul>\n\n<h4>Who it's for<\/h4>\n\n<ul>\n<li><strong>Yoga, pilates and fitness studios<\/strong> \u2014 recurring drop-in classes, capacity limits, waitlists, and a signed waiver on file before anyone steps on a mat.<\/li>\n<li><strong>Dance and martial arts schools<\/strong> \u2014 several weekly schedule blocks on one class, per-location rooms, and front-desk check-in.<\/li>\n<li><strong>Music teachers and schools<\/strong> \u2014 appointment-style lessons with availability windows and optional deposits, alongside recurring group classes.<\/li>\n<li><strong>Pottery, craft and maker studios<\/strong> \u2014 small capacities, multiple rooms, and a roster you can mark present in one action.<\/li>\n<li><strong>Wellness practitioners<\/strong> \u2014 one-to-one appointments shown in the visitor's own timezone, with a self-service client dashboard.<\/li>\n<li><strong>Community programs and co-ops<\/strong> \u2014 free and comp bookings with no payment gateway required, and waiver compliance across a whole roster.<\/li>\n<\/ul>\n\n<h4>Built for Elementor<\/h4>\n\n<p>The client-facing pages (booking form, class schedule, appointment booking, client dashboard) are Elementor widgets, so you design them visually alongside the rest of your site. <strong>The free Elementor plugin is required<\/strong> to display these on your site. Elementor Pro is <em>optional<\/em> \u2014 it unlocks dynamic tags and one-click Theme Builder starter pages, but is not required for booking to work.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin connects to the following third-party services.<\/p>\n\n<p><strong>Stripe<\/strong> \u2014 used to process card payments after you connect a Stripe account and a client pays for a booking or appointment. The booking and payment details required to create the charge (amount, currency, and related metadata) are sent to Stripe at payment time. Stripe.js is loaded from Stripe's servers on pages that display a payment form, as required for PCI compliance.\nTerms of service: https:\/\/stripe.com\/legal \u2014 Privacy policy: https:\/\/stripe.com\/privacy<\/p>\n\n<p><strong>Google Maps<\/strong> \u2014 used by the optional Location \"Map Embed\" and \"Directions Link\" Elementor dynamic tags. If you place the Map Embed tag on a page, the visitor's browser loads an embedded map from google.com for the location's address (Google receives the visitor's IP address and the studio address, as with any embedded map). The Directions Link tag only builds a link to google.com\/maps containing the studio address; nothing is sent unless the visitor clicks it. No data is sent from your server, and neither tag is active unless you add it to a page.\nTerms of service: https:\/\/policies.google.com\/terms \u2014 Privacy policy: https:\/\/policies.google.com\/privacy<\/p>\n\n<p><strong>Zoom<\/strong> \u2014 used to automatically create, update, and delete Zoom meetings for virtual class and appointment sessions, only after you connect your own Zoom Server-to-Server OAuth app under Settings \u2192 Integrations. When a virtual booking is confirmed (and on reschedule or cancellation), your server sends the session's topic, start time, duration, timezone, and the host's email address to api.zoom.us \/ zoom.us using your own credentials. Nothing is sent unless you enable the integration, and visitors' browsers never contact Zoom through this plugin.\nTerms of service: https:\/\/explore.zoom.us\/en\/terms\/ \u2014 Privacy policy: https:\/\/explore.zoom.us\/en\/privacy\/<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate the free <strong>Elementor<\/strong> plugin (Plugins \u2192 Add New \u2192 search \"Elementor\").<\/li>\n<li>Upload the <code>gather-grove-booking<\/code> folder to <code>\/wp-content\/plugins\/<\/code>, or install the zip via Plugins \u2192 Add New \u2192 Upload Plugin.<\/li>\n<li>Activate <strong>Gather Grove Booking<\/strong> through the Plugins screen.<\/li>\n<li>Go to <strong>Gather Grove \u2192 Settings<\/strong> to configure your studio, then connect Stripe under the Payments tab.<\/li>\n<li>Use <strong>Gather Grove \u2192 Getting Started<\/strong> to create your booking and schedule pages.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20elementor%3F\"><h3>Do I need Elementor?<\/h3><\/dt>\n<dd><p>Yes \u2014 the free Elementor plugin is required to display the booking form, schedule, and other client-facing pages. The admin and booking engine run without it, but your visitors need the Elementor widgets to book.<\/p><\/dd>\n<dt id=\"do%20i%20need%20elementor%20pro%3F\"><h3>Do I need Elementor Pro?<\/h3><\/dt>\n<dd><p>No. Elementor Pro is optional. It adds dynamic tags and automatic Theme Builder starter pages, but every booking feature works with the free Elementor plugin.<\/p><\/dd>\n<dt id=\"how%20are%20payments%20processed%3F\"><h3>How are payments processed?<\/h3><\/dt>\n<dd><p>Card payments are processed by Stripe. You connect your own Stripe account; Gather Grove never stores card numbers on your site.<\/p><\/dd>\n<dt id=\"does%20it%20work%20without%20a%20payment%20gateway%3F\"><h3>Does it work without a payment gateway?<\/h3><\/dt>\n<dd><p>Yes. You can run free classes, complimentary (comp) bookings, and offline\/invoice payments without connecting Stripe.<\/p><\/dd>\n<dt id=\"will%20my%20data%20be%20deleted%20if%20i%20uninstall%3F\"><h3>Will my data be deleted if I uninstall?<\/h3><\/dt>\n<dd><p>No. Uninstalling leaves your studio data intact by default so you can reinstall safely. You can opt in to full data deletion under Settings \u2192 General \u2192 Danger Zone.<\/p><\/dd>\n<dt id=\"can%20i%20style%20the%20widgets%20using%20my%20real%20classes%20in%20the%20elementor%20editor%3F\"><h3>Can I style the widgets using my real classes in the Elementor editor?<\/h3><\/dt>\n<dd><p>Yes. Gather Grove widgets show a styleable sample by default in the Elementor editor. To style against your actual content, open the widget's Content tab, find the \"Editor Preview\" section, and set \"Preview in editor\" to \"Real data\" (for the Class Card widget, also pick a specific class). The editor canvas then renders your real class so you can style it without switching to the live page. This is rolling out across the widgets \u2014 the Class Card and Sessions List widgets have it today, with more on the way. It only affects the editor; your published page always shows live data.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.178.1<\/h4>\n\n<ul>\n<li>Maintenance: the WordPress.org build no longer includes a file that only the paid membership-applications screen uses. Nothing changes for your studio.<\/li>\n<\/ul>\n\n<h4>1.178.0<\/h4>\n\n<ul>\n<li>New: birthday greetings can go out at the start of each client's birthday month instead of on the day. Choose \"At the start of their birthday month\" under Settings &gt; Emails &gt; Automated &gt; Birthday Greeting. Everyone with a birthday that month is greeted on the 1st, and anyone who adds their month later is greeted the next morning. Each client still gets one birthday email a year.<\/li>\n<li>New: in birthday-month mode, the Birthday field on My Account becomes a simple month picker. Many people are happier sharing a month than a full date. Birthdays already on file count automatically. Staff can set a month on the client's Profile tab.<\/li>\n<li>New: the {birthday_month} placeholder for the Birthday Greeting template.<\/li>\n<li>New: promo codes can limit each client to a number of uses per calendar year instead of ever, and can be restricted to the client's birthday month. Together they make one shared \"free class in your birthday month\" code safe to publish.<\/li>\n<li>Fixed: saving your profile on My Account no longer erases your address. The form doesn't show the address fields, and each save was clearing them.<\/li>\n<\/ul>\n\n<h4>1.177.3<\/h4>\n\n<ul>\n<li>Fixed: the Class Discovery widget could overload a slow server. Each time a visitor changed a filter or typed another letter in the search box, the widget dropped its previous request and sent a new one \u2014 but the server finished every dropped request anyway, so they piled up. The widget now sends one request at a time, follows it with a single request for the latest filters, and waits longer between searches when the server is answering slowly. Results and links are unchanged.<\/li>\n<\/ul>\n\n<h4>1.177.2<\/h4>\n\n<ul>\n<li>Fixed: approving a free membership with \"Approve a membership\" (or the founding-cohort import) now gives them the membership straight away, the same as approving a request they made. Before, it only marked them approved, so they held no membership and, if emailed, were asked to complete a purchase for a free plan. A rate you agreed with them is never waived.<\/li>\n<li>Fixed: the \"Approve a membership\" card now says what happens for free and paid memberships, marks free memberships in the list, and confirms when a free membership has been granted.<\/li>\n<\/ul>\n\n<h4>1.177.1<\/h4>\n\n<ul>\n<li>Fixed: Membership Requests no longer tells staff that approving always emails a link to pay. Each waiting request or application now says what Approve will do: a free membership is granted straight away; a paid request emails a link to complete the purchase; a paid application emails the applicant that they are approved so they can buy it. Nobody is charged by approving.<\/li>\n<\/ul>\n\n<h4>1.177.0<\/h4>\n\n<ul>\n<li>Added: Membership Requests now shows membership applications sent through an application form, next to the requests made on the site, so everyone waiting for a decision is on one page. Each shows who applied, for which membership, when, how long they have been waiting, and a link to their full application. Approve or Decline works exactly as it does in Forms \u2014 the applicant gets the same email, and a free membership is granted the same way. The menu count includes them. Needs Gather Grove Forms 1.30.0 or newer; staff also need permission to manage forms to see and decide applications.<\/li>\n<\/ul>\n\n<h4>1.176.0<\/h4>\n\n<ul>\n<li>Fixed: a membership switched on by the daily payment check (when Stripe's notification was missed or late) now sends the member their \"Purchase confirmed\" receipt and is recorded as a purchase \u2014 once, whichever check notices the payment first.<\/li>\n<li>Fixed: a member's receipt is no longer skipped when the payment is confirmed while a staff member is logged in. Gifts are still receipted only to the person who bought them.<\/li>\n<li>Fixed: class packs paid with a card that needed extra verification now send the buyer a receipt.<\/li>\n<li>Fixed: a membership agreement form can no longer be signed on someone else's login. If the email typed on the agreement isn't the signed-in person's, the form asks them to sign in as that person instead of filing the signature to the wrong account. Parents signing for a child from the family link are unaffected.<\/li>\n<\/ul>\n\n<h4>1.175.0<\/h4>\n\n<ul>\n<li>Fixed: approving an application now grants a free package to the applicant named by the email on the form, not to whoever happened to be logged in on the device it was filled in on. If that email has no account yet, nothing is granted to anyone (as for any guest applicant).<\/li>\n<li>Fixed: members whose card payment is confirmed after checkout now get their \"Purchase confirmed\" receipt. Every membership is receipted exactly once, however it activates; gifts are still receipted to the giver, and renewals are not receipted as purchases.<\/li>\n<li>Fixed: a membership activated after checkout is now recorded as a purchase in the activity stream, so purchase history and tier-based member tagging see it.<\/li>\n<\/ul>\n\n<h4>1.174.2<\/h4>\n\n<ul>\n<li>Fixed: a package's \"What's included\" lines (and every other list the plugin stores as JSON) kept accented letters, dashes and other non-ASCII characters intact. An em dash used to be saved as the four characters \"u2014\" and show that way in the shop.<\/li>\n<\/ul>\n\n<h4>1.174.1<\/h4>\n\n<ul>\n<li>Security: the instructor profile's intro-video embed is now filtered through wp_kses at output (an iframe allow-list on top of the plugin's widget allow-list).<\/li>\n<li>Changed: the JSON-LD class schema is encoded at the echo.<\/li>\n<\/ul>\n\n<h4>1.174.0<\/h4>\n\n<ul>\n<li>Fixed: signing in through the Login widget from a link that names a page \u2014 \"sign in to continue\" \u2014 now takes you to that page. It used to send everyone to their usual page (My Account, the Instructor Dashboard, or home), so a member invited to a community room who already had an account accepted, signed in, and landed on My Account instead of the room. Only pages on your own site are followed; anything else still goes to the usual page.<\/li>\n<\/ul>\n\n<h4>1.173.0<\/h4>\n\n<ul>\n<li>Fixed: a demo fixture (seeded instructor, its linked user, or seeded member) is never mailed \u2014 judged by record, not by domain, and regardless of Demo Mode, booking scope, or the release filter.<\/li>\n<\/ul>\n\n<h4>1.172.0<\/h4>\n\n<ul>\n<li>Fixed: co-teachers did not get the pre-class roster email listing who is coming. If the lead teacher had no email address saved, nobody got it \u2014 the roster was dropped silently, with nothing in the plugin to say so. Everyone teaching a session now gets their own copy.<\/li>\n<\/ul>\n\n<h4>1.171.3<\/h4>\n\n<ul>\n<li>Fixed: if you renamed Appointments to your own word under Settings \u2192 Custom Labels, the word never appeared anywhere \u2014 the Services menu ignored it. It now uses your wording, the same way Classes and Instructors already did.<\/li>\n<li>Fixed: the Gather Grove dashboard tile always said \"Today's classes\", even for studios who call them events, gatherings or ceremonies. It now uses your own word.<\/li>\n<\/ul>\n\n<h4>1.171.2<\/h4>\n\n<ul>\n<li>Fixed: a class scheduled for a different length than usual showed its usual length on the schedule. If you ran a 90-minute class for two hours at a special event, or trimmed one to 75 minutes for the day, the booking, the times and the reminder email were all correct \u2014 but the schedule, the class list and the pop-up all still said 90 minutes. Every view now reads the length from the session itself.<\/li>\n<\/ul>\n\n<h4>1.171.1<\/h4>\n\n<ul>\n<li>Fixed: cancelling a booking that was paid with a pack could fail to give the session back. On packs where the booking had never been counted, the database refused the whole update, so the member's remaining sessions were not credited. Sessions are now always restored.<\/li>\n<li>Changed: the public schedule and class-grid renderers close their output buffer on the same straight-line path as every other buffer in the plugin; the exception path discards it explicitly.<\/li>\n<\/ul>\n\n<h4>1.170.4<\/h4>\n\n<ul>\n<li>Fixed: payments made for a child showed up in Reports with the Client column blank. A family membership is bought for the child, and a child has no login of their own, so there was no name to print \u2014 the money was always counted, it just had nobody's name against it. Rows now read the child's name, with a new \"Paid By\" column naming the parent, in the transactions list and the CSV export alike.<\/li>\n<li>Fixed: a parent's own Purchases tab said \"No transactions found for this client\" even after they had paid, because their children's payments were filed under the children. The tab now shows everything the household has paid, with a Member column saying who each payment was for.<\/li>\n<\/ul>\n\n<h4>1.170.3<\/h4>\n\n<ul>\n<li>Fixed: nobody could create an account from the sign-up pop-up. If you ask new members for a phone number \u2014 which is the default \u2014 the pop-up never showed a phone box but still refused to continue without one, so anyone signing up from a class page or an RSVP hit \"Please enter a phone number\" with nowhere to type it. The box is now there. The separate Login and Register pages were never affected.<\/li>\n<\/ul>\n\n<h4>1.170.2<\/h4>\n\n<ul>\n<li>Fixed: two membership and household lookups rebuilt so the WordPress.org security scanner can verify them. No change to what they return.<\/li>\n<\/ul>\n\n<h4>1.170.1<\/h4>\n\n<ul>\n<li>Changed: updated the bundled Gather Grove core to 0.55.0.<\/li>\n<\/ul>\n\n<h4>1.170.0<\/h4>\n\n<ul>\n<li>Fixed: a studio that started using Pulse after it had already been selling could never get its membership history across. Booking has always told Pulse about a purchase as it happens, but it had no way to hand over the ones that came before \u2014 so \"everyone on the $99 tier\" or \"when someone buys a membership\" simply had nothing to work with, and the import said it had finished. Past purchases, memberships and renewals now come across with the rest of the history.<\/li>\n<li>Fixed: a renewal now arrives as its own event on the day it was paid, rather than everything folding back onto the day the member first joined. Without that, a member who has paid every month since 2023 looked like they last bought something two years ago \u2014 which is exactly the kind of member a win-back campaign should never be mailing.<\/li>\n<li>Fixed: purchases imported from another platform came across dated to the day the import ran and priced at zero. They now carry the date and price they actually had.<\/li>\n<li>Added: Booking now tells Pulse which kinds of past activity it cannot hand over, and why, so \"the import finished\" stops being mistaken for \"you have everything\". Past failed and recovered payments are the honest gap \u2014 Booking records where a payment ended up, not the moment it went wrong, so those can only be captured from now on.<\/li>\n<\/ul>\n\n<h4>1.169.0<\/h4>\n\n<ul>\n<li>Fixed: if you asked for access to a members-only class while booking for someone in your household, the access was granted to <em>you<\/em> instead of to them \u2014 so the studio approved it, you were told you were approved, and the class still turned you away. The request now asks who it is for, and the approval lands on that person.<\/li>\n<li>Added: a \"Who is this access for?\" choice on the request panel, listing exactly the people you are allowed to book for. Anyone who already has the membership, or already has a request waiting on it, is left off.<\/li>\n<li>Fixed: emails about a membership request now go to whoever asked for it. A request made for a child or a family member without their own login used to resolve to an address that did not exist, and the approval email quietly went nowhere.<\/li>\n<li>Fixed: the studio's request email now names the person the membership is for, not just the person who asked \u2014 approving puts the membership on their account.<\/li>\n<li>Fixed: after your request was approved, an adult family member you book for could disappear from the checkout you had just been told to complete.<\/li>\n<\/ul>\n\n<h4>1.168.0<\/h4>\n\n<ul>\n<li>Fixed: a parent could see a family member in the booking form's \"Who is this for?\" list, choose them, and be told \"You don't have permission to book for that person\". The list showed everyone in the household; the booking check allowed a narrower set. They now come from the same place, so the list can never again name somebody the booking is going to refuse.<\/li>\n<li>Fixed: an adult you had granted \"Can manage children\" got no \"Who is this for?\" list at all, so the one person that setting exists to help had no way to say which child they were booking. They now see the children they are allowed to book for.<\/li>\n<li>Added: supported adults. Someone with their own account can now say that the adults in their household may book classes and appointments for them \u2014 for a self-directed or day-programme participant, an adult child, or anyone else who has their own login and would rather a parent or caregiver did the booking. Turn it on from the Household section of your account, or ask the studio to set it up.<\/li>\n<li>Added: studios can record the arrangement from Clients \u2192 Household, with a new \"Booked for by household\" column. The person can always turn it off again themselves.<\/li>\n<li>Changed: the household roster now says why you cannot book for a linked adult, on the roster where you added them, instead of leaving you to find out at checkout.<\/li>\n<li>Note: only the person themselves or the studio can turn this on \u2014 a payer cannot grant it to themselves over another adult. Memberships remain non-transferable: a supported adult needs their own pass, which a caregiver can buy and use on their behalf.<\/li>\n<\/ul>\n\n<h4>1.167.0<\/h4>\n\n<ul>\n<li>Fixed: booking and course confirmations no longer promise \"a full refund\" for cancelling. Cancelling has never returned money automatically \u2014 refunds have always been the studio's own decision \u2014 so the email was committing you to something the software does not do.<\/li>\n<li>Fixed: the cancellation email no longer tells a member that a named amount \"will be returned to your original payment method within 5-10 business days\". It now states what they paid and leaves the refund to you.<\/li>\n<li>Changed: confirmations now show YOUR Cancellation Policy from Settings, the same words shown at checkout. Previously the emails ignored it and stated their own rule, so a studio could advertise one policy and have its confirmation contradict it.<\/li>\n<li>Note: the \"cancellation window\" setting has never been enforced anywhere in the booking system, and this release does not start enforcing it. Members can still cancel at any time. Set your Cancellation Policy text to describe what you actually do.<\/li>\n<\/ul>\n\n<h4>1.166.0<\/h4>\n\n<ul>\n<li>Fixed: the studio's address now also appears on appointment confirmations, course enrolment confirmations, the email a guest gets when someone books them a seat, and the note a substitute teacher receives \u2014 the four other messages sent to someone expected to turn up somewhere.<\/li>\n<li>Fixed: \"Add to Calendar\" carries the address everywhere it appears, including on a member's account page and in an instructor's subscribed calendar feed. A substitute covering an unfamiliar room gets a calendar entry that actually navigates.<\/li>\n<li>Note: cancellations, rejections and \"you are back on this class\" notices deliberately do not show an address \u2014 nobody is being asked to travel.<\/li>\n<\/ul>\n\n<h4>1.165.0<\/h4>\n\n<ul>\n<li>Fixed: booking confirmations now show the studio's street address under the location name. They named the place but never said where it was, which for a studio whose name is its brand left a first-time student with nothing to navigate to.<\/li>\n<li>Fixed: \"Add to Google Calendar\" and the calendar invite attached to a confirmation now carry the full address, so tapping the entry for directions actually finds the place instead of searching for the studio's name.<\/li>\n<li>Fixed: a suite or unit number entered on a location was never included in any address, sending students to the right building and the wrong door.<\/li>\n<li>Changed: addresses now read \"Crestone, CO 81131\" rather than \"Crestone, CO, 81131\", and are formatted the same way everywhere they appear.<\/li>\n<\/ul>\n\n<h4>1.164.0<\/h4>\n\n<ul>\n<li>Added: promo codes now work on the enrolment checkout link, so an offer made at an info session or agreed with one student can be redeemed by typing the code \u2014 the discount is worked out on your server from the code and the package price, never from the link.<\/li>\n<li>Added: a promo code can be limited to specific packages, so a code written for one programme cannot be spent on anything else.<\/li>\n<li>Fixed: a code that cannot be used says so and returns you to the page you typed it on, instead of quietly sending you to Stripe at the full price.<\/li>\n<\/ul>\n\n<h4>1.163.1<\/h4>\n\n<ul>\n<li>Fixed: since 1.162.0 the booking window opened from the schedule did nothing on some pages, because the booking script's settings were attached before the script existed. Found in the browser check, not by the tests; a test now pins the order.<\/li>\n<\/ul>\n\n<h4>1.163.0<\/h4>\n\n<ul>\n<li>Changed: housekeeping found by review, none of it visible. Four empty placeholder files, twenty-nine methods nobody called, five unused constants, eight unused imports and about forty-five stylesheet rules that matched nothing are gone; three screens share one status-badge helper and three exports share one CSV writer; every dollar amount goes through the currency formatter (a studio charging in another currency saw a stray \"$\" in three places); the plugin's scripts keep their helpers under one namespace; and the developer notes stop describing widgets and list tables that were removed months ago.<\/li>\n<\/ul>\n\n<h4>1.162.0<\/h4>\n\n<ul>\n<li>Changed: the public schedule, class lists, calendar and instructor dashboard now read each class's details once per page instead of several times per row, so busy schedules load with a handful of database reads.<\/li>\n<li>Changed: the Front Desk roster, Waiver Compliance report, Invoices list, Bookings list, Clients list and CSV export, package shop and enrolment picker each make one read for the whole page instead of one per row.<\/li>\n<li>Changed: attendance now has database indexes for the counts and reports that read it, so milestone and attendance lookups stop scanning the whole table as history grows; the mail log is indexed for the reminder sweep.<\/li>\n<li>Changed: generating a season of sessions clears the schedule cache once, not once per session; scheduling an automation is a single write that cannot double-schedule under load; email styling and custom class labels are resolved once per batch of emails.<\/li>\n<li>Changed: Booking's stylesheet and scripts load only on pages that actually contain a Booking widget.<\/li>\n<\/ul>\n\n<h4>1.161.0<\/h4>\n\n<ul>\n<li>Fixed: typing a member's email address into the guest checkout \u2014 for a class, an appointment or a gift card \u2014 attached the booking to that member's account, emailed them a confirmation they never made, and quietly turned their account into a \"guest\" one. An address that belongs to a member is now asked to log in; a returning guest can still book without a password.<\/li>\n<li>Fixed: \"book for someone else\" could be used without logging in, minting accounts for any email address and booking them past the waiver. It now requires a logged-in buyer, and the option only appears when you are logged in.<\/li>\n<li>Fixed: the \"you already have credit that covers this class\" prompt listed a member's packs and balances to anyone who typed their email. It is only offered to logged-in members now.<\/li>\n<li>Fixed: a family promo code took the household size from the form, so a single-person household could claim the large-family discount on twenty bookings from one code. The size is now the household on record.<\/li>\n<li>Changed: checking a promo code while logged out gives the same answer whether the code is new-clients-only or already used by that address, so an address cannot be probed. Household invitations and gift-card redemption attempts are rate-limited.<\/li>\n<\/ul>\n\n<h4>1.160.0<\/h4>\n\n<p>\ud83d\udea8 Fixed: a declined card on a class that requires approval held the seat forever \u2014 nothing could cancel or sweep a pending-approval booking, and the retry took a second seat. It is released like any other failed payment now.\n\ud83d\udea8 Fixed: a class could be booked on an expired, used-up or wrong-class pack \u2014 only ownership of the pack was checked. Every condition is checked now, and a pack that fails to debit no longer leaves a \"paid\" seat behind.\n\ud83d\udea8 Fixed: rejecting a booking never returned the member's pack session, account credit or promo code, never offered the seat to the waitlist, and refunded the card before the seat was released. All four are right now.\n\ud83d\udea8 Fixed: a third of classes never got their day-before reminder \u2014 the reminder looked 20 to 28 hours ahead but only ran twice a day, so anything in the gap fell through. The window now covers the whole period.\n\ud83d\udea8 Fixed: birthday greetings never went to anyone who typed their own birthday into their profile; anniversary and birthday emails could go out a day early or late in your timezone; and 1:1 appointments were flagged \"under-enrolled\" every day.\n* Fixed: booking extra seats from a waitlist offer skipped the capacity check; cancelling a group booking offered only one of its seats to the waitlist; a waitlist offer accepted in the same minute it expired could be marked expired and lose its seat; undoing a late cancel revived a guest seat that had been cancelled separately; retrying a declined card handed your seat to the waitlist before the retry landed; a double-click could cancel the booking still being paid for.\n* Fixed: recording the same walk-in twice created a second seat and a second invoice; paying an invoice for a cancelled seat sent a \"you're booked\" email; a package paid by invoice never got its record or its purchase hooks, and the second one on a site failed silently.\n* Fixed: cancelling a course sent one \"booking cancelled\" email per remaining week (with a session number as the reason), never offered the freed seats to the waitlist, and double-counted a session you had already late-cancelled. It sends one email now, listing the released dates and the refund.\n* Fixed: ending a membership immediately released one seat per booking instead of every seat, and skipped the normal cancellation (waitlist, invoice); it also now sends the member one membership-ended notice instead of a flood of per-class ones.\n* Fixed: an expired class pack blocked buying the same pack again; \"sessions remaining this period\" on a membership always showed the full allowance; a $0 membership granted on approval became unlimited forever; a payment plan that recovered on its next installment never told Pulse, so dunning emails kept going; a deposit plan wrapped after its trial billed one installment short.\n* Fixed: turning an automation on for one class did nothing when it was off studio-wide; \"getting ready\" and \"your class changed\" emails still went out for a cancelled class; moving a class did not move its queued roster and prep emails; two overlapping cron runs could send the same automation email twice; the Review Request \"trigger after (hours)\" setting was ignored; \"renews soon\" and \"expires soon\" emails still went out when the date had moved.\n* Fixed: the Front Desk \"Add Client\" walk-in modal always showed a $0.00 drop-in price.<\/p>\n\n<h4>1.159.0<\/h4>\n\n<ul>\n<li>Changed: every Gather Grove Booking admin screen now uses the same cards, status badges, banners and empty states that Pulse's admin does, so the two read as one product side by side. Lists sit in cards with purpose-built rows instead of WordPress list tables; statuses are colour-coded badges everywhere; a screen with nothing on it yet says what to do first. Filters, search, sorting, paging, bulk actions and every row action work as before.<\/li>\n<li>Changed: the shared component stylesheets now load from the vendored core as registered handles instead of hand-copied files \u2014 Booking's copy of the admin chrome sheet had drifted behind core's and nothing said so. A test now fails if a component core ships is not loaded, if any screen renders outside the shared helper, or if a helper goes unused.<\/li>\n<li>Fixed: cancelling a booking from the Bookings list painted the status pill with hard-coded colours instead of the studio's badge style; marking a session complete could relabel the wrong pill in a row that also showed \"Customized\" or \"Sub\"; the Bookings list showed a plain grey pill for waitlisted, attended, late-cancel and scheduled rows; the Update Attendance button on a booking's detail page never refreshed the pill after saving; the Membership Requests Approve\/Reject buttons updated the wrong cells; the client Documents tab could not show its empty state after the last file was deleted.<\/li>\n<\/ul>\n\n<h4>1.158.4<\/h4>\n\n<ul>\n<li>Changed: on a site with an Elementor palette and an empty Brand tab, the Gather Grove admin screens now take their accent from your site's own palette instead of Gather Grove green, matching what the front end already did. Vendored core 0.53.0.<\/li>\n<\/ul>\n\n<h4>1.158.3<\/h4>\n\n<ul>\n<li>Fixed: the admin Sessions and Bookings lists showed \"No items found\" for every filter on MySQL 8, and the class-participants email export returned nobody. 1.157.0 guarded each optional date bound with ( %s = '' OR column &gt;= %s ); MySQL 8 refuses to compare a DATETIME column with '' even when the flag in front of it is true, so the whole statement failed. Unset bounds now bind the edges of the DATETIME range and compare directly.<\/li>\n<\/ul>\n\n<h4>1.158.2<\/h4>\n\n<ul>\n<li>Fixed: notification emails were hard to read on a phone. In a roster or reminder, the label column (\"Class\", \"When\", \"Location\") sat beside its value and squeezed it to about a third of the screen, so a two-word class name wrapped onto three lines. On a phone the label now sits above its value, each using the full width. Nothing changes on a computer. Vendored core 0.48.2.<\/li>\n<\/ul>\n\n<h4>1.158.1<\/h4>\n\n<p>\ud83d\udea8 Fixed: a logo with a transparent background could arrive on a black rectangle. 1.158.0 made an email-safe copy of any picture your site had converted to WebP, but always made it a JPEG \u2014 and JPEG cannot store transparency. Transparent images now stay PNG. Already-converted images are rebuilt automatically.<\/p>\n\n<ul>\n<li>Fixed: emails were too narrow to read on a phone, and now tighten their spacing on small screens.<\/li>\n<li>Changed: emails declare that their design is finished, so mail apps that respect it stop repainting them for dark mode.<\/li>\n<\/ul>\n\n<p>Vendored core 0.48.1.<\/p>\n\n<h4>1.158.0<\/h4>\n\n<p>\ud83d\udea8 Fixed: your logo now shows up correctly in Outlook. Two separate problems in the same place, both invisible from inside the site because the only people who saw them were the recipients of your emails.<\/p>\n\n<p>First, the size. The logo carried only CSS sizing, and classic Outlook ignores it \u2014 so a square logo that looked right everywhere else rendered at its full uploaded size in Outlook, pushing the rest of the header out of shape on every booking confirmation, reminder and cancellation. The logo now states real pixel dimensions, which is the only sizing Outlook reads.<\/p>\n\n<p>Second, the format. If your site converts images to WebP for speed \u2014 many do, often through a plugin or your host \u2014 the logo we picked up was a WebP, and classic Outlook cannot display a WebP at all. Those recipients saw a broken-image box where your logo should be. Gather Grove now makes a JPEG copy for email automatically, once, and uses that.<\/p>\n\n<p>Nothing to configure, and nothing changes on your website. Vendored core 0.48.0.<\/p>\n\n<h4>1.157.0<\/h4>\n\n<ul>\n<li>Security: a client or instructor account can now be removed from Gather Grove screens only when every role on that account belongs to Gather Grove. Accounts that also hold a WordPress role (editor, author, subscriber, \u2026) are left in place; the WordPress Users screen remains the only place to delete those.<\/li>\n<li>Security: the client-profile editor no longer renames WordPress accounts that Gather Grove does not manage; it updates the Gather Grove client record only.<\/li>\n<li>Changed: every database query is now a single fixed statement with every value bound through <code>$wpdb-&gt;prepare()<\/code>; list filters use bound flags rather than assembled <code>WHERE<\/code> fragments.<\/li>\n<li>Maintenance: updated the bundled Stripe PHP library from 20.3.1 to 21.3.0.<\/li>\n<\/ul>\n\n<h4>1.156.0<\/h4>\n\n<p>\ud83d\udea8 Fixed: the Gather Grove admin screens were unreadable on a dark studio brand.\nOur admin CSS reads the shared --gg-color-* tokens, and on an admin screen those\nwere already set to the studio's FRONT-END palette, so a dark brand painted cream\ntext on WordPress's light admin chrome \u2014 the dashboard heading measured 1.01:1,\neffectively invisible, alongside eight further contrast failures on that one\nscreen. The admin now emits core 0.47.2's contrast-guarded admin palette, which\nre-points those tokens at WordPress's own admin colours and clamps the studio's\nbrand hues so they stay legible. Light-brand studios are unaffected. Vendored\ncore 0.47.2.<\/p>\n\n<h4>1.155.0<\/h4>\n\n<ul>\n<li>Fixed: Gather Grove Admins can now actually save Settings. The Settings page was gated on the \"manage settings\" capability, but WordPress required full site-administrator rights to save it \u2014 so a Gather Grove Admin could open Settings, edit any field, press Save, and be told they were not allowed to manage options for this site. The capability now means what the menu always claimed it meant.<\/li>\n<li>Changed: the Payments tab is now visible only to full site administrators. It holds live Stripe credentials, which stays owner-only \u2014 matching Factory Reset and the Stripe connect button. Nothing a Gather Grove Admin can see is now unsaveable.<\/li>\n<\/ul>\n\n<h4>1.154.1<\/h4>\n\n<ul>\n<li>Fixed: the booking form no longer offers \"Buy a Pack\" or \"Subscribe\" on sites that have not connected a payment gateway yet \u2014 those purchases could be selected but never completed. Drop-in booking and existing credits are unaffected.\n&hellip;<\/li>\n<\/ul>","raw_excerpt":"For yoga studios, teachers, and community programs \u2014 class booking, waivers, appointments, waitlists, and Stripe payments. Built for Elementor.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/319887","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=319887"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/gturtle108"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=319887"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=319887"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=319887"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=319887"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=319887"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=319887"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}