Passed
Push — master ( 3a3f23...fdc038 )
by litefeel
02:23
created

Writing_On_GitHub_Import::import_post()   D

Complexity

Conditions 9
Paths 8

Size

Total Lines 40
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 0
Metric Value
cc 9
eloc 21
nc 8
nop 2
dl 0
loc 40
ccs 0
cts 22
cp 0
crap 90
rs 4.909
c 0
b 0
f 0
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 true|WP_Error
0 ignored issues
show
Documentation introduced by
Should the return type not be WP_Error|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...
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() {
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...
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/');
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
132
        foreach ($prefixs as $prefix) {
0 ignored issues
show
introduced by
No space after opening parenthesis is prohibited
Loading history...
introduced by
No space before closing parenthesis is prohibited
Loading history...
133
            if ( ! strncasecmp($path, $prefix, strlen( $prefix ) ) ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
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() ) {
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...
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) {
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...
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) ) {
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...
242
                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...
243
            }
244
        } else {
245
            $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...
246
            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...
247
                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...
248
            }
249
250
            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...
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 ) {
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...
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);
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...
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