PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
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 2.0.1 All 84 releases
← All changes | app/Helpers/FormatHelper.php +138 -2 3.0.10 → 3.0.16 View file →
@@ -304,8 +304,134 @@
304 304 return self::countryNames()[$code] ?? $code;
305 305 }
306 306
307 307 /**
308 + * Build a customer's postal address as display lines, for invoices and any
309 + * other document that has to show where the customer actually is.
310 + *
311 + * Two sources, in order of authority:
312 + * 1. The booking's own contact data — what the customer entered at the time
313 + * of purchase, which is what an invoice should reflect.
314 + * 2. The linked customer record, which carries the structured city / state /
315 + * postal code / country that the booking form does not always collect.
316 + *
317 + * @param object|array|null $booking Booking (or payment joined to one) carrying
318 + * contact_data / contact_country / customer_id.
319 + * @return string[] Non-empty address lines, ready to render one per line.
320 + */
321 + public static function customerAddressLines($booking): array
322 + {
323 + $get = static function ($source, string $key) {
324 + if (is_array($source)) {
325 + return $source[$key] ?? null;
326 + }
327 + if (is_object($source)) {
328 + return $source->$key ?? null;
329 + }
330 + return null;
331 + };
332 +
333 + $parts = ['address' => '', 'city' => '', 'state' => '', 'postal_code' => '', 'country' => ''];
334 +
335 + // 1. What the customer typed when booking.
336 + $contactData = $get($booking, 'contact_data');
337 + if (is_string($contactData) && $contactData !== '') {
338 + $contactData = json_decode($contactData, true);
339 + }
340 + if (is_array($contactData)) {
341 + foreach (array_keys($parts) as $key) {
342 + if (!empty($contactData[$key]) && is_scalar($contactData[$key])) {
343 + $parts[$key] = trim((string) $contactData[$key]);
344 + }
345 + }
346 + // The booking form stores the postcode under either name.
347 + if ($parts['postal_code'] === '' && !empty($contactData['zip'])) {
348 + $parts['postal_code'] = trim((string) $contactData['zip']);
349 + }
350 + }
351 +
352 + if ($parts['country'] === '') {
353 + $parts['country'] = trim((string) ($get($booking, 'contact_country') ?? ''));
354 + }
355 +
356 + // 2. Fill the gaps from the customer record.
357 + $customerId = (int) ($get($booking, 'customer_id') ?? 0);
358 + if ($customerId > 0 && in_array('', $parts, true)) {
359 + $customer = (new \Yatra\Repositories\CustomerRepository())->find($customerId);
360 +
361 + if ($customer) {
362 + foreach (array_keys($parts) as $key) {
363 + if ($parts[$key] === '' && !empty($customer->$key)) {
364 + $parts[$key] = trim((string) $customer->$key);
365 + }
366 + }
367 + }
368 + }
369 +
370 + // "City, State 12345" reads as one line; street and country get their own.
371 + $locality = trim(implode(', ', array_filter([$parts['city'], $parts['state']])));
372 + if ($parts['postal_code'] !== '') {
373 + $locality = trim($locality . ' ' . $parts['postal_code']);
374 + }
375 +
376 + $country = $parts['country'] !== '' ? self::getCountryName($parts['country']) : '';
377 +
378 + return array_values(array_filter([$parts['address'], $locality, $country], static function ($line) {
379 + return $line !== '';
380 + }));
381 + }
382 +
383 + /**
384 + * The operator's own business address, one entry per line.
385 + *
386 + * Settings hold the address in separate fields (street, city, state, postcode,
387 + * country) but documents only ever printed `company_address` — so everything
388 + * after the street silently vanished and the address looked truncated at its
389 + * final line. Composed the same way as {@see customerAddressLines()} so both
390 + * sides of a document read identically.
391 + *
392 + * @return list<string>
393 + */
394 + public static function companyAddressLines(): array
395 + {
396 + $get = static function (string $key): string {
397 + return trim((string) \Yatra\Services\SettingsService::get($key, ''));
398 + };
399 +
400 + $street = $get('company_address');
401 + $city = $get('company_city');
402 + $state = $get('company_state');
403 + $zip = $get('company_zip');
404 + $countryRaw = $get('company_country');
405 +
406 + // "City, State 12345" reads as one line; street and country get their own.
407 + $locality = trim(implode(', ', array_filter([$city, $state])));
408 + if ($zip !== '') {
409 + $locality = trim($locality . ' ' . $zip);
410 + }
411 +
412 + $country = $countryRaw !== '' ? self::getCountryName($countryRaw) : '';
413 +
414 + // The street field may itself carry line breaks (an operator pasting a full
415 + // address), so keep those as separate lines rather than one run-on entry.
416 + $lines = [];
417 + foreach (preg_split('/\R/', $street) ?: [] as $streetLine) {
418 + $streetLine = trim($streetLine);
419 + if ($streetLine !== '') {
420 + $lines[] = $streetLine;
421 + }
422 + }
423 +
424 + foreach ([$locality, $country] as $line) {
425 + if ($line !== '') {
426 + $lines[] = $line;
427 + }
428 + }
429 +
430 + return array_values($lines);
431 + }
432 +
433 + /**
308 434 * Canonical country list — single source of truth used by every
309 435 * country / nationality dropdown in both Free and Pro plugins.
310 436 *
311 437 * Returns the full ISO-3166-1 alpha-2 set (sovereign states +
@@ -674,10 +800,20 @@
674 800 */
675 801 public static function formatRatingStars(float $rating, bool $showNumber = false): string
676 802 {
677 803 $rating = max(0, min(5, $rating));
678 - $fullStars = (int) floor($rating);
679 - $hasHalfStar = ($rating - $fullStars) >= 0.5;
804 +
805 + // Rounds to the nearest half star (see yatra_rating_star_parts), so this
806 + // renderer agrees with the confirmation page and reviews block.
807 + if (function_exists('yatra_rating_star_parts')) {
808 + $parts = yatra_rating_star_parts($rating);
809 + $fullStars = $parts['full'];
810 + $hasHalfStar = $parts['half'];
811 + } else {
812 + $halves = (int) round($rating * 2);
813 + $fullStars = intdiv($halves, 2);
814 + $hasHalfStar = ($halves % 2) === 1;
815 + }
680 816
681 817 $html = '<span class="yatra-rating-stars">';
682 818
683 819 for ($i = 1; $i <= 5; $i++) {