Passed
Push — ci ( 9f72b5...d152cd )
by litefeel
02:50
created

Writing_On_GitHub_Import::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 2
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 ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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 string|WP_Error
0 ignored issues
show
Documentation introduced by
Should the return type not be WP_Error|string|array|false? Also, consider making the array more specific, something like array<String>, or String[].

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.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
60
	 */
61
	protected function import_files( $files ) {
62
63
		$error 		= false;
64
		$delete_ids = false;
65
66
		$result = $this->compare( $files, $delete_ids );
67
68
		if ( is_wp_error( $result ) ) {
69
			return $result;
70
		}
71
72
		if ( $delete_ids ) {
73 View Code Duplication
			foreach ($delete_ids as $id) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
introduced by
No space after opening parenthesis is prohibited
Loading history...
introduced by
No space before closing parenthesis is prohibited
Loading history...
74
				$result = $this->app->database()->delete_post( $id );
75
				if ( is_wp_error( $result ) ) {
76
					if ( $error ) {
77
						$error->add( $result->get_error_code(), $result->get_error_message() );
78
					} else {
79
						$error = $result;
80
					}
81
				}
82
			}
83
		}
84
85
		return $error;
86
	}
87
88
	/**
89
	 * Imports the latest commit on the master branch.
90
	 *
91
	 * @return string|WP_Error
92
	 */
93 View Code Duplication
	public function master() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
94
		$result = $this->app->api()->fetch()->tree_recursive();
95
96
		if ( is_wp_error( $result ) ) {
97
            /* @var WP_Error $result */
98
			return $result;
99
		}
100
101
        if ( is_array( $result ) ) {
102
            $result = $this->import_files( $result );
103
        }
104
105
		if ( is_wp_error( $result ) ) {
106
            /* @var WP_Error $result */
107
			return $result;
108
		}
109
110
		return __( 'Payload processed', 'writing-on-github' );
111
	}
112
113
    /**
114
     * Do compare
115
     * @param  Writing_On_GitHub_File_Info[]|WP_Error $files
116
     * @param  int[] &$delete_ids
117
     *
118
     * @return string|WP_Error
0 ignored issues
show
Documentation introduced by
Should the return type not be WP_Error|string|array? Also, consider making the array more specific, something like array<String>, or String[].

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.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
119
     */
120
	protected function compare( $files, &$delete_ids ) {
0 ignored issues
show
Complexity introduced by
This operation has 7776 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
121
		if ( is_wp_error( $files ) ) {
122
            /* @var WP_Error $files */
123
			return $files;
124
		}
125
126
		$posts = array();
127
		$new   = array();
128
129
		$idsmap = array();
130
131
		foreach ( $files as $file ) {
132
			if ( ! $this->importable_file( $file ) ) {
133
				continue;
134
			}
135
136
			$blob = $this->app->api()->fetch()->blob( $file );
137
			// network error ?
138
			if ( ! $blob instanceof Writing_On_GitHub_Blob ) {
139
				continue;
140
			}
141
142
			if ( $this->importable_raw_file( $blob ) ) {
143
				$this->import_raw_file( $blob, $file->status == 'removed' );
144
				continue;
145
			}
146
147
			if ( ! $this->importable_blob( $blob ) ) {
148
				continue;
149
			}
150
151
			$post = $this->blob_to_post( $blob );
152
153
			if ( $file->status == 'removed' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
154
				if ( $blob->id() ) {
155
					$idsmap[$blob->id()] = true;
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
156
				}
157
			} elseif ( $post != false ) {
0 ignored issues
show
introduced by
Found "!= false". Use Yoda Condition checks, you must
Loading history...
158
				$posts[] = $post;
159
				if ( $post->is_new() ) {
160
					$new[] = $post;
161
				}
162
			}
163
		}
164
165
		foreach ( $posts as $post ) {
166
			if ( $post->id() && isset( $idsmap[ $post->id() ] ) ) {
167
				unset( $idsmap[ $post->id() ] );
168
			}
169
		}
170
		$delete_ids = array();
171
		foreach ( $idsmap as $id => $value ) {
172
			$delete_ids[] = $id;
173
		}
174
175
		// $this->app->database()->save_posts( $posts, $commit->author_email() );
176
177
		$result = $this->app->database()->save_posts( $posts );
178
179
		if ( is_wp_error( $result ) ) {
180
			return $result;
181
		}
182
183
		if ( ! empty( $new ) ) {
184
			$result = $this->app->export()->new_posts( $new );
185
186
			if ( is_wp_error( $result ) ) {
187
				return $result;
188
			}
189
		}
190
191
		return $posts;
192
	}
193
194
	/**
195
	 * Checks whether the provided blob should be imported.
196
	 *
197
	 * @param Writing_On_GitHub_File_Info $file
198
	 *
199
	 * @return bool
200
	 */
201
	protected function importable_file( Writing_On_GitHub_File_Info $file ) {
202
203
		// only _pages and _posts
204
		if ( strncasecmp($file->path, '_pages/', strlen('_pages/') ) != 0 &&
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !(strncasecmp($fi...rlen('images/')) != 0);.
Loading history...
introduced by
Found "!= 0". Use Yoda Condition checks, you must
Loading history...
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
205
			 strncasecmp($file->path, '_posts/', strlen('_posts/') ) != 0 &&
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
206
			 strncasecmp($file->path, 'images/', strlen('images/') ) != 0 ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
207
			return false;
208
		}
209
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
210
211
		// if ( ! $file->has_frontmatter() ) {
212
		// 	return false;
213
		// }
214
215
		return true;
216
	}
217
218
	/**
219
	 * Checks whether the provided blob should be imported.
220
	 *
221
	 * @param Writing_On_GitHub_Blob $blob Blob to validate.
222
	 *
223
	 * @return bool
224
	 */
225
	protected function importable_blob( Writing_On_GitHub_Blob $blob ) {
226
		// global $wpdb;
227
228
		// // Skip the repo's readme.
229
		// if ( 'readme' === strtolower( substr( $blob->path(), 0, 6 ) ) ) {
230
		// 	return false;
231
		// }
232
233
		// // If the blob sha already matches a post, then move on.
234
		// if ( ! is_wp_error( $this->app->database()->fetch_by_sha( $blob->sha() ) ) ) {
235
		// 	return false;
236
		// }
237
238
		if ( ! $blob->has_frontmatter() ) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return $blob->has_frontmatter();.
Loading history...
239
			return false;
240
		}
241
242
		return true;
243
	}
244
245
	protected function importable_raw_file( Writing_On_GitHub_Blob $blob ) {
246
		if ( $blob->has_frontmatter() ) {
247
			return false;
248
		}
249
250
		// only images
251
		if ( strncasecmp($blob->path(), 'images/', strlen('images/') ) != 0) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !(strncasecmp($bl...rlen('images/')) != 0);.
Loading history...
introduced by
Found "!= 0". Use Yoda Condition checks, you must
Loading history...
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
introduced by
No space before closing parenthesis is prohibited
Loading history...
252
			return false;
253
		}
254
255
		return true;
256
	}
257
258
	/**
259
	 * Imports a raw file content into file system.
260
	 * @param  Writing_On_GitHub_Blob $blob
261
	 * @param  bool                   $is_remove
262
	 */
263
	protected function import_raw_file( Writing_On_GitHub_Blob $blob, $is_remove ) {
264
		$arr = wp_upload_dir();
265
		$path = $arr['basedir'] . '/writing-on-github/' . $blob->path();
266
		if ( $is_remove ) {
267
			if ( file_exists($path) ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
268
				unlink($path);
0 ignored issues
show
introduced by
Filesystem writes are forbidden, you should not be using unlink()
Loading history...
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
269
			}
270
		} else {
271
			$dirname = dirname($path);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
272
			if ( ! file_exists($dirname) ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
273
				wp_mkdir_p($dirname);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
274
			}
275
276
			file_put_contents($path, $blob->content());
0 ignored issues
show
introduced by
Filesystem writes are forbidden, you should not be using file_put_contents()
Loading history...
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
277
		}
278
	}
279
280
	/**
281
	 * Imports a single blob content into matching post.
282
	 *
283
	 * @param Writing_On_GitHub_Blob $blob Blob to transform into a Post.
284
	 *
285
	 * @return Writing_On_GitHub_Post|false
286
	 */
287
	protected function blob_to_post( Writing_On_GitHub_Blob $blob ) {
0 ignored issues
show
Complexity introduced by
This operation has 582 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
288
		$args = array( 'post_content' => $blob->content_import() );
289
		$meta = $blob->meta();
290
291
		$id = false;
292
293
		if ( ! empty( $meta ) ) {
294
			if ( array_key_exists( 'layout', $meta ) ) {
295
				$args['post_type'] = $meta['layout'];
296
				unset( $meta['layout'] );
297
			}
298
299
			if ( array_key_exists( 'published', $meta ) ) {
300
				$args['post_status'] = true === $meta['published'] ? 'publish' : 'draft';
301
				unset( $meta['published'] );
302
			}
303
304
			if ( array_key_exists( 'post_title', $meta ) ) {
305
				$args['post_title'] = $meta['post_title'];
306
				unset( $meta['post_title'] );
307
			}
308
309
			if ( array_key_exists( 'post_name', $meta ) ) {
310
				$args['post_name'] = $meta['post_name'];
311
				unset( $meta['post_name'] );
312
			}
313
314
			if ( array_key_exists( 'ID', $meta ) ) {
315
				$id = $args['ID'] = $meta['ID'];
316
				$blob->set_id($id);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
317
				unset( $meta['ID'] );
318
			}
319
		}
320
321
		$meta['_wogh_sha'] = $blob->sha();
322
323
		if ( $id ) {
324
			$old_sha = get_post_meta( $id, '_wogh_sha', true );
325
			$old_github_path = get_post_meta( $id, '_wogh_github_path', true );
326
327
			// dont save post when has same sha
328
			if ( $old_sha  && $old_sha == $meta['_wogh_sha'] &&
329
				 $old_github_path && $old_github_path == $blob->path() ) {
330
				return false;
331
			}
332
		}
333
334
		$post = new Writing_On_GitHub_Post( $args, $this->app->api() );
335
		$post->set_old_github_path( $blob->path() );
336
		$post->set_meta( $meta );
337
		$blob->set_id( $post->id() );
338
339
		return $post;
340
	}
341
}
342