PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.9.1
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.9.1
1.1.10 1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 All 34 releases
desktop-mode / includes / my-wordpress / comment-stats.php

comment-stats.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 0.9.1, at includes/my-wordpress/comment-stats.php

261 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Desktop Mode — My WordPress: per-comment dossier endpoint.
4 *
5 * `GET /desktop-mode/v1/comment-stats/<id>` returns the rendered
6 * comment + author + parent post + thread context + reply tree +
7 * a count of how active the author has been across the site. Powers
8 * the right preview pane in the My WordPress folder when a comment
9 * is selected.
10 *
11 * Permissions:
12 * - The comment must be readable by the current user (approved,
13 * OR the user can `moderate_comments`, OR they're the comment
14 * author).
15 * - Author email / IP / user-agent only ship to viewers with
16 * `moderate_comments`.
17 *
18 * @package WPDesktopMode
19 * @since 0.8.0
20 */
21
22 defined( 'ABSPATH' ) || exit;
23
24 /**
25 * Register the route.
26 *
27 * @since 0.8.0
28 */
29 function desktop_mode_my_wordpress_register_comment_stats_route() {
30 register_rest_route(
31 'desktop-mode/v1',
32 '/comment-stats/(?P<id>\d+)',
33 array(
34 'methods' => WP_REST_Server::READABLE,
35 'callback' => 'desktop_mode_my_wordpress_comment_stats_callback',
36 'permission_callback' => static function () {
37 return is_user_logged_in();
38 },
39 'args' => array(
40 'id' => array(
41 'required' => true,
42 'type' => 'integer',
43 'sanitize_callback' => 'absint',
44 ),
45 ),
46 )
47 );
48 }
49 add_action( 'rest_api_init', 'desktop_mode_my_wordpress_register_comment_stats_route' );
50
51 /**
52 * Aggregator callback.
53 *
54 * @since 0.8.0
55 *
56 * @param WP_REST_Request $request REST request.
57 * @return array|WP_Error
58 */
59 function desktop_mode_my_wordpress_comment_stats_callback( $request ) {
60 global $wpdb;
61 $comment_id = (int) $request->get_param( 'id' );
62 $comment = get_comment( $comment_id );
63 if ( ! $comment ) {
64 return new WP_Error(
65 'desktop_mode_comment_not_found',
66 __( 'Comment not found.', 'desktop-mode' ),
67 array( 'status' => 404 )
68 );
69 }
70
71 $can_moderate = current_user_can( 'moderate_comments' );
72 $is_approved = '1' === (string) $comment->comment_approved;
73 $is_self = is_user_logged_in()
74 && (int) get_current_user_id() === (int) $comment->user_id
75 && (int) $comment->user_id > 0;
76
77 if ( ! $is_approved && ! $can_moderate && ! $is_self ) {
78 return new WP_Error(
79 'desktop_mode_comment_forbidden',
80 __( 'You do not have permission to view this comment.', 'desktop-mode' ),
81 array( 'status' => 403 )
82 );
83 }
84
85 // ----- Comment body ------------------------------------------------
86 $content_filtered = apply_filters( 'comment_text', $comment->comment_content, $comment, array() );
87 $body = array(
88 'id' => (int) $comment->comment_ID,
89 'parent' => (int) $comment->comment_parent,
90 'date' => mysql2date( 'c', $comment->comment_date_gmt, false ),
91 'status' => $is_approved
92 ? 'approved'
93 : ( '0' === (string) $comment->comment_approved
94 ? 'pending'
95 : (string) $comment->comment_approved ),
96 'rendered' => (string) $content_filtered,
97 'rendered_raw' => (string) $comment->comment_content,
98 'editLink' => $can_moderate
99 ? esc_url_raw(
100 admin_url(
101 'comment.php?action=editcomment&c=' . $comment->comment_ID
102 )
103 )
104 : '',
105 );
106 if ( $can_moderate ) {
107 $body['type'] = (string) $comment->comment_type;
108 $body['ip'] = (string) $comment->comment_author_IP;
109 $body['userAgent'] = (string) $comment->comment_agent;
110 $body['karma'] = (int) $comment->comment_karma;
111 }
112
113 // ----- Author ------------------------------------------------------
114 $author = array(
115 'name' => (string) $comment->comment_author,
116 'url' => esc_url_raw( (string) $comment->comment_author_url ),
117 'avatarUrl' => (string) get_avatar_url(
118 $comment,
119 array( 'size' => 96 )
120 ),
121 'userId' => (int) $comment->user_id,
122 );
123 if ( $can_moderate ) {
124 $author['email'] = (string) $comment->comment_author_email;
125 }
126 if ( $author['userId'] > 0 ) {
127 $user = get_userdata( $author['userId'] );
128 if ( $user ) {
129 $author['displayName'] = $user->display_name;
130 $author['profileLink'] = get_author_posts_url( $user->ID );
131 }
132 }
133
134 // ----- Parent post -------------------------------------------------
135 $post = get_post( (int) $comment->comment_post_ID );
136 $post_payload = null;
137 if ( $post ) {
138 $post_author = $post->post_author > 0
139 ? get_userdata( (int) $post->post_author )
140 : null;
141 $post_payload = array(
142 'id' => (int) $post->ID,
143 'title' => get_the_title( $post ),
144 'link' => (string) get_permalink( $post ),
145 'editLink' => current_user_can( 'edit_post', $post->ID )
146 ? (string) get_edit_post_link( $post->ID, 'raw' )
147 : '',
148 'status' => (string) $post->post_status,
149 'type' => (string) $post->post_type,
150 'date' => mysql2date( 'c', $post->post_date_gmt, false ),
151 'author' => $post_author
152 ? array(
153 'id' => (int) $post_author->ID,
154 'name' => $post_author->display_name,
155 'avatarUrl' => (string) get_avatar_url(
156 $post_author->ID,
157 array( 'size' => 48 )
158 ),
159 )
160 : null,
161 );
162 }
163
164 // ----- Parent comment (if this is a reply) -------------------------
165 $parent_payload = null;
166 if ( (int) $comment->comment_parent > 0 ) {
167 $parent_comment = get_comment( (int) $comment->comment_parent );
168 if ( $parent_comment ) {
169 $parent_payload = array(
170 'id' => (int) $parent_comment->comment_ID,
171 'authorName' => (string) $parent_comment->comment_author,
172 'date' => mysql2date( 'c', $parent_comment->comment_date_gmt, false ),
173 'excerpt' => wp_trim_words(
174 wp_strip_all_tags( $parent_comment->comment_content ),
175 40
176 ),
177 );
178 }
179 }
180
181 // ----- Replies (direct children) -----------------------------------
182 $reply_rows = $wpdb->get_results(
183 $wpdb->prepare(
184 "SELECT comment_ID, comment_author, comment_author_email,
185 comment_date_gmt, comment_content, comment_approved, user_id
186 FROM {$wpdb->comments}
187 WHERE comment_parent = %d
188 AND ( comment_approved = '1' %s )
189 ORDER BY comment_date_gmt ASC
190 LIMIT 20",
191 $comment->comment_ID,
192 $can_moderate ? "OR comment_approved = '0'" : ''
193 ),
194 ARRAY_A
195 );
196 $replies = array();
197 foreach ( (array) $reply_rows as $row ) {
198 $replies[] = array(
199 'id' => (int) $row['comment_ID'],
200 'authorName' => (string) $row['comment_author'],
201 'avatarUrl' => (string) get_avatar_url(
202 $row['comment_author_email'],
203 array( 'size' => 32 )
204 ),
205 'date' => mysql2date( 'c', (string) $row['comment_date_gmt'], false ),
206 'excerpt' => wp_trim_words(
207 wp_strip_all_tags( (string) $row['comment_content'] ),
208 40
209 ),
210 'status' => '1' === (string) $row['comment_approved']
211 ? 'approved'
212 : (string) $row['comment_approved'],
213 );
214 }
215
216 // ----- Author activity --------------------------------------------
217 // "How busy is this commenter site-wide?" — total approved
218 // comments by this email (or user_id when logged in).
219 $author_total = 0;
220 if ( $author['userId'] > 0 ) {
221 $author_total = (int) $wpdb->get_var(
222 $wpdb->prepare(
223 "SELECT COUNT(*) FROM {$wpdb->comments}
224 WHERE user_id = %d AND comment_approved = '1'",
225 $author['userId']
226 )
227 );
228 } elseif ( ! empty( $comment->comment_author_email ) ) {
229 $author_total = (int) $wpdb->get_var(
230 $wpdb->prepare(
231 "SELECT COUNT(*) FROM {$wpdb->comments}
232 WHERE comment_author_email = %s AND comment_approved = '1'",
233 (string) $comment->comment_author_email
234 )
235 );
236 }
237 $author['totalApprovedComments'] = $author_total;
238
239 $payload = array(
240 'comment' => $body,
241 'author' => $author,
242 'post' => $post_payload,
243 'parent' => $parent_payload,
244 'replies' => $replies,
245 );
246
247 /**
248 * Filter the per-comment dossier payload.
249 *
250 * @since 0.8.0
251 *
252 * @param array $payload Stats payload.
253 * @param int $comment_id Comment id.
254 */
255 return apply_filters(
256 'desktop_mode_my_wordpress_comment_stats',
257 $payload,
258 $comment_id
259 );
260 }
261