Completed
Push — master ( 8a7e31...f76ead )
by Armando
12s
created
lib/class-post.php 1 patch
Indentation   +740 added lines, -740 removed lines patch added patch discarded remove patch
@@ -18,625 +18,625 @@  discard block
 block discarded – undo
18 18
  */
19 19
 class WP2D_Post {
20 20
 
21
-	/**
22
-	 * The original post object.
23
-	 *
24
-	 * @var WP_Posts
25
-	 * @since 1.5.0
26
-	 */
27
-	public $post = null;
28
-
29
-	/**
30
-	 * The original post ID.
31
-	 *
32
-	 * @var int
33
-	 * @since 1.5.0
34
-	 */
35
-	public $ID = null;
36
-
37
-	/**
38
-	 * If this post should be shared on diaspora*.
39
-	 *
40
-	 * @var bool
41
-	 * @since 1.5.0
42
-	 */
43
-	public $post_to_diaspora = null;
44
-
45
-	/**
46
-	 * If a link back to the original post should be added.
47
-	 *
48
-	 * @var bool
49
-	 * @since 1.5.0
50
-	 */
51
-	public $fullentrylink = null;
52
-
53
-	/**
54
-	 * What content gets posted.
55
-	 *
56
-	 * @var string
57
-	 * @since 1.5.0
58
-	 */
59
-	public $display = null;
60
-
61
-	/**
62
-	 * The types of tags to post. (global,custom,post)
63
-	 *
64
-	 * @var array
65
-	 * @since 1.5.0
66
-	 */
67
-	public $tags_to_post = null;
68
-
69
-	/**
70
-	 * The post's custom tags.
71
-	 *
72
-	 * @var array
73
-	 * @since 1.5.0
74
-	 */
75
-	public $custom_tags = null;
76
-
77
-	/**
78
-	 * Aspects this post gets posted to.
79
-	 *
80
-	 * @var array
81
-	 * @since 1.5.0
82
-	 */
83
-	public $aspects = null;
84
-
85
-	/**
86
-	 * Services this post gets posted to.
87
-	 *
88
-	 * @var array
89
-	 * @since 1.5.0
90
-	 */
91
-	public $services = null;
92
-
93
-
94
-	/**
95
-	 * The post's history of diaspora* posts.
96
-	 *
97
-	 * @var array
98
-	 * @since 1.5.0
99
-	 */
100
-	public $post_history = null;
101
-
102
-	/**
103
-	 * If the post actions have all been set up already.
104
-	 *
105
-	 * @var boolean
106
-	 * @since 1.5.0
107
-	 */
108
-	private static $_is_set_up = false;
109
-
110
-	/**
111
-	 * Setup all the necessary WP callbacks.
112
-	 *
113
-	 * @since 1.5.0
114
-	 */
115
-	public static function setup() {
116
-		if ( self::$_is_set_up ) {
117
-			return;
118
-		}
119
-
120
-		$instance = new WP2D_Post( null );
121
-
122
-		// Notices when a post has been shared or if it has failed.
123
-		add_action( 'admin_notices', array( $instance, 'admin_notices' ) );
124
-		add_action( 'admin_init', array( $instance, 'ignore_post_error' ) );
125
-
126
-		// Handle diaspora* posting when saving the post.
127
-		add_action( 'save_post', array( $instance, 'post' ), 11, 2 );
128
-		add_action( 'save_post', array( $instance, 'save_meta_box_data' ), 10 );
129
-
130
-		// Add meta boxes.
131
-		add_action( 'add_meta_boxes', array( $instance, 'add_meta_boxes' ) );
132
-
133
-		self::$_is_set_up = true;
134
-	}
135
-
136
-	/**
137
-	 * Constructor.
138
-	 *
139
-	 * @since 1.5.0
140
-	 *
141
-	 * @param int|WP_Post $post Post ID or the post itself.
142
-	 */
143
-	public function __construct( $post ) {
144
-		$this->_assign_wp_post( $post );
145
-	}
146
-
147
-	/**
148
-	 * Assign the original WP_Post object and all the custom meta data.
149
-	 *
150
-	 * @since 1.5.0
151
-	 *
152
-	 * @param int|WP_Post $post Post ID or the post itself.
153
-	 */
154
-	private function _assign_wp_post( $post ) {
155
-		if ( $this->post = get_post( $post ) ) {
156
-			$this->ID = $this->post->ID;
157
-
158
-			$options = WP2D_Options::instance();
159
-
160
-			// Assign all meta values, expanding non-existent ones with the defaults.
161
-			$meta_current = get_post_meta( $this->ID, '_wp_to_diaspora', true );
162
-			$meta = wp_parse_args(
163
-				$meta_current,
164
-				$options->get_options()
165
-			);
166
-			if ( $meta ) {
167
-				foreach ( $meta as $key => $value ) {
168
-					$this->$key = $value;
169
-				}
170
-			}
171
-
172
-			// If no WP2D meta data has been saved yet, this post shouldn't be published.
173
-			// This can happen if existing posts (before WP2D) get updated externally, not through the post edit screen.
174
-			// Check gutobenn/wp-to-diaspora#91 for reference.
175
-			// Also, when we have a post scheduled for publishing, don't touch it.
176
-			// This is important when modifying scheduled posts using Quick Edit.
177
-			if ( ! in_array( $this->post->post_status, array( 'auto-draft', 'future' ) ) && ! $meta_current ) {
178
-				$this->post_to_diaspora = false;
179
-			}
180
-
181
-			$this->post_history = get_post_meta( $this->ID, '_wp_to_diaspora_post_history', true );
182
-		}
183
-	}
184
-
185
-	/**
186
-	 * Post to diaspora* when saving a post.
187
-	 *
188
-	 * @since 1.5.0
189
-	 *
190
-	 * @todo Maybe somebody wants to share a password protected post to a closed aspect.
191
-	 *
192
-	 * @param integer $post_id ID of the post being saved.
193
-	 * @param WP_Post $post    Post object being saved.
194
-	 * @return boolean If the post was posted successfully.
195
-	 */
196
-	public function post( $post_id, $post ) {
197
-		$this->_assign_wp_post( $post );
198
-
199
-		$options = WP2D_Options::instance();
200
-
201
-		// Is this post type enabled for posting?
202
-		if ( ! in_array( $post->post_type, $options->get_option( 'enabled_post_types' ) ) ) {
203
-			return false;
204
-		}
205
-
206
-		// Make sure we're posting to diaspora* and the post isn't password protected.
207
-		if ( ! ( $this->post_to_diaspora && 'publish' === $post->post_status && '' === $post->post_password ) ) {
208
-			return false;
209
-		}
210
-
211
-		$status_message = $this->_get_title_link();
212
-
213
-		// Post the full post text or just the excerpt?
214
-		if ( 'full' === $this->display ) {
215
-			$status_message .= $this->_get_full_content();
216
-		} else {
217
-			$status_message .= $this->_get_excerpt_content();
218
-		}
219
-
220
-		// Add the tags assigned to the post.
221
-		$status_message .= $this->_get_tags_to_add();
222
-
223
-		// Add the original entry link to the post?
224
-		$status_message .= $this->_get_posted_at_link();
225
-
226
-		$status_converter = new HtmlConverter( array( 'strip_tags' => true ) );
227
-		$status_message  = $status_converter->convert( $status_message );
228
-
229
-		// Set up the connection to diaspora*.
230
-		$api = WP2D_Helpers::api_quick_connect();
231
-		if ( ! empty( $status_message ) ) {
232
-			if ( $api->has_last_error() ) {
233
-				// Save the post error as post meta data, so we can display it to the user.
234
-				update_post_meta( $post_id, '_wp_to_diaspora_post_error', $api->get_last_error() );
235
-				return false;
236
-			}
237
-
238
-			// Add services to share to via diaspora*.
239
-			$extra_data = array(
240
-				'services' => $this->services,
241
-			);
242
-
243
-			// Try to post to diaspora*.
244
-			if ( $response = $api->post( $status_message, $this->aspects, $extra_data ) ) {
245
-				// Save certain diaspora* post data as meta data for future reference.
246
-				$this->_save_to_history( (object) $response );
247
-
248
-				// If there is still a previous post error around, remove it.
249
-				delete_post_meta( $post_id, '_wp_to_diaspora_post_error' );
250
-
251
-				// Unset post_to_diaspora meta field to prevent mistakenly republishing to diaspora*.
252
-				$meta = get_post_meta( $post_id, '_wp_to_diaspora', true );
253
-				$meta['post_to_diaspora'] = false;
254
-				update_post_meta( $post_id, '_wp_to_diaspora', $meta );
255
-			}
256
-		} else {
257
-			return false;
258
-		}
259
-	}
260
-
261
-	/**
262
-	 * Get the title of the post linking to the post itself.
263
-	 *
264
-	 * @since 1.5.0
265
-	 *
266
-	 * @return string Post title as a link.
267
-	 */
268
-	private function _get_title_link() {
269
-		$title = esc_html( $this->post->post_title );
270
-		$permalink = get_permalink( $this->ID );
271
-		$default = sprintf( '<strong><a href="%2$s" title="%2$s">%1$s</a></strong>', $title, $permalink );
272
-
273
-		/**
274
-		 * Filter the title link at the top of the post.
275
-		 *
276
-		 * @since 1.5.4.1
277
-		 *
278
-		 * @param string $default   The whole HTML of the title link to be outputted.
279
-		 * @param string $title     The title of the original post.
280
-		 * @param string $permalink The permalink of the original post.
281
-		 */
282
-		$link = apply_filters( 'wp2d_title_filter', $default, $title, $permalink );
283
-
284
-		return '<p>' . $link . '</p>';
285
-	}
286
-
287
-	/**
288
-	 * Get the full post content with only default filters applied.
289
-	 *
290
-	 * @since 1.5.0
291
-	 *
292
-	 * @return string The full post content.
293
-	 */
294
-	private function _get_full_content() {
295
-		// Only allow certain shortcodes.
296
-		global $shortcode_tags;
297
-		$shortcode_tags_bkp = array();
298
-
299
-		foreach ( $shortcode_tags as $shortcode_tag => $shortcode_function ) {
300
-			if ( ! in_array( $shortcode_tag, apply_filters( 'wp2d_shortcodes_filter', array( 'wp_caption', 'caption', 'gallery' ) ) ) ) {
301
-				$shortcode_tags_bkp[ $shortcode_tag ] = $shortcode_function;
302
-				unset( $shortcode_tags[ $shortcode_tag ] );
303
-			}
304
-		}
305
-
306
-		// Disable all filters and then enable only defaults. This prevents additional filters from being posted to diaspora*.
307
-		remove_all_filters( 'the_content' );
308
-		foreach ( apply_filters( 'wp2d_content_filters_filter', array( 'do_shortcode', 'wptexturize', 'convert_smilies', 'convert_chars', 'wpautop', 'shortcode_unautop', 'prepend_attachment', array( $this, 'embed_remove' ) ) ) as $filter ) {
309
-			add_filter( 'the_content', $filter );
310
-		}
311
-
312
-		// Extract URLs from [embed] shortcodes.
313
-		add_filter( 'embed_oembed_html', array( $this, 'embed_url' ), 10, 2 );
314
-
315
-		// Add the pretty caption after the images.
316
-		add_filter( 'img_caption_shortcode', array( $this, 'custom_img_caption' ), 10, 3 );
317
-
318
-		// Overwrite the native shortcode handler to add pretty captions.
319
-		// http://wordpress.stackexchange.com/a/74675/54456 for explanation.
320
-		add_shortcode( 'gallery', array( $this, 'custom_gallery_shortcode' ) );
321
-
322
-		$full_content = apply_filters( 'the_content', $this->post->post_content );
323
-
324
-		// Put the removed shortcode tags back again.
325
-		$shortcode_tags += $shortcode_tags_bkp;
326
-
327
-		return $full_content;
328
-	}
329
-
330
-	/**
331
-	 * Get the post's excerpt in a nice format.
332
-	 *
333
-	 * @since 1.5.0
334
-	 *
335
-	 * @return string Post's excerpt.
336
-	 */
337
-	private function _get_excerpt_content() {
338
-		// Look for the excerpt in the following order:
339
-		// 1. Custom post excerpt.
340
-		// 2. Text up to the <!--more--> tag.
341
-		// 3. Manually trimmed content.
342
-		$content = $this->post->post_content;
343
-		$excerpt = $this->post->post_excerpt;
344
-		if ( '' === $excerpt ) {
345
-			if ( $more_pos = strpos( $content, '<!--more' ) ) {
346
-				$excerpt = substr( $content, 0, $more_pos );
347
-			} else {
348
-				$excerpt = wp_trim_words( $content, 42, '[...]' );
349
-			}
350
-		}
351
-		return '<p>' . $excerpt . '</p>';
352
-	}
353
-
354
-	/**
355
-	 * Get a string of tags that have been added to the post.
356
-	 *
357
-	 * @since 1.5.0
358
-	 *
359
-	 * @return string Tags added to the post.
360
-	 */
361
-	private function _get_tags_to_add() {
362
-		$options = WP2D_Options::instance();
363
-		$tags_to_post = $this->tags_to_post;
364
-		$tags_to_add  = '';
365
-
366
-		// Add any diaspora* tags?
367
-		if ( ! empty( $tags_to_post ) ) {
368
-			// The diaspora* tags to add to the post.
369
-			$diaspora_tags = array();
370
-
371
-			// Add global tags?
372
-			$global_tags = $options->get_option( 'global_tags' );
373
-			if ( in_array( 'global', $tags_to_post ) && is_array( $global_tags ) ) {
374
-				$diaspora_tags += array_flip( $global_tags );
375
-			}
376
-
377
-			// Add custom tags?
378
-			if ( in_array( 'custom', $tags_to_post ) && is_array( $this->custom_tags ) ) {
379
-				$diaspora_tags += array_flip( $this->custom_tags );
380
-			}
381
-
382
-			// Add post tags?
383
-			$post_tags = wp_get_post_tags( $this->ID, array( 'fields' => 'slugs' ) );
384
-			if ( in_array( 'post', $tags_to_post ) && is_array( $post_tags ) ) {
385
-				$diaspora_tags += array_flip( $post_tags );
386
-			}
387
-
388
-			// Get an array of cleaned up tags.
389
-			// NOTE: Validate method needs a variable, as it's passed by reference!
390
-			$diaspora_tags = array_keys( $diaspora_tags );
391
-			$options->validate_tags( $diaspora_tags );
392
-
393
-			// Get all the tags and list them all nicely in a row.
394
-			$diaspora_tags_clean = array();
395
-			foreach ( $diaspora_tags as $tag ) {
396
-				$diaspora_tags_clean[] = '#' . $tag;
397
-			}
398
-
399
-			// Add all the found tags.
400
-			if ( ! empty( $diaspora_tags_clean ) ) {
401
-				$tags_to_add = implode( ' ', $diaspora_tags_clean ) . '<br />';
402
-			}
403
-		}
404
-
405
-		return $tags_to_add;
406
-	}
407
-
408
-	/**
409
-	 * Get the link to the original post.
410
-	 *
411
-	 * @since 1.5.0
412
-	 *
413
-	 * @return string Original post link.
414
-	 */
415
-	private function _get_posted_at_link() {
416
-		$link = '';
417
-		if ( $this->fullentrylink ) {
418
-
419
-			$text = esc_html( 'Originally posted at:', 'wp-to-diaspora' );
420
-			$permalink = get_permalink( $this->ID );
421
-			$title = esc_html( 'Permalink', 'wp-to-diaspora' );
422
-			$default = sprintf( '%1$s <a href="%2$s" title="%3$s">%2$s</a>', $text, $permalink, $title );
423
-
424
-			/**
425
-			 * Filter the "Originally posted at" link at the bottom of the post.
426
-			 *
427
-			 * @since 1.5.4.1
428
-			 *
429
-			 * @param string $default   The whole HTML of the text and link to be outputted.
430
-			 * @param string $text      The "Originally posted at:" text before the link.
431
-			 * @param string $permalink The permalink of the original post.
432
-			 * @param string $title     The "Permalink" title of the link.
433
-			 */
434
-			$link = apply_filters( 'wp2d_posted_at_link_filter', $default, $text, $permalink, $title );
435
-
436
-			$link = '<p>' . $link . '</p>';
437
-		}
438
-
439
-		return $link;
440
-	}
441
-
442
-	/**
443
-	 * Save the details of the new diaspora* post to this post's history.
444
-	 *
445
-	 * @since 1.5.0
446
-	 *
447
-	 * @param object $response Response from the API containing the diaspora* post details.
448
-	 */
449
-	private function _save_to_history( $response ) {
450
-		// Make sure the post history is an array.
451
-		if ( empty( $this->post_history ) ) {
452
-			$this->post_history = array();
453
-		}
454
-
455
-		// Add a new entry to the history.
456
-		$this->post_history[] = array(
457
-			'id'         => $response->id,
458
-			'guid'       => $response->guid,
459
-			'created_at' => $this->post->post_modified,
460
-			'aspects'    => $this->aspects,
461
-			'nsfw'       => $response->nsfw,
462
-			'post_url'   => $response->permalink,
463
-		);
464
-
465
-		update_post_meta( $this->ID, '_wp_to_diaspora_post_history', $this->post_history );
466
-	}
467
-
468
-	/**
469
-	 * Return URL from [embed] shortcode instead of generated iframe.
470
-	 *
471
-	 * @since 1.5.0
472
-	 * @see WP_Embed::shortcode()
473
-	 *
474
-	 * @param mixed  $html The cached HTML result, stored in post meta.
475
-	 * @param string $url  The attempted embed URL.
476
-	 * @return string URL of the embed.
477
-	 */
478
-	public function embed_url( $html, $url ) {
479
-		return $url;
480
-	}
481
-
482
-	/**
483
-	 * Removes '[embed]' and '[/embed]' left by embed_url.
484
-	 *
485
-	 * @since 1.5.0
486
-	 * @todo It would be great to fix it using only one filter.
487
-	 *       It's happening because embed filter is being removed by remove_all_filters('the_content') on WP2D_Post::post().
488
-	 *
489
-	 * @param string $content Content of the post.
490
-	 * @return string The content with the embed tags removed.
491
-	 */
492
-	public function embed_remove( $content ) {
493
-		return str_replace( array( '[embed]', '[/embed]' ), array( '<p>', '</p>' ), $content );
494
-	}
495
-
496
-	/**
497
-	 * Prettify the image caption.
498
-	 *
499
-	 * @since 1.5.3
500
-	 *
501
-	 * @param string $caption Caption to be prettified.
502
-	 * @return string Prettified image caption.
503
-	 */
504
-	public function get_img_caption( $caption ) {
505
-		$caption = trim( $caption );
506
-		if ( '' === $caption ) {
507
-			return '';
508
-		}
509
-
510
-		$default = sprintf( '<blockquote>%s</blockquote>',  $caption );
511
-
512
-		/**
513
-		 * Filter the image caption to be displayed after images with captions.
514
-		 *
515
-		 * @since 1.5.3
516
-		 *
517
-		 * @param string $default The whole HTML of the caption.
518
-		 * @param string $caption The caption text.
519
-		 */
520
-		return apply_filters( 'wp2d_image_caption', $default, $caption );
521
-	}
522
-
523
-	/**
524
-	 * Filter the default caption shortcode output.
525
-	 *
526
-	 * @since 1.5.3
527
-	 * @see img_caption_shortcode()
528
-	 *
529
-	 * @param string $empty   The caption output. Default empty.
530
-	 * @param array  $attr    Attributes of the caption shortcode.
531
-	 * @param string $content The image element, possibly wrapped in a hyperlink.
532
-	 * @return string The caption shortcode output.
533
-	 */
534
-	public function custom_img_caption( $empty, $attr, $content ) {
535
-		$content = do_shortcode( $content );
536
-
537
-		// If a caption attribute is defined, we'll add it after the image.
538
-		if ( isset( $attr['caption'] ) && '' !== $attr['caption'] ) {
539
-			$content .= "\n" . $this->get_img_caption( $attr['caption'] );
540
-		}
541
-
542
-		return $content;
543
-	}
544
-
545
-	/**
546
-	 * Create a custom gallery caption output.
547
-	 *
548
-	 * @since 1.5.3
549
-	 *
550
-	 * @param   array $attr Gallery attributes.
551
-	 * @return  string
552
-	 */
553
-	public function custom_gallery_shortcode( $attr ) {
554
-		// Default value in WordPress.
555
-		$captiontag = ( current_theme_supports( 'html5', 'gallery' ) ) ? 'figcaption' : 'dd';
556
-
557
-		// User value.
558
-		if ( isset( $attr['captiontag'] ) ) {
559
-			$captiontag = $attr['captiontag'];
560
-		}
561
-
562
-		// Let WordPress create the regular gallery.
563
-		$gallery = gallery_shortcode( $attr );
564
-
565
-		// Change the content of the captions.
566
-		$gallery = preg_replace_callback(
567
-			'~(<' . $captiontag . '.*>)(.*)(</' . $captiontag . '>)~mUus',
568
-			array( $this, 'custom_gallery_regex_callback' ),
569
-			$gallery
570
-		);
571
-
572
-		return $gallery;
573
-	}
574
-
575
-	/**
576
-	 * Change the result of the regex match from custom_gallery_shortcode.
577
-	 *
578
-	 * @param array $m Regex matches.
579
-	 * @return string Prettified gallery image caption.
580
-	 */
581
-	public function custom_gallery_regex_callback( $m ) {
582
-		return $this->get_img_caption( $m[2] );
583
-	}
584
-
585
-	/*
21
+  /**
22
+   * The original post object.
23
+   *
24
+   * @var WP_Posts
25
+   * @since 1.5.0
26
+   */
27
+  public $post = null;
28
+
29
+  /**
30
+   * The original post ID.
31
+   *
32
+   * @var int
33
+   * @since 1.5.0
34
+   */
35
+  public $ID = null;
36
+
37
+  /**
38
+   * If this post should be shared on diaspora*.
39
+   *
40
+   * @var bool
41
+   * @since 1.5.0
42
+   */
43
+  public $post_to_diaspora = null;
44
+
45
+  /**
46
+   * If a link back to the original post should be added.
47
+   *
48
+   * @var bool
49
+   * @since 1.5.0
50
+   */
51
+  public $fullentrylink = null;
52
+
53
+  /**
54
+   * What content gets posted.
55
+   *
56
+   * @var string
57
+   * @since 1.5.0
58
+   */
59
+  public $display = null;
60
+
61
+  /**
62
+   * The types of tags to post. (global,custom,post)
63
+   *
64
+   * @var array
65
+   * @since 1.5.0
66
+   */
67
+  public $tags_to_post = null;
68
+
69
+  /**
70
+   * The post's custom tags.
71
+   *
72
+   * @var array
73
+   * @since 1.5.0
74
+   */
75
+  public $custom_tags = null;
76
+
77
+  /**
78
+   * Aspects this post gets posted to.
79
+   *
80
+   * @var array
81
+   * @since 1.5.0
82
+   */
83
+  public $aspects = null;
84
+
85
+  /**
86
+   * Services this post gets posted to.
87
+   *
88
+   * @var array
89
+   * @since 1.5.0
90
+   */
91
+  public $services = null;
92
+
93
+
94
+  /**
95
+   * The post's history of diaspora* posts.
96
+   *
97
+   * @var array
98
+   * @since 1.5.0
99
+   */
100
+  public $post_history = null;
101
+
102
+  /**
103
+   * If the post actions have all been set up already.
104
+   *
105
+   * @var boolean
106
+   * @since 1.5.0
107
+   */
108
+  private static $_is_set_up = false;
109
+
110
+  /**
111
+   * Setup all the necessary WP callbacks.
112
+   *
113
+   * @since 1.5.0
114
+   */
115
+  public static function setup() {
116
+    if ( self::$_is_set_up ) {
117
+      return;
118
+    }
119
+
120
+    $instance = new WP2D_Post( null );
121
+
122
+    // Notices when a post has been shared or if it has failed.
123
+    add_action( 'admin_notices', array( $instance, 'admin_notices' ) );
124
+    add_action( 'admin_init', array( $instance, 'ignore_post_error' ) );
125
+
126
+    // Handle diaspora* posting when saving the post.
127
+    add_action( 'save_post', array( $instance, 'post' ), 11, 2 );
128
+    add_action( 'save_post', array( $instance, 'save_meta_box_data' ), 10 );
129
+
130
+    // Add meta boxes.
131
+    add_action( 'add_meta_boxes', array( $instance, 'add_meta_boxes' ) );
132
+
133
+    self::$_is_set_up = true;
134
+  }
135
+
136
+  /**
137
+   * Constructor.
138
+   *
139
+   * @since 1.5.0
140
+   *
141
+   * @param int|WP_Post $post Post ID or the post itself.
142
+   */
143
+  public function __construct( $post ) {
144
+    $this->_assign_wp_post( $post );
145
+  }
146
+
147
+  /**
148
+   * Assign the original WP_Post object and all the custom meta data.
149
+   *
150
+   * @since 1.5.0
151
+   *
152
+   * @param int|WP_Post $post Post ID or the post itself.
153
+   */
154
+  private function _assign_wp_post( $post ) {
155
+    if ( $this->post = get_post( $post ) ) {
156
+      $this->ID = $this->post->ID;
157
+
158
+      $options = WP2D_Options::instance();
159
+
160
+      // Assign all meta values, expanding non-existent ones with the defaults.
161
+      $meta_current = get_post_meta( $this->ID, '_wp_to_diaspora', true );
162
+      $meta = wp_parse_args(
163
+        $meta_current,
164
+        $options->get_options()
165
+      );
166
+      if ( $meta ) {
167
+        foreach ( $meta as $key => $value ) {
168
+          $this->$key = $value;
169
+        }
170
+      }
171
+
172
+      // If no WP2D meta data has been saved yet, this post shouldn't be published.
173
+      // This can happen if existing posts (before WP2D) get updated externally, not through the post edit screen.
174
+      // Check gutobenn/wp-to-diaspora#91 for reference.
175
+      // Also, when we have a post scheduled for publishing, don't touch it.
176
+      // This is important when modifying scheduled posts using Quick Edit.
177
+      if ( ! in_array( $this->post->post_status, array( 'auto-draft', 'future' ) ) && ! $meta_current ) {
178
+        $this->post_to_diaspora = false;
179
+      }
180
+
181
+      $this->post_history = get_post_meta( $this->ID, '_wp_to_diaspora_post_history', true );
182
+    }
183
+  }
184
+
185
+  /**
186
+   * Post to diaspora* when saving a post.
187
+   *
188
+   * @since 1.5.0
189
+   *
190
+   * @todo Maybe somebody wants to share a password protected post to a closed aspect.
191
+   *
192
+   * @param integer $post_id ID of the post being saved.
193
+   * @param WP_Post $post    Post object being saved.
194
+   * @return boolean If the post was posted successfully.
195
+   */
196
+  public function post( $post_id, $post ) {
197
+    $this->_assign_wp_post( $post );
198
+
199
+    $options = WP2D_Options::instance();
200
+
201
+    // Is this post type enabled for posting?
202
+    if ( ! in_array( $post->post_type, $options->get_option( 'enabled_post_types' ) ) ) {
203
+      return false;
204
+    }
205
+
206
+    // Make sure we're posting to diaspora* and the post isn't password protected.
207
+    if ( ! ( $this->post_to_diaspora && 'publish' === $post->post_status && '' === $post->post_password ) ) {
208
+      return false;
209
+    }
210
+
211
+    $status_message = $this->_get_title_link();
212
+
213
+    // Post the full post text or just the excerpt?
214
+    if ( 'full' === $this->display ) {
215
+      $status_message .= $this->_get_full_content();
216
+    } else {
217
+      $status_message .= $this->_get_excerpt_content();
218
+    }
219
+
220
+    // Add the tags assigned to the post.
221
+    $status_message .= $this->_get_tags_to_add();
222
+
223
+    // Add the original entry link to the post?
224
+    $status_message .= $this->_get_posted_at_link();
225
+
226
+    $status_converter = new HtmlConverter( array( 'strip_tags' => true ) );
227
+    $status_message  = $status_converter->convert( $status_message );
228
+
229
+    // Set up the connection to diaspora*.
230
+    $api = WP2D_Helpers::api_quick_connect();
231
+    if ( ! empty( $status_message ) ) {
232
+      if ( $api->has_last_error() ) {
233
+        // Save the post error as post meta data, so we can display it to the user.
234
+        update_post_meta( $post_id, '_wp_to_diaspora_post_error', $api->get_last_error() );
235
+        return false;
236
+      }
237
+
238
+      // Add services to share to via diaspora*.
239
+      $extra_data = array(
240
+        'services' => $this->services,
241
+      );
242
+
243
+      // Try to post to diaspora*.
244
+      if ( $response = $api->post( $status_message, $this->aspects, $extra_data ) ) {
245
+        // Save certain diaspora* post data as meta data for future reference.
246
+        $this->_save_to_history( (object) $response );
247
+
248
+        // If there is still a previous post error around, remove it.
249
+        delete_post_meta( $post_id, '_wp_to_diaspora_post_error' );
250
+
251
+        // Unset post_to_diaspora meta field to prevent mistakenly republishing to diaspora*.
252
+        $meta = get_post_meta( $post_id, '_wp_to_diaspora', true );
253
+        $meta['post_to_diaspora'] = false;
254
+        update_post_meta( $post_id, '_wp_to_diaspora', $meta );
255
+      }
256
+    } else {
257
+      return false;
258
+    }
259
+  }
260
+
261
+  /**
262
+   * Get the title of the post linking to the post itself.
263
+   *
264
+   * @since 1.5.0
265
+   *
266
+   * @return string Post title as a link.
267
+   */
268
+  private function _get_title_link() {
269
+    $title = esc_html( $this->post->post_title );
270
+    $permalink = get_permalink( $this->ID );
271
+    $default = sprintf( '<strong><a href="%2$s" title="%2$s">%1$s</a></strong>', $title, $permalink );
272
+
273
+    /**
274
+     * Filter the title link at the top of the post.
275
+     *
276
+     * @since 1.5.4.1
277
+     *
278
+     * @param string $default   The whole HTML of the title link to be outputted.
279
+     * @param string $title     The title of the original post.
280
+     * @param string $permalink The permalink of the original post.
281
+     */
282
+    $link = apply_filters( 'wp2d_title_filter', $default, $title, $permalink );
283
+
284
+    return '<p>' . $link . '</p>';
285
+  }
286
+
287
+  /**
288
+   * Get the full post content with only default filters applied.
289
+   *
290
+   * @since 1.5.0
291
+   *
292
+   * @return string The full post content.
293
+   */
294
+  private function _get_full_content() {
295
+    // Only allow certain shortcodes.
296
+    global $shortcode_tags;
297
+    $shortcode_tags_bkp = array();
298
+
299
+    foreach ( $shortcode_tags as $shortcode_tag => $shortcode_function ) {
300
+      if ( ! in_array( $shortcode_tag, apply_filters( 'wp2d_shortcodes_filter', array( 'wp_caption', 'caption', 'gallery' ) ) ) ) {
301
+        $shortcode_tags_bkp[ $shortcode_tag ] = $shortcode_function;
302
+        unset( $shortcode_tags[ $shortcode_tag ] );
303
+      }
304
+    }
305
+
306
+    // Disable all filters and then enable only defaults. This prevents additional filters from being posted to diaspora*.
307
+    remove_all_filters( 'the_content' );
308
+    foreach ( apply_filters( 'wp2d_content_filters_filter', array( 'do_shortcode', 'wptexturize', 'convert_smilies', 'convert_chars', 'wpautop', 'shortcode_unautop', 'prepend_attachment', array( $this, 'embed_remove' ) ) ) as $filter ) {
309
+      add_filter( 'the_content', $filter );
310
+    }
311
+
312
+    // Extract URLs from [embed] shortcodes.
313
+    add_filter( 'embed_oembed_html', array( $this, 'embed_url' ), 10, 2 );
314
+
315
+    // Add the pretty caption after the images.
316
+    add_filter( 'img_caption_shortcode', array( $this, 'custom_img_caption' ), 10, 3 );
317
+
318
+    // Overwrite the native shortcode handler to add pretty captions.
319
+    // http://wordpress.stackexchange.com/a/74675/54456 for explanation.
320
+    add_shortcode( 'gallery', array( $this, 'custom_gallery_shortcode' ) );
321
+
322
+    $full_content = apply_filters( 'the_content', $this->post->post_content );
323
+
324
+    // Put the removed shortcode tags back again.
325
+    $shortcode_tags += $shortcode_tags_bkp;
326
+
327
+    return $full_content;
328
+  }
329
+
330
+  /**
331
+   * Get the post's excerpt in a nice format.
332
+   *
333
+   * @since 1.5.0
334
+   *
335
+   * @return string Post's excerpt.
336
+   */
337
+  private function _get_excerpt_content() {
338
+    // Look for the excerpt in the following order:
339
+    // 1. Custom post excerpt.
340
+    // 2. Text up to the <!--more--> tag.
341
+    // 3. Manually trimmed content.
342
+    $content = $this->post->post_content;
343
+    $excerpt = $this->post->post_excerpt;
344
+    if ( '' === $excerpt ) {
345
+      if ( $more_pos = strpos( $content, '<!--more' ) ) {
346
+        $excerpt = substr( $content, 0, $more_pos );
347
+      } else {
348
+        $excerpt = wp_trim_words( $content, 42, '[...]' );
349
+      }
350
+    }
351
+    return '<p>' . $excerpt . '</p>';
352
+  }
353
+
354
+  /**
355
+   * Get a string of tags that have been added to the post.
356
+   *
357
+   * @since 1.5.0
358
+   *
359
+   * @return string Tags added to the post.
360
+   */
361
+  private function _get_tags_to_add() {
362
+    $options = WP2D_Options::instance();
363
+    $tags_to_post = $this->tags_to_post;
364
+    $tags_to_add  = '';
365
+
366
+    // Add any diaspora* tags?
367
+    if ( ! empty( $tags_to_post ) ) {
368
+      // The diaspora* tags to add to the post.
369
+      $diaspora_tags = array();
370
+
371
+      // Add global tags?
372
+      $global_tags = $options->get_option( 'global_tags' );
373
+      if ( in_array( 'global', $tags_to_post ) && is_array( $global_tags ) ) {
374
+        $diaspora_tags += array_flip( $global_tags );
375
+      }
376
+
377
+      // Add custom tags?
378
+      if ( in_array( 'custom', $tags_to_post ) && is_array( $this->custom_tags ) ) {
379
+        $diaspora_tags += array_flip( $this->custom_tags );
380
+      }
381
+
382
+      // Add post tags?
383
+      $post_tags = wp_get_post_tags( $this->ID, array( 'fields' => 'slugs' ) );
384
+      if ( in_array( 'post', $tags_to_post ) && is_array( $post_tags ) ) {
385
+        $diaspora_tags += array_flip( $post_tags );
386
+      }
387
+
388
+      // Get an array of cleaned up tags.
389
+      // NOTE: Validate method needs a variable, as it's passed by reference!
390
+      $diaspora_tags = array_keys( $diaspora_tags );
391
+      $options->validate_tags( $diaspora_tags );
392
+
393
+      // Get all the tags and list them all nicely in a row.
394
+      $diaspora_tags_clean = array();
395
+      foreach ( $diaspora_tags as $tag ) {
396
+        $diaspora_tags_clean[] = '#' . $tag;
397
+      }
398
+
399
+      // Add all the found tags.
400
+      if ( ! empty( $diaspora_tags_clean ) ) {
401
+        $tags_to_add = implode( ' ', $diaspora_tags_clean ) . '<br />';
402
+      }
403
+    }
404
+
405
+    return $tags_to_add;
406
+  }
407
+
408
+  /**
409
+   * Get the link to the original post.
410
+   *
411
+   * @since 1.5.0
412
+   *
413
+   * @return string Original post link.
414
+   */
415
+  private function _get_posted_at_link() {
416
+    $link = '';
417
+    if ( $this->fullentrylink ) {
418
+
419
+      $text = esc_html( 'Originally posted at:', 'wp-to-diaspora' );
420
+      $permalink = get_permalink( $this->ID );
421
+      $title = esc_html( 'Permalink', 'wp-to-diaspora' );
422
+      $default = sprintf( '%1$s <a href="%2$s" title="%3$s">%2$s</a>', $text, $permalink, $title );
423
+
424
+      /**
425
+       * Filter the "Originally posted at" link at the bottom of the post.
426
+       *
427
+       * @since 1.5.4.1
428
+       *
429
+       * @param string $default   The whole HTML of the text and link to be outputted.
430
+       * @param string $text      The "Originally posted at:" text before the link.
431
+       * @param string $permalink The permalink of the original post.
432
+       * @param string $title     The "Permalink" title of the link.
433
+       */
434
+      $link = apply_filters( 'wp2d_posted_at_link_filter', $default, $text, $permalink, $title );
435
+
436
+      $link = '<p>' . $link . '</p>';
437
+    }
438
+
439
+    return $link;
440
+  }
441
+
442
+  /**
443
+   * Save the details of the new diaspora* post to this post's history.
444
+   *
445
+   * @since 1.5.0
446
+   *
447
+   * @param object $response Response from the API containing the diaspora* post details.
448
+   */
449
+  private function _save_to_history( $response ) {
450
+    // Make sure the post history is an array.
451
+    if ( empty( $this->post_history ) ) {
452
+      $this->post_history = array();
453
+    }
454
+
455
+    // Add a new entry to the history.
456
+    $this->post_history[] = array(
457
+      'id'         => $response->id,
458
+      'guid'       => $response->guid,
459
+      'created_at' => $this->post->post_modified,
460
+      'aspects'    => $this->aspects,
461
+      'nsfw'       => $response->nsfw,
462
+      'post_url'   => $response->permalink,
463
+    );
464
+
465
+    update_post_meta( $this->ID, '_wp_to_diaspora_post_history', $this->post_history );
466
+  }
467
+
468
+  /**
469
+   * Return URL from [embed] shortcode instead of generated iframe.
470
+   *
471
+   * @since 1.5.0
472
+   * @see WP_Embed::shortcode()
473
+   *
474
+   * @param mixed  $html The cached HTML result, stored in post meta.
475
+   * @param string $url  The attempted embed URL.
476
+   * @return string URL of the embed.
477
+   */
478
+  public function embed_url( $html, $url ) {
479
+    return $url;
480
+  }
481
+
482
+  /**
483
+   * Removes '[embed]' and '[/embed]' left by embed_url.
484
+   *
485
+   * @since 1.5.0
486
+   * @todo It would be great to fix it using only one filter.
487
+   *       It's happening because embed filter is being removed by remove_all_filters('the_content') on WP2D_Post::post().
488
+   *
489
+   * @param string $content Content of the post.
490
+   * @return string The content with the embed tags removed.
491
+   */
492
+  public function embed_remove( $content ) {
493
+    return str_replace( array( '[embed]', '[/embed]' ), array( '<p>', '</p>' ), $content );
494
+  }
495
+
496
+  /**
497
+   * Prettify the image caption.
498
+   *
499
+   * @since 1.5.3
500
+   *
501
+   * @param string $caption Caption to be prettified.
502
+   * @return string Prettified image caption.
503
+   */
504
+  public function get_img_caption( $caption ) {
505
+    $caption = trim( $caption );
506
+    if ( '' === $caption ) {
507
+      return '';
508
+    }
509
+
510
+    $default = sprintf( '<blockquote>%s</blockquote>',  $caption );
511
+
512
+    /**
513
+     * Filter the image caption to be displayed after images with captions.
514
+     *
515
+     * @since 1.5.3
516
+     *
517
+     * @param string $default The whole HTML of the caption.
518
+     * @param string $caption The caption text.
519
+     */
520
+    return apply_filters( 'wp2d_image_caption', $default, $caption );
521
+  }
522
+
523
+  /**
524
+   * Filter the default caption shortcode output.
525
+   *
526
+   * @since 1.5.3
527
+   * @see img_caption_shortcode()
528
+   *
529
+   * @param string $empty   The caption output. Default empty.
530
+   * @param array  $attr    Attributes of the caption shortcode.
531
+   * @param string $content The image element, possibly wrapped in a hyperlink.
532
+   * @return string The caption shortcode output.
533
+   */
534
+  public function custom_img_caption( $empty, $attr, $content ) {
535
+    $content = do_shortcode( $content );
536
+
537
+    // If a caption attribute is defined, we'll add it after the image.
538
+    if ( isset( $attr['caption'] ) && '' !== $attr['caption'] ) {
539
+      $content .= "\n" . $this->get_img_caption( $attr['caption'] );
540
+    }
541
+
542
+    return $content;
543
+  }
544
+
545
+  /**
546
+   * Create a custom gallery caption output.
547
+   *
548
+   * @since 1.5.3
549
+   *
550
+   * @param   array $attr Gallery attributes.
551
+   * @return  string
552
+   */
553
+  public function custom_gallery_shortcode( $attr ) {
554
+    // Default value in WordPress.
555
+    $captiontag = ( current_theme_supports( 'html5', 'gallery' ) ) ? 'figcaption' : 'dd';
556
+
557
+    // User value.
558
+    if ( isset( $attr['captiontag'] ) ) {
559
+      $captiontag = $attr['captiontag'];
560
+    }
561
+
562
+    // Let WordPress create the regular gallery.
563
+    $gallery = gallery_shortcode( $attr );
564
+
565
+    // Change the content of the captions.
566
+    $gallery = preg_replace_callback(
567
+      '~(<' . $captiontag . '.*>)(.*)(</' . $captiontag . '>)~mUus',
568
+      array( $this, 'custom_gallery_regex_callback' ),
569
+      $gallery
570
+    );
571
+
572
+    return $gallery;
573
+  }
574
+
575
+  /**
576
+   * Change the result of the regex match from custom_gallery_shortcode.
577
+   *
578
+   * @param array $m Regex matches.
579
+   * @return string Prettified gallery image caption.
580
+   */
581
+  public function custom_gallery_regex_callback( $m ) {
582
+    return $this->get_img_caption( $m[2] );
583
+  }
584
+
585
+  /*
586 586
 	 * META BOX
587 587
 	 */
588 588
 
589
-	/**
590
-	 * Adds a meta box to the main column on the enabled Post Types' edit screens.
591
-	 *
592
-	 * @since 1.5.0
593
-	 */
594
-	public function add_meta_boxes() {
595
-		$options = WP2D_Options::instance();
596
-		foreach ( $options->get_option( 'enabled_post_types' ) as $post_type ) {
597
-			add_meta_box(
598
-				'wp_to_diaspora_meta_box',
599
-				'WP to diaspora*',
600
-				array( $this, 'meta_box_render' ),
601
-				$post_type,
602
-				'side',
603
-				'high'
604
-			);
605
-		}
606
-	}
607
-
608
-	/**
609
-	 * Prints the meta box content.
610
-	 *
611
-	 * @since 1.5.0
612
-	 *
613
-	 * @param WP_Post $post The object for the current post.
614
-	 */
615
-	public function meta_box_render( $post ) {
616
-		$this->_assign_wp_post( $post );
617
-
618
-		// Add an nonce field so we can check for it later.
619
-		wp_nonce_field( 'wp_to_diaspora_meta_box', 'wp_to_diaspora_meta_box_nonce' );
620
-
621
-		// Get the default values to use, but give priority to the meta data already set.
622
-		$options = WP2D_Options::instance();
623
-
624
-		// Make sure we have some value for post meta fields.
625
-		$this->custom_tags = $this->custom_tags ?: array();
626
-
627
-		// If this post is already published, don't post again to diaspora* by default.
628
-		$this->post_to_diaspora = ( $this->post_to_diaspora && 'publish' !== get_post_status( $this->ID ) );
629
-		$this->aspects          = $this->aspects  ?: array();
630
-		$this->services         = $this->services ?: array();
631
-
632
-		// Have we already posted on diaspora*?
633
-		if ( is_array( $this->post_history ) ) {
634
-			$latest_post = end( $this->post_history );
635
-			?>
589
+  /**
590
+   * Adds a meta box to the main column on the enabled Post Types' edit screens.
591
+   *
592
+   * @since 1.5.0
593
+   */
594
+  public function add_meta_boxes() {
595
+    $options = WP2D_Options::instance();
596
+    foreach ( $options->get_option( 'enabled_post_types' ) as $post_type ) {
597
+      add_meta_box(
598
+        'wp_to_diaspora_meta_box',
599
+        'WP to diaspora*',
600
+        array( $this, 'meta_box_render' ),
601
+        $post_type,
602
+        'side',
603
+        'high'
604
+      );
605
+    }
606
+  }
607
+
608
+  /**
609
+   * Prints the meta box content.
610
+   *
611
+   * @since 1.5.0
612
+   *
613
+   * @param WP_Post $post The object for the current post.
614
+   */
615
+  public function meta_box_render( $post ) {
616
+    $this->_assign_wp_post( $post );
617
+
618
+    // Add an nonce field so we can check for it later.
619
+    wp_nonce_field( 'wp_to_diaspora_meta_box', 'wp_to_diaspora_meta_box_nonce' );
620
+
621
+    // Get the default values to use, but give priority to the meta data already set.
622
+    $options = WP2D_Options::instance();
623
+
624
+    // Make sure we have some value for post meta fields.
625
+    $this->custom_tags = $this->custom_tags ?: array();
626
+
627
+    // If this post is already published, don't post again to diaspora* by default.
628
+    $this->post_to_diaspora = ( $this->post_to_diaspora && 'publish' !== get_post_status( $this->ID ) );
629
+    $this->aspects          = $this->aspects  ?: array();
630
+    $this->services         = $this->services ?: array();
631
+
632
+    // Have we already posted on diaspora*?
633
+    if ( is_array( $this->post_history ) ) {
634
+      $latest_post = end( $this->post_history );
635
+      ?>
636 636
 			<p><a href="<?php echo esc_attr( $latest_post['post_url'] ); ?>" target="_blank"><?php esc_html_e( 'Already posted to diaspora*.', 'wp-to-diaspora' ); ?></a></p>
637 637
 			<?php
638
-		}
639
-		?>
638
+    }
639
+    ?>
640 640
 
641 641
 		<p><?php $options->post_to_diaspora_render( $this->post_to_diaspora ); ?></p>
642 642
 		<p><?php $options->fullentrylink_render( $this->fullentrylink ); ?></p>
@@ -647,133 +647,133 @@  discard block
 block discarded – undo
647 647
 		<p><?php $options->aspects_services_render( array( 'services', $this->services ) ); ?></p>
648 648
 
649 649
 		<?php
650
-	}
651
-
652
-	/**
653
-	 * When the post is saved, save our meta data.
654
-	 *
655
-	 * @since 1.5.0
656
-	 *
657
-	 * @param integer $post_id The ID of the post being saved.
658
-	 */
659
-	public function save_meta_box_data( $post_id ) {
660
-		/*
650
+  }
651
+
652
+  /**
653
+   * When the post is saved, save our meta data.
654
+   *
655
+   * @since 1.5.0
656
+   *
657
+   * @param integer $post_id The ID of the post being saved.
658
+   */
659
+  public function save_meta_box_data( $post_id ) {
660
+    /*
661 661
 		 * We need to verify this came from our screen and with proper authorization,
662 662
 		 * because the save_post action can be triggered at other times.
663 663
 		 */
664
-		if ( ! $this->_is_safe_to_save() ) {
665
-			return;
666
-		}
667
-
668
-		/* OK, it's safe for us to save the data now. */
669
-
670
-		// Meta data to save.
671
-		$meta_to_save = $_POST['wp_to_diaspora_settings'];
672
-		$options = WP2D_Options::instance();
673
-
674
-		// Checkboxes.
675
-		$options->validate_checkboxes( array( 'post_to_diaspora', 'fullentrylink' ), $meta_to_save );
676
-
677
-		// Single Selects.
678
-		$options->validate_single_selects( 'display', $meta_to_save );
679
-
680
-		// Multiple Selects.
681
-		$options->validate_multi_selects( 'tags_to_post', $meta_to_save );
682
-
683
-		// Save custom tags as array.
684
-		$options->validate_tags( $meta_to_save['custom_tags'] );
685
-
686
-		// Clean up the list of aspects. If the list is empty, only use the 'Public' aspect.
687
-		$options->validate_aspects_services( $meta_to_save['aspects'], array( 'public' ) );
688
-
689
-		// Clean up the list of services.
690
-		$options->validate_aspects_services( $meta_to_save['services'] );
691
-
692
-		// Update the meta data for this post.
693
-		update_post_meta( $post_id, '_wp_to_diaspora', $meta_to_save );
694
-	}
695
-
696
-	/**
697
-	 * Perform all checks to see if we are allowed to save the meta data.
698
-	 *
699
-	 * @since 1.5.0
700
-	 *
701
-	 * @return boolean If the verification checks have passed.
702
-	 */
703
-	private function _is_safe_to_save() {
704
-		// Verify that our nonce is set and  valid.
705
-		if ( ! ( isset( $_POST['wp_to_diaspora_meta_box_nonce'] ) && wp_verify_nonce( $_POST['wp_to_diaspora_meta_box_nonce'], 'wp_to_diaspora_meta_box' ) ) ) {
706
-			return false;
707
-		}
708
-
709
-		// If this is an autosave, our form has not been submitted, so we don't want to do anything.
710
-		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
711
-			return false;
712
-		}
713
-
714
-		// Check the user's permissions.
715
-		$permission = ( isset( $_POST['post_type'] ) && 'page' === $_POST['post_type'] ) ? 'edit_pages' : 'edit_posts';
716
-		if ( ! current_user_can( $permission, $this->ID ) ) {
717
-			return false;
718
-		}
719
-
720
-		// Make real sure that we have some meta data to save.
721
-		if ( ! isset( $_POST['wp_to_diaspora_settings'] ) ) {
722
-			return false;
723
-		}
724
-
725
-		return true;
726
-	}
727
-
728
-	/**
729
-	 * Add admin notices when a post gets displayed.
730
-	 *
731
-	 * @since 1.5.0
732
-	 *
733
-	 * @todo Ignore post error with AJAX.
734
-	 */
735
-	public function admin_notices() {
736
-		global $post, $pagenow;
737
-		if ( ! $post || 'post.php' !== $pagenow ) {
738
-			return;
739
-		}
740
-
741
-		if ( ( $error = get_post_meta( $post->ID, '_wp_to_diaspora_post_error', true ) ) && is_wp_error( $error ) ) {
742
-			// Are we adding a help tab link to this notice?
743
-			$help_link = WP2D_Contextual_Help::get_help_tab_quick_link( $error );
744
-
745
-			// This notice will only be shown if posting to diaspora* has failed.
746
-			printf( '<div class="error notice is-dismissible"><p>%1$s %2$s %3$s <a href="%4$s">%5$s</a></p></div>',
747
-				esc_html__( 'Failed to post to diaspora*.', 'wp-to-diaspora' ),
748
-				esc_html__( $error->get_error_message() ),
749
-				$help_link,
750
-				esc_url( add_query_arg( 'wp2d_ignore_post_error', '' ) ),
751
-				esc_html__( 'Ignore', 'wp-to-diaspora' )
752
-			);
753
-		} elseif ( ( $diaspora_post_history = get_post_meta( $post->ID, '_wp_to_diaspora_post_history', true ) ) && is_array( $diaspora_post_history ) ) {
754
-			// Get the latest post from the history.
755
-			$latest_post = end( $diaspora_post_history );
756
-
757
-			// Only show if this post is showing a message and the post is a fresh share.
758
-			if ( isset( $_GET['message'] ) && $post->post_modified === $latest_post['created_at'] ) {
759
-				printf( '<div class="updated notice is-dismissible"><p>%1$s <a href="%2$s" target="_blank">%3$s</a></p></div>',
760
-					esc_html__( 'Successfully posted to diaspora*.', 'wp-to-diaspora' ),
761
-					esc_url( $latest_post['post_url'] ),
762
-					esc_html__( 'View Post' )
763
-				);
764
-			}
765
-		}
766
-	}
767
-
768
-	/**
769
-	 * Delete the error post meta data if it gets ignored.
770
-	 *
771
-	 * @since 1.5.0
772
-	 */
773
-	public function ignore_post_error() {
774
-		// If "Ignore" link has been clicked, delete the post error meta data.
775
-		if ( isset( $_GET['wp2d_ignore_post_error'], $_GET['post'] ) ) {
776
-			delete_post_meta( $_GET['post'], '_wp_to_diaspora_post_error' );
777
-		}
778
-	}
664
+    if ( ! $this->_is_safe_to_save() ) {
665
+      return;
666
+    }
667
+
668
+    /* OK, it's safe for us to save the data now. */
669
+
670
+    // Meta data to save.
671
+    $meta_to_save = $_POST['wp_to_diaspora_settings'];
672
+    $options = WP2D_Options::instance();
673
+
674
+    // Checkboxes.
675
+    $options->validate_checkboxes( array( 'post_to_diaspora', 'fullentrylink' ), $meta_to_save );
676
+
677
+    // Single Selects.
678
+    $options->validate_single_selects( 'display', $meta_to_save );
679
+
680
+    // Multiple Selects.
681
+    $options->validate_multi_selects( 'tags_to_post', $meta_to_save );
682
+
683
+    // Save custom tags as array.
684
+    $options->validate_tags( $meta_to_save['custom_tags'] );
685
+
686
+    // Clean up the list of aspects. If the list is empty, only use the 'Public' aspect.
687
+    $options->validate_aspects_services( $meta_to_save['aspects'], array( 'public' ) );
688
+
689
+    // Clean up the list of services.
690
+    $options->validate_aspects_services( $meta_to_save['services'] );
691
+
692
+    // Update the meta data for this post.
693
+    update_post_meta( $post_id, '_wp_to_diaspora', $meta_to_save );
694
+  }
695
+
696
+  /**
697
+   * Perform all checks to see if we are allowed to save the meta data.
698
+   *
699
+   * @since 1.5.0
700
+   *
701
+   * @return boolean If the verification checks have passed.
702
+   */
703
+  private function _is_safe_to_save() {
704
+    // Verify that our nonce is set and  valid.
705
+    if ( ! ( isset( $_POST['wp_to_diaspora_meta_box_nonce'] ) && wp_verify_nonce( $_POST['wp_to_diaspora_meta_box_nonce'], 'wp_to_diaspora_meta_box' ) ) ) {
706
+      return false;
707
+    }
708
+
709
+    // If this is an autosave, our form has not been submitted, so we don't want to do anything.
710
+    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
711
+      return false;
712
+    }
713
+
714
+    // Check the user's permissions.
715
+    $permission = ( isset( $_POST['post_type'] ) && 'page' === $_POST['post_type'] ) ? 'edit_pages' : 'edit_posts';
716
+    if ( ! current_user_can( $permission, $this->ID ) ) {
717
+      return false;
718
+    }
719
+
720
+    // Make real sure that we have some meta data to save.
721
+    if ( ! isset( $_POST['wp_to_diaspora_settings'] ) ) {
722
+      return false;
723
+    }
724
+
725
+    return true;
726
+  }
727
+
728
+  /**
729
+   * Add admin notices when a post gets displayed.
730
+   *
731
+   * @since 1.5.0
732
+   *
733
+   * @todo Ignore post error with AJAX.
734
+   */
735
+  public function admin_notices() {
736
+    global $post, $pagenow;
737
+    if ( ! $post || 'post.php' !== $pagenow ) {
738
+      return;
739
+    }
740
+
741
+    if ( ( $error = get_post_meta( $post->ID, '_wp_to_diaspora_post_error', true ) ) && is_wp_error( $error ) ) {
742
+      // Are we adding a help tab link to this notice?
743
+      $help_link = WP2D_Contextual_Help::get_help_tab_quick_link( $error );
744
+
745
+      // This notice will only be shown if posting to diaspora* has failed.
746
+      printf( '<div class="error notice is-dismissible"><p>%1$s %2$s %3$s <a href="%4$s">%5$s</a></p></div>',
747
+        esc_html__( 'Failed to post to diaspora*.', 'wp-to-diaspora' ),
748
+        esc_html__( $error->get_error_message() ),
749
+        $help_link,
750
+        esc_url( add_query_arg( 'wp2d_ignore_post_error', '' ) ),
751
+        esc_html__( 'Ignore', 'wp-to-diaspora' )
752
+      );
753
+    } elseif ( ( $diaspora_post_history = get_post_meta( $post->ID, '_wp_to_diaspora_post_history', true ) ) && is_array( $diaspora_post_history ) ) {
754
+      // Get the latest post from the history.
755
+      $latest_post = end( $diaspora_post_history );
756
+
757
+      // Only show if this post is showing a message and the post is a fresh share.
758
+      if ( isset( $_GET['message'] ) && $post->post_modified === $latest_post['created_at'] ) {
759
+        printf( '<div class="updated notice is-dismissible"><p>%1$s <a href="%2$s" target="_blank">%3$s</a></p></div>',
760
+          esc_html__( 'Successfully posted to diaspora*.', 'wp-to-diaspora' ),
761
+          esc_url( $latest_post['post_url'] ),
762
+          esc_html__( 'View Post' )
763
+        );
764
+      }
765
+    }
766
+  }
767
+
768
+  /**
769
+   * Delete the error post meta data if it gets ignored.
770
+   *
771
+   * @since 1.5.0
772
+   */
773
+  public function ignore_post_error() {
774
+    // If "Ignore" link has been clicked, delete the post error meta data.
775
+    if ( isset( $_GET['wp2d_ignore_post_error'], $_GET['post'] ) ) {
776
+      delete_post_meta( $_GET['post'], '_wp_to_diaspora_post_error' );
777
+    }
778
+  }
779 779
 }
Please login to merge, or discard this patch.