Making WordPress.org

Changeset 4814


Ignore:
Timestamp:
01/27/2017 11:17:15 PM (9 years ago)
Author:
coreymckrill
Message:

Official WordPress Events: Use the v2 REST endpoint to fetch WordCamps

This maintains the v1 routines for now, and adds separate routines for v2.
When the v1 endpoint is officially deprecated we can remove them. To
switch the endpoint used, change the value of WORDCAMP_API_VERSION.

Location:
sites/trunk/wordpress.org/public_html/wp-content/plugins/official-wordpress-events
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/official-wordpress-events/official-wordpress-event.php

    r492 r4814  
    88 */
    99class Official_WordPress_Event {
    10     public $type, $title, $url, $start_timestamp, $end_timestamp, $location;
     10    public $type, $title, $url, $start_timestamp, $end_timestamp, $location, $coordinates;
    1111
    1212    /**
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/official-wordpress-events/official-wordpress-events.php

    r4809 r4814  
    11<?php
    2 
    32/*
    43Plugin Name: Official WordPress Events
     
    98
    109class Official_WordPress_Events {
    11     const WORDCAMP_API_BASE_URL = 'http://central.wordcamp.org/wp-json/';
     10    const WORDCAMP_API_BASE_URL = 'https://central.wordcamp.org/wp-json/';
     11    const WORDCAMP_API_VERSION  = 2;
    1212    const MEETUP_API_BASE_URL   = 'https://api.meetup.com/';
    1313    const MEETUP_MEMBER_ID      = 72560962;
     
    2020     * Ability to feature a camp in a hero area
    2121     * Add a "load more" button that retrieves more events via AJAX and updates the DOM. Have each click load the next month of events?
    22      * Update WORDCAMP_API_BASE_URL to use HTTPS when central.wordcamp.org supports it
    2322     */
    2423
     
    6463    /**
    6564     * Get all official events
    66      *
     65     * 
    6766     * @return array
    6867     */
     
    7271
    7372        // todo Cache results here too, to avoid processing the raw data on each request? If so, then no longer need to cache API call results?
    74 
     73       
    7574        return $events;
    7675    }
    7776
    7877    /**
    79      * Sort events based on start timestamp
    80      *
     78     * Sort events based on start timestamp 
     79     * 
    8180     * This is a callback for usort()
    82      *
     81     * 
    8382     * @param $a
    8483     * @param $b
    85      *
    8684     * @return int
    8785     */
     
    114112
    115113    /**
     114     * Generate the WordCamps endpoint URL for a particular version of the REST API.
     115     *
     116     * @param int $api_version
     117     *
     118     * @return string
     119     */
     120    protected function get_wordcamp_events_endpoint( $api_version = 1 ) {
     121        switch ( $api_version ) {
     122            case 1 :
     123            default :
     124                $request_params = array(
     125                    'type'   => 'wordcamp',
     126                    'filter' => array(
     127                        'posts_per_page' => self::POSTS_PER_PAGE * .5,  // WordCamps happen much less frequently than meetups
     128                        // todo request camps that are in the next few months, ordered by start date ASC. requires https://github.com/WP-API/WP-API/issues/479 or customization on the wordcamp.org side
     129                    ),
     130                );
     131                $endpoint = add_query_arg( $request_params, self::WORDCAMP_API_BASE_URL . 'posts' );
     132                break;
     133
     134            case 2 :
     135                $request_params = array(
     136                    'status'   => 'wcpt-scheduled',
     137                    'per_page' => 100,
     138                    // todo 100 is the built-in limit for per_page. As the number of WordCamps per year grows, we may need to increase this. See https://github.com/WP-API/WP-API/issues/2914#issuecomment-266222585
     139                );
     140                $endpoint = add_query_arg( $request_params, self::WORDCAMP_API_BASE_URL . 'wp/v2/wordcamps' );
     141                break;
     142        }
     143
     144        return $endpoint;
     145    }
     146
     147    /**
    116148     * Retrieve events fromm the WordCamp.org API
    117149     *
     
    119151     */
    120152    protected function get_wordcamp_events() {
    121         $events         = array();
    122         $request_params = array(
    123             'type'   => 'wordcamp',
    124             'filter' => array(
    125                 'posts_per_page' => self::POSTS_PER_PAGE * .5,  // WordCamps happen much less frequently than meetups
    126                 // todo request camps that are in the next few months, ordered by start date ASC. requires https://github.com/WP-API/WP-API/issues/479 or customization on the wordcamp.org side
    127             ),
    128         );
    129 
    130         $response  = $this->remote_get( esc_url_raw( add_query_arg( $request_params, self::WORDCAMP_API_BASE_URL . 'posts' ) ) );
     153        $endpoint  = $this->get_wordcamp_events_endpoint( self::WORDCAMP_API_VERSION );
     154        $response  = $this->remote_get( esc_url_raw( $endpoint ) );
     155
     156        switch ( self::WORDCAMP_API_VERSION ) {
     157            case 1 :
     158            default :
     159                $events = $this->parse_wordcamp_events_api_v1( $response );
     160                break;
     161
     162            case 2 :
     163                $events = $this->parse_wordcamp_events_api_v2( $response );
     164                break;
     165        }
     166       
     167        return $events;
     168    }
     169
     170    /**
     171     * Parse a response from the v1 API.
     172     *
     173     * @param $response
     174     *
     175     * @return array
     176     */
     177    protected function parse_wordcamp_events_api_v1( $response ) {
     178        $events    = array();
    131179        $wordcamps = json_decode( wp_remote_retrieve_body( $response ) );
    132180
     
    175223
    176224    /**
     225     * Parse a response from the v2 API.
     226     *
     227     * This does additional sorting of the returned events that the v1 parser doesn't do.
     228     *
     229     * @param $response
     230     *
     231     * @return array
     232     */
     233    protected function parse_wordcamp_events_api_v2( $response ) {
     234        $events    = array();
     235        $wordcamps = json_decode( wp_remote_retrieve_body( $response ) );
     236
     237        if ( $wordcamps ) {
     238            foreach ( $wordcamps as $wordcamp ) {
     239                $event = array(
     240                    'type'  => 'wordcamp',
     241                    'title' => $wordcamp->title->rendered,
     242                );
     243
     244                foreach ( $wordcamp as $field => $value ) {
     245                    switch ( $field ) {
     246                        case 'Start Date (YYYY-mm-dd)':
     247                            $value = absint( $value );
     248                            if ( empty( $value ) || $value < strtotime( '-1 day' ) ) {
     249                                continue 3;
     250                            } else {
     251                                $event['start_timestamp'] = $value;
     252                            }
     253                            break;
     254
     255                        case 'End Date (YYYY-mm-dd)':
     256                            $value = absint( $value );
     257                            $event['end_timestamp'] = $value;
     258                            break;
     259
     260                        case 'URL':
     261                            if ( empty( $value ) ) {
     262                                continue 3;
     263                            } else {
     264                                $event['url'] = $value;
     265                            }
     266                            break;
     267
     268                        case 'Location':
     269                            $event['location'] = $value;
     270                            break;
     271
     272                        case '_venue_coordinates' :
     273                            if ( isset( $value->latitude, $value->longitude ) ) {
     274                                $event['coordinates'] = array(
     275                                    'latitude'  => $value->latitude,
     276                                    'longitude' => $value->longitude,
     277                                );
     278                            }
     279                            break;
     280                    }
     281                }
     282
     283                $events[] = new Official_WordPress_Event( $event );
     284            }
     285
     286            uasort( $events, array( $this, 'sort_events' ) );
     287
     288            // Return fewer WordCamps since they happen less frequently than meetups
     289            $events = array_slice( $events, 0, self::POSTS_PER_PAGE * 0.5 );
     290        }
     291
     292        return $events;
     293    }
     294
     295    /**
    177296     * Get WordPress meetups from the Meetup.com API
    178297     *
     
    185304            return $events;
    186305        }
    187 
     306       
    188307        $response = $this->remote_get( sprintf(
    189308            '%s2/events?group_id=%s&time=0,1m&page=%d&key=%s',
     
    208327                    $location = $this->format_reverse_geocode_address( $location->address_components );
    209328                }
    210 
     329               
    211330                $events[] = new Official_WordPress_Event( array(
    212331                    'type'            => 'meetup',
     
    214333                    'url'             => $meetup->event_url,
    215334                    'start_timestamp' => $start_timestamp,
    216                     'end_timestamp'   => ( empty ( $meetup->duration ) ? $start_timestamp : $start_timestamp + ( $meetup->duration / 1000 ) ),      // convert to seconds
     335                    'end_timestamp'   => ( empty ( $meetup->duration ) ? $start_timestamp : $start_timestamp + ( $meetup->duration / 1000 ) ),  // convert to seconds
    217336                    'location'        => $location,
    218337                ) );
     
    222341        return $events;
    223342    }
    224 
     343   
    225344    /*
    226345     * Gets the IDs of all of the meetup groups associated
     
    232351            return array();
    233352        }
    234 
     353       
    235354        $response = $this->remote_get( sprintf(
    236355            '%s2/profiles?&member_id=%d&key=%s',
     
    241360
    242361        $group_ids = json_decode( wp_remote_retrieve_body( $response ) );
    243 
     362   
    244363        if ( ! empty ( $group_ids->results ) ) {
    245364            $group_ids = wp_list_pluck( $group_ids->results, 'group' );
    246365            $group_ids = wp_list_pluck( $group_ids, 'id' );
    247366        }
    248 
     367       
    249368        if ( ! isset( $group_ids ) || ! is_array( $group_ids ) ) {
    250369            $group_ids = array();
    251370        }
    252 
     371       
    253372        return $group_ids;
    254373    }
     
    358477                } elseif ( 200 != $response['response']['code'] ) {
    359478                    // trigger_error() has a message limit of 1024 bytes, so we truncate $response['body'] to make sure that $body doesn't get truncated.
    360 
     479   
    361480                    $error = sprintf(
    362481                        'Received HTTP code: %s and body: %s. Request was to: %s; Arguments were: %s',
     
    366485                        print_r( $args, true )
    367486                    );
    368 
    369                     $response = new WP_Error( 'woe_invalid_http_response', 'Invalid HTTP response code', $response );
    370                 }
    371 
     487                   
     488                    $response = new WP_Error( 'woe_invalid_http_response', 'Invalid HTTP response code', $response ); 
     489                }
     490   
    372491                if ( $error ) {
    373492                    $error = preg_replace( '/&key=[a-z0-9]+/i', '&key=[redacted]', $error );
    374493                    trigger_error( sprintf( '%s error for %s: %s', __METHOD__, parse_url( site_url(), PHP_URL_HOST ), sanitize_text_field( $error ) ), E_USER_WARNING );
    375 
     494   
    376495                    if ( $to = apply_filters( 'owe_error_email_addresses', array() ) ) {
    377496                        wp_mail( $to, sprintf( '%s error for %s', __METHOD__, parse_url( site_url(), PHP_URL_HOST ) ), sanitize_text_field( $error ) );
Note: See TracChangeset for help on using the changeset viewer.