PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.8
Yatra – Travel Booking & Tour Operator Software v3.0.8
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 2.0.10 All 83 releases
yatra / app / Core / Routing / PageContext.php

PageContext.php in Yatra – Travel Booking & Tour Operator Software 3.0.8, at app/Core/Routing/PageContext.php

142 lines 4.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Yatra\Core\Routing;
6
7 /**
8 * PageContext
9 *
10 * Per-request handoff between a page handler (which decides what to render and
11 * configures $wp_query) and the `template_include` filter (which actually swaps
12 * the theme template for a Yatra one).
13 *
14 * The previous design did `include $template; exit;` inside each handler. That
15 * bypassed WordPress's normal template-loader pipeline, so SEO/cache plugins,
16 * FSE template-hierarchy resolution, theme template-overrides, and downstream
17 * `wp_footer` hooks couldn't participate. PageContext is the seam that lets the
18 * handler decide, and lets WordPress drive.
19 *
20 * Lifecycle:
21 * 1. Handler calls PageContext::instance()->select($absolute_template_path).
22 * 2. Handler returns true (no include, no exit).
23 * 3. TemplateLoader::filterTemplateInclude() reads from the context and
24 * returns the Yatra template path; WP includes it normally.
25 * 4. PageContext is reset at the end of the request (PHP destruction).
26 *
27 * Stays a singleton on purpose: the WordPress request is itself a singleton,
28 * and the `template_include` filter has no way to receive an instance, so a
29 * static accessor is the pragmatic choice.
30 */
31 final class PageContext
32 {
33 private static ?PageContext $instance = null;
34
35 private ?string $templatePath = null;
36 private string $pageType = '';
37 private array $bodyClasses = [];
38 private array $data = [];
39 private bool $handled = false;
40
41 private function __construct() {}
42
43 public static function instance(): PageContext
44 {
45 if (self::$instance === null) {
46 self::$instance = new self();
47 }
48 return self::$instance;
49 }
50
51 /**
52 * Reset state — primarily for tests and edge cases (e.g. an internal redirect).
53 */
54 public static function reset(): void
55 {
56 self::$instance = null;
57 }
58
59 /**
60 * Mark the current request as handled by Yatra and select the template to render.
61 *
62 * @param string $absolutePath Absolute path to a readable PHP template file.
63 * @param string $pageType Logical page type (e.g. 'trip', 'listing', 'account').
64 * Used for body_class hints and FSE template name.
65 * @return bool true on success, false if the path is invalid.
66 */
67 public function select(string $absolutePath, string $pageType = ''): bool
68 {
69 if ($absolutePath === '' || !is_readable($absolutePath)) {
70 return false;
71 }
72 $this->templatePath = $absolutePath;
73 $this->pageType = $pageType;
74 $this->handled = true;
75 return true;
76 }
77
78 public function hasTemplate(): bool
79 {
80 return $this->handled && $this->templatePath !== null;
81 }
82
83 public function getTemplate(): ?string
84 {
85 return $this->templatePath;
86 }
87
88 public function getPageType(): string
89 {
90 return $this->pageType;
91 }
92
93 public function isHandled(): bool
94 {
95 return $this->handled;
96 }
97
98 /**
99 * Add one or more body classes that should appear on Yatra pages.
100 *
101 * @param string|string[] $class
102 */
103 public function addBodyClass($class): void
104 {
105 $classes = is_array($class) ? $class : [$class];
106 foreach ($classes as $c) {
107 $c = (string) $c;
108 if ($c !== '' && !in_array($c, $this->bodyClasses, true)) {
109 $this->bodyClasses[] = $c;
110 }
111 }
112 }
113
114 /**
115 * @return string[]
116 */
117 public function getBodyClasses(): array
118 {
119 return $this->bodyClasses;
120 }
121
122 /**
123 * Stash arbitrary handler-side data that the template_include filter or
124 * downstream hooks might want to read. Avoid using this for data the
125 * template itself needs — pass that through globals/query vars as today.
126 *
127 * @param mixed $value
128 */
129 public function set(string $key, $value): void
130 {
131 $this->data[$key] = $value;
132 }
133
134 /**
135 * @return mixed
136 */
137 public function get(string $key, $default = null)
138 {
139 return array_key_exists($key, $this->data) ? $this->data[$key] : $default;
140 }
141 }
142