Making WordPress.org


Ignore:
Timestamp:
08/02/2018 07:12:19 PM (8 years ago)
Author:
coreymckrill
Message:

WordCamp Reports: Updates to WordCamp Status and WordCamp Details reports

  • Simplify the Details report, making all criteria optional, and adding a parameter so specific WordCamp IDs can be submitted.
  • Rework the UI of the Status report so that it utilizes the Details report for exporting data about WordCamps that appear in the results.
File:
1 edited

Legend:

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

    r7516 r7588  
    88
    99use Exception;
    10 use WordCamp\Reports;
    11 use function WordCamp\Reports\Validation\validate_wordcamp_status;
     10use DateTime;
     11use WP_Error, WP_Post;
     12use function WordCamp\Reports\{get_assets_url, get_assets_dir_path, get_views_dir_path};
     13use WordCamp\Reports\Utility\Date_Range;
     14use function WordCamp\Reports\Validation\{validate_date_range, validate_wordcamp_status};
     15use function WordCamp\Reports\Time\{year_array, quarter_array, month_array, convert_time_period_to_date_range};
    1216use WordCamp_Loader;
     17use WordCamp\Utilities\Export_CSV;
    1318
    1419/**
     
    1924 * @package WordCamp\Reports\Report
    2025 */
    21 class WordCamp_Status extends Date_Range {
     26class WordCamp_Status extends Base {
    2227    /**
    2328     * Report name.
     
    6974
    7075    /**
     76     * The date range that defines the scope of the report data.
     77     *
     78     * @var null|Date_Range
     79     */
     80    public $range = null;
     81
     82    /**
    7183     * The status to filter for in the report.
    7284     *
     
    106118        ) );
    107119
    108         parent::__construct( $start_date, $end_date, $options );
     120        parent::__construct( $options );
     121
     122        try {
     123            $this->range = validate_date_range( $start_date, $end_date, $options );
     124        } catch ( Exception $e ) {
     125            $this->error->add(
     126                self::$slug . '-date-error',
     127                $e->getMessage()
     128            );
     129        }
    109130
    110131        if ( $status && 'any' !== $status ) {
     
    139160     */
    140161    protected function get_cache_key() {
    141         $cache_key = parent::get_cache_key();
     162        $cache_key_segments = [
     163            parent::get_cache_key(),
     164            $this->range->generate_cache_key_segment(),
     165        ];
    142166
    143167        if ( $this->status ) {
    144             $cache_key .= '_' . $this->status;
    145         }
    146 
    147         return $cache_key;
     168            $cache_key_segments[] = $this->status;
     169        }
     170
     171        return implode( '_', $cache_key_segments );
     172    }
     173
     174    /**
     175     * Generate a cache expiration interval.
     176     *
     177     * @return int A time interval in seconds.
     178     */
     179    protected function get_cache_expiration() {
     180        return $this->range->generate_cache_duration( parent::get_cache_expiration() );
    148181    }
    149182
     
    177210            // Trim log entries occurring after the date range.
    178211            $logs = array_filter( $logs, function( $entry ) {
    179                 if ( $entry['timestamp'] > $this->end_date->getTimestamp() ) {
     212                if ( $entry['timestamp'] > $this->range->end->getTimestamp() ) {
    180213                    return false;
    181214                }
     
    195228            // Trim log entries occurring before the date range.
    196229            $logs = array_filter( $logs, function( $entry ) {
    197                 if ( $entry['timestamp'] < $this->start_date->getTimestamp() ) {
     230                if ( $entry['timestamp'] < $this->range->start->getTimestamp() ) {
    198231                    return false;
    199232                }
     
    300333                    'key'     => 'Start Date (YYYY-mm-dd)',
    301334                    'compare' => '>=',
    302                     'value'   => strtotime( '-3 months', $this->start_date->getTimestamp() ),
     335                    'value'   => strtotime( '-3 months', $this->range->start->getTimestamp() ),
    303336                    'type'    => 'NUMERIC',
    304337                ),
     
    312345     * Retrieve the log of status changes for a particular WordCamp.
    313346     *
    314      * @param \WP_Post $wordcamp A WordCamp post.
     347     * @param WP_Post $wordcamp A WordCamp post.
    315348     *
    316349     * @return array
    317350     */
    318     protected function get_wordcamp_status_logs( \WP_Post $wordcamp ) {
     351    protected function get_wordcamp_status_logs( WP_Post $wordcamp ) {
    319352        $log_entries = get_post_meta( $wordcamp->ID, '_status_change' );
    320353
     
    398431    public function render_html() {
    399432        $data       = $this->compile_report_data( $this->get_data() );
    400         $start_date = $this->start_date;
    401         $end_date   = $this->end_date;
     433        $start_date = $this->range->start;
     434        $end_date   = $this->range->end;
    402435        $status     = $this->status;
    403436
     
    407440
    408441        if ( ! empty( $this->error->get_error_messages() ) ) {
    409             ?>
    410             <div class="notice notice-error">
    411                 <?php foreach ( $this->error->get_error_messages() as $message ) : ?>
    412                     <?php echo wpautop( wp_kses_post( $message ) ); ?>
    413                 <?php endforeach; ?>
    414             </div>
    415         <?php
     442            $this->render_error_html();
    416443        } else {
    417             include Reports\get_views_dir_path() . 'html/wordcamp-status.php';
     444            include get_views_dir_path() . 'html/wordcamp-status.php';
    418445        }
    419446    }
     
    427454        wp_register_script(
    428455            self::$slug,
    429             Reports\get_assets_url() . 'js/' . self::$slug . '.js',
    430             array( 'jquery' ),
    431             Reports\JS_VERSION,
     456            get_assets_url() . 'js/' . self::$slug . '.js',
     457            array( 'jquery', 'select2' ),
     458            filemtime( get_assets_dir_path() . 'js/' . self::$slug . '.js' ),
    432459            true
    433460        );
     
    435462        wp_register_style(
    436463            self::$slug,
    437             Reports\get_assets_url() . 'css/' . self::$slug . '.css',
    438             array(),
    439             Reports\CSS_VERSION,
     464            get_assets_url() . 'css/' . self::$slug . '.css',
     465            array( 'select2' ),
     466            filemtime( get_assets_dir_path() . 'css/' . self::$slug . '.css' ),
    440467            'screen'
    441468        );
     
    449476    public static function enqueue_admin_assets() {
    450477        self::register_assets();
    451 
     478        WordCamp_Details::register_assets();
     479
     480        wp_enqueue_style( WordCamp_Details::$slug );
    452481        wp_enqueue_script( self::$slug );
    453482        wp_enqueue_style( self::$slug );
     
    468497        $statuses   = WordCamp_Loader::get_post_statuses();
    469498
     499        $field_defaults = [
     500            'ID'                      => 'checked',
     501            'Name'                    => 'checked disabled',
     502            'Start Date (YYYY-mm-dd)' => 'checked',
     503            'End Date (YYYY-mm-dd)'   => 'checked',
     504            'Location'                => 'checked',
     505            'URL'                     => 'checked',
     506            'Created'                 => 'checked',
     507            'Status'                  => 'checked',
     508        ];
     509
    470510        $report = null;
    471511
    472         if ( 'run-report' === $action && wp_verify_nonce( $nonce, 'run-report' ) ) {
     512        if ( 'Show results' === $action
     513             && wp_verify_nonce( $nonce, 'run-report' )
     514             && current_user_can( 'manage_network' )
     515        ) {
    473516            $options = array(
    474                 'earliest_start' => new \DateTime( '2015-01-01' ), // No status log data before 2015.
     517                'public'         => false,
     518                'earliest_start' => new DateTime( '2015-01-01' ), // No status log data before 2015.
    475519            );
    476520
     
    480524
    481525            $report = new self( $start_date, $end_date, $status, $options );
    482 
    483             // The report adjusts the end date in some circumstances.
    484             if ( empty( $report->error->get_error_messages() ) ) {
    485                 $end_date = $report->end_date->format( 'Y-m-d' );
    486             }
    487         }
    488 
    489         include Reports\get_views_dir_path() . 'report/wordcamp-status.php';
     526        }
     527
     528        include get_views_dir_path() . 'report/wordcamp-status.php';
     529    }
     530
     531    /**
     532     * Export the report data to a file.
     533     *
     534     * @return void
     535     */
     536    public static function export_to_file() {
     537        $start_date = filter_input( INPUT_POST, 'start-date' );
     538        $end_date   = filter_input( INPUT_POST, 'end-date' );
     539        $status     = filter_input( INPUT_POST, 'status' );
     540        $fields     = filter_input( INPUT_POST, 'fields', FILTER_SANITIZE_STRING, [ 'flags' => FILTER_REQUIRE_ARRAY ] );
     541        $refresh    = filter_input( INPUT_POST, 'refresh', FILTER_VALIDATE_BOOLEAN );
     542        $action     = filter_input( INPUT_POST, 'action' );
     543        $nonce      = filter_input( INPUT_POST, self::$slug . '-nonce' );
     544
     545        if ( 'Export CSV' !== $action ) {
     546            return;
     547        }
     548
     549        if ( wp_verify_nonce( $nonce, 'run-report' ) && current_user_can( 'manage_network' ) ) {
     550            $error = null;
     551
     552            $options = array(
     553                'public'         => false,
     554                'earliest_start' => new DateTime( '2015-01-01' ), // No status log data before 2015.
     555            );
     556
     557            if ( $refresh ) {
     558                $options['flush_cache'] = true;
     559            }
     560
     561            $status_report = new self( $start_date, $end_date, $status, $options );
     562            $wordcamp_ids  = array_keys( $status_report->get_data() );
     563
     564            if ( ! empty( $status_report->error->get_error_messages() ) ) {
     565                $error = $status_report->error;
     566            } elseif ( empty( $wordcamp_ids ) ) {
     567                $error = new WP_Error(
     568                    self::$slug . '-export-error',
     569                    'No status data available for the given criteria.'
     570                );
     571            }
     572
     573            $include_counts = false;
     574            if ( ! empty( array_intersect( $fields, [ 'Tickets', 'Speakers', 'Sponsors', 'Organizers' ] ) ) ) {
     575                $include_counts = true;
     576            }
     577
     578            // The "Name" field should always be included, but does not get submitted because the input is disabled,
     579            // so add it in here.
     580            $fields[] = 'Name';
     581
     582            $options = array(
     583                'fields' => $fields,
     584                'public' => false,
     585            );
     586
     587            $details_report = new WordCamp_Details( null, $wordcamp_ids, $include_counts, $options );
     588
     589            $filename = [ $status_report::$name ];
     590            $filename[] = $status_report->range->start->format( 'Y-m-d' );
     591            $filename[] = $status_report->range->end->format( 'Y-m-d' );
     592            if ( $status_report->status ) {
     593                $filename[] = $status_report->status;
     594            }
     595            if ( $details_report->include_counts ) {
     596                $filename[] = 'include-counts';
     597            }
     598
     599            $data = $details_report->prepare_data_for_display( $details_report->get_data() );
     600
     601            $headers = ( ! empty( $data ) ) ? array_keys( $data[0] ) : [];
     602
     603            $exporter = new Export_CSV( array(
     604                'filename' => $filename,
     605                'headers'  => $headers,
     606                'data'     => $data,
     607            ) );
     608
     609            if ( ! empty( $details_report->error->get_error_messages() ) ) {
     610                $exporter->error = $details_report->merge_errors( $details_report->error, $exporter->error );
     611            }
     612
     613            if ( $error instanceof WP_Error ) {
     614                $exporter->error = $details_report->merge_errors( $error, $exporter->error );
     615            }
     616
     617            $exporter->emit_file();
     618        } // End if().
    490619    }
    491620
     
    503632            self::register_assets();
    504633
     634            wp_enqueue_style( 'select2' );
    505635            wp_enqueue_script( self::$slug );
    506636
     
    525655        $action = filter_input( INPUT_GET, 'action' );
    526656
    527         $years    = self::year_array( absint( date( 'Y' ) ), 2015 );
    528         $months   = self::month_array();
     657        $years    = year_array( absint( date( 'Y' ) ), 2015 );
     658        $quarters = quarter_array();
     659        $months   = month_array();
    529660        $statuses = WordCamp_Loader::get_post_statuses();
    530661
     
    540671
    541672        if ( 'Show results' === $action ) {
    542             $range = self::convert_time_period_to_date_range( $year, $period );
     673            try {
     674                $range = convert_time_period_to_date_range( $year, $period );
     675            } catch ( Exception $e ) {
     676                $error = new WP_Error(
     677                    self::$slug . '-time-period-error',
     678                    $e->getMessage()
     679                );
     680            }
    543681
    544682            $options = array(
    545                 'earliest_start' => new \DateTime( '2015-01-01' ), // No status log data before 2015.
     683                'earliest_start' => new DateTime( '2015-01-01' ), // No status log data before 2015.
    546684            );
    547685
    548             $report = new self( $range['start_date'], $range['end_date'], $status, $options );
    549         }
    550 
    551         include Reports\get_views_dir_path() . 'public/wordcamp-status.php';
     686            $report = new self( $range->start, $range->end, $status, $options );
     687        }
     688
     689        include get_views_dir_path() . 'public/wordcamp-status.php';
    552690    }
    553691}
Note: See TracChangeset for help on using the changeset viewer.