From c11c5d6db7962f5f1e3e990b4946d73af4f0ffc7 Mon Sep 17 00:00:00 2001 From: Leo Germani Date: Tue, 4 Oct 2022 18:26:14 -0300 Subject: [PATCH 01/10] exploring --- .../schema/third-party/coauthor.php | 63 ++++++++++++++++++- .../third-party/coauthors-plus.php | 29 +++++---- 2 files changed, 79 insertions(+), 13 deletions(-) diff --git a/src/generators/schema/third-party/coauthor.php b/src/generators/schema/third-party/coauthor.php index 49d09dd6e00..3fb41f7fada 100644 --- a/src/generators/schema/third-party/coauthor.php +++ b/src/generators/schema/third-party/coauthor.php @@ -2,8 +2,10 @@ namespace Yoast\WP\SEO\Generators\Schema\Third_Party; +use Yoast\WP\SEO\Config\Schema_IDs; use Yoast\WP\SEO\Generators\Schema\Author; + /** * Returns schema Author data for the CoAuthor Plus assigned user on a post. */ @@ -12,7 +14,7 @@ class CoAuthor extends Author { /** * The user ID of the author we're generating data for. * - * @var int + * @var int $user_id */ private $user_id; @@ -62,6 +64,31 @@ public function generate_from_user_id( $user_id ) { return $this->generate(); } + /** + * Generate the Person data given a user ID. + * + * @param int $user_id User ID. + * + * @return array|bool + */ + public function generate_from_guest_author( $guest_author ) { + $this->user_id = $user_id; + + $data = $this->build_person_data_for_guest_author( $guest_author, true ); + + $data['@type'] = 'Person'; + unset( $data['logo'] ); + + // If this is a post and the author archives are enabled, set the author archive url as the author url. + // if ( $this->helpers->options->get( 'disable-author' ) !== true ) { + // $data['url'] = $this->helpers->user->get_the_author_posts_url( $user_id ); + // } + + return $data; + + //return $this->generate(); + } + /** * Determines a User ID for the Person data. * @@ -70,4 +97,38 @@ public function generate_from_user_id( $user_id ) { protected function determine_user_id() { return $this->user_id; } + + /** + * Builds our array of Schema Person data for a given user ID. + * + * @param int $user_id The user ID to use. + * @param bool $add_hash Wether or not the person's image url hash should be added to the image id. + * + * @return array An array of Schema Person data. + */ + protected function build_person_data_for_guest_author( $guest_author, $add_hash = false ) { + $data = [ + '@type' => $this->type, + '@id' => $this->context->site_url . Schema_IDs::PERSON_HASH . \wp_hash( $guest_author->user_login . $guest_author->ID . 'guest' ), + ]; + + $data['name'] = $this->helpers->schema->html->smart_strip_tags( $guest_author->display_name ); + //$data = $this->add_image( $data, $guest_author, $add_hash ); + + if ( ! empty( $guest_author->description ) ) { + $data['description'] = $this->helpers->schema->html->smart_strip_tags( $guest_author->description ); + } + + //$data = $this->add_same_as_urls( $data, $guest_author, $user_id ); + + /** + * Filter: 'wpseo_schema_person_data' - Allows filtering of schema data per user. + * + * @param array $data The schema data we have for this person. + * @param int $user_id The current user we're collecting schema data for. + */ + //$data = \apply_filters( 'wpseo_schema_person_data', $data, $user_id );generate_from_guest_author + + return $data; + } } diff --git a/src/integrations/third-party/coauthors-plus.php b/src/integrations/third-party/coauthors-plus.php index 32b577463e4..e7dab9ddc92 100644 --- a/src/integrations/third-party/coauthors-plus.php +++ b/src/integrations/third-party/coauthors-plus.php @@ -2,10 +2,9 @@ namespace Yoast\WP\SEO\Integrations\Third_Party; -use WP_User; +use Yoast\WP\SEO\Config\Schema_Types; use Yoast\WP\SEO\Conditionals\Third_Party\CoAuthors_Plus_Activated_Conditional; use Yoast\WP\SEO\Conditionals\Third_Party\CoAuthors_Plus_Flag_Conditional; -use Yoast\WP\SEO\Config\Schema_Types; use Yoast\WP\SEO\Context\Meta_Tags_Context; use Yoast\WP\SEO\Generators\Schema\Abstract_Schema_Piece; use Yoast\WP\SEO\Generators\Schema\Third_Party\CoAuthor; @@ -103,29 +102,35 @@ public function filter_graph( $data, $context ) { /** * Contains the authors from the CoAuthors Plus plugin. * - * @var WP_User[] $author_objects + * @var \WP_User[] $author_objects */ $author_objects = \get_coauthors( $context->post->ID ); - if ( \count( $author_objects ) <= 1 ) { - return $data; - } + //var_dump($author_objects ); die; + // if ( \count( $author_objects ) <= 1 ) { + // return $data; + // } $ids = []; // Add the authors to the schema. foreach ( $author_objects as $author ) { - if ( $author->ID === (int) $context->post->post_author ) { - continue; - } + //var_dump($author->ID, $context->post); die; + // if ( $author->ID === (int) $context->post->post_author ) { + // continue; + // } $author_generator = new CoAuthor(); $author_generator->context = $context; $author_generator->helpers = $this->helpers; - $author_data = $author_generator->generate_from_user_id( $author->ID ); + //var_dump($author instanceof \WP_User); die; + if ( $author instanceof \WP_User ) { + $author_data = $author_generator->generate_from_user_id( $author->ID ); + } elseif ( ! empty( $author->type ) && 'guest-author' === $author->type ) { + $author_data = $author_generator->generate_from_guest_author( $author ); + } if ( ! empty( $author_data ) ) { $ids[] = [ '@id' => $author_data['@id'] ]; } } - $schema_types = new Schema_Types(); $article_types = $schema_types->get_article_type_options_values(); @@ -133,7 +138,7 @@ public function filter_graph( $data, $context ) { $add_to_graph = false; foreach ( $data as $key => $piece ) { if ( \in_array( $piece['@type'], $article_types, true ) ) { - $data[ $key ]['author'] = \array_merge( [ $piece['author'] ], $ids ); + $data[ $key ]['author'] = $ids; //\array_merge( [ $piece['author'] ], $ids ); $add_to_graph = true; break; } From 93d4965116fb89b007c72e386a01f9c94017dafe Mon Sep 17 00:00:00 2001 From: Leo Germani Date: Wed, 5 Oct 2022 15:03:14 -0300 Subject: [PATCH 02/10] wrap up basic support --- .../schema/third-party/coauthor.php | 39 ++++++++++++------- .../third-party/coauthors-plus.php | 36 +++++++++-------- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/generators/schema/third-party/coauthor.php b/src/generators/schema/third-party/coauthor.php index 3fb41f7fada..cae781efeaf 100644 --- a/src/generators/schema/third-party/coauthor.php +++ b/src/generators/schema/third-party/coauthor.php @@ -65,9 +65,9 @@ public function generate_from_user_id( $user_id ) { } /** - * Generate the Person data given a user ID. + * Generate the Person data given a Guest Author object. * - * @param int $user_id User ID. + * @param object $guest_author The Guest Author object. * * @return array|bool */ @@ -80,13 +80,11 @@ public function generate_from_guest_author( $guest_author ) { unset( $data['logo'] ); // If this is a post and the author archives are enabled, set the author archive url as the author url. - // if ( $this->helpers->options->get( 'disable-author' ) !== true ) { - // $data['url'] = $this->helpers->user->get_the_author_posts_url( $user_id ); - // } + if ( $this->helpers->options->get( 'disable-author' ) !== true ) { + $data['url'] = \get_author_posts_url( $guest_author->ID, $guest_author->user_nicename ); + } return $data; - - //return $this->generate(); } /** @@ -99,27 +97,40 @@ protected function determine_user_id() { } /** - * Builds our array of Schema Person data for a given user ID. + * Builds our array of Schema Person data for a given Guest Author. * - * @param int $user_id The user ID to use. - * @param bool $add_hash Wether or not the person's image url hash should be added to the image id. + * @param object $guest_author The Guest Author object. + * @param bool $add_hash Wether or not the person's image url hash should be added to the image id. * * @return array An array of Schema Person data. */ protected function build_person_data_for_guest_author( $guest_author, $add_hash = false ) { + $schema_id = $this->context->site_url . Schema_IDs::PERSON_LOGO_HASH; $data = [ '@type' => $this->type, - '@id' => $this->context->site_url . Schema_IDs::PERSON_HASH . \wp_hash( $guest_author->user_login . $guest_author->ID . 'guest' ), + '@id' => $schema_id . \wp_hash( $guest_author->user_login . $guest_author->ID . 'guest' ), ]; $data['name'] = $this->helpers->schema->html->smart_strip_tags( $guest_author->display_name ); - //$data = $this->add_image( $data, $guest_author, $add_hash ); + + $data = $this->set_image_from_avatar( $data, $guest_author, $schema_id, $add_hash ); + + // If local avatar is present, override. + $avatar_meta = \wp_get_attachment_image_src( get_post_thumbnail_id( $guest_author->ID ) ); + if ( $avatar_meta ) { + $avatar_meta = [ + 'url' => $avatar_meta[0], + 'width' => $avatar_meta[1], + 'height' => $avatar_meta[2], + ]; + $data['image'] = $this->helpers->schema->image->generate_from_attachment_meta( $schema_id, $avatar_meta, $data['name'], $add_hash ); + } if ( ! empty( $guest_author->description ) ) { $data['description'] = $this->helpers->schema->html->smart_strip_tags( $guest_author->description ); } - //$data = $this->add_same_as_urls( $data, $guest_author, $user_id ); + $data = $this->add_same_as_urls( $data, $guest_author, $user_id ); /** * Filter: 'wpseo_schema_person_data' - Allows filtering of schema data per user. @@ -127,7 +138,7 @@ protected function build_person_data_for_guest_author( $guest_author, $add_hash * @param array $data The schema data we have for this person. * @param int $user_id The current user we're collecting schema data for. */ - //$data = \apply_filters( 'wpseo_schema_person_data', $data, $user_id );generate_from_guest_author + $data = \apply_filters( 'wpseo_schema_person_data', $data, $user_id ); return $data; } diff --git a/src/integrations/third-party/coauthors-plus.php b/src/integrations/third-party/coauthors-plus.php index e7dab9ddc92..4c21aad0835 100644 --- a/src/integrations/third-party/coauthors-plus.php +++ b/src/integrations/third-party/coauthors-plus.php @@ -105,30 +105,26 @@ public function filter_graph( $data, $context ) { * @var \WP_User[] $author_objects */ $author_objects = \get_coauthors( $context->post->ID ); - //var_dump($author_objects ); die; - // if ( \count( $author_objects ) <= 1 ) { - // return $data; - // } - $ids = []; + $ids = []; + $authors = []; // Add the authors to the schema. foreach ( $author_objects as $author ) { - //var_dump($author->ID, $context->post); die; - // if ( $author->ID === (int) $context->post->post_author ) { - // continue; - // } $author_generator = new CoAuthor(); $author_generator->context = $context; $author_generator->helpers = $this->helpers; - //var_dump($author instanceof \WP_User); die; + if ( $author instanceof \WP_User ) { - $author_data = $author_generator->generate_from_user_id( $author->ID ); - } elseif ( ! empty( $author->type ) && 'guest-author' === $author->type ) { - $author_data = $author_generator->generate_from_guest_author( $author ); + $author_data = $author_generator->generate_from_user_id( $author->ID ); + } + elseif ( ! empty( $author->type ) && $author->type === 'guest-author' ) { + $author_data = $author_generator->generate_from_guest_author( $author ); } + if ( ! empty( $author_data ) ) { - $ids[] = [ '@id' => $author_data['@id'] ]; + $ids[] = [ '@id' => $author_data['@id'] ]; + $authors[] = $author_data; } } $schema_types = new Schema_Types(); @@ -138,16 +134,24 @@ public function filter_graph( $data, $context ) { $add_to_graph = false; foreach ( $data as $key => $piece ) { if ( \in_array( $piece['@type'], $article_types, true ) ) { - $data[ $key ]['author'] = $ids; //\array_merge( [ $piece['author'] ], $ids ); + $data[ $key ]['author'] = $ids; $add_to_graph = true; break; } } if ( $add_to_graph ) { + // Clean all Persons from the schema, as the user stored as post owner might be incorrectly added if the post post has only guest authors as authors. + $data = array_filter( + $data, + function( $piece ) { + return empty( $piece['@type'] ) || $piece['@type'] !== 'Person'; + } + ); + if ( ! empty( $author_data ) ) { if ( $context->site_represents !== 'person' || $author->ID !== $context->site_user_id ) { - $data[] = $author_data; + $data = array_merge( $data, $authors ); } } } From a618c90ca2745983d542907289c371bbfd652e79 Mon Sep 17 00:00:00 2001 From: Leo Germani Date: Tue, 18 Oct 2022 16:39:18 -0300 Subject: [PATCH 03/10] Add support in author meta tag --- .../third-party/coauthors-plus.php | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/integrations/third-party/coauthors-plus.php b/src/integrations/third-party/coauthors-plus.php index 4c21aad0835..9e7d87948ac 100644 --- a/src/integrations/third-party/coauthors-plus.php +++ b/src/integrations/third-party/coauthors-plus.php @@ -31,6 +31,7 @@ class CoAuthors_Plus implements Integration_Interface { public function register_hooks() { \add_filter( 'wpseo_schema_graph', [ $this, 'filter_graph' ], 11, 2 ); \add_filter( 'wpseo_schema_author', [ $this, 'filter_author_graph' ], 11, 4 ); + \add_filter( 'wpseo_meta_author', [ $this, 'filter_author_meta' ], 11, 2 ); } /** @@ -158,4 +159,29 @@ function( $piece ) { return $data; } + + /** + * Filters the author meta tag + * + * @param string $author_name The article author's display name. Return empty to disable the tag. + * @param Indexable_Presentation $presentation The presentation of an indexable. + * @return string + */ + public function filter_author_meta( $author_name, $presentation ) { + $author_objects = \get_coauthors( $presentation->context->post->id ); + + // Fallback in case of error. + if ( empty( $author_objects ) ) { + return $author_name; + } + + $output = ''; + foreach ( $author_objects as $i => $author ) { + $output .= $author->display_name; + if ( $i <= ( count( $author_objects ) - 2 ) ) { + $output .= ', '; + } + } + return $output; + } } From b735e296f6b7fdeae3936c115f95df2564cbc86d Mon Sep 17 00:00:00 2001 From: Leo Germani Date: Wed, 19 Oct 2022 11:34:47 -0300 Subject: [PATCH 04/10] support guest author archive page --- .../third-party/coauthors-plus.php | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/integrations/third-party/coauthors-plus.php b/src/integrations/third-party/coauthors-plus.php index 9e7d87948ac..31ec312f15e 100644 --- a/src/integrations/third-party/coauthors-plus.php +++ b/src/integrations/third-party/coauthors-plus.php @@ -31,6 +31,7 @@ class CoAuthors_Plus implements Integration_Interface { public function register_hooks() { \add_filter( 'wpseo_schema_graph', [ $this, 'filter_graph' ], 11, 2 ); \add_filter( 'wpseo_schema_author', [ $this, 'filter_author_graph' ], 11, 4 ); + \add_filter( 'wpseo_schema_profilepage', [ $this, 'filter_schema_profilepage' ], 11, 4 ); \add_filter( 'wpseo_meta_author', [ $this, 'filter_author_meta' ], 11, 2 ); } @@ -57,6 +58,36 @@ public function __construct( Helpers_Surface $helpers ) { $this->helpers = $helpers; } + /** + * Filters the graph output of authors archive for guest authors. + * + * @param array $data The schema graph. + * @param Meta_Tags_Context $context The context object. + * @param Abstract_Schema_Piece $graph_piece_generator The graph piece generator. + * @param Abstract_Schema_Piece[] $graph_piece_generators The graph piece generators. + * + * @return array The (potentially altered) schema graph. + */ + public function filter_schema_profilepage( $data, $context, $graph_piece_generator, $graph_piece_generators ) { + + if ( ! is_author() ) { + return $data; + } + + $user = get_queried_object(); + + if ( empty( $user->type ) || $user->type !== 'guest-author' ) { + return $data; + } + + // Fix author URL. + $author_url = get_author_posts_url( $user->ID ); + $graph_piece_generator->context->canonical = $author_url; + $graph_piece_generator->context->main_schema_id = $author_url; + + return $graph_piece_generator->generate(); + } + /** * Filters the graph output to add authors. * From 29647ffbf25d0e2f1b758da9ba0e5ab24e18b089 Mon Sep 17 00:00:00 2001 From: leogermani Date: Thu, 20 Oct 2022 08:22:14 -0300 Subject: [PATCH 05/10] Update src/generators/schema/third-party/coauthor.php Co-authored-by: Joost de Valk --- src/generators/schema/third-party/coauthor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generators/schema/third-party/coauthor.php b/src/generators/schema/third-party/coauthor.php index cae781efeaf..d231d98df1a 100644 --- a/src/generators/schema/third-party/coauthor.php +++ b/src/generators/schema/third-party/coauthor.php @@ -116,7 +116,7 @@ protected function build_person_data_for_guest_author( $guest_author, $add_hash $data = $this->set_image_from_avatar( $data, $guest_author, $schema_id, $add_hash ); // If local avatar is present, override. - $avatar_meta = \wp_get_attachment_image_src( get_post_thumbnail_id( $guest_author->ID ) ); + $avatar_meta = \wp_get_attachment_image_src( \get_post_thumbnail_id( $guest_author->ID ) ); if ( $avatar_meta ) { $avatar_meta = [ 'url' => $avatar_meta[0], From 004d6156219c9a8e56066b0e38d40084e87bffd9 Mon Sep 17 00:00:00 2001 From: leogermani Date: Thu, 20 Oct 2022 08:22:24 -0300 Subject: [PATCH 06/10] Update src/integrations/third-party/coauthors-plus.php Co-authored-by: Joost de Valk --- src/integrations/third-party/coauthors-plus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/integrations/third-party/coauthors-plus.php b/src/integrations/third-party/coauthors-plus.php index 31ec312f15e..28fd93a40f3 100644 --- a/src/integrations/third-party/coauthors-plus.php +++ b/src/integrations/third-party/coauthors-plus.php @@ -74,7 +74,7 @@ public function filter_schema_profilepage( $data, $context, $graph_piece_generat return $data; } - $user = get_queried_object(); + $user = \get_queried_object(); if ( empty( $user->type ) || $user->type !== 'guest-author' ) { return $data; From e94cfd46b2e7d9a63c2870703b4a1f062ab83830 Mon Sep 17 00:00:00 2001 From: leogermani Date: Thu, 20 Oct 2022 08:23:02 -0300 Subject: [PATCH 07/10] Update src/integrations/third-party/coauthors-plus.php Co-authored-by: Joost de Valk --- src/integrations/third-party/coauthors-plus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/integrations/third-party/coauthors-plus.php b/src/integrations/third-party/coauthors-plus.php index 28fd93a40f3..29b86ebbc28 100644 --- a/src/integrations/third-party/coauthors-plus.php +++ b/src/integrations/third-party/coauthors-plus.php @@ -183,7 +183,7 @@ function( $piece ) { if ( ! empty( $author_data ) ) { if ( $context->site_represents !== 'person' || $author->ID !== $context->site_user_id ) { - $data = array_merge( $data, $authors ); + $data = \array_merge( $data, $authors ); } } } From f0b764124a441147dba559d0c403b37dfca6cf8a Mon Sep 17 00:00:00 2001 From: leogermani Date: Thu, 20 Oct 2022 08:23:34 -0300 Subject: [PATCH 08/10] Update src/integrations/third-party/coauthors-plus.php Co-authored-by: Joost de Valk --- src/integrations/third-party/coauthors-plus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/integrations/third-party/coauthors-plus.php b/src/integrations/third-party/coauthors-plus.php index 29b86ebbc28..420ccaf611c 100644 --- a/src/integrations/third-party/coauthors-plus.php +++ b/src/integrations/third-party/coauthors-plus.php @@ -81,7 +81,7 @@ public function filter_schema_profilepage( $data, $context, $graph_piece_generat } // Fix author URL. - $author_url = get_author_posts_url( $user->ID ); + $author_url = \get_author_posts_url( $user->ID ); $graph_piece_generator->context->canonical = $author_url; $graph_piece_generator->context->main_schema_id = $author_url; From 361d610129c91e9129c9cda63140d1c1c2dd3897 Mon Sep 17 00:00:00 2001 From: leogermani Date: Thu, 20 Oct 2022 08:23:43 -0300 Subject: [PATCH 09/10] Update src/integrations/third-party/coauthors-plus.php Co-authored-by: Joost de Valk --- src/integrations/third-party/coauthors-plus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/integrations/third-party/coauthors-plus.php b/src/integrations/third-party/coauthors-plus.php index 420ccaf611c..09af2319e9e 100644 --- a/src/integrations/third-party/coauthors-plus.php +++ b/src/integrations/third-party/coauthors-plus.php @@ -174,7 +174,7 @@ public function filter_graph( $data, $context ) { if ( $add_to_graph ) { // Clean all Persons from the schema, as the user stored as post owner might be incorrectly added if the post post has only guest authors as authors. - $data = array_filter( + $data = \array_filter( $data, function( $piece ) { return empty( $piece['@type'] ) || $piece['@type'] !== 'Person'; From b8d4c3652e30643641f6d5a7c2cc37cfc07205ad Mon Sep 17 00:00:00 2001 From: Leo Germani Date: Thu, 20 Oct 2022 08:53:13 -0300 Subject: [PATCH 10/10] Avoid conflict between guest author and user ids --- src/integrations/third-party/coauthors-plus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/integrations/third-party/coauthors-plus.php b/src/integrations/third-party/coauthors-plus.php index 09af2319e9e..4654f819063 100644 --- a/src/integrations/third-party/coauthors-plus.php +++ b/src/integrations/third-party/coauthors-plus.php @@ -81,7 +81,7 @@ public function filter_schema_profilepage( $data, $context, $graph_piece_generat } // Fix author URL. - $author_url = \get_author_posts_url( $user->ID ); + $author_url = \get_author_posts_url( $user->ID, $user->user_nicename ); $graph_piece_generator->context->canonical = $author_url; $graph_piece_generator->context->main_schema_id = $author_url;