PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.17
Yatra – Travel Booking & Tour Operator Software v3.0.17
3.0.17 3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 All 85 releases
← All changes | app/Services/SettingsService.php +68 -6 3.0.7 → 3.0.17 View file →
@@ -45,8 +45,10 @@
45 45 /** Primary brand color (hex) for trip/booking/listing frontend — see FrontendThemeCss */
46 46 'frontend_primary_color' => '#3b82f6',
47 47 /** Max width for Yatra trip/booking/listing containers (CSS length). Empty = theme.json / content width / filter. */
48 48 'frontend_container_max_width' => '',
49 + /** Trip listing card density: 'standard' | 'compact_mobile' | 'compact_all'. */
50 + 'frontend_listing_card_layout' => 'standard',
49 51
50 52 // Booking
51 53 'booking_base' => 'book',
52 54 'use_booking_page' => false,
@@ -55,8 +57,13 @@
55 57 'privacy_policy_page_id' => 0,
56 58 'enable_guest_booking' => true,
57 59 'booking_confirmation' => true,
58 60 'auto_confirm_bookings' => false,
61 + // Auto-confirm mode: none | online | all. Default 'online' (successful
62 + // online payment => confirmed). Behaviour is resolved via
63 + // yatra_get_auto_confirm_mode(), which uses the stored mode when set and
64 + // otherwise derives from the legacy auto_confirm_bookings boolean.
65 + 'auto_confirm_mode' => 'online',
59 66 'require_login' => false,
60 67 'allow_guest_checkout' => true,
61 68 // Hold guest bookings in `pending_verification` status until
62 69 // the customer clicks a magic link sent to the email they
@@ -74,8 +81,12 @@
74 81 // gracefully by skipping the cancellation paragraph or
75 82 // falling back to the per-trip cancellation_policy.
76 83 'booking_expiry_hours' => 24,
77 84 'booking_reminder_days' => 3,
85 + // Storefront booking horizon in months. 12 is the value that was
86 + // hard-coded before it became configurable, so a site that never
87 + // touches it behaves exactly as before. See yatra_get_availability_horizon_months().
88 + 'availability_horizon_months' => 12,
78 89 'allow_waitlist' => true,
79 90 'waitlist_auto_confirm' => false,
80 91 // Pro: when enabled, the single-trip date_specific mode renders a
81 92 // <select> of available departure dates instead of the flatpickr
@@ -112,8 +123,12 @@
112 123 'email_from_address' => '',
113 124 'admin_email' => '',
114 125 'enable_admin_notifications' => true,
115 126 'enable_customer_notifications' => true,
127 + // Blind copy of every outgoing Yatra email, for archiving or monitoring.
128 + // Empty (the default) means no copy is sent, so existing sites are
129 + // unaffected. Accepts several comma-separated addresses.
130 + 'email_always_bcc' => '',
116 131
117 132 // Email template enable flags.
118 133 //
119 134 // These mirror SettingsController::$default_settings + the
@@ -131,8 +146,13 @@
131 146 // confirmation + every transactional email silently no-ops
132 147 // on those installs (sendIfEnabled gates on the flag).
133 148 'email_template_booking' => true,
134 149 'email_template_confirmation' => true,
150 + // Separate "part payment received" email. Off by default: existing sites
151 + // keep sending the single payment-received template for every payment,
152 + // exactly as before. Only meaningful when deposits / partial payments
153 + // are enabled.
154 + 'email_template_partial_payment' => false,
135 155 'email_template_cancellation' => true,
136 156 'email_template_reminder' => true,
137 157 'email_template_admin_new_booking' => true,
138 158 'email_template_admin_payment' => true,
@@ -139,8 +159,10 @@
139 159 'email_template_admin_cancellation' => true,
140 160 'email_template_trip_consent' => true,
141 161 'email_template_customer_verification' => true,
142 162 'email_template_guest_verification' => true,
163 + 'email_template_account_email_change' => true,
164 + 'email_template_account_email_changed' => true,
143 165 'email_template_booking_completed' => true,
144 166 'email_template_booking_expired_customer' => true,
145 167 'email_template_admin_booking_expired' => true,
146 168 'email_template_scheduled_payment_reminder' => true,
@@ -149,9 +171,18 @@
149 171 'email_template_admin_scheduled_payment_failed' => true,
150 172 'email_template_enquiry_received' => true,
151 173 'email_template_enquiry_admin' => true,
152 174 'email_template_enquiry_response' => true,
153 - 'email_template_review_request' => true,
175 + // Off by default, unlike the other templates. A review request is the
176 + // one transactional email that is not a response to something the
177 + // customer just did, and several jurisdictions treat it as advertising
178 + // rather than service mail — in Germany the BGH (VI ZR 225/17) holds it
179 + // needs prior consent, and the existing-customer exemption in
180 + // §7 Abs. 3 UWG does not cover it. Shipping it on would have every new
181 + // site mailing customers for consent it has not collected, so the
182 + // operator turns it on once they have decided how they collect it.
183 + // Sites that already have it on are untouched.
184 + 'email_template_review_request' => false,
154 185 'email_template_abandoned_booking_recovery_first' => true,
155 186 'email_template_abandoned_booking_recovery_second' => true,
156 187 'email_template_abandoned_booking_recovery_final' => true,
157 188 // Customer-registration gate (AuthController::register reads
@@ -176,8 +207,12 @@
176 207 'search_show_destination' => true,
177 208 'search_show_activities' => true,
178 209 'search_show_duration' => true,
179 210 'search_show_budget' => true,
211 + // Opt-in (default false): show a date field that filters trips to those
212 + // with a departure on the selected date. Off by default so existing
213 + // search bars are unchanged on update.
214 + 'search_show_date' => false,
180 215 // Collapse the listing filter sidebar sections on mobile. Default false
181 216 // = today's behaviour (all sections expanded on every viewport), so an
182 217 // existing site sees no change on update until the owner opts in.
183 218 'collapse_filters_on_mobile' => false,
@@ -192,9 +227,13 @@
192 227 'require_booking_to_review' => false,
193 228 'auto_approve_reviews' => false,
194 229 'enable_review_moderation' => true,
195 230 'minimum_rating' => 1,
196 - 'review_reminder_days' => 7,
231 + 'review_reminder_days' => 3,
232 + // Never ask about a trip that ended longer ago than this. The
233 + // reminder is anchored to the tour's end date, so a backlog of
234 + // bookings completed late is skipped rather than mailed in bulk.
235 + 'review_reminder_max_age_days' => 14,
197 236
198 237 // Tax
199 238 'enable_tax' => false,
200 239 'tax_rate' => 0,
@@ -216,8 +255,18 @@
216 255 'destination_base' => 'destination',
217 256 'activity_base' => 'activity',
218 257 'trip_category_base' => 'trip-category',
219 258
259 + // SEO
260 + 'enable_sitemap' => true,
261 + // Which Yatra content types appear in /yatra-sitemap.xml. Defaults to
262 + // every type, so a site that never touches this keeps today's sitemap.
263 + 'sitemap_types' => ['archive', 'trip', 'destination', 'activity', 'category'],
264 + // Opt-in, and deliberately separate from the list above: dropping a type
265 + // from the sitemap is housekeeping, while noindex de-indexes pages that
266 + // may currently rank. That should never happen as a side effect.
267 + 'sitemap_noindex_excluded' => false,
268 +
220 269 // Advanced
221 270 'enable_debug_mode' => false,
222 271 'delete_data_on_uninstall' => false,
223 272
@@ -300,12 +349,17 @@
300 349 }
301 350
302 351 /**
303 352 * Get booking form configuration (merged with defaults)
304 - *
353 + *
354 + * @param int|null $tripId Trip being booked. When given, Pro's Dynamic Form
355 + * Field module resolves each section's per-trip
356 + * conditions for that trip (title, description and
357 + * field list); without it the full config is
358 + * returned, conditions included (the Settings editor).
305 359 * @return array
306 360 */
307 - public static function getBookingFormConfig(): array
361 + public static function getBookingFormConfig(?int $tripId = null): array
308 362 {
309 363 $saved_config = self::get('booking_form_config', []);
310 364 $default_config = self::getDefaultBookingFormConfig();
311 365
@@ -310,9 +364,9 @@
310 364 $default_config = self::getDefaultBookingFormConfig();
311 365
312 366 // If no saved config, return defaults (Pro may filter)
313 367 if (empty($saved_config)) {
314 - return apply_filters('yatra_booking_form_config', $default_config);
368 + return apply_filters('yatra_booking_form_config', $default_config, $tripId);
315 369 }
316 370
317 371 // Merge saved over defaults. IMPORTANT: `fields` is a positional list,
318 372 // so a naive array_replace_recursive() merges field-by-INDEX — which
@@ -402,9 +456,9 @@
402 456 $merged[$form_type] = $saved_section;
403 457 }
404 458 }
405 459
406 - return apply_filters('yatra_booking_form_config', $merged);
460 + return apply_filters('yatra_booking_form_config', $merged, $tripId);
407 461 }
408 462
409 463 private static function isEmailIdentityKey(string $key): bool
410 464 {
@@ -1039,8 +1093,16 @@
1039 1093 'scheduled_payment_days' => 15,
1040 1094 'scheduled_payment_installments' => 1,
1041 1095 'scheduled_payment_interval' => 30,
1042 1096 'scheduled_payment_reminder_days' => 3,
1097 + // Anchor for the remaining-balance schedule:
1098 + // 'booking' (default, backward-compatible) → balance charged
1099 + // scheduled_payment_days after the deposit.
1100 + // 'tour' → balance charged/collected balance_due_days BEFORE the
1101 + // tour start date, and bookings made within that window
1102 + // must pay in full up front.
1103 + 'balance_anchor' => 'booking',
1104 + 'balance_due_days' => 14,
1043 1105 ];
1044 1106 }
1045 1107
1046 1108 private static function isScheduledPaymentSetting(string $key): bool