Making WordPress.org

Changeset 2018


Ignore:
Timestamp:
10/29/2015 11:42:08 PM (11 years ago)
Author:
iandunn
Message:

WordCamp Payments Dashboard: Add support for exporting requests to a CSV.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments-network/wordcamp-payments-network.php

    r1817 r2018  
    2525
    2626                add_action( 'wordcamp_payments_aggregate', array( __CLASS__, 'aggregate' ) );
     27                add_action( 'admin_enqueue_scripts',  array( __CLASS__, 'enqueue_assets' ) );
    2728                add_action( 'network_admin_menu', array( __CLASS__, 'network_admin_menu' ) );
    2829                add_action( 'init', array( __CLASS__, 'upgrade' ) );
     30                add_action( 'init', array( __CLASS__, 'process_export_request' ) );
    2931
    3032                // Diff-based updates to the index.
     
    127129                        'post_id' => $request->ID,
    128130                        'created' => get_post_time( 'U', true, $request->ID ),
     131                                // todo Sometimes this is empty. Core normally catches this (r8636), but misses in our case because we don't use drafts. #1350-meta might have the side-effect of solving this.
     132                        'paid'    => absint( get_post_meta( $request->ID, '_camppayments_date_vendor_paid', true ) ),
    129133                        'due' => absint( get_post_meta( $request->ID, '_camppayments_due_by', true ) ),
    130134                        'status' => $request->post_status,
     
    178182
    179183        /**
     184         * Enqueue scripts and stylesheets
     185         *
     186         * @param string $hook
     187         */
     188        public static function enqueue_assets( $hook ) {
     189                if ( 'index_page_wcp-dashboard' == $hook && 'export' == self::get_current_tab() ) {
     190                        wp_enqueue_script( 'jquery-ui-datepicker' );
     191                        wp_enqueue_style( 'jquery-ui' );
     192                        wp_enqueue_style( 'wp-datepicker-skins' );
     193                }
     194        }
     195
     196        /**
    180197         * Renders the Dashboard - Payments screen.
    181198         */
    182199        public static function render_dashboard() {
    183200                ?>
     201
    184202                <div class="wrap">
    185                         <?php screen_icon( 'tools' ); ?>
    186203                        <h1>WordCamp Payments Dashboard</h1>
     204
    187205                        <?php settings_errors(); ?>
     206
    188207                        <h3 class="nav-tab-wrapper"><?php self::render_dashboard_tabs(); ?></h3>
    189208
    190                         <?php self::$list_table->print_inline_css(); ?>
    191                         <div id="wcp-list-table">
    192 
    193                                 <?php self::$list_table->prepare_items(); ?>
    194                                 <form id="posts-filter" action="" method="get">
    195                                         <input type="hidden" name="page" value="wcp-dashboard" />
    196                                         <input type="hidden" name="wcp-section" value="overdue" />
    197                                         <?php self::$list_table->display(); ?>
    198                                 </form>
    199 
    200                         </div>
     209                        <?php
     210                                if ( 'export' == self::get_current_tab() ) {
     211                                        self::render_export_tab();
     212                                } else {
     213                                        self::render_table_tabs();
     214                                }
     215                        ?>
     216
     217                </div> <!-- /wrap -->
     218
     219                <?php
     220        }
     221
     222        /**
     223         * Render the table tabs, like Overview, Pending, etc
     224         */
     225        protected static function render_table_tabs() {
     226                ?>
     227
     228                <?php self::$list_table->print_inline_css(); ?>
     229
     230                <div id="wcp-list-table">
     231                        <?php self::$list_table->prepare_items(); ?>
     232
     233                        <form id="posts-filter" action="" method="get">
     234                                <input type="hidden" name="page" value="wcp-dashboard" />
     235                                <input type="hidden" name="wcp-section" value="overdue" />
     236                                <?php self::$list_table->display(); ?>
     237                        </form>
     238                </div>
     239
     240                <?php
     241        }
     242
     243        /**
     244         * Process export requests
     245         */
     246        public static function process_export_request() {
     247                if ( empty( $_POST['submit'] ) || 'export' != self::get_current_tab() ) {
     248                        return;
     249                }
     250
     251                if ( ! current_user_can( 'manage_network' ) || ! check_admin_referer( 'export', 'wcpn_request_export' ) ) {
     252                        return;
     253                }
     254
     255                $start_date = strtotime( $_POST['wcpn_export_start_date'] . ' 00:00:00' );
     256                $end_date   = strtotime( $_POST['wcpn_export_end_date']   . ' 23:59:59' );
     257                $filename   = sanitize_file_name( sprintf( 'wordcamp-payments-%s-to-%s.csv', date( 'Y-m-d', $start_date ), date( 'Y-m-d', $end_date ) ) );
     258
     259                $report = self::generate_payment_report( $_POST['wcpn_date_type'], $start_date, $end_date );
     260
     261                if ( is_wp_error( $report ) ) {
     262                        add_settings_error( 'wcp-dashboard', $report->get_error_code(), $report->get_error_message() );
     263                } else {
     264                        header( 'Content-Type: text/csv' );
     265                        header( sprintf( 'Content-Disposition: attachment; filename="%s"', $filename ) );
     266                        header( 'Cache-control: private' );
     267                        header( 'Pragma: private' );
     268                        header( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );
     269
     270                        echo $report;
     271                        die();
     272                }
     273        }
     274
     275        /*
     276         * Generate and return the raw payment report contents
     277         *
     278         * @param string $date_type 'paid' | 'created'
     279         * @param int $start_date
     280         * @param int $end_date
     281         *
     282         * @return string | WP_Error
     283         */
     284        protected static function generate_payment_report( $date_type, $start_date, $end_date ) {
     285                global $wpdb;
     286
     287                if ( ! in_array( $date_type, array( 'paid', 'created' ), true ) ) {
     288                        return new WP_Error( 'wcpn_bad_date_type', 'Invalid date type.' );
     289                }
     290
     291                if ( ! is_int( $start_date ) || ! is_int( $end_date ) ) {
     292                        return new WP_Error( 'wcpn_bad_dates', 'Invalid start or end date.' );
     293                }
     294
     295                $column_headings = array(
     296                        'WordCamp', 'ID', 'Title', 'Status', 'Date Vendor was Paid', 'Creation Date', 'Due Date', 'Amount',
     297                        'Currency', 'Category', 'Payment Method','Vendor Name', 'Vendor Contact Person', 'Vendor Country',
     298                        'Check Payable To', 'URL', 'Supporting Documentation Notes',
     299                );
     300
     301                $table_name = self::get_table_name();
     302
     303                $request_indexes = $wpdb->get_results( $wpdb->prepare( "
     304                        SELECT *
     305                        FROM   `{$table_name}`
     306                        WHERE  `{$date_type}` BETWEEN %d AND %d",
     307                        $start_date,
     308                        $end_date
     309                ) );
     310                $report = fopen( 'php://output', 'w' );
     311
     312                fputcsv( $report, $column_headings );
     313
     314                foreach( $request_indexes as $index ) {
     315                        fputcsv( $report, self::get_report_row( $index ) );
     316                }
     317
     318                fclose( $report );
     319
     320                return ob_get_clean();
     321        }
     322
     323        /**
     324         * Gather all the request details needed for a row in the export file
     325         *
     326         * @param stdClass $index
     327         *
     328         * @return array
     329         */
     330        protected static function get_report_row( $index ) {
     331                switch_to_blog( $index->blog_id );
     332
     333                $request          = get_post( $index->post_id );
     334                $currency         = get_post_meta( $index->post_id, '_camppayments_currency',         true );
     335                $category         = get_post_meta( $index->post_id, '_camppayments_payment_category', true );
     336                $date_vendor_paid = get_post_meta( $index->post_id, '_camppayments_date_vendor_paid', true );
     337
     338                if ( $date_vendor_paid ) {
     339                        $date_vendor_paid = date( 'Y-m-d', $date_vendor_paid );
     340                }
     341
     342                if ( 'null-select-one' === $currency ) {
     343                        $currency = '';
     344                }
     345
     346                if ( 'null' === $category ) {
     347                        $category = '';
     348                }
     349
     350                $row = array(
     351                        get_wordcamp_name(),
     352                        sprintf( '%d-%d', $index->blog_id, $index->post_id ),
     353                        $request->post_title,
     354                        $index->status,
     355                        $date_vendor_paid,
     356                        date( 'Y-m-d', $index->created ),
     357                        date( 'Y-m-d', $index->due ),
     358                        get_post_meta( $index->post_id, '_camppayments_payment_amount', true ),
     359                        $currency,
     360                        $category,
     361                        get_post_meta( $index->post_id, '_camppayments_payment_method', true ),
     362                        get_post_meta( $index->post_id, '_camppayments_vendor_name', true ),
     363                        get_post_meta( $index->post_id, '_camppayments_vendor_contact_person', true ),
     364                        get_post_meta( $index->post_id, '_camppayments_vendor_country', true ),
     365                        get_post_meta( $index->post_id, '_camppayments_payable_to', true ),
     366                        get_edit_post_link( $index->post_id ),
     367                        get_post_meta( $index->post_id, '_camppayments_file_notes', true ),
     368                );
     369
     370                restore_current_blog();
     371
     372                return $row;
     373        }
     374
     375        /**
     376         * Render the Export tab
     377         */
     378        protected static function render_export_tab() {
     379                $today      = date( 'Y-m-d' );
     380                $last_month = date( 'Y-m-d', strtotime( 'now - 1 month' ) );
     381                ?>
     382
     383                <script>
     384                        /**
     385                         * Fallback to the jQueryUI datepicker if the browser doesn't support <input type="date">
     386                         */
     387                        jQuery( document ).ready( function( $ ) {
     388                                var browserTest = document.createElement( 'input' );
     389                                browserTest.setAttribute( 'type', 'date' );
     390
     391                                if ( 'text' === browserTest.type ) {
     392                                        $( '#wcpn_export' ).find( 'input[type=date]' ).datepicker( {
     393                                                dateFormat : 'yy-mm-dd',
     394                                                changeMonth: true,
     395                                                changeYear : true
     396                                        } );
     397                                }
     398                        } );
     399                </script>
     400
     401                <form id="wcpn_export" method="POST">
     402                        <?php wp_nonce_field( 'export', 'wcpn_request_export' ); ?>
     403
     404                        <p>
     405                                This form will supply a CSV file with payment requests matching the parameters you select below.
     406                                For example, all requests that were <code>paid</code> between <code><?php echo esc_html( $last_month ); ?></code> and <code><?php echo esc_html( $today ); ?></code>.
     407                        </p>
     408
     409                        <p>
     410                                <label>
     411                                        Date type:
     412                                        <select name="wcpn_date_type">
     413                                                <option value="created">created</option>
     414                                                <option value="paid" selected>paid</option>
     415                                        </select>
     416                                </label>
     417                        </p>
     418
     419                        <p>
     420                                <label>
     421                                        Start date:
     422                                        <input type="date" name="wcpn_export_start_date" class="medium-text" value="<?php echo esc_attr( $last_month ); ?>" />
     423                                </label>
     424                        </p>
     425
     426                        <p>
     427                                <label>
     428                                        End date:
     429                                        <input type="date" name="wcpn_export_end_date" class="medium-text" value="<?php echo esc_attr( $today ); ?>" />
     430                                </label>
     431                        </p>
     432
     433                        <?php submit_button( 'Export' ); ?>
     434                </form>
     435
    201436                <?php
    202437        }
     
    217452                $tab = 'overdue';
    218453
    219                 if ( isset( $_REQUEST['wcp-section'] ) && in_array( $_REQUEST['wcp-section'], array( 'pending', 'overdue', 'paid', 'incomplete' ) ) ) {
     454                if ( isset( $_REQUEST['wcp-section'] ) && in_array( $_REQUEST['wcp-section'], array( 'pending', 'overdue', 'paid', 'incomplete', 'export' ) ) ) {
    220455                        $tab = $_REQUEST['wcp-section'];
    221456                }
     
    234469                        'paid'    => 'Paid',
    235470                        'incomplete' => __( 'Incomplete', 'wordcamporg' ),
     471                        'export'     => __( 'Export', 'wordcamporg' ),
    236472                );
    237473
Note: See TracChangeset for help on using the changeset viewer.