1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* GitHub Import Manager |
4
|
|
|
* |
5
|
|
|
* @package Writing_On_GitHub |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Class Writing_On_GitHub_Import |
10
|
|
|
*/ |
11
|
|
|
class Writing_On_GitHub_Import { |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Application container. |
15
|
|
|
* |
16
|
|
|
* @var Writing_On_GitHub |
17
|
|
|
*/ |
18
|
|
|
protected $app; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Initializes a new import manager. |
22
|
|
|
* |
23
|
|
|
* @param Writing_On_GitHub $app Application container. |
24
|
|
|
*/ |
25
|
|
|
public function __construct( Writing_On_GitHub $app ) { |
26
|
|
|
$this->app = $app; |
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Imports a payload. |
31
|
|
|
* @param Writing_On_GitHub_Payload $payload |
32
|
|
|
* |
33
|
|
|
* @return string|WP_Error |
34
|
|
|
*/ |
35
|
|
View Code Duplication |
public function payload( Writing_On_GitHub_Payload $payload ) { |
|
|
|
|
36
|
|
|
|
37
|
|
|
$result = $this->app->api()->fetch()->compare( $payload->get_before_commit_id() ); |
38
|
|
|
|
39
|
|
|
if ( is_wp_error( $result ) ) { |
40
|
|
|
/* @var WP_Error $result */ |
41
|
|
|
return $result; |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
if ( is_array( $result ) ) { |
45
|
|
|
$result = $this->import_files( $result ); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
if ( is_wp_error( $result ) ) { |
49
|
|
|
return $files; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
return __( 'Payload processed', 'writing-on-github' ); |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* import blob by files |
57
|
|
|
* @param Writing_On_GitHub_File_Info[] $files |
58
|
|
|
* |
59
|
|
|
* @return true|WP_Error |
|
|
|
|
60
|
|
|
*/ |
61
|
|
|
protected function import_files( $files ) { |
62
|
|
|
|
63
|
|
|
$error = true; |
64
|
|
|
|
65
|
|
|
foreach ( $files as $file ) { |
66
|
|
|
if ( ! $this->importable_file( $file ) ) { |
67
|
|
|
continue; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
$blob = $this->app->api()->fetch()->blob( $file ); |
71
|
|
|
// network error ? |
72
|
|
|
if ( ! $blob instanceof Writing_On_GitHub_Blob ) { |
73
|
|
|
continue; |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
$is_remove = 'removed' == $file->status; |
77
|
|
|
|
78
|
|
|
$result = false; |
79
|
|
|
if ( $this->importable_raw_file( $blob ) ) { |
80
|
|
|
$result = $this->import_raw_file( $blob, $is_remove ); |
81
|
|
|
} elseif ( $this->importable_post( $blob ) ) { |
82
|
|
|
$result = $this->import_post( $blob, $is_remove ); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
if ( is_wp_error( $result ) ) { |
86
|
|
|
/* @var WP_Error $result */ |
87
|
|
|
$error = wogh_append_error( $error, $result ); |
88
|
|
|
} |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
return $error; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Imports the latest commit on the master branch. |
96
|
|
|
* |
97
|
|
|
* @return string|WP_Error |
98
|
|
|
*/ |
99
|
|
View Code Duplication |
public function master() { |
|
|
|
|
100
|
|
|
$result = $this->app->api()->fetch()->tree_recursive(); |
101
|
|
|
|
102
|
|
|
if ( is_wp_error( $result ) ) { |
103
|
|
|
/* @var WP_Error $result */ |
104
|
|
|
return $result; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
if ( is_array( $result ) ) { |
108
|
|
|
$result = $this->import_files( $result ); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
if ( is_wp_error( $result ) ) { |
112
|
|
|
/* @var WP_Error $result */ |
113
|
|
|
return $result; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
return __( 'Payload processed', 'writing-on-github' ); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Checks whether the provided blob should be imported. |
121
|
|
|
* |
122
|
|
|
* @param Writing_On_GitHub_File_Info $file |
123
|
|
|
* |
124
|
|
|
* @return bool |
125
|
|
|
*/ |
126
|
|
|
protected function importable_file( Writing_On_GitHub_File_Info $file ) { |
127
|
|
|
|
128
|
|
|
$path = $file->path; |
129
|
|
|
|
130
|
|
|
// only _pages, _posts and images |
131
|
|
|
$prefixs = array( '_pages/', '_posts/', 'images/'); |
|
|
|
|
132
|
|
|
foreach ($prefixs as $prefix) { |
|
|
|
|
133
|
|
|
if ( ! strncasecmp($path, $prefix, strlen( $prefix ) ) ) { |
|
|
|
|
134
|
|
|
return true; |
135
|
|
|
} |
136
|
|
|
} |
137
|
|
|
return false; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Checks whether the provided blob should be imported. |
142
|
|
|
* |
143
|
|
|
* @param Writing_On_GitHub_Blob $blob Blob to validate. |
144
|
|
|
* |
145
|
|
|
* @return bool |
146
|
|
|
*/ |
147
|
|
|
protected function importable_post( Writing_On_GitHub_Blob $blob ) { |
148
|
|
|
// global $wpdb; |
149
|
|
|
|
150
|
|
|
// // Skip the repo's readme. |
151
|
|
|
// if ( 'readme' === strtolower( substr( $blob->path(), 0, 6 ) ) ) { |
152
|
|
|
// return false; |
153
|
|
|
// } |
154
|
|
|
|
155
|
|
|
// // If the blob sha already matches a post, then move on. |
156
|
|
|
// if ( ! is_wp_error( $this->app->database()->fetch_by_sha( $blob->sha() ) ) ) { |
157
|
|
|
// return false; |
158
|
|
|
// } |
159
|
|
|
|
160
|
|
|
if ( ! $blob->has_frontmatter() ) { |
|
|
|
|
161
|
|
|
return false; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
return true; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* Imports a post into wordpress |
169
|
|
|
* @param Writing_On_GitHub_Blob $blob |
170
|
|
|
* @param bool $is_remove |
171
|
|
|
* @return WP_Error|bool |
172
|
|
|
*/ |
173
|
|
|
protected function import_post( Writing_On_GitHub_Blob $blob, $is_remove ) { |
174
|
|
|
|
175
|
|
|
if ( $is_remove ) { |
176
|
|
|
$id = $blob->id(); |
177
|
|
|
if ( empty( $id ) ) { |
178
|
|
|
return false; |
179
|
|
|
} |
180
|
|
|
$result = $this->app->database()->delete_post( $id ); |
181
|
|
|
if ( is_wp_error( $result ) ) { |
182
|
|
|
/* @var WP_Error $result */ |
183
|
|
|
return $result; |
184
|
|
|
} |
185
|
|
|
return true; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
$post = $this->blob_to_post( $blob ); |
189
|
|
|
|
190
|
|
|
if ( ! $post instanceof Writing_On_GitHub_Post ) { |
191
|
|
|
return false; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
$result = $this->app->database()->save_post( $post ); |
195
|
|
|
if ( is_wp_error( $result ) ) { |
196
|
|
|
/** @var WP_Error $result */ |
197
|
|
|
return $result; |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
if ( $post->is_new() || |
201
|
|
|
! wogh_equal_front_matter( $post, $blob ) ) { |
202
|
|
|
|
203
|
|
|
$result = $this->app->export()->new_posts( array( $post ) ); |
204
|
|
|
|
205
|
|
|
if ( is_wp_error( $result ) ) { |
206
|
|
|
/** @var WP_Error $result */ |
207
|
|
|
return $result; |
208
|
|
|
} |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
return true; |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
/** |
215
|
|
|
* import raw file |
216
|
|
|
* @param Writing_On_GitHub_Blob $blob |
217
|
|
|
* @return bool |
218
|
|
|
*/ |
219
|
|
|
protected function importable_raw_file( Writing_On_GitHub_Blob $blob ) { |
220
|
|
|
if ( $blob->has_frontmatter() ) { |
221
|
|
|
return false; |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
// only images |
225
|
|
|
if ( strncasecmp($blob->path(), 'images/', strlen('images/') ) != 0) { |
|
|
|
|
226
|
|
|
return false; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
return true; |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
/** |
233
|
|
|
* Imports a raw file content into file system. |
234
|
|
|
* @param Writing_On_GitHub_Blob $blob |
235
|
|
|
* @param bool $is_remove |
236
|
|
|
*/ |
237
|
|
|
protected function import_raw_file( Writing_On_GitHub_Blob $blob, $is_remove ) { |
238
|
|
|
$arr = wp_upload_dir(); |
239
|
|
|
$path = $arr['basedir'] . '/writing-on-github/' . $blob->path(); |
240
|
|
|
if ( $is_remove ) { |
241
|
|
|
if ( file_exists($path) ) { |
|
|
|
|
242
|
|
|
unlink($path); |
|
|
|
|
243
|
|
|
} |
244
|
|
|
} else { |
245
|
|
|
$dirname = dirname($path); |
|
|
|
|
246
|
|
|
if ( ! file_exists($dirname) ) { |
|
|
|
|
247
|
|
|
wp_mkdir_p($dirname); |
|
|
|
|
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
file_put_contents($path, $blob->content()); |
|
|
|
|
251
|
|
|
} |
252
|
|
|
return true; |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
/** |
256
|
|
|
* Imports a single blob content into matching post. |
257
|
|
|
* |
258
|
|
|
* @param Writing_On_GitHub_Blob $blob Blob to transform into a Post. |
259
|
|
|
* |
260
|
|
|
* @return Writing_On_GitHub_Post|false |
261
|
|
|
*/ |
262
|
|
|
protected function blob_to_post( Writing_On_GitHub_Blob $blob ) { |
|
|
|
|
263
|
|
|
$args = array( 'post_content' => $blob->content_import() ); |
264
|
|
|
$meta = $blob->meta(); |
265
|
|
|
|
266
|
|
|
$id = false; |
267
|
|
|
|
268
|
|
|
if ( ! empty( $meta ) ) { |
269
|
|
|
if ( array_key_exists( 'layout', $meta ) ) { |
270
|
|
|
$args['post_type'] = $meta['layout']; |
271
|
|
|
unset( $meta['layout'] ); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
if ( array_key_exists( 'published', $meta ) ) { |
275
|
|
|
$args['post_status'] = true === $meta['published'] ? 'publish' : 'draft'; |
276
|
|
|
unset( $meta['published'] ); |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
if ( array_key_exists( 'post_title', $meta ) ) { |
280
|
|
|
$args['post_title'] = $meta['post_title']; |
281
|
|
|
unset( $meta['post_title'] ); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
if ( array_key_exists( 'post_name', $meta ) ) { |
285
|
|
|
$args['post_name'] = $meta['post_name']; |
286
|
|
|
unset( $meta['post_name'] ); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
if ( array_key_exists( 'ID', $meta ) ) { |
290
|
|
|
$id = $args['ID'] = $meta['ID']; |
291
|
|
|
$blob->set_id($id); |
|
|
|
|
292
|
|
|
unset( $meta['ID'] ); |
293
|
|
|
} |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
$meta['_wogh_sha'] = $blob->sha(); |
297
|
|
|
|
298
|
|
|
if ( $id ) { |
299
|
|
|
$old_sha = get_post_meta( $id, '_wogh_sha', true ); |
300
|
|
|
$old_github_path = get_post_meta( $id, '_wogh_github_path', true ); |
301
|
|
|
|
302
|
|
|
// dont save post when has same sha |
303
|
|
|
if ( $old_sha && $old_sha == $meta['_wogh_sha'] && |
304
|
|
|
$old_github_path && $old_github_path == $blob->path() ) { |
305
|
|
|
return false; |
306
|
|
|
} |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
$post = new Writing_On_GitHub_Post( $args, $this->app->api() ); |
310
|
|
|
$post->set_old_github_path( $blob->path() ); |
311
|
|
|
$post->set_meta( $meta ); |
312
|
|
|
$blob->set_id( $post->id() ); |
313
|
|
|
|
314
|
|
|
return $post; |
315
|
|
|
} |
316
|
|
|
} |
317
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.