Passed
Push — master ( 9604c7...90a7ba )
by
unknown
01:48
created

Response::redirect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 3
dl 0
loc 4
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
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
	public static function response() {
19
		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
	 * @param  ResponseInterface $response
27
	 * @return null
28
	 */
29
	public static function respond( ResponseInterface $response ) {
30
		if ( ! headers_sent() ) {
31
			static::sendHeaders( $response );
32
		}
33
		static::sendBody( $response );
34
	}
35
36
	/**
37
	 * Send a request's headers to the client
38
	 *
39
	 * @param  ResponseInterface $response
40
	 * @return null
41
	 */
42
	protected static function sendHeaders( $response ) {
43
		// Status
44
		header( sprintf(
45
			'HTTP/%s %s %s',
46
			$response->getProtocolVersion(),
47
			$response->getStatusCode(),
48
			$response->getReasonPhrase()
49
		) );
50
51
		// Headers
52
		foreach ( $response->getHeaders() as $name => $values ) {
53
			foreach ( $values as $value ) {
54
				header( sprintf( '%s: %s', $name, $value ), false );
55
			}
56
		}
57
	}
58
59
	/**
60
	 * Send a request's body to the client
61
	 *
62
	 * @param  ResponseInterface $response
63
	 * @return null
64
	 */
65
	protected static function sendBody( $response, $chunk_size = 4096 ) {
66
		$body = $response->getBody();
67
		if ( $body->isSeekable() ) {
68
			$body->rewind();
69
		}
70
71
		$content_length = $response->getHeaderLine( 'Content-Length' );
72
		if ( ! $content_length ) {
73
			$content_length = $body->getSize();
74
		}
75
76
		$content_left = $content_length ? $content_length : -1;
77
		$amount_to_read = $content_left > -1 ? min( $chunk_size, $content_left ) : $chunk_size;
78
		while ( ! $body->eof() ) {
79
			echo $body->read( $amount_to_read );
80
81
			if ( $content_left > -1 ) {
82
				$content_left -= $amount_to_read;
83
			}
84
85
			if ( connection_status() != CONNECTION_NORMAL ) {
86
				break;
87
			}
88
		}
89
	}
90
91
	/**
92
	 * Return a cloned response with the passed string as the body
93
	 * 
94
	 * @param  Psr7Response $response
95
	 * @param  string       $output
96
	 * @return Psr7Response
97
	 */
98
	public static function output( Psr7Response $response, $output ) {
99
		$response = $response->withBody( Psr7\stream_for( $output ) );
100
		return $response;
101
	}
102
103
	/**
104
	 * Return a cloned response, resolving and rendering a template as the body
105
	 * 
106
	 * @param  Psr7Response    $response
107
	 * @param  string|string[] $templates
108
	 * @param  array           $context
109
	 * @return Psr7Response
110
	 */
111
	public static function template( Psr7Response $response, $templates, $context = array() ) {
112
		$templates = is_array( $templates ) ? $templates : [$templates];
113
		$template = locate_template( $templates, false );
0 ignored issues
show
Bug introduced by
The function locate_template was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

113
		$template = /** @scrutinizer ignore-call */ locate_template( $templates, false );
Loading history...
114
115
		$engine = Framework::resolve( 'framework.templating.engine' );
116
		$html = $engine->render( $template, $context );
117
118
		$response = $response->withHeader( 'Content-Type', 'text/html' );
119
		$response = $response->withBody( Psr7\stream_for( $html ) );
120
		return $response;
121
	}
122
123
	/**
124
	 * Return a cloned response, json encoding the passed array as the body
125
	 * 
126
	 * @param  Psr7Response $response
127
	 * @param  array        $data
128
	 * @return Psr7Response
129
	 */
130
	public static function json( Psr7Response $response, $data ) {
131
		$response = $response->withHeader( 'Content-Type', 'application/json' );
132
		$response = $response->withBody( Psr7\stream_for( wp_json_encode( $data ) ) );
0 ignored issues
show
Bug introduced by
The function wp_json_encode was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

132
		$response = $response->withBody( Psr7\stream_for( /** @scrutinizer ignore-call */ wp_json_encode( $data ) ) );
Loading history...
133
		return $response;
134
	}
135
136
	/**
137
	 * Return a cloned response, with location and status headers
138
	 * 
139
	 * @param  Psr7Response $response
140
	 * @param  string       $url
141
	 * @param  integer      $status
142
	 * @return Psr7Response
143
	 */
144
	public static function redirect( Psr7Response $response, $url, $status = 302 ) {
145
		$response = $response->withStatus( $status );
146
		$response = $response->withHeader( 'Location', $url );
147
		return $response;
148
	}
149
150
	/**
151
	 * Return a cloned response, with status headers and rendering a suitable template as the body
152
	 * 
153
	 * @param  Psr7Response $response
154
	 * @param  integer      $status
155
	 * @return Psr7Response
156
	 */
157
	public static function error( Psr7Response $response, $status ) {
158
		global $wp_query;
159
		if ( $status === 404 ) {
160
			$wp_query->set_404();
161
		}
162
163
		$response = $response->withStatus( $status );
164
		return static::template( $response, array( $status . '.php', 'index.php' ) );
165
	}
166
}
167