WordPress_GitHub_Sync_Payload   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 198
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Test Coverage

Coverage 70.69%

Importance

Changes 0
Metric Value
dl 0
loc 198
ccs 41
cts 58
cp 0.7069
rs 10
c 0
b 0
f 0
wmc 25
lcom 2
cbo 3

10 Methods

Rating   Name   Duplication   Size   Complexity  
C __construct() 0 27 7
A get_payload_from_raw_response() 0 23 3
C should_import() 0 36 7
A get_commit_id() 0 3 2
A get_author_email() 0 3 1
A get_commits() 0 3 1
A get_repository_name() 0 3 1
A has_error() 0 3 1
A get_error() 0 3 1
A message() 0 3 1
1
<?php
2
/**
3
 * GitHub Webhook payload.
4
 * @package WordPress_GitHub_Sync
5
 */
6
7
/**
8
 * Class WordPress_GitHub_Sync_Payload
9
 */
10
class WordPress_GitHub_Sync_Payload {
11
12
	/**
13
	 * Application container.
14
	 *
15
	 * @var WordPress_GitHub_Sync
16
	 */
17
	protected $app;
18
19
	/**
20
	 * Payload data.
21
	 *
22
	 * @var stdClass
23
	 */
24
	protected $data;
25
26
	/**
27
	 * Payload error.
28
	 *
29
	 * @var null|string
30
	 */
31
	protected $error = null;
32
33
	/**
34
	 * WordPress_GitHub_Sync_Payload constructor.
35
	 *
36
	 * @param WordPress_GitHub_Sync $app      Application container.
37
	 * @param string                $raw_data Raw request data.
38
	 */
39 6
	public function __construct( WordPress_GitHub_Sync $app, $raw_data ) {
40 6
		$this->app  = $app;
41 6
		$this->data = $this->get_payload_from_raw_response( $raw_data );
42
43 6
		if ( null === $this->data ) {
44 1
			switch ( json_last_error() ) {
45 1
				case JSON_ERROR_DEPTH:
46
					$this->error = __( 'Maximum stack depth exceeded', 'wp-github-sync' );
47
					break;
48 1
				case JSON_ERROR_STATE_MISMATCH:
49
					$this->error = __( 'Underflow or the modes mismatch', 'wp-github-sync' );
50
					break;
51 1
				case JSON_ERROR_CTRL_CHAR:
52
					$this->error = __( 'Unexpected control character found', 'wp-github-sync' );
53
					break;
54 1
				case JSON_ERROR_SYNTAX:
55 1
					$this->error = __( 'Syntax error, malformed JSON', 'wp-github-sync' );
56 1
					break;
57
				case JSON_ERROR_UTF8:
58
					$this->error = __( 'Malformed UTF-8 characters, possibly incorrectly encoded', 'wp-github-sync' );
59
					break;
60
				default:
61
					$this->error = __( 'Unknown error', 'wp-github-sync' );
62
					break;
63 1
			}
64 1
		}
65 6
	}
66
67
68
	/**
69
	 * Attempts to get the JSON decoded string.
70
	 *
71
	 * @param string $raw_data A raw string from php://input
72 4
	 *
73
	 * @see    WordPress_GitHub_Sync_Request::read_raw_data()
74 4
	 *
75 1
	 * @return Object|null An object from JSON Decode or false if failure.
76
	 *
77
	 * @author JayWood <[email protected]>
78
	 */
79 3
	private function get_payload_from_raw_response( $raw_data ) {
80 3
81 3
		/*
82
		 * Try this the old way first, despite this not working in some servers. Assuming there's a flag
83 3
		 * at the Nginx or Apache level that auto-parses encoded strings.
84
		 */
85
		$maybe_decoded = json_decode( $raw_data );
86
		if ( null !== $maybe_decoded ) {
87 3
			return $maybe_decoded;
88 1
		}
89
90
		/*
91
		 * GitHub returns a raw string with Action and Payload keys by default, we have to parse that string
92 2
		 * using parse_str() and then grab the payload.
93
		 */
94 2
		parse_str( $raw_data, $decoded_data );
95
96
		if ( ! isset( $decoded_data['payload'] ) ) {
97
			return null;
98 2
		}
99 1
100
		return json_decode( $decoded_data['payload'] );
101
	}
102 1
103
	/**
104
	 * Returns whether payload should be imported.
105
	 *
106 1
	 * @return bool
107
	 */
108
	public function should_import() {
109
		// @todo how do we get this without importing the whole api object just for this?
110
		if ( strtolower( $this->data->repository->full_name ) !== strtolower( $this->app->api()->fetch()->repository() ) ) {
111
			return false;
112
		}
113
114 2
		// The last term in the ref is the payload_branch name.
115 2
		$refs   = explode( '/', $this->data->ref );
116
		$payload_branch = array_pop( $refs );
117
		$sync_branch = apply_filters( 'wpghs_sync_branch', 'master' );
118
119
		if ( ! $sync_branch ) {
120
			throw new Exception( __( 'Sync branch not set. Filter `wpghs_sync_branch` misconfigured.', 'wp-github-sync' ) );
121
		}
122
123 1
		if ( $sync_branch !== $payload_branch ) {
124 1
			return false;
125
		}
126
127
		// We add a tag to commits we push out, so we shouldn't pull them in again.
128
		$tag = apply_filters( 'wpghs_commit_msg_tag', 'wpghs' );
129
130
		if ( ! $tag ) {
131
			throw new Exception( __( 'Commit message tag not set. Filter `wpghs_commit_msg_tag` misconfigured.', 'wp-github-sync' ) );
132 1
		}
133 1
134
		if ( $tag === substr( $this->message(), -1 * strlen( $tag ) ) ) {
135
			return false;
136
		}
137
138
		if ( ! $this->get_commit_id() ) {
139
			return false;
140
		}
141
142
		return true;
143
	}
144
145
	/**
146
	 * Returns the sha of the head commit.
147
	 *
148
	 * @return string
149
	 */
150 1
	public function get_commit_id() {
151 1
		return $this->data->head_commit ? $this->data->head_commit->id : null;
152
	}
153
154
	/**
155
	 * Returns the email address for the commit author.
156
	 *
157
	 * @return string
158
	 */
159 1
	public function get_author_email() {
160 1
		return $this->data->head_commit->author->email;
161
	}
162
163
	/**
164
	 * Returns array commits for the payload.
165
	 *
166
	 * @return array
167
	 */
168 2
	public function get_commits() {
169 2
		return $this->data->commits;
170
	}
171
172
	/**
173
	 * Returns the repository's full name.
174
	 *
175
	 * @return string
176
	 */
177
	public function get_repository_name() {
178
		return $this->data->repository->full_name;
179
	}
180
181
	/**
182
	 * Return whether the payload has an error.
183
	 *
184
	 * @return bool
185
	 */
186
	public function has_error() {
187
		return $this->error !== null;
188
	}
189
190
	/**
191
	 * Return the payload error string.
192
	 *
193
	 * @return string|null
194
	 */
195
	public function get_error() {
196
		return $this->error;
197
	}
198
199
	/**
200
	 * Returns the payload's commit message.
201
	 *
202
	 * @return string
203
	 */
204
	protected function message() {
205
		return $this->data->head_commit->message;
206
	}
207
}
208