| @@ -54,9 +54,9 @@ | ||
| 54 | 54 | * |
| 55 | 55 | * @return string The option name. |
| 56 | 56 | */ |
| 57 | 57 | public static function get_monthly_option_name( $user_id, $year, $month ) { |
| 58 | - return sprintf( '%s%d_%d_%02d', self::OPTION_PREFIX, $user_id, $year, $month ); | |
| 58 | + return \sprintf( '%s%d_%d_%02d', self::OPTION_PREFIX, $user_id, $year, $month ); | |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | 61 | /** |
| 62 | 62 | * Get the option name for annual stats. |
| @@ -66,9 +66,9 @@ | ||
| 66 | 66 | * |
| 67 | 67 | * @return string The option name. |
| 68 | 68 | */ |
| 69 | 69 | public static function get_annual_option_name( $user_id, $year ) { |
| 70 | - return sprintf( '%s%d_%d_annual', self::OPTION_PREFIX, $user_id, $year ); | |
| 70 | + return \sprintf( '%s%d_%d_annual', self::OPTION_PREFIX, $user_id, $year ); | |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | 73 | /** |
| 74 | 74 | * Get monthly statistics. |
| @@ -926,9 +926,8 @@ | ||
| 926 | 926 | 'post_type' => Outbox::POST_TYPE, |
| 927 | 927 | 'posts_per_page' => 1, |
| 928 | 928 | 'orderby' => 'date', |
| 929 | 929 | 'order' => 'ASC', |
| 930 | - 'fields' => 'ids', | |
| 931 | 930 | // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query |
| 932 | 931 | 'meta_query' => array( |
| 933 | 932 | array( |
| 934 | 933 | 'key' => '_activitypub_activity_type', |
| @@ -942,15 +941,30 @@ | ||
| 942 | 941 | } |
| 943 | 942 | |
| 944 | 943 | $earliest_outbox = \get_posts( $outbox_args ); |
| 945 | 944 | |
| 946 | - if ( empty( $earliest_outbox ) ) { | |
| 947 | - return null; | |
| 945 | + /* | |
| 946 | + * Prefer `post_date_gmt`; fall back to local `post_date` when the GMT field | |
| 947 | + * is empty or the MySQL zero-date (rare corruption seen on some production | |
| 948 | + * sites). The zero-date is a truthy string, so it has to be detected | |
| 949 | + * explicitly rather than via `?:`. | |
| 950 | + * | |
| 951 | + * Convert the local `post_date` fallback to GMT first so the later | |
| 952 | + * `strtotime()` + `gmdate()` flow consistently derives the year in UTC. | |
| 953 | + */ | |
| 954 | + $earliest_date = ''; | |
| 955 | + if ( $earliest_outbox ) { | |
| 956 | + $gmt = $earliest_outbox[0]->post_date_gmt; | |
| 957 | + $earliest_date = ( empty( $gmt ) || '0000-00-00 00:00:00' === $gmt ) | |
| 958 | + ? \get_gmt_from_date( $earliest_outbox[0]->post_date ) | |
| 959 | + : $gmt; | |
| 948 | 960 | } |
| 961 | + } | |
| 949 | 962 | |
| 950 | - $earliest_post = \get_post( $earliest_outbox[0] ); | |
| 951 | - $earliest_date = $earliest_post->post_date_gmt; | |
| 963 | + $timestamp = \strtotime( (string) $earliest_date ); | |
| 964 | + if ( false === $timestamp ) { | |
| 965 | + return null; | |
| 952 | 966 | } |
| 953 | 967 | |
| 954 | - return (int) \gmdate( 'Y', \strtotime( $earliest_date ) ); | |
| 968 | + return (int) \gmdate( 'Y', $timestamp ); | |
| 955 | 969 | } |
| 956 | 970 | } |