diff --git a/.travis.yml b/.travis.yml index fea742a8..28765d3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,35 +1,30 @@ language: php php: - - "nightly" + - 7.1 env: - WP_VERSION=latest +matrix: matrix: include: -# nightly+latest already included above as first build. -# - php: "nightly" -# env: WP_VERSION=latest - - php: "nightly" - env: WP_VERSION=4.6 - - php: "nightly" - env: WP_VERSION=4.5 - php: "5.2" env: WP_VERSION=latest - php: "5.2" env: WP_VERSION=4.6 - - php: "5.2" - env: WP_VERSION=4.5 - - php: "5.6" - env: WP_VERSION=latest - php: "5.6" env: - - WP_VERSION=4.6 + - WP_VERSION=latest - SNIFF=1 - php: "5.6" - env: WP_VERSION=4.5 - - php: "7" + env: WP_VERSION=4.6 + - php: "7.0" + env: WP_VERSION=latest + - php: "7.0" + env: WP_VERSION=4.6 + # 7.1 / latest already included above as first build. + - php: "7.1" env: WP_VERSION=4.6 before_script: @@ -48,6 +43,15 @@ before_script: - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/scripts/phpcs --config-set installed_paths $SNIFFS_DIR; fi # After CodeSniffer install you should refresh your path. - if [[ "$SNIFF" == "1" ]]; then phpenv rehash; fi + # Properly handle PHPunit versions + - export PATH="$HOME/.composer/vendor/bin:$PATH" + - | + if [[ ${TRAVIS_PHP_VERSION:0:2} == "7." ]]; then + composer global require "phpunit/phpunit=5.7.*" + elif [[ ${TRAVIS_PHP_VERSION:0:3} != "5.2" ]]; then + composer global require "phpunit/phpunit=4.8.*" + fi + - phpunit --version script: # Search for PHP syntax errors. diff --git a/co-authors-plus.php b/co-authors-plus.php index ad68feb4..66b18e0c 100644 --- a/co-authors-plus.php +++ b/co-authors-plus.php @@ -119,6 +119,7 @@ function __construct() { // Delete CoAuthor Cache on Post Save & Post Delete add_action( 'save_post', array( $this, 'clear_cache') ); add_action( 'delete_post', array( $this, 'clear_cache') ); + add_action( 'set_object_terms', array( $this, 'clear_cache_on_terms_set' ), 10, 6 ); } /** @@ -1473,6 +1474,42 @@ public function filter_jetpack_open_graph_tags( $og_tags, $image_dimensions ) { return apply_filters( 'coauthors_open_graph_tags', $og_tags ); } + /** + * Retrieve a list of coauthor terms for a single post. + * + * Grabs a correctly ordered list of authors for a single post, appropriately + * cached because it requires `wp_get_object_terms()` to succeed. + * + * @param int $post_id ID of the post for which to retrieve authors. + * @return array Array of coauthor WP_Term objects + */ + public function get_coauthor_terms_for_post( $post_id ) { + + if ( ! $post_id ) { + return array(); + } + + $cache_key = 'coauthors_post_' . $post_id; + $coauthor_terms = wp_cache_get( $cache_key, 'co-authors-plus' ); + + if ( false === $coauthor_terms ) { + $coauthor_terms = wp_get_object_terms( $post_id, $this->coauthor_taxonomy, array( + 'orderby' => 'term_order', + 'order' => 'ASC', + ) ); + + // This usually happens if the taxonomy doesn't exist, which should never happen, but you never know. + if ( is_wp_error( $coauthor_terms ) ) { + return array(); + } + + wp_cache_set( $cache_key, $coauthor_terms, 'co-authors-plus' ); + } + + return $coauthor_terms; + + } + /** * Callback to clear the cache on post save and post delete. * @@ -1481,6 +1518,23 @@ public function filter_jetpack_open_graph_tags( $og_tags, $image_dimensions ) { public function clear_cache( $post_id ) { wp_cache_delete( 'coauthors_post_' . $post_id, 'co-authors-plus' ); } + + /** + * Callback to clear the cache when an object's terms are changed. + * + * @param $post_id The Post ID. + */ + public function clear_cache_on_terms_set( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ) { + + // We only care about the coauthors taxonomy + if ( $this->coauthor_taxonomy !== $taxonomy ) { + return; + } + + wp_cache_delete( 'coauthors_post_' . $object_id, 'co-authors-plus' ); + + } + } global $coauthors_plus; @@ -1624,3 +1678,17 @@ function cap_filter_comment_moderation_email_recipients( $recipients, $comment_i } return $recipients; } + +/** + * Retrieve a list of coauthor terms for a single post. + * + * Grabs a correctly ordered list of authors for a single post, appropriately + * cached because it requires `wp_get_object_terms()` to succeed. + * + * @param int $post_id ID of the post for which to retrieve authors. + * @return array Array of coauthor WP_Term objects + */ +function cap_get_coauthor_terms_for_post( $post_id ) { + global $coauthors_plus; + return $coauthors_plus->get_coauthor_terms_for_post( $post_id ); +} diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 9b334317..568f988e 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -76,10 +76,9 @@ public function create_terms_for_posts() { $count++; - $terms = get_the_terms( $single_post->ID, $coauthors_plus->coauthor_taxonomy ); - - if ( is_wp_error( $terms ) ) { - WP_CLI::error( $terms->get_error_message() ); + $terms = cap_get_coauthor_terms_for_post( $single_post->ID ); + if ( empty( $terms ) ) { + WP_CLI::error( sprintf( 'No co-authors found for post #%d.', $single_post->ID ) ); } if ( ! empty( $terms ) ) { @@ -236,8 +235,13 @@ public function assign_user_to_coauthor( $args, $assoc_args ) { $posts = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author=%d AND post_type IN ('$post_types')", $user->ID ) ); $affected = 0; foreach ( $posts as $post_id ) { - if ( $coauthors = get_the_terms( $post_id, $coauthors_plus->coauthor_taxonomy ) ) { - WP_CLI::line( sprintf( __( 'Skipping - Post #%d already has co-authors assigned: %s', 'co-authors-plus' ), $post_id, implode( ', ', wp_list_pluck( $coauthors, 'slug' ) ) ) ); + $coauthors = cap_get_coauthor_terms_for_post( $post_id ); + if ( ! empty( $coauthors ) ) { + WP_CLI::line( sprintf( + __( 'Skipping - Post #%d already has co-authors assigned: %s', 'co-authors-plus' ), + $post_id, + implode( ', ', wp_list_pluck( $coauthors, 'slug' ) ) + ) ); continue; } @@ -545,8 +549,8 @@ public function list_posts_without_terms( $args, $assoc_args ) { while ( $posts->post_count ) { foreach ( $posts->posts as $single_post ) { - - $terms = get_the_terms( $single_post->ID, $coauthors_plus->coauthor_taxonomy ); + + $terms = cap_get_coauthor_terms_for_post( $single_post->ID ); if ( empty( $terms ) ) { $saved = array( $single_post->ID, @@ -698,9 +702,9 @@ public function remove_terms_from_revisions() { WP_CLI::line( 'Found ' . count( $ids ) . ' revisions to look through' ); $affected = 0; foreach ( $ids as $post_id ) { - - $terms = get_the_terms( $post_id, $coauthors_plus->coauthor_taxonomy ); - if ( ! $terms ) { + + $terms = cap_get_coauthor_terms_for_post( $post_id ); + if ( empty( $terms ) ) { continue; } diff --git a/template-tags.php b/template-tags.php index a5cd99ab..ffc398ae 100644 --- a/template-tags.php +++ b/template-tags.php @@ -14,11 +14,7 @@ function get_coauthors( $post_id = 0 ) { } if ( $post_id ) { - $cache_key = 'coauthors_post_' . $post_id; - if ( false === ( $coauthor_terms = wp_cache_get( $cache_key, 'co-authors-plus' ) ) ) { - $coauthor_terms = wp_get_object_terms( $post_id, $coauthors_plus->coauthor_taxonomy, array( 'orderby' => 'term_order', 'order' => 'ASC' ) ); - wp_cache_set( $cache_key, $coauthor_terms, 'co-authors-plus' ); - } + $coauthor_terms = cap_get_coauthor_terms_for_post( $post_id ); if ( is_array( $coauthor_terms ) && ! empty( $coauthor_terms ) ) { foreach ( $coauthor_terms as $coauthor ) { $coauthor_slug = preg_replace( '#^cap\-#', '', $coauthor->slug ); diff --git a/tests/test-author-queried-object.php b/tests/test-author-queried-object.php index 94e357f8..25689cf5 100644 --- a/tests/test-author-queried-object.php +++ b/tests/test-author-queried-object.php @@ -5,6 +5,20 @@ class Test_Author_Queried_Object extends CoAuthorsPlus_TestCase { + /** + * Set up for test + * + * Don't create tables as 'temporary'. + * + * @see https://github.com/Automattic/Co-Authors-Plus/issues/398 + */ + function setUp() { + parent::setUp(); + + remove_filter( 'query', array( $this, '_create_temporary_tables' ) ); + remove_filter( 'query', array( $this, '_drop_temporary_tables' ) ); + } + /** * On author pages, the queried object should only be set * to a user that's not a member of the blog if they