PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 7.6
Jetpack – WP Security, Backup, Speed, & Growth v7.6
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 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
jetpack / modules / comments / base.php

base.php in Jetpack – WP Security, Backup, Speed, & Growth 7.6, at modules/comments/base.php

309 lines 9.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * All the code shared between WP.com Highlander and Jetpack Highlander
5 */
6 class Highlander_Comments_Base {
7 function __construct() {
8 $this->setup_globals();
9 $this->setup_actions();
10 $this->setup_filters();
11 }
12
13 /**
14 * Set any global variables or class variables
15 * @since JetpackComments (1.4)
16 */
17 protected function setup_globals() {}
18
19 /**
20 * Setup actions for methods in this class
21 * @since JetpackComments (1.4)
22 */
23 protected function setup_actions() {
24 // Before a comment is posted
25 add_action( 'pre_comment_on_post', array( $this, 'allow_logged_out_user_to_comment_as_external' ) );
26
27 // After a comment is posted
28 add_action( 'comment_post', array( $this, 'set_comment_cookies' ) );
29 }
30
31 /**
32 * Setup filters for methods in this class
33 * @since JetpackComments (1.4)
34 */
35 protected function setup_filters() {
36 add_filter( 'comments_array', array( $this, 'comments_array' ) );
37 add_filter( 'preprocess_comment', array( $this, 'allow_logged_in_user_to_comment_as_guest' ), 0 );
38 }
39
40 /**
41 * Is this a Highlander POST request?
42 * Optionally restrict to one or more credentials slug (facebook, twitter, ...)
43 *
44 * @param string Comment credentials slug
45 * @param ...
46 * @return false|string false if it's not a Highlander POST request. The matching credentials slug if it is.
47 */
48 function is_highlander_comment_post() {
49 if ( empty( $_POST['hc_post_as'] ) ) {
50 return false;
51 }
52
53 if ( func_num_args() ) {
54 foreach ( func_get_args() as $id_source ) {
55 if ( $id_source === $_POST['hc_post_as'] ) {
56 return $id_source;
57 }
58 }
59 return false;
60 }
61
62 return is_string( $_POST['hc_post_as'] ) && in_array( $_POST['hc_post_as'], $this->id_sources ) ? $_POST['hc_post_as'] : false;
63 }
64
65 /**
66 * Signs an array of scalars with the self-hosted blog's Jetpack Token
67 *
68 * @param array $parameters
69 * @param string $key
70 * @return string HMAC
71 */
72 static function sign_remote_comment_parameters( $parameters, $key ) {
73 unset(
74 $parameters['sig'], // Don't sign the signature
75 $parameters['replytocom'] // This parameter is unsigned - it changes dynamically as the comment form moves from parent comment to parent comment
76 );
77
78 ksort( $parameters );
79
80 $signing = array();
81 foreach ( $parameters as $k => $v ) {
82 if ( ! is_scalar( $v ) ) {
83 return new WP_Error( 'invalid_input', __( 'Invalid request', 'jetpack' ), array( 'status' => 400 ) );
84 }
85
86 $signing[] = "{$k}={$v}";
87 }
88
89 return hash_hmac( 'sha1', implode( ':', $signing ), $key );
90 }
91
92 /*
93 * After commenting as a guest while logged in, the user needs to see both:
94 *
95 * ( user_id = blah AND comment_approved = 0 )
96 * and
97 * ( comment_author_email = blah AND comment_approved = 0 )
98 *
99 * Core only does the first since the user is logged in.
100 *
101 * Add the second to the comments array.
102 */
103 function comments_array( $comments ) {
104 global $wpdb, $post;
105
106 $commenter = $this->get_current_commenter();
107
108 if ( ! $commenter['user_id'] ) {
109 return $comments;
110 }
111
112 if ( ! $commenter['comment_author'] ) {
113 return $comments;
114 }
115
116 $in_moderation_comments = $wpdb->get_results(
117 $wpdb->prepare(
118 "SELECT * FROM `$wpdb->comments` WHERE `comment_post_ID` = %d AND `user_id` = 0 AND `comment_author` = %s AND `comment_author_email` = %s AND `comment_approved` = '0' ORDER BY `comment_date_gmt` /* Highlander_Comments_Base::comments_array() */",
119 $post->ID,
120 wp_specialchars_decode( $commenter['comment_author'], ENT_QUOTES ),
121 $commenter['comment_author_email']
122 )
123 );
124
125 if ( ! $in_moderation_comments ) {
126 return $comments;
127 }
128
129 // @todo ZOMG this is a bad idea
130 $comments = array_merge( $comments, $in_moderation_comments );
131 usort( $comments, array( $this, 'sort_comments_by_comment_date_gmt' ) );
132
133 return $comments;
134 }
135
136 /**
137 * Comment sort comparator: comment_date_gmt
138 *
139 * @since JetpackComments (1.4)
140 * @param object $a
141 * @param object $b
142 * @return int
143 */
144 public function sort_comments_by_comment_date_gmt( $a, $b ) {
145 if ( $a->comment_date_gmt == $b->comment_date_gmt ) {
146 return 0;
147 }
148
149 return $a->comment_date_gmt < $b->comment_date_gmt ? -1 : 1;
150 }
151
152 /**
153 * Get the current commenter's information from their cookie
154 *
155 * @since JetpackComments (1.4)
156 * @return array Commenters information from cookie
157 */
158 protected function get_current_commenter() {
159 // Defaults
160 $user_id = 0;
161 $comment_author = '';
162 $comment_author_email = '';
163 $comment_author_url = '';
164
165 if ( isset( $_COOKIE[ 'comment_author_' . COOKIEHASH ] ) ) {
166 $comment_author = $_COOKIE[ 'comment_author_' . COOKIEHASH ];
167 }
168
169 if ( isset( $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] ) ) {
170 $comment_author_email = $_COOKIE[ 'comment_author_email_' . COOKIEHASH ];
171 }
172
173 if ( isset( $_COOKIE[ 'comment_author_url_' . COOKIEHASH ] ) ) {
174 $comment_author_url = $_COOKIE[ 'comment_author_url_' . COOKIEHASH ];
175 }
176
177 if ( is_user_logged_in() ) {
178 $user = wp_get_current_user();
179 $user_id = $user->ID;
180 }
181
182 return compact( 'comment_author', 'comment_author_email', 'comment_author_url', 'user_id' );
183 }
184
185 /**
186 * Allows a logged out user to leave a comment as a facebook or twitter credentialed user.
187 * Overrides WordPress' core comment_registration option to treat these commenters as "registered" (verified) users.
188 *
189 * @since JetpackComments (1.4)
190 * @return If no
191 */
192 function allow_logged_out_user_to_comment_as_external() {
193 if ( ! $this->is_highlander_comment_post( 'facebook', 'twitter', 'googleplus' ) ) {
194 return;
195 }
196
197 add_filter( 'pre_option_comment_registration', '__return_zero' );
198 }
199
200 /**
201 * Allow a logged in user to post as a guest, FB, or twitter credentialed request.
202 * Bypasses WordPress' core overrides that force a logged in user to comment as that user.
203 * Respects comment_registration option.
204 *
205 * @since JetpackComments (1.4)
206 * @param array $comment_data
207 * @return int
208 */
209 function allow_logged_in_user_to_comment_as_guest( $comment_data ) {
210 // Bail if user registration is allowed
211 if ( get_option( 'comment_registration' ) ) {
212 return $comment_data;
213 }
214
215 // Bail if user is not logged in or not a post request
216 if ( 'POST' != strtoupper( $_SERVER['REQUEST_METHOD'] ) || ! is_user_logged_in() ) {
217 return $comment_data;
218 }
219
220 // Bail if this is not a guest or external service credentialed request
221 if ( ! $this->is_highlander_comment_post( 'guest', 'facebook', 'twitter', 'googleplus' ) ) {
222 return $comment_data;
223 }
224
225 $user = wp_get_current_user();
226
227 foreach ( array(
228 'comment_author' => 'display_name',
229 'comment_author_email' => 'user_email',
230 'comment_author_url' => 'user_url',
231 ) as $comment_field => $user_field ) {
232 if ( $comment_data[ $comment_field ] != addslashes( $user->$user_field ) ) {
233 return $comment_data; // some other plugin already did something funky
234 }
235 }
236
237 if ( get_option( 'require_name_email' ) ) {
238 if ( 6 > strlen( $_POST['email'] ) || empty( $_POST['author'] ) ) {
239 wp_die( __( 'Error: please fill the required fields (name, email).', 'jetpack' ), 400 );
240 } elseif ( ! is_email( $_POST['email'] ) ) {
241 wp_die( __( 'Error: please enter a valid email address.', 'jetpack' ), 400 );
242 }
243 }
244
245 $author_change = false;
246 foreach ( array(
247 'comment_author' => 'author',
248 'comment_author_email' => 'email',
249 'comment_author_url' => 'url',
250 ) as $comment_field => $post_field ) {
251 if ( $comment_data[ $comment_field ] != $_POST[ $post_field ] && 'url' != $post_field ) {
252 $author_change = true;
253 }
254 $comment_data[ $comment_field ] = $_POST[ $post_field ];
255 }
256
257 // Mark as guest comment if name or email were changed
258 if ( $author_change ) {
259 $comment_data['user_id'] = $comment_data['user_ID'] = 0;
260 }
261
262 return $comment_data;
263 }
264
265 /**
266 * Set the comment cookies or bail if comment is invalid
267 *
268 * @since JetpackComments (1.4)
269 * @param type $comment_id
270 * @return If comment is invalid
271 */
272 public function set_comment_cookies( $comment_id ) {
273 // Get comment and bail if it's invalid somehow
274 $comment = get_comment( $comment_id );
275 if ( empty( $comment ) || is_wp_error( $comment ) ) {
276 return;
277 }
278
279 $id_source = $this->is_highlander_comment_post();
280 if ( empty( $id_source ) ) {
281 return;
282 }
283
284 // Set comment author cookies
285 // phpcs:ignore WordPress.WP.CapitalPDangit
286 if ( ( 'wordpress' != $id_source ) && is_user_logged_in() ) {
287 /** This filter is already documented in core/wp-includes/comment-functions.php */
288 $comment_cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 );
289 setcookie( 'comment_author_' . COOKIEHASH, $comment->comment_author, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
290 setcookie( 'comment_author_email_' . COOKIEHASH, $comment->comment_author_email, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
291 setcookie( 'comment_author_url_' . COOKIEHASH, esc_url( $comment->comment_author_url ), time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
292 }
293 }
294
295 /**
296 * Get an avatar from Photon
297 *
298 * @since JetpackComments (1.4)
299 * @param string $url
300 * @param int $size
301 * @return string
302 */
303 protected function photon_avatar( $url, $size ) {
304 $size = (int) $size;
305
306 return jetpack_photon_url( $url, array( 'resize' => "$size,$size" ) );
307 }
308 }
309