Skip to content

Commit

Permalink
feat: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lucymtc committed Mar 21, 2024
1 parent 626778e commit 5936925
Show file tree
Hide file tree
Showing 2 changed files with 292 additions and 122 deletions.
244 changes: 122 additions & 122 deletions wp/headless-wp/includes/classes/Integrations/YoastSEO.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,128 +42,6 @@ public function register() {
add_filter( 'rest_pre_echo_response' , [ $this, 'optimise_yoast_payload' ], 10, 3 );
}

/**
* Optimises the Yoast SEO payload in REST API responses.
*
* This method modifies the API response to reduce the payload size by removing
* the 'yoast_head' and 'yoast_json_head' fields from the response when they are
* not needed for the nextjs app.
* See https://github.com/10up/headstartwp/issues/563
*
* @param array $result The response data to be served, typically an array.
* @param \WP_REST_Server $server Server instance.
* @param \WP_REST_Request $request Request used to generate the response.
*
* @return array Modified response data.
*/
public function optimise_yoast_payload( $result, $server, $request ) {

$embed = isset( $_GET['_embed'] ) ? rest_parse_embed_param( $_GET['_embed'] ) : false;

if ( ! $embed ) {
return $result;
}

$first_post = true;

foreach ( $result as &$post_obj ) {

if ( ! empty( $post_obj['_embedded']['wp:term'] ) ) {
$this->optimise_yoast_payload_for_taxonomy( $post_obj['_embedded']['wp:term'], $request, $first_post );
}

if ( ! empty( $post_obj['_embedded']['author'] ) ) {
$this->optimise_yoast_payload_for_author( $post_obj['_embedded']['author'], $request, $first_post );
}

if ( ! $first_post ) {
unset( $post_obj['yoast_head'], $post_obj['yoast_head_json'] );
}

$first_post = false;
}

unset( $post_obj );

return $result;
}

/**
* Optimises the Yoast SEO payload for taxonomies.
* Removes yoast head from _embed terms for any term that is not in the queried params.
* Logic runs for the first post, yoast head metadata is removed completely for other posts.
*
* @param array $taxonomy_groups The _embedded wp:term collections.
* @param \WP_REST_Request $request Request used to generate the response.
* @param boolean $first_post Whether this is the first post in the response.
*
* @return void
*/
protected function optimise_yoast_payload_for_taxonomy( &$taxonomy_groups, $request, $first_post ) {

foreach ( $taxonomy_groups as &$taxonomy_group ) {

foreach ( $taxonomy_group as &$term_obj ) {

$param = null;

if ( $first_post ) {
// Get the queried terms for the taxonomy.
$param = $term_obj['taxonomy'] === 'category' ?
$request->get_param('category') ?? $request->get_param('categories') :
$request->get_param( $term_obj['taxonomy'] );
}

if ( $first_post && ! empty( $param ) ) {
$param = is_array( $param ) ? $param : explode( ',', $param );

// If the term slug is not in param array, unset yoast heads.
if ( ! in_array( $term_obj['slug'], $param, true ) && ! in_array( $term_obj['id'], $param, true ) ) {
unset( $term_obj['yoast_head'], $term_obj['yoast_head_json'] );
}
} else {
unset( $term_obj['yoast_head'], $term_obj['yoast_head_json'] );
}
}

unset( $term_obj );
}

unset( $taxonomy_group );
}

/**
* Optimises the Yoast SEO payload for author.
* Removes yoast head from _embed author for any author that is not in the queried params.
* Logic runs for the first post, yoast head metadata is removed completely for other posts.
*
* @param array $authors The _embedded author collections.
* @param \WP_REST_Request $request Request used to generate the response.
* @param boolean $first_post Whether this is the first post in the response.
*
* @return void
*/
protected function optimise_yoast_payload_for_author( &$authors, $request, $first_post ) {

foreach ( $authors as &$author ) {

$param = $first_post ? $request->get_param( 'author' ) : null;

if ( $first_post && ! empty( $param ) ) {
$param = is_array( $param ) ? $param : explode( ',', $param );

// If the term slug is not in param array, unset yoast heads.
if ( ! in_array( $author['slug'], $param, true ) && ! in_array( $author['id'], $param, true ) ) {
unset( $author['yoast_head'], $author['yoast_head_json'] );
}
} else {
unset( $author['yoast_head'], $author['yoast_head_json'] );
}
}

unset( $author );
}

/**
* Checks if Yoast SEO Urls should be rewritten
*
Expand Down Expand Up @@ -448,4 +326,126 @@ function ( $presenters ) {
}
);
}

/**
* Optimises the Yoast SEO payload in REST API responses.
*
* This method modifies the API response to reduce the payload size by removing
* the 'yoast_head' and 'yoast_json_head' fields from the response when they are
* not needed for the nextjs app.
* See https://github.com/10up/headstartwp/issues/563
*
* @param array $result The response data to be served, typically an array.
* @param \WP_REST_Server $server Server instance.
* @param \WP_REST_Request $request Request used to generate the response.
*
* @return array Modified response data.
*/
public function optimise_yoast_payload( $result, $server, $request, $embed = false ) {

$embed = $embed ?: rest_parse_embed_param( $_GET['_embed'] ?? false );

if ( ! $embed ) {
return $result;
}

$first_post = true;

foreach ( $result as &$post_obj ) {

if ( ! empty( $post_obj['_embedded']['wp:term'] ) ) {
$this->optimise_yoast_payload_for_taxonomy( $post_obj['_embedded']['wp:term'], $request, $first_post );
}

if ( ! empty( $post_obj['_embedded']['author'] ) ) {
$this->optimise_yoast_payload_for_author( $post_obj['_embedded']['author'], $request, $first_post );
}

if ( ! $first_post ) {
unset( $post_obj['yoast_head'], $post_obj['yoast_head_json'] );
}

$first_post = false;
}

unset( $post_obj );

return $result;
}

/**
* Optimises the Yoast SEO payload for taxonomies.
* Removes yoast head from _embed terms for any term that is not in the queried params.
* Logic runs for the first post, yoast head metadata is removed completely for other posts.
*
* @param array $taxonomy_groups The _embedded wp:term collections.
* @param \WP_REST_Request $request Request used to generate the response.
* @param boolean $first_post Whether this is the first post in the response.
*
* @return void
*/
protected function optimise_yoast_payload_for_taxonomy( &$taxonomy_groups, $request, $first_post ) {

foreach ( $taxonomy_groups as &$taxonomy_group ) {

foreach ( $taxonomy_group as &$term_obj ) {

$param = null;

if ( $first_post ) {
// Get the queried terms for the taxonomy.
$param = $term_obj['taxonomy'] === 'category' ?
$request->get_param('category') ?? $request->get_param('categories') :
$request->get_param( $term_obj['taxonomy'] );
}

if ( $first_post && ! empty( $param ) ) {
$param = is_array( $param ) ? $param : explode( ',', $param );

// If the term slug is not in param array, unset yoast heads.
if ( ! in_array( $term_obj['slug'], $param, true ) && ! in_array( $term_obj['id'], $param, true ) ) {
unset( $term_obj['yoast_head'], $term_obj['yoast_head_json'] );
}
} else {
unset( $term_obj['yoast_head'], $term_obj['yoast_head_json'] );
}
}

unset( $term_obj );
}

unset( $taxonomy_group );
}

/**
* Optimises the Yoast SEO payload for author.
* Removes yoast head from _embed author for any author that is not in the queried params.
* Logic runs for the first post, yoast head metadata is removed completely for other posts.
*
* @param array $authors The _embedded author collections.
* @param \WP_REST_Request $request Request used to generate the response.
* @param boolean $first_post Whether this is the first post in the response.
*
* @return void
*/
protected function optimise_yoast_payload_for_author( &$authors, $request, $first_post ) {

foreach ( $authors as &$author ) {

$param = $first_post ? $request->get_param( 'author' ) : null;

if ( $first_post && ! empty( $param ) ) {
$param = is_array( $param ) ? $param : explode( ',', $param );

// If the term slug is not in param array, unset yoast heads.
if ( ! in_array( $author['slug'], $param, true ) && ! in_array( $author['id'], $param, true ) ) {
unset( $author['yoast_head'], $author['yoast_head_json'] );
}
} else {
unset( $author['yoast_head'], $author['yoast_head_json'] );
}
}

unset( $author );
}
}
Loading

0 comments on commit 5936925

Please sign in to comment.