Making WordPress.org


Ignore:
Timestamp:
02/26/2016 12:57:40 AM (10 years ago)
Author:
kovshenin
Message:

WordCamp.org: Reintegrate branch into trunk (wordcamp-payments)

Location:
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments
Files:
2 edited

Legend:

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

  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/includes/payment-request.php

    r2628 r2633  
    88
    99    const POST_TYPE = 'wcp_payment_request';
     10
     11    // @see https://core.trac.wordpress.org/ticket/19074
     12    public static $transition_post_status = array();
    1013
    1114    public function __construct() {
     
    2023
    2124        // Saving posts
    22         add_filter( 'wp_insert_post_data',    array( $this, 'update_request_status' ), 10, 2 );
    23         add_filter( 'wp_insert_post_data',    array( $this, 'ensure_post_date_gmt_set' ), 10, 2 );
     25        add_filter( 'wp_insert_post_data',    array( $this, 'wp_insert_post_data' ), 10, 2 );
    2426        add_action( 'save_post',              array( $this, 'save_payment' ), 10, 2 );
    2527        add_filter( 'map_meta_cap',           array( $this, 'modify_capabilities' ), 10, 4 );
     
    7577     */
    7678    public static function register_post_statuses() {
     79        // Uses core's draft status.
     80
     81        register_post_status( 'wcb-incomplete', array (
     82            'label' => _x( 'Incomplete', 'payment request', 'wordcamporg' ),
     83            'public' => false,
     84            'protected' => true,
     85            'label_count' => _nx_noop(
     86                'Incomplete <span class="count">(%s)</span>',
     87                'Incomplete <span class="count">(%s)</span>',
     88                'wordcamporg'
     89            ),
     90        ) );
     91
     92        register_post_status( 'wcb-pending-approval', array (
     93            'label' => _x( 'Pending Approval', 'payment request', 'wordcamporg' ),
     94            'public' => false,
     95            'protected' => true,
     96            'label_count' => _nx_noop(
     97                'Pending Approval <span class="count">(%s)</span>',
     98                'Pending Approval <span class="count">(%s)</span>',
     99                'wordcamporg'
     100            ),
     101        ) );
     102
     103        register_post_status( 'wcb-approved', array (
     104            'label' => _x( 'Approved', 'payment request', 'wordcamporg' ),
     105            'public' => false,
     106            'protected' => true,
     107            'label_count' => _nx_noop(
     108                'Approved <span class="count">(%s)</span>',
     109                'Approved <span class="count">(%s)</span>',
     110                'wordcamporg'
     111            ),
     112        ) );
     113
     114        register_post_status( 'wcb-pending-payment', array (
     115            'label' => _x( 'Pending Payment', 'payment request', 'wordcamporg' ),
     116            'public' => false,
     117            'protected' => true,
     118            'label_count' => _nx_noop(
     119                'Pending Payment <span class="count">(%s)</span>',
     120                'Pending Payment <span class="count">(%s)</span>',
     121                'wordcamporg'
     122            ),
     123        ) );
     124
     125        register_post_status( 'wcb-paid', array (
     126            'label' => _x( 'Paid', 'payment request', 'wordcamporg' ),
     127            'public' => false,
     128            'protected' => true,
     129            'label_count' => _nx_noop(
     130                'Paid <span class="count">(%s)</span>',
     131                'Paid <span class="count">(%s)</span>',
     132                'wordcamporg'
     133            ),
     134        ) );
     135
     136        register_post_status( 'wcb-failed', array (
     137            'label' => _x( 'Failed', 'payment request', 'wordcamporg' ),
     138            'public' => false,
     139            'protected' => true,
     140            'label_count' => _nx_noop(
     141                'Failed <span class="count">(%s)</span>',
     142                'Failed <span class="count">(%s)</span>',
     143                'wordcamporg'
     144            ),
     145        ) );
     146
     147        register_post_status( 'wcb-cancelled', array (
     148            'label' => _x( 'Cancelled', 'payment request', 'wordcamporg' ),
     149            'public' => false,
     150            'protected' => true,
     151            'label_count' => _nx_noop(
     152                'Cancelled <span class="count">(%s)</span>',
     153                'Cancelled <span class="count">(%s)</span>',
     154                'wordcamporg'
     155            ),
     156        ) );
     157
     158        // Legacy statuses
    77159        register_post_status(
    78160            'paid',
     
    125207        );
    126208
    127         if ( 'incomplete' != $post->post_status && current_user_can( 'manage_network' ) ) {
    128             add_meta_box(
    129                 'wcp_mark_incomplete',
    130                 __( 'Mark as Incomplete', 'wordcamporg' ),
    131                 array( $this, 'render_mark_incomplete_metabox' ),
    132                 self::POST_TYPE,
    133                 'side',
    134                 'high'
    135             );
    136         }
    137 
    138209        add_meta_box(
    139210            'wcp_general_info',
     
    206277        wp_nonce_field( 'status', 'status_nonce' );
    207278
    208         $delete_text                   = EMPTY_TRASH_DAYS ? __( 'Move to Trash' ) : __( 'Delete Permanently' );
    209         $submit_text                   = 'auto-draft' == $post->post_status ? __( 'Submit Request', 'wordcamporg' ) : __( 'Update Request', 'wordcamporg' );
    210         $current_user_can_edit_request = 'paid' != $post->post_status || current_user_can( 'manage_network' );
     279        $back_compat_statuses = array(
     280            'unpaid' => 'draft',
     281            'incomplete' => 'wcb-incomplete',
     282            'paid' => 'wcb-paid',
     283        );
     284
     285        // Map old statuses to new statuses.
     286        if ( array_key_exists( $post->post_status, $back_compat_statuses ) ) {
     287            $post->post_status = $back_compat_statuses[ $post->post_status ];
     288        }
     289
     290        $editable_statuses = array( 'auto-draft', 'draft', 'wcb-incomplete' );
     291        $current_user_can_edit_request = false;
     292        $submit_text = _x( 'Update', 'payment request', 'wordcamporg' );
     293
     294        if ( current_user_can( 'manage_network' ) ) {
     295            $current_user_can_edit_request = true;
     296        } elseif ( in_array( $post->post_status, $editable_statuses ) ) {
     297            $submit_text = __( 'Submit for Review', 'wordcamporg' );
     298            $current_user_can_edit_request = true;
     299        }
    211300
    212301        $date_vendor_paid = get_post_meta( $post->ID, '_camppayments_date_vendor_paid', true );
     
    217306        }
    218307
     308        $incomplete_notes = get_post_meta( $post->ID, '_wcp_incomplete_notes', true );
     309        $incomplete_readonly = ! current_user_can( 'manage_network' ) ? 'readonly' : '';
     310
    219311        require_once( dirname( __DIR__ ) . '/views/payment-request/metabox-status.php' );
    220312    }
    221313
    222     /**
    223      * Render the Mark as Incomplete metabox
    224      *
    225      * @param WP_Post $post
    226      */
    227     public function render_mark_incomplete_metabox( $post ) {
    228         wp_nonce_field( 'mark_incomplete', 'mark_incomplete_nonce' );
    229 
    230         require_once( dirname( __DIR__ ) . '/views/payment-request/metabox-mark-incomplete.php' );
     314    public static function get_post_statuses() {
     315        return array(
     316            'draft',
     317            'wcb-incomplete',
     318            'wcb-pending-approval',
     319            'wcb-approved',
     320            'wcb-pending-payment',
     321            'wcb-paid',
     322            'wcb-failed',
     323            'wcb-cancelled',
     324        );
    231325    }
    232326
     
    476570        global $post;
    477571
    478         if ( 'paid' == $post->post_status && 'paid' != get_query_var( 'post_status' ) ) {
    479             $states['paid'] = __( 'Paid', 'wordcamporg' );
    480         }
    481 
    482         if ( 'unpaid' == $post->post_status && 'unpaid' != get_query_var( 'post_status' ) ) {
    483             $states['unpaid'] = __( 'Unpaid', 'wordcamporg' );
    484         }
    485 
    486         if ( 'incomplete' == $post->post_status && 'incomplete' != get_query_var( 'post_status' ) ) {
    487             $states['incomplete'] = __( 'Incomplete', 'wordcamporg' );
     572        if ( $post->post_type != self::POST_TYPE )
     573            return $states;
     574
     575        // Back-compat
     576        $back_compat_statuses = array(
     577            'unpaid' => 'draft',
     578            'incomplete' => 'wcb-incomplete',
     579            'paid' => 'wcb-paid',
     580        );
     581
     582        // Map old statuses to new statuses.
     583        if ( array_key_exists( $post->post_status, $back_compat_statuses ) ) {
     584            $post->post_status = $back_compat_statuses[ $post->post_status ];
     585        }
     586
     587        $status = get_post_status_object( $post->post_status );
     588        if ( get_query_var( 'post_status' ) != $post->post_status ) {
     589            $states[ $status->name ] = $status->label;
    488590        }
    489591
     
    492594
    493595    /**
    494      * Set the request's status based on whether the vendor has been paid.
    495596     *
    496597     * @param array $post_data
    497598     * @param array $post_data_raw
     599     *
    498600     * @return array
    499601     */
    500     public function update_request_status( $post_data, $post_data_raw ) {
    501         if ( WordCamp_Budgets::post_edit_is_actionable( $post_data, self::POST_TYPE ) ) {
    502             if ( $this->should_mark_request_incomplete() ) {
    503                 $post_data['post_status'] = 'incomplete';
    504                 $this->notify_requester_request_incomplete( $post_data_raw['ID'], $post_data, $post_data_raw );
    505 
    506                 update_post_meta( $post_data_raw['ID'], '_wcp_incomplete_notes', sanitize_text_field( $post_data_raw['wcp_mark_incomplete_notes'] ) );
    507             } else {
    508                 $previous_status          = $post_data['post_status'];
    509                 $valid_paid_date          = false !== strtotime( sanitize_text_field( $_POST['date_vendor_paid'] ) );
    510                 // todo realign
    511 
    512                 if ( current_user_can( 'manage_network' ) && $valid_paid_date ) {
    513                     $post_data['post_status'] = 'paid';
    514                 } else {
    515                     $post_data['post_status'] = 'unpaid';
    516                 }
    517 
    518                 if ( 'paid' != $previous_status && 'paid' == $post_data['post_status'] ) {
    519                     $this->notify_requester_payment_made( $post_data_raw['ID'], $post_data );
    520                 }
    521             }
    522         }
    523 
    524         return $post_data;
    525     }
    526 
    527     /**
    528      * Ensure that new posts have the `post_date_gmt` field populated.
    529      *
    530      * Core only handles this for post types that use the `draft` status (see r8636).
    531      *
    532      * @param array $post_data
    533      * @param array $post_data_raw
    534      *
    535      * @return array
    536      */
    537     public function ensure_post_date_gmt_set( $post_data, $post_data_raw ) {
     602    public function wp_insert_post_data( $post_data, $post_data_raw ) {
     603        if ( $post_data['post_type'] != self::POST_TYPE )
     604            return $post_data;
     605
     606        // Ensure that new posts have the `post_date_gmt` field populated.
    538607        if ( 'auto-draft' !== $post_data['post_status'] ) {
    539608            if ( '0000-00-00 00:00:00' === $post_data['post_date_gmt'] ) {
     
    542611        }
    543612
     613        // Save Draft button was clicked.
     614        if ( ! empty( $post_data_raw['wcb-save-draft'] ) ) {
     615            $post_data['post_status'] = 'draft';
     616        }
     617
     618        // Submit for Review button was clicked.
     619        if ( ! current_user_can( 'manage_network' ) ) {
     620            $editable_statuses = array( 'auto-draft', 'draft', 'wcb-incomplete' );
     621            if ( ! empty( $post_data_raw['wcb-update'] ) && in_array( $post_data['post_status'], $editable_statuses ) ) {
     622                $post_data['post_status'] = 'wcb-pending-approval';
     623            }
     624        }
     625
    544626        return $post_data;
    545627    }
    546628
    547629    /**
    548      * Determine if the user wants to mark a vendor payment as incomplete, and if that is valid
    549      *
    550      * @return bool
    551      */
    552     protected function should_mark_request_incomplete() {
    553         $mark_incomplete = false;
    554 
    555         if ( isset( $_POST['wcp_mark_incomplete_checkbox'] ) && 'on' == $_POST['wcp_mark_incomplete_checkbox'] && ! empty( $_POST['wcp_mark_incomplete_notes'] ) ) {
    556             if ( isset( $_POST['mark_incomplete_nonce'] ) && wp_verify_nonce( $_POST['mark_incomplete_nonce'], 'mark_incomplete' ) ) {
    557                 if ( current_user_can( 'manage_network' ) ) {
    558                     $mark_incomplete = true;
     630     * Notify the payment requester that it has been marked as paid.
     631     *
     632     * @param int|WP_Post $post
     633     */
     634    protected function notify_requester_payment_made( $post ) {
     635        $post = get_post( $post );
     636
     637        if ( ! $to = WordCamp_Budgets::get_requester_formatted_email( $post->post_author ) ) {
     638            return;
     639        }
     640
     641        $subject = sprintf( '"%s" has been paid', $post->post_title );
     642        $headers = array( 'Reply-To: support@wordcamp.org' );
     643
     644        $message = sprintf(
     645            "The request for \"%s\" has been marked as paid by WordCamp Central.
     646
     647            You can view the request at:
     648
     649            %s
     650
     651            If you have any questions, please reply to let us know.",
     652            $post->post_title,
     653            admin_url( sprintf( 'post.php?post=%s&action=edit', $post->ID ) )
     654        );
     655        $message = str_replace( "\t", '', $message );
     656
     657        wp_mail( $to, $subject, $message, $headers );
     658    }
     659
     660    /**
     661     * Notify the payment requester that it has been marked as paid.
     662     *
     663     * @param int|WP_Post $post
     664     */
     665    protected function notify_requester_request_incomplete( $post ) {
     666        $post = get_post( $post );
     667
     668        if ( ! $to = WordCamp_Budgets::get_requester_formatted_email( $post->post_author ) ) {
     669            return;
     670        }
     671
     672        $subject = sprintf( '"%s" is incomplete', $post->post_title );
     673        $headers = array( 'Reply-To: support@wordcamp.org' );
     674        $notes = get_post_meta( $post->ID, '_wcp_incomplete_notes', true );
     675
     676        $message = sprintf(
     677            "The request for \"%s\" has been marked as incomplete by WordCamp Central.
     678
     679            The reason for this is: %s
     680
     681            You can complete the request at:
     682
     683            %s
     684
     685            If you have any questions, please reply to let us know.",
     686            $post->post_title,
     687            esc_html( $notes ),
     688            admin_url( sprintf( 'post.php?post=%s&action=edit', $post->ID ) )
     689        );
     690        $message = str_replace( "\t", '', $message );
     691
     692        wp_mail( $to, $subject, $message, $headers );
     693    }
     694
     695    /**
     696     * Save the post's data
     697     *
     698     * @param int     $post_id
     699     * @param WP_Post $post
     700     */
     701    public function save_payment( $post_id, $post ) {
     702
     703        // Update the timestamp and logs either way.
     704        if ( $post->post_type == self::POST_TYPE && $post_id ) {
     705            update_post_meta( $post_id, '_wcb_updated_timestamp', time() );
     706
     707            $user = get_user_by( 'id', get_current_user_id() );
     708
     709            // Look at post status transitions.
     710            foreach ( self::$transition_post_status as $data ) {
     711                list( $new, $old, $transition_post ) = $data;
     712
     713                // Transitioning a different post.
     714                if ( $transition_post->ID != $post->ID )
     715                    continue;
     716
     717                if ( $new == 'incomplete' || $new == 'wcb-incomplete' ) {
     718                    $incomplete_text = get_post_meta( $post->ID, '_wcp_incomplete_notes', true );
     719                    $incomplete_text = preg_replace( '#\.$#', '', $incomplete_text ); // trailing-undot-it.
     720                    WordCamp_Budgets::log( $post->ID, $user->ID, sprintf( 'Marked as incomplete: %s', $incomplete_text ), array(
     721                        'action' => 'marked-incomplete',
     722                        'reason' => 'maybe notes',
     723                    ) );
     724
     725                    $this->notify_requester_request_incomplete( $post->ID );
     726                    WordCamp_Budgets::log( $post->ID, $user->ID, 'Incomplete notification e-mail sent.', array(
     727                        'action' => 'incomplete-notification-sent',
     728                    ) );
     729
     730                } elseif ( $new == 'paid' || $new == 'wcb-paid' ) {
     731                    WordCamp_Budgets::log( $post->ID, $user->ID, 'Marked as paid', array(
     732                        'action' => 'marked-paid',
     733                    ) );
     734
     735                    $this->notify_requester_payment_made( $post->ID );
     736                    WordCamp_Budgets::log( $post->ID, $user->ID, 'Paid notification e-mail sent.', array(
     737                        'action' => 'paid-notification-sent',
     738                    ) );
     739
     740                } elseif ( $old == 'auto-draft' ) {
     741                    WordCamp_Budgets::log( $post->ID, $user->ID, 'Request created', array(
     742                        'action' => 'updated',
     743                    ) );
    559744                }
    560745            }
    561         }
    562 
    563         return $mark_incomplete;
    564     }
    565 
    566     /**
    567      * Notify the payment requester that it has been marked as paid.
    568      *
    569      * @param int   $request_id
    570      * @param array $post_data
    571      */
    572     protected function notify_requester_payment_made( $request_id, $post_data ) {
    573         if ( ! $to = WordCamp_Budgets::get_requester_formatted_email( $post_data['post_author'] ) ) {
    574             return;
    575         }
    576 
    577         $subject = sprintf( '`%s` has been paid', $post_data['post_title'] );
    578         $headers = array( 'Reply-To: support@wordcamp.org' );
    579 
    580         $message = sprintf(
    581             "The request for `%s` has been marked as paid by WordCamp Central.
    582 
    583             You can view the request at:
    584 
    585             %s
    586 
    587             If you have any questions, please reply to let us know.",
    588             $post_data['post_title'],
    589             admin_url( sprintf( 'post.php?post=%s&action=edit', $request_id ) )
    590         );
    591         $message = str_replace( "\t", '', $message );
    592 
    593         wp_mail( $to, $subject, $message, $headers );
    594     }
    595 
    596     /**
    597      * Notify the payment requester that it has been marked as paid.
    598      *
    599      * @param int   $request_id
    600      * @param array $post_data
    601      * @param array $post_data_raw
    602      */
    603     protected function notify_requester_request_incomplete( $request_id, $post_data, $post_data_raw ) {
    604         if ( ! $to = WordCamp_Budgets::get_requester_formatted_email( $post_data['post_author'] ) ) {
    605             return;
    606         }
    607 
    608         $subject = sprintf( '`%s` is incomplete', $post_data['post_title'] );
    609         $headers = array( 'Reply-To: support@wordcamp.org' );
    610 
    611         $message = sprintf(
    612             "The request for `%s` has been marked as incomplete by WordCamp Central.
    613 
    614             The reason for this is: %s
    615 
    616             You can complete the request at:
    617 
    618             %s
    619 
    620             If you have any questions, please reply to let us know.",
    621             $post_data['post_title'],
    622             sanitize_text_field( stripslashes( $post_data_raw['wcp_mark_incomplete_notes'] ) ),
    623             admin_url( sprintf( 'post.php?post=%s&action=edit', $request_id ) )
    624         );
    625         $message = str_replace( "\t", '', $message );
    626 
    627         wp_mail( $to, $subject, $message, $headers );
    628     }
    629 
    630     /**
    631      * Save the post's data
    632      *
    633      * @param int     $post_id
    634      * @param WP_Post $post
    635      */
    636     public function save_payment( $post_id, $post ) {
     746
     747            WordCamp_Budgets::log( $post->ID, $user->ID, 'Request updated', array(
     748                'action' => 'updated',
     749            ) );
     750        }
     751
     752        // The rest only if triggered by a user submitting a form.
    637753        if ( ! WordCamp_Budgets::post_edit_is_actionable( $post, self::POST_TYPE ) ) {
    638754            return;
     
    651767        $this->sanitize_save_normal_fields( $post_id );
    652768        WordCamp_Budgets::validate_save_payment_method_fields( $post_id, 'camppayments' );
    653         $this->sanitize_save_misc_fields(   $post_id );
     769        $this->sanitize_save_misc_fields( $post_id );
    654770    }
    655771
     
    716832     */
    717833    protected function sanitize_save_misc_fields( $post_id ) {
     834        $post = get_post( $post_id );
     835
    718836        // Status
    719837        if ( current_user_can( 'manage_network' ) ) {
     
    722840        }
    723841
     842        if ( isset( $_POST['wcp_mark_incomplete_notes'] ) ) {
     843            $safe_value = '';
     844            if ( $post->post_status == 'wcb-incomplete' ) {
     845                $safe_value = wp_kses( $_POST['wcp_mark_incomplete_notes'], wp_kses_allowed_html( 'strip' ) );
     846            }
     847
     848            update_post_meta( $post_id, '_wcp_incomplete_notes', $safe_value );
     849        }
     850
    724851        // Attach existing files
    725852        remove_action( 'save_post', array( $this, 'save_payment' ), 10 ); // avoid infinite recursion
     
    739866            return;
    740867
    741         $user = get_user_by( 'id', get_current_user_id() );
    742         if ( $new == 'auto-draft' )
     868        if ( $new == 'auto-draft' || $new == $old )
    743869            return;
    744870
    745         if ( $new == 'incomplete' && $old != 'incomplete' ) {
    746             $incomplete_text = get_post_meta( $post->ID, '_wcp_incomplete_notes', true );
    747             $incomplete_text = preg_replace( '#\.$#', '', $incomplete_text ); // trailing-undot-it.
    748             WordCamp_Budgets::log( $post->ID, $user->ID, sprintf( 'Marked as incomplete: %s', $incomplete_text ), array(
    749                 'action' => 'marked-incomplete',
    750                 'reason' => 'maybe notes',
    751             ) );
    752         } elseif ( $new == 'paid' && $old != 'paid' ) {
    753             WordCamp_Budgets::log( $post->ID, $user->ID, 'Marked as paid', array(
    754                 'action' => 'marked-paid',
    755             ) );
    756         } elseif ( $old == 'auto-draft' && $new != 'auto-draft' ) {
    757             WordCamp_Budgets::log( $post->ID, $user->ID, 'Request created', array(
    758                 'action' => 'updated',
    759             ) );
    760         } else {
    761             WordCamp_Budgets::log( $post->ID, $user->ID, 'Request updated', array(
    762                 'action' => 'updated',
    763             ) );
    764         }
     871        // Move logging to save_post because transitions are fired before save_post.
     872        self::$transition_post_status[] = array( $new, $old, $post );
    765873    }
    766874
Note: See TracChangeset for help on using the changeset viewer.