Skip to content

Commit

Permalink
feat: support Newspack Sponsors for listings (#65)
Browse files Browse the repository at this point in the history
* feat: support Newspack Sponsors

* refactor: response object with author and sponsors

* fix: sponsors for queried listings
  • Loading branch information
dkoo authored Jun 15, 2021
1 parent 29b0a34 commit 7d2ef64
Show file tree
Hide file tree
Showing 8 changed files with 349 additions and 141 deletions.
184 changes: 113 additions & 71 deletions includes/class-newspack-listings-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
* Sets up API endpoints and handlers for listings.
*/
final class Newspack_Listings_Api {
/**
* REST route namespace.
*
* @var Newspack_Listings_Api
*/
protected static $namespace = 'newspack-listings/v1';

/**
* The single instance of the class.
Expand Down Expand Up @@ -56,20 +62,50 @@ public static function register_routes() {

// GET listings posts by ID, query args, or title search term.
register_rest_route(
'newspack-listings/v1',
self::$namespace,
'listings',
[
[
'methods' => \WP_REST_Server::READABLE,
'callback' => [ __CLASS__, 'get_items' ],
'args' => [
'query' => [
'sanitize_callback' => '\Newspack_Listings\Utils\sanitize_array',
],
'id' => [
'sanitize_callback' => 'absint',
],
'type' => [
'sanitize_callback' => '\Newspack_Listings\Utils\sanitize_array',
],
'attributes' => [
'sanitize_callback' => '\Newspack_Listings\Utils\sanitize_array',
],
'offset' => [
'sanitize_callback' => 'absint',
],
'page' => [
'sanitize_callback' => 'absint',
],
'per_page' => [
'sanitize_callback' => 'absint',
],
'search' => [
'sanitize_callback' => 'sanitize_text_field',
],
'_fields' => [
'sanitize_callback' => 'sanitize_text_field',
],

],
'permission_callback' => '__return_true',
],
]
);

// GET listings taxonomy terms by name search term.
register_rest_route(
'newspack-listings/v1',
self::$namespace,
'terms',
[
[
Expand All @@ -82,7 +118,7 @@ public static function register_routes() {

// GET listings taxonomy terms by name search term.
register_rest_route(
'newspack-listings/v1',
self::$namespace,
'children',
[
[
Expand All @@ -95,7 +131,7 @@ public static function register_routes() {

// Set listings taxonomy terms.
register_rest_route(
'newspack-listings/v1',
self::$namespace,
'children',
[
[
Expand Down Expand Up @@ -254,6 +290,7 @@ public static function build_listings_query( $query, $args = [] ) {
* @return WP_REST_Response.
*/
public static function get_items( $request ) {
$response = [];
$params = $request->get_params();
$fields = explode( ',', $params['_fields'] );
$search = ! empty( $params['search'] ) ? $params['search'] : null;
Expand Down Expand Up @@ -297,81 +334,88 @@ public static function get_items( $request ) {
$listings_query = new \WP_Query( $args );

if ( $listings_query->have_posts() ) {
$response = new \WP_REST_Response(
array_map(
function( $post ) use ( $attributes, $fields, $is_amp, $next_page, $query ) {
$item = [
'id' => $post->ID,
'title' => $post->post_title,
];

// if $fields includes html, get rendered HTML for the post.
if ( in_array( 'html', $fields ) && ! empty( $attributes ) ) {
$html = Utils\template_include(
'listing',
[
'attributes' => $attributes,
'post' => $post,
]
);

// If an AMP page, convert to valid AMP HTML.
if ( $is_amp ) {
$html = Utils\generate_amp_partial( $html );
}

$item['html'] = $html;
$listings = array_map(
function( $post ) use ( $attributes, $fields, $is_amp, $next_page, $query ) {
$item = [
'id' => $post->ID,
'title' => $post->post_title,
];

// if $fields includes html, get rendered HTML for the post.
if ( in_array( 'html', $fields ) && ! empty( $attributes ) ) {
$html = Utils\template_include(
'listing',
[
'attributes' => $attributes,
'post' => $post,
]
);

// If an AMP page, convert to valid AMP HTML.
if ( $is_amp ) {
$html = Utils\generate_amp_partial( $html );
}

// If $fields includes category, get the post categories.
if ( in_array( 'category', $fields ) ) {
$item['category'] = get_the_terms( $post->ID, 'category' );
}

// If $fields includes tags, get the post tags.
if ( in_array( 'tags', $fields ) ) {
$item['tags'] = get_the_terms( $post->ID, 'post_tag' );
}
$item['html'] = $html;
}

// If $fields includes category, get the post categories.
if ( in_array( 'category', $fields ) ) {
$item['category'] = get_the_terms( $post->ID, 'category' );
}

// If $fields includes tags, get the post tags.
if ( in_array( 'tags', $fields ) ) {
$item['tags'] = get_the_terms( $post->ID, 'post_tag' );
}

// If $fields includes excerpt, get the post excerpt.
if ( in_array( 'excerpt', $fields ) ) {
$item['excerpt'] = Utils\get_listing_excerpt( $post );
}

// If $fields includes media, get the featured image + caption.
if ( in_array( 'media', $fields ) ) {
$item['media'] = [
'image' => get_the_post_thumbnail_url( $post->ID, 'medium' ),
'caption' => get_the_post_thumbnail_caption( $post->ID ),
];
}

// If $fields includes author and the post isn't set to hide author, get the post author.
if ( in_array( 'author', $fields ) && empty( get_post_meta( $post->ID, 'newspack_listings_hide_author', true ) ) ) {
$item['author'] = get_the_author_meta( 'display_name', $post->post_author );
}
// If $fields includes meta, get all Newspack Listings meta fields.
if ( in_array( 'meta', $fields ) || in_array( 'author', $fields ) ) {
$item['meta'] = [];
$post_meta = Core::get_meta_values( $post->ID, $post->post_type );

// If $fields includes excerpt, get the post excerpt.
if ( in_array( 'excerpt', $fields ) ) {
$item['excerpt'] = Utils\get_listing_excerpt( $post );
if ( ! empty( $post_meta ) ) {
$item['meta'] = $post_meta;
}
}

// If $fields includes media, get the featured image + caption.
if ( in_array( 'media', $fields ) ) {
$item['media'] = [
'image' => get_the_post_thumbnail_url( $post->ID, 'medium' ),
'caption' => get_the_post_thumbnail_caption( $post->ID ),
];
}
// If $fields includes type, get the post type.
if ( in_array( 'type', $fields ) ) {
$item['type'] = $post->post_type;
}

// If $fields includes meta, get all Newspack Listings meta fields.
if ( in_array( 'meta', $fields ) ) {
$post_meta = Core::get_meta_values( $post->ID, $post->post_type );
// If $fields includes author and the post isn't set to hide author, get the post author.
if ( in_array( 'author', $fields ) && empty( get_post_meta( $post->ID, 'newspack_listings_hide_author', true ) ) ) {
$item['author'] = get_the_author_meta( 'display_name', $post->post_author );
}

if ( ! empty( $post_meta ) ) {
$item['meta'] = $post_meta;
}
}
$item['test'] = 'Brody';

// If $fields includes type, get the post type.
if ( in_array( 'type', $fields ) ) {
$item['type'] = $post->post_type;
}
// If $fields includes sponsors include sponsors info.
if ( in_array( 'sponsors', $fields ) ) {
$item['sponsors'] = Utils\get_sponsors( $post->ID, 'native' );
}

return $item;
},
$listings_query->posts
),
200
return $item;
},
$listings_query->posts
);

$response = new \WP_REST_Response( $listings );

// Provide next URL if there are more pages.
if ( $next_page <= $listings_query->max_num_pages ) {
$next_url = add_query_arg(
Expand All @@ -382,18 +426,16 @@ function( $post ) use ( $attributes, $fields, $is_amp, $next_page, $query ) {
'amp' => $is_amp,
'_fields' => 'html',
],
rest_url( '/newspack-listings/v1/listings' )
rest_url( '/' . self::$namespace . '/listings' )
);
}

if ( ! empty( $next_url ) ) {
$response->header( 'next-url', $next_url );
}

return $response;
}

return new \WP_REST_Response( [] );
return rest_ensure_response( $response );
}

/**
Expand Down
14 changes: 14 additions & 0 deletions includes/class-newspack-listings-core.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public function __construct() {
add_filter( 'newspack_listings_hide_author', [ __CLASS__, 'hide_author' ] );
add_filter( 'newspack_listings_hide_publish_date', [ __CLASS__, 'hide_publish_date' ] );
add_filter( 'newspack_theme_featured_image_post_types', [ __CLASS__, 'support_featured_image_options' ] );
add_filter( 'newspack_sponsors_post_types', [ __CLASS__, 'support_newspack_sponsors' ] );
register_activation_hook( NEWSPACK_LISTINGS_FILE, [ __CLASS__, 'activation_hook' ] );
}

Expand Down Expand Up @@ -827,6 +828,19 @@ public static function activation_hook() {
flush_rewrite_rules(); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.flush_rewrite_rules_flush_rewrite_rules
}

/**
* If using the Newspack Sponsors plugin, add support for sponsors to all listings.
*
* @param array $post_types Array of supported post types.
* @return array Filtered array of supported post types.
*/
public static function support_newspack_sponsors( $post_types ) {
return array_merge(
$post_types,
array_values( self::NEWSPACK_LISTINGS_POST_TYPES )
);
}

/**
* Convert legacy custom taxonomies to regular post categories and tags.
* Helpful for sites that have been using v1 of the Listings plugin.
Expand Down
22 changes: 22 additions & 0 deletions includes/newspack-listings-utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,25 @@ function generate_amp_partial( $html ) {
}
return \AMP_DOM_Utils::get_content_from_dom( $dom );
}

/**
* Get sponsors for the given listing.
*
* @param int $post_id ID of the listing.
* @param string $scope 'Native' or 'underwritten'.
* @param string $type 'Post' or 'archive'.
*
* @return array|boolean Array of sponsors, or false if none.
*/
function get_sponsors( $post_id = null, $scope = null, $type = 'post' ) {
// Bail if we don't have the Sponsors plugin.
if ( ! function_exists( '\Newspack_Sponsors\get_all_sponsors' ) ) {
return false;
}

if ( null === $post_id ) {
$post_id = get_the_ID();
}

return \Newspack_Sponsors\get_all_sponsors( $post_id, $scope, $type );
}
31 changes: 19 additions & 12 deletions src/assets/shared/listing.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

.newspack-listings {
&__listing-post {
display: block;

@media only screen and ( min-width: $tablet_width ) {
.media-position-left &,
.media-position-right & {
display: flex;
}
}

+ .is-link {
padding-left: 0;
padding-right: 0;
Expand Down Expand Up @@ -50,18 +59,6 @@
}
}

&__listing-post,
&__listing-link {
display: block;

@media only screen and ( min-width: $tablet_width ) {
.media-position-left &,
.media-position-right & {
display: flex;
}
}
}

&__listing-title {
margin-top: 0.5rem;

Expand Down Expand Up @@ -125,4 +122,14 @@
&__column-reverse {
flex-direction: row-reverse;
}

&__sponsors {
align-items: center;
display: flex;

.sponsor-logos {
border-right: 1px solid var( --newspack-listings--grey-light );
margin-right: 0.75rem;
}
}
}
2 changes: 1 addition & 1 deletion src/blocks/curated-list/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const CuratedListEditorComponent = ( {
const posts = await apiFetch( {
path: addQueryArgs( '/newspack-listings/v1/listings', {
query: { ...query, maxItems: MAX_EDITOR_ITEMS }, // Get up to MAX_EDITOR_ITEMS listings in the editor so we can show all locations.
_fields: 'id,title,author,category,tags,excerpt,media,meta,type',
_fields: 'id,title,author,category,tags,excerpt,media,meta,type,sponsors',
} ),
} );
setAttributes( { listingIds: posts.map( post => post.id ) } );
Expand Down
2 changes: 1 addition & 1 deletion src/blocks/listing/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const ListingEditorComponent = ( {
path: addQueryArgs( '/newspack-listings/v1/listings', {
per_page: 100,
id: listingId,
_fields: 'id,title,author,category,tags,excerpt,media,meta',
_fields: 'id,title,author,category,tags,excerpt,media,meta,sponsors',
} ),
} );

Expand Down
Loading

0 comments on commit 7d2ef64

Please sign in to comment.