PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 6.4
Jetpack – WP Security, Backup, Speed, & Growth v6.4
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 14.4.2 All 500 releases
jetpack / modules / comments / base.php
base.php
295 lines 9.0 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' ) );
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 if ( !$commenter['comment_author'] )
112 return $comments;
113
114 $in_moderation_comments = $wpdb->get_results( $wpdb->prepare(
115 "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() */",
116 $post->ID,
117 wp_specialchars_decode( $commenter['comment_author'], ENT_QUOTES ),
118 $commenter['comment_author_email']
119 ) );
120
121 if ( !$in_moderation_comments )
122 return $comments;
123
124 // @todo ZOMG this is a bad idea
125 $comments = array_merge( $comments, $in_moderation_comments );
126 usort( $comments, array( $this, 'sort_comments_by_comment_date_gmt' ) );
127
128 return $comments;
129 }
130
131 /**
132 * Comment sort comparator: comment_date_gmt
133 *
134 * @since JetpackComments (1.4)
135 * @param object $a
136 * @param object $b
137 * @return int
138 */
139 public function sort_comments_by_comment_date_gmt( $a, $b ) {
140 if ( $a->comment_date_gmt == $b->comment_date_gmt ) {
141 return 0;
142 }
143
144 return $a->comment_date_gmt < $b->comment_date_gmt ? -1 : 1;
145 }
146
147 /**
148 * Get the current commenter's information from their cookie
149 *
150 * @since JetpackComments (1.4)
151 * @return array Commenters information from cookie
152 */
153 protected function get_current_commenter() {
154 // Defaults
155 $user_id = 0;
156 $comment_author = '';
157 $comment_author_email = '';
158 $comment_author_url = '';
159
160 if ( isset( $_COOKIE['comment_author_' . COOKIEHASH] ) ) {
161 $comment_author = $_COOKIE['comment_author_' . COOKIEHASH];
162 }
163
164 if ( isset( $_COOKIE['comment_author_email_' . COOKIEHASH] ) ) {
165 $comment_author_email = $_COOKIE['comment_author_email_' . COOKIEHASH];
166 }
167
168 if ( isset( $_COOKIE['comment_author_url_' . COOKIEHASH] ) ) {
169 $comment_author_url = $_COOKIE['comment_author_url_' . COOKIEHASH];
170 }
171
172 if ( is_user_logged_in() ) {
173 $user = wp_get_current_user();
174 $user_id = $user->ID;
175 }
176
177 return compact( 'comment_author', 'comment_author_email', 'comment_author_url', 'user_id' );
178 }
179
180 /**
181 * Allows a logged out user to leave a comment as a facebook or twitter credentialed user.
182 * Overrides WordPress' core comment_registration option to treat these commenters as "registered" (verified) users.
183 *
184 * @since JetpackComments (1.4)
185 * @return If no
186 */
187 function allow_logged_out_user_to_comment_as_external() {
188 if ( !$this->is_highlander_comment_post( 'facebook', 'twitter', 'googleplus' ) ) {
189 return;
190 }
191
192 add_filter( 'pre_option_comment_registration', '__return_zero' );
193 }
194
195 /**
196 * Allow a logged in user to post as a guest, FB, or twitter credentialed request.
197 * Bypasses WordPress' core overrides that force a logged in user to comment as that user.
198 * Respects comment_registration option.
199 *
200 * @since JetpackComments (1.4)
201 * @param array $comment_data
202 * @return int
203 */
204 function allow_logged_in_user_to_comment_as_guest( $comment_data ) {
205 // Bail if user registration is allowed
206 if ( get_option( 'comment_registration' ) ) {
207 return $comment_data;
208 }
209
210 // Bail if user is not logged in or not a post request
211 if ( 'POST' != strtoupper( $_SERVER['REQUEST_METHOD'] ) || !is_user_logged_in() ) {
212 return $comment_data;
213 }
214
215 // Bail if this is not a guest or external service credentialed request
216 if ( !$this->is_highlander_comment_post( 'guest', 'facebook', 'twitter', 'googleplus' ) ) {
217 return $comment_data;
218 }
219
220 $user = wp_get_current_user();
221
222 foreach ( array( 'comment_author' => 'display_name', 'comment_author_email' => 'user_email', 'comment_author_url' => 'user_url' ) as $comment_field => $user_field ) {
223 if ( $comment_data[$comment_field] != addslashes( $user->$user_field ) ) {
224 return $comment_data; // some other plugin already did something funky
225 }
226 }
227
228 if ( get_option( 'require_name_email' ) ) {
229 if ( 6 > strlen( $_POST['email'] ) || empty( $_POST['author'] ) ) {
230 wp_die( __( 'Error: please fill the required fields (name, email).', 'jetpack' ) );
231 } elseif ( ! is_email( $_POST['email'] ) ) {
232 wp_die( __( 'Error: please enter a valid email address.', 'jetpack' ) );
233 }
234 }
235
236 $author_change = false;
237 foreach ( array( 'comment_author' => 'author', 'comment_author_email' => 'email', 'comment_author_url' => 'url' ) as $comment_field => $post_field ) {
238 if ( $comment_data[$comment_field] != $_POST[$post_field] && 'url' != $post_field ) {
239 $author_change = true;
240 }
241 $comment_data[$comment_field] = $_POST[$post_field];
242 }
243
244 // Mark as guest comment if name or email were changed
245 if ( $author_change ) {
246 $comment_data['user_id'] = $comment_data['user_ID'] = 0;
247 }
248
249 return $comment_data;
250 }
251
252 /**
253 * Set the comment cookies or bail if comment is invalid
254 *
255 * @since JetpackComments (1.4)
256 * @param type $comment_id
257 * @return If comment is invalid
258 */
259 public function set_comment_cookies( $comment_id ) {
260 // Get comment and bail if it's invalid somehow
261 $comment = get_comment( $comment_id );
262 if ( empty( $comment ) || is_wp_error( $comment ) ) {
263 return;
264 }
265
266 $id_source = $this->is_highlander_comment_post();
267 if ( empty( $id_source ) ) {
268 return;
269 }
270
271 // Set comment author cookies
272 if ( ( 'wordpress' != $id_source ) && is_user_logged_in() ) {
273 /** This filter is already documented in core/wp-includes/comment-functions.php */
274 $comment_cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 );
275 setcookie( 'comment_author_' . COOKIEHASH, $comment->comment_author, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
276 setcookie( 'comment_author_email_' . COOKIEHASH, $comment->comment_author_email, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
277 setcookie( 'comment_author_url_' . COOKIEHASH, esc_url($comment->comment_author_url), time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
278 }
279 }
280
281 /**
282 * Get an avatar from Photon
283 *
284 * @since JetpackComments (1.4)
285 * @param string $url
286 * @param int $size
287 * @return string
288 */
289 protected function photon_avatar( $url, $size ) {
290 $size = (int) $size;
291
292 return jetpack_photon_url( $url, array( 'resize' => "$size,$size" ) );
293 }
294 }
295