From a00d79a07d7518d2885d610cf47f30c2c246dfcc Mon Sep 17 00:00:00 2001
From: Ian Belanger <ianbelanger@git.wordpress.org>
Date: Fri, 28 Feb 2020 20:05:39 +0000
Subject: [PATCH] Bundled Themes: Twenty Thirteen update calendar widget styles
 for 5.4 markup.

Fixes the alignment of month links in the calendar widget with the changes in version 5.4

Props sabernhardt.
Fixes #49546.

git-svn-id: https://develop.svn.wordpress.org/trunk@47392 602fd350-edb4-49c9-b593-d223f7449a82
---
 src/wp-content/themes/twentythirteen/style.css | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/wp-content/themes/twentythirteen/style.css b/src/wp-content/themes/twentythirteen/style.css
index 6473b2fd38..84fdf73418 100644
--- a/src/wp-content/themes/twentythirteen/style.css
+++ b/src/wp-content/themes/twentythirteen/style.css
@@ -2583,6 +2583,22 @@ footer.entry-meta {
 	background-color: transparent;
 }
 
+.wp-calendar-table {
+	margin-bottom: 0;
+}
+
+.wp-calendar-nav {
+	display: table;
+	line-height: 2;
+	margin-bottom: 20px;
+	width: 100%;
+}
+
+.wp-calendar-nav span {
+	display: table-cell;
+	text-align: center;
+}
+
 /* Text widget */
 .widget_text ul,
 .widget_text ol {
-- 
2.23.0

From 5231937c576b4d63a19e0e38f227c2c9e767ff24 Mon Sep 17 00:00:00 2001
From: Cory Hughart <cory@blackbird.digital>
Date: Fri, 28 Feb 2020 14:08:30 -0500
Subject: [PATCH] initial implementation based off work by @jtsternberg

---
 src/wp-admin/includes/admin-filters.php       |   3 +
 .../includes/class-wp-posts-list-table.php    | 105 +++++++++++++++++-
 src/wp-includes/class-wp-taxonomy.php         |   9 ++
 src/wp-includes/taxonomy.php                  |   2 +
 4 files changed, 118 insertions(+), 1 deletion(-)

diff --git a/src/wp-admin/includes/admin-filters.php b/src/wp-admin/includes/admin-filters.php
index 4e66b28bb8..cefc948ff0 100644
--- a/src/wp-admin/includes/admin-filters.php
+++ b/src/wp-admin/includes/admin-filters.php
@@ -148,3 +148,6 @@ add_action( 'post_updated', array( 'WP_Privacy_Policy_Content', '_policy_page_up
 
 // Append '(Draft)' to draft page titles in the privacy page dropdown.
 add_filter( 'list_pages', '_wp_privacy_settings_filter_draft_page_titles', 10, 2 );
+
+// Sortable taxonomy columns
+add_filter( 'posts_clauses', array( 'WP_Posts_List_Table', '_peform_sortable_taxonomy_columns_query' ), 10, 2 );
diff --git a/src/wp-admin/includes/class-wp-posts-list-table.php b/src/wp-admin/includes/class-wp-posts-list-table.php
index 3a8dd65936..6744a9c6e0 100644
--- a/src/wp-admin/includes/class-wp-posts-list-table.php
+++ b/src/wp-admin/includes/class-wp-posts-list-table.php
@@ -116,6 +116,92 @@ class WP_Posts_List_Table extends WP_List_Table {
 		}
 	}
 
+
+	/**
+	 * Performs column sorting for taxonomies registered with 'show_column_sortable'.
+	 *
+	 * @since  5.4.0
+	 *
+	 * @global wpdb $wpdb WordPress database abstraction object.
+	 *
+	 * @param array    $clauses  The list of clauses for the query.
+	 * @param WP_Query $wp_query The WP_Query instance (passed by reference).
+	 * @return string Modified clauses
+	 */
+	public static function _peform_sortable_taxonomy_columns_query( $clauses, $wp_query ) {
+		global $wpdb;
+
+		if ( ! isset( $wp_query->query['orderby'] ) ) {
+			return $clauses;
+		}
+
+		$taxonomies = self::get_sortable_taxonomy_columns( $wp_query->query['post_type'] );
+
+		if ( empty( $taxonomies ) || ! is_array( $taxonomies ) ) {
+			return $clauses;
+		}
+
+		$sortable_taxonomies = array();
+		foreach ( $taxonomies as $taxonomy ) {
+			if ( 'category' == $taxonomy )
+				$column_key = 'categories';
+			elseif ( 'post_tag' == $taxonomy )
+				$column_key = 'tags';
+			else
+				$column_key = 'taxonomy-' . $taxonomy;
+
+			$sortable_taxonomies[ $taxonomy ] = $column_key;
+		}
+
+		$key = array_search( $wp_query->query['orderby'], $sortable_taxonomies, true );
+
+		if ( false === $key ) {
+			return $clauses;
+		}
+
+		$clauses['join'] .= "
+			LEFT OUTER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID={$wpdb->term_relationships}.object_id
+			LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id)
+			LEFT OUTER JOIN {$wpdb->terms} USING (term_id)
+		";
+		$clauses['where'] = $wpdb->prepare( " AND taxonomy = '%s'", $key );
+		$clauses['groupby'] = "object_id";
+		$clauses['orderby'] = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) ";
+		$clauses['orderby'] .= ( 'ASC' == strtoupper( $wp_query->get('order') ) ) ? 'ASC' : 'DESC';
+
+		return $clauses;
+	}
+
+	/**
+	 * Get a list of all taxonomies registered as sortable.
+	 * Passes through the "manage_taxonomies_for_{$post_type}_sortable_columns" filter.
+	 *
+	 * @since  5.4.0
+	 *
+	 * @param  string $post_type Post type to retrieve Taxonomies
+	 * @return array Array of sortable taxonomies
+	 */
+	public static function get_sortable_taxonomy_columns( $post_type ) {
+		$taxonomies = get_object_taxonomies( $post_type, 'objects' );
+		$taxonomies = wp_filter_object_list( $taxonomies, array( 'show_admin_column' => true, 'show_column_sortable' => true ), 'and', 'name' );
+
+		/**
+		 * Filter the sortable taxonomy columns in the Posts list table.
+		 *
+		 * The dynamic portion of the hook name, `$post_type`, refers to the post
+		 * type slug.
+		 *
+		 * @since 5.4.0
+		 *
+		 * @param array  $taxonomies Array of taxonomies to enable sortable columns for.
+		 * @param string $post_type  The post type.
+		 */
+		$taxonomies = apply_filters( "manage_taxonomies_for_{$post_type}_sortable_columns", $taxonomies );
+		$taxonomies = array_filter( $taxonomies, 'taxonomy_exists' );
+
+		return $taxonomies;
+	}
+
 	/**
 	 * Sets whether the table layout should be hierarchical or not.
 	 *
@@ -689,12 +775,29 @@ class WP_Posts_List_Table extends WP_List_Table {
 	 * @return array
 	 */
 	protected function get_sortable_columns() {
-		return array(
+		$sortables = array(
 			'title'    => 'title',
 			'parent'   => 'parent',
 			'comments' => 'comment_count',
 			'date'     => array( 'date', true ),
 		);
+
+		$taxonomies = self::get_sortable_taxonomy_columns( $this->screen->post_type );
+
+		if ( ! empty( $taxonomies ) && is_array( $taxonomies ) ) {
+			foreach ( $taxonomies as $taxonomy ) {
+				if ( 'category' == $taxonomy )
+					$column_key = 'categories';
+				elseif ( 'post_tag' == $taxonomy )
+					$column_key = 'tags';
+				else
+					$column_key = 'taxonomy-' . $taxonomy;
+
+				$sortables[ $column_key ] = $column_key;
+			}
+		}
+
+		return $sortables;
 	}
 
 	/**
diff --git a/src/wp-includes/class-wp-taxonomy.php b/src/wp-includes/class-wp-taxonomy.php
index 7cb35e9044..bdbfe21803 100644
--- a/src/wp-includes/class-wp-taxonomy.php
+++ b/src/wp-includes/class-wp-taxonomy.php
@@ -124,6 +124,14 @@ final class WP_Taxonomy {
 	 */
 	public $show_admin_column = false;
 
+	/**
+	 * Whether the admin column for the taxonomy on its post type listing screens is sortable.
+	 *
+	 * @since 5.4.0
+	 * @var bool
+	 */
+	public $show_column_sortable = false;
+
 	/**
 	 * The callback function for the meta box display.
 	 *
@@ -269,6 +277,7 @@ final class WP_Taxonomy {
 			'show_tagcloud'         => null,
 			'show_in_quick_edit'    => null,
 			'show_admin_column'     => false,
+			'show_column_sortable'  => false,
 			'meta_box_cb'           => null,
 			'meta_box_sanitize_cb'  => null,
 			'capabilities'          => array(),
diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php
index 370cb46ad5..38851ab3ec 100644
--- a/src/wp-includes/taxonomy.php
+++ b/src/wp-includes/taxonomy.php
@@ -67,6 +67,7 @@ function create_initial_taxonomies() {
 			'public'                => true,
 			'show_ui'               => true,
 			'show_admin_column'     => true,
+			'show_column_sortable'  => true,
 			'_builtin'              => true,
 			'capabilities'          => array(
 				'manage_terms' => 'manage_categories',
@@ -90,6 +91,7 @@ function create_initial_taxonomies() {
 			'public'                => true,
 			'show_ui'               => true,
 			'show_admin_column'     => true,
+			'show_column_sortable'  => true,
 			'_builtin'              => true,
 			'capabilities'          => array(
 				'manage_terms' => 'manage_post_tags',
-- 
2.23.0

From e7f9028de49328565e971805f902861b02bb8bed Mon Sep 17 00:00:00 2001
From: Cory Hughart <cory@blackbird.digital>
Date: Fri, 28 Feb 2020 15:33:25 -0500
Subject: [PATCH] fix posts with no taxonomy assigned not appearing

---
 .../includes/class-wp-posts-list-table.php    | 21 ++++++++++++-------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/wp-admin/includes/class-wp-posts-list-table.php b/src/wp-admin/includes/class-wp-posts-list-table.php
index 6744a9c6e0..dafe5ce7d2 100644
--- a/src/wp-admin/includes/class-wp-posts-list-table.php
+++ b/src/wp-admin/includes/class-wp-posts-list-table.php
@@ -159,15 +159,20 @@ class WP_Posts_List_Table extends WP_List_Table {
 			return $clauses;
 		}
 
-		$clauses['join'] .= "
-			LEFT OUTER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID={$wpdb->term_relationships}.object_id
-			LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id)
-			LEFT OUTER JOIN {$wpdb->terms} USING (term_id)
-		";
-		$clauses['where'] = $wpdb->prepare( " AND taxonomy = '%s'", $key );
-		$clauses['groupby'] = "object_id";
-		$clauses['orderby'] = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) ";
+		$clauses['join'] .= $wpdb->prepare( "
+			LEFT OUTER JOIN (
+				SELECT object_id, taxonomy, name
+				FROM {$wpdb->term_relationships}
+				LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id)
+				LEFT OUTER JOIN {$wpdb->terms} USING (term_id)
+				WHERE taxonomy = '%s'
+			) tax
+			ON {$wpdb->posts}.ID=tax.object_id
+		", $key );
+		$clauses['groupby'] = "{$wpdb->posts}.ID"; // term_taxonomy_id
+		$clauses['orderby'] = "GROUP_CONCAT(tax.name ORDER BY tax.name ASC) ";
 		$clauses['orderby'] .= ( 'ASC' == strtoupper( $wp_query->get('order') ) ) ? 'ASC' : 'DESC';
+		$clauses['orderby'] .= ", post_title ASC";
 
 		return $clauses;
 	}
-- 
2.23.0

