Issues (67)

lib/import.php (1 issue)

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 $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result also could return the type true which is incompatible with the documented return type WP_Error|string.
Loading history...
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
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/', '_drafts/', '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 = false;
180
        $meta = $blob->meta();
181
        if ( ! empty( $meta ) ) {
182
            if ( array_key_exists( 'ID', $meta ) ) {
183
                $id = $meta['ID'];
184
            }
185
        }
186
        
187
        if ( empty( $id ) ) {
188
            return false;
189
        }
190
        $result = $this->app->database()->delete_post( $id );
191
        if ( is_wp_error( $result ) ) {
192
            /* @var WP_Error $result */
193
            return $result;
194
        }
195
        return true;
196
    }
197
198
    /**
199
     * Imports a post into wordpress
200
     * @param  Writing_On_GitHub_Blob $blob
201
     * @param  boolean                $force
202
     * @return WP_Error|bool
203
     */
204
    protected function import_post( Writing_On_GitHub_Blob $blob, $force = false ) {
205
        $post = $this->blob_to_post( $blob, $force );
206
207
        if ( ! $post instanceof Writing_On_GitHub_Post ) {
208
            return false;
209
        }
210
211
        $result = $this->app->database()->save_post( $post );
212
        if ( is_wp_error( $result ) ) {
213
            /** @var WP_Error $result */
214
            return $result;
215
        }
216
217
        if ( $post->is_new() ||
218
                ! wogh_equal_path( $post, $blob ) ||
219
                ! wogh_equal_front_matter( $post, $blob ) ) {
220
221
            $result = $this->app->export()->export_post( $post );
222
223
            if ( is_wp_error( $result ) ) {
224
                /** @var WP_Error $result */
225
                return $result;
226
            }
227
        }
228
229
        clean_post_cache( $post->id() );
230
231
        return true;
232
    }
233
234
    /**
235
     * import raw file
236
     * @param  Writing_On_GitHub_Blob $blob
237
     * @return bool
238
     */
239
    protected function importable_raw_file( Writing_On_GitHub_Blob $blob ) {
240
        if ( $blob->has_frontmatter() ) {
241
            return false;
242
        }
243
244
        // only images
245
        if ( strncasecmp($blob->path(), 'images/', strlen('images/') ) != 0) {
246
            return false;
247
        }
248
249
        return true;
250
    }
251
252
    /**
253
     * Imports a raw file content into file system.
254
     * @param  Writing_On_GitHub_Blob $blob
255
     * @param  bool                   $is_remove
256
     */
257
    protected function import_raw_file( Writing_On_GitHub_Blob $blob, $is_remove ) {
258
        $arr = wp_upload_dir();
259
        $path = $arr['basedir'] . '/writing-on-github/' . $blob->path();
260
        if ( $is_remove ) {
261
            if ( file_exists($path) ) {
262
                unlink($path);
263
            }
264
        } else {
265
            $dirname = dirname($path);
266
            if ( ! file_exists($dirname) ) {
267
                wp_mkdir_p($dirname);
268
            }
269
270
            file_put_contents($path, $blob->content());
271
        }
272
        return true;
273
    }
274
275
    /**
276
     * Imports a single blob content into matching post.
277
     *
278
     * @param Writing_On_GitHub_Blob $blob Blob to transform into a Post.
279
     * @param boolean                $force
280
     *
281
     * @return Writing_On_GitHub_Post|false
282
     */
283
    protected function blob_to_post( Writing_On_GitHub_Blob $blob, $force = false ) {
284
        $args = array( 'post_content' => $blob->content_import() );
285
        $meta = $blob->meta();
286
287
        $id = false;
288
289
        if ( ! empty( $meta ) ) {
290
            if ( array_key_exists( 'layout', $meta ) ) {
291
                $args['post_type'] = $meta['layout'];
292
                unset( $meta['layout'] );
293
            }
294
295
            if ( array_key_exists( 'published', $meta ) ) {
296
                $args['post_status'] = true === $meta['published'] ? 'publish' : 'draft';
297
                unset( $meta['published'] );
298
            }
299
300
            if ( array_key_exists( 'post_title', $meta ) ) {
301
                $args['post_title'] = $meta['post_title'];
302
                unset( $meta['post_title'] );
303
            }
304
305
            if ( array_key_exists( 'post_name', $meta ) ) {
306
                $args['post_name'] = $meta['post_name'];
307
                unset( $meta['post_name'] );
308
            }
309
310
            if ( array_key_exists( 'ID', $meta ) ) {
311
                $id = $args['ID'] = $meta['ID'];
312
                $blob->set_id( $id );
313
                unset( $meta['ID'] );
314
            }
315
316
            if ( array_key_exists( 'post_date', $meta ) ) {
317
                if ( empty( $meta['post_date'] ) ) {
318
                    $meta['post_date'] = current_time( 'mysql' );
319
                }
320
321
                $args['post_date'] = $meta['post_date'];
322
                unset( $meta['post_date'] );
323
            }
324
        }
325
326
        $meta['_wogh_sha'] = $blob->sha();
327
328
        if ( ! $force && $id ) {
329
            $old_sha = get_post_meta( $id, '_wogh_sha', true );
330
            $old_github_path = get_post_meta( $id, '_wogh_github_path', true );
331
332
            // dont save post when has same sha
333
            if ( $old_sha  && $old_sha == $meta['_wogh_sha'] &&
334
                 $old_github_path && $old_github_path == $blob->path() ) {
335
                return false;
336
            }
337
        }
338
339
        $post = new Writing_On_GitHub_Post( $args, $this->app->api() );
340
        $post->set_old_github_path( $blob->path() );
341
        $post->set_meta( $meta );
342
        $post->set_blob( $blob );
343
        $blob->set_id( $post->id() );
344
345
        return $post;
346
    }
347
}
348