Completed
Pull Request — master (#130)
by
unknown
04:39
created

WordPress_GitHub_Sync_Post::sha()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 23
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 9.5384
Metric Value
dl 0
loc 23
rs 8.5906
ccs 7
cts 13
cp 0.5385
cc 6
eloc 10
nc 6
nop 0
crap 9.5384
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
					$this->id  = $this->post->ID;
77
					$this->new = false;
78
				} else {
79 1
					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" . cyps_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
		return apply_filters( 'wpghs_filename', $filename, $this );
214
	}
215
216
	/**
217
	 * Returns a post slug we can use in the GitHub filename
218
	 *
219
	 * @return string
220
	 */
221 11
	protected function get_name() {
222 11
		if ( '' !== $this->name() ) {
223 11
			return $this->name();
224
		}
225
226
		return sanitize_title( get_the_title( $this->post ) );
227
	}
228
229
	/**
230
	 * Returns the URL for the post on GitHub.
231
	 *
232
	 * @return string
233
	 */
234 3
	public function github_view_url() {
235 3
		return 'https://github.com/' . $this->api->fetch()->repository() . '/blob/master/' . $this->github_path();
236
	}
237
238
	/**
239
	 * Returns the URL for the post on GitHub.
240
	 *
241
	 * @return string
242
	 */
243 3
	public function github_edit_url() {
244 3
		return 'https://github.com/' . $this->api->fetch()->repository() . '/edit/master/' . $this->github_path();
245
	}
246
247
	/**
248
	 * Retrieve post type directory from blob path.
249
	 *
250
	 * @param string $path Path string.
251
	 *
252
	 * @return string
253
	 */
254
	public function get_directory_from_path( $path ) {
255
		$directory = explode( '/', $path );
256
		$directory = count( $directory ) > 0 ? $directory[0] : '';
257
258
		return $directory;
259
	}
260
261
	/**
262
	 * Determines the last author to modify the post
263
	 *
264
	 * Returns Array an array containing the author name and email
265
	 */
266
	public function last_modified_author() {
267
		if ( $last_id = get_post_meta( $this->id, '_edit_last', true ) ) {
268
			$user = get_userdata( $last_id );
269
270
			if ( $user ) {
271
				return array( 'name' => $user->display_name, 'email' => $user->user_email );
272
			}
273
		}
274
275
		return array();
276
	}
277
278
	/**
279
	 * The post's sha
280
	 * Cached as post meta, or will make a live call if need be
281
	 *
282
	 * Returns String the sha1 hash
283
	 */
284 6
	public function sha() {
285 6
		$sha = get_post_meta( $this->id, '_sha', true );
286
287
		// If we've done a full export and we have no sha
288
		// then we should try a live check to see if it exists.
289 6
		if ( ! $sha && 'yes' === get_option( '_wpghs_fully_exported' ) ) {
290
291
			// @todo could we eliminate this by calling down the full tree and searching it
292
			$data = $this->api->fetch()->remote_contents( $this );
293
294
			if ( ! is_wp_error( $data ) ) {
295
				update_post_meta( $this->id, '_sha', $data->sha );
296
				$sha = $data->sha;
297
			}
298
		}
299
300
		// if the sha still doesn't exist, then it's empty
301 6
		if ( ! $sha || is_wp_error( $sha ) ) {
302 4
			$sha = '';
303 4
		}
304
305 6
		return $sha;
306
	}
307
308
	/**
309
	 * Save the sha to post
310
	 *
311
	 * @param string $sha
312
	 */
313
	public function set_sha( $sha ) {
314
		update_post_meta( $this->id, '_sha', $sha );
315
	}
316
317
	/**
318
	 * The post's metadata
319
	 *
320
	 * Returns Array the post's metadata
321
	 */
322 5
	public function meta() {
323
		$meta = array(
324 5
			'ID'           => $this->post->ID,
325 5
			'post_title'   => get_the_title( $this->post ),
326 5
			'author'       => ( $author = get_userdata( $this->post->post_author ) ) ? $author->display_name : '',
327 5
			'post_date'    => $this->post->post_date,
328 5
			'post_excerpt' => $this->post->post_excerpt,
329 5
			'layout'       => get_post_type( $this->post ),
330 5
			'permalink'    => get_permalink( $this->post ),
331 5
			'published'    => 'publish' === $this->status() ? true : false,
332 5
		);
333
334
		//convert traditional post_meta values, hide hidden values, skip already populated values
335 5
		foreach ( get_post_custom( $this->id ) as $key => $value ) {
336
337 5
			if ( '_' === substr( $key, 0, 1 ) || isset($meta[$key]) ) {
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
338 5
				continue;
339
			}
340
341
			if( is_array($value) && count($value) === 1 ){
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
introduced by
Found "=== 1". 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...
342
				$value = $value[0];
343
			}
344
345
			/**
346
			 * unserialize if needed
347
			 * @link https://codex.wordpress.org/Function_Reference/get_post_custom
348
			 */
349
			$value = maybe_unserialize($value);
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...
350
351
			$meta[$key] = $value;
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
352
353 5
		}
354
355 5
		return apply_filters( 'wpghs_post_meta', $meta, $this );
356
	}
357
358
	/**
359
	 * Returns whether the Post has been saved in the DB yet.
360
	 *
361
	 * @return bool
362
	 */
363 7
	public function is_new() {
364 7
		return $this->new;
365
	}
366
367
	/**
368
	 * Sets the Post's meta.
369
	 *
370
	 * @param array $meta
371
	 */
372 7
	public function set_meta( $meta ) {
373 7
		$this->meta = $meta;
374 7
	}
375
376
	/**
377
	 * Returns the Post's arguments.
378
	 *
379
	 * @return array
380
	 */
381 5
	public function get_args() {
382 5
		return $this->args;
383
	}
384
385
	/**
386
	 * Returns the Post's meta.
387
	 *
388
	 * @return array
389
	 */
390 5
	public function get_meta() {
391 5
		return $this->meta;
392
	}
393
394
	/**
395
	 * Sets the Post's WP_Post object.
396
	 *
397
	 * @param WP_Post $post
398
	 *
399
	 * @return $this
400
	 */
401
	public function set_post( WP_Post $post ) {
402
		$this->post = $post;
403
		$this->id   = $post->ID;
404
405
		return $this;
406
	}
407
408
	/**
409
	 * Transforms the Post into a Blob.
410
	 *
411
	 * @return WordPress_GitHub_Sync_Blob
412
	 */
413 3
	public function to_blob() {
414 3
		$data = new stdClass;
415
416 3
		$data->path    = $this->github_path();
417 3
		$data->content = $this->github_content();
418
419 3
		return new WordPress_GitHub_Sync_Blob( $data );
420
	}
421
}
422