WordPress_GitHub_Sync_Base_Client::call()   C
last analyzed

Complexity

Conditions 8
Paths 7

Size

Total Lines 36
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 8

Importance

Changes 0
Metric Value
cc 8
eloc 23
nc 7
nop 3
dl 0
loc 36
ccs 26
cts 26
cp 1
crap 8
rs 5.3846
c 0
b 0
f 0
1
<?php
2
/**
3
 * Base API client class.
4
 * @package WordPress_GitHub_Sync
5
 */
6
7
/**
8
 * Class WordPress_GitHub_Sync_Base_Client
9
 */
10
class WordPress_GitHub_Sync_Base_Client {
11
12
	const TOKEN_OPTION_KEY = 'wpghs_oauth_token';
13
	const REPO_OPTION_KEY = 'wpghs_repository';
14
	const HOST_OPTION_KEY = 'wpghs_host';
15
16
	/**
17
	 * Application container.
18
	 *
19
	 * @var WordPress_GitHub_Sync
20
	 */
21
	protected $app;
22
23
	/**
24
	 * Instantiates a new Api object.
25
	 *
26
	 * @param WordPress_GitHub_Sync $app Application container.
27
	 */
28 19
	public function __construct( WordPress_GitHub_Sync $app ) {
29 19
		$this->app = $app;
30 19
	}
31
32
	/**
33
	 * Generic GitHub API interface and response handler
34
	 *
35
	 * @param string $method HTTP method.
36
	 * @param string $endpoint API endpoint.
37
	 * @param array  $body Request body.
38
	 *
39
	 * @return stdClass|WP_Error
40
	 */
41 16
	protected function call( $method, $endpoint, $body = array() ) {
42 16
		if ( is_wp_error( $error = $this->can_call() ) ) {
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->can_call(); of type WP_Error|boolean adds the type boolean to the return on line 43 which is incompatible with the return type documented by WordPress_GitHub_Sync_Base_Client::call of type stdClass|WP_Error.
Loading history...
43 3
			return $error;
44
		}
45
46
		$args = array(
47 13
			'method'  => $method,
48
			'headers' => array(
49 13
				'Authorization' => 'token ' . $this->oauth_token(),
50 13
			),
51 13
		);
52
53 13
		if ( 'GET' !== $method ) {
54 5
			$args['body'] = function_exists( 'wp_json_encode' ) ?
55 5
				wp_json_encode( $body ) :
56 5
				json_encode( $body );
57 5
		}
58
59 13
		$response = wp_remote_request( $endpoint, $args );
60 13
		$status   = wp_remote_retrieve_header( $response, 'status' );
61 13
		$body     = json_decode( wp_remote_retrieve_body( $response ) );
62
63 13
		if ( '2' !== substr( $status, 0, 1 ) && '3' !== substr( $status, 0, 1 ) ) {
64 7
			return new WP_Error(
65 7
				strtolower( str_replace( ' ', '_', $status ) ),
66 7
				sprintf(
67 7
					__( 'Method %s to endpoint %s failed with error: %s', 'wp-github-sync' ),
68 7
					$method,
69 7
					$endpoint,
70 7
					$body && $body->message ? $body->message : 'Unknown error'
71 7
				)
72 7
			);
73
		}
74
75 11
		return $body;
76
	}
77
78
	/**
79
	 * Validates whether the Api object can make a call.
80
	 *
81
	 * @return true|WP_Error
82
	 */
83 16
	protected function can_call() {
84 16
		if ( ! $this->oauth_token() ) {
85 1
			return new WP_Error(
86 1
				'missing_token',
87 1
				__( 'WordPress-GitHub-Sync needs an auth token. Please update your settings.', 'wp-github-sync' )
88 1
			);
89
		}
90
91 15
		$repo = $this->repository();
92
93 15
		if ( ! $repo ) {
94 1
			return new WP_Error(
95 1
				'missing_repository',
96 1
				__( 'WordPress-GitHub-Sync needs a repository. Please update your settings.', 'wp-github-sync' )
97 1
			);
98
		}
99
100 14
		$parts = explode( '/', $repo );
101
102 14
		if ( 2 !== count( $parts ) ) {
103 1
			return new WP_Error(
104 1
				'malformed_repository',
105 1
				__( 'WordPress-GitHub-Sync needs a properly formed repository. Please update your settings.', 'wp-github-sync' )
106 1
			);
107
		}
108
109 13
		return true;
110
	}
111
112
	/**
113
	 * Returns the repository to sync with
114
	 *
115
	 * @return string
116
	 */
117 16
	public function repository() {
118 16
		return (string) get_option( self::REPO_OPTION_KEY );
119
	}
120
121
	/**
122
	 * Returns the user's oauth token
123
	 *
124
	 * @return string
125
	 */
126 16
	public function oauth_token() {
127 16
		return (string) get_option( self::TOKEN_OPTION_KEY );
128
	}
129
130
	/**
131
	 * Returns the GitHub host to sync with (for GitHub Enterprise support)
132
	 */
133 16
	public function api_base() {
134 16
		return get_option( self::HOST_OPTION_KEY );
135
	}
136
137
	/**
138
	 * API endpoint for the master branch reference
139
	 */
140 14
	public function reference_endpoint() {
141 14
		$sync_branch = apply_filters( 'wpghs_sync_branch', 'master' );
142
143 14
		if ( ! $sync_branch ) {
144
			throw new Exception( __( 'Sync branch not set. Filter `wpghs_sync_branch` misconfigured.', 'wp-github-sync' ) );
145
		}
146
147 14
		$url = $this->api_base() . '/repos/';
148 14
		$url = $url . $this->repository() . '/git/refs/heads/' . $sync_branch;
149
150 14
		return $url;
151
	}
152
153
	/**
154
	 * Api to get and create commits
155
	 */
156 10
	public function commit_endpoint() {
157 10
		$url = $this->api_base() . '/repos/';
158 10
		$url = $url . $this->repository() . '/git/commits';
159
160 10
		return $url;
161
	}
162
163
	/**
164
	 * Api to get and create trees
165
	 */
166 9
	public function tree_endpoint() {
167 9
		$url = $this->api_base() . '/repos/';
168 9
		$url = $url . $this->repository() . '/git/trees';
169
170 9
		return $url;
171
	}
172
173
	/**
174
	 * Builds the proper blob API endpoint for a given post
175
	 *
176
	 * Returns String the relative API call path
177
	 */
178 2
	public function blob_endpoint() {
179 2
		$url = $this->api_base() . '/repos/';
180 2
		$url = $url . $this->repository() . '/git/blobs';
181
182 2
		return $url;
183
	}
184
185
	/**
186
	 * Builds the proper content API endpoint for a given post
187
	 *
188
	 * Returns String the relative API call path
189
	 */
190
	public function content_endpoint() {
191
		$url = $this->api_base() . '/repos/';
192
		$url = $url . $this->repository() . '/contents/';
193
194
		return $url;
195
	}
196
}
197