<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[12379] sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/inc/cli/class-stats.php: Translate: Add weekly stats summary to stats generator cron</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://meta.trac.wordpress.org/changeset/12379">12379</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://meta.trac.wordpress.org/changeset/12379","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>spiraltee</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2023-02-02 00:55:53 +0000 (Thu, 02 Feb 2023)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Translate: Add weekly stats summary to stats generator cron</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggpcustomizationsinccliclassstatsphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/inc/cli/class-stats.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggpcustomizationsinccliclassstatsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/inc/cli/class-stats.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/inc/cli/class-stats.php  2023-02-01 18:13:47 UTC (rev 12378)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/inc/cli/class-stats.php    2023-02-02 00:55:53 UTC (rev 12379)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10,6 +10,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> namespace WordPressdotorg\GlotPress\Customizations\CLI;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+require WP_PLUGIN_DIR . '/wp-i18n-teams/wp-i18n-teams.php';
+
</ins><span class="cx" style="display: block; padding: 0 10px"> use DateTime;
</span><span class="cx" style="display: block; padding: 0 10px"> use Exception;
</span><span class="cx" style="display: block; padding: 0 10px"> use GP;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -18,7 +20,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> use WP_CLI;
</span><span class="cx" style="display: block; padding: 0 10px"> use WP_CLI_Command;
</span><span class="cx" style="display: block; padding: 0 10px"> use WP_Query;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+use WordPressdotorg\GlotPress\Routes\Plugin;
</ins><span class="cx" style="display: block; padding: 0 10px"> use function WordPressdotorg\Locales\get_locales;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+use function WordPressdotorg\I18nTeams\Locales\get_locales_data;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> class Stats {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -45,68 +49,73 @@
</span><span class="cx" style="display: block; padding: 0 10px">        private int $id_first_user_of_this_year = 0;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Percentage of non-EN_US sites.
+        */
+       private string $translated_sites_pct = '';
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Id of each forum database, for each country
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @var int[]
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        private array $forum_ids = array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                'pt'    => 383,
-               'make'  => 384,
-//             ''      => 385,
-               'emoji' => 386,
-               'hau'   => 387,
-               'fao'   => 388,
-               'af'    => 389,
-               'am'    => 390,
-               'id'    => 391,
-               'mya'   => 392,
-               'ja'    => 393,
-               'ru'    => 394,
-               'de'    => 395,
-               'bs'    => 396,
-               'th'    => 397,
-               'cn'    => 398,
-               'ak'    => 399,
-               'an'    => 400,
-               'ar'    => 401,
-               'arq'   => 402,
-               'ug'    => 403,
-               'tw'    => 404,
-               'bg'    => 405,
-               'sr'    => 406,
-               'hr'    => 407,
-               'nl'    => 408,
-               'he'    => 409,
-               'ka'    => 410,
-               'fi'    => 411,
-               'mk'    => 412,
-               'ca'    => 413,
-               'sk'    => 414,
-               'pl'    => 415,
-               'ro'    => 416,
-               'es'    => 417,
-               'br'    => 418,
-               'en'    => 419,
-               'sq'    => 420,
-               'hy'    => 421,
-               'rup'   => 422,
-               'frp'   => 423,
-               'as'    => 424,
-               'ast'   => 425,
-               'az'    => 426,
-               'az-tr' => 427,
-               'bcc'   => 428,
-               'eu'    => 429,
-               'bel'   => 430,
-               'bn'    => 431,
-               'bre'   => 432,
-               'ceb'   => 433,
-               'zh-hk' => 434,
-               'co'    => 435,
-               'cs'    => 436,
-               'et'    => 437,
-               'eo'    => 438,
-               'uz'    => 439,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         'pt'                => 383,
+               'make'              => 384,
+               // ''      => 385,
+                                       'emoji' => 386,
+               'hau'               => 387,
+               'fao'               => 388,
+               'af'                => 389,
+               'am'                => 390,
+               'id'                => 391,
+               'mya'               => 392,
+               'ja'                => 393,
+               'ru'                => 394,
+               'de'                => 395,
+               'bs'                => 396,
+               'th'                => 397,
+               'cn'                => 398,
+               'ak'                => 399,
+               'an'                => 400,
+               'ar'                => 401,
+               'arq'               => 402,
+               'ug'                => 403,
+               'tw'                => 404,
+               'bg'                => 405,
+               'sr'                => 406,
+               'hr'                => 407,
+               'nl'                => 408,
+               'he'                => 409,
+               'ka'                => 410,
+               'fi'                => 411,
+               'mk'                => 412,
+               'ca'                => 413,
+               'sk'                => 414,
+               'pl'                => 415,
+               'ro'                => 416,
+               'es'                => 417,
+               'br'                => 418,
+               'en'                => 419,
+               'sq'                => 420,
+               'hy'                => 421,
+               'rup'               => 422,
+               'frp'               => 423,
+               'as'                => 424,
+               'ast'               => 425,
+               'az'                => 426,
+               'az-tr'             => 427,
+               'bcc'               => 428,
+               'eu'                => 429,
+               'bel'               => 430,
+               'bn'                => 431,
+               'bre'               => 432,
+               'ceb'               => 433,
+               'zh-hk'             => 434,
+               'co'                => 435,
+               'cs'                => 436,
+               'et'                => 437,
+               'eo'                => 438,
+               'uz'                => 439,
</ins><span class="cx" style="display: block; padding: 0 10px">         );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        private string $header                           = '';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -120,7 +129,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">        private string $contributors_per_locale          = '';
</span><span class="cx" style="display: block; padding: 0 10px">        private string $managers_stats                   = '';
</span><span class="cx" style="display: block; padding: 0 10px">        private string $most_active_translators          = '';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        private string $stats_comparison                 = '';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px">         /**
</span><span class="cx" style="display: block; padding: 0 10px">         * The name of the custom post type used to the translation feedback.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -149,9 +160,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        return;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                define( 'MAKE_POLYGLOTS_BLOG_ID', 19 );
+               define( 'POLYGLOTS_PAGE_ID', 42132 );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->echo_the_values = $echo_the_values;
</span><span class="cx" style="display: block; padding: 0 10px">                $this->set_number_of_years_with_data();
</span><span class="cx" style="display: block; padding: 0 10px">                $this->print_header();
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $this->print_stats_comparison( gmdate( 'Y-m-d' ) );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->print_wordpress_translation_percentage();
</span><span class="cx" style="display: block; padding: 0 10px">                $this->print_packages_generated();
</span><span class="cx" style="display: block; padding: 0 10px">                $this->print_unique_themes_plugins_by_year();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -162,10 +177,248 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $this->print_contributors_per_locale();
</span><span class="cx" style="display: block; padding: 0 10px">                $this->print_managers_stats();
</span><span class="cx" style="display: block; padding: 0 10px">                $this->print_most_active_translators();
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $this->store_stats();
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->update_page();
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Store the generated stats in the database
+        *
+        * @return void
+        */
+       private function store_stats() {
+               global $wpdb;
+
+               $this->translated_sites_pct = $this->get_translated_sites_pct();
+
+               $contributors_per_locale  = Plugin::get_contributors_count();
+               $total_contributors_count = array_sum( $contributors_per_locale );
+
+               $all_locales_data = get_locales_data();
+               $stats_data       = $all_locales_data['status_counts'];
+               $total_gtes       = array_sum( $this->count_managers( 'general_translation_editor' ) );
+               $total_ptes       = array_sum( $this->count_managers( 'translation_editor' ) );
+
+               $locale_requests = $this->get_locale_requests();
+               $editor_requests = $this->get_editor_requests();
+
+               $result = $wpdb->insert(
+                       'polyglot_stats',
+                       array(
+                               'releases_by_locale'                    => $stats_data['all'],
+                               'releases_by_locale_uptodate'           => $stats_data['latest'],
+                               'releases_by_locale_minor_behind'       => $stats_data['minor-behind'],
+                               'releases_by_locale_one_major_behind'   => $stats_data['major-behind-one'],
+                               'releases_by_locale_multi_major_behind' => $stats_data['major-behind-many'],
+                               'locales_total'                         => $this->get_core_total(),
+                               'locales_100'                           => $this->get_core_full_translated(),
+                               'locales_95_plus'                       => $this->get_core_interval( 100, 95 ),
+                               'locales_90_plus'                       => $this->get_core_interval( 95, 90 ),
+                               'locales_50_plus'                       => $this->get_core_interval( 90, 50 ),
+                               'locales_below_50'                      => $this->get_core_interval( 50, 0, '<', '>' ),
+                               'locales_with_language_packs'           => $stats_data['has-language-pack'],
+                               'locales_without_project'               => $stats_data['no-wp-project'],
+                               'requests_total'                        => $editor_requests['total'],
+                               'requests_unresolved'                   => $editor_requests['unresolved_editor_requests'],
+                               'locale_requests_total'                 => $locale_requests['total'],
+                               'locale_requests_unresolved'            => $locale_requests['unresolved_locale_requests'],
+                               'translators_gtes'                      => $total_gtes,
+                               'translators_ptes'                      => $total_ptes,
+                               'translators_contributors'              => $total_contributors_count,
+                               'wp_translated_sites_pct'               => $this->translated_sites_pct,
+                               'date'                                  => gmdate( 'Y-m-d' ),
+                       )
+               );
+       }
+
+       /**
+        * Fetch total number of locale requests and number of unresolved locale requests.
+        *
+        * @return array $locale_requests Array of the count of each of resolved and unresolved locale requests.
+        */
+       private function get_locale_requests() {
+               $locale_requests = array();
+               switch_to_blog( MAKE_POLYGLOTS_BLOG_ID );
+               $args                     = array(
+                       'post_type'   => 'post',
+                       'tag'         => 'locale-requests',
+                       'post_status' => 'publish',
+               );
+               $locale_requests['total'] = ( new WP_query( $args ) )->found_posts;
+               register_taxonomy(
+                       'p2_resolved',
+                       'post',
+                       array(
+                               'public'    => true,
+                               'query_var' => 'resolved',
+                               'rewrite'   => false,
+                               'show_ui'   => false,
+                       )
+               );
+
+               $args = array(
+                       'tag'       => 'locale-requests',
+                       'tax_query' => array(
+                               array(
+                                       'taxonomy' => 'p2_resolved',
+                                       'field'    => 'slug',
+                                       'terms'    => 'unresolved',
+                               ),
+                       ),
+               );
+               $locale_requests['unresolved_locale_requests'] = ( new WP_query( $args ) )->found_posts;
+
+               restore_current_blog();
+
+               return $locale_requests;
+       }
+
+       /**
+        * Fetch total number of editor requests and number of unresolved editor requests.
+        *
+        * @return array $editor_requests Array of the count of each of resolved and unresolved editor requests.
+        */
+       private function get_editor_requests() {
+               $editor_requests = array();
+               switch_to_blog( MAKE_POLYGLOTS_BLOG_ID );
+               register_taxonomy(
+                       'p2_resolved',
+                       'post',
+                       array(
+                               'public'    => true,
+                               'query_var' => 'resolved',
+                               'rewrite'   => false,
+                               'show_ui'   => false,
+                       )
+               );
+               $args                     = array(
+                       'post_type'   => 'post',
+                       'tag'         => 'editor-requests',
+                       'post_status' => 'publish',
+               );
+               $editor_requests['total'] = ( new WP_query( $args ) )->found_posts;
+               $args                     = array(
+                       'post_type' => 'post',
+                       'tag'       => 'editor-requests',
+                       'tax_query' => array(
+                               array(
+                                       'taxonomy' => 'p2_resolved',
+                                       'field'    => 'slug',
+                                       'terms'    => 'unresolved',
+                               ),
+                       ),
+               );
+               $editor_requests['unresolved_editor_requests'] = ( new WP_query( $args ) )->found_posts;
+               restore_current_blog();
+
+               return $editor_requests;
+       }
+
+       /**
+        * Fetch stats data for a specific date.
+        *
+        * @param string $date The date for the record to be retrieved.
+        *
+        * @return mixed
+        */
+       private function get_data_for_date( $date ) {
+               global $wpdb;
+               $sql     = "SELECT * FROM polyglot_stats WHERE date = '" . $date . "'";
+               $results = $wpdb->get_results( $sql );
+               return $results[0];
+       }
+
+
+       /**
+        * Get the percentage of non-EN_US sites.
+        *
+        * @return float
+        */
+       private function get_translated_sites_pct() {
+               $translation_stats_json  = file_get_contents( 'https://api.wordpress.org/stats/locale/1.0/' );
+               $ranslation_stats_array  = $translation_stats_json && '{' == $translation_stats_json[0] ? json_decode( $translation_stats_json, true ) : null;
+               $wp_translated_sites_pct = 100 - $ranslation_stats_array['English (US)'];
+               return $wp_translated_sites_pct;
+       }
+
+       /**
+        * Print stats compared week on week.
+        *
+        * @param string $current_date The date for which we display the stats.
+        * @param string $old_date The date to compare the stats with.
+        *
+        * @return void
+        */
+       private function print_stats_comparison( $current_date, $old_date = null ) {
+               if ( ! $this->is_date_valid( $current_date ) || ( $old_date && ! $this->is_date_valid( $old_date ) ) ) {
+                       return;
+               }
+               $old_date          = is_null( $old_date ) ? date( 'Y-m-d', strtotime( '-1 week' ) ) : $old_date;
+               $current_date_data = $this->get_data_for_date( $current_date );
+               $old_date_data     = $this->get_data_for_date( $old_date );
+
+               if ( ! $current_date_data || ! $old_date_data ) {
+                       return;
+               }
+               if ( ! $this->echo_the_values ) {
+                       $this->stats_comparison = $this->create_gutenberg_heading( 'Summary for weekly stats' );
+               } else {
+                       $this->print_wpcli_heading( 'Summary for weekly stats' );
+               }
+               $stats_diff = new \stdClass();
+               foreach ( $current_date_data as $key => $value ) {
+                       $stats_diff->$key = $value - $old_date_data->$key;
+               }
+               $all_locales_data = get_locales_data();
+               $stats_data       = $all_locales_data['status_counts'];
+
+               $code = 'Below stats are dated ' . $current_date . ' compared to ' . $old_date . ' (differences between brackets)' . PHP_EOL . PHP_EOL;
+
+               $code .= 'Releases: ' . $current_date_data->releases_by_locale . ' (' . $this->prefix_num( $stats_diff->releases_by_locale ) . ') locale, ' . $current_date_data->releases_by_locale_uptodate . ' (' . $this->prefix_num( $stats_diff->releases_by_locale_uptodate ) . ') up to date, ' . $current_date_data->releases_by_locale_minor_behind . ' (' . $this->prefix_num( $stats_diff->releases_by_locale_minor_behind ) . ') behind by minor versions, ' . $current_date_data->releases_by_locale_one_major_behind . ' (' . $this->prefix_num( $stats_diff->releases_by_locale_one_major_behind ) . ') behind by one major version, ' . $current_date_data->releases_by_locale_multi_major_behind . ' (' . $this->prefix_num( $stats_diff->releases_by_locale_multi_major_behind ) . ') behind more than one major version, ' . $stats_data['no-site'] . ' (N/A) have site but never released, ' . $stats_data['no-releases'] . ' (N/A) have no site.' . PHP_EOL . PHP_EOL;
+
+               $code .= 'Translations: ' . $current_date_data->locales_total . ' (' . $this->prefix_num( $stats_diff->locales_total ) . ') total, ' . $current_date_data->locales_100 . ' (' . $this->prefix_num( $stats_diff->locales_100 ) . ') at 100%, ' . $current_date_data->locales_95_plus . ' (' . $this->prefix_num( $stats_diff->locales_95_plus ) . ') over 95%, ' . $current_date_data->locales_90_plus . ' (' . $this->prefix_num( $stats_diff->locales_90_plus ) . ') over 90%, ' . $current_date_data->locales_50_plus . ' (' . $this->prefix_num( $stats_diff->locales_50_plus ) . ') over 50%, ' . $current_date_data->locales_below_50 . ' (' . $this->prefix_num( $stats_diff->locales_below_50 ) . ') below 50%, ' . $current_date_data->locales_with_language_packs . ' (' . $this->prefix_num( $stats_diff->locales_with_language_packs ) . ') have a language pack generated, ' . $current_date_data->locales_without_project . ' (' . $this->prefix_
 num( $stats_diff->locales_without_project ) . ') have no project.' . PHP_EOL . PHP_EOL;
+
+               $code .= 'Requests: There are ' . $current_date_data->requests_unresolved . ' unresolved editor requests out of ' . $current_date_data->requests_total . ' (' . $this->prefix_num( $stats_diff->requests_unresolved ) . ') total and ' . $current_date_data->locale_requests_unresolved . ' unresolved locale requests out of ' . $current_date_data->locale_requests_total . ' (' . $this->prefix_num( $stats_diff->locale_requests_unresolved ) . ') total.' . PHP_EOL . PHP_EOL;
+
+               $code .= 'Translators: There are ' . $current_date_data->translators_gtes . ' (' . $this->prefix_num( $stats_diff->translators_gtes ) . ') GTE, ' . $current_date_data->translators_ptes . ' (' . $this->prefix_num( $stats_diff->translators_ptes ) . ')  and ' . $current_date_data->translators_contributors . ' (' . $this->prefix_num( $stats_diff->translators_contributors ) . ') translation contributors.' . PHP_EOL;
+               $code .= '(A wordpress.org account could have multiple roles over different locale)' . PHP_EOL . PHP_EOL;
+
+               $code .= 'Site language: ' . $current_date_data->wp_translated_sites_pct . '% (' . $this->prefix_num( round( $stats_diff->wp_translated_sites_pct, 3 ) ) . '%) of WordPress sites are running a translated WordPress site. ' . PHP_EOL;
+               if ( ! $this->echo_the_values ) {
+                       $this->stats_comparison .= $this->create_gutenberg_code( $code );
+               } else {
+                       WP_CLI::log( $code );
+               }
+       }
+
+       /**
+        * Checks if date is valid
+        *
+        * @param string $date The date that needs to be validated.
+        *
+        * @return boolean True if date is valid and False if invalid
+        */
+       private function is_date_valid( $date, $format = 'Y-m-d' ) {
+               $_date = DateTime::createFromFormat( $format, $date );
+               return $_date && $_date->format( $format ) === $date;
+       }
+
+       /**
+        * Prefix numbers greater than zero with plus sign and plus_minus sign if number is zero.
+        *
+        * @param int $num Number to be prefixed.
+        *
+        * @return string Prefixed number
+        */
+       private function prefix_num( $num ) {
+               if ( 0 === $num ) {
+                       return '±0';
+               }
+               return $num > 0 ? sprintf( '+%d', $num ) : $num;
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Set the number of years between 2010 (first year with translations) and the current year.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @return void
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -181,7 +434,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        private function print_header(): void {
</span><span class="cx" style="display: block; padding: 0 10px">                if ( ! $this->echo_the_values ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $this->header = $this->create_gutenberg_paragraph( 'Polyglots stats. Created at ' . gmdate( 'Y-m-d H:i:s' ) . ' ' . date_default_timezone_get() );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $this->header  = $this->create_gutenberg_paragraph( 'Polyglots stats. Created at ' . gmdate( 'Y-m-d H:i:s' ) . ' ' . date_default_timezone_get() );
</ins><span class="cx" style="display: block; padding: 0 10px">                         $this->header .= $this->create_gutenberg_paragraph( 'Created using the <b>wp wporg-translate show-stats --url=translate.wordpress.org</b> command.' );
</span><span class="cx" style="display: block; padding: 0 10px">                } else {
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->print_wpcli_heading( 'Polyglots stats. Created at ' . gmdate( 'Y-m-d H:i:s' ) . ' ' . date_default_timezone_get() );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -302,24 +555,24 @@
</span><span class="cx" style="display: block; padding: 0 10px">                } else {
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->print_wpcli_heading( $header );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $code       = "Year \t Core Packs \t Plugin Packs \t Theme Packs \t Total Packs " . PHP_EOL;
-               $code      .= '.......................................................................' . PHP_EOL;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $code  = "Year \t Core Packs \t Plugin Packs \t Theme Packs \t Total Packs " . PHP_EOL;
+               $code .= '.......................................................................' . PHP_EOL;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $packages as $package ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        if ( gmdate( 'Y' ) == $package['year'] ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                $code .= str_pad( $package['year'] . ' (*) ', 10 ) .
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                         str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['core_packs']) ), 16 ) .
-                                        str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['plugin_packs'] ) ), 16 ) .
-                                        str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['theme_packs'] ) ), 16 ) .
-                                        str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['total_packs'] ) ), 16 ) .
-                                        PHP_EOL;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                          str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['core_packs'] ) ), 16 ) .
+                                                str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['plugin_packs'] ) ), 16 ) .
+                                                str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['theme_packs'] ) ), 16 ) .
+                                                str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['total_packs'] ) ), 16 ) .
+                                                PHP_EOL;
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px">                        $code .= str_pad( $package['year'], 10 ) .
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                 str_pad( number_format_i18n( $package['core_packs'] ), 16 ) .
-                                str_pad( number_format_i18n( $package['plugin_packs'] ), 16 ) .
-                                str_pad( number_format_i18n( $package['theme_packs'] ), 16 ) .
-                                str_pad( number_format_i18n( $package['total_packs'] ), 16 ) .
-                                PHP_EOL;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                  str_pad( number_format_i18n( $package['core_packs'] ), 16 ) .
+                                        str_pad( number_format_i18n( $package['plugin_packs'] ), 16 ) .
+                                        str_pad( number_format_i18n( $package['theme_packs'] ), 16 ) .
+                                        str_pad( number_format_i18n( $package['total_packs'] ), 16 ) .
+                                        PHP_EOL;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">                $code .= '.......................................................................' . PHP_EOL;
</span><span class="cx" style="display: block; padding: 0 10px">                $code .= '(*) Estimated for the current year.' . PHP_EOL;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -366,22 +619,22 @@
</span><span class="cx" style="display: block; padding: 0 10px">                } else {
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->print_wpcli_heading( $header );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $code       = "Year \t Plugins \t Themes \t Total" . PHP_EOL;
-               $code      .= '................................................................' . PHP_EOL;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $code  = "Year \t Plugins \t Themes \t Total" . PHP_EOL;
+               $code .= '................................................................' . PHP_EOL;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $packages as $package ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        if ( gmdate( 'Y' ) == $package['year'] ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                $code .= str_pad( $package['year'] . ' (*) ', 10 ) .
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                         str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['plugins']) ), 16 ) .
-                                        str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['themes'] ) ), 16 ) .
-                                        str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['total'] ) ), 16 ) .
-                                        PHP_EOL;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                          str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['plugins'] ) ), 16 ) .
+                                                str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['themes'] ) ), 16 ) .
+                                                str_pad( number_format_i18n( $this->estimate_value_for_full_year( $package['total'] ) ), 16 ) .
+                                                PHP_EOL;
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px">                        $code .= str_pad( $package['year'], 10 ) .
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                 str_pad( number_format_i18n( $package['plugins'] ), 16 ) .
-                                str_pad( number_format_i18n( $package['themes'] ), 16 ) .
-                                str_pad( number_format_i18n( $package['total'] ), 16 ) .
-                                PHP_EOL;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                  str_pad( number_format_i18n( $package['plugins'] ), 16 ) .
+                                        str_pad( number_format_i18n( $package['themes'] ), 16 ) .
+                                        str_pad( number_format_i18n( $package['total'] ), 16 ) .
+                                        PHP_EOL;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">                $code .= '................................................................' . PHP_EOL;
</span><span class="cx" style="display: block; padding: 0 10px">                $code .= '(*) Estimated for the current year.' . PHP_EOL;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -432,11 +685,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                $last_id = $first_id - 1;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $first_id = $wpdb->get_var( $wpdb->prepare(
-                               "SELECT MIN(id) FROM {$wpdb->gp_translations} WHERE date_added BETWEEN %s AND %s",
-                               $year . '-01-01 00:00:00',
-                               $year . '-01-02 00:00:00',
-                       ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $first_id = $wpdb->get_var(
+                               $wpdb->prepare(
+                                       "SELECT MIN(id) FROM {$wpdb->gp_translations} WHERE date_added BETWEEN %s AND %s",
+                                       $year . '-01-01 00:00:00',
+                                       $year . '-01-02 00:00:00',
+                               )
+                       );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $row = $wpdb->get_row(
</span><span class="cx" style="display: block; padding: 0 10px">                                $wpdb->prepare(
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -502,7 +757,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $forum_replies[ $year ] = $this->get_forums_stats( 'reply', $year );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                ksort($this->forum_ids);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         ksort( $this->forum_ids );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $header = 'Forums. Topics by year and locale.';
</span><span class="cx" style="display: block; padding: 0 10px">                if ( ! $this->echo_the_values ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -511,16 +766,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->print_wpcli_heading( $header );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $code .= str_pad('Locale', 12 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $code .= str_pad( 'Locale', 12 );
</ins><span class="cx" style="display: block; padding: 0 10px">                 for ( $year = $last_year; $year > $first_year; $year -- ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $code .= str_pad( $year, 8,' ', STR_PAD_LEFT  );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $code .= str_pad( $year, 8, ' ', STR_PAD_LEFT );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">                $code .= PHP_EOL;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $this->forum_ids as $key => $value ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $code .= str_pad($key, 12 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $code .= str_pad( $key, 12 );
</ins><span class="cx" style="display: block; padding: 0 10px">                         for ( $year = $last_year; $year > $first_year; $year -- ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $code .= str_pad( number_format_i18n( $forum_posts[$year][$key] ), 8,' ', STR_PAD_LEFT  );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $code .= str_pad( number_format_i18n( $forum_posts[ $year ][ $key ] ), 8, ' ', STR_PAD_LEFT );
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px">                        $code .= PHP_EOL;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -538,16 +793,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->print_wpcli_heading( $header );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $code = str_pad('Locale', 12 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $code = str_pad( 'Locale', 12 );
</ins><span class="cx" style="display: block; padding: 0 10px">                 for ( $year = $last_year; $year > $first_year; $year -- ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $code .= str_pad( $year, 8,' ', STR_PAD_LEFT  );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $code .= str_pad( $year, 8, ' ', STR_PAD_LEFT );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">                $code .= PHP_EOL;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $this->forum_ids as $key => $value ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $code .= str_pad($key, 12 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $code .= str_pad( $key, 12 );
</ins><span class="cx" style="display: block; padding: 0 10px">                         for ( $year = $last_year; $year > $first_year; $year -- ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $code .= str_pad( number_format_i18n( $forum_replies[$year][$key] ), 8,' ', STR_PAD_LEFT  );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $code .= str_pad( number_format_i18n( $forum_replies[ $year ][ $key ] ), 8, ' ', STR_PAD_LEFT );
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px">                        $code .= PHP_EOL;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -584,10 +839,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                $last_id = $first_id - 1;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $first_id = $wpdb->get_var( $wpdb->prepare(
-                               "SELECT MIN(id) FROM {$wpdb->gp_translations} WHERE date_added >= %s",
-                               $year . '-01-01'
-                       ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $first_id = $wpdb->get_var(
+                               $wpdb->prepare(
+                                       "SELECT MIN(id) FROM {$wpdb->gp_translations} WHERE date_added >= %s",
+                                       $year . '-01-01'
+                               )
+                       );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $rows = $wpdb->get_results(
</span><span class="cx" style="display: block; padding: 0 10px">                                $wpdb->prepare(
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -613,7 +870,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                }
</span><span class="cx" style="display: block; padding: 0 10px">                                $strings_added = number_format_i18n( $row['strings_added'] );
</span><span class="cx" style="display: block; padding: 0 10px">                                $contributor   = get_user_by( 'id', $row['user_id'] );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                if ($contributor) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         if ( $contributor ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                         $code .= "{$year} \t  {$strings_added}  \t {$contributor->user_login}" . PHP_EOL;
</span><span class="cx" style="display: block; padding: 0 10px">                                }
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -739,7 +996,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        $comment_meta_translation_id
</span><span class="cx" style="display: block; padding: 0 10px">                                )
</span><span class="cx" style="display: block; padding: 0 10px">                        );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( ! $translation ) { 
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if ( ! $translation ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                 continue;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -826,7 +1083,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $comments_number = number_format_i18n( $commenter->comments_number );
</span><span class="cx" style="display: block; padding: 0 10px">                        $code           .= " - {$commenter->user_login}: {$tabs} {$comments_number} comments. Profile: {$url}" . PHP_EOL;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $code                    .= PHP_EOL;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $code .= PHP_EOL;
</ins><span class="cx" style="display: block; padding: 0 10px">                 if ( ! $this->echo_the_values ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->feedback_received .= $this->create_gutenberg_code( $code );
</span><span class="cx" style="display: block; padding: 0 10px">                } else {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -872,7 +1129,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $code .= 'General Translator Editors (GTE):' . PHP_EOL;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $code .= " - Total:\t\t\t\t\t\t\t\t" . number_format_i18n( array_sum( $general_translation_editors ) ). PHP_EOL;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $code .= " - Total:\t\t\t\t\t\t\t\t" . number_format_i18n( array_sum( $general_translation_editors ) ) . PHP_EOL;
</ins><span class="cx" style="display: block; padding: 0 10px">                 $code .= " - Total users that have been registered this year and get the role:\t" . number_format_i18n( array_sum( $registered_this_year_new_general_translation_editors ) ) . PHP_EOL;
</span><span class="cx" style="display: block; padding: 0 10px">                $code .= " - Total users that have start translating this year and get the role:\t" . number_format_i18n( array_sum( $started_this_year_new_general_translation_editors ) ) . PHP_EOL;
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $locales as $locale ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -904,8 +1161,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @return void
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        private function print_contributors_per_locale():void {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $locales                       = get_locales();
-               $header                        = 'Contributors per locale';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $locales = get_locales();
+               $header  = 'Contributors per locale';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                if ( ! $this->echo_the_values ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->contributors_per_locale = $this->create_gutenberg_heading( $header );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -921,10 +1178,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $locales as $locale ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $current_contributors = $this->get_translation_contributors( $locale, 365 );
</span><span class="cx" style="display: block; padding: 0 10px">                        $all_contributors     = $this->get_translation_contributors( $locale );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $code                .= str_pad( $locale->english_name, 40) .
-                                               str_pad( number_format_i18n( count( $current_contributors ) ), 20) .
-                                               str_pad( number_format_i18n( count($all_contributors) - count( $current_contributors ) ), 20) .
-                                               str_pad( number_format_i18n( count( $all_contributors ) ), 20) . PHP_EOL;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $code                .= str_pad( $locale->english_name, 40 ) .
+                                                                       str_pad( number_format_i18n( count( $current_contributors ) ), 20 ) .
+                                                                       str_pad( number_format_i18n( count( $all_contributors ) - count( $current_contributors ) ), 20 ) .
+                                                                       str_pad( number_format_i18n( count( $all_contributors ) ), 20 ) . PHP_EOL;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                if ( ! $this->echo_the_values ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1255,9 +1512,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                if ( $this->echo_the_values ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        return;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                define( 'MAKE_POLYGLOTS_BLOG_ID', 19 );
-               define( 'POLYGLOTS_PAGE_ID', 42132 );
-               add_filter( 'wp_revisions_to_keep',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+               add_filter(
+                       'wp_revisions_to_keep',
</ins><span class="cx" style="display: block; padding: 0 10px">                         function ( $num, $post ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                if ( POLYGLOTS_PAGE_ID === $post->ID ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                        $num = 0; // pretend we don't want to keep revisions so that it will not lookup all old revisions.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1266,7 +1523,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                return $num;
</span><span class="cx" style="display: block; padding: 0 10px">                        },
</span><span class="cx" style="display: block; padding: 0 10px">                        10,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                2 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 2
+               );
</ins><span class="cx" style="display: block; padding: 0 10px">                 switch_to_blog( MAKE_POLYGLOTS_BLOG_ID );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                wp_update_post(
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1288,6 +1546,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        private function get_polyglots_stats_page_content(): string {
</span><span class="cx" style="display: block; padding: 0 10px">                return $this->header .
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        $this->stats_comparison .
</ins><span class="cx" style="display: block; padding: 0 10px">                         $this->wordpress_translation_percentage .
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->originals_by_year .
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->packages_generated_by_year .
</span></span></pre>
</div>
</div>

</body>
</html>