Changeset 3796366
- Timestamp:
- 11/11/2026 01:08:04 PM (4 hours ago)
- Location:
- host-domination-booking-engine
- Files:
-
- 32 added
- 7 edited
-
tags/1.5.44 (added)
-
tags/1.5.44/assets (added)
-
tags/1.5.44/assets/css (added)
-
tags/1.5.44/assets/css/admin.css (added)
-
tags/1.5.44/assets/flatpickr (added)
-
tags/1.5.44/assets/flatpickr/flatpickr.min.css (added)
-
tags/1.5.44/assets/flatpickr/flatpickr.min.js (added)
-
tags/1.5.44/assets/flatpickr/it.js (added)
-
tags/1.5.44/assets/images (added)
-
tags/1.5.44/assets/images/booking-engine-pro-video-preview.webp (added)
-
tags/1.5.44/assets/js (added)
-
tags/1.5.44/assets/js/admin.js (added)
-
tags/1.5.44/assets/js/block-editor.js (added)
-
tags/1.5.44/assets/js/frontend-triangoli-1.1.22.js (added)
-
tags/1.5.44/assets/js/frontend.js (added)
-
tags/1.5.44/assets/js/global-selector.js (added)
-
tags/1.5.44/assets/room-property-cards (added)
-
tags/1.5.44/assets/room-property-cards/css (added)
-
tags/1.5.44/assets/room-property-cards/css/admin.css (added)
-
tags/1.5.44/assets/room-property-cards/css/calendar-preview.css (added)
-
tags/1.5.44/assets/room-property-cards/css/frontend.css (added)
-
tags/1.5.44/assets/room-property-cards/js (added)
-
tags/1.5.44/assets/room-property-cards/js/admin.js (added)
-
tags/1.5.44/assets/room-property-cards/js/calendar-preview.js (added)
-
tags/1.5.44/assets/room-property-cards/js/frontend.js (added)
-
tags/1.5.44/host-domination-booking-engine.php (added)
-
tags/1.5.44/includes (added)
-
tags/1.5.44/includes/class-hdbe-addons-manager.php (added)
-
tags/1.5.44/includes/class-hdbe-elementor-widget.php (added)
-
tags/1.5.44/includes/class-hdbe-room-property-cards.php (added)
-
tags/1.5.44/includes/class-hdbe-self-checkin.php (added)
-
tags/1.5.44/readme.txt (added)
-
trunk/assets/flatpickr/flatpickr.min.js (modified) (3 diffs)
-
trunk/assets/js/frontend-triangoli-1.1.22.js (modified) (1 diff)
-
trunk/assets/js/frontend.js (modified) (1 diff)
-
trunk/assets/room-property-cards/js/calendar-preview.js (modified) (1 diff)
-
trunk/host-domination-booking-engine.php (modified) (10 diffs)
-
trunk/includes/class-hdbe-room-property-cards.php (modified) (4 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
host-domination-booking-engine/trunk/assets/flatpickr/flatpickr.min.js
r3738709 r3796366 26 26 return false; 27 27 } 28 function monthName(d){ 29 try { return d.toLocaleDateString('en-US', {month:'long', year:'numeric'}); } 30 catch(e){ return d.getFullYear()+'-'+pad(d.getMonth()+1); } 28 // WordPress passes its public locale through Flatpickr's standard locale option. 29 // This bundled compact renderer also needs to honor it: the old implementation 30 // always formatted months with en-US, no matter which locale was selected. 31 function localeTag(opts){ 32 var raw = opts && opts.locale; 33 if (typeof raw === 'string' && raw && raw !== 'default') { 34 return raw.replace(/_/g, '-'); 35 } 36 if (raw && typeof raw === 'object' && typeof raw.code === 'string') { 37 return raw.code.replace(/_/g, '-'); 38 } 39 return 'en-US'; 40 } 41 function monthName(d, opts){ 42 var loc = opts && opts.locale; 43 if (loc && typeof loc === 'object' && loc.months && 44 loc.months.longhand && loc.months.longhand[d.getMonth()]) { 45 return loc.months.longhand[d.getMonth()] + ' ' + d.getFullYear(); 46 } 47 try { 48 return new Intl.DateTimeFormat(localeTag(opts), {month:'long', year:'numeric'}).format(d); 49 } catch(e) { 50 try { return d.toLocaleDateString('en-US', {month:'long', year:'numeric'}); } 51 catch(ignored){ return d.getFullYear()+'-'+pad(d.getMonth()+1); } 52 } 53 } 54 function weekdayInitials(opts){ 55 var loc = opts && opts.locale; 56 if (loc && typeof loc === 'object' && loc.weekdays && 57 Array.isArray(loc.weekdays.shorthand) && loc.weekdays.shorthand.length === 7) { 58 // Flatpickr locale arrays run Sunday to Saturday; this grid starts Monday. 59 return loc.weekdays.shorthand.slice(1).concat(loc.weekdays.shorthand[0]); 60 } 61 try { 62 var tag = localeTag(opts); 63 var fmt = new Intl.DateTimeFormat(tag, {weekday:'narrow'}); 64 var initials = []; 65 for (var day=0; day<7; day++) { 66 // 2024-01-01 is a Monday; choose local noon to avoid DST boundaries. 67 var label = fmt.format(new Date(2024, 0, 1 + day, 12)); 68 // Some locales (e.g. Catalan) use meaningful two-letter narrow 69 // abbreviations; keep them instead of truncating every day to 'D'. 70 if (Array.from(label).length === 1) label = label.toLocaleUpperCase(tag); 71 initials.push(label); 72 } 73 if (initials.every(function(label){ return label.length > 0; })) return initials; 74 } catch(e) {} 75 return (opts && Array.isArray(opts.weekdaysShort) && opts.weekdaysShort.length === 7) 76 ? opts.weekdaysShort : ['M','T','W','T','F','S','S']; 31 77 } 32 78 function build(input, opts){ … … 86 132 var title = document.createElement('div'); 87 133 title.className = 'flatpickr-current-month'; 88 title.textContent = monthName(month );134 title.textContent = monthName(month, opts); 89 135 90 136 let next = document.createElement('span'); … … 134 180 var weekdays = document.createElement('div'); 135 181 weekdays.className = 'flatpickr-weekdays'; 136 var weekdayLabels = (opts.weekdaysShort && opts.weekdaysShort.length === 7) 137 ? opts.weekdaysShort 138 : ['M','T','W','T','F','S','S']; 182 var weekdayLabels = weekdayInitials(opts); 139 183 weekdayLabels.forEach(function(w){ 140 184 var el=document.createElement('span'); el.className='flatpickr-weekday'; el.textContent=w; weekdays.appendChild(el); -
host-domination-booking-engine/trunk/assets/js/frontend-triangoli-1.1.22.js
r3791074 r3796366 674 674 maxDate: frontendMaxDate, 675 675 dateFormat: dateFormat, 676 locale: (localeCode === 'it' && window.flatpickr.l10ns && window.flatpickr.l10ns.it) ? window.flatpickr.l10ns.it : 'default',676 locale: localeCode, // Full WordPress/frontend locale (e.g. fr_FR), resolved per calendar. 677 677 weekdaysShort: weekdaysShort, 678 678 disable: [function(date){ return isFullyBlockedDay(date); }], -
host-domination-booking-engine/trunk/assets/js/frontend.js
r3791074 r3796366 600 600 maxDate: frontendMaxDate, 601 601 dateFormat: dateFormat, 602 locale: (localeCode === 'it' && window.flatpickr.l10ns && window.flatpickr.l10ns.it) ? window.flatpickr.l10ns.it : 'default',602 locale: localeCode, // Full WordPress/frontend locale (e.g. fr_FR), resolved per calendar. 603 603 weekdaysShort: weekdaysShort, 604 604 disable: [function(date){ return isFullyBlockedDay(date); }], -
host-domination-booking-engine/trunk/assets/room-property-cards/js/calendar-preview.js
r3791074 r3796366 39 39 } catch (e) { formatted = amount.toFixed(2) + ' ' + currency; } 40 40 var template = (window.HDRPCCalendarPreview && HDRPCCalendarPreview.priceLabel) || 'Nights from %s'; 41 $price.text(template.replace( '%s', formatted));41 $price.text(template.replace(/%1\$s|%s/g, formatted)); 42 42 } 43 43 $(function(){ -
host-domination-booking-engine/trunk/host-domination-booking-engine.php
r3791074 r3796366 4 4 * Plugin URI: https://hostdomination.com/booking-engine/ 5 5 * Description: Lightweight Booking Engine with Calendar Sync and Reservation Requests for Vacation Rentals, Apartments, B&Bs and Hosts. 6 * Version: 1.5. 336 * Version: 1.5.44 7 7 * Requires at least: 6.0 8 8 * Requires PHP: 7.4 … … 17 17 18 18 final class HDBE_Plugin { 19 const VERSION = '1.5. 33';19 const VERSION = '1.5.44'; 20 20 const DB_VERSION = '0.16.7'; 21 21 const OPT_SETTINGS = 'hdbe_settings'; … … 1086 1086 } 1087 1087 1088 /** 1089 * Locale announced by the actually loaded booking-engine gettext catalog. 1090 * HD BE Translate installs its own language packs for the guest-facing 1091 * interface, independently of the WordPress site or administrator locale. 1092 * Reading the *active* catalog avoids treating WordPress's WPLANG as the 1093 * definitive language for calendar labels. 1094 */ 1095 private static function loaded_booking_catalog_locale() { 1096 global $l10n; 1097 $domain = 'host-domination-booking-engine'; 1098 if (!isset($l10n[$domain]) && function_exists('__')) { 1099 // Allow WordPress/HD BE Translate to initialize the domain first. 1100 __('Available', $domain); 1101 } 1102 if (!isset($l10n[$domain]) || !is_object($l10n[$domain])) return ''; 1103 $translations = $l10n[$domain]; 1104 $locale = ''; 1105 if (method_exists($translations, 'get_header')) { 1106 $locale = (string) $translations->get_header('Language'); 1107 } 1108 if ('' === trim($locale) && (property_exists($translations, 'headers') || method_exists($translations, '__get'))) { 1109 // WordPress 6.5+ WP_Translations exposes headers through __get(), 1110 // not __isset(), so do not guard it with isset(). 1111 $headers = $translations->headers; 1112 if (is_array($headers)) { 1113 $locale = (string) ($headers['Language'] ?? $headers['language'] ?? ''); 1114 } 1115 } 1116 return self::normalize_public_booking_locale($locale); 1117 } 1118 1119 private static function normalize_public_booking_locale($locale) { 1120 $locale = trim(str_replace('-', '_', (string) $locale)); 1121 if (!preg_match('/^[A-Za-z]{2,3}(?:_[A-Za-z]{2,4})?$/D', $locale)) return ''; 1122 $parts = explode('_', $locale, 2); 1123 $lang = strtolower($parts[0]); 1124 $regional = ['en'=>'US', 'it'=>'IT', 'fr'=>'FR', 'es'=>'ES', 'de'=>'DE', 'pt'=>'PT', 'ca'=>'ES']; 1125 if (!in_array($lang, ['en','it','fr','es','de','pt','ca','eu'], true)) return ''; 1126 return $lang . '_' . (isset($parts[1]) ? strtoupper($parts[1]) : ($regional[$lang] ?? 'ES')); 1127 } 1128 1129 /** 1130 * Select the language of public booking content. HD BE Translate's loaded 1131 * frontend catalog (when available) takes priority over the WordPress 1132 * admin/site language. The documented hdbe_public_booking_locale filter 1133 * remains available for an explicit frontend-language selection; plugins 1134 * including HD BE Translate may use it to pass their selected language. 1135 * Otherwise ordinary multilingual plugins and WordPress still work. 1136 */ 1137 private static function public_booking_locale() { 1138 $locale = 'en_US'; // English source strings are the built-in default. 1139 if (function_exists('get_locale')) { 1140 $site_locale = (string) get_locale(); 1141 if (function_exists('is_admin') && is_admin() && function_exists('get_option')) { 1142 $site_locale = (string) get_option('WPLANG', ''); 1143 } 1144 $locale = self::normalize_public_booking_locale($site_locale) ?: 'en_US'; 1145 } 1146 1147 if (function_exists('pll_current_language')) { 1148 $selected = pll_current_language('locale'); 1149 if (is_string($selected)) { 1150 $locale = self::normalize_public_booking_locale($selected) ?: $locale; 1151 } 1152 } 1153 if (function_exists('has_filter') && has_filter('wpml_current_language')) { 1154 $selected = apply_filters('wpml_current_language', null); 1155 if (is_string($selected)) { 1156 $locale = self::normalize_public_booking_locale($selected) ?: $locale; 1157 } 1158 } 1159 1160 // The catalog's Language header is useful for diagnostics, NOT for 1161 // choosing the visitor's language: it could be a stale Italian MO. 1162 // The selected frontend language always wins over an old catalog. 1163 1164 // Highest-priority integration point for an explicit guest language. 1165 $selected = apply_filters('hdbe_public_booking_locale', $locale); 1166 return self::normalize_public_booking_locale($selected) ?: $locale; 1167 } 1168 1169 /** 1170 * Calendar-only language bridge for HD BE Translate. 1171 * 1172 * Language settings are independent of the WordPress site language. Respect 1173 * the explicit frontend selection first; use an explicit backend selection 1174 * only when no frontend language is selected. An actual frontend selection 1175 * must never be overwritten by the administration language. 1176 * 1177 * The translate client can override this without relying on option keys: 1178 * add_filter('hdbe_calendar_locale', fn($locale) => 'fr_FR'); 1179 */ 1180 private static function translate_client_calendar_locale() { 1181 if (!function_exists('get_option')) return ''; 1182 1183 // HD BE Translate 0.2.15 stores its Language tab at 'hdmlp_settings', 1184 // NOT at the speculative option names supported below for legacy add-ons. 1185 // Its existing public frontend-config callback resolves the *effective* 1186 // guest language, including 'auto' and external multilingual selectors. 1187 // Use that result rather than the WordPress administrator/site locale. 1188 if (class_exists('HDMLP_Client') && is_callable(['HDMLP_Client', 'filter_frontend_config'])) { 1189 $translated_config = HDMLP_Client::filter_frontend_config([]); 1190 if (is_array($translated_config)) { 1191 $resolved = self::normalize_public_booking_locale($translated_config['numberLocale'] ?? ''); 1192 if ($resolved) return $resolved; 1193 } 1194 } 1195 1196 // Compatibility when the client is installed but does not expose the 1197 // frontend config callback. Honor an explicitly selected frontend 1198 // language; 'auto' must still follow WordPress, not the backend locale. 1199 $hdmlp_settings = get_option('hdmlp_settings', []); 1200 if (is_array($hdmlp_settings) && isset($hdmlp_settings['frontend_locale'])) { 1201 $requested = (string) $hdmlp_settings['frontend_locale']; 1202 $resolved = self::normalize_public_booking_locale($requested); 1203 if ($resolved) return $resolved; 1204 if ('auto' === strtolower(trim($requested))) return ''; 1205 } 1206 1207 $settings_keys = [ 1208 'hdbe_translate_settings', 1209 'hdbe_translate_options', 1210 'hdbe_translate_language_settings', 1211 'hdbe_translate_client_settings', 1212 'hdbe_translate_preferences', 1213 'hdbe_language_settings', 1214 'hd_be_translate_settings', 1215 ]; 1216 $front_keys = [ 1217 'frontend_locale', 'frontend_language', 'front_end_locale', 1218 'front_end_language', 'front_locale', 'front_language', 1219 'language_frontend', 'locale_frontend', 'guest_locale', 1220 'guest_language', 'frontend_lang', 'front_lang', 1221 'frontend', 'front_end', 'front', 'public_language', 1222 ]; 1223 $back_keys = [ 1224 'backend_locale', 'backend_language', 'back_end_locale', 1225 'back_end_language', 'back_locale', 'back_language', 1226 'language_backend', 'locale_backend', 'admin_locale', 1227 'admin_language', 'backend_lang', 'back_lang', 1228 'backend', 'back_end', 'back', 'admin', 1229 ]; 1230 1231 $front = ''; 1232 $back = ''; 1233 foreach ($settings_keys as $key) { 1234 $settings = get_option($key, []); 1235 if (!is_array($settings)) continue; 1236 // Ignore unrelated values: only recognized, explicitly configured 1237 // locale fields are eligible for calendar localization. 1238 foreach ($front_keys as $field) { 1239 if (isset($settings[$field]) && is_string($settings[$field])) { 1240 $candidate = self::normalize_public_booking_locale($settings[$field]); 1241 if ($candidate) { $front = $candidate; break; } 1242 } 1243 } 1244 foreach ($back_keys as $field) { 1245 if (isset($settings[$field]) && is_string($settings[$field])) { 1246 $candidate = self::normalize_public_booking_locale($settings[$field]); 1247 if ($candidate) { $back = $candidate; break; } 1248 } 1249 } 1250 if ($front) break; 1251 } 1252 1253 $individual_options = [ 1254 'hdbe_translate_frontend_locale', 'hdbe_translate_frontend_language', 1255 'hdbe_translate_front_locale', 'hdbe_translate_front_language', 1256 'hd_be_translate_frontend_locale', 1257 ]; 1258 if (!$front) { 1259 foreach ($individual_options as $key) { 1260 $value = get_option($key, ''); 1261 if (!is_string($value)) continue; 1262 $front = self::normalize_public_booking_locale($value); 1263 if ($front) break; 1264 } 1265 } 1266 if (!$back) { 1267 foreach ([ 1268 'hdbe_translate_backend_locale', 'hdbe_translate_backend_language', 1269 'hdbe_translate_admin_locale', 'hdbe_translate_admin_language', 1270 'hd_be_translate_backend_locale', 1271 ] as $key) { 1272 $value = get_option($key, ''); 1273 if (!is_string($value)) continue; 1274 $back = self::normalize_public_booking_locale($value); 1275 if ($back) break; 1276 } 1277 } 1278 return $front ?: $back; 1279 } 1280 1281 /** 1282 * Localization of calendar month headings and weekday initials only. 1283 * Flatpickr's Intl implementation formats dates using this locale; the 1284 * form's other translations and the actual booking/calendar data remain 1285 * entirely untouched. 1286 */ 1287 private static function calendar_display_locale() { 1288 $fallback = self::public_booking_locale(); 1289 1290 // If the client supplies an explicit, validated selection via settings, 1291 // it takes precedence over the WordPress default locale. 1292 $selected = self::translate_client_calendar_locale(); 1293 if (!$selected && function_exists('apply_filters')) { 1294 // Existing WordPress plugin-locale integration used by some 1295 // translation plugins. This may differ from get_locale(). 1296 $domain_locale = apply_filters('plugin_locale', $fallback, 'host-domination-booking-engine'); 1297 if (is_string($domain_locale)) { 1298 $candidate = self::normalize_public_booking_locale($domain_locale); 1299 if ($candidate && $candidate !== $fallback) $selected = $candidate; 1300 } 1301 } 1302 if (!$selected) { 1303 // A frontend language pack can be installed independently of 1304 // WordPress's site language. Only trust its active catalog when 1305 // the HD BE Translate client is actually enabled. 1306 $enabled = false; 1307 $active = (array) get_option('active_plugins', []); 1308 foreach ($active as $plugin_file) { 1309 if ('hd-be-translate/hd-be-translate.php' === $plugin_file) { 1310 $enabled = true; 1311 break; 1312 } 1313 } 1314 if ($enabled) $selected = self::loaded_booking_catalog_locale(); 1315 } 1316 $selected = $selected ?: $fallback; 1317 1318 // Highest priority: a direct integration from the client addon. 1319 // Keep the hook calendar-specific to avoid rewriting other UI strings. 1320 $selected = apply_filters('hdbe_calendar_locale', $selected, $fallback); 1321 return self::normalize_public_booking_locale($selected) ?: $fallback; 1322 } 1088 1323 1089 1324 /** … … 1177 1412 ]; 1178 1413 return $labels[$key] ?? $key; 1414 } 1415 1416 /** 1417 * Guest-facing copy is always translated from the installed gettext 1418 * catalog published by HD BE Translate Manager (English source msgids). 1419 * No hard-coded translations are maintained in the Booking Engine. 1420 * If the loaded catalog is for a DIFFERENT locale than the selected site/ 1421 * visitor language, refuse to display that foreign-language translation: 1422 * fall back to the original English string until the correct MO is loaded. 1423 */ 1424 private static function public_booking_text($key, $translated = null) { 1425 $sources = [ 1426 'min_nights_one' => 'Minimum %d night required', 1427 'min_nights_many' => 'Minimum %d nights required', 1428 'available' => 'Available', 1429 'busy' => 'Not available', 1430 'phone_placeholder' => 'Your phone number', 1431 'contact_phone_label' => 'Contact phone', 1432 'privacy_link' => 'Privacy Policy', 1433 'terms_link' => 'Terms and Conditions', 1434 'privacy_consent' => 'I have read and accept the %s.', 1435 'privacy_terms_consent' => 'I have read and accept the %1$s and %2$s.', 1436 ]; 1437 if (!isset($sources[$key])) return ''; 1438 1439 if (null === $translated) { 1440 switch ($key) { 1441 case 'min_nights_one': $translated = __('Minimum %d night required', 'host-domination-booking-engine'); break; 1442 case 'min_nights_many': $translated = __('Minimum %d nights required', 'host-domination-booking-engine'); break; 1443 case 'available': $translated = __('Available', 'host-domination-booking-engine'); break; 1444 case 'busy': $translated = __('Not available', 'host-domination-booking-engine'); break; 1445 case 'phone_placeholder': $translated = __('Your phone number', 'host-domination-booking-engine'); break; 1446 case 'contact_phone_label': $translated = __('Contact phone', 'host-domination-booking-engine'); break; 1447 case 'privacy_link': $translated = __('Privacy Policy', 'host-domination-booking-engine'); break; 1448 case 'terms_link': $translated = __('Terms and Conditions', 'host-domination-booking-engine'); break; 1449 case 'privacy_consent': $translated = __('I have read and accept the %s.', 'host-domination-booking-engine'); break; 1450 case 'privacy_terms_consent': $translated = __('I have read and accept the %1$s and %2$s.', 'host-domination-booking-engine'); break; 1451 } 1452 } 1453 1454 $catalog_locale = self::loaded_booking_catalog_locale(); 1455 $visitor_locale = self::public_booking_locale(); 1456 if ($catalog_locale !== '' && $visitor_locale !== '' && strcasecmp($catalog_locale, $visitor_locale) !== 0) { 1457 return $sources[$key]; 1458 } 1459 1460 return (string) $translated; 1461 } 1462 1463 private static function public_minimum_nights_text($nights) { 1464 $nights = max(1, (int) $nights); 1465 /* translators: %d is the minimum number of nights. */ 1466 $translated = _n('Minimum %d night required', 'Minimum %d nights required', $nights, 'host-domination-booking-engine'); 1467 $key = 1 === $nights ? 'min_nights_one' : 'min_nights_many'; 1468 $source = 1 === $nights ? 'Minimum %d night required' : 'Minimum %d nights required'; 1469 if ($translated === $source) { 1470 // Some language packs index simple gettext strings but not plurals. 1471 $translated = self::public_booking_text($key); 1472 } else { 1473 $translated = self::public_booking_text($key, $translated); 1474 } 1475 return sprintf($translated, $nights); 1179 1476 } 1180 1477 … … 3797 4094 'dateFormat' => 'd-m-Y', 3798 4095 'desktopCalendarMonths' => (int)($settings['desktop_calendar_months'] ?? 1) === 2 ? 2 : 1, 3799 'locale' => self::lang(), 4096 // Prefer the Language tab's explicit HD BE Translate choice over WordPress. 4097 // Month/day formatting only; booking data and prices are unchanged. 4098 'locale' => self::calendar_display_locale(), 3800 4099 'numberLocale' => self::frontend_locale(), 3801 4100 'weekdaysShort' => self::frontend_weekday_initials(), … … 3835 4134 // The base nightly price remains only a fallback when no advanced price exists for a day. 3836 4135 $frontend_config = apply_filters('hdbe_frontend_config', $frontend_config, $cal, $settings); 4136 // Calendar month/day labels honor HD BE Translate's explicit locale. 4137 // Re-apply after PRO filters so date/price extensions cannot override it. 4138 $frontend_config['locale'] = self::calendar_display_locale(); 3837 4139 // Reservation boundaries are owned by the base engine and must survive PRO config filters. 3838 4140 $frontend_config['bookings'] = $bookings_for_edges; … … 3897 4199 </div> 3898 4200 <?php /* translators: %d is the minimum required number of nights. */ ?> 3899 <span class="hdbe-min-nights-note"><?php echo esc_html(s printf(_n('Minimum %d night required', 'Minimum %d nights required', $hdbe_min_nights_front, 'host-domination-booking-engine'),$hdbe_min_nights_front)); ?></span>3900 <div class="hdbe-legend" >3901 <span><i class="hdbe-dot hdbe-dot-free"></i><?php echo esc_html(self:: t('available')); ?></span>3902 <span><i class="hdbe-dot hdbe-dot-busy"></i><?php echo esc_html(self:: t('busy')); ?></span>4201 <span class="hdbe-min-nights-note"><?php echo esc_html(self::public_minimum_nights_text($hdbe_min_nights_front)); ?></span> 4202 <div class="hdbe-legend" data-hdbe-calendar-locale="<?php echo esc_attr(self::calendar_display_locale()); ?>" data-hdbe-locale="<?php echo esc_attr(self::public_booking_locale()); ?>" data-hdbe-version="<?php echo esc_attr(self::VERSION); ?>" data-hdbe-catalog-locale="<?php echo esc_attr(self::loaded_booking_catalog_locale()); ?>"> 4203 <span><i class="hdbe-dot hdbe-dot-free"></i><?php echo esc_html(self::public_booking_text('available')); ?></span> 4204 <span><i class="hdbe-dot hdbe-dot-busy"></i><?php echo esc_html(self::public_booking_text('busy')); ?></span> 3903 4205 </div> 3904 4206 <div class="hdbe-error"></div> … … 3924 4226 <div class="hdbe-field"><label><?php echo esc_html__('Full name', 'host-domination-booking-engine'); ?></label><input name="guest_name" required placeholder="<?php echo esc_attr__('Full name', 'host-domination-booking-engine'); ?>"></div> 3925 4227 <div class="hdbe-field"><label><?php echo esc_html(self::t('email')); ?></label><input type="email" name="guest_email" required placeholder="email@example.com"></div> 3926 <div class="hdbe-field"><label><?php echo esc_html __('Contact phone', 'host-domination-booking-engine'); ?></label><input name="phone" required placeholder="<?php echo esc_attr__('Your phone number', 'host-domination-booking-engine'); ?>"></div>4228 <div class="hdbe-field"><label><?php echo esc_html(self::public_booking_text('contact_phone_label')); ?></label><input name="phone" required placeholder="<?php echo esc_attr(self::public_booking_text('phone_placeholder')); ?>"></div> 3927 4229 <?php 3928 4230 $max_guests_front = max(1, (int)($cal->max_guests ?? 2)); … … 3976 4278 <?php if ($privacy_policy_configured): ?> 3977 4279 <?php 3978 $privacy_link = '<a href="' . esc_url($privacy_policy_url) . '" target="_blank" rel="noopener noreferrer">' . esc_html __('Privacy Policy', 'host-domination-booking-engine') . '</a>';4280 $privacy_link = '<a href="' . esc_url($privacy_policy_url) . '" target="_blank" rel="noopener noreferrer">' . esc_html(self::public_booking_text('privacy_link')) . '</a>'; 3979 4281 if ($terms_and_conditions_url) { 3980 $terms_link = '<a href="' . esc_url($terms_and_conditions_url) . '" target="_blank" rel="noopener noreferrer">' . esc_html __('Terms and Conditions', 'host-domination-booking-engine') . '</a>';4282 $terms_link = '<a href="' . esc_url($terms_and_conditions_url) . '" target="_blank" rel="noopener noreferrer">' . esc_html(self::public_booking_text('terms_link')) . '</a>'; 3981 4283 $privacy_consent_text = sprintf( 3982 4284 /* translators: 1: Privacy Policy link, 2: Terms and Conditions link. */ 3983 __('I have read and accept the %1$s and %2$s.', 'host-domination-booking-engine'),4285 self::public_booking_text('privacy_terms_consent'), 3984 4286 $privacy_link, 3985 4287 $terms_link … … 3988 4290 $privacy_consent_text = sprintf( 3989 4291 /* translators: %s: Privacy Policy link. */ 3990 __('I have read and accept the %s.', 'host-domination-booking-engine'),4292 self::public_booking_text('privacy_consent'), 3991 4293 $privacy_link 3992 4294 ); -
host-domination-booking-engine/trunk/includes/class-hdbe-room-property-cards.php
r3791074 r3796366 9 9 10 10 final class HDBE_Free_Room_Property_Cards { 11 const VERSION = '1.5.3 3';11 const VERSION = '1.5.35'; 12 12 private static $admin_assets_enqueued = false; 13 13 const OPTION = 'hdbe_room_property_cards'; … … 282 282 'guestPlural' => __('guests', 'host-domination-booking-engine'), 283 283 /* translators: %s is the formatted nightly price. */ 284 'priceLabel' => __('Nights from %s', 'host-domination-booking-engine'),284 'priceLabel' => self::starting_price_label_template(), 285 285 'unsavedWarning' => __('You have unsaved property changes. Continue to card settings without saving?', 'host-domination-booking-engine'), 286 286 'locale' => str_replace('_', '-', determine_locale()), … … 628 628 $formatted = self::format_nightly_price((float) $card['starting_price'], (string) ($card['currency'] ?? 'EUR')); 629 629 /* translators: %s is the formatted currency amount (e.g. €85). */ 630 echo '<div class="hdrpc-card-nightly-price"' . (!empty($card['starting_price_is_advanced']) ? ' data-advanced-price="1"' : '') . '>' . '<span class="hdrpc-nightly-price-label">' . esc_html(sprintf( __('Nights from %s', 'host-domination-booking-engine'), $formatted)) . '</span></div>';630 echo '<div class="hdrpc-card-nightly-price"' . (!empty($card['starting_price_is_advanced']) ? ' data-advanced-price="1"' : '') . '>' . '<span class="hdrpc-nightly-price-label">' . esc_html(sprintf(self::starting_price_label_template(), $formatted)) . '</span></div>'; 631 631 } elseif ($preview && !empty($card['show_starting_price'])) { 632 632 echo '<div class="hdrpc-card-nightly-price" hidden><span class="hdrpc-nightly-price-label"></span></div>'; … … 743 743 } 744 744 745 /** 746 * Localized template for the nightly starting price displayed on public cards 747 * and the Property / Room editor's live preview. 748 * 749 * Keep the original gettext msgid for compatibility with existing HD BE 750 * Translate language packs. The fallback is only applied when that msgid 751 * has no translation for the selected public-booking language. 752 * Translators: keep %s (formatted nightly price) in the translation. 753 */ 754 private static function starting_price_label_template() { 755 $source = 'Nights from %s'; 756 /* translators: %s is the formatted starting price, for example €110. */ 757 $translated = __('Nights from %s', 'host-domination-booking-engine'); 758 759 $locale = function_exists('determine_locale') ? determine_locale() : get_locale(); 760 $locale = (string) apply_filters('hdbe_public_booking_locale', (string) $locale); 761 $locale = strtolower(str_replace('_', '-', $locale)); 762 $lang = explode('-', $locale)[0]; 763 $fallbacks = [ 764 'it' => 'Da %s a notte', 765 'es' => 'Desde %s por noche', 766 'fr' => 'À partir de %s par nuit', 767 'de' => 'Ab %s pro Nacht', 768 'pt' => 'A partir de %s por noite', 769 'eu' => 'Gau bakoitzeko %s-tik aurrera', 770 ]; 771 if ($translated === $source && isset($fallbacks[$lang])) { 772 $translated = $fallbacks[$lang]; 773 } 774 775 // Invalid / incomplete translations must not break sprintf or the JS 776 // preview when the source is customized by language packs or filters. 777 if (false === strpos($translated, '%s') && false === strpos($translated, '%1$s')) { 778 $translated = $fallbacks[$lang] ?? $source; 779 } 780 $translated = apply_filters('hdbe_room_property_card_nightly_price_label', $translated, $locale, $source); 781 return (is_string($translated) && (false !== strpos($translated, '%s') || false !== strpos($translated, '%1$s'))) 782 ? $translated : ($fallbacks[$lang] ?? $source); 783 } 784 745 785 private static function format_nightly_price($price, $currency) { 746 786 $amount = number_format_i18n($price, (abs($price - round($price)) < 0.0001 ? 0 : 2)); -
host-domination-booking-engine/trunk/readme.txt
r3791081 r3796366 5 5 Requires at least: 6.0 6 6 Tested up to: 7.1 7 Stable tag: 1.5. 337 Stable tag: 1.5.44 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later … … 577 577 == Changelog == 578 578 579 = 1.5.44 = 580 * Fixed: Calendar months and weekdays now display in the correct language. 581 * Improved: Full integration with HD BE Translate language settings. 582 * Localization: Improved translation support and English fallback. 583 579 584 = 1.5.33 = 580 585 * NEW! Bank Transfer Payments
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)