Changeset 7912
- Timestamp:
- 11/28/2018 10:47:15 PM (6 years ago)
- 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 24 24 */ 25 25 class 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 26 33 /** 27 34 * Report name. … … 106 113 107 114 /** 115 * An array of data from the WordCamp Details report. 116 * 117 * @var array|null 118 */ 119 protected $wordcamps = null; 120 121 /** 108 122 * Data fields that can be visible in a public context. 109 123 * … … 111 125 */ 112 126 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' => '', 123 141 ]; 124 142 … … 201 219 * Query and parse the data for the report. 202 220 * 203 * TODO Refactor the raw data structure to make it exportable as a CSV, move some of the counting stuff204 * to compile_report_data().205 *206 221 * @return array 207 222 */ … … 218 233 } 219 234 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. 221 236 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(); 260 240 261 241 $wordcamp_ids = array_keys( $wordcamps ); … … 267 247 $valid = validate_wordcamp_id( $wordcamp_id ); 268 248 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 ) ); 273 250 } catch ( Exception $e ) { 274 251 $this->error->add( … … 276 253 $e->getMessage() 277 254 ); 278 255 } 256 257 if ( ! empty( $this->error->get_error_messages() ) ) { 279 258 break; 280 259 } 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;342 260 } 343 261 … … 351 269 * Compile the report data into results. 352 270 * 353 * TODO Move some of the logic from get_data into here.354 *355 271 * @param array $data The data to compile. 356 272 * … … 358 274 */ 359 275 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; 361 355 } 362 356 … … 388 382 389 383 /** 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 /** 390 435 * Retrieve all of the data for one site. 391 436 * 392 437 * @param int $site_id 438 * @param int $wordcamp_id 393 439 * 394 440 * @return array 395 441 */ 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 = []; 404 444 405 445 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' );409 446 410 447 $attendees = new WP_Query( [ … … 414 451 ] ); 415 452 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 ); 424 469 } 425 470 … … 430 475 ] ); 431 476 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 ); 440 493 } 441 494 442 495 $sessions = new WP_Query( [ 443 'posts_per_page' => - 496 'posts_per_page' => -1, 444 497 'post_type' => 'wcb_session', 445 498 'post_status' => 'publish', … … 447 500 [ 448 501 'key' => '_wcpt_session_type', 449 'value' => 'session', 502 'value' => 'session', // Other session types are usually things like "Lunch". 450 503 ] 451 504 ], 452 505 ] ); 453 506 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 } 455 524 456 525 $speakers = new WP_Query( [ … … 460 529 ] ); 461 530 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 ); 470 547 } 471 548 … … 476 553 ] ); 477 554 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 } 491 572 492 573 restore_current_blog(); 493 574 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']; 503 608 } 609 610 unset( $value['first_name'] ); 504 611 } ); 505 612 } … … 509 616 510 617 /** 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; 544 636 } 545 637 … … 550 642 */ 551 643 public function render_html() { 552 $data = $this->prepare_data_for_display( $this->get_data() );644 $data = $this->compile_report_data( $this->get_data() ); 553 645 $start_date = $this->range->start; 554 646 $end_date = $this->range->end; 555 647 $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 );563 648 564 649 if ( ! empty( $this->error->get_error_messages() ) ) { … … 592 677 ) { 593 678 $options = array( 594 'public' => false,679 'public' => false, 595 680 'max_interval' => new DateInterval( 'P1Y1M' ), 596 681 ); -
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-reports/views/html/wordcamp-counts.php
r7883 r7912 9 9 use DateTime; 10 10 11 /** @var array $data */ 11 12 /** @var DateTime $start_date */ 12 13 /** @var DateTime $end_date */ 13 14 /** @var string $statuses */ 14 /** @var array $data */15 /** @var array $totals */16 /** @var array $uniques */17 /** @var array $genders */18 15 19 16 $gender_legend = '<span class="description small"><span class="total">Total</span> / F / M / ?</span>'; 20 17 ?> 21 18 22 <?php if ( count( $data ) ) : ?>19 <?php if ( count( $data['wordcamps'] ) ) : ?> 23 20 <h3 id="active-heading"> 24 Numbers for WordCamps occurring21 Counts for WordCamps occurring 25 22 <?php if ( $start_date->format( 'Y-m-d' ) === $end_date->format( 'Y-m-d' ) ) : ?> 26 23 on <?php echo esc_html( $start_date->format( 'M jS, Y' ) ); ?> … … 33 30 <tr> 34 31 <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> 36 33 </tr> 37 34 </table> … … 47 44 <tr> 48 45 <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> 51 48 </tr> 52 49 <tr> 53 50 <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> 56 53 </tr> 57 54 <tr> 58 55 <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> 60 57 <td class="number">n/a</td> 61 58 </tr> 62 59 <tr> 63 60 <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> 66 63 </tr> 67 64 <tr> 68 65 <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> 71 68 </tr> 72 69 </table> 73 70 74 <?php if ( ! empty( $ genders) ) : ?>75 <h4> Gender Breakdown</h4>71 <?php if ( ! empty( $data['genders'] ) ) : ?> 72 <h4>Estimated Gender Breakdown</h4> 76 73 77 74 <table class="striped widefat but-not-too-wide"> … … 85 82 <tr> 86 83 <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> 91 88 </tr> 92 89 <tr> 93 90 <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> 98 95 </tr> 99 96 <tr> 100 97 <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> 105 102 </tr> 106 103 </table> … … 114 111 <td>Date</td> 115 112 <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> 118 115 <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> 120 117 <td>Sponsors</td> 121 118 </tr> 122 <?php foreach ( $data as $event ) : ?>119 <?php foreach ( $data['wordcamps'] as $event ) : ?> 123 120 <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> 127 124 <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'] ); ?> 133 130 <?php endif; ?> 134 131 </td> 135 132 <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'] ); ?> 141 138 <?php endif; ?> 142 139 </td> 143 140 <td class="number total"> 144 <?php echo number_format_i18n( $event[' sessions']['total'] ); ?>141 <?php echo number_format_i18n( $event['totals']['session'] ); ?> 145 142 </td> 146 143 <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'] ); ?> 152 149 <?php endif; ?> 153 150 </td> 154 151 <td class="number total"> 155 <?php echo number_format_i18n( $event[' sponsors']['total'] ); ?>152 <?php echo number_format_i18n( $event['totals']['sponsor'] ); ?> 156 153 </td> 157 154 </tr> -
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-reports/views/report/wordcamp-counts.php
r7883 r7912 56 56 </tr> 57 57 <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> 59 59 <td><input type="checkbox" id="include-gender" name="include-gender" <?php checked( $include_gender ); ?> /></td> 60 60 </tr>
Note: See TracChangeset
for help on using the changeset viewer.