{"id":283320,"date":"2026-04-02T17:33:42","date_gmt":"2026-04-02T17:33:42","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/free-short-term-rental-booking-ical\/"},"modified":"2026-05-24T22:47:04","modified_gmt":"2026-05-24T22:47:04","slug":"vachr-short-term-rental-reservations","status":"publish","type":"plugin","link":"https:\/\/dsb.wordpress.org\/plugins\/vachr-short-term-rental-reservations\/","author":23454938,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.0.1","stable_tag":"2.0.1","tested":"7.0","requires":"5.0","requires_php":"7.2","requires_plugins":null,"header_name":"Vachr Short-Term Rental Reservations","header_author":"Radomir Vachr","header_description":"A professional short-term rental booking engine for WordPress. Includes advanced seasonal pricing (Summer, Winter, Holidays), dynamic discounts, and multi-currency support. Sync effortlessly with Airbnb, Booking.com, and more via two-way iCal integration. Features a responsive frontend calendar, customizable contact fields, additional services (cleaning, parking, etc.), and automated email notifications. Lightweight, collision-protected, and fully translatable.","assets_banners_color":"c4d3eb","last_updated":"2026-05-24 22:47:04","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/vachr.cz","rating":0,"author_block_rating":0,"active_installs":0,"downloads":1294,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.4.2":{"tag":"1.4.2","author":"chuckumi","date":"2026-04-13 00:14:42"},"1.4.3":{"tag":"1.4.3","author":"chuckumi","date":"2026-04-06 20:29:14"},"1.4.4":{"tag":"1.4.4","author":"chuckumi","date":"2026-04-06 20:29:14"},"1.4.5":{"tag":"1.4.5","author":"chuckumi","date":"2026-04-06 20:29:14"},"1.4.6":{"tag":"1.4.6","author":"chuckumi","date":"2026-04-06 20:29:14"},"1.4.7":{"tag":"1.4.7","author":"chuckumi","date":"2026-04-06 20:29:14"},"1.4.8":{"tag":"1.4.8","author":"chuckumi","date":"2026-04-06 20:29:14"},"1.4.9":{"tag":"1.4.9","author":"chuckumi","date":"2026-04-06 20:29:14"},"1.5.0":{"tag":"1.5.0","author":"chuckumi","date":"2026-04-06 20:29:14"},"1.5.1":{"tag":"1.5.1","author":"chuckumi","date":"2026-04-06 20:30:48"},"1.5.2":{"tag":"1.5.2","author":"chuckumi","date":"2026-04-06 22:16:45"},"1.5.3":{"tag":"1.5.3","author":"chuckumi","date":"2026-04-10 22:32:38"},"1.5.4":{"tag":"1.5.4","author":"chuckumi","date":"2026-04-11 21:33:24"},"1.6.0":{"tag":"1.6.0","author":"chuckumi","date":"2026-04-13 00:16:05"},"1.6.1":{"tag":"1.6.1","author":"chuckumi","date":"2026-04-21 22:45:18"},"1.6.2":{"tag":"1.6.2","author":"chuckumi","date":"2026-04-21 23:06:20"},"1.7.3":{"tag":"1.7.3","author":"chuckumi","date":"2026-04-23 23:40:10"},"1.7.7":{"tag":"1.7.7","author":"chuckumi","date":"2026-04-24 17:33:11"},"1.7.8":{"tag":"1.7.8","author":"chuckumi","date":"2026-04-24 20:24:30"},"1.7.9":{"tag":"1.7.9","author":"chuckumi","date":"2026-04-24 20:42:09"},"1.9.1":{"tag":"1.9.1","author":"chuckumi","date":"2026-04-26 00:00:11"},"1.9.10":{"tag":"1.9.10","author":"chuckumi","date":"2026-04-26 23:49:22"},"1.9.11":{"tag":"1.9.11","author":"chuckumi","date":"2026-04-27 11:08:39"},"1.9.12":{"tag":"1.9.12","author":"chuckumi","date":"2026-04-28 16:28:55"},"1.9.13":{"tag":"1.9.13","author":"chuckumi","date":"2026-04-28 16:56:22"},"1.9.16":{"tag":"1.9.16","author":"chuckumi","date":"2026-04-29 13:38:10"},"1.9.17":{"tag":"1.9.17","author":"chuckumi","date":"2026-04-29 21:41:37"},"1.9.18":{"tag":"1.9.18","author":"chuckumi","date":"2026-04-30 22:42:44"},"1.9.19":{"tag":"1.9.19","author":"chuckumi","date":"2026-05-01 00:04:28"},"1.9.20":{"tag":"1.9.20","author":"chuckumi","date":"2026-05-01 16:53:09"},"1.9.21":{"tag":"1.9.21","author":"chuckumi","date":"2026-05-04 18:06:39"},"1.9.22":{"tag":"1.9.22","author":"chuckumi","date":"2026-05-04 21:03:51"},"1.9.23":{"tag":"1.9.23","author":"chuckumi","date":"2026-05-04 22:52:18"},"1.9.24":{"tag":"1.9.24","author":"chuckumi","date":"2026-05-07 23:33:00"},"1.9.25":{"tag":"1.9.25","author":"chuckumi","date":"2026-05-09 22:23:45"},"1.9.26":{"tag":"1.9.26","author":"chuckumi","date":"2026-05-10 20:17:26"},"1.9.28":{"tag":"1.9.28","author":"chuckumi","date":"2026-05-21 23:52:19"},"1.9.29":{"tag":"1.9.29","author":"chuckumi","date":"2026-05-22 00:51:21"},"1.9.6":{"tag":"1.9.6","author":"chuckumi","date":"2026-04-26 17:21:19"},"1.9.7":{"tag":"1.9.7","author":"chuckumi","date":"2026-04-26 20:57:18"},"1.9.8":{"tag":"1.9.8","author":"chuckumi","date":"2026-04-26 22:51:23"},"1.9.9":{"tag":"1.9.9","author":"chuckumi","date":"2026-04-26 22:54:41"},"2.0.0":{"tag":"2.0.0","author":"chuckumi","date":"2026-05-22 19:57:24"},"2.0.1":{"tag":"2.0.1","author":"chuckumi","date":"2026-05-24 22:47:04"}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-256x256.jpg":{"filename":"icon-256x256.jpg","revision":3500164,"resolution":"256x256","location":"assets","locale":"","width":256,"height":229}},"assets_banners":{"banner-1544x500.jpg":{"filename":"banner-1544x500.jpg","revision":3526041,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.jpg":{"filename":"banner-772x250.jpg","revision":3526041,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.4.2","1.4.3","1.4.4","1.4.5","1.4.6","1.4.7","1.4.8","1.4.9","1.5.0","1.5.1","1.5.2","1.5.3","1.5.4","1.6.0","1.6.1","1.6.2","1.7.3","1.7.7","1.7.8","1.7.9","1.9.1","1.9.10","1.9.11","1.9.12","1.9.13","1.9.16","1.9.17","1.9.18","1.9.19","1.9.20","1.9.21","1.9.22","1.9.23","1.9.24","1.9.25","1.9.26","1.9.28","1.9.29","1.9.6","1.9.7","1.9.8","1.9.9","2.0.0","2.0.1"],"block_files":[],"assets_screenshots":{"screenshot-1.jpg":{"filename":"screenshot-1.jpg","revision":3500164,"resolution":"1","location":"assets","locale":"","width":968,"height":639},"screenshot-10.jpg":{"filename":"screenshot-10.jpg","revision":3497761,"resolution":"10","location":"assets","locale":"","width":2660,"height":1228},"screenshot-11.jpg":{"filename":"screenshot-11.jpg","revision":3497761,"resolution":"11","location":"assets","locale":"","width":2612,"height":1356},"screenshot-12.jpg":{"filename":"screenshot-12.jpg","revision":3497761,"resolution":"12","location":"assets","locale":"","width":2564,"height":1418},"screenshot-13.jpg":{"filename":"screenshot-13.jpg","revision":3497761,"resolution":"13","location":"assets","locale":"","width":1356,"height":1416},"screenshot-2.jpg":{"filename":"screenshot-2.jpg","revision":3497761,"resolution":"2","location":"assets","locale":"","width":1026,"height":1418},"screenshot-3.jpg":{"filename":"screenshot-3.jpg","revision":3497761,"resolution":"3","location":"assets","locale":"","width":1084,"height":716},"screenshot-4.jpg":{"filename":"screenshot-4.jpg","revision":3497761,"resolution":"4","location":"assets","locale":"","width":2534,"height":1300},"screenshot-5.jpg":{"filename":"screenshot-5.jpg","revision":3497761,"resolution":"5","location":"assets","locale":"","width":2476,"height":1102},"screenshot-6.jpg":{"filename":"screenshot-6.jpg","revision":3497761,"resolution":"6","location":"assets","locale":"","width":2474,"height":1096},"screenshot-7.jpg":{"filename":"screenshot-7.jpg","revision":3497761,"resolution":"7","location":"assets","locale":"","width":2880,"height":1362},"screenshot-8.jpg":{"filename":"screenshot-8.jpg","revision":3497761,"resolution":"8","location":"assets","locale":"","width":2480,"height":1406},"screenshot-9.jpg":{"filename":"screenshot-9.jpg","revision":3497761,"resolution":"9","location":"assets","locale":"","width":2690,"height":698}},"screenshots":{"1":"Frontend availability calendar.","2":"Booking form - guest contact information.","3":"Booking form - services and price overview.","4":"Admin - Unit management and settings.","5":"Admin - Rates and pricing engine configuration.","6":"Admin - Apartment-specific services configuration.","7":"Admin - Bookings overview from website and external channels (Booking.com, Airbnb, etc.).","8":"Admin - Customizing the visual appearance of the calendar and forms.","9":"Admin - Guest registration management for tourist tax records.","10":"Admin - Advanced discounts and seasonal pricing rules.","11":"Admin - Two-way iCal synchronization settings for external OTAs.","12":"Admin - Global services and amenities management.","13":"Public guest registration form for collecting tourist tax data.","14":"Admin - Payment methods configuration.","15":"Admin - Invoice management.","16":"Booking form - payment options.","17":"Hosted payment page via Stripe or Mollie.","18":"Admin - Multilingual apartment content templates.","19":"Admin - Apartment-specific arrival instructions and content overrides."}},"plugin_section":[],"plugin_tags":[269,416,7103,5075,722],"plugin_category":[40],"plugin_contributors":[259308],"plugin_business_model":[],"class_list":["post-283320","plugin","type-plugin","status-publish","hentry","plugin_tags-booking","plugin_tags-calendar","plugin_tags-ical","plugin_tags-rental","plugin_tags-reservation","plugin_category-calendar-and-events","plugin_contributors-chuckumi","plugin_committers-chuckumi"],"banners":{"banner":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/banner-772x250.jpg?rev=3526041","banner_2x":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/banner-1544x500.jpg?rev=3526041","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/icon-256x256.jpg?rev=3500164","icon_2x":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/icon-256x256.jpg?rev=3500164","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-1.jpg?rev=3500164","caption":"Frontend availability calendar."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-2.jpg?rev=3497761","caption":"Booking form - guest contact information."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-3.jpg?rev=3497761","caption":"Booking form - services and price overview."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-4.jpg?rev=3497761","caption":"Admin - Unit management and settings."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-5.jpg?rev=3497761","caption":"Admin - Rates and pricing engine configuration."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-6.jpg?rev=3497761","caption":"Admin - Apartment-specific services configuration."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-7.jpg?rev=3497761","caption":"Admin - Bookings overview from website and external channels (Booking.com, Airbnb, etc.)."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-8.jpg?rev=3497761","caption":"Admin - Customizing the visual appearance of the calendar and forms."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-9.jpg?rev=3497761","caption":"Admin - Guest registration management for tourist tax records."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-10.jpg?rev=3497761","caption":"Admin - Advanced discounts and seasonal pricing rules."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-11.jpg?rev=3497761","caption":"Admin - Two-way iCal synchronization settings for external OTAs."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-12.jpg?rev=3497761","caption":"Admin - Global services and amenities management."},{"src":"https:\/\/ps.w.org\/vachr-short-term-rental-reservations\/assets\/screenshot-13.jpg?rev=3497761","caption":"Public guest registration form for collecting tourist tax data."}],"raw_content":"<!--section=description-->\n<p>The <strong>Vachr Short-Term Rental Reservations<\/strong> is the ultimate, all-in-one booking and management solution for WordPress, designed specifically for property owners and managers who need full control without complexity. It transforms your WordPress site into a professional rental platform for apartments, vacation homes, or rooms, offering everything you need for effortless property management in one place.<\/p>\n\n<p>[youtube https:\/\/www.youtube.com\/watch?v=ss2JD-JexpM]\nVideo tutorial: https:\/\/www.youtube.com\/watch?v=ss2JD-JexpM\n<em>Watch this video to see how to manage and use the system.<\/em><\/p>\n\n<p>This plugin is a complete powerhouse that handles everything from initial booking to guest registration. It features a highly flexible pricing engine for creating complex discounts and seasonal rates, fully customizable registration forms with custom fields, and the ability to offer additional services with their own pricing. The entire system is translatable and allows you to tailor the visual appearance of your forms to perfectly match your website's brand.<\/p>\n\n<p>This plugin is completely free to use. However, if you find it helpful and would like to support its further development, any small donation (even just a few Euros) is greatly appreciated. Your support will help me implement upcoming features and improvements. You can manage an unlimited number of apartments, everything is fully translatable, and it offers all the essential tools without limitations. I use it myself and can personally vouch for its reliability and effectiveness.<\/p>\n\n<p>Need help with setup? I offer one-time WordPress setup for short-term rentals, including connection to Booking.com, Airbnb, and more for 100 EUR, plus optional yearly light support for 20 EUR.<\/p>\n\n<h4>Key Advantages<\/h4>\n\n<ul>\n<li><strong>Ultimate All-in-One Tool:<\/strong> Manage everything from bookings and pricing to guest registration and custom services in one intuitive interface.<\/li>\n<li><strong>Flexible Discounts &amp; Pricing:<\/strong> Create advanced seasonal pricing, weekend rates, and dynamic discounts based on stay duration or specific conditions.<\/li>\n<li><strong>Rental Season Control:<\/strong> Close apartments for exact date ranges, recurring months, or recurring day ranges when the property is not available.<\/li>\n<li><strong>Online Payments &amp; Flexible Checkout:<\/strong> Accept online card payments via Stripe or Mollie, and optionally enable bank transfer or cash payment methods.<\/li>\n<li><strong>Invoices &amp; Transactions:<\/strong> Keep payment records, invoice numbers, billing details, payment status, and paid timestamps connected to each booking.<\/li>\n<li><strong>Custom Registration Forms:<\/strong> Build your own registration forms with custom fields to collect exactly the guest data you need.<\/li>\n<li><strong>Guest Registration Matching:<\/strong> Link guest registrations to bookings, review unpaired records, and correct the apartment or booking assignment from the admin panel.<\/li>\n<li><strong>Custom Services with Pricing:<\/strong> Offer and manage additional services (like cleaning, breakfast, or bike rentals) with their own configurable prices.<\/li>\n<li><strong>Translatable Apartment Amenities:<\/strong> Manage a reusable amenities catalog (Wi-Fi, Netflix, parking, wellness, kitchen equipment, safety items, and more) and assign amenities per apartment.<\/li>\n<li><strong>Multilingual Apartment Content:<\/strong> Manage reusable templates for apartment descriptions, amenities, and arrival instructions, with per-apartment overrides.<\/li>\n<li><strong>Automated Arrival Instructions:<\/strong> Send arrival instructions to confirmed guests a configurable number of days before check-in.<\/li>\n<li><strong>Staff Access Rules:<\/strong> Send limited booking or registration details to cleaners and staff, and expose the same limited data through a password-protected page shortcode.<\/li>\n<li><strong>Total Visual Control:<\/strong> Easily customize the look and feel of your booking calendars and forms to match your site's design.<\/li>\n<li><strong>Two-Way iCal Integration:<\/strong> Automatic synchronization with major travel agencies (Airbnb, Booking.com, VRBO) to eliminate the risk of overbooking.<\/li>\n<li><strong>Fully Translatable:<\/strong> Ready for international guests with multi-language support and easy translation management.<\/li>\n<li><strong>Lightweight &amp; Fast:<\/strong> Optimized for performance to ensure your site remains quick for visitors.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<p>[youtube https:\/\/www.youtube.com\/watch?v=ss2JD-JexpM]\nVideo tutorial: https:\/\/www.youtube.com\/watch?v=ss2JD-JexpM\n<em>Watch this video to see how to manage and use the system.<\/em><\/p>\n\n<ol>\n<li>Upload the plugin files to the <code>\/wp-content\/plugins\/vachr-short-term-rental-reservations<\/code> directory, or install the plugin through the WordPress plugins screen directly.<\/li>\n<li>Activate the plugin through the 'Plugins' screen in WordPress.<\/li>\n<li>Go to the 'Apartments' menu to create your first rental unit.<\/li>\n<li>Use the provided shortcodes to display the booking form or calendar on your pages.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"how%20do%20i%20display%20the%20booking%20form%3F\"><h3>How do I display the booking form?<\/h3><\/dt>\n<dd><p>Use the shortcode <code>[vstrb_booking_form unit=\"YOUR_ID\"]<\/code>.<\/p>\n\n<p>Optional parameters:<\/p>\n\n<ul>\n<li><code>months=\"N\"<\/code> - number of calendar months to display (default: <code>1<\/code>).<\/li>\n<li><code>grid=\"N\"<\/code> - number of month columns in the calendar grid (default: <code>1<\/code>).<\/li>\n<li><code>currency=\"CODE\"<\/code> - currency code used in the price breakdown (default: <code>EUR<\/code>).<\/li>\n<li><code>language=\"CODE\"<\/code> - two-letter language code (e.g. <code>cs<\/code>, <code>de<\/code>, <code>en<\/code>) used for services, contact field labels, and the price quote. If omitted, the language of the current page (reflected in the <code>&lt;html lang&gt;<\/code> attribute, set automatically by multilingual plugins) is used; the visitor's browser language serves as a last resort fallback.<\/li>\n<li><code>enable_stripe=\"1\"<\/code> - show card payment via Stripe. Configure Stripe keys and webhook secret in <strong>Apartments -&gt; Settings -&gt; Payments &amp; Invoices<\/strong>.<\/li>\n<li><code>enable_mollie=\"1\"<\/code> - show card payment via Mollie. Configure the Mollie API key and use the displayed Mollie webhook URL in <strong>Apartments -&gt; Settings -&gt; Payments &amp; Invoices<\/strong>.<\/li>\n<li><code>enable_bank_transfer=\"1\"<\/code> - show bank transfer payment. Configure default bank instructions in <strong>Apartments -&gt; Settings -&gt; Payments &amp; Invoices<\/strong>, or translated per-apartment instructions in <strong>Bookings -&gt; Apartment Content<\/strong>.<\/li>\n<li><code>enable_cash=\"1\"<\/code> - show cash payment.<\/li>\n<\/ul>\n\n<p>Example: <code>[vstrb_booking_form unit=\"YOUR_ID\" language=\"de\"]<\/code><\/p>\n\n<p>Payment example with Mollie and bank transfer:\n    [vstrb_booking_form unit=\"YOUR_ID\" enable_mollie=\"1\" enable_bank_transfer=\"1\" enable_cash=\"1\"]<\/p>\n\n<p>Payment example with all payment methods:\n    [vstrb_booking_form unit=\"YOUR_ID\" enable_stripe=\"1\" enable_mollie=\"1\" enable_bank_transfer=\"1\" enable_cash=\"1\"]<\/p><\/dd>\n<dt id=\"how%20do%20i%20enable%20mollie%20payments%3F\"><h3>How do I enable Mollie payments?<\/h3><\/dt>\n<dd><ol>\n<li>Go to <strong>Apartments -&gt; Settings -&gt; Payments &amp; Invoices<\/strong>.<\/li>\n<li>Enter your Mollie API key (<code>test_...<\/code> or <code>live_...<\/code>).<\/li>\n<li>Copy the displayed <strong>Mollie Webhook URL<\/strong> into your Mollie dashboard webhook settings.<\/li>\n<li>Add <code>enable_mollie=\"1\"<\/code> to your booking form shortcode.<\/li>\n<\/ol>\n\n<p>Example: <code>[vstrb_booking_form unit=\"YOUR_ID\" enable_mollie=\"1\"]<\/code><\/p><\/dd>\n<dt id=\"how%20do%20i%20display%20the%20availability%20calendar%3F\"><h3>How do I display the availability calendar?<\/h3><\/dt>\n<dd><p>Use the shortcode <code>[vstrb_availability_calendar unit=\"YOUR_ID\" months=\"3\"]<\/code>.<\/p><\/dd>\n<dt id=\"how%20do%20i%20collect%20guest%20registration%20data%20%28e.g.%20from%20booking.com%20guests%29%3F\"><h3>How do I collect guest registration data (e.g. from Booking.com guests)?<\/h3><\/dt>\n<dd><p>Use the shortcode <code>[vstrb_guest_registration unit=\"YOUR_ID\"]<\/code> on any page. Share the link with your guest - they fill in their personal details without needing to register. Submitted data is saved to the database and sent by email to both the admin and the guest. You can review all registrations under <strong>Bookings -&gt; Guest Registrations<\/strong> in the admin panel.<\/p>\n\n<p>If the registration link contains a specific apartment (<code>unit<\/code>), that apartment is kept as the primary assignment. The plugin then tries to link the registration to a matching booking for the same apartment and stay dates. When the apartment is not known and there is exactly one matching booking for the submitted stay dates, the registration can be linked automatically to that booking. If the match is not clear, you can manually pair or unpair the registration group in the admin panel.<\/p>\n\n<p>The Guest Registrations admin screen includes filters for apartment, booking source, stay date range, guest\/email\/reference search, booking ID, and linked or unlinked registration groups. You can also change the apartment for a whole registration group when a guest submitted the form under the wrong apartment.<\/p>\n\n<p>Optional parameters:<\/p>\n\n<ul>\n<li><code>title=\"TEXT\"<\/code> - custom heading displayed above the form. If omitted, the apartment name is used as the heading.<\/li>\n<li><code>language=\"LOCALE\"<\/code> - locale code (e.g. <code>cs_CZ<\/code>, <code>de_DE<\/code>, <code>en_US<\/code>) to render the form labels in a specific language. If omitted, the current site language is used.<\/li>\n<li><code>param=\"accommodation\"<\/code> - resolve the apartment from a URL parameter instead of a fixed <code>unit<\/code> ID. This is useful for Booking.com links with <code>[PROPERTY_NAME]<\/code>.<\/li>\n<li><code>match=\"contains\"<\/code> - allow one unique partial match when Booking.com sends a longer or shorter property name.<\/li>\n<li><code>fallback=\"TEXT\"<\/code> - text shown when no unique apartment is matched.<\/li>\n<\/ul>\n\n<p>Example: <code>[vstrb_guest_registration unit=\"YOUR_ID\" title=\"Apartment Modry Dum\" language=\"cs_CZ\"]<\/code><\/p>\n\n<p>Booking.com example page shortcode:\n    [vstrb_guest_registration param=\"accommodation\" language=\"en_US\" fallback=\"Accommodation not found. Please contact us.\"]<\/p>\n\n<p>Booking.com message URL:\n    https:\/\/example.com\/accommodation-registration-tourist-tax\/?accommodation=[PROPERTY_NAME]&amp;source=booking_com<\/p>\n\n<p>Add the exact Booking.com property name to <strong>External accommodation names \/ aliases<\/strong> in the matching apartment editor. One alias per line is supported. Matching ignores case, accents, and extra punctuation.<\/p><\/dd>\n<dt id=\"how%20do%20i%20manage%20multilingual%20apartment%20descriptions%2C%20amenities%2C%20arrival%20instructions%2C%20and%20bank%20transfer%20instructions%3F\"><h3>How do I manage multilingual apartment descriptions, amenities, arrival instructions, and bank transfer instructions?<\/h3><\/dt>\n<dd><p>Create reusable content templates under <strong>Bookings -&gt; Apartment Content<\/strong>. Each template can contain translated apartment descriptions, amenities text, arrival instructions, and bank transfer payment instructions for the languages configured in <strong>Bookings -&gt; Settings<\/strong>.<\/p>\n\n<p>Then open an apartment and use the <strong>Guest-facing Apartment Content<\/strong> section in the apartment details. You can assign a template and optionally override any language directly for that apartment.<\/p>\n\n<p>Template texts support placeholders in double braces. Built-in placeholders include:<\/p>\n\n<ul>\n<li><code>{{apartment_name}}<\/code><\/li>\n<li><code>{{apartment_id}}<\/code><\/li>\n<li><code>{{site_name}}<\/code><\/li>\n<li><code>{{checkin_time}}<\/code><\/li>\n<li><code>{{checkout_time}}<\/code><\/li>\n<li><code>{{capacity}}<\/code><\/li>\n<li><code>{{booking_id}}<\/code> - available in arrival instruction emails.<\/li>\n<li><code>{{guest_name}}<\/code> - available in arrival instruction emails.<\/li>\n<li><code>{{date_from}}<\/code> and <code>{{date_to}}<\/code> - available in arrival instruction emails.<\/li>\n<li><code>{{invoice_number}}<\/code>, <code>{{payment_amount}}<\/code>, and <code>{{payment_currency}}<\/code> - available in bank transfer instructions after booking submission.<\/li>\n<\/ul>\n\n<p>Bank transfer callbacks use the generic <strong>Bank Notify URL<\/strong> from settings. The endpoint accepts JSON, form-encoded payloads, and simple XML bodies. It recognizes common wrapper keys such as <code>transaction<\/code>, <code>payment<\/code>, <code>data<\/code>, <code>entry<\/code>, or <code>accountStatement<\/code>, and common aliases:<\/p>\n\n<ul>\n<li>token: <code>token<\/code>, <code>webhook_token<\/code>, <code>secret<\/code>, <code>shared_secret<\/code>, <code>api_key<\/code>, or the <code>X-VSTRB-Token<\/code>, <code>X-Webhook-Token<\/code>, or <code>Authorization: Bearer ...<\/code> header.<\/li>\n<li>booking: <code>booking_id<\/code>, <code>bookingId<\/code>, <code>reservation_id<\/code>, or <code>order_id<\/code>.<\/li>\n<li>invoice: <code>invoice_number<\/code>, <code>invoiceNumber<\/code>, <code>invoice_no<\/code>, <code>invoice<\/code>, or <code>bill_number<\/code>.<\/li>\n<li>reference \/ variable symbol: <code>reference<\/code>, <code>payment_reference<\/code>, <code>variable_symbol<\/code>, <code>variableSymbol<\/code>, <code>vs<\/code>, <code>transaction_id<\/code>, <code>bank_reference<\/code>, <code>endToEndId<\/code>, <code>remittanceInformation<\/code>, <code>message<\/code>, <code>note<\/code>, or <code>userIdentification<\/code>.<\/li>\n<li>amount and currency: <code>amount<\/code>, <code>value<\/code>, <code>transaction_amount<\/code>, <code>castka<\/code>, <code>sum<\/code>, <code>currency<\/code>, <code>ccy<\/code>, or <code>mena<\/code>.<\/li>\n<\/ul>\n\n<p>The plugin matches payments by booking ID first, then invoice number, then exact reference\/variable-symbol match against stored payment references or invoice numbers. It does not connect directly to a specific bank API by itself; a bank export, external automation, or middleware can call the endpoint in one of the supported shapes.<\/p>\n\n<p>You can also define custom placeholders in the apartment editor, for example <code>door_pin<\/code>, <code>wifi_password<\/code>, or <code>parking_note<\/code>. Custom placeholders can have one global value or language-specific values. Use them as <code>{{door_pin}}<\/code> or with a fallback like <code>{{door_pin|provided before arrival}}<\/code>.<\/p>\n\n<p>Example: door PIN and Wi-Fi password<\/p>\n\n<ol>\n<li>Open <strong>Apartments -&gt; Edit Apartment<\/strong>.<\/li>\n<li>In <strong>Guest-facing Apartment Content -&gt; Template Placeholders<\/strong>, add:\n\n<ul>\n<li>Key: <code>door_pin<\/code><\/li>\n<li>Global value: <code>123456<\/code><\/li>\n<\/ul><\/li>\n<li>Add another placeholder:\n\n<ul>\n<li>Key: <code>wifi_password<\/code><\/li>\n<li>Global value: <code>MySecureWifiPassword<\/code><\/li>\n<\/ul><\/li>\n<li><p>Use these placeholders in an arrival instruction template:<\/p>\n\n<p>Your apartment is {{apartment_name}}.\nCheck-in is possible from {{checkin_time}}.\nThe entrance door PIN is {{door_pin}}.\nThe Wi-Fi password is {{wifi_password}}.<\/p><\/li>\n<\/ol>\n\n<p>Example: translated custom placeholder<\/p>\n\n<p>If a placeholder contains text that should be translated, fill the language-specific values:<\/p>\n\n<ul>\n<li>Key: <code>parking_note<\/code><\/li>\n<li>Global value: <code>Parking is available behind the house.<\/code><\/li>\n<li>CS value: <code>Parkovani je mozne za domem.<\/code><\/li>\n<li>DE value: <code>Parken ist hinter dem Haus moeglich.<\/code><\/li>\n<\/ul>\n\n<p>Then use it in a template:<\/p>\n\n<pre><code>{{parking_note}}\n<\/code><\/pre>\n\n<p>When the content is displayed or emailed in Czech, the CS value is used. In German, the DE value is used. If no matching language value exists, the global value is used.<\/p>\n\n<p>Example: fallback text when a value is missing<\/p>\n\n<pre><code>Door PIN: {{door_pin|provided before arrival}}\n<\/code><\/pre>\n\n<p>If <code>door_pin<\/code> is empty, the guest will see <code>provided before arrival<\/code> instead of a blank value.<\/p>\n\n<p>You can display the saved content with these shortcodes:<\/p>\n\n<ul>\n<li><code>[vstrb_unit_description unit=\"YOUR_ID\" language=\"cs\"]<\/code><\/li>\n<li><code>[vstrb_unit_amenity_list unit=\"YOUR_ID\" language=\"cs\"]<\/code><\/li>\n<li><code>[vstrb_unit_arrival_instructions unit=\"YOUR_ID\" language=\"cs\"]<\/code><\/li>\n<li><code>[vstrb_unit_arrival_instructions_by_code param=\"unit_code\" language=\"cs\"]<\/code><\/li>\n<li><code>[vstrb_unit_arrival_instructions_by_name param=\"accommodation\" language=\"cs\"]<\/code><\/li>\n<li><code>[vstrb_unit_arrival_instructions_by_reservation]<\/code><\/li>\n<\/ul>\n\n<p>If the <code>language<\/code> attribute is omitted, the site language is used. Apartment-specific text has priority over the selected template.<\/p>\n\n<p>To show arrival instructions without exposing an internal apartment ID, prefer <code>[vstrb_unit_arrival_instructions_by_code]<\/code>. Set a <strong>Public apartment code<\/strong> in the apartment editor and put that code into the external channel link. This is more reliable than matching a name sent by Booking.com, Airbnb, or another channel.<\/p>\n\n<p>Example page shortcode:\n    [vstrb_unit_arrival_instructions_by_code param=\"unit_code\" language=\"cs\" fallback=\"Accommodation not found. Please contact us.\"]<\/p>\n\n<p>Example guest URL:\n    https:\/\/example.com\/arrival\/?unit_code=blue-house<\/p>\n\n<p>If an external channel can only send the accommodation name, use <code>[vstrb_unit_arrival_instructions_by_name]<\/code> and add the exact channel-specific names to <strong>External accommodation names \/ aliases<\/strong> in the apartment editor. The shortcode matches the URL value against the apartment title and these aliases. Matching ignores case, accents, and extra punctuation.<\/p>\n\n<p>Optional parameters:<\/p>\n\n<ul>\n<li><code>param=\"NAME\"<\/code> - GET parameter containing the public code or accommodation name. Defaults: <code>unit_code<\/code> for the code shortcode, <code>unit_name<\/code> for the name shortcode.<\/li>\n<li><code>code=\"TEXT\"<\/code> - use a fixed public apartment code instead of a GET parameter, useful for testing.<\/li>\n<li><code>name=\"TEXT\"<\/code> - use a fixed accommodation name or alias instead of a GET parameter, useful for testing.<\/li>\n<li><code>match=\"exact\"<\/code> - default exact normalized title match.<\/li>\n<li><code>match=\"contains\"<\/code> - name shortcode only: allow one unique partial match when an external channel sends a longer or shorter name.<\/li>\n<li><code>show_title=\"1\"<\/code> - show the matched apartment title above the instructions.<\/li>\n<li><code>fallback=\"TEXT\"<\/code> - text shown when no unique apartment is matched.<\/li>\n<\/ul><\/dd>\n<dt id=\"how%20do%20automated%20arrival%20instruction%20emails%20work%3F\"><h3>How do automated arrival instruction emails work?<\/h3><\/dt>\n<dd><p>In the apartment editor, enable <strong>Email arrival instructions automatically before check-in<\/strong> and set <strong>Send days before arrival<\/strong>.<\/p>\n\n<p>The daily WordPress cron checks confirmed bookings with a customer email address. If arrival instructions exist for the apartment, the guest receives an email with the apartment description, amenities, and arrival instructions in the saved booking language when available. Each booking is marked after sending so the instructions are not sent repeatedly.<\/p>\n\n<p>To display arrival instructions by matching a guest stay, use:\n    [vstrb_unit_arrival_instructions_by_reservation]<\/p>\n\n<p>The shortcode reads arrival date, departure date, first name, and last name from URL parameters. It accepts ISO dates and common local numeric date formats such as <code>2026-06-01<\/code>, <code>1.6.2026<\/code>, <code>01\/06\/2026<\/code>, and <code>06\/01\/2026<\/code>; ambiguous formats are tried against stored reservations without converting through UTC. It first tries to find one apartment by stay dates only. If multiple apartments match the same dates, it narrows the result by both guest names, then by last name only, then by first name only. Name matching ignores accents and letter case. If no unique match is found, it displays the first apartment with available instructions in alphabetical order.<\/p>\n\n<p>Example page shortcode:\n    [vstrb_unit_arrival_instructions_by_reservation date_from_param=\"checkin\" date_to_param=\"checkout\" first_name_param=\"guest_first_name\" last_name_param=\"guest_last_name\" language=\"cs\" available_days_before=\"1\" unavailable_text=\"Arrival instructions are not available yet.\" fallback=\"Arrival instructions are not available. Please contact us.\"]<\/p>\n\n<p>Example guest URL, password: <code>testtest<\/code>:\n    https:\/\/vachr.cz\/apartment-1-demo-pin\/?checkin=2026-06-23&amp;checkout=25.6.2026&amp;guest_first_name=Jan&amp;guest_last_name=Novak<\/p>\n\n<p>Optional parameters:<\/p>\n\n<ul>\n<li><code>unit=\"ID\"<\/code> - limit matching to one apartment, useful when date combinations may repeat across apartments.<\/li>\n<li><code>date_from_param=\"date_from\"<\/code> - URL parameter containing arrival.<\/li>\n<li><code>date_to_param=\"date_to\"<\/code> - URL parameter containing departure.<\/li>\n<li><code>first_name_param=\"first_name\"<\/code> - URL parameter containing first name.<\/li>\n<li><code>last_name_param=\"last_name\"<\/code> - URL parameter containing last name.<\/li>\n<li><code>date_from=\"YYYY-MM-DD\"<\/code> - fixed arrival date instead of a URL parameter.<\/li>\n<li><code>date_to=\"YYYY-MM-DD\"<\/code> - fixed departure date instead of a URL parameter.<\/li>\n<li><code>first_name=\"TEXT\"<\/code> - fixed first name instead of a URL parameter.<\/li>\n<li><code>last_name=\"TEXT\"<\/code> - fixed last name instead of a URL parameter.<\/li>\n<li><code>language=\"cs\"<\/code> - language used for apartment instructions.<\/li>\n<li><code>show_title=\"1\"<\/code> - show the matched or fallback apartment title above the instructions.<\/li>\n<li><code>fallback=\"TEXT\"<\/code> - text shown when no apartment has arrival instructions.<\/li>\n<li><code>available_days_before=\"1\"<\/code> - how many days before arrival the instructions may be shown. Default: <code>1<\/code>. Use <code>0<\/code> to show them only on the arrival day.<\/li>\n<li><code>unavailable_text=\"TEXT\"<\/code> - text shown when the guest opens the page too early. If omitted, a translated default message is shown.<\/li>\n<\/ul><\/dd>\n<dt id=\"can%20i%20pre-fill%20the%20guest%20registration%20form%20from%20a%20url%3F\"><h3>Can I pre-fill the guest registration form from a URL?<\/h3><\/dt>\n<dd><p>Yes. The <code>[vstrb_guest_registration]<\/code> shortcode reads the following GET parameters and pre-fills the corresponding form fields:<\/p>\n\n<ul>\n<li><code>date_from<\/code> - check-in date (format: <code>YYYY-MM-DD<\/code>)<\/li>\n<li><code>date_to<\/code> - check-out date (format: <code>YYYY-MM-DD<\/code>)<\/li>\n<li><code>first_name<\/code> - guest's first name (pre-fills the first guest block)<\/li>\n<li><code>last_name<\/code> - guest's last name (pre-fills the first guest block)<\/li>\n<li><code>source<\/code> - booking source; accepted values: <code>booking_com<\/code>, <code>airbnb<\/code>, <code>vrbo<\/code>, <code>expedia<\/code>, <code>direct<\/code>, <code>other<\/code><\/li>\n<li><code>booking_ref<\/code> - booking reference number<\/li>\n<li><code>accommodation<\/code> - external accommodation name used to resolve the apartment when <code>[vstrb_guest_registration param=\"accommodation\"]<\/code> is used<\/li>\n<\/ul>\n\n<p>Example URL:\n    https:\/\/bayernrelax.eu\/en\/accommodation-instructions\/?accommodation=[PROPERTY_NAME]&amp;date_from=2026-07-01&amp;date_to=2026-07-07&amp;first_name=John&amp;last_name=Doe&amp;source=booking_com&amp;booking_ref=1234567890<\/p>\n\n<p>This is useful when sending a registration link directly from a booking confirmation email.<\/p><\/dd>\n<dt id=\"how%20do%20admin%20price%20offers%20work%20for%20imported%20reservations%3F\"><h3>How do admin price offers work for imported reservations?<\/h3><\/dt>\n<dd><p>Open <strong>Bookings<\/strong>, click <strong>Offer<\/strong> on any reservation, and use the <strong>Price offer<\/strong> panel. The plugin calculates the price from the current reservation unit, dates, guest count, services, seasonal rates, discounts, surcharges, and refundable deposit settings.<\/p>\n\n<p>You can add a one-time manual discount as a fixed amount or percentage. The generated result is saved back to the booking total and into the booking price breakdown, so notification emails and admin details show the same final amount.<\/p>\n\n<p>For imported iCal reservations from e-chalupy.cz, Booking.com, Airbnb, and similar channels, the guest email is often not stored as the booking customer email. In that case you can enter any recipient in <strong>Send offer to email<\/strong>. If the iCal description contains an email address, the field is prefilled automatically.<\/p>\n\n<p>Each offer also has a private public link in <strong>Public price offer link<\/strong>. Copy that URL and send it manually through any channel. The link uses a random token and displays only the price offer page for that booking.<\/p>\n\n<p>The email sent from the price offer panel includes the offer summary and the same public price offer link.<\/p><\/dd>\n<dt id=\"how%20do%20i%20show%20limited%20booking%20details%20to%20cleaners%20or%20staff%3F\"><h3>How do I show limited booking details to cleaners or staff?<\/h3><\/dt>\n<dd><p>Go to <strong>Apartments -&gt; Settings -&gt; Notifications<\/strong> and add one staff access rule per line:<\/p>\n\n<pre><code>cleaner@example.com|unit,dates,guests|departure|cs_CZ|1\nreception@example.com|unit,dates,guests,contact|arrival|de_DE|3\nmanager@example.com|all|all|en_US|1\n<\/code><\/pre>\n\n<p>The format is <code>email|fields|events|language|days_before<\/code>.<\/p>\n\n<p>The fields part controls visible information in staff emails and the staff frontend shortcode. The events part controls which staff emails are sent. The optional language part controls the language of staff emails for that address; use locale codes such as <code>cs_CZ<\/code>, <code>de_DE<\/code>, or <code>en_US<\/code>. If it is omitted, the site language is used. The optional days_before part controls how many days before an arrival or departure reminder is sent. Use <code>0<\/code> for the same day, <code>1<\/code> for one day before, <code>3<\/code> for three days before, etc. If you want days_before without a language, use either <code>email|fields|events||3<\/code> or the shorthand <code>email|fields|events|3<\/code>.<\/p>\n\n<p>Available fields:<\/p>\n\n<ul>\n<li><code>unit<\/code> - apartment name.<\/li>\n<li><code>dates<\/code> - stay dates.<\/li>\n<li><code>guests<\/code> - guest count.<\/li>\n<li><code>status<\/code> - booking status.<\/li>\n<li><code>source<\/code> - booking source.<\/li>\n<li><code>customer<\/code> - customer name.<\/li>\n<li><code>contact<\/code> - customer email and phone.<\/li>\n<li><code>price<\/code> - booking total and currency.<\/li>\n<li><code>note<\/code> - booking note.<\/li>\n<li><code>booking_reference<\/code> - external booking reference on guest registrations.<\/li>\n<li><code>guest_names<\/code> - names submitted in guest registrations.<\/li>\n<li><code>all<\/code> - allow all fields.<\/li>\n<\/ul>\n\n<p>Available events:<\/p>\n\n<ul>\n<li><code>new_booking<\/code> - email when a new booking is created.<\/li>\n<li><code>registration<\/code> - email when guest registration details are submitted.<\/li>\n<li><code>arrival<\/code> - email before check-in, using the rule's days_before value.<\/li>\n<li><code>departure<\/code> - email before checkout, using the rule's days_before value.<\/li>\n<li><code>ical_cancelled<\/code> - email when a future imported iCal reservation disappears from its source feed and is treated as cancelled.<\/li>\n<li><code>all<\/code> - receive all staff emails.<\/li>\n<\/ul>\n\n<p>For a cleaner who should not see prices or guest contact details and should only receive checkout reminders, use:<\/p>\n\n<pre><code>cleaner@example.com|unit,dates,guests|departure|cs_CZ|1\n<\/code><\/pre>\n\n<p>For a reception or handover person who should only receive arrival reminders, use:<\/p>\n\n<pre><code>reception@example.com|unit,dates,guests,contact|arrival|de_DE|3\n<\/code><\/pre>\n\n<p>Then create a WordPress page or post, optionally protect it with a WordPress password, and add:<\/p>\n\n<pre><code>[vstrb_staff_bookings email=\"cleaner@example.com\" days=\"30\"]\n<\/code><\/pre>\n\n<p>Optional shortcode parameters:<\/p>\n\n<ul>\n<li><code>email=\"EMAIL\"<\/code> - staff rule to use.<\/li>\n<li><code>days=\"N\"<\/code> - number of upcoming days to display (default: <code>30<\/code>).<\/li>\n<li><code>unit=\"ID\"<\/code> - limit to one apartment.<\/li>\n<li><code>limit=\"N\"<\/code> - maximum number of bookings (default: <code>50<\/code>).<\/li>\n<li><code>include_registrations=\"0\"<\/code> - hide guest registration groups.<\/li>\n<li><code>status=\"all\"<\/code> - include cancelled and blocked bookings too.<\/li>\n<\/ul><\/dd>\n<dt id=\"how%20can%20ai%20posts%20be%20generated%20automatically%3F\"><h3>How can AI posts be generated automatically?<\/h3><\/dt>\n<dd><p>Open <strong>Bookings -&gt; AI Post Generator<\/strong> and use <strong>Scheduled AI generation profiles<\/strong>. Each profile can have its own source URLs or pasted source text, custom prompt, languages, category, draft\/publish status, notification email, and daily, weekly, or monthly schedule with a selected time.<\/p>\n\n<p>WordPress cron runs enabled profiles automatically. After each run, the configured notification email receives a summary telling whether new drafts are ready, posts were published, or errors occurred. The processed-source history is reused, so the same source is not generated repeatedly.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.0.1<\/h4>\n\n<ul>\n<li>Added localized Pro feature descriptions in the free plugin admin screen.<\/li>\n<li>Added localized Pro information links for Czech and German sites, with English as the default fallback.<\/li>\n<\/ul>\n\n<h4>2.0.0<\/h4>\n\n<ul>\n<li>Added an AI Post Generator for WordPress 7.0+ AI Client: create posts from source URLs or pasted text, choose target languages, and avoid duplicate generation with a processed-source history table.<\/li>\n<li>Improved AI Post Generator compatibility by avoiding optional model parameters unsupported by some AI providers.<\/li>\n<li>Reduced AI prompt size and increased the OpenAI HTTP timeout for generated posts.<\/li>\n<li>Added multi-item extraction for RSS\/Atom feeds, pages with article blocks, and same-site article listings.<\/li>\n<li>Added per-connector preferred model selection with provider pricing notes for the AI Post Generator.<\/li>\n<li>Added content-purpose prompt presets so event pages can create posts only from concrete events instead of summarizing the whole website.<\/li>\n<li>Added category selection for posts created by the AI Post Generator.<\/li>\n<li>Added scheduled AI generation profiles with independent daily, weekly, or monthly cron timing and completion emails.<\/li>\n<li>Added custom prompt instructions for manual and scheduled AI post generation.<\/li>\n<\/ul>\n\n<h4>1.9.29<\/h4>\n\n<ul>\n<li>Fixed translations<\/li>\n<\/ul>\n\n<h4>1.9.28<\/h4>\n\n<ul>\n<li>Added per-invoice language overrides so each saved invoice can be printed in a different language.<\/li>\n<\/ul>\n\n<h4>1.9.27<\/h4>\n\n<ul>\n<li>Added universal supplier billing settings for invoices, including configurable country\/region and tax ID labels.<\/li>\n<li>Added a separate invoice language setting for printable invoice pages and PDF output.<\/li>\n<li>Added printable invoice pages for saved invoice records with browser PDF saving support.<\/li>\n<li>Updated bundled translations for invoice supplier and PDF actions.<\/li>\n<\/ul>\n\n<h4>1.9.26<\/h4>\n\n<ul>\n<li>Fixed staff arrival\/departure reminders for imported iCal bookings saved as blocked reservations.<\/li>\n<li>Added an admin test form for sending staff notification emails from a single rule string.<\/li>\n<\/ul>\n\n<h4>1.9.25<\/h4>\n\n<ul>\n<li>Fixed guest registration booking matching so registrations can be linked to the only matching booking by stay dates even when the submitted apartment is not the correct one.<\/li>\n<li>Added admin controls to change the apartment for a guest registration group and pair it with bookings from other apartments.<\/li>\n<li>Added Guest Registrations admin filters for apartment, source, stay dates, guest\/email\/reference search, booking ID, and linked\/unlinked status.<\/li>\n<\/ul>\n\n<h4>1.9.24<\/h4>\n\n<ul>\n<li>feat: Add logic to skip importing unavailable Airbnb events<\/li>\n<li>feat: Update invoice number format to remove prefix and improve consistency<\/li>\n<li>feat: Remove price offer URL from email and update translations for payment details inclusion<\/li>\n<li>feat: Add invoice number generation and payment details inclusion for price offers<\/li>\n<li>chore: Bump version to 1.9.21 in readme and main plugin file<\/li>\n<\/ul>\n\n<h4>1.9.20<\/h4>\n\n<ul>\n<li>Fixed shortcode language handling so booking form labels, calendar labels, services, price breakdowns, and frontend messages consistently follow the <code>language<\/code> attribute.<\/li>\n<li>Fixed admin service lists to display service name translations for the current admin language, with fallback translations for default seeded services.<\/li>\n<li>Fixed customer email language handling and plain-text price formatting so localized messages do not mix languages or show escaped <code>&amp;nbsp;<\/code> entities.<\/li>\n<\/ul>\n\n<h4>1.9.19<\/h4>\n\n<ul>\n<li>Added <code>[vstrb_unit_arrival_instructions_by_reservation]<\/code> for displaying apartment arrival instructions by matching stay dates and guest name against bookings and linked guest registrations.<\/li>\n<li>Added local numeric date parsing for Booking.com-style URL parameters without UTC day shifts.<\/li>\n<li>Added cascaded matching: dates first, then both guest names, then last name, then first name, with accent-insensitive and case-insensitive name comparison.<\/li>\n<li>Added <code>available_days_before<\/code> and <code>unavailable_text<\/code> controls for reservation-matched arrival instructions.<\/li>\n<li>Added alphabetical fallback to the first apartment with arrival instructions when no unique reservation or registration match is found.<\/li>\n<\/ul>\n\n<h4>1.9.18<\/h4>\n\n<ul>\n<li>Reserved release.<\/li>\n<\/ul>\n\n<h4>1.9.17<\/h4>\n\n<ul>\n<li>Fixed iCal cleanup for e-chalupy imports stored under legacy provider source variants.<\/li>\n<li>Removed stale imported blocks whose stay has not ended yet when they disappear from the source feed.<\/li>\n<li>Improved the manual iCal import page so import results and feed timestamps are shown immediately after running an import.<\/li>\n<\/ul>\n\n<h4>1.9.16<\/h4>\n\n<ul>\n<li>Fixed iCal cleanup for legacy imported blocks stored as <code>ical_other<\/code> after provider normalization.<\/li>\n<\/ul>\n\n<h4>1.9.15<\/h4>\n\n<ul>\n<li>Added a translatable apartment amenities catalog with per-apartment amenity selection.<\/li>\n<li>Expanded the default amenities catalog with TV, streaming platforms, game consoles, balcony, terrace, pool, sauna, parking, accessibility, family, kitchen, bathroom, safety, and outdoor equipment.<\/li>\n<li>Added <code>[vstrb_unit_amenity_list]<\/code> for displaying translated apartment amenities.<\/li>\n<li>Removed the legacy <code>[vstrb_unit_amenities]<\/code> shortcode from the public shortcode list.<\/li>\n<\/ul>\n\n<h4>1.9.14<\/h4>\n\n<ul>\n<li>Added email notifications when a future imported iCal reservation disappears from the source feed and is treated as cancelled.<\/li>\n<li>Added the <code>ical_cancelled<\/code> staff notification event and updated bundled translations.<\/li>\n<\/ul>\n\n<h4>1.9.13<\/h4>\n\n<ul>\n<li>Added manual recipient email support for admin price offers, useful for imported iCal reservations where the channel email is not saved as the customer email.<\/li>\n<li>Added private public price offer links with token-based access so admins can copy and send a standalone offer page.<\/li>\n<li>Expanded readme documentation for admin price offers, imported reservations, manual discounts, email sending, and public offer links.<\/li>\n<\/ul>\n\n<h4>1.9.12<\/h4>\n\n<ul>\n<li>Added admin price offers for reservations, including automatic price generation, one-time manual discounts, saving the offer total, and emailing the offer to the guest.<\/li>\n<\/ul>\n\n<h4>1.9.10<\/h4>\n\n<ul>\n<li>Improved WordPress.org Plugin Check compliance for staff booking shortcodes, translation comments, input sanitization, and plugin textdomain loading.<\/li>\n<\/ul>\n\n<h4>1.9.9<\/h4>\n\n<ul>\n<li>Preserved URL query parameters after submitting a WordPress password-protected page password.<\/li>\n<\/ul>\n\n<h4>1.9.8<\/h4>\n\n<ul>\n<li>Added <code>[vstrb_unit_arrival_instructions_by_code]<\/code> shortcode for showing arrival instructions via a stable public apartment code.<\/li>\n<li>Added external accommodation name aliases for <code>[vstrb_unit_arrival_instructions_by_name]<\/code>.<\/li>\n<li>Added <code>[vstrb_guest_registration param=\"accommodation\"]<\/code> support for resolving a Booking.com <code>[PROPERTY_NAME]<\/code> URL parameter to a WordPress apartment title or alias.<\/li>\n<\/ul>\n\n<h4>1.9.7<\/h4>\n\n<ul>\n<li>Added <code>[vstrb_unit_arrival_instructions_by_name]<\/code> shortcode for showing arrival instructions by matching an accommodation name from a URL parameter to the apartment title.<\/li>\n<\/ul>\n\n<h4>1.9.6<\/h4>\n\n<ul>\n<li>Added optional per-staff days-before scheduling for arrival and departure reminders using the <code>email|fields|events|language|days_before<\/code> rule format.<\/li>\n<li>Staff reminder send tracking is now stored per event and per email address so different staff rules can use different reminder timing.<\/li>\n<\/ul>\n\n<h4>1.9.5<\/h4>\n\n<ul>\n<li>Added optional per-staff email language selection using the <code>email|fields|events|language<\/code> rule format.<\/li>\n<li>Updated bundled translations and documentation for staff notification language settings.<\/li>\n<\/ul>\n\n<h4>1.9.4<\/h4>\n\n<ul>\n<li>Added per-staff notification event selection so each email can receive only new booking, registration, arrival, or departure notices.<\/li>\n<li>Added staff arrival reminders one day before check-in.<\/li>\n<\/ul>\n\n<h4>1.9.3<\/h4>\n\n<ul>\n<li>Added automatic staff departure reminders one day before checkout, using the same per-email field permissions.<\/li>\n<\/ul>\n\n<h4>1.9.2<\/h4>\n\n<ul>\n<li>Added staff access rules for per-email field permissions in booking and guest registration notifications.<\/li>\n<li>Added <code>[vstrb_staff_bookings]<\/code> shortcode for password-protected staff pages that respect the same per-email permissions.<\/li>\n<li>Added Czech and bundled translation updates for staff access settings and labels.<\/li>\n<\/ul>\n\n<h4>1.9.1<\/h4>\n\n<ul>\n<li>Added apartment cloning - duplicate any apartment as a draft directly from the admin list.<\/li>\n<\/ul>\n\n<h4>1.9.0<\/h4>\n\n<ul>\n<li>Added multilingual bank transfer instructions through Apartment Content templates and per-apartment overrides.<\/li>\n<li>Added tolerant bank payment notification matching for common JSON, form, and simple XML payload shapes.<\/li>\n<li>Added support for bank payment placeholders such as <code>{{invoice_number}}<\/code>, <code>{{payment_amount}}<\/code>, and <code>{{payment_currency}}<\/code>.<\/li>\n<\/ul>\n\n<h4>1.8.3<\/h4>\n\n<ul>\n<li>Improved booking notification emails with the same detailed price breakdown shown in the frontend booking form.<\/li>\n<li>Stored a booking price snapshot for new direct bookings, including nights, accommodation, services, discounts, surcharges, refundable deposit, and final total.<\/li>\n<li>Filtered internal booking\/payment\/invoice metadata out of the custom contact fields section in notification emails.<\/li>\n<\/ul>\n\n<h4>1.8.2<\/h4>\n\n<ul>\n<li>Added template placeholder support for multilingual apartment content and arrival instruction emails.<\/li>\n<li>Added built-in placeholders for apartment details, site name, booking details, guest name, and stay dates.<\/li>\n<li>Added apartment-level custom placeholders with global and language-specific values, useful for door PINs, Wi-Fi passwords, parking notes, and similar reusable details.<\/li>\n<\/ul>\n\n<h4>1.8.1<\/h4>\n\n<ul>\n<li>Added reusable multilingual apartment content templates for descriptions, amenities, and arrival instructions.<\/li>\n<li>Added apartment-level multilingual overrides for descriptions, amenities, and arrival instructions.<\/li>\n<li>Added shortcodes for displaying apartment description, amenities, and arrival instructions on frontend pages.<\/li>\n<li>Added optional automated arrival instruction emails for confirmed bookings, configurable per apartment by number of days before check-in.<\/li>\n<li>Stored the booking form language with new direct bookings so arrival instruction emails can use the guest's language when available.<\/li>\n<\/ul>\n\n<h4>1.8.0<\/h4>\n\n<ul>\n<li>Added extended card payment diagnostics for Stripe and Mollie payments, including gateway status, gateway payment status, payment method type, safe card details, and provider timestamps where available.<\/li>\n<li>Displayed extended payment details in the bookings list and Invoices &amp; Transactions admin page.<\/li>\n<\/ul>\n\n<h4>1.7.9<\/h4>\n\n<ul>\n<li>Fixed Mollie webhook handling for webhook test events such as <code>hook.ping<\/code>, returning HTTP 200 instead of treating event IDs as payment IDs.<\/li>\n<\/ul>\n\n<h4>1.7.8<\/h4>\n\n<ul>\n<li>Fixed Mollie webhook route diagnostics by allowing GET checks on the webhook URL while keeping POST as the payment update handler.<\/li>\n<li>Removed duplicate REST route registration hook from the REST include file.<\/li>\n<\/ul>\n\n<h4>1.7.7<\/h4>\n\n<ul>\n<li>Added weekday-based Rates &amp; Discounts validity so prices, discounts, and surcharges can apply on selected days of the week.<\/li>\n<li>Added annual date\/range validity for Rates &amp; Discounts using yearless dates such as <code>1.5.<\/code>, <code>8.5.<\/code>, or <code>24.12.-26.12.<\/code> that repeat every year.<\/li>\n<\/ul>\n\n<h4>1.7.6<\/h4>\n\n<ul>\n<li>Fixed weekend pricing rules so weekend discounts and surcharges apply only to Friday-to-Saturday and Saturday-to-Sunday nights, not Sunday-to-Monday.<\/li>\n<li>Updated the Rates &amp; Discounts admin label to clarify that weekend pricing means weekend nights only.<\/li>\n<\/ul>\n\n<h4>1.7.5<\/h4>\n\n<ul>\n<li>Fixed closed days to display as Closed\/Zav\u0159eno instead of Occupied\/Obsazeno in the frontend calendar.<\/li>\n<li>Fixed closed-period calendar selection so closed days cannot be selected in the booking calendar.<\/li>\n<li>Added apartment closed-period rules for exact date ranges, recurring closed months, and recurring day ranges.<\/li>\n<li>Closed periods now appear as unavailable in the frontend calendar and block quote\/booking submissions.<\/li>\n<\/ul>\n\n<h4>1.7.4<\/h4>\n\n<ul>\n<li>Added global Rates &amp; Discounts rules for all apartments, with apartment-specific matching rules taking precedence.<\/li>\n<li>Added rate enable\/disable controls, cloning for rate groups, and an Always validity option.<\/li>\n<\/ul>\n\n<h4>1.7.3<\/h4>\n\n<ul>\n<li>Fixed Rates &amp; Discounts editing so updating an existing rate no longer duplicates currency values or applies the same discount multiple times.<\/li>\n<li>Added automatic cleanup for duplicate rate rows created by previous edits.<\/li>\n<li>Added setting <strong>Include Refundable Deposit in Online Payment<\/strong> to control whether refundable deposit is charged during online card payment.<\/li>\n<li>Improved stay adjustment flow and corrected refundable deposit placement in total calculations.<\/li>\n<li>Updated and standardized translation strings\/quote formatting across all bundled language files.<\/li>\n<\/ul>\n\n<h4>1.7.2<\/h4>\n\n<ul>\n<li>Added detailed discount and surcharge breakdown in frontend price summary, including full i18n support.<\/li>\n<li>Refactored pricing adjustment logic to clearly separate per-day and per-stay adjustments.<\/li>\n<li>Improved rates engine support for fixed amount and percentage discounts\/surcharges applied per stay.<\/li>\n<\/ul>\n\n<h4>1.7.1<\/h4>\n\n<ul>\n<li>Added refundable deposit support to booking flow, REST responses, and frontend quote display.<\/li>\n<li>Added\/updated localization strings for refundable deposit labels across bundled language packs.<\/li>\n<\/ul>\n\n<h4>1.7.0<\/h4>\n\n<ul>\n<li>Enhanced pricing calculations and discount breakdown handling in quote computation.<\/li>\n<\/ul>\n\n<h4>1.6.2<\/h4>\n\n<ul>\n<li>Fixed months translations in admin rates.<\/li>\n<li>Fixed sanitization\/unslashing in Rates admin save handler for <code>apply_mode<\/code>, <code>months_of_year<\/code>, <code>day_of_year_from<\/code>, and <code>day_of_year_to<\/code>.<\/li>\n<li>Fixed escaped output in Rates admin list (<code>date_scope<\/code>).<\/li>\n<li>Normalized line endings in <code>includes\/shortcodes.php<\/code> to avoid mixed line-ending warnings.<\/li>\n<\/ul>\n\n<h4>1.6.1<\/h4>\n\n<ul>\n<li>Improved calendar month navigation usability: previous\/next month names are now displayed next to left\/right arrow buttons.<\/li>\n<li>Fixed multi-month calendar navigation hint so the next arrow shows the month after the last visible month (e.g. with 3 visible months, the label points to month +4 from the first visible month).<\/li>\n<li>Added new recurring temporal scope modes for Rates &amp; Discounts: Specific dates, Selected months every year, and Day-of-year range every year (1-366, including wrap-around ranges).<\/li>\n<li>Extended pricing engine matching to support month-based and day-of-year recurring rate application without yearly date reconfiguration.<\/li>\n<li>Added admin validation for new recurring modes (at least one month required, valid day-of-year range inputs).<\/li>\n<li>Fixed admin form validation issue (An invalid form control with name='date_to' is not focusable) when switching from date mode to recurring modes.<\/li>\n<li>Added localization strings for all newly introduced Rates &amp; Discounts UI\/error labels across all bundled language files.<\/li>\n<li>Fixed encoding inconsistencies in localization files that could display replacement characters in some editors\/environments.<\/li>\n<li>Corrected missing diacritics and accented characters in multiple language packs (including cs_CZ, de_DE, es_ES, fr_FR, pl_PL, and pt_PT).<\/li>\n<li>Improved consistency of newly added payment and invoice translation strings across bundled .po files.<\/li>\n<\/ul>\n\n<h4>1.6.0<\/h4>\n\n<ul>\n<li>Added online payments support with Stripe integration, including configurable Stripe keys, webhook secret, and optional success\/cancel URLs.<\/li>\n<li>Added configurable payment methods in booking form shortcode: card (Stripe), bank transfer, and cash.<\/li>\n<li>Added payment return-state handling for successful\/failed payment confirmations in the frontend booking flow.<\/li>\n<li>Added new <strong>Invoices &amp; Transactions<\/strong> admin page for managing invoice and payment records.<\/li>\n<li>Added invoice editing tools in admin (status, number, amount, currency, paid timestamp, and billing fields).<\/li>\n<li>Added payment\/invoice filtering in admin by status, method, and booking ID.<\/li>\n<li>Added one-click <strong>Mark Paid<\/strong> workflow with invoice matching and admin notices.<\/li>\n<li>Added optional auto-confirm booking behavior after successful payment matching.<\/li>\n<li>Extended settings with <strong>Payments &amp; Invoices<\/strong> section, Stripe setup guide, bank transfer instructions, and callback token support.<\/li>\n<li>Added and updated localization strings for payment and invoice features across bundled language files.<\/li>\n<\/ul>\n\n<h4>1.5.5<\/h4>\n\n<ul>\n<li>Extended guest registration form with optional billing details section (<code>Add Billing Details<\/code> button).<\/li>\n<li>Added billing fields storage for guest registration groups (<code>billing_name<\/code>, <code>company_id<\/code>, <code>vat_id<\/code>, billing address).<\/li>\n<li>Added <code>Edit contact<\/code> action in <strong>Bookings -&gt; Guest Registrations<\/strong> to update shared contact and billing data for a whole registration group.<\/li>\n<li>Added <code>Edit guest<\/code> action in registration detail rows to update individual guest identity\/document\/address fields.<\/li>\n<li>Added <code>Print invoice<\/code> action for registration groups with a one-click printable invoice page.<\/li>\n<li>Extended Guest Registrations CSV export with billing columns.<\/li>\n<li>Added translation keys for all newly introduced billing\/invoice\/edit labels across all bundled language files and recompiled <code>.mo<\/code> files.<\/li>\n<\/ul>\n\n<h4>1.5.4<\/h4>\n\n<ul>\n<li>Add offering details for WordPress setup<\/li>\n<li>Admin calendar booking form: CAPTCHA validation is now bypassed for users with <code>manage_options<\/code> to prevent <code>captcha_invalid<\/code> when creating bookings from wp-admin.<\/li>\n<li>Admin calendar booking form: minimum stay restriction is no longer enforced for users with <code>manage_options<\/code>, so admins can create manual short stays (e.g. 1 night) even if the apartment has a higher minimum.<\/li>\n<\/ul>\n\n<h4>1.5.3<\/h4>\n\n<ul>\n<li>added missing translations<\/li>\n<\/ul>\n\n<h4>1.5.2<\/h4>\n\n<ul>\n<li>fixed ical<\/li>\n<li>Fixed calendar nightly price preview to correctly use seasonal <code>replace<\/code> rates (for example <code>off_season<\/code>) instead of always falling back to apartment base price.<\/li>\n<li>Fixed calendar price preview for seasonal rates with <code>Min Nights &gt; 1<\/code> so the expected seasonal nightly price is still shown in day cells.<\/li>\n<li>Improved rate calculation chaining: <code>replace<\/code> rate is now applied first and then matching discount\/surcharge rate is applied on top (for example <code>1000<\/code> with <code>-10%<\/code> now shows <code>900<\/code>).<\/li>\n<li>Moved calendar discount highlighting from a global setting to per-rate control (<code>Highlight in calendar<\/code>) in <strong>Rates &amp; Discounts<\/strong>.<\/li>\n<li>Added rates cache version invalidation on rate save\/delete to ensure calendar reflects updated rate values immediately.<\/li>\n<li>Fixed rule precedence for overlapping <code>replace<\/code> rates: explicit finite date-window overrides (e.g. September\/Autumn) now correctly take precedence over broad seasonal windows like <code>off_season<\/code>.<\/li>\n<li>Fixed calendar preview sorting when <code>Min Nights<\/code> is ignored: <code>min_nights<\/code> no longer incorrectly dominates rule ordering in day-cell price calculation.<\/li>\n<\/ul>\n\n<h4>1.5.1<\/h4>\n\n<ul>\n<li>feat: Enhance iCal export functionality and improve price label localization<\/li>\n<li>update: Optimize calendar day cell layout and styling<\/li>\n<li>feat: Add <code>cal_only<\/code> mode for accurate surcharge and discount calculations<\/li>\n<li>update: Simplify plugin references and add styling enhancements with external link<\/li>\n<\/ul>\n\n<h4>1.5.0<\/h4>\n\n<ul>\n<li>Added optional per-night price display directly in calendar day cells. Configure in <strong>General Settings -&gt; Calendar Price Display<\/strong> (global default) or override per apartment in the apartment editor (Details metabox). Three modes: hidden (default), show nightly price, or show discount\/surcharge delta only. For per-person pricing modes, the nightly price is calculated using the apartment's configured capacity. Rates with a minimum stay requirement higher than 1 night are excluded from the calendar display.<\/li>\n<li>Added minimum price support for calendars and new \"from price\" labels to clarify displayed pricing context.<\/li>\n<li>Added configurable styling options for calendar price badges, including badge background\/text colors, badge size, discount strip color, surcharge strip color, and price-mode label color\/size\/style.<\/li>\n<li>Added bold and italic styling options for the calendar price-mode label.<\/li>\n<li>Added support for distinguishing discount and surcharge badges in calendar rendering.<\/li>\n<li>Improved diff price display in calendar and enhanced badge visibility\/readability.<\/li>\n<li>Added localization strings for calendar price display settings.<\/li>\n<li>Added localization strings for pricing labels across all bundled language files.<\/li>\n<\/ul>\n\n<h4>1.4.9<\/h4>\n\n<ul>\n<li>Fixed service names displaying in wrong language when using a multilingual plugin (e.g. Polylang): REST endpoints now correctly switch locale using the full locale code resolved via the active multilingual plugin.<\/li>\n<li>Replaced static CAPTCHA (<code>2 + 3<\/code>) with a server-signed dynamic math challenge (random addition or subtraction of small numbers). The correct answer is HMAC-signed with a 30-minute expiry - impossible to bypass by hardcoding the answer.<\/li>\n<\/ul>\n\n<h4>1.4.8<\/h4>\n\n<ul>\n<li>Added <code>language<\/code> attribute to <code>[vstrb_booking_form]<\/code> shortcode - sets the locale for services, contact field labels, and price quote. Priority: shortcode attribute -&gt; page language (<code>&lt;html lang&gt;<\/code>) -&gt; visitor's browser language.<\/li>\n<li>Extended API requests to include locale data for services, contact fields, and price quote.<\/li>\n<\/ul>\n\n<h4>1.4.7<\/h4>\n\n<ul>\n<li>Added new youtube video tutorial<\/li>\n<\/ul>\n\n<h4>1.4.6<\/h4>\n\n<ul>\n<li>Fixed multi-month calendar grid rendering in frontend booking form\/calendar.<\/li>\n<li>The <code>grid<\/code> shortcode attribute now consistently controls the number of month columns (e.g. <code>grid=\"1\"<\/code> = one column).<\/li>\n<li>Reworked calendar month container layout to CSS Grid for predictable month alignment across breakpoints.<\/li>\n<\/ul>\n\n<h4>1.4.5<\/h4>\n\n<ul>\n<li>Added booking edit mode in <strong>Bookings<\/strong> admin list.<\/li>\n<li>Internal bookings can now be edited fully (dates, guest\/contact details, status, pricing fields, note, etc.).<\/li>\n<li>Imported iCal bookings are now protected and allow editing only of the internal note.<\/li>\n<li>Updating internal booking dates now safely rebuilds occupied-day locks and refreshes calendar cache.<\/li>\n<li>Added registration-to-booking linking for guest document registrations.<\/li>\n<li>Automatic booking pairing now runs on guest registration submit only when an exact 100% match is found.<\/li>\n<li>Added manual pairing\/unpairing UI for registration groups in <strong>Guest Registrations<\/strong>.<\/li>\n<\/ul>\n\n<h4>1.4.4<\/h4>\n\n<ul>\n<li>Minor changes<\/li>\n<\/ul>\n\n<h4>1.4.3<\/h4>\n\n<ul>\n<li>Minor changes<\/li>\n<\/ul>\n\n<h4>1.4.2<\/h4>\n\n<ul>\n<li>Reworked JavaScript output to follow WordPress enqueue best practices: removed inline <code>&lt;script&gt;<\/code> tags from PHP templates and moved logic to <code>wp_add_inline_script()<\/code> attached to enqueued plugin handles.<\/li>\n<li>Ensured admin assets are loaded not only on plugin submenu pages, but also on <code>vstrb_unit<\/code> edit\/list screens (<code>edit.php<\/code>, <code>post.php<\/code>, <code>post-new.php<\/code>) where plugin JS is needed.<\/li>\n<li>Removed unnecessary <code>load_plugin_textdomain()<\/code> call for WordPress.org-hosted translation loading.<\/li>\n<li>Kept REST route <code>permission_callback<\/code> handling explicit and unchanged for intended public endpoints.<\/li>\n<li>Improved Plugin Check compatibility by normalizing line endings in core plugin files (<code>includes\/shortcodes.php<\/code>, <code>includes\/db.php<\/code>, <code>includes\/admin.php<\/code>, <code>includes\/cpt.php<\/code>).<\/li>\n<li>Refactored CPT POST array handling to use <code>filter_input()<\/code> helper access, reducing false-positive nonce warnings while keeping nonce validation in <code>save_meta()<\/code>.<\/li>\n<li>Security hardening: replaced non-sanitizing request reads with explicit sanitization\/validation in admin and CPT input helpers (<code>get_param_*<\/code>, <code>request_param_int<\/code>, <code>post_array<\/code>, checkbox handling, and meta save processing).<\/li>\n<li>Security hardening: strengthened REST payload validation for JSON shape, dates (<code>YYYY-MM<\/code> \/ <code>YYYY-MM-DD<\/code>), currency codes, scalar text fields, and email addresses before processing or storage.<\/li>\n<li>Security hardening: improved output escaping of generated markup in admin\/shortcodes (<code>wp_kses()<\/code> with allowed markup map) and escaped conditional CSS class output in calendar rendering.<\/li>\n<li>Security hardening: sanitized inline assets before enqueue (<code>wp_add_inline_script<\/code> \/ <code>wp_add_inline_style<\/code>) to prevent unsafe tag injection.<\/li>\n<li>iCal export endpoint now returns a proper <code>WP_REST_Response<\/code> with calendar headers instead of direct <code>echo<\/code> output.<\/li>\n<li>Email notification hardening: validate recipient addresses with <code>sanitize_email()<\/code> + <code>is_email()<\/code> and sanitize dynamic summary\/meta text values.<\/li>\n<li>Normalized line endings in additional files flagged by Plugin Check (<code>includes\/emails.php<\/code>, <code>includes\/ical.php<\/code>, <code>includes\/rest.php<\/code>).<\/li>\n<li>Synced <code>readme.txt<\/code> Stable tag with plugin version header (<code>1.4.2<\/code>).<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>Project renamed from name Free Short-Term Rental Booking to Vachr Short-Term Rental Reservations <\/li>\n<\/ul>\n\n<h4>1.3.5<\/h4>\n\n<ul>\n<li>Guest Registrations admin table now groups multiple guests from the same stay into a single collapsible row. Click \"Show guests\" to expand and see individual guest details (name, date of birth, nationality, document, address).<\/li>\n<li>Added \"Delete group\" action to remove all guests belonging to the same registration group at once.<\/li>\n<li>If no booking reference is provided during guest registration, a unique internal reference is automatically generated (format: <code>VSTRB-{unit}-{date}-{random}<\/code>), ensuring guests submitted together are always correctly grouped.<\/li>\n<li>Fixed undefined array key warnings on fresh installations when visual settings have not been configured yet (<code>cal_date_size<\/code>, <code>cal_date_color<\/code>, <code>cal_lbl_size<\/code>, <code>cal_lbl_color<\/code>, <code>cal_h_size<\/code>, <code>cal_h_color<\/code>, <code>cal_h_align<\/code>, <code>frm_h_size<\/code>, <code>frm_h_color<\/code>).<\/li>\n<\/ul>\n\n<h4>1.3.4<\/h4>\n\n<ul>\n<li>Added <code>title<\/code> attribute to <code>[vstrb_guest_registration]<\/code> shortcode - allows setting a custom heading above the form. Defaults to the apartment name.<\/li>\n<li>Added <code>language<\/code> attribute to <code>[vstrb_guest_registration]<\/code> shortcode - renders all form labels in the specified locale (e.g. <code>cs_CZ<\/code>, <code>de_DE<\/code>). Uses <code>switch_to_locale()<\/code> \/ <code>restore_current_locale()<\/code> so the rest of the page is unaffected.<\/li>\n<li>Updated Shortcode Guide in the Apartments admin list with documentation and an example for both new attributes.<\/li>\n<\/ul>\n\n<h4>1.3.3<\/h4>\n\n<ul>\n<li>Replaced single \"Permanent Address\" field in guest registration form with three separate fields: Street, City, and Country.<\/li>\n<li>Added <code>street<\/code>, <code>city<\/code>, <code>state<\/code> columns to the guest registrations database table; existing installations are migrated automatically.<\/li>\n<li>Updated admin Guest Registrations table, notification emails, and all 11 language translations accordingly.<\/li>\n<\/ul>\n\n<h4>1.3.2<\/h4>\n\n<ul>\n<li>Extended guest registration form: added Booking Source dropdown (Booking.com, Airbnb, VRBO, Expedia, Direct, Other) and Booking Reference number field.<\/li>\n<li>Form fields can be pre-filled via GET parameters (<code>date_from<\/code>, <code>date_to<\/code>, <code>first_name<\/code>, <code>last_name<\/code>, <code>source<\/code>, <code>booking_ref<\/code>) - useful for linking directly from booking confirmation emails.<\/li>\n<li>Source and booking reference are stored in the database, shown in the admin Guest Registrations table, and included in admin notification emails.<\/li>\n<\/ul>\n\n<h4>1.3.1<\/h4>\n\n<ul>\n<li>Fixed guest registration form layout: corrected CSS container class, added <code>vstrb-field<\/code> flex styles and notice colours to <code>frontend.css<\/code>.<\/li>\n<li>Added full translations for guest registration feature in all 11 supported languages (cs_CZ, de_DE, es_ES, fr_FR, it_IT, ja, nl_NL, pl_PL, pt_PT, ru_RU, zh_CN).<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>Added <code>[vstrb_guest_registration unit=\"ID\"]<\/code> shortcode - a standalone registration form for guests who book through external channels (e.g. Booking.com). No WordPress account required.<\/li>\n<li>New database table <code>wp_vstrb_guest_registrations<\/code> stores: first name, last name, date of birth, permanent address, document type &amp; number, nationality, accommodation dates, and email - linked to a specific apartment.<\/li>\n<li>Submitted registrations trigger automatic email notifications to both the admin and the guest.<\/li>\n<li>New admin page <strong>Bookings -&gt; Guest Registrations<\/strong> with a filterable table overview and per-record delete action.<\/li>\n<\/ul>\n\n<h4>1.2.2<\/h4>\n\n<ul>\n<li>Added <code>Available Languages<\/code> setting in General Settings (comma-separated language codes).<\/li>\n<li>Service translation fields and Contact Fields language selectors now use only languages configured in General Settings.<\/li>\n<li>Improved language-list consistency between settings validation and admin forms.<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>Added surcharge operations (<code>Surcharge %<\/code> and <code>Surcharge $<\/code>) in Rates &amp; Discounts.<\/li>\n<li>Added a <code>Single Night Only<\/code> rule so you can target one-night stays precisely.<\/li>\n<li>Extended live price breakdown with a dedicated surcharge line.<\/li>\n<li>Improved live price breakdown for services: each selected service is now shown on its own line with quantity, unit price, and line total.<\/li>\n<li>Added support for unlimited validity on rates and discounts with a new No end date option.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Added minimum-stay discount tiers (e.g., weekly discounts), with longer stays taking precedence.<\/li>\n<li>Added a real-time price breakdown to the booking form so guests can see the final total before submitting.<\/li>\n<\/ul>\n\n<h4>1.1.1<\/h4>\n\n<ul>\n<li>Fixed iCal date handling by properly applying time zones for DTSTART\/DTEND and ensuring existing UID-matched imports update both booking ranges and occupied-day locks to prevent one-day discrepancies in the calendar.<\/li>\n<li>Improved iCal sync cleanup to remove only stale future imported blocked reservations (including cancellations from source channels) while preserving historical bookings.<\/li>\n<li>Fixed checkout\/checkin design<\/li>\n<li>Update nonce handling in admin forms for improved security<\/li>\n<li>Set the backend bookings list to default Date From to today, include ongoing\/future reservations (date_to &gt;= today), and sort by start date ascending by default.<\/li>\n<li>Fixed iCal provider normalization so Airbnb calendar URLs are consistently detected and stored as airbnb (not other), including automatic migration of legacy<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Initial release on WordPress.org.<\/li>\n<\/ul>","raw_excerpt":"A professional short-term rental booking engine for WordPress with two-way iCal synchronization.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/283320","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=283320"}],"author":[{"embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/chuckumi"}],"wp:attachment":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=283320"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=283320"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=283320"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=283320"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=283320"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=283320"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}