Writing_On_GitHub_Post::github_content()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 3
b 0
f 0
nc 4
nop 0
dl 0
loc 7
ccs 0
cts 5
cp 0
crap 12
rs 10
1
<?php
2
/**
3
 * The post object which represents both the GitHub and WordPress post
4
 * @package WP_Writing_On_GitHub
5
 */
6
7
/**
8
 * Class Writing_On_GitHub_Post
9
 */
10
class Writing_On_GitHub_Post {
11
12
    /**
13
     * Api object
14
     *
15
     * @var Writing_On_GitHub_Api
16
     */
17
    public $api;
18
19
    /**
20
     * Post ID
21
     * @var integer
22
     */
23
    public $id = 0;
24
25
    /**
26
     * Blob object
27
     * @var Writing_On_GitHub_Blob
28
     */
29
    public $blob;
30
31
    /**
32
     * Post object
33
     * @var WP_Post
34
     */
35
    public $post;
36
37
    /**
38
     * Post args.
39
     *
40
     * @var array
41
     */
42
    protected $args;
43
44
    /**
45
     * Post meta.
46
     *
47
     * @var array
48
     */
49
    protected $meta;
50
51
    /**
52
     * Whether the post has been saved.
53
     *
54
     * @var bool
55
     */
56
    protected $new = true;
57
58
59
    protected $old_github_path;
60
61
    /**
62
     * Instantiates a new Post object
63
     *
64
     * @param int|array                 $id_or_args Either a post ID or an array of arguments.
65
     * @param Writing_On_GitHub_Api $api API object.
66
     *
67
     * @todo remove database operations from this method
68
     */
69
    public function __construct( $id_or_args, Writing_On_GitHub_Api $api ) {
70
        $this->api = $api;
71
72
        if ( is_numeric( $id_or_args ) ) {
73
            $this->id   = (int) $id_or_args;
74
            $this->post = get_post( $this->id );
75
            $this->new  = false;
76
        }
77
78
        if ( is_array( $id_or_args ) ) {
79
            $this->args = $id_or_args;
80
81
            if ( isset( $this->args['ID'] ) ) {
82
                $this->post = get_post( $this->args['ID'] );
83
84
                if ( $this->post ) {
85
                    $this->id  = $this->post->ID;
86
                    $this->new = false;
87
                } else {
88
                    unset( $this->args['ID'] );
89
                }
90
            }
91
        }
92
    }
93
94
    public function id() {
95
        return $this->id;
96
    }
97
98
    /**
99
     * Returns the post type
100
     */
101
    public function type() {
102
        return $this->post->post_type;
103
    }
104
105
    /**
106
     * Returns the post type
107
     */
108
    public function status() {
109
        return $this->post->post_status;
110
    }
111
112
    /**
113
     * Returns the post name
114
     */
115
    public function name() {
116
        return $this->post->post_name;
117
    }
118
119
    /**
120
     * Returns true if the post has a password
121
     * @return bool
122
     */
123
    public function has_password() {
124
        return ! empty( $this->post->post_password );
125
    }
126
127
    /**
128
     * Combines the 2 content parts for GitHub
129
     */
130
    public function github_content() {
131
        $use_blob = wogh_is_dont_export_content() && $this->blob;
132
        $content = $use_blob ?
133
            $this->blob->post_content() :
134
            $this->post_content();
135
136
        return $this->front_matter() . $content;
137
        // $content = $this->front_matter() . $content;
138
        // $ending  = apply_filters( 'wogh_line_endings', "\n" );
139
140
        // return preg_replace( '~(*BSR_ANYCRLF)\R~', $ending, $content );
141
    }
142
143
    /**
144
     * The post's YAML frontmatter
145
     *
146
     * Returns String the YAML frontmatter, ready to be written to the file
147
     */
148
    public function front_matter() {
149
        return "---\n" . spyc_dump( $this->meta() ) . "---\n";
150
    }
151
152
    /**
153
     * Returns the post_content
154
     *
155
     * Markdownify's the content if applicable
156
     */
157
    public function post_content() {
158
        $content = $this->post->post_content;
159
160
        if ( function_exists( 'wpmarkdown_html_to_markdown' ) ) {
161
            $content = wpmarkdown_html_to_markdown( $content );
162
        } else if ( class_exists( 'WPCom_Markdown' ) ) {
163
            if ( WPCom_Markdown::get_instance()->is_markdown( $this->post->ID ) ) {
0 ignored issues
show
Bug introduced by
The type WPCom_Markdown was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
164
                $content = $this->post->post_content_filtered;
165
            }
166
        }
167
168
        return apply_filters( 'wogh_content_export', $content, $this );
169
    }
170
171
    public function old_github_path() {
172
        return $this->old_github_path;
173
    }
174
175
    public function set_old_github_path( $path ) {
176
        $this->old_github_path = $path;
177
        update_post_meta( $this->id, '_wogh_github_path', $path );
178
    }
179
180
181
    /**
182
     * Retrieves or calculates the proper GitHub path for a given post
183
     *
184
     * Returns (string) the path relative to repo root
185
     */
186
    public function github_path() {
187
        $path = $this->github_directory() . $this->github_filename();
188
189
        return $path;
190
    }
191
192
    /**
193
     * Get GitHub directory based on post
194
     *
195
     * @return string
196
     */
197
    public function github_directory() {
198
        if ( 'publish' !== $this->status() ) {
199
            return apply_filters( 'wogh_directory_unpublished', '_drafts/', $this );
200
        }
201
202
        $name = '';
203
204
        switch ( $this->type() ) {
205
            case 'post':
206
                $name = 'posts';
207
                break;
208
            case 'page':
209
                $name = 'pages';
210
                break;
211
            default:
212
                $obj = get_post_type_object( $this->type() );
213
214
                if ( $obj ) {
215
                    $name = strtolower( $obj->labels->name );
216
                }
217
218
                if ( ! $name ) {
219
                    $name = '';
220
                }
221
        }
222
223
        if ( $name ) {
224
            $name = '_' . $name . '/';
225
        }
226
227
        return apply_filters( 'wogh_directory_published', $name, $this );
228
    }
229
230
    /**
231
     * Build GitHub filename based on post
232
     */
233
    public function github_filename() {
234
        if ( 'post' === $this->type() ) {
235
            $filename = get_the_time( 'Y/', $this->id ) . $this->get_name() . '.md';
0 ignored issues
show
Bug introduced by
Are you sure get_the_time('Y/', $this->id) of type false|integer|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

235
            $filename = /** @scrutinizer ignore-type */ get_the_time( 'Y/', $this->id ) . $this->get_name() . '.md';
Loading history...
236
        } else {
237
            $filename = $this->get_name() . '.md';
238
        }
239
240
        return apply_filters( 'wogh_filename', $filename, $this );
241
    }
242
243
    /**
244
     * Returns a post slug we can use in the GitHub filename
245
     *
246
     * @return string
247
     */
248
    protected function get_name() {
249
        if ( '' !== $this->name() ) {
250
            return $this->name();
251
        }
252
253
        return sanitize_title( get_the_title( $this->post ) );
254
    }
255
256
    /**
257
     * is put on github
258
     * @return boolean
259
     */
260
    public function is_on_github() {
261
        $sha = get_post_meta( $this->id, '_wogh_sha', true );
262
        $github_path = get_post_meta( $this->id, '_wogh_github_path', true );
263
        if ( $sha && $github_path ) {
264
            return true;
265
        }
266
        return false;
267
    }
268
269
    /**
270
     * Returns the URL for the post on GitHub.
271
     *
272
     * @return string
273
     */
274
    public function github_view_url() {
275
        $github_path = get_post_meta( $this->id, '_wogh_github_path', true );
276
        $repository = $this->api->fetch()->repository();
277
        $branch = $this->api->fetch()->branch();
278
279
        return "https://github.com/$repository/blob/$branch/$github_path";
280
    }
281
282
    /**
283
     * Returns the URL for the post on GitHub.
284
     *
285
     * @return string
286
     */
287
    public function github_edit_url() {
288
        $github_path = get_post_meta( $this->id, '_wogh_github_path', true );
289
        $repository = $this->api->fetch()->repository();
290
        $branch = $this->api->fetch()->branch();
291
292
        return "https://github.com/$repository/edit/$branch/$github_path";
293
    }
294
295
    /**
296
     * Retrieve post type directory from blob path.
297
     *
298
     * @param string $path Path string.
299
     *
300
     * @return string
301
     */
302
    public function get_directory_from_path( $path ) {
303
        $directory = explode( '/', $path );
304
        $directory = count( $directory ) > 0 ? $directory[0] : '';
305
306
        return $directory;
307
    }
308
309
    /**
310
     * Determines the last author to modify the post
311
     *
312
     * Returns Array an array containing the author name and email
313
     */
314
    public function last_modified_author() {
315
        if ( $last_id = get_post_meta( $this->id, '_edit_last', true ) ) {
316
            $user = get_userdata( $last_id );
0 ignored issues
show
Bug introduced by
It seems like $last_id can also be of type string; however, parameter $user_id of get_userdata() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

316
            $user = get_userdata( /** @scrutinizer ignore-type */ $last_id );
Loading history...
317
318
            if ( $user ) {
319
                return array( 'name' => $user->display_name, 'email' => $user->user_email );
320
            }
321
        }
322
323
        return array();
324
    }
325
326
    /**
327
     * The post's sha
328
     * Cached as post meta, or will make a live call if need be
329
     *
330
     * Returns String the sha1 hash
331
     */
332
    public function sha() {
333
        $sha = get_post_meta( $this->id, '_wogh_sha', true );
334
335
        // If we've done a full export and we have no sha
336
        // then we should try a live check to see if it exists.
337
        // if ( ! $sha && 'yes' === get_option( '_wogh_fully_exported' ) ) {
338
339
        //  // @todo could we eliminate this by calling down the full tree and searching it
340
        //  $data = $this->api->fetch()->remote_contents( $this );
341
342
        //  if ( ! is_wp_error( $data ) ) {
343
        //      update_post_meta( $this->id, '_wogh_sha', $data->sha );
344
        //      $sha = $data->sha;
345
        //  }
346
        // }
347
348
        // if the sha still doesn't exist, then it's empty
349
        if ( ! $sha || is_wp_error( $sha ) ) {
350
            $sha = '';
351
        }
352
353
        return $sha;
354
    }
355
356
    /**
357
     * Save the sha to post
358
     *
359
     * @param string $sha
360
     */
361
    public function set_sha( $sha ) {
362
        update_post_meta( $this->id, '_wogh_sha', $sha );
363
    }
364
365
    /**
366
     * The post's metadata
367
     *
368
     * Returns Array the post's metadata
369
     */
370
    public function meta() {
371
        $meta = array(
372
            'ID'           => $this->id,
373
            'post_title'   => get_the_title( $this->post ),
374
            'post_name'    => $this->post->post_name,
375
            'author'       => ( $author = get_userdata( $this->post->post_author ) ) ? $author->display_name : '',
0 ignored issues
show
Bug introduced by
$this->post->post_author of type string is incompatible with the type integer expected by parameter $user_id of get_userdata(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

375
            'author'       => ( $author = get_userdata( /** @scrutinizer ignore-type */ $this->post->post_author ) ) ? $author->display_name : '',
Loading history...
376
            'post_date'    => $this->post->post_date,
377
            'post_excerpt' => $this->post->post_excerpt,
378
            'layout'       => get_post_type( $this->post ),
379
            'link'         => get_permalink( $this->post ),
380
            'published'    => 'publish' === $this->status() ? true : false,
381
            'tags'         => wp_get_post_tags( $this->id, array( 'fields' => 'names' ) ),
382
            'categories'   => wp_get_post_categories( $this->id, array( 'fields' => 'names' ) )
383
        );
384
        if ( empty($this->post->post_name) ) {
385
            unset($meta['post_name']);
386
        }
387
        if ( empty($this->post->post_excerpt) ) {
388
            unset($meta['post_excerpt']);
389
        }
390
        if ( 'yes' == get_option('wogh_ignore_author') ) {
391
            unset($meta['author']);
392
        }
393
394
        //convert traditional post_meta values, hide hidden values, skip already populated values
395
        // foreach ( get_post_custom( $this->id ) as $key => $value ) {
396
397
        //  if ( '_' === substr( $key, 0, 1 ) || isset( $meta[ $key ] ) ) {
398
        //      continue;
399
        //  }
400
401
        //  $meta[ $key ] = $value;
402
403
        // }
404
405
        return apply_filters( 'wogh_post_meta', $meta, $this );
406
    }
407
408
    /**
409
     * Returns whether the Post has been saved in the DB yet.
410
     *
411
     * @return bool
412
     */
413
    public function is_new() {
414
        return $this->new;
415
    }
416
417
    /**
418
     * Sets the Post's meta.
419
     *
420
     * @param array $meta
421
     */
422
    public function set_meta( $meta ) {
423
        $this->meta = $meta;
424
    }
425
426
    /**
427
     * Returns the Post's arguments.
428
     *
429
     * @return array
430
     */
431
    public function get_args() {
432
        return $this->args;
433
    }
434
435
    /**
436
     * Returns the Post's meta.
437
     *
438
     * @return array
439
     */
440
    public function get_meta() {
441
        return $this->meta;
442
    }
443
444
    /**
445
     * Get the blob
446
     * @return Writing_On_GitHub_Blob
447
     */
448
    public function get_blob() {
449
        return $this->blob;
450
    }
451
452
    /**
453
     * Set the blob
454
     * @param Writing_On_GitHub_Blob $blob
455
     */
456
    public function set_blob( Writing_On_GitHub_Blob $blob ) {
457
        $this->blob = $blob;
458
    }
459
460
    /**
461
     * Sets the Post's WP_Post object.
462
     *
463
     * @param WP_Post $post
464
     *
465
     * @return $this
466
     */
467
    public function set_post( WP_Post $post ) {
468
        $this->post = $post;
469
        $this->id   = $post->ID;
470
471
        return $this;
472
    }
473
474
    /**
475
     * Transforms the Post into a Blob.
476
     *
477
     * @return Writing_On_GitHub_Blob
478
     */
479
    public function to_blob() {
480
        $data = new stdClass;
481
482
        $data->path    = $this->github_path();
483
        $data->content = $this->github_content();
484
        $data->sha     = $this->sha();
485
486
        return new Writing_On_GitHub_Blob( $data );
487
    }
488
}
489