Making WordPress.org

source: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/tools/class-stats-report.php

Last change on this file was 11742, checked in by dd32, 6 weeks ago

Plugin Directory: Stats Report: Fix the stats page options, incorrect parameter name added in [11728].

See #4306.

  • Property svn:eol-style set to native
File size: 15.8 KB
Line 
1<?php
2namespace WordPressdotorg\Plugin_Directory\Admin\Tools;
3use WordPressdotorg\Plugin_Directory\Template;
4use WordPressdotorg\Plugin_Directory\Clients\HelpScout;
5
6/**
7 * All functionality related to Stats_Report Tool.
8 *
9 * @package WordPressdotorg\Plugin_Directory\Admin\Tools
10 */
11class Stats_Report {
12
13        /**
14         * Fetch the instance of the Stats_Report class.
15         */
16        public static function instance() {
17                static $instance = null;
18
19                return ! is_null( $instance ) ? $instance : $instance = new self();
20        }
21
22        /**
23         * Constructor.
24         */
25        private function __construct() {
26                add_action( 'admin_menu', array( $this, 'add_to_menu' ) );
27        }
28
29        /**
30         * Adds the "Stats Report" link to the admin menu under "Tools".
31         */
32        public function add_to_menu() {
33                add_submenu_page(
34                        'tools.php',
35                        __( 'Stats Report', 'wporg-plugins' ),
36                        __( 'Stats Report', 'wporg-plugins' ),
37                        'plugin_review',
38                        'statsreport',
39                        array( $this, 'show_stats' )
40                );
41        }
42
43        /**
44         * Returns the stats.
45         *
46         * @param array $args {
47         *    Optional. Array of override arguments
48         *
49         *     @type string $date       The date (in Y-m-d format) for the end of the stats time interval (non-inclusive). Default today.
50         *     @type int    $num_days   The number of days in the stats time interval that ends at $date. Default 7.
51         *     @type int    $recentdays The number of days back from today to be considered "recent". Default 7.
52         * }
53         * @return array {
54         *     Array of stats.
55         *
56         *     @type int $plugin_approve                        The number of plugins approved within the defined time interval.
57         *     @type int $plugin_delist                         The number of plugins delisted within the defined time interval.
58         *     @type int $plugin_new                            The number of plugins submitted within the defined time interval.
59         *     @type int $plugin_reject                         The number of plugins rejected within the defined time interval.
60         *     @type int $in_queue                              The number of plugins currently in the queue (new or pending).
61         *     @type int $in_queue_new                          The number of new plugins currently in the queue.
62         *     @type int $in_queue_pending                      The number of pending plugins currently in the queue.
63         *     @type int $in_queue_from_time_window             The number of plugins currently in the queue submitted during the specified time window.
64         *     @type int $in_queue_old                          The number of plugins currently in the queue that are older than "recently".
65         *     @type int $helpscout_queue_total_conversations   The number of ongoing Help Scout conversations.
66         *     @type int $helpscout_queue_new_conversations     The number of new Help Scout conversations.
67         *     @type int $helpscout_queue_customers             The number of unique Plugin authors contacted.
68         *     @type int $helpscout_queue_conversations_per_day The number of Help Scout conversations per day.
69         *     @type int $helpscout_queue_busiest_day           The busiest day in the Help Scout queue.
70         *     @type int $helpscout_queue_messages_received     The number of emails received in HelpScout.
71         *     @type int $helpscout_queue_replies_sent          The number of replies sent to emails.
72         *     @type int $helpscout_queue_emails_created        The number of new outgoing conversations created.
73         * }
74         */
75        public function get_stats( $args = array() ) {
76                global $wpdb;
77
78                $stats['as_of_date'] = gmdate( 'Y-m-d' );
79
80                $defaults = array(
81                        'date'       => $stats['as_of_date'],
82                        'num_days'   => 7,
83                        'recentdays' => 7,
84                );
85
86                foreach ( $defaults as $key => $val ) {
87                        $args[ $key ] = empty( $args[ $key ] ) ? $val : $args[ $key ];
88                }
89
90                $stats = $args;
91
92                // --------------
93                // Plugin Status Changes
94                // --------------
95                $stats[ 'plugin_approve' ] = (int) $wpdb->get_var( $wpdb->prepare(
96                        "SELECT COUNT(*) FROM $wpdb->postmeta WHERE meta_key = '_approved' AND meta_value >= %d AND meta_value < %d",
97                        strtotime( $args['date'] ) - ( $args['num_days'] * DAY_IN_SECONDS ),
98                        strtotime( $args['date'] ) + DAY_IN_SECONDS
99                ) );
100
101                $stats[ 'plugin_delist' ] = (int) $wpdb->get_var( $wpdb->prepare(
102                        "SELECT COUNT(*) FROM $wpdb->postmeta WHERE meta_key = 'plugin_closed_date' AND meta_value >= %s AND meta_value < %s",
103                        date( 'Y-m-d', strtotime( $args['date'] ) - ( $args['num_days'] * DAY_IN_SECONDS ) ),
104                        date( 'Y-m-d', strtotime( $args['date'] ) )
105                ) );
106
107                $stats[ 'plugin_delist_reasons' ] = array_column( $wpdb->get_results( $wpdb->prepare(
108                        "SELECT reason.meta_value as reason, COUNT(*) as count FROM $wpdb->postmeta closed_date JOIN $wpdb->postmeta reason ON closed_date.post_id = reason.post_id AND reason.meta_key = '_close_reason' WHERE closed_date.meta_key = 'plugin_closed_date' AND closed_date.meta_value >= %s AND closed_date.meta_value < %s GROUP BY reason.meta_value",
109                        date( 'Y-m-d', strtotime( $args['date'] ) - ( $args['num_days'] * DAY_IN_SECONDS ) ),
110                        date( 'Y-m-d', strtotime( $args['date'] ) )
111                ) ), 'count', 'reason' );
112
113                $stats[ 'plugin_new' ] = (int) $wpdb->get_var( $wpdb->prepare(
114                        "SELECT COUNT(*) FROM $wpdb->postmeta WHERE meta_key = '_submitted_date' AND meta_value >= %d AND meta_value < %d",
115                        strtotime( $args['date'] ) - ( $args['num_days'] * DAY_IN_SECONDS ),
116                        strtotime( $args['date'] ) + DAY_IN_SECONDS
117                ) );
118
119                $stats[ 'plugin_reject' ] = (int) $wpdb->get_var( $wpdb->prepare(
120                        "SELECT COUNT(*) FROM $wpdb->postmeta WHERE meta_key = '_rejected' AND meta_value >= %d AND meta_value < %d",
121                        strtotime( $args['date'] ) - ( $args['num_days'] * DAY_IN_SECONDS ),
122                        strtotime( $args['date'] ) + DAY_IN_SECONDS
123                ) );
124
125                // --------------
126                // Plugin Queue
127                // --------------
128                // # of plugins currently in the queue that are new (have not been processed/replied to yet)
129                $stats['in_queue_new'] = $wpdb->get_var(
130                        "SELECT COUNT(*) FROM $wpdb->posts WHERE `post_type` = 'plugin' AND `post_status` = 'new'"
131                );
132
133                // # of plugins currently in the queue that are pending (have been initially replied to)
134                $stats['in_queue_pending'] = $wpdb->get_var(
135                        "SELECT COUNT(*) FROM $wpdb->posts WHERE `post_type` = 'plugin' AND `post_status` = 'pending'"
136                );
137
138                // # of plugins currently in the queue (new + pending)
139                $stats['in_queue'] = $stats['in_queue_new'] + $stats['in_queue_pending'];
140
141                // # of plugins currently in the queue submitted during the specified time window
142                $stats['in_queue_from_time_window'] = $wpdb->get_var( $wpdb->prepare(
143                        "SELECT COUNT(*) FROM $wpdb->posts WHERE `post_type` = 'plugin' AND `post_status` IN ( 'new','pending' ) AND post_date < %s AND post_date > DATE_SUB( %s, INTERVAL %d DAY )",
144                        $args['date'],
145                        $args['date'],
146                        absint( $args['num_days'] ) + 1
147                ) );
148
149                // # of plugins currently in the queue that are older than "recently"
150                $stats['in_queue_old'] = $wpdb->get_var( $wpdb->prepare(
151                        "SELECT COUNT(*) FROM $wpdb->posts WHERE `post_type` = 'plugin' AND `post_status` IN ( 'new','pending' ) AND post_date < DATE_SUB( %s, INTERVAL %d DAY )",
152                        $args['date'],
153                        absint( $args['recentdays'] ) + 1
154                ) );
155
156                // --------------
157                // Help Scout Queue
158                // --------------
159
160                $start_datetime = gmdate( 'Y-m-d\T00:00:00\Z', strtotime( $args['date'] ) - ( $args['num_days'] * DAY_IN_SECONDS ) );
161                $end_datetime   = gmdate( 'Y-m-d\T23:59:59\Z', strtotime( $args['date'] ) );
162
163                $api_payload = [
164                        'start'     => $start_datetime,
165                        'end'       => $end_datetime,
166                        'mailboxes' => HELPSCOUT_PLUGINS_MAILBOXID,
167                ];
168               
169                $company_report  = HelpScout::api( '/v2/reports/company', $api_payload );
170                $mailbox_overall = HelpScout::api( '/v2/reports/conversations', $api_payload );
171                $email_report    = HelpScout::api( '/v2/reports/email', $api_payload );
172
173                // If any of the API's are unavailable, make it obvious that the requests have failed, but returning 0's for everything.
174                if ( ! $company_report || ! $mailbox_overall || ! $email_report ) {
175                        $company_report = $mailbox_overall = $email_report = false;
176                }
177
178                $stats['helpscout_queue_total_conversations']     = $mailbox_overall->current->totalConversations ?? 0;
179                $stats['helpscout_queue_new_conversations']       = $mailbox_overall->current->newConversations ?? 0;
180                $stats['helpscout_queue_customers']               = $mailbox_overall->current->customers ?? 0;
181                $stats['helpscout_queue_conversations_per_day']   = $mailbox_overall->current->conversationsPerDay ?? 0;
182                $stats['helpscout_queue_busiest_day']             = gmdate( 'l', strtotime( 'Sunday +' . ( $mailbox_overall->busiestDay->day ?? 0 ) . ' days' ) ); // Hacky? but works
183                $stats['helpscout_queue_messages_received']       = $mailbox_overall->current->messagesReceived ?? 0;
184                $stats['helpscout_queue_replies_sent']            = $company_report->current->totalReplies;
185                $stats['helpscout_queue_emails_created']          = $email_report->current->volume->emailsCreated ?? 0;
186
187                return $stats;
188        }
189
190        /**
191         * Outputs the stats report admin page, including form to customize time range
192         * and the stats themselves.
193         */
194        public function show_stats() {
195                if ( ! current_user_can( 'plugin_review' ) ) {
196                        return;
197                }
198
199                $args = array();
200
201                if ( isset( $_REQUEST['date'] ) && preg_match( '/[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/', $_REQUEST['date'] ) ) {
202                        $args['date'] = $_REQUEST['date'];
203                } else {
204                        $args['date'] = gmdate( 'Y-m-d' );
205                }
206
207                $args['num_days']   = empty( $_REQUEST['days'] ) ? 7 : absint( $_REQUEST['days'] );
208                $args['recentdays'] = empty( $_REQUEST['recentdays'] ) ? 7 : absint( $_REQUEST['recentdays'] );
209
210                $stats = $this->get_stats( $args );
211
212                $date = gmdate( 'Y-m-d' );
213
214                $start_date = gmdate( 'Y-m-d', strtotime( "-{$stats['num_days']} days", strtotime( $stats['date'] ) ) );
215                ?>
216
217                <div class="wrap stats-report">
218
219                <h1><?php _e( 'Plugin Repository and email Stats Report', 'wporg-plugins' ); ?></h1>
220
221                <form method="get">
222                <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>"/>
223                <table class="form-table"><tbody>
224                <tr><th scope="row"><label for="date"><?php _e( 'Date', 'wporg-plugins' ); ?></label></th><td>
225                <input name="date" type="text" id="date" value="<?php echo esc_attr( $args['date'] ); ?>" class="text">
226                <p>
227                <?php
228                        /* translators: %s: today's date */
229                        printf(
230                                __( 'The day up to which stats are to be gathered. In YYYY-MM-DD format. Defaults to today (%s).', 'wporg-plugins' ),
231                                esc_html( $date )
232                        );
233                ?>
234                </p>
235                </td></tr>
236
237                <tr><th scope="row"><label for="days"><?php _e( 'Number of days', 'wporg-plugins' ); ?></label></th><td>
238                <input name="days" type="text" id="days" value="<?php echo esc_attr( $args['num_days'] ); ?>" class="small-text">
239                <p>
240                <?php
241                        /* translators: %d: 7 */
242                        printf(
243                                __( 'The number of days before "Date" to include in stats. Default is %d.', 'wporg-plugins' ),
244                                7
245                        );
246                ?>
247                </p>
248                </td></tr>
249
250                <tr><th scope="row"><label for="recentdays"><?php _e( '"Recent" number of days', 'wporg-plugins' ); ?></label></th><td>
251                <input name="recentdays" type="text" id="recentdays" value="<?php echo esc_attr( $args['recentdays'] ); ?>" class="small-text">
252                <p>
253                <?php
254                        /* translators: %d: 7 */
255                        printf(
256                                __( 'The number of days before today to consider as being "recent" (stats marked with **). Default is %d.', 'wporg-plugins' ),
257                                7
258                        );
259                ?>
260                </p>
261                </td></tr>
262
263                </tbody></table>
264                <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_attr_e( 'Submit', 'wporg-plugins' ); ?>"></p>
265                </form>
266
267                <h2><?php _e( 'Stats', 'wporg-plugins' ); ?></h2>
268
269                <p>
270                <?php
271                        /* translators: 1: number of days, 2: selected date, 3: number of most recent days */
272                        printf(
273                                __( 'Displaying stats for the %1$d days preceding %2$s (and other stats for the %3$d most recent days).', 'wporg-plugins' ),
274                                esc_html( $stats['num_days'] ),
275                                esc_html( $stats['date'] ),
276                                esc_html( $stats['recentdays'] )
277                        );
278                ?>
279                </p>
280
281                <h3><?php _e( 'Plugin Status Change Stats', 'wporg-plugins' ); ?></h3>
282
283                <ul style="font-family:Courier New;">
284                        <li>
285                        <?php
286                                /* translators: %d: number of requested plugins */
287                                printf(
288                                        __( 'Plugins requested : %d', 'wporg-plugins' ),
289                                        esc_html( $stats['plugin_new'] )
290                                );
291                        ?>
292                        </li>
293                        <li>
294                        <?php
295                                /* translators: %s: number of rejected plugins */
296                                printf(
297                                        __( 'Plugins rejected : %s', 'wporg-plugins' ),
298                                        esc_html( $stats['plugin_reject'] )
299                                );
300                        ?>
301                        </li>
302                        <li>
303                        <?php
304                                /* translators: %s: number of closed plugins */
305                                printf(
306                                        __( 'Plugins closed : %s', 'wporg-plugins' ),
307                                        esc_html( $stats['plugin_delist'] )
308                                );
309                                $reasons = array();
310                                if ( $stats['plugin_delist_reasons'] ) {
311                                        echo '<ul>';
312                                        foreach ( $stats['plugin_delist_reasons'] as $reason => $number ) {
313                                                $reason = Template::get_close_reasons()[ $reason ];
314                                                echo "<li>&nbsp;&nbsp;{$reason}: {$number}</li>";
315                                        }
316                                        echo '</ul>';
317                                }
318                        ?>
319                        </li>
320                        <li>
321                        <?php
322                                /* translators: %s: number of approved plugins */
323                                printf(
324                                        __( 'Plugins approved : %s', 'wporg-plugins' ),
325                                        esc_html( $stats['plugin_approve'] )
326                                );
327                        ?>
328                        </li>
329                </ul>
330
331                <h3><?php _e( 'Plugin Queue Stats (current)', 'wporg-plugins' ); ?></h3>
332
333                <ul style="font-family:Courier New;">
334                        <li>
335                        <?php
336                                /* translators: %d: number of plugins in the queue */
337                                printf(
338                                        __( 'Plugins in the queue (new and pending)* : %d', 'wporg-plugins' ),
339                                        esc_html( $stats['in_queue'] )
340                                );
341                        ?>
342                        </li>
343                        <li>
344                        <?php
345                                /* translators: 1: number of most recent days, 2: number of older plugins in the queue */
346                                printf(
347                                        __( '&rarr; (older than %1$d days ago)** : %2$d', 'wporg-plugins' ),
348                                        esc_html( $stats['recentdays'] ),
349                                        esc_html( $stats['in_queue_old'] )
350                                );
351                        ?>
352                        </li>
353                        <li>
354                        <?php
355                                /* translators: 1: start date, 2: end date, 3: number of plugins in the queue within defined time window */
356                                printf(
357                                        __( '&rarr; (%1$s - %2$s) : %3$d', 'wporg-plugins' ),
358                                        esc_html( $start_date ),
359                                        esc_html( $stats['date'] ),
360                                        esc_html( $stats['in_queue_from_time_window'] )
361                                );
362                        ?>
363                        </li>
364                        <li>
365                        <?php
366                                /* translators: %d: number of new plugins */
367                                printf(
368                                        __( '&rarr; (new; not processed or replied to yet)* : %d', 'wporg-plugins' ),
369                                        esc_html( $stats['in_queue_new'] )
370                                );
371                        ?>
372                        </li>
373                        <li>
374                        <?php
375                                /* translators: %d: number of pending plugins */
376                                printf(
377                                        __( '&rarr; (pending; replied to)* : %d', 'wporg-plugins' ),
378                                        esc_html( $stats['in_queue_pending'] )
379                                );
380                        ?>
381                        </li>
382                </ul>
383
384                <h3><?php _e( 'Help Scout Queue Stats', 'wporg-plugins' ); ?></h3>
385
386                <ul style="font-family:Courier New;">
387                        <li>
388                        <?php
389                                printf(
390                                        'Total Conversations: %d',
391                                        esc_html( $stats['helpscout_queue_total_conversations'] )
392                                );
393                        ?>
394                        </li>
395                        <li>
396                        <?php
397                                printf(
398                                        'New Conversations: %d',
399                                        esc_html( $stats['helpscout_queue_new_conversations'] )
400                                );
401                        ?>
402                        </li>
403                        <li>
404                        <?php
405                                printf(
406                                        'Customers: %d',
407                                        esc_html( $stats['helpscout_queue_customers'] )
408                                );
409                        ?>
410                        </li>
411                        <li>
412                        <?php
413                                printf(
414                                        'Conversations per Day: %d',
415                                        esc_html( $stats['helpscout_queue_conversations_per_day'] )
416                                );
417                        ?>
418                        </li>
419                        <li>
420                        <?php
421                                printf(
422                                        'Busiest Day: %s',
423                                        esc_html( $stats['helpscout_queue_busiest_day'] )
424                                );
425                        ?>
426                        </li>
427                        <li>
428                        <?php
429                                printf(
430                                        'Messages Received: %d',
431                                        esc_html( $stats['helpscout_queue_messages_received'] )
432                                );
433                        ?>
434                        </li>
435                        <li>
436                        <?php
437                                printf(
438                                        'Replies Sent: %d',
439                                        esc_html( $stats['helpscout_queue_replies_sent'] )
440                                );
441                        ?>
442                        </li>
443                        <li>
444                        <?php
445                                printf(
446                                        'Emails Created: %d',
447                                        esc_html( $stats['helpscout_queue_emails_created'] )
448                                );
449                        ?>
450                        </li>
451                </ul>
452
453                <ul style="font-style:italic;">
454                        <li><code>*</code> : <?php _e( "Stat reflects current size of queue and does not take into account 'date' or 'day' interval", 'wporg-plugins' ); ?></li>
455                        <li><code>**</code> : <?php _e( "Stat reflects activity only within the 'recentdays' from today", 'wporg-plugins' ); ?></li>
456                </ul>
457
458                </div>
459                <?php
460        }
461
462}
Note: See TracBrowser for help on using the repository browser.