Making WordPress.org


Ignore:
Timestamp:
01/31/2016 10:58:15 PM (9 years ago)
Author:
ocean90
Message:

Translate: Add child pages to plugin projects to show contributors and language packs, first pass.

See #1388.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-routes/routes/wp-plugins.php

    r2267 r2439  
    33class WPorg_GP_Route_WP_Plugins extends GP_Route {
    44
     5    /**
     6     * Prints stats about sub-project of a specific project.
     7     *
     8     * @param string $project_slug Slug of a project.
     9     */
    510    public function get_plugin_projects( $project_slug ) {
    611        global $wpdb;
     
    97102        $this->tmpl( 'projects-wp-plugins', get_defined_vars() );
    98103    }
     104
     105    /**
     106     * Prints stats about contributors of a specific project.
     107     *
     108     * @param string $project_slug Slug of a project.
     109     */
     110    public function get_plugin_contributors( $project_slug ) {
     111        global $wpdb;
     112
     113        $project_path = 'wp-plugins/' . $project_slug;
     114        $project = GP::$project->by_path( $project_path );
     115        if ( ! $project ) {
     116            return $this->die_with_404();
     117        }
     118
     119        if ( function_exists( 'wporg_get_plugin_icon' ) ) {
     120            $project->icon = wporg_get_plugin_icon( $project->slug, 64 );
     121        } else {
     122            $project->icon = '<div class="default-icon"><span class="dashicons dashicons-admin-plugins"></span></div>';
     123        }
     124
     125        $contributors_by_locale = array();
     126        $default_value = array(
     127            'count' => 0,
     128            'editors' => array(),
     129            'contributors' => array(),
     130        );
     131
     132        $translation_editors = $wpdb->get_results( $wpdb->prepare( "
     133            SELECT
     134                `user_id`, `locale`
     135            FROM {$wpdb->wporg_translation_editors}
     136            WHERE `project_id` = %d
     137        ", $project->id ), OBJECT );
     138
     139        foreach ( $translation_editors as $translation_editor ) {
     140            if ( ! isset( $contributors_by_locale[ $translation_editor->locale ] ) ) {
     141                $contributors_by_locale[ $translation_editor->locale ] = $default_value;
     142            }
     143
     144            $user = get_user_by( 'id', $translation_editor->user_id );
     145            if ( ! $user ) {
     146                continue;
     147            }
     148
     149            $contributors_by_locale[ $translation_editor->locale ]['editors'][ $translation_editor->user_id ] = (object) array(
     150                'nicename'     => $user->user_nicename,
     151                'display_name' => $this->_encode( $user->display_name ),
     152            );
     153
     154            $contributors_by_locale[ $translation_editor->locale ]['count']++;
     155        }
     156
     157        unset( $translation_editors );
     158
     159        $sub_projects = $wpdb->get_col( $wpdb->prepare( "
     160            SELECT id
     161            FROM {$wpdb->gp_projects}
     162            WHERE parent_project_id = %d
     163        ", $project->id ) );
     164
     165        foreach ( $sub_projects as $sub_project ) {
     166            foreach( $this->get_translation_contributors_by_locale( $sub_project ) as $row ) {
     167                if ( ! isset( $contributors_by_locale[ $row->locale ] ) ) {
     168                    $contributors_by_locale[ $row->locale ] = $default_value;
     169                }
     170
     171                if ( isset( $contributors_by_locale[ $row->locale ]['editors'][ $row->user_id ] ) ) {
     172                    continue;
     173                }
     174
     175                if ( isset( $contributors_by_locale[ $row->locale ]['contributors'][ $row->user_id ] ) ) {
     176                    continue;
     177                }
     178
     179                $user = get_user_by( 'id', $row->user_id );
     180                if ( ! $user ) {
     181                    continue;
     182                }
     183
     184                $contributors_by_locale[ $row->locale ]['contributors'][ $row->user_id ] = (object) array(
     185                    'nicename'     => $user->user_nicename,
     186                    'display_name' => $this->_encode( $user->display_name ),
     187                );
     188
     189                $contributors_by_locale[ $row->locale ]['count']++;
     190            }
     191        }
     192
     193        $chart_data = $this->get_plugin_contributors_chart_data( $project->id, $sub_projects );
     194
     195        $this->tmpl( 'projects-wp-plugins-contributors', get_defined_vars() );
     196    }
     197
     198    /**
     199     * Generates the chart data for contributors activity.
     200     *
     201     * @param  int    $project_id   The ID of a project. Used to store data as meta.
     202     * @param  array $sub_projects Optional. IDs of sub-projects.
     203     * @return array The data to build a chart via Chartist.js.
     204     */
     205    private function get_plugin_contributors_chart_data( $project_id, $sub_projects = null ) {
     206        $chart_data = gp_get_meta( 'wp-plugins', $project_id, 'contributors-chart-data' );
     207        if ( $chart_data ) {
     208            if ( $chart_data['last_updated'] + DAY_IN_SECONDS > time() ) {
     209                return $chart_data;
     210            }
     211        }
     212
     213        global $wpdb;
     214
     215        if ( ! $sub_projects ) {
     216            $sub_projects = $wpdb->get_col( $wpdb->prepare( "
     217                SELECT id
     218                FROM {$wpdb->gp_projects}
     219                WHERE parent_project_id = %d
     220            ", $$project_id ) );
     221        }
     222
     223        $translation_set_ids = $wpdb->get_col( "
     224            SELECT `id` FROM {$wpdb->gp_translation_sets} WHERE `project_id` IN (" . implode( ',', $sub_projects ) . ")
     225        " );
     226
     227        if ( ! $translation_set_ids ) {
     228            return array();
     229        }
     230
     231        $date_begin = new DateTime( '-6 day' );
     232        $date_end = new DateTime( 'NOW' );
     233        $date_interval = new DateInterval( 'P1D' );
     234        $date_range = new DatePeriod( $date_begin, $date_interval, $date_end );
     235
     236        $days = array();
     237        foreach( $date_range as $date ) {
     238            $days[] = $date->format( 'Y-m-d' );
     239        }
     240        $days[] = $date_end->format( 'Y-m-d' );
     241
     242        $counts = $wpdb->get_results( "
     243            SELECT
     244                DATE(date_modified) AS `day`, COUNT(*) AS `count`, `status`
     245            FROM {$wpdb->gp_translations}
     246            WHERE
     247                `translation_set_id` IN (" . implode( ',', $translation_set_ids ) . ")
     248                AND date_modified >= ( CURDATE() - INTERVAL 7 DAY )
     249            GROUP BY `status`, `day`
     250            ORDER BY `day` DESC
     251        " );
     252
     253        $status = array( 'current', 'waiting', 'rejected' );
     254        $data = [];
     255        foreach ( $days as $day ) {
     256            $data[ $day ] = array( 'current' => 0, 'waiting' => 0, 'rejected' => 0 );
     257            foreach ( $counts as $count ) {
     258                if ( $count->day !== $day || ! in_array( $count->status, $status ) ) {
     259                    continue;
     260                }
     261
     262                $data[ $day ][ $count->status ] = (int) $count->count;
     263            }
     264        }
     265
     266
     267        $labels = array_keys( $data );
     268        array_pop( $labels );
     269        $labels[] = ''; // Don't show a label for today
     270
     271        $series = array();
     272        $series_data = array_values( $data );
     273        foreach ( $status as $stati ) {
     274            $series[] = (object) array(
     275                'name' => $stati,
     276                'data' => wp_list_pluck( $series_data, $stati ),
     277            );
     278        }
     279
     280        $last_updated = time();
     281        $chart_data = compact( 'labels', 'series', 'last_updated' );
     282
     283        gp_update_meta( $project_id, 'contributors-chart-data', $chart_data, 'wp-plugins' );
     284
     285        return $chart_data;
     286    }
     287
     288    /**
     289     * Prints stats about language packs of a specific project.
     290     *
     291     * @param string $project_slug Slug of a project.
     292     */
     293    public function get_plugin_language_packs( $project_slug ) {
     294        $project_path = 'wp-plugins/' . $project_slug;
     295        $project = GP::$project->by_path( $project_path );
     296        if ( ! $project ) {
     297            return $this->die_with_404();
     298        }
     299
     300        if ( function_exists( 'wporg_get_plugin_icon' ) ) {
     301            $project->icon = wporg_get_plugin_icon( $project->slug, 64 );
     302        } else {
     303            $project->icon = '<div class="default-icon"><span class="dashicons dashicons-admin-plugins"></span></div>';
     304        }
     305
     306        $http_context = stream_context_create( array(
     307            'http' => array(
     308                'user_agent' => 'WordPress.org Translate',
     309            ),
     310        ) );
     311        $json = file_get_contents( "https://api.wordpress.org/translations/plugins/1.0/?slug={$project_slug}", null, $http_context );
     312        $language_packs = $json && '{' == $json[0] ? json_decode( $json ) : null;
     313
     314
     315        $this->tmpl( 'projects-wp-plugins-language-packs', get_defined_vars() );
     316    }
     317
     318    /**
     319     * Retrieves translators of a specific project.
     320     *
     321     * @param int $project_id Project ID.
     322     * @return object Translators of the project.
     323     */
     324    private function get_translation_contributors_by_locale( $project_id ) {
     325        global $wpdb;
     326
     327        $sql = $wpdb->prepare( "
     328            SELECT ts.`locale`, ts.`slug` AS `locale_slug`, t.`user_id`
     329            FROM `{$wpdb->gp_translations}` t, `{$wpdb->gp_translation_sets}` ts
     330            WHERE t.`translation_set_id` = ts.`id`
     331                AND t.`user_id` IS NOT NULL AND t.`user_id` != 0
     332                AND t.`date_modified` > %s
     333                AND ts.`project_id` = %d
     334                AND t.`status` <> 'rejected'
     335            GROUP BY ts.`locale`, ts.`slug`, t.`user_id`
     336        ", date( 'Y-m-d', time() - YEAR_IN_SECONDS ), $project_id );
     337
     338        return $wpdb->get_results( $sql );
     339    }
     340
     341    private function _encode( $raw ) {
     342        $raw = mb_convert_encoding( $raw, 'UTF-8', 'ASCII, JIS, UTF-8, Windows-1252, ISO-8859-1' );
     343        return ent2ncr( htmlspecialchars_decode( htmlentities( $raw, ENT_NOQUOTES, 'UTF-8' ), ENT_NOQUOTES ) );
     344    }
    99345}
Note: See TracChangeset for help on using the changeset viewer.