Passed
Push — master ( 502689...887c78 )
by litefeel
03:36
created

lib/import.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
 * 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
    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
     * @param  boolean $force
59
     *
60
     * @return true|WP_Error
0 ignored issues
show
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...
61
     */
62
    protected function import_files( $files, $force = false ) {
63
64
        $error = true;
65
66
        foreach ( $files as $file ) {
67
            if ( ! $this->importable_file( $file ) ) {
68
                continue;
69
            }
70
71
            $blob = $this->app->api()->fetch()->blob( $file );
72
            // network error ?
73
            if ( ! $blob instanceof Writing_On_GitHub_Blob ) {
74
                continue;
75
            }
76
77
            $is_remove = 'removed' == $file->status;
78
79
            $result = false;
80
            if ( $this->importable_raw_file( $blob ) ) {
81
                $result = $this->import_raw_file( $blob, $is_remove );
82
            } elseif ( $this->importable_post( $blob ) ) {
83
                if ( $is_remove ) {
84
                    $result = $this->delete_post( $blob );
85
                } else {
86
                    $result = $this->import_post( $blob, $force );
87
                }
88
            }
89
90
            if ( is_wp_error( $result ) ) {
91
                /* @var WP_Error $result */
92
                $error = wogh_append_error( $error, $result );
93
            }
94
        }
95
96
        return $error;
97
    }
98
99
    /**
100
     * Imports the latest commit on the master branch.
101
     *
102
     * @param  boolean $force
103
     * @return string|WP_Error
104
     */
105
    public function master( $force = false ) {
106
        $result = $this->app->api()->fetch()->tree_recursive();
107
108
        if ( is_wp_error( $result ) ) {
109
            /* @var WP_Error $result */
110
            return $result;
111
        }
112
113
        if ( is_array( $result ) ) {
114
            $result = $this->import_files( $result, $force );
115
        }
116
117
        if ( is_wp_error( $result ) ) {
118
            /* @var WP_Error $result */
119
            return $result;
120
        }
121
122
        return __( 'Payload processed', 'writing-on-github' );
123
    }
124
125
    /**
126
     * Checks whether the provided blob should be imported.
127
     *
128
     * @param Writing_On_GitHub_File_Info $file
129
     *
130
     * @return bool
131
     */
132
    protected function importable_file( Writing_On_GitHub_File_Info $file ) {
133
134
        $path = $file->path;
135
136
        // only _pages, _posts and images
137
        $prefixs = array( '_pages/', '_posts/', 'images/');
138
        foreach ($prefixs as $prefix) {
139
            if ( ! strncasecmp($path, $prefix, strlen( $prefix ) ) ) {
140
                return true;
141
            }
142
        }
143
        return false;
144
    }
145
146
    /**
147
     * Checks whether the provided blob should be imported.
148
     *
149
     * @param Writing_On_GitHub_Blob $blob Blob to validate.
150
     *
151
     * @return bool
152
     */
153
    protected function importable_post( Writing_On_GitHub_Blob $blob ) {
154
        // global $wpdb;
155
156
        // // Skip the repo's readme.
157
        // if ( 'readme' === strtolower( substr( $blob->path(), 0, 6 ) ) ) {
158
        //  return false;
159
        // }
160
161
        // // If the blob sha already matches a post, then move on.
162
        // if ( ! is_wp_error( $this->app->database()->fetch_by_sha( $blob->sha() ) ) ) {
163
        //  return false;
164
        // }
165
166
        if ( ! $blob->has_frontmatter() ) {
167
            return false;
168
        }
169
170
        return true;
171
    }
172
173
    /**
174
     * Delete post
175
     * @param  Writing_On_GitHub_Blob $blob
176
     * @return WP_Error|bool
177
     */
178
    protected function delete_post( Writing_On_GitHub_Blob $blob ) {
179
        $id = $blob->id();
180
        if ( empty( $id ) ) {
181
            return false;
182
        }
183
        $result = $this->app->database()->delete_post( $id );
184
        if ( is_wp_error( $result ) ) {
185
            /* @var WP_Error $result */
186
            return $result;
187
        }
188
        return true;
189
    }
190
191
    /**
192
     * Imports a post into wordpress
193
     * @param  Writing_On_GitHub_Blob $blob
194
     * @param  boolean                $force
195
     * @return WP_Error|bool
196
     */
197
    protected function import_post( Writing_On_GitHub_Blob $blob, $force = false ) {
198
        $post = $this->blob_to_post( $blob, $force );
199
200
        if ( ! $post instanceof Writing_On_GitHub_Post ) {
201
            return false;
202
        }
203
204
        $result = $this->app->database()->save_post( $post );
205
        if ( is_wp_error( $result ) ) {
206
            /** @var WP_Error $result */
207
            return $result;
208
        }
209
210
        if ( $post->is_new() ||
211
                ! wogh_equal_front_matter( $post, $blob ) ) {
212
213
            $result = $this->app->export()->export_post( $post );
214
215
            if ( is_wp_error( $result ) ) {
216
                /** @var WP_Error $result */
217
                return $result;
218
            }
219
        }
220
221
        clean_post_cache( $post->id() );
222
223
        return true;
224
    }
225
226
    /**
227
     * import raw file
228
     * @param  Writing_On_GitHub_Blob $blob
229
     * @return bool
230
     */
231
    protected function importable_raw_file( Writing_On_GitHub_Blob $blob ) {
232
        if ( $blob->has_frontmatter() ) {
233
            return false;
234
        }
235
236
        // only images
237
        if ( strncasecmp($blob->path(), 'images/', strlen('images/') ) != 0) {
238
            return false;
239
        }
240
241
        return true;
242
    }
243
244
    /**
245
     * Imports a raw file content into file system.
246
     * @param  Writing_On_GitHub_Blob $blob
247
     * @param  bool                   $is_remove
248
     */
249
    protected function import_raw_file( Writing_On_GitHub_Blob $blob, $is_remove ) {
250
        $arr = wp_upload_dir();
251
        $path = $arr['basedir'] . '/writing-on-github/' . $blob->path();
252
        if ( $is_remove ) {
253
            if ( file_exists($path) ) {
254
                unlink($path);
255
            }
256
        } else {
257
            $dirname = dirname($path);
258
            if ( ! file_exists($dirname) ) {
259
                wp_mkdir_p($dirname);
260
            }
261
262
            file_put_contents($path, $blob->content());
263
        }
264
        return true;
265
    }
266
267
    /**
268
     * Imports a single blob content into matching post.
269
     *
270
     * @param Writing_On_GitHub_Blob $blob Blob to transform into a Post.
271
     * @param boolean                $force
272
     *
273
     * @return Writing_On_GitHub_Post|false
274
     */
275
    protected function blob_to_post( Writing_On_GitHub_Blob $blob, $force = false ) {
0 ignored issues
show
This operation has 679 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...
276
        $args = array( 'post_content' => $blob->content_import() );
277
        $meta = $blob->meta();
278
279
        $id = false;
280
281
        if ( ! empty( $meta ) ) {
282
            if ( array_key_exists( 'layout', $meta ) ) {
283
                $args['post_type'] = $meta['layout'];
284
                unset( $meta['layout'] );
285
            }
286
287
            if ( array_key_exists( 'published', $meta ) ) {
288
                $args['post_status'] = true === $meta['published'] ? 'publish' : 'draft';
289
                unset( $meta['published'] );
290
            }
291
292
            if ( array_key_exists( 'post_title', $meta ) ) {
293
                $args['post_title'] = $meta['post_title'];
294
                unset( $meta['post_title'] );
295
            }
296
297
            if ( array_key_exists( 'post_name', $meta ) ) {
298
                $args['post_name'] = $meta['post_name'];
299
                unset( $meta['post_name'] );
300
            }
301
302
            if ( array_key_exists( 'ID', $meta ) ) {
303
                $id = $args['ID'] = $meta['ID'];
304
                $blob->set_id($id);
305
                unset( $meta['ID'] );
306
            }
307
        }
308
309
        $meta['_wogh_sha'] = $blob->sha();
310
311
        if ( ! $force && $id ) {
312
            $old_sha = get_post_meta( $id, '_wogh_sha', true );
313
            $old_github_path = get_post_meta( $id, '_wogh_github_path', true );
314
315
            // dont save post when has same sha
316
            if ( $old_sha  && $old_sha == $meta['_wogh_sha'] &&
317
                 $old_github_path && $old_github_path == $blob->path() ) {
318
                return false;
319
            }
320
        }
321
322
        $post = new Writing_On_GitHub_Post( $args, $this->app->api() );
323
        $post->set_old_github_path( $blob->path() );
324
        $post->set_meta( $meta );
325
        $post->set_blob( $blob );
326
        $blob->set_id( $post->id() );
327
328
        return $post;
329
    }
330
}
331