LLMS_Comments
Custom filters & actions for LifterLMS comments.
Description Description
This class owes a great debt to WooCommerce.
Source Source
File: includes/class.llms.comments.php
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | class LLMS_Comments { /** * Transient key where calculated comment stats are stored. * * @var string */ protected static $count_transient_key = 'llms_count_comments' ; /** * Constructor. * * @since 3.37.12 * @since 6.6.0 Conditionally hook `wp_count_comments` filter. * * @return void */ public function __construct() { // Secure order notes. add_filter( 'comments_clauses' , array ( __CLASS__ , 'exclude_order_comments' ), 10, 1 ); add_action( 'comment_feed_join' , array ( __CLASS__ , 'exclude_order_comments_from_feed_join' ) ); add_action( 'comment_feed_where' , array ( __CLASS__ , 'exclude_order_comments_from_feed_where' ) ); // Delete comments count cache whenever there is a new comment or a comment status changes. add_action( 'wp_insert_comment' , array ( __CLASS__ , 'delete_comments_count_cache' ) ); add_action( 'wp_set_comment_status' , array ( __CLASS__ , 'delete_comments_count_cache' ) ); /** * Remove order notes when counting comments on WP versions earlier than 6.0. * * @todo This filter can be safely deprecated once support is dropped for WordPress 6.0. */ if ( self::should_modify_comment_counts() ) { add_filter( 'wp_count_comments' , array ( __CLASS__ , 'wp_count_comments' ), 999, 2 ); } } /** * Delete transient data when inserting new comments or updating comment status * * Next time wp_count_comments is called it'll be automatically regenerated * * @since 3.0.0 * @since 3.37.12 Use class variable to access the transient key name. * * @return void */ public static function delete_comments_count_cache() { delete_transient( self:: $count_transient_key ); } /** * Exclude order comments from queries and RSS. * * @since 3.0.0 * @since 3.37.12 Use strict comparison for `in_array()`. * * @param array $clauses Array of SQL clauses. * @return array */ public static function exclude_order_comments( $clauses ) { global $wpdb , $typenow ; // Allow queries when in the admin. if ( is_admin() && in_array( $typenow , array ( 'llms_order' ), true ) && current_user_can( apply_filters( 'lifterlms_admin_order_access' , 'manage_options' ) ) ) { return $clauses ; } if ( ! $clauses [ 'join' ] ) { $clauses [ 'join' ] = '' ; } if ( ! strstr ( $clauses [ 'join' ], "JOIN $wpdb->posts" ) ) { $clauses [ 'join' ] .= " LEFT JOIN $wpdb->posts ON comment_post_ID = $wpdb->posts.ID " ; } if ( $clauses [ 'where' ] ) { $clauses [ 'where' ] .= ' AND ' ; } $clauses [ 'where' ] .= " $wpdb->posts.post_type NOT IN ('" . implode( "','" , array ( 'llms_order ' ) ) . "' ) "; return $clauses ; } /** * Exclude order comments from queries and RSS. * * @since 3.0.0 * * @param string $join SQL join clause. * @return string */ public static function exclude_order_comments_from_feed_join( $join ) { global $wpdb ; if ( ! strstr ( $join , $wpdb ->posts ) ) { $join = " LEFT JOIN $wpdb->posts ON $wpdb->comments.comment_post_ID = $wpdb->posts.ID " ; } return $join ; } /** * Exclude order comments from queries and RSS. * * @since 3.0.0 * * @param string $where SQL where clause. * @return string */ public static function exclude_order_comments_from_feed_where( $where ) { global $wpdb ; if ( $where ) { $where .= ' AND ' ; } $where .= " $wpdb->posts.post_type NOT IN ('" . implode( "','" , array ( 'llms_order ' ) ) . "' ) "; return $where ; } /** * Retrieve an array mapping database values to their human-readable meanings * * The array key is the value stored in the $wpdb->comments table for the `comment_approved` column. * * The array values are the equivalent value as expected by the return of the `wp_count_comments()` function. * * @since 3.37.12 * * @return array */ protected static function get_approved_map() { return array ( '0' => 'moderated' , '1' => 'approved' , 'spam' => 'spam' , 'trash' => 'trash' , 'post-trashed' => 'post-trashed' , ); } /** * Retrieve order note comment counts. * * @since 3.37.12 * * @return array[] */ protected static function get_note_counts() { global $wpdb ; return $wpdb ->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching " SELECT comment_approved, COUNT ( * ) AS num_comments FROM { $wpdb ->comments} WHERE comment_type = 'llms_order_note' GROUP BY comment_approved; ", ARRAY_A ); } /** * Remove order notes from an existing comment count stats object. * * This method accepts a stats object, generated by another plugin (like WooCommerce) or using core information * from `get_comment_counts()` and then subtracts LifterLMS order note comments from the existing comment counts * which would have included order notes in the counts. * * @since 3.37.12 * * @todo This method can be safely deprecated once support is dropped for WordPress 6.0. * * @param stdClass $stats Comment stats object. See the return of LLMS_Comments::wp_comment_counts() for object details. * @return stdClass See LLMS_Comments::wp_comment_counts() for return object details. */ protected static function modify_comment_stats( $stats ) { $counts = self::get_note_counts(); $map = self::get_approved_map(); foreach ( ( array ) $counts as $row ) { if ( ! in_array( $row [ 'comment_approved' ], array ( 'post-trashed' , 'trash' , 'spam' ), true ) ) { $stats ->all -= $row [ 'num_comments' ]; $stats ->total_comments -= $row [ 'num_comments' ]; } if ( isset( $map [ $row [ 'comment_approved' ] ] ) ) { $var = $map [ $row [ 'comment_approved' ] ]; $stats -> $var -= $row [ 'num_comments' ]; } } set_transient( self:: $count_transient_key , $stats ); return $stats ; } /** * Determines whether or not comment count modification is necessary. * * Since WordPress 6.0 the `get_comment_count()` function utilizes `get_comments()` whereas in earlier versions the counts * are retrieved by a direct SQL query. This change means that the filter in this class on `comments_clauses` ensures that * our comments we hide & don't count in the comments management UI are already excluded and we do not need to filter * `wp_count_comments` to subtract our comments. * * @since 6.6.0 * * @return boolean Returns `true` on WP earlier than 6.0 and `false` on 6.0 and later. */ private static function should_modify_comment_counts() { global $wp_version ; return version_compare( $wp_version , '6.0-src' , '<' ); } /** * Remove order notes from the count when counting comments * * This method is hooked to `wp_count_comments`, called by `wp_count_comments()`. * * It handles two potential scenarios: * * 1) No other plugins have run the filter and the incoming $stats is an empty array. * In this scenario we'll utilize `get_comment_count()` to create a new $stats object * * 2) Another plugin has already generated a stats object and then incoming $stats is a stdClass. * * In either scenario we query the number of order notes and subtract this number from the existing * comment counts. * * @since 3.0.0 * @since 3.37.12 Use strict comparisons. * Fix issue encountered when $stats is an empty array. * Modify the stats generation method. * @since 6.6.0 Will throw `_doing_it_wrong()` when run on WP 6.0 or later and return the input `$stats` unchanged. * * @todo This method can be safely deprecated once support is dropped for WordPress 6.0. * * @param stdClass|array $stats Empty array or a stdClass of stats from another plugin. * @param int $post_id WP Post ID. `0` indicates comment stats for the entire site. * @return stdClass { * The number of comments keyed by their status. * * @type int $approved The number of approved comments. * @type int $moderated The number of comments awaiting moderation (a.k.a. pending). * @type int $spam The number of spam comments. * @type int $trash The number of trashed comments. * @type int $post-trashed The number of comments for posts that are in the trash. * @type int $total_comments The total number of non-trashed comments, including spam. * @type int $all The total number of pending or approved comments. * } */ public static function wp_count_comments( $stats , $post_id ) { // If someone calls this directly on 6.0 or later notify them and return early. if ( ! self::should_modify_comment_counts() ) { _doing_it_wrong( __METHOD__ , 'This method should not be called on WordPress 6.0 or later.' , '6.6.0' ); return $stats ; } // Don't modify when querying for a specific post. if ( 0 !== $post_id ) { return $stats ; } // Return cached object if available. $cached = get_transient( self:: $count_transient_key ); if ( $cached ) { return $cached ; } // If $stats is empty, get a new object from the WP Core that we can modify. if ( empty ( $stats ) ) { $stats = get_comment_count( $post_id ); // The keys in wp_count_comments() and get_comment_counts() don't match. $stats [ 'moderated' ] = $stats [ 'awaiting_moderation' ]; unset( $stats [ 'awaiting_moderation' ] ); // Cast to an object. $stats = (object) $stats ; } // Otherwise modify the existing stats object. return self::modify_comment_stats( $stats ); } } |
Expand full source code Collapse full source code View on GitHub
Methods Methods
- __construct — Constructor.
- delete_comments_count_cache — Delete transient data when inserting new comments or updating comment status
- exclude_order_comments — Exclude order comments from queries and RSS.
- exclude_order_comments_from_feed_join — Exclude order comments from queries and RSS.
- exclude_order_comments_from_feed_where — Exclude order comments from queries and RSS.
- get_approved_map — Retrieve an array mapping database values to their human-readable meanings
- get_note_counts — Retrieve order note comment counts.
- modify_comment_stats — Remove order notes from an existing comment count stats object.
- should_modify_comment_counts — Determines whether or not comment count modification is necessary.
- wp_count_comments — Remove order notes from the count when counting comments
Changelog Changelog
Version | Description |
---|---|
3.0.0 | Introduced. |