Automattic /
jetpack
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 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 ) ); |
||
|
0 ignored issues
–
show
|
|||
| 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 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.