Passed
Push — master ( c00ab5...5ed1e2 )
by litefeel
03:01
created

lib/controller.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Controller object manages tree retrieval, manipulation and publishing
4
 * @package Writing_On_GitHub
5
 */
6
7
/**
8
 * Class Writing_On_GitHub_Controller
9
 */
10
class Writing_On_GitHub_Controller {
11
12
	/**
13
	 * Application container.
14
	 *
15
	 * @var Writing_On_GitHub
16
	 */
17
	public $app;
18
19
	/**
20
	 * Instantiates a new Controller object
21
	 *
22
	 * @param Writing_On_GitHub $app Applicatio container.
23
	 */
24
	public function __construct( Writing_On_GitHub $app ) {
25
		$this->app = $app;
26
	}
27
28
	/**
29
	 * Webhook callback as triggered from GitHub push.
30
	 *
31
	 * Reads the Webhook payload and syncs posts as necessary.
32
	 *
33
	 * @return boolean
34
	 */
35
	public function pull_posts() {
36
		$this->set_ajax();
37
		if ( ! $this->app->semaphore()->is_open() ) {
38
			return $this->app->response()->error( new WP_Error(
39
				'semaphore_locked',
40
				sprintf( __( '%s : Semaphore is locked, import/export already in progress.', 'writing-on-github' ), 'Controller::pull_posts()' )
41
			) );
42
		}
43
44 View Code Duplication
		if ( ! $this->app->request()->is_secret_valid() ) {
45
			return $this->app->response()->error( new WP_Error(
46
				'invalid_headers',
47
				__( 'Failed to validate secret.', 'writing-on-github' )
48
			) );
49
		}
50
51
		// ping
52
		if ( $this->app->request()->is_ping() ) {
53
			return $this->app->response()->success( __( 'Wordpress is ready.', 'writing-on-github' ) );
54
		}
55
56
		// push
57 View Code Duplication
		if ( ! $this->app->request()->is_push() ) {
58
			return $this->app->response()->error( new WP_Error(
59
				'invalid_headers',
60
				__( 'Failed to validate webhook event.', 'writing-on-github' )
61
			) );
62
		}
63
		$payload = $this->app->request()->payload();
64
65
		if ( ! $payload->should_import() ) {
66
			return $this->app->response()->error( new WP_Error(
67
				'invalid_payload',
68
				sprintf(
69
					__( "%s won't be imported.", 'writing-on-github' ),
70
					strtolower( $payload->get_commit_id() ) ? : '[Missing Commit ID]'
71
				)
72
			) );
73
		}
74
75
		$this->app->semaphore()->lock();
76
		remove_action( 'save_post', array( $this, 'export_post' ) );
77
		remove_action( 'delete_post', array( $this, 'delete_post' ) );
78
79
		$result = $this->app->import()->payload( $payload );
80
81
		$this->app->semaphore()->unlock();
82
83
		if ( is_wp_error( $result ) ) {
84
            /* @var WP_Error $result */
85
			return $this->app->response()->error( $result );
86
		}
87
88
		return $this->app->response()->success( $result );
89
	}
90
91
	/**
92
	 * Imports posts from the current master branch.
93
	 *
94
	 * @return boolean
95
	 */
96
	public function import_master( $user_id = 0 ) {
97
		if ( ! $this->app->semaphore()->is_open() ) {
98
			return $this->app->response()->error( new WP_Error(
99
				'semaphore_locked',
100
				sprintf( __( '%s : Semaphore is locked, import/export already in progress.', 'writing-on-github' ), 'Controller::import_master()' )
101
			) );
102
		}
103
104
		$this->app->semaphore()->lock();
105
		remove_action( 'save_post', array( $this, 'export_post' ) );
106
		remove_action( 'save_post', array( $this, 'delete_post' ) );
107
108
		if ( $user_id ) {
109
			wp_set_current_user( $user_id );
110
		}
111
112
		$result = $this->app->import()->master();
113
114
		$this->app->semaphore()->unlock();
115
116
        if ( is_wp_error( $result ) ) {
117
            /* @var WP_Error $result */
118
            update_option( '_wogh_import_error', $result->get_error_message() );
119
120
			return $this->app->response()->error( $result );
121
		}
122
123
		update_option( '_wogh_import_complete', 'yes' );
124
125
		return $this->app->response()->success( $result );
126
	}
127
128
	/**
129
	 * Export all the posts in the database to GitHub.
130
	 *
131
     * @param  int        $user_id
132
     * @param  boolean    $force
133
     * @return boolean
134
     */
135
	public function export_all( $user_id = 0, $force = false ) {
136
		if ( ! $this->app->semaphore()->is_open() ) {
137
			return $this->app->response()->error( new WP_Error(
138
				'semaphore_locked',
139
				sprintf( __( '%s : Semaphore is locked, import/export already in progress.', 'writing-on-github' ), 'Controller::export_all()' )
140
			) );
141
		}
142
143
		$this->app->semaphore()->lock();
144
145
		if ( $user_id ) {
146
			wp_set_current_user( $user_id );
147
		}
148
149
		$result = $this->app->export()->full($force);
150
		$this->app->semaphore()->unlock();
151
152
		// Maybe move option updating out of this class/upgrade message display?
153
		if ( is_wp_error( $result ) ) {
154
            /* @var WP_Error $result */
155
			update_option( '_wogh_export_error', $result->get_error_message() );
156
157
			return $this->app->response()->error( $result );
158
		} else {
159
			update_option( '_wogh_export_complete', 'yes' );
160
			update_option( '_wogh_fully_exported', 'yes' );
161
162
			return $this->app->response()->success( $result );
163
		}
164
	}
165
166
	/**
167
	 * Exports a single post to GitHub by ID.
168
	 *
169
	 * Called on the save_post hook.
170
	 *
171
	 * @param int $post_id Post ID.
172
	 *
173
	 * @return boolean
0 ignored issues
show
Should the return type not be null|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
174
	 */
175 View Code Duplication
	public function export_post( $post_id ) {
176
		if ( wp_is_post_revision( $post_id ) ) {
177
			return;
178
		}
179
180
		if ( ! $this->app->semaphore()->is_open() ) {
181
			return $this->app->response()->error( new WP_Error(
182
				'semaphore_locked',
183
				sprintf( __( '%s : Semaphore is locked, import/export already in progress.', 'writing-on-github' ), 'Controller::export_post()' )
184
			) );
185
		}
186
187
		$this->app->semaphore()->lock();
188
		$result = $this->app->export()->update( $post_id );
189
		$this->app->semaphore()->unlock();
190
191
		if ( is_wp_error( $result ) ) {
192
            /* @var WP_Error $result */
193
			return $this->app->response()->error( $result );
194
		}
195
196
		return $this->app->response()->success( $result );
197
	}
198
199
	/**
200
	 * Removes the post from the tree.
201
	 *
202
	 * Called the delete_post hook.
203
	 *
204
	 * @param int $post_id Post ID.
205
	 *
206
	 * @return boolean
0 ignored issues
show
Should the return type not be null|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
207
	 */
208 View Code Duplication
	public function delete_post( $post_id ) {
209
		if ( wp_is_post_revision( $post_id ) ) {
210
			return;
211
		}
212
213
		if ( ! $this->app->semaphore()->is_open() ) {
214
			return $this->app->response()->error( new WP_Error(
215
				'semaphore_locked',
216
				sprintf( __( '%s : Semaphore is locked, import/export already in progress.', 'writing-on-github' ), 'Controller::delete_post()' )
217
			) );
218
		}
219
220
		$this->app->semaphore()->lock();
221
		$result = $this->app->export()->delete( $post_id );
222
		$this->app->semaphore()->unlock();
223
224
		if ( is_wp_error( $result ) ) {
225
            /* @var WP_Error $result */
226
			return $this->app->response()->error( $result );
227
		}
228
229
		return $this->app->response()->success( $result );
230
	}
231
232
	/**
233
	 * Indicates we're running our own AJAX hook
234
	 * and thus should respond with JSON, rather
235
	 * than just returning data.
236
	 */
237
	protected function set_ajax() {
238
		if ( ! defined( 'WOGH_AJAX' ) ) {
239
			define( 'WOGH_AJAX', true );
240
		}
241
	}
242
}
243