| @@ -70,9 +70,9 @@ | ||
| 70 | 70 | |
| 71 | 71 | /** |
| 72 | 72 | * Model for the languages. |
| 73 | 73 | * |
| 74 | - * @var Model\Languages | |
| 74 | + * @var \WP_Syntex\Polylang\Model\Languages | |
| 75 | 75 | */ |
| 76 | 76 | public $languages; |
| 77 | 77 | |
| 78 | 78 | /** |
| @@ -77,9 +77,9 @@ | ||
| 77 | 77 | |
| 78 | 78 | /** |
| 79 | 79 | * Model for taxonomies translated by Polylang. |
| 80 | 80 | * |
| 81 | - * @var Model\Post_Types | |
| 81 | + * @var \WP_Syntex\Polylang\Model\Post_Types | |
| 82 | 82 | */ |
| 83 | 83 | public $post_types; |
| 84 | 84 | |
| 85 | 85 | /** |
| @@ -84,9 +84,9 @@ | ||
| 84 | 84 | |
| 85 | 85 | /** |
| 86 | 86 | * Model for taxonomies filtered/translated by Polylang. |
| 87 | 87 | * |
| 88 | - * @var Model\Taxonomies | |
| 88 | + * @var \WP_Syntex\Polylang\Model\Taxonomies | |
| 89 | 89 | */ |
| 90 | 90 | public $taxonomies; |
| 91 | 91 | |
| 92 | 92 | /** |
| @@ -320,9 +320,9 @@ | ||
| 320 | 320 | * @param PLL_Language $lang PLL_Language instance. |
| 321 | 321 | * @param array $q { |
| 322 | 322 | * WP_Query arguments: |
| 323 | 323 | * |
| 324 | - * @type string|string[] $post_type Post type or array of post types. | |
| 324 | + * @type string|string[] $post_type Post type or array of post types, defaults to 'post'. | |
| 325 | 325 | * @type int $m Combination YearMonth. Accepts any four-digit year and month. |
| 326 | 326 | * @type int $year Four-digit year. |
| 327 | 327 | * @type int $monthnum Two-digit month. |
| 328 | 328 | * @type int $day Day of the month. |
| @@ -328,9 +328,9 @@ | ||
| 328 | 328 | * @type int $day Day of the month. |
| 329 | 329 | * @type int $author Author id. |
| 330 | 330 | * @type string $author_name User 'user_nicename'. |
| 331 | 331 | * @type string $post_format Post format. |
| 332 | - * @type string $post_status Post status. | |
| 332 | + * @type string $post_status Post status, defaults to 'publish'. | |
| 333 | 333 | * } |
| 334 | 334 | * @return int |
| 335 | 335 | * |
| 336 | 336 | * @phpstan-param array{ |
| @@ -343,9 +343,8 @@ | ||
| 343 | 343 | * author?: int<1, max>, |
| 344 | 344 | * author_name?: non-falsy-string, |
| 345 | 345 | * post_format?: non-falsy-string |
| 346 | 346 | * } $q |
| 347 | - * @phpstan-return int<0, max> | |
| 348 | 347 | */ |
| 349 | 348 | public function count_posts( $lang, $q = array() ): int { |
| 350 | 349 | global $wpdb; |
| 351 | 350 | |
| @@ -365,18 +364,18 @@ | ||
| 365 | 364 | $q['post_type'] = array( 'post' ); // We *need* a post type. |
| 366 | 365 | } |
| 367 | 366 | |
| 368 | 367 | $cache_key = $this->cache->get_unique_key( 'pll_count_posts_', $q ); |
| 369 | - $counts = wp_cache_get( $cache_key, 'counts' ); | |
| 368 | + $counts = $this->get_counts_cache( $cache_key ); | |
| 370 | 369 | |
| 371 | 370 | if ( ! is_array( $counts ) ) { |
| 372 | 371 | $counts = array(); |
| 373 | - $select = "SELECT pll_tr.term_taxonomy_id, COUNT( * ) AS num_posts FROM {$wpdb->posts}"; | |
| 372 | + $select = "SELECT pll_tr.term_taxonomy_id, post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts}"; | |
| 374 | 373 | $join = $this->post->join_clause(); |
| 375 | - $where = sprintf( " WHERE post_status = '%s'", esc_sql( $q['post_status'] ) ); | |
| 376 | - $where .= sprintf( " AND {$wpdb->posts}.post_type IN ( '%s' )", implode( "', '", esc_sql( $q['post_type'] ) ) ); | |
| 374 | + $where = sprintf( " WHERE {$wpdb->posts}.post_type IN ( '%s' )", implode( "', '", esc_sql( $q['post_type'] ) ) ); | |
| 377 | 375 | $where .= $this->post->where_clause( $this->languages->get_list() ); |
| 378 | - $groupby = ' GROUP BY pll_tr.term_taxonomy_id'; | |
| 376 | + $where .= " AND post_status != 'auto-draft'"; | |
| 377 | + $groupby = ' GROUP BY pll_tr.term_taxonomy_id, post_status'; | |
| 379 | 378 | |
| 380 | 379 | if ( ! empty( $q['m'] ) ) { |
| 381 | 380 | $q['m'] = '' . preg_replace( '|[^0-9]|', '', $q['m'] ); |
| 382 | 381 | $where .= $wpdb->prepare( " AND YEAR( {$wpdb->posts}.post_date ) = %d", substr( $q['m'], 0, 4 ) ); |
| @@ -423,17 +422,23 @@ | ||
| 423 | 422 | } |
| 424 | 423 | |
| 425 | 424 | // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared |
| 426 | 425 | $res = $wpdb->get_results( $select . $join . $where . $groupby, ARRAY_A ); |
| 426 | + | |
| 427 | 427 | foreach ( (array) $res as $row ) { |
| 428 | - $counts[ $row['term_taxonomy_id'] ] = $row['num_posts']; | |
| 428 | + $counts[ $row['term_taxonomy_id'] ][ $row['post_status'] ] = $row['num_posts']; | |
| 429 | 429 | } |
| 430 | 430 | |
| 431 | - wp_cache_set( $cache_key, $counts, 'counts' ); | |
| 431 | + $this->set_counts_cache( $cache_key, $counts ); | |
| 432 | 432 | } |
| 433 | 433 | |
| 434 | 434 | $term_taxonomy_id = $lang->get_tax_prop( 'language', 'term_taxonomy_id' ); |
| 435 | - return empty( $counts[ $term_taxonomy_id ] ) ? 0 : $counts[ $term_taxonomy_id ]; | |
| 435 | + | |
| 436 | + if ( 'any' === $q['post_status'] ) { | |
| 437 | + return isset( $counts[ $term_taxonomy_id ] ) ? (int) array_sum( $counts[ $term_taxonomy_id ] ) : 0; | |
| 438 | + } | |
| 439 | + | |
| 440 | + return $counts[ $term_taxonomy_id ][ $q['post_status'] ] ?? 0; | |
| 436 | 441 | } |
| 437 | 442 | |
| 438 | 443 | /** |
| 439 | 444 | * Setup the links model based on options. |
| @@ -611,6 +616,49 @@ | ||
| 611 | 616 | return; |
| 612 | 617 | } |
| 613 | 618 | |
| 614 | 619 | $this->set_language_in_mass( $lang, $types_with_objects ); |
| 620 | + } | |
| 621 | + | |
| 622 | + /** | |
| 623 | + * Returns the number of posts grouped per language from the cache. | |
| 624 | + * | |
| 625 | + * @since 3.9 | |
| 626 | + * | |
| 627 | + * @param string $cache_key The cache key. | |
| 628 | + * @return array|false The counts grouped per language, false if the cache is empty. | |
| 629 | + */ | |
| 630 | + private function get_counts_cache( string $cache_key ) { | |
| 631 | + $last_changed = wp_cache_get_last_changed( 'posts' ); | |
| 632 | + | |
| 633 | + if ( ! function_exists( 'wp_cache_get_salted' ) ) { | |
| 634 | + // Backward compatibility with WordPress < 6.9. | |
| 635 | + $cache_key = "{$cache_key}:{$last_changed}"; | |
| 636 | + $counts = wp_cache_get( $cache_key, 'posts' ); | |
| 637 | + } else { | |
| 638 | + $counts = wp_cache_get_salted( $cache_key, 'posts', $last_changed ); | |
| 639 | + } | |
| 640 | + | |
| 641 | + return is_array( $counts ) ? $counts : false; | |
| 642 | + } | |
| 643 | + | |
| 644 | + /** | |
| 645 | + * Stores the number of posts grouped per language in the cache. | |
| 646 | + * | |
| 647 | + * @since 3.9 | |
| 648 | + * | |
| 649 | + * @param string $cache_key The cache key. | |
| 650 | + * @param int[][] $counts The number of posts grouped per language and post status. | |
| 651 | + * @return bool True if the value has been stored, false otherwise. | |
| 652 | + */ | |
| 653 | + private function set_counts_cache( $cache_key, array $counts ): bool { | |
| 654 | + $last_changed = wp_cache_get_last_changed( 'posts' ); | |
| 655 | + | |
| 656 | + if ( ! function_exists( 'wp_cache_set_salted' ) ) { | |
| 657 | + // Backward compatibility with WordPress < 6.9. | |
| 658 | + $cache_key = "{$cache_key}:{$last_changed}"; | |
| 659 | + return wp_cache_set( $cache_key, $counts, 'posts' ); | |
| 660 | + } | |
| 661 | + | |
| 662 | + return wp_cache_set_salted( $cache_key, $counts, 'posts', $last_changed ); | |
| 615 | 663 | } |
| 616 | 664 | } |