WordPress_GitHub_Sync_Post::to_blob()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 8
ccs 1
cts 1
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * The post object which represents both the GitHub and WordPress post
4
 * @package WordPress_GitHub_Sync
5
 */
6
7
/**
8
 * Class WordPress_GitHub_Sync_Post
9
 */
10
class WordPress_GitHub_Sync_Post {
11
12
	/**
13
	 * Api object
14
	 *
15
	 * @var WordPress_GitHub_Sync_Api
16
	 */
17
	public $api;
18
19
	/**
20
	 * Post ID
21
	 * @var integer
22
	 */
23
	public $id = 0;
24
25
	/**
26
	 * Post object
27
	 * @var WP_Post
28
	 */
29
	public $post;
30
31
	/**
32
	 * Post args.
33
	 *
34
	 * @var array
35
	 */
36
	protected $args;
37
38
	/**
39
	 * Post meta.
40
	 *
41
	 * @var array
42
	 */
43
	protected $meta;
44
45
	/**
46
	 * Whether the post has been saved.
47
	 *
48
	 * @var bool
49
	 */
50
	protected $new = true;
51
52
	/**
53
	 * Instantiates a new Post object
54
	 *
55
	 * @param int|array                 $id_or_args Either a post ID or an array of arguments.
56
	 * @param WordPress_GitHub_Sync_Api $api API object.
57
	 *
58
	 * @todo remove database operations from this method
59
	 */
60 36
	public function __construct( $id_or_args, WordPress_GitHub_Sync_Api $api ) {
61 36
		$this->api = $api;
62
63 36
		if ( is_numeric( $id_or_args ) ) {
64 29
			$this->id   = (int) $id_or_args;
65 29
			$this->post = get_post( $this->id );
66 29
			$this->new  = false;
67 29
		}
68
69 36
		if ( is_array( $id_or_args ) ) {
70 7
			$this->args = $id_or_args;
71
72 7
			if ( isset( $this->args['ID'] ) ) {
73 1
				$this->post = get_post( $this->args['ID'] );
74
75 1
				if ( $this->post ) {
76 1
					$this->id  = $this->post->ID;
77 1
					$this->new = false;
78 1
				} else {
79
					unset( $this->args['ID'] );
80
				}
81 1
			}
82 7
		}
83 36
	}
84
85
	/**
86
	 * Returns the post type
87
	 */
88 19
	public function type() {
89 19
		return $this->post->post_type;
90
	}
91
92
	/**
93
	 * Returns the post type
94
	 */
95 22
	public function status() {
96 22
		return $this->post->post_status;
97
	}
98
99
	/**
100
	 * Returns the post name
101
	 */
102 12
	public function name() {
103 12
		return $this->post->post_name;
104
	}
105
106
	/**
107
	 * Returns true if the post has a password
108
	 * @return bool
109
	 */
110 2
	public function has_password() {
111 2
		return ! empty( $this->post->post_password );
112
	}
113
114
	/**
115
	 * Combines the 2 content parts for GitHub
116
	 */
117 5
	public function github_content() {
118 5
		$content = $this->front_matter() . $this->post_content();
119 5
		$ending  = apply_filters( 'wpghs_line_endings', "\n" );
120
121 5
		return preg_replace( '~(*BSR_ANYCRLF)\R~', $ending, $content );
122
	}
123
124
	/**
125
	 * The post's YAML frontmatter
126
	 *
127
	 * Returns String the YAML frontmatter, ready to be written to the file
128
	 */
129 5
	public function front_matter() {
130 5
		return "---\n" . spyc_dump( $this->meta() ) . "---\n";
131
	}
132
133
	/**
134
	 * Returns the post_content
135
	 *
136
	 * Markdownify's the content if applicable
137
	 */
138 5
	public function post_content() {
139 5
		$content = $this->post->post_content;
140
141 5
		if ( function_exists( 'wpmarkdown_html_to_markdown' ) ) {
142
			$content = wpmarkdown_html_to_markdown( $content );
143 5
		} else if ( class_exists( 'WPCom_Markdown' ) ) {
144
			if ( WPCom_Markdown::get_instance()->is_markdown( $this->post->ID ) ) {
145
				$content = $this->post->post_content_filtered;
146
			}
147
		}
148
149 5
		return apply_filters( 'wpghs_content_export', $content, $this );
150
	}
151
152
	/**
153
	 * Retrieves or calculates the proper GitHub path for a given post
154
	 *
155
	 * Returns (string) the path relative to repo root
156
	 */
157 11
	public function github_path() {
158 11
		$path = $this->github_directory() . $this->github_filename();
159
160 11
		update_post_meta( $this->id, '_wpghs_github_path', $path );
161
162 11
		return $path;
163
	}
164
165
	/**
166
	 * Get GitHub directory based on post
167
	 *
168
	 * @return string
169
	 */
170 17
	public function github_directory() {
171 17
		if ( 'publish' !== $this->status() ) {
172 1
			return apply_filters( 'wpghs_directory_unpublished', '_drafts/', $this );
173
		}
174
175 16
		$name = '';
176
177 16
		switch ( $this->type() ) {
178 16
			case 'post':
179 13
				$name = 'posts';
180 13
				break;
181 3
			case 'page':
182 1
				$name = 'pages';
183 1
				break;
184 2
			default:
185 2
				$obj = get_post_type_object( $this->type() );
186
187 2
				if ( $obj ) {
188 1
					$name = strtolower( $obj->labels->name );
189 1
				}
190
191 2
				if ( ! $name ) {
192 1
					$name = '';
193 1
				}
194 16
		}
195
196 16
		if ( $name ) {
197 15
			$name = '_' . $name . '/';
198 15
		}
199
200 16
		return apply_filters( 'wpghs_directory_published', $name, $this );
201
	}
202
203
	/**
204
	 * Build GitHub filename based on post
205
	 */
206 11
	public function github_filename() {
207 11
		if ( 'post' === $this->type() ) {
208 11
			$filename = get_the_time( 'Y-m-d-', $this->id ) . $this->get_name() . '.md';
209 11
		} else {
210
			$filename = $this->get_name() . '.md';
211
		}
212
213 11
		$filename = sanitize_file_name( $filename );
214
215
		return apply_filters( 'wpghs_filename', $filename, $this );
216
	}
217
218
	/**
219
	 * Returns a post slug we can use in the GitHub filename
220
	 *
221 11
	 * @return string
222 11
	 */
223 11
	protected function get_name() {
224
		if ( '' !== $this->name() ) {
225
			return $this->name();
226
		}
227
228
		return get_the_title( $this->post );
229
	}
230
231
	/**
232
	 * Returns the URL for the post on GitHub.
233
	 *
234 3
	 * @return string
235 3
	 */
236
	public function github_view_url() {
237
		return 'https://github.com/' . $this->api->fetch()->repository() . '/blob/master/' . $this->github_path();
238
	}
239
240
	/**
241
	 * Returns the URL for the post on GitHub.
242
	 *
243 3
	 * @return string
244 3
	 */
245
	public function github_edit_url() {
246
		return 'https://github.com/' . $this->api->fetch()->repository() . '/edit/master/' . $this->github_path();
247
	}
248
249
	/**
250
	 * Retrieve post type directory from blob path.
251
	 *
252
	 * @param string $path Path string.
253
	 *
254
	 * @return string
255
	 */
256
	public function get_directory_from_path( $path ) {
257
		$directory = explode( '/', $path );
258
		$directory = count( $directory ) > 0 ? $directory[0] : '';
259
260
		return $directory;
261
	}
262
263
	/**
264
	 * Determines the last author to modify the post
265
	 *
266
	 * Returns Array an array containing the author name and email
267
	 */
268
	public function last_modified_author() {
269
		if ( $last_id = get_post_meta( $this->id, '_edit_last', true ) ) {
270
			$user = get_userdata( $last_id );
271
272
			if ( $user ) {
273
				return array( 'name' => $user->display_name, 'email' => $user->user_email );
274
			}
275
		}
276
277
		return array();
278
	}
279
280
	/**
281
	 * The post's sha
282
	 * Cached as post meta, or will make a live call if need be
283
	 *
284 6
	 * Returns String the sha1 hash
285 6
	 */
286
	public function sha() {
287
		$sha = get_post_meta( $this->id, '_sha', true );
288
289 6
		// If we've done a full export and we have no sha
290
		// then we should try a live check to see if it exists.
291
		if ( ! $sha && 'yes' === get_option( '_wpghs_fully_exported' ) ) {
292
293
			// @todo could we eliminate this by calling down the full tree and searching it
294
			$data = $this->api->fetch()->remote_contents( $this );
295
296
			if ( ! is_wp_error( $data ) ) {
297
				update_post_meta( $this->id, '_sha', $data->sha );
298
				$sha = $data->sha;
299
			}
300
		}
301 6
302 4
		// if the sha still doesn't exist, then it's empty
303 4
		if ( ! $sha || is_wp_error( $sha ) ) {
304
			$sha = '';
305 6
		}
306
307
		return $sha;
308
	}
309
310
	/**
311
	 * Save the sha to post
312
	 *
313
	 * @param string $sha
314
	 */
315
	public function set_sha( $sha ) {
316
		update_post_meta( $this->id, '_sha', $sha );
317
	}
318
319
	/**
320
	 * The post's metadata
321
	 *
322 5
	 * Returns Array the post's metadata
323
	 */
324 5
	public function meta() {
325 5
		$meta = array(
326 5
			'ID'           => $this->post->ID,
327 5
			'post_title'   => get_the_title( $this->post ),
328 5
			'author'       => ( $author = get_userdata( $this->post->post_author ) ) ? $author->display_name : '',
329 5
			'post_excerpt' => $this->post->post_excerpt,
330 5
			'layout'       => get_post_type( $this->post ),
331 5
			'permalink'    => get_permalink( $this->post ),
332 5
			'published'    => 'publish' === $this->status() ? true : false,
333
		);
334 5
335
		// only include the post date if the post is published
336
		if ( $meta['published'] ) {
337
			$meta['post_date'] = $this->post->post_date;
338
		}
339
340
		return apply_filters( 'wpghs_post_meta', $meta, $this );
341
	}
342 7
343 7
	/**
344
	 * Returns whether the Post has been saved in the DB yet.
345
	 *
346
	 * @return bool
347
	 */
348
	public function is_new() {
349
		return $this->new;
350
	}
351 7
352 7
	/**
353 7
	 * Sets the Post's meta.
354
	 *
355
	 * @param array $meta
356
	 */
357
	public function set_meta( $meta ) {
358
		$this->meta = $meta;
359
	}
360 6
361 6
	/**
362
	 * Returns the Post's arguments.
363
	 *
364
	 * @return array
365
	 */
366
	public function get_args() {
367
		return $this->args;
368
	}
369 6
370 6
	/**
371
	 * Returns the Post's meta.
372
	 *
373
	 * @return array
374
	 */
375
	public function get_meta() {
376
		return $this->meta;
377
	}
378
379
	/**
380
	 * Sets the Post's WP_Post object.
381
	 *
382
	 * @param WP_Post $post
383
	 *
384
	 * @return $this
385
	 */
386
	public function set_post( WP_Post $post ) {
387
		$this->post = $post;
388
		$this->id   = $post->ID;
389
390
		return $this;
391
	}
392 3
393 3
	/**
394
	 * Transforms the Post into a Blob.
395 3
	 *
396 3
	 * @return WordPress_GitHub_Sync_Blob
397
	 */
398 3
	public function to_blob() {
399
		$data = new stdClass;
400
401
		$data->path    = $this->github_path();
402
		$data->content = $this->github_content();
403
404
		return new WordPress_GitHub_Sync_Blob( $data );
405
	}
406
}
407