Making WordPress.org

Changeset 1533


Ignore:
Timestamp:
05/01/2015 11:32:18 PM (11 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.