Plugin Directory

source: stream/tags/4.0.0/connectors/class-connector-comments.php

Last change on this file was 2976418, checked in by kasparsd, 9 months ago

Committing 3.10.0 to trunk

File size: 19.1 KB
Line 
1<?php
2/**
3 * Connector for Comments
4 *
5 * @package WP_Stream
6 */
7
8namespace WP_Stream;
9
10/**
11 * Class - Connector_Comments
12 */
13class Connector_Comments extends Connector {
14        /**
15         * Connector slug
16         *
17         * @var string
18         */
19        public $name = 'comments';
20
21        /**
22         * Actions registered for this connector
23         *
24         * @var array
25         */
26        public $actions = array(
27                'comment_flood_trigger',
28                'wp_insert_comment',
29                'edit_comment',
30                'before_delete_post',
31                'deleted_post',
32                'delete_comment',
33                'trash_comment',
34                'untrash_comment',
35                'spam_comment',
36                'unspam_comment',
37                'transition_comment_status',
38                'comment_duplicate_trigger',
39        );
40
41        /**
42         * Catch and store the post ID during post deletion
43         *
44         * @var int
45         */
46        protected $delete_post = 0;
47
48        /**
49         * Return translated connector label
50         *
51         * @return string Translated connector label
52         */
53        public function get_label() {
54                return esc_html__( 'Comments', 'stream' );
55        }
56
57        /**
58         * Return translated action labels
59         *
60         * @return array Action label translations
61         */
62        public function get_action_labels() {
63                return array(
64                        'created'    => esc_html__( 'Created', 'stream' ),
65                        'edited'     => esc_html__( 'Edited', 'stream' ),
66                        'replied'    => esc_html__( 'Replied', 'stream' ),
67                        'approved'   => esc_html__( 'Approved', 'stream' ),
68                        'unapproved' => esc_html__( 'Unapproved', 'stream' ),
69                        'trashed'    => esc_html__( 'Trashed', 'stream' ),
70                        'untrashed'  => esc_html__( 'Restored', 'stream' ),
71                        'spammed'    => esc_html__( 'Marked as Spam', 'stream' ),
72                        'unspammed'  => esc_html__( 'Unmarked as Spam', 'stream' ),
73                        'deleted'    => esc_html__( 'Deleted', 'stream' ),
74                        'duplicate'  => esc_html__( 'Duplicate', 'stream' ),
75                        'flood'      => esc_html__( 'Throttled', 'stream' ),
76                );
77        }
78
79        /**
80         * Return translated context labels
81         *
82         * @return array Context label translations
83         */
84        public function get_context_labels() {
85                return array(
86                        'comments' => esc_html__( 'Comments', 'stream' ),
87                );
88        }
89
90        /**
91         * Return translated comment type labels
92         *
93         * @return array Comment type label translations
94         */
95        public function get_comment_type_labels() {
96                return apply_filters(
97                        'wp_stream_comments_comment_type_labels',
98                        array(
99                                'comment'   => esc_html__( 'Comment', 'stream' ),
100                                'trackback' => esc_html__( 'Trackback', 'stream' ),
101                                'pingback'  => esc_html__( 'Pingback', 'stream' ),
102                        )
103                );
104        }
105
106        /**
107         * Return the comment type label for a given comment ID
108         *
109         * @param int $comment_id  ID of the comment.
110         *
111         * @return string The comment type label
112         */
113        public function get_comment_type_label( $comment_id ) {
114                $comment_type = get_comment_type( $comment_id );
115
116                if ( empty( $comment_type ) ) {
117                        $comment_type = 'comment';
118                }
119
120                $comment_type_labels = $this->get_comment_type_labels();
121
122                $label = isset( $comment_type_labels[ $comment_type ] ) ? $comment_type_labels[ $comment_type ] : $comment_type;
123
124                return $label;
125        }
126
127        /**
128         * Add action links to Stream drop row in admin list screen
129         *
130         * @filter wp_stream_action_links_{connector}
131         *
132         * @param array  $links   Previous links registered.
133         * @param object $record  Stream record.
134         *
135         * @return array Action links
136         */
137        public function action_links( $links, $record ) {
138                if ( $record->object_id ) {
139                        $comment = get_comment( $record->object_id );
140                        if ( $comment ) {
141                                $approve_nonce = wp_create_nonce( "approve-comment_$comment->comment_ID" );
142
143                                $links[ esc_html__( 'Edit', 'stream' ) ] = admin_url( "comment.php?action=editcomment&c=$comment->comment_ID" );
144
145                                if ( 1 === $comment->comment_approved ) {
146                                        $links[ esc_html__( 'Unapprove', 'stream' ) ] = admin_url(
147                                                sprintf(
148                                                        'comment.php?action=unapprovecomment&c=%s&_wpnonce=%s',
149                                                        $record->object_id,
150                                                        $approve_nonce
151                                                )
152                                        );
153                                } elseif ( empty( $comment->comment_approved ) ) {
154                                        $links[ esc_html__( 'Approve', 'stream' ) ] = admin_url(
155                                                sprintf(
156                                                        'comment.php?action=approvecomment&c=%s&_wpnonce=%s',
157                                                        $record->object_id,
158                                                        $approve_nonce
159                                                )
160                                        );
161                                }
162                        }
163                }
164
165                return $links;
166        }
167
168        /**
169         * Fetches the comment author and returns the specified field.
170         *
171         * This also takes into consideration whether or not the blog requires only
172         * name and e-mail or that users be logged in to comment. In either case it
173         * will try to see if the e-mail provided does belong to a registered user.
174         *
175         * @param object|int $comment  A comment object or comment ID.
176         * @param string     $field    What field you want to return.
177         *
178         * @return int|string $output User ID or user display name
179         */
180        public function get_comment_author( $comment, $field = 'id' ) {
181                $comment = is_object( $comment ) ? $comment : get_comment( absint( $comment ) );
182
183                $req_name_email = get_option( 'require_name_email' );
184                $req_user_login = get_option( 'comment_registration' );
185
186                $user_id   = 0;
187                $user_name = esc_html__( 'Guest', 'stream' );
188
189                $output = '';
190
191                if ( $req_name_email && isset( $comment->comment_author_email ) && isset( $comment->comment_author ) ) {
192                        $user      = get_user_by( 'email', $comment->comment_author_email );
193                        $user_id   = isset( $user->ID ) ? $user->ID : 0;
194                        $user_name = isset( $user->display_name ) ? $user->display_name : $comment->comment_author;
195                }
196
197                if ( $req_user_login && isset( $comment->user_id ) ) {
198                        $user      = get_user_by( 'id', $comment->user_id );
199                        $user_id   = $user->ID;
200                        $user_name = $user->display_name;
201                }
202
203                if ( 'id' === $field ) {
204                        $output = $user_id;
205                } elseif ( 'name' === $field ) {
206                        $output = $user_name;
207                }
208
209                return $output;
210        }
211
212        /**
213         * Tracks comment flood blocks
214         *
215         * @action comment_flood_trigger
216         *
217         * @param string $time_lastcomment  Time of last comment before block.
218         * @param string $time_newcomment   Time of first comment after block.
219         */
220        public function callback_comment_flood_trigger( $time_lastcomment, $time_newcomment ) {
221                $options        = wp_stream_get_instance()->settings->options;
222                $flood_tracking = isset( $options['advanced_comment_flood_tracking'] ) ? $options['advanced_comment_flood_tracking'] : false;
223
224                if ( ! $flood_tracking ) {
225                        return;
226                }
227
228                $req_user_login = get_option( 'comment_registration' );
229
230                if ( $req_user_login ) {
231                        $user      = wp_get_current_user();
232                        $user_id   = $user->ID;
233                        $user_name = $user->display_name;
234                } else {
235                        $user_name = esc_html__( 'a logged out user', 'stream' );
236                }
237
238                $this->log(
239                        /* translators: %s: a username (e.g. "administrator") */
240                        __( 'Comment flooding by %s detected and prevented', 'stream' ),
241                        compact( 'user_name', 'user_id', 'time_lastcomment', 'time_newcomment' ),
242                        null,
243                        'comments',
244                        'flood'
245                );
246        }
247
248        /**
249         * Tracks comment creation
250         *
251         * @action wp_insert_comment
252         *
253         * @param int        $comment_id  Comment ID.
254         * @param WP_Comment $comment     Comment object.
255         */
256        public function callback_wp_insert_comment( $comment_id, $comment ) {
257                if ( in_array( $comment->comment_type, $this->get_ignored_comment_types(), true ) ) {
258                        return;
259                }
260
261                $user_id        = $this->get_comment_author( $comment, 'id' );
262                $user_name      = $this->get_comment_author( $comment, 'name' );
263                $post_id        = $comment->comment_post_ID;
264                $post_type      = get_post_type( $post_id );
265                $post           = get_post( $post_id );
266                $post_title     = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'stream' );
267                $comment_status = ( 1 === $comment->comment_approved ) ? esc_html__( 'approved automatically', 'stream' ) : esc_html__( 'pending approval', 'stream' );
268                $is_spam        = false;
269
270                // Auto-marked spam comments.
271                $options     = wp_stream_get_instance()->settings->options;
272                $ak_tracking = isset( $options['advanced_akismet_tracking'] ) ? $options['advanced_akismet_tracking'] : false;
273
274                if ( class_exists( 'Akismet' ) && $ak_tracking && \Akismet::matches_last_comment( $comment ) ) {
275                        $ak_last_comment = \Akismet::get_last_comment();
276                        if ( 'true' === $ak_last_comment['akismet_result'] ) {
277                                $is_spam        = true;
278                                $comment_status = esc_html__( 'automatically marked as spam by Akismet', 'stream' );
279                        }
280                }
281
282                $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
283
284                if ( $comment->comment_parent ) {
285                        $parent_user_name = get_comment_author( $comment->comment_parent );
286
287                        $this->log(
288                                /* translators: %1$s: a parent comment's author, %2$s: a comment author, %3$s: a post title, %4$s: a comment status, %5$s: a comment type */
289                                _x(
290                                        'Reply to %1$s\'s %5$s by %2$s on %3$s %4$s',
291                                        "1: Parent comment's author, 2: Comment author, 3: Post title, 4: Comment status, 5: Comment type",
292                                        'stream'
293                                ),
294                                compact( 'parent_user_name', 'user_name', 'post_title', 'comment_status', 'comment_type', 'post_id' ),
295                                $comment_id,
296                                $post_type,
297                                'replied',
298                                $user_id
299                        );
300                } else {
301                        $this->log(
302                                /* translators: %1$s: a comment author, %2$s: a post title, %3$s: a comment status, %4$s: and a comment type */
303                                _x(
304                                        'New %4$s by %1$s on %2$s %3$s',
305                                        '1: Comment author, 2: Post title 3: Comment status, 4: Comment type',
306                                        'stream'
307                                ),
308                                compact( 'user_name', 'post_title', 'comment_status', 'comment_type', 'post_id', 'is_spam' ),
309                                $comment_id,
310                                $post_type,
311                                $is_spam ? 'spammed' : 'created',
312                                $user_id
313                        );
314                }
315        }
316
317        /**
318         * Tracks comment updates
319         *
320         * @action edit_comment
321         *
322         * @param int $comment_id  Comment ID.
323         */
324        public function callback_edit_comment( $comment_id ) {
325                $comment = get_comment( $comment_id );
326
327                if ( in_array( $comment->comment_type, $this->get_ignored_comment_types(), true ) ) {
328                        return;
329                }
330
331                $user_id      = $this->get_comment_author( $comment, 'id' );
332                $user_name    = $this->get_comment_author( $comment, 'name' );
333                $post_id      = $comment->comment_post_ID;
334                $post_type    = get_post_type( $post_id );
335                $post         = get_post( $post_id );
336                $post_title   = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'stream' );
337                $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
338
339                $this->log(
340                        /* translators: %1$s: a comment author, %2$s: a post title, %3$s: a comment type */
341                        _x(
342                                '%1$s\'s %3$s on %2$s edited',
343                                '1: Comment author, 2: Post title, 3: Comment type',
344                                'stream'
345                        ),
346                        compact( 'user_name', 'post_title', 'comment_type', 'post_id', 'user_id' ),
347                        $comment_id,
348                        $post_type,
349                        'edited'
350                );
351        }
352
353        /**
354         * Catch the post ID during deletion
355         *
356         * @action before_delete_post
357         *
358         * @param int $post_id  Post ID.
359         */
360        public function callback_before_delete_post( $post_id ) {
361                if ( wp_is_post_revision( $post_id ) ) {
362                        return;
363                }
364
365                $this->delete_post = $post_id;
366        }
367
368        /**
369         * Reset the post ID after deletion
370         *
371         * @action deleted_post
372         *
373         * @param int $post_id  Post ID.
374         */
375        public function callback_deleted_post( $post_id ) {
376                if ( wp_is_post_revision( $post_id ) ) {
377                        return;
378                }
379
380                $this->delete_post = 0;
381        }
382
383        /**
384         * Tracks comment delete
385         *
386         * @action delete_comment
387         *
388         * @param int $comment_id  Comment ID.
389         */
390        public function callback_delete_comment( $comment_id ) {
391                $comment = get_comment( $comment_id );
392
393                if ( in_array( $comment->comment_type, $this->get_ignored_comment_types(), true ) ) {
394                        return;
395                }
396
397                $user_id      = $this->get_comment_author( $comment, 'id' );
398                $user_name    = $this->get_comment_author( $comment, 'name' );
399                $post_id      = absint( $comment->comment_post_ID );
400                $post_type    = get_post_type( $post_id );
401                $post         = get_post( $post_id );
402                $post_title   = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'stream' );
403                $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
404
405                if ( $this->delete_post === $post_id ) {
406                        return;
407                }
408
409                $this->log(
410                        /* translators: %1$s: a comment author, %2$s: a post title, %3$s: a comment type */
411                        _x(
412                                '%1$s\'s %3$s on %2$s deleted permanently',
413                                '1: Comment author, 2: Post title, 3: Comment type',
414                                'stream'
415                        ),
416                        compact( 'user_name', 'post_title', 'comment_type', 'post_id', 'user_id' ),
417                        $comment_id,
418                        $post_type,
419                        'deleted'
420                );
421        }
422
423        /**
424         * Tracks comment trashing
425         *
426         * @action trash_comment
427         *
428         * @param int $comment_id  Comment ID.
429         */
430        public function callback_trash_comment( $comment_id ) {
431                $comment = get_comment( $comment_id );
432
433                if ( in_array( $comment->comment_type, $this->get_ignored_comment_types(), true ) ) {
434                        return;
435                }
436
437                $user_id      = $this->get_comment_author( $comment, 'id' );
438                $user_name    = $this->get_comment_author( $comment, 'name' );
439                $post_id      = $comment->comment_post_ID;
440                $post_type    = get_post_type( $post_id );
441                $post         = get_post( $post_id );
442                $post_title   = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'stream' );
443                $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
444
445                $this->log(
446                        /* translators: %1$s: a comment author, %2$s a post title, %3$s a comment type */
447                        _x(
448                                '%1$s\'s %3$s on %2$s trashed',
449                                '1: Comment author, 2: Post title, 3: Comment type',
450                                'stream'
451                        ),
452                        compact( 'user_name', 'post_title', 'comment_type', 'post_id', 'user_id' ),
453                        $comment_id,
454                        $post_type,
455                        'trashed'
456                );
457        }
458
459        /**
460         * Tracks comment trashing
461         *
462         * @action untrash_comment
463         *
464         * @param int $comment_id  Comment ID.
465         */
466        public function callback_untrash_comment( $comment_id ) {
467                $comment = get_comment( $comment_id );
468
469                if ( in_array( $comment->comment_type, $this->get_ignored_comment_types(), true ) ) {
470                        return;
471                }
472
473                $user_id      = $this->get_comment_author( $comment, 'id' );
474                $user_name    = $this->get_comment_author( $comment, 'name' );
475                $post_id      = $comment->comment_post_ID;
476                $post_type    = get_post_type( $post_id );
477                $post         = get_post( $post_id );
478                $post_title   = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'stream' );
479                $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
480
481                $this->log(
482                        /* translators: %1$s: a comment author, %2$s: a post title, %3$s: a comment type */
483                        _x(
484                                '%1$s\'s %3$s on %2$s restored',
485                                '1: Comment author, 2: Post title, 3: Comment type',
486                                'stream'
487                        ),
488                        compact( 'user_name', 'post_title', 'comment_type', 'post_id', 'user_id' ),
489                        $comment_id,
490                        $post_type,
491                        'untrashed'
492                );
493        }
494
495        /**
496         * Tracks comment marking as spam
497         *
498         * @action spam_comment
499         *
500         * @param int $comment_id  Comment ID.
501         */
502        public function callback_spam_comment( $comment_id ) {
503                $comment = get_comment( $comment_id );
504
505                if ( in_array( $comment->comment_type, $this->get_ignored_comment_types(), true ) ) {
506                        return;
507                }
508
509                $user_id      = $this->get_comment_author( $comment, 'id' );
510                $user_name    = $this->get_comment_author( $comment, 'name' );
511                $post_id      = $comment->comment_post_ID;
512                $post_type    = get_post_type( $post_id );
513                $post         = get_post( $post_id );
514                $post_title   = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'stream' );
515                $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
516
517                $this->log(
518                        /* translators: %1$s: a comment author, %2$s: a post title, %3$s: a comment type */
519                        _x(
520                                '%1$s\'s %3$s on %2$s marked as spam',
521                                '1: Comment author, 2: Post title, 3: Comment type',
522                                'stream'
523                        ),
524                        compact( 'user_name', 'post_title', 'comment_type', 'post_id', 'user_id' ),
525                        $comment_id,
526                        $post_type,
527                        'spammed'
528                );
529        }
530
531        /**
532         * Tracks comment unmarking as spam
533         *
534         * @action unspam_comment
535         *
536         * @param int $comment_id  Comment ID.
537         */
538        public function callback_unspam_comment( $comment_id ) {
539                $comment = get_comment( $comment_id );
540
541                if ( in_array( $comment->comment_type, $this->get_ignored_comment_types(), true ) ) {
542                        return;
543                }
544
545                $user_id      = $this->get_comment_author( $comment, 'id' );
546                $user_name    = $this->get_comment_author( $comment, 'name' );
547                $post_id      = $comment->comment_post_ID;
548                $post_type    = get_post_type( $post_id );
549                $post         = get_post( $post_id );
550                $post_title   = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'stream' );
551                $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
552
553                $this->log(
554                        /* translators: %1$s: a comment author, %2$s: a post title, %3$s: a comment type */
555                        _x(
556                                '%1$s\'s %3$s on %2$s unmarked as spam',
557                                '1: Comment author, 2: Post title, 3: Comment type',
558                                'stream'
559                        ),
560                        compact( 'user_name', 'post_title', 'comment_type', 'post_id', 'user_id' ),
561                        $comment_id,
562                        $post_type,
563                        'unspammed'
564                );
565        }
566
567        /**
568         * Track comment status transition
569         *
570         * @action transition_comment_status
571         *
572         * @param string     $new_status  New comment status.
573         * @param string     $old_status  Old comment status.
574         * @param WP_Comment $comment     Comment object.
575         */
576        public function callback_transition_comment_status( $new_status, $old_status, $comment ) {
577                if ( in_array( $comment->comment_type, $this->get_ignored_comment_types(), true ) ) {
578                        return;
579                }
580
581                if ( 'approved' !== $new_status && 'unapproved' !== $new_status || 'trash' === $old_status || 'spam' === $old_status ) {
582                        return;
583                }
584
585                $user_id      = $this->get_comment_author( $comment, 'id' );
586                $user_name    = $this->get_comment_author( $comment, 'name' );
587                $post_id      = $comment->comment_post_ID;
588                $post_type    = get_post_type( $post_id );
589                $post         = get_post( $post_id );
590                $post_title   = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'stream' );
591                $comment_type = get_comment_type( $comment->comment_ID );
592
593                $this->log(
594                        /* translators: %1$s: comment author, %2$s: comment status, %3$s: comment type, %4$s: old comment status, %5$s: post title */
595                        _x(
596                                '%1$s\'s %3$s on "%5$s" %2$s',
597                                'Comment status transition. 1: Comment author, 2: New status, 3: Comment type, 4. Old status, 5. Post title',
598                                'stream'
599                        ),
600                        compact( 'user_name', 'new_status', 'comment_type', 'old_status', 'post_title', 'post_id', 'user_id' ),
601                        $comment->comment_ID,
602                        $post_type,
603                        $new_status
604                );
605        }
606
607        /**
608         * Track attempts to add duplicate comments
609         *
610         * @action comment_duplicate_trigger
611         *
612         * @param array $comment_data  Comment data.
613         */
614        public function callback_comment_duplicate_trigger( $comment_data ) {
615                global $wpdb;
616                if ( ! empty( $wpdb->last_result ) ) {
617                        return;
618                }
619
620                $comment_id = $wpdb->last_result[0]->comment_ID;
621                $comment    = get_comment( $comment_id );
622
623                if ( in_array( $comment->comment_type, $this->get_ignored_comment_types(), true ) ) {
624                        return;
625                }
626
627                $user_id      = $this->get_comment_author( $comment, 'id' );
628                $user_name    = $this->get_comment_author( $comment, 'name' );
629                $post_id      = $comment->comment_post_ID;
630                $post_type    = get_post_type( $post_id );
631                $post         = get_post( $post_id );
632                $post_title   = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'stream' );
633                $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
634
635                $this->log(
636                        /* translators: %1$s: a comment author, %2$s: a post title, %3$s: a comment type */
637                        _x(
638                                'Duplicate %3$s by %1$s prevented on %2$s',
639                                '1: Comment author, 2: Post title, 3: Comment type',
640                                'stream'
641                        ),
642                        compact( 'user_name', 'post_title', 'comment_type', 'post_id', 'user_id' ),
643                        $comment_id,
644                        $post_type,
645                        'duplicate'
646                );
647        }
648
649        /**
650         * Constructs list of ignored comment types for the comments connector
651         *
652         * @return  array  List of ignored comment types
653         */
654        public function get_ignored_comment_types() {
655                return apply_filters(
656                        'wp_stream_comments_exclude_comment_types',
657                        array()
658                );
659        }
660}
Note: See TracBrowser for help on using the repository browser.