Passed
Push — master ( 682a54...fa63c5 )
by
unknown
01:55
created

Response   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 4

Test Coverage

Coverage 3.28%

Importance

Changes 0
Metric Value
dl 0
loc 178
ccs 2
cts 61
cp 0.0328
rs 10
c 0
b 0
f 0
wmc 25
lcom 0
cbo 4

10 Methods

Rating   Name   Duplication   Size   Complexity  
A response() 0 3 1
A output() 0 4 1
C sendBody() 0 25 8
A json() 0 5 1
A redirect() 0 5 1
A error() 0 9 2
A respond() 0 6 2
A sendHeaders() 0 16 3
B resolveTemplate() 0 16 5
A template() 0 10 1
1
<?php
2
3
namespace CarbonFramework;
4
5
use GuzzleHttp\Psr7;
6
use GuzzleHttp\Psr7\Response as Psr7Response;
7
use Psr\Http\Message\ResponseInterface;
8
9
/**
10
 * A collection of tools for the creation of responses
11
 */
12
class Response {
13
	/**
14
	 * Create a new response object
15
	 *
16
	 * @return Psr7Response
17
	 */
18 1
	public static function response() {
19 1
		return new Psr7Response();
20
	}
21
22
	/**
23
	 * Send output based on a response object
24
	 * @credit modified version of slimphp/slim - Slim/App.php
25
	 *
26
	 * @codeCoverageIgnore
27
	 * @param  ResponseInterface $response
28
	 * @return null
29
	 */
30
	public static function respond( ResponseInterface $response ) {
31
		if ( ! headers_sent() ) {
32
			static::sendHeaders( $response );
33
		}
34
		static::sendBody( $response );
35
	}
36
37
	/**
38
	 * Send a request's headers to the client
39
	 *
40
	 * @param  ResponseInterface $response
41
	 * @return null
42
	 */
43
	protected static function sendHeaders( $response ) {
44
		// Status
45
		header( sprintf(
46
			'HTTP/%s %s %s',
47
			$response->getProtocolVersion(),
48
			$response->getStatusCode(),
49
			$response->getReasonPhrase()
50
		) );
51
52
		// Headers
53
		foreach ( $response->getHeaders() as $name => $values ) {
54
			foreach ( $values as $value ) {
55
				header( sprintf( '%s: %s', $name, $value ), false );
56
			}
57
		}
58
	}
59
60
	/**
61
	 * Send a request's body to the client
62
	 *
63
	 * @param  ResponseInterface $response
64
	 * @return null
65
	 */
66
	protected static function sendBody( $response, $chunk_size = 4096 ) {
67
		$body = $response->getBody();
68
		if ( $body->isSeekable() ) {
69
			$body->rewind();
70
		}
71
72
		$content_length = $response->getHeaderLine( 'Content-Length' );
73
		if ( ! $content_length ) {
74
			$content_length = $body->getSize();
75
		}
76
77
		$content_left = $content_length ? $content_length : -1;
78
		$amount_to_read = $content_left > -1 ? min( $chunk_size, $content_left ) : $chunk_size;
79
		while ( ! $body->eof() ) {
80
			echo $body->read( $amount_to_read );
81
82
			if ( $content_left > -1 ) {
83
				$content_left -= $amount_to_read;
84
			}
85
86
			if ( connection_status() != CONNECTION_NORMAL ) {
87
				break;
88
			}
89
		}
90
	}
91
92
	/**
93
	 * Return a cloned response with the passed string as the body
94
	 *
95
	 * @param  Psr7Response $response
96
	 * @param  string       $output
97
	 * @return Psr7Response
98
	 */
99
	public static function output( Psr7Response $response, $output ) {
100
		$response = $response->withBody( Psr7\stream_for( $output ) );
101
		return $response;
102
	}
103
104
	/**
105
	 * Resolve a template or a template array to an absolute filepath
106
	 *
107
	 * @param  string|string[] $templates
108
	 * @return string
109
	 */
110
	protected static function resolveTemplate( $templates ) {
111
		$templates = is_array( $templates ) ? $templates : [$templates];
112
		$template = locate_template( $templates, false );
113
114
		// locate_template failed to find the template - test if a valid absolute path was passed
115
		if ( ! $template ) {
116
			foreach ( $templates as $tpl ) {
117
				if ( file_exists( $tpl ) ) {
118
					$template = $tpl;
119
					break;
120
				}
121
			}
122
		}
123
124
		return $template;
125
	}
126
127
	/**
128
	 * Return a cloned response, resolving and rendering a template as the body
129
	 *
130
	 * @param  Psr7Response    $response
131
	 * @param  string|string[] $templates
132
	 * @param  array           $context
133
	 * @return Psr7Response
134
	 */
135
	public static function template( Psr7Response $response, $templates, $context = array() ) {
136
		$template = static::resolveTemplate( $templates );
137
138
		$engine = Framework::resolve( 'framework.templating.engine' );
139
		$html = $engine->render( $template, $context );
140
141
		$response = $response->withHeader( 'Content-Type', 'text/html' );
142
		$response = $response->withBody( Psr7\stream_for( $html ) );
143
		return $response;
144
	}
145
146
	/**
147
	 * Return a cloned response, json encoding the passed data as the body
148
	 *
149
	 * @param  Psr7Response $response
150
	 * @param  mixed        $data
151
	 * @return Psr7Response
152
	 */
153
	public static function json( Psr7Response $response, $data ) {
154
		$response = $response->withHeader( 'Content-Type', 'application/json' );
155
		$response = $response->withBody( Psr7\stream_for( wp_json_encode( $data ) ) );
156
		return $response;
157
	}
158
159
	/**
160
	 * Return a cloned response, with location and status headers
161
	 *
162
	 * @param  Psr7Response $response
163
	 * @param  string       $url
164
	 * @param  integer      $status
165
	 * @return Psr7Response
166
	 */
167
	public static function redirect( Psr7Response $response, $url, $status = 302 ) {
168
		$response = $response->withStatus( $status );
169
		$response = $response->withHeader( 'Location', $url );
170
		return $response;
171
	}
172
173
	/**
174
	 * Return a cloned response, with status headers and rendering a suitable template as the body
175
	 *
176
	 * @param  Psr7Response $response
177
	 * @param  integer      $status
178
	 * @return Psr7Response
179
	 */
180
	public static function error( Psr7Response $response, $status ) {
181
		global $wp_query;
182
		if ( $status === 404 ) {
183
			$wp_query->set_404();
184
		}
185
186
		$response = $response->withStatus( $status );
187
		return static::template( $response, array( $status . '.php', 'index.php' ) );
188
	}
189
}
190