Making WordPress.org

Changeset 7912


Ignore:
Timestamp:
11/28/2018 10:47:15 PM (8 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.