PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | class.frame-nonce-preview.php +133 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,133 @@
1 +<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 +/**
3 + * Allows viewing posts on the frontend when the user is not logged in.
4 + *
5 + * @package automattic/jetpack
6 + */
7 +
8 +// phpcs:disable WordPress.Security.NonceVerification.Recommended -- This is _implementing_ cross-site nonce handling, no need for WordPress's nonces.
9 +
10 +/**
11 + * Allows viewing posts on the frontend when the user is not logged in.
12 + */
13 +class Jetpack_Frame_Nonce_Preview {
14 + /**
15 + * Static instance.
16 + *
17 + * @todo This should be private.
18 + * @var self
19 + */
20 + public static $instance = null;
21 +
22 + /**
23 + * Returns the single instance of the Jetpack_Frame_Nonce_Preview object
24 + *
25 + * @since 4.3.0
26 + *
27 + * @return Jetpack_Frame_Nonce_Preview
28 + **/
29 + public static function get_instance() {
30 + if ( null === self::$instance ) {
31 + self::$instance = new Jetpack_Frame_Nonce_Preview();
32 + }
33 +
34 + return self::$instance;
35 + }
36 +
37 + /**
38 + * Constructor.
39 + *
40 + * @todo This should be private.
41 + */
42 + public function __construct() {
43 + if ( isset( $_GET['frame-nonce'] ) && ! is_admin() ) {
44 + add_filter( 'pre_get_posts', array( $this, 'maybe_display_post' ) );
45 + }
46 +
47 + // autosave previews are validated differently.
48 + if ( isset( $_GET['frame-nonce'] ) && isset( $_GET['preview_id'] ) && isset( $_GET['preview_nonce'] ) ) {
49 + remove_action( 'init', '_show_post_preview' );
50 + add_action( 'init', array( $this, 'handle_autosave_nonce_validation' ) );
51 + }
52 + }
53 +
54 + /**
55 + * Verify that frame nonce exists, and if so, validate the nonce by calling WP.com.
56 + *
57 + * @since 4.3.0
58 + *
59 + * @return bool
60 + */
61 + public function is_frame_nonce_valid() {
62 + if ( empty( $_GET['frame-nonce'] ) ) {
63 + return false;
64 + }
65 +
66 + $xml = new Jetpack_IXR_Client();
67 + $xml->query( 'jetpack.verifyFrameNonce', sanitize_key( $_GET['frame-nonce'] ) );
68 +
69 + if ( $xml->isError() ) {
70 + return false;
71 + }
72 +
73 + return (bool) $xml->getResponse();
74 + }
75 +
76 + /**
77 + * Conditionally add a hook on posts_results if this is the main query, a preview, and singular.
78 + *
79 + * @since 4.3.0
80 + *
81 + * @param WP_Query $query Query.
82 + * @return WP_Query
83 + */
84 + public function maybe_display_post( $query ) {
85 + if (
86 + $query->is_main_query() &&
87 + $query->is_preview() &&
88 + $query->is_singular()
89 + ) {
90 + add_filter( 'posts_results', array( $this, 'set_post_to_publish' ), 10, 2 );
91 + }
92 +
93 + return $query;
94 + }
95 +
96 + /**
97 + * Conditionally set the first post to 'publish' if the frame nonce is valid and there is a post.
98 + *
99 + * @since 4.3.0
100 + *
101 + * @param array $posts Posts.
102 + * @return array
103 + */
104 + public function set_post_to_publish( $posts ) {
105 + remove_filter( 'posts_results', array( $this, 'set_post_to_publish' ), 10 );
106 +
107 + if ( empty( $posts ) || is_user_logged_in() || ! $this->is_frame_nonce_valid() ) {
108 + return $posts;
109 + }
110 +
111 + $posts[0]->post_status = 'publish';
112 +
113 + // Disable comments and pings for this post.
114 + add_filter( 'comments_open', '__return_false' );
115 + add_filter( 'pings_open', '__return_false' );
116 +
117 + return $posts;
118 + }
119 +
120 + /**
121 + * Handle validation for autosave preview request
122 + *
123 + * @since 4.7.0
124 + */
125 + public function handle_autosave_nonce_validation() {
126 + if ( ! $this->is_frame_nonce_valid() ) {
127 + wp_die( esc_html__( 'Sorry, you are not allowed to preview drafts.', 'jetpack' ) );
128 + }
129 + add_filter( 'the_preview', '_set_preview' );
130 + }
131 +}
132 +
133 +Jetpack_Frame_Nonce_Preview::get_instance();