Making WordPress.org

Changeset 7912


Ignore:
Timestamp:
11/28/2018 10:47:15 PM (6 years ago)
Author:
coreymckrill
Message:

WordCamp Reports: Refactor WordCamp Counts for better data caching

This separates the data gathering so that get_data only handles the "raw"
rows of data that could be exported to a CSV, while compile_report_data
handles the counting of totals, uniques, etc. This also streamlines the
gender estimation process so that the API client is only used once per site.

Location:
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-reports
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-reports/classes/report/class-wordcamp-counts.php

    r7883 r7912  
    2424 */
    2525class WordCamp_Counts extends Base {
     26    /**
     27     * The lowest acceptable probability when determining gender.
     28     *
     29     * @var float
     30     */
     31    const GENDER_PROBABILITY_THRESHOLD = 0.9;
     32
    2633    /**
    2734     * Report name.
     
    106113
    107114    /**
     115     * An array of data from the WordCamp Details report.
     116     *
     117     * @var array|null
     118     */
     119    protected $wordcamps = null;
     120
     121    /**
    108122     * Data fields that can be visible in a public context.
    109123     *
     
    111125     */
    112126    protected $public_data_fields = [
    113         'ID'                      => 0,
    114         'Name'                    => '',
    115         'URL'                     => '',
    116         'Start Date (YYYY-mm-dd)' => '',
    117         'Status'                  => '',
    118         'attendees'               => 0,
    119         'organizers'              => 0,
    120         'sessions'                => 0,
    121         'speakers'                => 0,
    122         'sponsors'                => 0,
     127        'wordcamp_id' => 0,
     128        'site_id'     => 0,
     129        'post_id'     => 0,
     130        'type'        => '',
     131        'gender'      => '',
     132    ];
     133
     134    /**
     135     * Data fields that should only be visible in a private context.
     136     *
     137     * @var array An associative array of key/default value pairs.
     138     */
     139    protected $private_data_fields = [
     140        'identifier'  => '',
    123141    ];
    124142
     
    201219     * Query and parse the data for the report.
    202220     *
    203      * TODO Refactor the raw data structure to make it exportable as a CSV, move some of the counting stuff
    204      * to compile_report_data().
    205      *
    206221     * @return array
    207222     */
     
    218233        }
    219234
    220         // @todo Maybe find a way to run this without having to hack the memory limit.
     235        // @todo Maybe find a way to run this without having to hack the ini.
    221236        ini_set( 'memory_limit', '900M' );
    222 
    223         $details_options = [
    224             'public' => false,
    225         ];
    226         $details_report = new WordCamp_Details( $this->range, [], false, $details_options );
    227 
    228         if ( ! empty( $details_report->error->get_error_messages() ) ) {
    229             $this->error = $this->merge_errors( $this->error, $details_report->error );
    230 
    231             return [];
    232         }
    233 
    234         $wordcamps = array_filter( $details_report->get_data(), function( $wordcamp ) {
    235             // Skip camps with no website URL.
    236             if ( ! $wordcamp['URL'] ) {
    237                 return false;
    238             }
    239 
    240             if ( ! empty( $this->statuses ) && ! in_array( $wordcamp['Status'], $this->statuses ) ) {
    241                 return false;
    242             }
    243 
    244             return true;
    245         } );
    246 
    247         $wordcamps = array_reduce( $wordcamps, function( $carry, $item ) {
    248             $keep = [
    249                 'ID'                      => '',
    250                 'Name'                    => '',
    251                 'URL'                     => '',
    252                 'Start Date (YYYY-mm-dd)' => '',
    253                 'Status'                  => '',
    254             ];
    255 
    256             $carry[ $item['ID'] ] = array_intersect_key( $item, $keep );
    257 
    258             return $carry;
    259         }, [] );
     237        ini_set( 'max_execution_time', 300 );
     238
     239        $wordcamps = $this->get_wordcamps();
    260240
    261241        $wordcamp_ids = array_keys( $wordcamps );
     
    267247                $valid = validate_wordcamp_id( $wordcamp_id );
    268248
    269                 $data[ $wordcamp_id ] = array_merge(
    270                     $wordcamps[ $wordcamp_id ],
    271                     $this->get_data_for_site( $valid->site_id )
    272                 );
     249                $data = array_merge( $data, $this->get_data_for_site( $valid->site_id, $valid->post_id ) );
    273250            } catch ( Exception $e ) {
    274251                $this->error->add(
     
    276253                    $e->getMessage()
    277254                );
    278 
     255            }
     256
     257            if ( ! empty( $this->error->get_error_messages() ) ) {
    279258                break;
    280259            }
    281         }
    282 
    283         $totals = [
    284             'attendees'  => 0,
    285             'organizers' => 0,
    286             'sessions'   => 0,
    287             'speakers'   => 0,
    288             'sponsors'   => 0,
    289         ];
    290 
    291         $uniques = [
    292             'attendees'  => [],
    293             'organizers' => [],
    294             'speakers'   => [],
    295             'sponsors'   => [],
    296         ];
    297 
    298         $gender_template = [
    299             'female'  => 0,
    300             'male'    => 0,
    301             'unknown' => 0,
    302         ];
    303 
    304         $genders = [
    305             'attendees'  => $gender_template,
    306             'organizers' => $gender_template,
    307             'speakers'   => $gender_template,
    308         ];
    309 
    310         foreach ( $data as $id => &$event ) {
    311             foreach ( $totals as $key => $bucket ) {
    312                 if ( isset( $uniques[ $key ] ) ) {
    313                     $uniques[ $key ] = array_unique( array_merge( $uniques[ $key ], $event[ $key ]['total'] ) );
    314                 }
    315 
    316                 if ( $this->include_gender && isset( $genders[ $key ] ) ) {
    317                     $event[ $key ]['gender'] = array_reduce( $event[ $key ]['gender'], function( $carry, $item ) {
    318                         $carry[ $item ] ++;
    319 
    320                         return $carry;
    321                     }, $gender_template );
    322 
    323                     foreach ( $genders[ $key ] as $gender => &$total ) {
    324                         $total += $event[ $key ]['gender'][ $gender ];
    325                     }
    326                 }
    327 
    328                 $event[ $key ]['total'] = count( $event[ $key ]['total'] );
    329 
    330                 $totals[ $key ] += $event[ $key ]['total'];
    331             }
    332         }
    333 
    334         $data['totals'] = $totals;
    335 
    336         $data['uniques'] = array_map( function( $group ) {
    337             return count( $group );
    338         }, $uniques );
    339 
    340         if ( $this->include_gender ) {
    341             $data['genders'] = $genders;
    342260        }
    343261
     
    351269     * Compile the report data into results.
    352270     *
    353      * TODO Move some of the logic from get_data into here.
    354      *
    355271     * @param array $data The data to compile.
    356272     *
     
    358274     */
    359275    public function compile_report_data( array $data ) {
    360         return $data;
     276        $wordcamps = $this->prepare_data_for_display( $this->get_wordcamps() );
     277
     278        $compiled_data = [
     279            'wordcamps' => [],
     280            'totals'    => [
     281                'attendee'  => 0,
     282                'organizer' => 0,
     283                'session'   => 0,
     284                'speaker'   => 0,
     285                'sponsor'   => 0,
     286            ],
     287            'uniques'   => [
     288                'attendee'  => [],
     289                'organizer' => [],
     290                'speaker'   => [],
     291                'sponsor'   => [],
     292            ],
     293        ];
     294
     295        $wordcamp_template = [
     296            'totals' => [
     297                'attendee'  => 0,
     298                'organizer' => 0,
     299                'session'   => 0,
     300                'speaker'   => 0,
     301                'sponsor'   => 0,
     302            ],
     303        ];
     304
     305        if ( $this->include_gender ) {
     306            $gender_template = [
     307                'female'  => 0,
     308                'male'    => 0,
     309                'unknown' => 0,
     310            ];
     311
     312            $wordcamp_template['genders'] = $compiled_data['genders'] = [
     313                'attendee'  => $gender_template,
     314                'organizer' => $gender_template,
     315                'speaker'   => $gender_template,
     316            ];
     317        }
     318
     319        foreach ( $data as $item ) {
     320            $wordcamp_id = $item['wordcamp_id'];
     321
     322            if ( ! isset( $compiled_data['wordcamps'][ $wordcamp_id ] ) ) {
     323                $compiled_data['wordcamps'][ $wordcamp_id ] = array_merge(
     324                    [
     325                        'info' => $wordcamps[ $wordcamp_id ],
     326                    ],
     327                    $wordcamp_template
     328                );
     329            }
     330
     331            $type       = $item['type'];
     332            $identifier = $item['identifier'];
     333
     334            $compiled_data['wordcamps'][ $wordcamp_id ]['totals'][ $type ] ++;
     335            $compiled_data['totals'][ $type ] ++;
     336            if ( isset( $compiled_data['uniques'][ $type ] ) ) {
     337                $compiled_data['uniques'][ $type ][] = $identifier;
     338            }
     339
     340            if ( $this->include_gender && isset( $wordcamp_template['genders'][ $type ] ) ) {
     341                $gender = $item['gender'];
     342
     343                $compiled_data['wordcamps'][ $wordcamp_id ]['genders'][ $type ][ $gender ] ++;
     344                $compiled_data['genders'][ $type ][ $gender ] ++;
     345            }
     346        }
     347
     348        $compiled_data['uniques'] = array_map( function( $group ) {
     349            $group = array_unique( $group );
     350
     351            return count( $group );
     352        }, $compiled_data['uniques'] );
     353
     354        return $compiled_data;
    361355    }
    362356
     
    388382
    389383    /**
     384     * Get data from a WordCamp Details report and filter it.
     385     *
     386     * @return array|null
     387     */
     388    protected function get_wordcamps() {
     389        if ( is_array( $this->wordcamps ) ) {
     390            return $this->wordcamps;
     391        }
     392
     393        $details_options = [
     394            'public' => false,
     395        ];
     396        $details_report = new WordCamp_Details( $this->range, [], false, $details_options );
     397
     398        if ( ! empty( $details_report->error->get_error_messages() ) ) {
     399            $this->error = $this->merge_errors( $this->error, $details_report->error );
     400
     401            return [];
     402        }
     403
     404        $wordcamps = array_filter( $details_report->get_data(), function( $wordcamp ) {
     405            // Skip camps with no website URL.
     406            if ( ! $wordcamp['URL'] ) {
     407                return false;
     408            }
     409
     410            if ( ! empty( $this->statuses ) && ! in_array( $wordcamp['Status'], $this->statuses ) ) {
     411                return false;
     412            }
     413
     414            return true;
     415        } );
     416
     417        $this->wordcamps = array_reduce( $wordcamps, function( $carry, $item ) {
     418            $keep = [
     419                'ID'                      => '',
     420                'Name'                    => '',
     421                'URL'                     => '',
     422                'Start Date (YYYY-mm-dd)' => '',
     423                'Status'                  => '',
     424            ];
     425
     426            $carry[ $item['ID'] ] = array_intersect_key( $item, $keep );
     427
     428            return $carry;
     429        }, [] );
     430
     431        return $this->wordcamps;
     432    }
     433
     434    /**
    390435     * Retrieve all of the data for one site.
    391436     *
    392437     * @param int $site_id
     438     * @param int $wordcamp_id
    393439     *
    394440     * @return array
    395441     */
    396     protected function get_data_for_site( $site_id ) {
    397         $site_data = [
    398             'attendees'  => [],
    399             'organizers' => [],
    400             'sessions'   => [],
    401             'speakers'   => [],
    402             'sponsors'   => [],
    403         ];
     442    protected function get_data_for_site( $site_id, $wordcamp_id ) {
     443        $site_data = [];
    404444
    405445        switch_to_blog( $site_id );
    406 
    407         // The get_locale() function doesn't work inside switch_to_blog because it returns early.
    408         $wp_locale = get_site_option( 'WPLANG', 'en_US' );
    409446
    410447        $attendees = new WP_Query( [
     
    414451        ] );
    415452
    416         $site_data['attendees']['total'] = wp_list_pluck( $attendees->posts, 'tix_email', 'ID' );
    417 
    418         if ( $this->include_gender ) {
    419             $names = array_map( function( $name ) {
    420                 return explode( ' ', $name )[0];
    421             }, wp_list_pluck( $attendees->posts, 'tix_first_name', 'ID' ) );
    422 
    423             $site_data['attendees']['gender'] = $this->get_genders( $names, $wp_locale );
     453        foreach ( $attendees->posts as $attendee ) {
     454            $data = [
     455                'wordcamp_id' => $wordcamp_id,
     456                'site_id'     => $site_id,
     457                'post_id'     => $attendee->ID,
     458                'type'        => 'attendee',
     459                'identifier'  => $attendee->tix_email,
     460            ];
     461
     462            if ( $this->include_gender ) {
     463                $data['first_name'] = explode( ' ', $attendee->tix_first_name )[0];
     464            }
     465
     466            $site_data[] = $data;
     467
     468            clean_post_cache( $attendee );
    424469        }
    425470
     
    430475        ] );
    431476
    432         $site_data['organizers']['total']  = wp_list_pluck( $organizers->posts, '_wcpt_user_id', 'ID' );
    433 
    434         if ( $this->include_gender ) {
    435             $names = array_map( function( $name ) {
    436                 return explode( ' ', $name )[0];
    437             }, wp_list_pluck( $organizers->posts, 'post_title', 'ID' ) );
    438 
    439             $site_data['organizers']['gender'] = $this->get_genders( $names, $wp_locale );
     477        foreach ( $organizers->posts as $organizer ) {
     478            $data = [
     479                'wordcamp_id' => $wordcamp_id,
     480                'site_id'     => $site_id,
     481                'post_id'     => $organizer->ID,
     482                'type'        => 'organizer',
     483                'identifier'  => $organizer->_wcpt_user_id,
     484            ];
     485
     486            if ( $this->include_gender ) {
     487                $data['first_name'] = explode( ' ', $organizer->post_title )[0];
     488            }
     489
     490            $site_data[] = $data;
     491
     492            clean_post_cache( $organizer );
    440493        }
    441494
    442495        $sessions = new WP_Query( [
    443             'posts_per_page' => - 1,
     496            'posts_per_page' => -1,
    444497            'post_type'      => 'wcb_session',
    445498            'post_status'    => 'publish',
     
    447500                [
    448501                    'key'   => '_wcpt_session_type',
    449                     'value' => 'session',
     502                    'value' => 'session', // Other session types are usually things like "Lunch".
    450503                ]
    451504            ],
    452505        ] );
    453506
    454         $site_data['sessions']['total'] = wp_list_pluck( $sessions->posts, 'ID' );
     507        foreach ( $sessions->posts as $session ) {
     508            $data = [
     509                'wordcamp_id' => $wordcamp_id,
     510                'site_id'     => $site_id,
     511                'post_id'     => $session->ID,
     512                'type'        => 'session',
     513                'identifier'  => '',
     514            ];
     515
     516            if ( $this->include_gender ) {
     517                $data['first_name'] = '';
     518            }
     519
     520            $site_data[] = $data;
     521
     522            clean_post_cache( $session );
     523        }
    455524
    456525        $speakers = new WP_Query( [
     
    460529        ] );
    461530
    462         $site_data['speakers']['total']  = wp_list_pluck( $speakers->posts, '_wcb_speaker_email', 'ID' );
    463 
    464         if ( $this->include_gender ) {
    465             $names = array_map( function( $name ) {
    466                 return explode( ' ', $name )[0];
    467             }, wp_list_pluck( $speakers->posts, 'post_title', 'ID' ) );
    468 
    469             $site_data['speakers']['gender'] = $this->get_genders( $names, $wp_locale );
     531        foreach ( $speakers->posts as $speaker ) {
     532            $data = [
     533                'wordcamp_id' => $wordcamp_id,
     534                'site_id'     => $site_id,
     535                'post_id'     => $speaker->ID,
     536                'type'        => 'speaker',
     537                'identifier'  => $speaker->_wcb_speaker_email,
     538            ];
     539
     540            if ( $this->include_gender ) {
     541                $data['first_name'] = explode( ' ', $speaker->post_title )[0];
     542            }
     543
     544            $site_data[] = $data;
     545
     546            clean_post_cache( $speaker );
    470547        }
    471548
     
    476553        ] );
    477554
    478         $site_data['sponsors']['total'] = array_map( function( $url ) {
    479             $hostname = wp_parse_url( $url, PHP_URL_HOST );
    480 
    481             if ( ! $hostname ) {
    482                 return '';
    483             }
    484 
    485             $trimmed = substr( $hostname, 0, strripos( $hostname, '.' ) ); // Remove the TLD.
    486             $trimmed = preg_replace( '/\.com?$/', '', $trimmed ); // Remove possible secondary .com or .co.
    487             $trimmed = preg_replace( '/^www\./', '', $trimmed ); // Remove possible www.
    488 
    489             return $trimmed;
    490         }, wp_list_pluck( $sponsors->posts, '_wcpt_sponsor_website' ) );
     555        foreach ( $sponsors->posts as $sponsor ) {
     556            $data = [
     557                'wordcamp_id' => $wordcamp_id,
     558                'site_id'     => $site_id,
     559                'post_id'     => $sponsor->ID,
     560                'type'        => 'sponsor',
     561                'identifier'  => $this->get_sponsor_identifier( $sponsor->_wcpt_sponsor_website ),
     562            ];
     563
     564            if ( $this->include_gender ) {
     565                $data['first_name'] = '';
     566            }
     567
     568            $site_data[] = $data;
     569
     570            clean_post_cache( $sponsor );
     571        }
    491572
    492573        restore_current_blog();
    493574
    494         foreach ( $site_data as $type => &$data ) {
    495             if ( 'sessions' === $type ) {
    496                 continue;
    497             }
    498 
    499             // Convert blanks to unique values.
    500             array_walk( $data['total'], function( &$value, $key ) use ( $site_id ) {
    501                 if ( ! $value ) {
    502                     $value = "{$site_id}_{$key}";
     575        // Convert blanks to unique values.
     576        array_walk( $site_data, function( &$value ) {
     577            if ( 'session' === $value['type'] ) {
     578                return;
     579            }
     580
     581            if ( empty( $value['identifier'] ) ) {
     582                $value['identifier'] = "{$value['site_id']}_{$value['post_id']}";
     583            }
     584        } );
     585
     586        if ( $this->include_gender ) {
     587            $names = array_filter( wp_list_pluck( $site_data, 'first_name' ) );
     588
     589            // The get_locale() function doesn't work inside switch_to_blog because it returns early.
     590            $wp_locale = get_site_option( 'WPLANG', 'en_US' );
     591
     592            $gender_data = $this->genderize->get_gender_data( $names, $wp_locale );
     593
     594            if ( ! empty( $this->genderize->error->get_error_messages() ) ) {
     595                $this->merge_errors( $this->error, $this->genderize->error );
     596
     597                return [];
     598            }
     599
     600            array_walk( $site_data, function( &$value ) use ( $gender_data ) {
     601                $name = strtolower( $value['first_name'] );
     602                $data = $gender_data[ $name ];
     603
     604                if ( ! $data['gender'] || $data['probability'] < self::GENDER_PROBABILITY_THRESHOLD ) {
     605                    $value['gender'] = 'unknown';
     606                } else {
     607                    $value['gender'] = $data['gender'];
    503608                }
     609
     610                unset( $value['first_name'] );
    504611            } );
    505612        }
     
    509616
    510617    /**
    511      * Try to detect the genders for a list of first names.
    512      *
    513      * @param array  $names
    514      * @param string $locale
    515      *
    516      * @return array
    517      */
    518     protected function get_genders( $names, $locale ) {
    519         $probability_threshold = (float) 0.9;
    520 
    521         $names   = array_map( 'strtolower', $names );
    522         $genders = [];
    523 
    524         $gender_data = $this->genderize->get_gender_data( $names, $locale );
    525 
    526         if ( ! empty( $this->genderize->error->get_error_messages() ) ) {
    527             $this->merge_errors( $this->error, $this->genderize->error );
    528 
    529             return [];
    530         }
    531 
    532         foreach ( $names as $name ) {
    533             $data = $gender_data[ $name ];
    534 
    535             if ( ! $data['gender'] || $data['probability'] < $probability_threshold ) {
    536                 $genders[] = 'unknown';
    537                 continue;
    538             }
    539 
    540             $genders[] = $data['gender'];
    541         }
    542 
    543         return $genders;
     618     * Reduce a sponsor URL to a simple domain name with no TLD.
     619     *
     620     * @param string $sponsor_url
     621     *
     622     * @return string
     623     */
     624    protected function get_sponsor_identifier( $sponsor_url ) {
     625        $hostname = wp_parse_url( $sponsor_url, PHP_URL_HOST );
     626
     627        if ( ! $hostname ) {
     628            return '';
     629        }
     630
     631        $trimmed = substr( $hostname, 0, strripos( $hostname, '.' ) ); // Remove the TLD.
     632        $trimmed = preg_replace( '/\.com?$/', '', $trimmed ); // Remove possible secondary .com or .co.
     633        $trimmed = preg_replace( '/^www\./', '', $trimmed ); // Remove possible www.
     634
     635        return $trimmed;
    544636    }
    545637
     
    550642     */
    551643    public function render_html() {
    552         $data = $this->prepare_data_for_display( $this->get_data() );
     644        $data       = $this->compile_report_data( $this->get_data() );
    553645        $start_date = $this->range->start;
    554646        $end_date   = $this->range->end;
    555647        $statuses   = $this->statuses;
    556 
    557         if ( $this->include_gender ) {
    558             $genders = array_pop( $data );
    559         }
    560 
    561         $uniques = array_pop( $data );
    562         $totals  = array_pop( $data );
    563648
    564649        if ( ! empty( $this->error->get_error_messages() ) ) {
     
    592677        ) {
    593678            $options = array(
    594                 'public' => false,
     679                'public'       => false,
    595680                'max_interval' => new DateInterval( 'P1Y1M' ),
    596681            );
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-reports/views/html/wordcamp-counts.php

    r7883 r7912  
    99use DateTime;
    1010
     11/** @var array $data */
    1112/** @var DateTime $start_date */
    1213/** @var DateTime $end_date */
    1314/** @var string $statuses */
    14 /** @var array $data */
    15 /** @var array $totals */
    16 /** @var array $uniques */
    17 /** @var array $genders */
    1815
    1916$gender_legend = '<span class="description small"><span class="total">Total</span> / F / M / ?</span>';
    2017?>
    2118
    22 <?php if ( count( $data ) ) : ?>
     19<?php if ( count( $data['wordcamps'] ) ) : ?>
    2320    <h3 id="active-heading">
    24         Numbers for WordCamps occurring
     21        Counts for WordCamps occurring
    2522        <?php if ( $start_date->format( 'Y-m-d' ) === $end_date->format( 'Y-m-d' ) ) : ?>
    2623            on <?php echo esc_html( $start_date->format( 'M jS, Y' ) ); ?>
     
    3330        <tr>
    3431            <td>WordCamps</td>
    35             <td class="number total"><?php echo number_format_i18n( count( $data ) ); ?></td>
     32            <td class="number total"><?php echo number_format_i18n( count( $data['wordcamps'] ) ); ?></td>
    3633        </tr>
    3734    </table>
     
    4744        <tr>
    4845            <td>Attendees</td>
    49             <td class="number"><?php echo number_format_i18n( $totals['attendees'] ); ?></td>
    50             <td class="number"><?php echo number_format_i18n( $uniques['attendees'] ); ?></td>
     46            <td class="number"><?php echo number_format_i18n( $data['totals']['attendee'] ); ?></td>
     47            <td class="number"><?php echo number_format_i18n( $data['uniques']['attendee'] ); ?></td>
    5148        </tr>
    5249        <tr>
    5350            <td>Organizers</td>
    54             <td class="number"><?php echo number_format_i18n( $totals['organizers'] ); ?></td>
    55             <td class="number"><?php echo number_format_i18n( $uniques['organizers'] ); ?></td>
     51            <td class="number"><?php echo number_format_i18n( $data['totals']['organizer'] ); ?></td>
     52            <td class="number"><?php echo number_format_i18n( $data['uniques']['organizer'] ); ?></td>
    5653        </tr>
    5754        <tr>
    5855            <td>Sessions</td>
    59             <td class="number"><?php echo number_format_i18n( $totals['sessions'] ); ?></td>
     56            <td class="number"><?php echo number_format_i18n( $data['totals']['session'] ); ?></td>
    6057            <td class="number">n/a</td>
    6158        </tr>
    6259        <tr>
    6360            <td>Speakers</td>
    64             <td class="number"><?php echo number_format_i18n( $totals['speakers'] ); ?></td>
    65             <td class="number"><?php echo number_format_i18n( $uniques['speakers'] ); ?></td>
     61            <td class="number"><?php echo number_format_i18n( $data['totals']['speaker'] ); ?></td>
     62            <td class="number"><?php echo number_format_i18n( $data['uniques']['speaker'] ); ?></td>
    6663        </tr>
    6764        <tr>
    6865            <td>Sponsors</td>
    69             <td class="number"><?php echo number_format_i18n( $totals['sponsors'] ); ?></td>
    70             <td class="number"><?php echo number_format_i18n( $uniques['sponsors'] ); ?></td>
     66            <td class="number"><?php echo number_format_i18n( $data['totals']['sponsor'] ); ?></td>
     67            <td class="number"><?php echo number_format_i18n( $data['uniques']['sponsor'] ); ?></td>
    7168        </tr>
    7269    </table>
    7370
    74     <?php if ( ! empty( $genders ) ) : ?>
    75         <h4>Gender Breakdown</h4>
     71    <?php if ( ! empty( $data['genders'] ) ) : ?>
     72        <h4>Estimated Gender Breakdown</h4>
    7673
    7774        <table class="striped widefat but-not-too-wide">
     
    8582            <tr>
    8683                <td>Attendees</td>
    87                 <td class="number"><?php echo number_format_i18n( $totals['attendees'] ); ?></td>
    88                 <td class="number"><?php echo number_format_i18n( $genders['attendees']['female'] ); ?></td>
    89                 <td class="number"><?php echo number_format_i18n( $genders['attendees']['male'] ); ?></td>
    90                 <td class="number"><?php echo number_format_i18n( $genders['attendees']['unknown'] ); ?></td>
     84                <td class="number"><?php echo number_format_i18n( $data['totals']['attendee'] ); ?></td>
     85                <td class="number"><?php echo number_format_i18n( $data['genders']['attendee']['female'] ); ?></td>
     86                <td class="number"><?php echo number_format_i18n( $data['genders']['attendee']['male'] ); ?></td>
     87                <td class="number"><?php echo number_format_i18n( $data['genders']['attendee']['unknown'] ); ?></td>
    9188            </tr>
    9289            <tr>
    9390                <td>Organizers</td>
    94                 <td class="number"><?php echo number_format_i18n( $totals['organizers'] ); ?></td>
    95                 <td class="number"><?php echo number_format_i18n( $genders['organizers']['female'] ); ?></td>
    96                 <td class="number"><?php echo number_format_i18n( $genders['organizers']['male'] ); ?></td>
    97                 <td class="number"><?php echo number_format_i18n( $genders['organizers']['unknown'] ); ?></td>
     91                <td class="number"><?php echo number_format_i18n( $data['totals']['organizer'] ); ?></td>
     92                <td class="number"><?php echo number_format_i18n( $data['genders']['organizer']['female'] ); ?></td>
     93                <td class="number"><?php echo number_format_i18n( $data['genders']['organizer']['male'] ); ?></td>
     94                <td class="number"><?php echo number_format_i18n( $data['genders']['organizer']['unknown'] ); ?></td>
    9895            </tr>
    9996            <tr>
    10097                <td>Speakers</td>
    101                 <td class="number"><?php echo number_format_i18n( $totals['speakers'] ); ?></td>
    102                 <td class="number"><?php echo number_format_i18n( $genders['speakers']['female'] ); ?></td>
    103                 <td class="number"><?php echo number_format_i18n( $genders['speakers']['male'] ); ?></td>
    104                 <td class="number"><?php echo number_format_i18n( $genders['speakers']['unknown'] ); ?></td>
     98                <td class="number"><?php echo number_format_i18n( $data['totals']['speaker'] ); ?></td>
     99                <td class="number"><?php echo number_format_i18n( $data['genders']['speaker']['female'] ); ?></td>
     100                <td class="number"><?php echo number_format_i18n( $data['genders']['speaker']['male'] ); ?></td>
     101                <td class="number"><?php echo number_format_i18n( $data['genders']['speaker']['unknown'] ); ?></td>
    105102            </tr>
    106103        </table>
     
    114111            <td>Date</td>
    115112            <td>Status</td>
    116             <td>Attendees<?php if ( ! empty( $genders ) ) : ?><br /><?php echo $gender_legend ?><?php endif; ?></td>
    117             <td>Organizers<?php if ( ! empty( $genders ) ) : ?><br /><?php echo $gender_legend ?><?php endif; ?></td>
     113            <td>Attendees<?php if ( ! empty( $data['genders'] ) ) : ?><br /><?php echo $gender_legend ?><?php endif; ?></td>
     114            <td>Organizers<?php if ( ! empty( $data['genders'] ) ) : ?><br /><?php echo $gender_legend ?><?php endif; ?></td>
    118115            <td>Sessions</td>
    119             <td>Speakers<?php if ( ! empty( $genders ) ) : ?><br /><?php echo $gender_legend ?><?php endif; ?></td>
     116            <td>Speakers<?php if ( ! empty( $data['genders'] ) ) : ?><br /><?php echo $gender_legend ?><?php endif; ?></td>
    120117            <td>Sponsors</td>
    121118        </tr>
    122         <?php foreach ( $data as $event ) : ?>
     119        <?php foreach ( $data['wordcamps'] as $event ) : ?>
    123120            <tr>
    124                 <td><a href="<?php echo esc_attr( $event['URL'] ); ?>"><?php echo esc_html( $event['Name'] ); ?></a></td>
    125                 <td><?php echo esc_html( $event['Start Date (YYYY-mm-dd)'] ); ?></td>
    126                 <td><?php echo esc_html( $event['Status'] ); ?></td>
     121                <td><a href="<?php echo esc_attr( $event['info']['URL'] ); ?>"><?php echo esc_html( $event['info']['Name'] ); ?></a></td>
     122                <td><?php echo esc_html( $event['info']['Start Date (YYYY-mm-dd)'] ); ?></td>
     123                <td><?php echo esc_html( $event['info']['Status'] ); ?></td>
    127124                <td class="number">
    128                     <span class="total"><?php echo number_format_i18n( $event['attendees']['total'] ); ?></span>
    129                     <?php if ( ! empty( $genders ) ) : ?>
    130                         / <?php echo number_format_i18n( $event['attendees']['gender']['female'] ); ?>
    131                         / <?php echo number_format_i18n( $event['attendees']['gender']['male'] ); ?>
    132                         / <?php echo number_format_i18n( $event['attendees']['gender']['unknown'] ); ?>
     125                    <span class="total"><?php echo number_format_i18n( $event['totals']['attendee'] ); ?></span>
     126                    <?php if ( ! empty( $data['genders'] ) ) : ?>
     127                        / <?php echo number_format_i18n( $event['genders']['attendee']['female'] ); ?>
     128                        / <?php echo number_format_i18n( $event['genders']['attendee']['male'] ); ?>
     129                        / <?php echo number_format_i18n( $event['genders']['attendee']['unknown'] ); ?>
    133130                    <?php endif; ?>
    134131                </td>
    135132                <td class="number">
    136                     <span class="total"><?php echo number_format_i18n( $event['organizers']['total'] ); ?></span>
    137                     <?php if ( ! empty( $genders ) ) : ?>
    138                         / <?php echo number_format_i18n( $event['organizers']['gender']['female'] ); ?>
    139                         / <?php echo number_format_i18n( $event['organizers']['gender']['male'] ); ?>
    140                         / <?php echo number_format_i18n( $event['organizers']['gender']['unknown'] ); ?>
     133                    <span class="total"><?php echo number_format_i18n( $event['totals']['organizer'] ); ?></span>
     134                    <?php if ( ! empty( $data['genders'] ) ) : ?>
     135                        / <?php echo number_format_i18n( $event['genders']['organizer']['female'] ); ?>
     136                        / <?php echo number_format_i18n( $event['genders']['organizer']['male'] ); ?>
     137                        / <?php echo number_format_i18n( $event['genders']['organizer']['unknown'] ); ?>
    141138                    <?php endif; ?>
    142139                </td>
    143140                <td class="number total">
    144                     <?php echo number_format_i18n( $event['sessions']['total'] ); ?>
     141                    <?php echo number_format_i18n( $event['totals']['session'] ); ?>
    145142                </td>
    146143                <td class="number">
    147                     <span class="total"><?php echo number_format_i18n( $event['speakers']['total'] ); ?></span>
    148                     <?php if ( ! empty( $genders ) ) : ?>
    149                         / <?php echo number_format_i18n( $event['speakers']['gender']['female'] ); ?>
    150                         / <?php echo number_format_i18n( $event['speakers']['gender']['male'] ); ?>
    151                         / <?php echo number_format_i18n( $event['speakers']['gender']['unknown'] ); ?>
     144                    <span class="total"><?php echo number_format_i18n( $event['totals']['speaker'] ); ?></span>
     145                    <?php if ( ! empty( $data['genders'] ) ) : ?>
     146                        / <?php echo number_format_i18n( $event['genders']['speaker']['female'] ); ?>
     147                        / <?php echo number_format_i18n( $event['genders']['speaker']['male'] ); ?>
     148                        / <?php echo number_format_i18n( $event['genders']['speaker']['unknown'] ); ?>
    152149                    <?php endif; ?>
    153150                </td>
    154151                <td class="number total">
    155                     <?php echo number_format_i18n( $event['sponsors']['total'] ); ?>
     152                    <?php echo number_format_i18n( $event['totals']['sponsor'] ); ?>
    156153                </td>
    157154            </tr>
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-reports/views/report/wordcamp-counts.php

    r7883 r7912  
    5656            </tr>
    5757            <tr>
    58                 <th scope="row"><label for="refresh">Include gender breakdowns</label></th>
     58                <th scope="row"><label for="refresh">Include estimated gender breakdowns</label></th>
    5959                <td><input type="checkbox" id="include-gender" name="include-gender" <?php checked( $include_gender ); ?> /></td>
    6060            </tr>
Note: See TracChangeset for help on using the changeset viewer.