1<?php
2/**
3 * WordPress Comment Administration API.
4 *
5 * @package WordPress
6 * @subpackage Administration
7 * @since 2.3.0
8 */
9
10/**
11 * Determines if a comment exists based on author and date.
12 *
13 * For best performance, use `$timezone = 'gmt'`, which queries a field that is properly indexed. The default value
14 * for `$timezone` is 'blog' for legacy reasons.
15 *
16 * @since 2.0.0
17 * @since 4.4.0 Added the `$timezone` parameter.
18 *
19 * @global wpdb $wpdb WordPress database abstraction object.
20 *
21 * @param string $comment_author Author of the comment.
22 * @param string $comment_date Date of the comment.
23 * @param string $timezone Timezone. Accepts 'blog' or 'gmt'. Default 'blog'.
24 * @return string|null Comment post ID on success.
25 */
26function comment_exists( $comment_author, $comment_date, $timezone = 'blog' ) {
27 global $wpdb;
28
29 $date_field = 'comment_date';
30 if ( 'gmt' === $timezone ) {
31 $date_field = 'comment_date_gmt';
32 }
33
34 return $wpdb->get_var(
35 $wpdb->prepare(
36 "SELECT comment_post_ID FROM $wpdb->comments
37 WHERE comment_author = %s AND $date_field = %s",
38 stripslashes( $comment_author ),
39 stripslashes( $comment_date )
40 )
41 );
42}
43
44/**
45 * Updates a comment with values provided in $_POST.
46 *
47 * @since 2.0.0
48 * @since 5.5.0 A return value was added.
49 *
50 * @return int|WP_Error The value 1 if the comment was updated, 0 if not updated.
51 * A WP_Error object on failure.
52 */
53function edit_comment() {
54 if ( ! current_user_can( 'edit_comment', (int) $_POST['comment_ID'] ) ) {
55 wp_die( __( 'Sorry, you are not allowed to edit comments on this post.' ) );
56 }
57
58 if ( isset( $_POST['newcomment_author'] ) ) {
59 $_POST['comment_author'] = $_POST['newcomment_author'];
60 }
61 if ( isset( $_POST['newcomment_author_email'] ) ) {
62 $_POST['comment_author_email'] = $_POST['newcomment_author_email'];
63 }
64 if ( isset( $_POST['newcomment_author_url'] ) ) {
65 $_POST['comment_author_url'] = $_POST['newcomment_author_url'];
66 }
67 if ( isset( $_POST['comment_status'] ) ) {
68 $_POST['comment_approved'] = $_POST['comment_status'];
69 }
70 if ( isset( $_POST['content'] ) ) {
71 $_POST['comment_content'] = $_POST['content'];
72 }
73 if ( isset( $_POST['comment_ID'] ) ) {
74 $_POST['comment_ID'] = (int) $_POST['comment_ID'];
75 }
76
77 foreach ( array( 'aa', 'mm', 'jj', 'hh', 'mn' ) as $timeunit ) {
78 if ( ! empty( $_POST[ 'hidden_' . $timeunit ] ) && $_POST[ 'hidden_' . $timeunit ] !== $_POST[ $timeunit ] ) {
79 $_POST['edit_date'] = '1';
80 break;
81 }
82 }
83
84 if ( ! empty( $_POST['edit_date'] ) ) {
85 $aa = $_POST['aa'];
86 $mm = $_POST['mm'];
87 $jj = $_POST['jj'];
88 $hh = $_POST['hh'];
89 $mn = $_POST['mn'];
90 $ss = $_POST['ss'];
91 $jj = ( $jj > 31 ) ? 31 : $jj;
92 $hh = ( $hh > 23 ) ? $hh - 24 : $hh;
93 $mn = ( $mn > 59 ) ? $mn - 60 : $mn;
94 $ss = ( $ss > 59 ) ? $ss - 60 : $ss;
95
96 $_POST['comment_date'] = "$aa-$mm-$jj $hh:$mn:$ss";
97 }
98
99 return wp_update_comment( $_POST, true );
100}
101
102/**
103 * Returns a WP_Comment object based on comment ID.
104 *
105 * @since 2.0.0
106 *
107 * @param int $id ID of comment to retrieve.
108 * @return WP_Comment|false Comment if found. False on failure.
109 */
110function get_comment_to_edit( $id ) {
111 $comment = get_comment( $id );
112 if ( ! $comment ) {
113 return false;
114 }
115
116 $comment->comment_ID = (int) $comment->comment_ID;
117 $comment->comment_post_ID = (int) $comment->comment_post_ID;
118
119 $comment->comment_content = format_to_edit( $comment->comment_content );
120 /**
121 * Filters the comment content before editing.
122 *
123 * @since 2.0.0
124 *
125 * @param string $comment_content Comment content.
126 */
127 $comment->comment_content = apply_filters( 'comment_edit_pre', $comment->comment_content );
128
129 $comment->comment_author = format_to_edit( $comment->comment_author );
130 $comment->comment_author_email = format_to_edit( $comment->comment_author_email );
131 $comment->comment_author_url = format_to_edit( $comment->comment_author_url );
132 $comment->comment_author_url = esc_url( $comment->comment_author_url );
133
134 return $comment;
135}
136
137/**
138 * Gets the number of pending comments on a post or posts.
139 *
140 * @since 2.3.0
141 * @since 6.9.0 Exclude the 'note' comment type from the count.
142 *
143 * @global wpdb $wpdb WordPress database abstraction object.
144 *
145 * @param int|int[] $post_id Either a single Post ID or an array of Post IDs
146 * @return int|int[] Either a single Posts pending comments as an int or an array of ints keyed on the Post IDs
147 */
148function get_pending_comments_num( $post_id ) {
149 global $wpdb;
150
151 $single = false;
152 if ( ! is_array( $post_id ) ) {
153 $post_id_array = (array) $post_id;
154 $single = true;
155 } else {
156 $post_id_array = $post_id;
157 }
158 $post_id_array = array_map( 'intval', $post_id_array );
159 $post_id_in = "'" . implode( "', '", $post_id_array ) . "'";
160
161 $pending = $wpdb->get_results( "SELECT comment_post_ID, COUNT(comment_ID) as num_comments FROM $wpdb->comments WHERE comment_post_ID IN ( $post_id_in ) AND comment_approved = '0' AND comment_type != 'note' GROUP BY comment_post_ID", ARRAY_A );
162
163 if ( $single ) {
164 if ( empty( $pending ) ) {
165 return 0;
166 } else {
167 return absint( $pending[0]['num_comments'] );
168 }
169 }
170
171 $pending_keyed = array();
172
173 // Default to zero pending for all posts in request.
174 foreach ( $post_id_array as $id ) {
175 $pending_keyed[ $id ] = 0;
176 }
177
178 if ( ! empty( $pending ) ) {
179 foreach ( $pending as $pend ) {
180 $pending_keyed[ $pend['comment_post_ID'] ] = absint( $pend['num_comments'] );
181 }
182 }
183
184 return $pending_keyed;
185}
186
187/**
188 * Adds avatars to relevant places in admin.
189 *
190 * @since 2.5.0
191 *
192 * @param string $name User name.
193 * @return string Avatar with the user name.
194 */
195function floated_admin_avatar( $name ) {
196 $avatar = get_avatar( get_comment(), 32, 'mystery' );
197 return "$avatar $name";
198}
199
200/**
201 * Enqueues comment shortcuts jQuery script.
202 *
203 * @since 2.7.0
204 */
205function enqueue_comment_hotkeys_js() {
206 if ( 'true' === get_user_option( 'comment_shortcuts' ) ) {
207 wp_enqueue_script( 'jquery-table-hotkeys' );
208 }
209}
210
211/**
212 * Displays error message at bottom of comments.
213 *
214 * @since 2.5.0
215 *
216 * @param string $msg Error Message. Assumed to contain HTML and be sanitized.
217 */
218function comment_footer_die( $msg ) {
219 echo "<div class='wrap'><p>$msg</p></div>";
220 require_once ABSPATH . 'wp-admin/admin-footer.php';
221 die;
222}
223