Making WordPress.org

Changeset 1533


Ignore:
Timestamp:
05/01/2015 11:32:18 PM (10 years ago)
Author:
iandunn
Message:

WordCamp JSON API: Embed related Speaker and Session posts within each other.

Fixes #1009

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/wcorg-json-api.php

    r1525 r1533  
    112112    return $prepared_post;
    113113}
    114 add_filter( 'json_prepare_post', 'wcorg_json_expose_whitelisted_meta_data', 998, 3 );
     114add_filter( 'json_prepare_post', 'wcorg_json_expose_whitelisted_meta_data', 997, 3 );
    115115
    116116/**
     
    120120 * that is derived from those fields. For example, we can't expose a Speaker's e-mail address, but can we go ahead
    121121 * and derive their Gravatar URL and expose that instead.
    122  *
    123  * In other cases, some data wouldn't be particularly useful or meaningful on its own, like the `_wcpt_speaker_id`
    124  * attached to a `wcb_session` post. Instead of providing that raw to the API, we can instead expand it into a
    125  * a full `wcb_speaker` object, so that clients don't have to make additional requests to fetch the data they
    126  * actually want.
    127122 *
    128123 * @param array  $prepared_post
     
    145140    return $prepared_post;
    146141}
    147 add_filter( 'json_prepare_post', 'wcorg_json_expose_additional_post_data', 999, 3 );   // after `wcorg_json_expose_whitelisted_meta_data()`, because anything added before that method gets wiped out
     142add_filter( 'json_prepare_post', 'wcorg_json_expose_additional_post_data', 998, 3 );   // after `wcorg_json_expose_whitelisted_meta_data()`, because anything added before that method gets wiped out
    148143
    149144/**
     
    164159
    165160    return $avatar;
     161}
     162
     163/**
     164 * Embed related posts within a post
     165 *
     166 * Some post data wouldn't be particularly useful or meaningful on its own, like the `_wcpt_speaker_id` attached
     167 * to a `wcb_session` post. Instead of providing that raw to the API, we can expand it into a full `wcb_speaker`
     168 * object, so that clients don't have to make additional requests to fetch the data they actually want.
     169 *
     170 * @param array  $prepared_post
     171 * @param array  $raw_post
     172 * @param string $context
     173 *
     174 * @return array
     175 */
     176function wcorg_json_embed_related_posts( $prepared_post, $raw_post, $context ) {
     177    /** @var $wp_json_posts WP_JSON_Posts */
     178    global $wp_json_posts;
     179
     180    if ( is_wp_error( $prepared_post ) || empty ( $prepared_post['type'] ) ) {
     181        return $prepared_post;
     182    }
     183
     184    // Unhook this callback before making any other WP_JSON_Posts::get_posts() calls, to avoid infinite recursion
     185    remove_filter( 'json_prepare_post', 'wcorg_json_embed_related_posts', 999, 3 );
     186
     187    switch( $prepared_post['type'] ) {
     188        case 'wcb_speaker':
     189            $prepared_post['sessions'] = wcorg_json_get_speaker_sessions( $prepared_post['ID'] );
     190            break;
     191
     192        case 'wcb_session':
     193            $speaker_id               = get_post_meta( $prepared_post['ID'], '_wcpt_speaker_id', true );
     194            $speaker                  = $wp_json_posts->get_post( $speaker_id );
     195            $prepared_post['speaker'] = is_a( $speaker, 'WP_JSON_Response' ) ? $speaker : null;
     196            break;
     197    }
     198
     199    add_filter( 'json_prepare_post', 'wcorg_json_embed_related_posts', 999, 3 );
     200
     201    return $prepared_post;
     202}
     203add_filter( 'json_prepare_post', 'wcorg_json_embed_related_posts', 999, 3 );   // after `wcorg_json_expose_additional_post_data()`
     204
     205/**
     206 * Get the sessions for a given speaker.
     207 *
     208 * @param int $speaker_post_id
     209 *
     210 * @return array
     211 */
     212function wcorg_json_get_speaker_sessions( $speaker_post_id ) {
     213    /** @var $wp_json_posts WP_JSON_Posts */
     214    global $wp_json_posts;
     215
     216    $sessions      = array();
     217    $transient_key = "wcorg_json_speaker_{$speaker_post_id}_session_ids";
     218
     219    /*
     220     * Get the IDs of the related posts from WP_Query, because WP_JSON_Posts doesn't support meta queries yet.
     221     *
     222     * This can be removed when https://github.com/WP-API/WP-API/issues/479 is resolved.
     223     */
     224    if ( ! $session_ids = get_transient( $transient_key ) ) {
     225        $session_ids = get_posts( array(
     226            'posts_per_page' => -1,
     227            'post_type'      => 'wcb_session',
     228            'meta_key'       => '_wcpt_speaker_id',
     229            'meta_value'     => $speaker_post_id,
     230        ) );
     231
     232        $session_ids = wp_list_pluck( $session_ids, 'ID' );
     233        set_transient( $transient_key, $session_ids, 2 * HOUR_IN_SECONDS );
     234    }
     235
     236    if ( $session_ids ) {
     237        $sessions = $wp_json_posts->get_posts(
     238            array(
     239                'posts_per_page' => -1,
     240                'post__in'       => $session_ids,
     241                'orderby'        => 'title',
     242                'order'          => 'asc',
     243            ),
     244            'view',
     245            'wcb_session'
     246        );
     247    }
     248
     249    return $sessions;
    166250}
    167251
Note: See TracChangeset for help on using the changeset viewer.