PluginProbe
Solid Performance – Your No-Code Caching, Performance, & Page Speed Solution / 1.3.0
Solid Performance – Your No-Code Caching, Performance, & Page Speed Solution v1.3.0
2.0.1 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.5.0 1.6.0 1.6.1 1.7.0 1.7.1 1.8.0 1.9.0 2.0.0
solid-performance / src / Performance / Http / Header.php

Header.php in Solid Performance – Your No-Code Caching, Performance, & Page Speed Solution 1.3.0, at src/Performance/Http/Header.php

190 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Holds HTTP headers.
4 *
5 * @see Header_Factory
6 *
7 * @since 1.0.0
8 *
9 * @package SolidWP\Performance
10 */
11
12 declare( strict_types=1 );
13
14 namespace SolidWP\Performance\Http;
15
16 /**
17 * Holds HTTP headers.
18 *
19 * @see Header_Factory
20 *
21 * @since 1.0.0
22 *
23 * @package SolidWP\Performance
24 */
25 class Header {
26
27 protected const UPPER = '_ABCDEFGHIJKLMNOPQRSTUVWXYZ';
28 protected const LOWER = '-abcdefghijklmnopqrstuvwxyz';
29
30 /**
31 * A list of response headers indexed by their header name.
32 *
33 * @var array<string, string[]>
34 */
35 private array $headers;
36
37 /**
38 * @param string[] $headers The list of raw HTTP headers.
39 */
40 public function __construct( array $headers ) {
41 $this->normalize_headers( $headers );
42 }
43
44 /**
45 * Returns headers.
46 *
47 * @param string|null $name The name of the header, or if null, all headers.
48 *
49 * @return array<string, string[]>
50 */
51 public function all( ?string $name = null ): array {
52 if ( null !== $name ) {
53 return $this->headers[ strtr( $name, self::UPPER, self::LOWER ) ] ?? [];
54 }
55
56 return $this->headers;
57 }
58
59 /**
60 * Returns true if the HTTP header is defined.
61 *
62 * @param string $name The header name.
63 *
64 * @return bool
65 */
66 public function has( string $name ): bool {
67 return array_key_exists( strtr( $name, self::UPPER, self::LOWER ), $this->all() );
68 }
69
70 /**
71 * Returns the first header by name.
72 *
73 * @param string $name The header name.
74 *
75 * @return string|null
76 */
77 public function get( string $name ): ?string {
78 $headers = $this->all( $name );
79
80 if ( ! $headers ) {
81 return null;
82 }
83
84 if ( null === $headers[0] ) {
85 return null;
86 }
87
88 return implode( ', ', $headers );
89 }
90
91 /**
92 * Returns true if the given HTTP header contains the given value.
93 *
94 * @param string $name The header name.
95 * @param string $value The header value to look for.
96 */
97 public function contains( string $name, string $value ): bool {
98 $header = $this->get( $name );
99
100 if ( null === $header ) {
101 return false;
102 }
103
104 return str_contains( $header, $value );
105 }
106
107 /**
108 * Returns true if the given HTTP header starts with the given value.
109 *
110 * @param string $name The header name.
111 * @param string $value The header value to look for.
112 *
113 * @return bool
114 */
115 public function starts_with( string $name, string $value ): bool {
116 $headers = $this->all( $name );
117
118 if ( ! $headers ) {
119 return false;
120 }
121
122 foreach ( $headers as $header_value ) {
123 if ( str_starts_with( strtolower( $header_value ), strtolower( $value ) ) ) {
124 return true;
125 }
126 }
127
128 return false;
129 }
130
131 /**
132 * Sets a header by name.
133 *
134 * @param string $name The header name.
135 * @param string|string[]|null $values The value or an array of values.
136 * @param bool $replace Whether to replace the actual value or not (true by default).
137 */
138 public function set( string $name, $values, bool $replace = true ): void {
139 $name = strtr( $name, self::UPPER, self::LOWER );
140
141 if ( is_array( $values ) ) {
142 $values = array_values( $values );
143
144 if ( true === $replace || ! isset( $this->headers[ $name ] ) ) {
145 $this->headers[ $name ] = $values;
146 } else {
147 $this->headers[ $name ] = array_merge( $this->headers[ $name ], $values );
148 }
149 } elseif ( true === $replace || ! isset( $this->headers[ $name ] ) ) {
150 $this->headers[ $name ] = [ $values ];
151 } else {
152 $this->headers[ $name ][] = $values;
153 }
154 }
155
156 /**
157 * Removes a header.
158 *
159 * @param string $name The header name.
160 *
161 * @return void
162 */
163 public function remove( string $name ): void {
164 unset( $this->headers[ strtr( $name, self::UPPER, self::LOWER ) ] );
165 }
166
167 /**
168 * Normalize and format the HTTP headers.
169 *
170 * @param string[] $headers The raw HTTP headers.
171 */
172 private function normalize_headers( array $headers ): void {
173 foreach ( $headers as $header => $content ) {
174 // Parse response type headers.
175 if ( str_contains( $content, ':' ) ) {
176 // Split the header into name and value parts.
177 [ $name, $value ] = explode( ':', $content, 2 ) + [ null, null ];
178
179 $name = strtr( trim( $name ), self::UPPER, self::LOWER );
180 $value = trim( $value );
181 } else {
182 $name = strtr( $header, self::UPPER, self::LOWER );
183 $value = $content;
184 }
185
186 $this->set( $name, $value, false );
187 }
188 }
189 }
190