Making WordPress.org

Changeset 3119


Ignore:
Timestamp:
05/11/2016 11:21:02 PM (8 years ago)
Author:
iandunn
Message:

WordCamp Budgets: Attach a PDF copy of the invoice to the notification email.

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

Legend:

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

    r3109 r3119  
    323323    $invoice_url  = admin_url( sprintf( 'post.php?post=%s&action=edit', $invoice_id ) );
    324324    $headers      = array( 'Reply-To: support@wordcamp.org' );
     325    $attachments  = array();
     326    $attachment_message = '';
     327    $invoice_filename = false;
     328    // todo realign
    325329
    326330    if ( 'approved' === $new_status ) {
     
    328332        $sponsor_email  = get_post_meta( $sponsor_id, '_wcpt_sponsor_email_address',  true );
    329333        $status_message = "has been sent to $sponsor_name via $sponsor_email. You will receive another notification when they have paid the invoice.";
     334        $qbo_invoice_id   = get_post_meta( $invoice_id, '_wcbsi_qbo_invoice_id', true );
     335        $invoice_filename = \WordCamp_QBO_Client::get_invoice_filename( $qbo_invoice_id );
     336        // todo realign
     337
     338        if ( ! is_wp_error( $invoice_filename ) ) {
     339            $attachments[]      = $invoice_filename;
     340            $attachment_message = "\nA copy of the invoice has been attached to this message, in case you need to follow up with the sponsor.";
     341        }
    330342    } elseif ( 'paid' === $new_status ) {
    331343        $status_message = "has been paid by $sponsor_name. Go ahead and publish them to your website!";
     
    340352
    341353        $invoice_url
     354        $attachment_message
    342355
    343356        If you have any questions, please reply to let us know."
    344357    );
    345358
    346     wp_mail( $to, $subject, $message, $headers );
     359    wp_mail( $to, $subject, $message, $headers, $attachments );
     360
     361    if ( $invoice_filename ) {
     362        unlink( $invoice_filename );
     363    }
    347364
    348365    restore_current_blog();
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-qbo-client/wordcamp-qbo-client.php

    r3112 r3119  
    434434
    435435    /**
     436     * Get the filename for a PDF copy of an invoice
     437     *
     438     * @param int $invoice_id
     439     *
     440     * @return WP_Error|string
     441     */
     442    public static function get_invoice_filename( $invoice_id ) {
     443        $request  = self::build_invoice_filename_request( $invoice_id );
     444        $response = wp_remote_get( $request['url'], $request['args'] );
     445
     446        if ( is_wp_error( $response ) ) {
     447            $result = $response;
     448        } else {
     449            $result = json_decode( wp_remote_retrieve_body( $response ) );
     450
     451            if ( $result && is_file( $result->filename ) ) {
     452                $result = $result->filename;
     453            } else {
     454                $result = new WP_Error( 'invalid_filename', 'The filename was not valid.', $result );
     455            }
     456        }
     457
     458        return $result;
     459    }
     460
     461    /**
     462     * Build the request to get the filename for a PDF copy of an invoice
     463     *
     464     * @param array $invoice_ids
     465     *
     466     * @return array
     467     */
     468    protected static function build_invoice_filename_request( $invoice_id ) {
     469        $params = array(
     470            'invoice_id' => strval( absint( $invoice_id ) ),    // absint() to validate, strval() to convert to type expected by API
     471        );
     472
     473        $request_url = self::$api_base . '/invoice_pdf';
     474
     475        $args = array(
     476            'headers' => array(
     477                'Authorization' => self::_get_auth_header( 'get', $request_url, '', $params ),
     478                'Content-Type'  => 'application/json',
     479            ),
     480        );
     481
     482        $request_url = add_query_arg( $params, $request_url );  // has to be done after get_auth_header() is called so that the base url and params can be passed separately
     483
     484        return array(
     485            'url'  => $request_url,
     486            'args' => $args,
     487        );
     488    }
     489
     490    /**
    436491     * Create an HMAC signature header for a request.
    437492     *
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-qbo/wordcamp-qbo.php

    r3114 r3119  
    9090            'methods' => 'GET, POST',
    9191            'callback' => array( __CLASS__, 'rest_callback_invoice' ),
     92        ) );
     93
     94        register_rest_route( 'wordcamp-qbo/v1', '/invoice_pdf', array(
     95            'methods' => 'GET',
     96            'callback' => array( __CLASS__, 'rest_callback_invoice_pdf' ),
    9297        ) );
    9398
     
    595600
    596601    /**
     602     * REST: /invoice_pdf
     603     *
     604     * Saves a PDF copy of the invoice and returns the filename
     605     *
     606     * Note: The function that eventually ends up using the file should delete it once it's done with it.
     607     *
     608     * @param WP_REST_Request $request
     609     *
     610     * @return string|WP_Error The filename on success, or a WP_Error on failure
     611     */
     612    public static function rest_callback_invoice_pdf( $request ) {
     613        if ( ! self::_is_valid_request( $request ) ) {
     614            return new WP_Error( 'unauthorized', 'Unauthorized', array( 'status' => 401 ) );
     615        }
     616
     617        $qbo_request = self::build_qbo_get_invoice_pdf_request( $request->get_param( 'invoice_id' ) );
     618        $response    = wp_remote_get( $qbo_request['url'], $qbo_request['args'] );
     619
     620        if ( is_wp_error( $response ) ) {
     621            $result = $response;
     622        } elseif ( 200 != wp_remote_retrieve_response_code( $response ) ) {
     623            $result = new WP_Error( 'invalid_http_code', 'Invalid HTTP response code', $response );
     624        } else {
     625            $body             = wp_remote_retrieve_body( $response );
     626            $valid_pdf_header = '%PDF-' === substr( $body, 0, 5 );
     627            $valid_pdf_footer = '%%EOF' === substr( $body, strlen( $body ) - 7, 5 );
     628
     629            if ( $valid_pdf_header && $valid_pdf_footer ) {
     630                $filename = sprintf(
     631                    '%sWPCS-invoice-%d.pdf',
     632                    get_temp_dir(),
     633                    $request->get_param( 'invoice_id' )
     634                );
     635
     636                if ( file_put_contents( $filename, $body ) ) {
     637                    $result = array( 'filename' => $filename );
     638                } else {
     639                    $result = new WP_Error( 'write_error', 'Failed writing PDF to disk.', compact( 'filename', 'body' ) );
     640                }
     641            } else {
     642                $result = new WP_Error( 'invalid_body', 'Response body was not a PDF.', $response );
     643            }
     644        }
     645
     646        return $result;
     647    }
     648
     649    /**
     650     * Build a request to send an Invoice via QuickBook's API
     651     *
     652     * @param int $invoice_id
     653     *
     654     * @return array
     655     */
     656    protected static function build_qbo_get_invoice_pdf_request( $invoice_id ) {
     657        self::load_options();
     658        $oauth = self::_get_oauth();
     659        $oauth->set_token( self::$options['auth']['oauth_token'], self::$options['auth']['oauth_token_secret'] );
     660
     661        $request_url = sprintf(
     662            '%s/v3/company/%d/invoice/%d/pdf',
     663            self::$api_base_url,
     664            rawurlencode( self::$options['auth']['realmId'] ),
     665            rawurlencode( $invoice_id )
     666        );
     667
     668        $args = array(
     669            'timeout' => self::REMOTE_REQUEST_TIMEOUT,
     670            'headers' => array(
     671                'Authorization' => $oauth->get_oauth_header( 'GET', $request_url ),
     672                'Accept'        => 'application/pdf',
     673                'Content-Type'  => 'application/pdf',
     674            ),
     675            'body' => '',
     676        );
     677
     678        return array(
     679            'url'  => $request_url,
     680            'args' => $args,
     681        );
     682    }
     683
     684    /**
    597685     * Notify Central that an invoice was created but couldn't be sent to the sponsor
    598686     *
Note: See TracChangeset for help on using the changeset viewer.