Making WordPress.org

Ticket #407: 407.diff

File 407.diff, 10.0 KB (added by iandunn, 11 years ago)
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/official-wordpress-events/official-wordpress-event.php

     
     1<?php
     2
     3/*
     4 * An official WordPress event
     5 *
     6 * This doesn't have any real functionality, but it exists to provide a standard data structure
     7 * for events across various event types.
     8 */
     9class Official_WordPress_Event {
     10        public $type, $title, $url, $start_timestamp, $end_timestamp, $location;
     11
     12        /**
     13         * Constructor
     14         *
     15         * @param array $members
     16         */
     17        public function __construct( $members ) {
     18                $valid_members = get_object_vars( $this );
     19
     20                foreach ( $members as $member => $value ) {
     21                        if ( array_key_exists( $member, $valid_members ) ) {
     22                                $this->$member = $value;
     23                        }
     24                }
     25        }
     26}
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/official-wordpress-events/official-wordpress-events.php

     
     1<?php
     2/*
     3Plugin Name: Official WordPress Events
     4Description: Retrieves data on official WordPress events
     5Version:     0.1
     6Author:      WordPress.org Meta Team
     7*/
     8
     9class Official_WordPress_Events {
     10        const WORDCAMP_API_BASE_URL = 'https://central.wordcamp.org/wp-json.php';
     11        const MEETUP_API_BASE_URL   = 'https://api.meetup.com/';
     12        const MEETUP_MEMBER_ID      = 72560962;
     13        const POSTS_PER_PAGE        = 50;
     14
     15
     16        /*
     17         * @todo
     18         *
     19         * Setup `owe_error_email_addresses` callback and MEETUP_API_KEY, etc when deploy to production
     20         * Ability to feature a camp in a hero area
     21         * 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         */
     23
     24
     25        /**
     26         * Constructor
     27         */
     28        public function __construct() {
     29                add_shortcode( 'official_wordpress_events', array( $this, 'render_events' ) );
     30        }
     31
     32        /**
     33         * Gather the events data and render the events template with it
     34         */
     35        public function render_events() {
     36                $events = $this->get_all_events();
     37               
     38                if ( $events ) {
     39                        require_once( __DIR__ . '/template-events.php' );
     40                }
     41        }
     42
     43        /**
     44         * Get all official events
     45         *
     46         * @return array
     47         */
     48        protected function get_all_events() {
     49                $events = array_merge( $this->get_wordcamp_events(), $this->get_meetup_events() );
     50                usort( $events, array( $this, 'sort_events' ) );
     51               
     52                return $events;
     53        }
     54
     55        /**
     56         * Sort events based on start timestamp
     57         *
     58         * This is a callback for usort()
     59         *
     60         * @param $a
     61         * @param $b
     62         * @return int
     63         */
     64        protected function sort_events( $a, $b ) {
     65                if ( $a->start_timestamp == $b->start_timestamp ) {
     66                        return 0;
     67                } else {
     68                        return $a->start_timestamp > $b->start_timestamp ? 1 : -1;
     69                }
     70        }
     71
     72        /**
     73         * Retrieve events fromm the WordCamp.org API
     74         *
     75         * @return array
     76         */
     77        protected function get_wordcamp_events() {
     78                $events    = array();
     79                $response  = $this->remote_get( self::WORDCAMP_API_BASE_URL . '/posts/?type=wordcamp' );
     80                $wordcamps = json_decode( wp_remote_retrieve_body( $response ) );
     81               
     82                if ( $wordcamps ) {
     83                        foreach ( $wordcamps as $wordcamp ) {
     84                                if ( isset( $wordcamp->post_meta->{'Start Date (YYYY-mm-dd)'}[0] ) && $wordcamp->post_meta->{'Start Date (YYYY-mm-dd)'}[0] < time() ) {
     85                                        continue;
     86                                       
     87                                        // todo if https://github.com/WP-API/WP-API/pull/118 is merged, then finish register_json_query_vars() in WordCamp_Loader and filter this via the url
     88                                        // restrict it to just the upcoming month?
     89                                }
     90                                       
     91                                $events[] = new Official_WordPress_Event( array(
     92                                        'type'            => 'wordcamp',
     93                                        'title'           => $wordcamp->title,
     94                                        'url'             => $wordcamp->post_meta->URL[0],
     95                                        'start_timestamp' => $wordcamp->post_meta->{'Start Date (YYYY-mm-dd)'}[0],
     96                                        'end_timestamp'   => $wordcamp->post_meta->{'End Date (YYYY-mm-dd)'}[0],
     97                                        'localtion'       => $wordcamp->post_meta->Location[0]
     98                                ) );
     99                        }
     100                }
     101               
     102                return $events;
     103        }
     104
     105        /**
     106         * Get WordPress meetups from the Meetup.com API
     107         *
     108         * @return array
     109         */
     110        protected function get_meetup_events() {
     111                $events = array();
     112
     113                if ( ! defined( 'MEETUP_API_KEY' ) || ! MEETUP_API_KEY || ! $groups = $this->get_meetup_group_ids() ) {
     114                        return $events;
     115                }
     116               
     117                $response = $this->remote_get( sprintf(
     118                        '%s2/events?group_id=%s&time=0,1m&page=%d&key=%s',
     119                        self::MEETUP_API_BASE_URL,
     120                        implode( ',', $groups ),
     121                        self::POSTS_PER_PAGE,
     122                        MEETUP_API_KEY
     123                ) );
     124
     125                $meetups = json_decode( wp_remote_retrieve_body( $response ) );
     126                if ( ! empty ( $meetups->results ) ) {
     127                        $meetups = $meetups->results;
     128                } else {
     129                        $meetups = array();
     130                }
     131               
     132                if ( $meetups ) {
     133                        foreach ( $meetups as $meetup ) {
     134                                $location        = array();
     135                                $start_timestamp = ( $meetup->time / 1000 ) + ( $meetup->utc_offset / 1000 );    // convert to seconds
     136                               
     137                                foreach ( array( 'city', 'state', 'country' ) as $part ) {
     138                                        if ( ! empty( $meetup->venue->$part ) ) {
     139                                                if ( in_array( $part, array( 'state', 'country' ) ) ) {
     140                                                        $location[] = strtoupper( $meetup->venue->$part );
     141                                                } else {
     142                                                        $location[] = $meetup->venue->$part;
     143                                                }
     144                                        }
     145                                }
     146                               
     147                                $events[] = new Official_WordPress_Event( array(
     148                                        'type'            => 'meetup',
     149                                        'title'           => $meetup->name,
     150                                        'url'             => $meetup->event_url,
     151                                        'start_timestamp' => $start_timestamp,
     152                                        'end_timestamp'   => ( empty ( $meetup->duration ) ? $start_timestamp : $start_timestamp + ( $meetup->duration / 1000 ) ),      // convert to seconds
     153                                        'location'        => empty( $location ) ? '' : implode( ' ', $location )
     154                                ) );
     155                        }
     156                }
     157
     158                return $events;
     159        }
     160       
     161        /*
     162         * Gets the IDs of all of the meetup groups associated
     163         *
     164         * @return array
     165         */
     166        protected function get_meetup_group_ids() {
     167                if ( ! defined( 'MEETUP_API_KEY' ) || ! MEETUP_API_KEY ) {
     168                        return array();
     169                }
     170               
     171                $response = $this->remote_get( sprintf(
     172                        '%s2/profiles?&member_id=%d&key=%s',
     173                        self::MEETUP_API_BASE_URL,
     174                        self::MEETUP_MEMBER_ID,
     175                        MEETUP_API_KEY
     176                ) );
     177
     178                $group_ids = json_decode( wp_remote_retrieve_body( $response ) );
     179       
     180                if ( ! empty ( $group_ids->results ) ) {
     181                        $group_ids = wp_list_pluck( $group_ids->results, 'group' );
     182                        $group_ids = wp_list_pluck( $group_ids, 'id' );
     183                }
     184               
     185                if ( ! isset( $group_ids ) || ! is_array( $group_ids ) ) {
     186                        $group_ids = array();
     187                }
     188               
     189                return $group_ids;
     190        }
     191
     192        /**
     193         * Wrapper for wp_remote_get()
     194         *
     195         * This adds caching and error logging/notification
     196         *
     197         * @param string $url
     198         * @param array  $args
     199         * @return false|array|WP_Error False if a valid $url was not passed; otherwise the results from wp_remote_get()
     200         */
     201        protected function remote_get( $url, $args = array() ) {
     202                $response = $error = false;
     203               
     204                if ( $url ) {
     205                        $transient_key = 'owe_' . wp_hash( $url . print_r( $args, true ) );
     206                       
     207                        if ( ! $response = get_transient( $transient_key ) ) {
     208                                $response = wp_remote_get( $url, $args );
     209       
     210                                if ( is_wp_error( $response ) ) {
     211                                        $error = sprintf(
     212                                                'Recieved WP_Error message: %s; Request was to %s; Arguments were: %s',
     213                                                implode( ', ', $response->get_error_messages() ),
     214                                                $url,
     215                                                print_r( $args, true )
     216                                        );
     217                                } elseif ( 200 != $response['response']['code'] ) {
     218                                        // trigger_error() has a message limit of 1024 bytes, so we truncate $response['body'] to make sure that $body doesn't get truncated.
     219       
     220                                        $error = sprintf(
     221                                                'Recieved HTTP code: %s and body: %s. Request was to: %s; Arguments were: %s',
     222                                                $response['response']['code'],
     223                                                substr( sanitize_text_field( $response['body'] ), 0, 500 ),
     224                                                $url,
     225                                                print_r( $args, true )
     226                                        );
     227                                       
     228                                        $response = new WP_Error( 'woe_invalid_http_response', 'Invalid HTTP response code', $response );
     229                                }
     230       
     231                                if ( $error ) {
     232                                        trigger_error( sprintf( '%s error for %s: %s', __METHOD__, parse_url( site_url(), PHP_URL_HOST ), sanitize_text_field( $error ) ), E_USER_WARNING );
     233       
     234                                        if ( $to = apply_filters( 'owe_error_email_addresses', array() ) ) {
     235                                                wp_mail( $to, sprintf( '%s error for %s', __METHOD__, parse_url( site_url(), PHP_URL_HOST ) ), sanitize_text_field( $error ) );
     236                                        }
     237                                } else {
     238                                        set_transient( $transient_key, $response, HOUR_IN_SECONDS );
     239                                }
     240                        }
     241                }
     242
     243                return $response;
     244        }
     245}
     246
     247require_once( __DIR__ . DIRECTORY_SEPARATOR . 'official-wordpress-event.php' );
     248$GLOBALS['Official_WordPress_Events'] = new Official_WordPress_Events();
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/official-wordpress-events/template-events.php

    Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/official-wordpress-events/official-wordpress-events.php
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
     1<div id="ofe_events">
     2        <ul>
     3                <?php foreach ( $events as $event ) : ?>
     4
     5                        <li>
     6                                <a href="<?php echo esc_attr( esc_url( $event->url ) ); ?>">
     7                                        <?php echo esc_html( $event->title ); ?>
     8                                </a><br />
     9
     10                                <?php echo esc_html( date( 'l, F jS | g:i a', (int) $event->start_timestamp ) ); ?><br />
     11
     12                                <?php echo esc_html( $event->location ); ?>
     13                        </li>
     14
     15                <?php endforeach; ?>
     16        </ul>
     17</div> <!-- end #ofe_events -->