/** * Returns the status of the donation. * * @return string * @access public * @since 1.3.0 */ public function get_donation_status() { if (!$this->has_valid_donation()) { return ''; } return $this->donation->get_status(true); }
/** * Return the categories of the campaigns that were donated to. * * @return string * @access public * @since 1.4.2 */ public function get_campaign_categories_for_donation($value) { if (!$this->has_valid_donation()) { return $value; } $categories = $this->donation->get_campaign_categories_donated_to('campaign_category', array('fields' => 'names')); return implode(', ', $categories); }
/** * Get things started * * @see WP_List_Table::__construct() * @uses Charitable_Donations_Table::prepare_donation_counts() * * @access public * @since 1.0.0 */ public function __construct() { global $status, $page; $donation_post_type = get_post_type_object('donation'); // Set parent defaults parent::__construct(array('singular' => $donation_post_type->labels->singular_name, 'plural' => $donation_post_type->labels->name, 'ajax' => false)); $this->base_url = admin_url('edit.php?page=charitable-donations-table'); $this->donation_statuses = Charitable_Donation::get_valid_donation_statuses(); $this->prepare_donation_counts(); $this->process_bulk_action(); }
/** * Static method that is fired right after a donation is completed, sending the donation receipt. * * @param int $donation_id * @return boolean * @access public * @static * @since 1.0.0 */ public static function send_with_donation_id($donation_id) { if (!charitable_get_helper('emails')->is_enabled_email(self::get_email_id())) { return false; } if (!Charitable_Donation::is_approved_status(get_post_status($donation_id))) { return false; } $email = new Charitable_Email_Donation_Receipt(array('donation' => new Charitable_Donation($donation_id))); $email->send(); return true; }
/** * Returns a summary of the donation, including all the campaigns that were donated to. * * @return string * @access public * @since 1.0.0 */ public function get_donation_summary() { if (!$this->has_valid_donation()) { return ''; } $output = ""; foreach ($this->donation->get_campaign_donations() as $campaign_donation) { $line_item = sprintf('%s: %s%s', $campaign_donation->campaign_name, charitable_get_currency_helper()->get_monetary_amount($campaign_donation->amount), PHP_EOL); $output .= apply_filters('charitable_donation_summary_line_item_email', $line_item, $campaign_donation); } return $output; }
?> </p> </div> </div> <?php if (count($donations)) { ?> <div class="recent-donations"> <table> <caption><h3><?php _e('Recent Donations', 'charitable'); ?> </h3></caption> <?php foreach ($donations as $post) { $donation = new Charitable_Donation($post); ?> <tr> <td class="donation-date"><?php echo $donation->get_date(); ?> </td> <td class="donation-id">#<?php echo $donation->get_number(); ?> </td> <td class="donation-status"><?php echo $donation->get_status(true); ?> </td> <td class="donation-total"><?php
/** * A helper function to get the National ID Number for a donation. * * @param Charitable_Donation $donation * @return string */ function ed_donation_get_national_id_number($donation) { $data = $donation->get_donor_data(); if (array_key_exists('national_id_number', $data)) { return $data['national_id_number']; } return ''; }
/** * Returns the donation status. Defaults to charitable-pending. * * @return string * @access private * @since 1.0.0 */ private function get_donation_status() { $status = $this->get_donation_data_value('status', 'charitable-pending'); if (!Charitable_Donation::is_valid_donation_status($status)) { $status = 'charitable-pending'; } return $status; }
?> </th> <td><?php echo $donation->get_gateway_label(); ?> </td> </tr> <tr> <th><?php _e('Change Status', 'charitable'); ?> </th> <td> <select id="change-donation-status" name="post_status"> <?php foreach (Charitable_Donation::get_valid_donation_statuses() as $status => $label) { ?> <option value="<?php echo $status; ?> " <?php selected($status, $donation->get_status()); ?> ><?php echo $label; ?> </option> <?php } ?> </select>
/** * A method used to join the campaign donations table on the campaigns query. * * @param string $join_statement * @return string * @access public * @static * @since 1.0.0 */ public static function join_campaign_donations_table($join_statement) { global $wpdb; $statuses = Charitable_Donation::get_approval_statuses(); $statuses = array_filter($statuses, array('Charitable_Donation', 'is_valid_donation_status')); $statuses = "'" . implode("','", $statuses) . "'"; $join_statement .= " LEFT JOIN ( SELECT cd1.campaign_donation_id, cd1.donation_id, cd1.donor_id, cd1.amount, cd1.campaign_id\r\n\t\t\tFROM {$wpdb->prefix}charitable_campaign_donations cd1 \r\n\t\t\tINNER JOIN {$wpdb->posts} po1 ON cd1.donation_id = po1.ID\r\n\t\t\tWHERE po1.post_status IN ( {$statuses} )\r\n\t\t) cd ON cd.campaign_id = {$wpdb->posts}.ID"; return $join_statement; }
/** * Display the offline payment instructions, if applicable. * * @param Charitable_Donation $donation * @return void * @since 1.0.0 */ function charitable_template_donation_receipt_offline_payment_instructions(Charitable_Donation $donation) { if ('offline' != $donation->get_gateway()) { return; } charitable_template('donation-receipt/offline-payment-instructions.php', array('donation' => $donation)); }
/** * Verifies whether the current user can access the donation receipt. * * @param Charitable_Donation $donation * @return boolean * @since 1.1.2 */ function charitable_user_can_access_receipt(Charitable_Donation $donation) { /* If the donation key is stored in the session, the user can access this receipt */ if (charitable_get_session()->has_donation_key($donation->get_donation_key())) { return true; } if (!is_user_logged_in()) { return false; } /* Retrieve the donor and current logged in user */ $donor = $donation->get_donor(); $user = wp_get_current_user(); /* Make sure they match */ if ($donor->ID) { return $donor->ID == $user->ID; } return $donor->get_email() == $user->user_email; }
/** * Fix the donation dates. * * This upgrade routine was added in 1.3.0 * * @see https://github.com/Charitable/Charitable/issues/58 * * @return void * @access public * @since 1.3.0 */ public function fix_donation_dates() { if (!current_user_can('manage_charitable_settings')) { wp_die(__('You do not have permission to do Charitable upgrades', 'charitable'), __('Error', 'charitable'), array('response' => 403)); } ignore_user_abort(true); if (!charitable_is_func_disabled('set_time_limit') && !ini_get('safe_mode')) { @set_time_limit(0); } $step = isset($_GET['step']) ? absint($_GET['step']) : 1; $number = 20; $total = Charitable_Donations::count_all(); /** * If there are no donations to update, go ahead and wrap it up right now. */ if (!$total) { $this->finish_upgrade('fix_donation_dates'); } $donations = get_posts(array('post_type' => Charitable::DONATION_POST_TYPE, 'posts_per_page' => $number, 'paged' => $step, 'post_status' => array_keys(Charitable_Donation::get_valid_donation_statuses()))); if (count($donations)) { /** * Prevent donation receipt & admin notifications from getting resent. */ remove_action('save_post_' . Charitable::DONATION_POST_TYPE, array('Charitable_Email_Donation_Receipt', 'send_with_donation_id')); remove_action('save_post_' . Charitable::DONATION_POST_TYPE, array('Charitable_Email_New_Donation', 'send_with_donation_id')); foreach ($donations as $donation) { /** * Thankfully, we store the timestamp of the donation in the log, * so we can use that to correct any incorrect post_date/post_date_gmt * values. */ $donation_log = get_post_meta($donation->ID, '_donation_log', true); if (empty($donation_log)) { continue; } $time = $donation_log[0]['time']; $date_gmt = gmdate('Y-m-d H:i:s', $time); if ($date_gmt == $donation->post_date_gmt) { continue; } $date = get_date_from_gmt($date_gmt); wp_update_post(array('ID' => $donation->ID, 'post_date' => $date, 'post_date_gmt' => $date_gmt)); } $step++; $redirect = add_query_arg(array('page' => 'charitable-upgrades', 'charitable-upgrade' => 'fix_donation_dates', 'step' => $step, 'number' => $number, 'total' => $total), admin_url('index.php')); wp_redirect($redirect); exit; } $this->upgrade_logs(); $this->finish_upgrade('fix_donation_dates'); }
/** * Verifies whether the current user can access the donation receipt. * * @param Charitable_Donation $donation * @return boolean * @since 1.1.2 */ function charitable_user_can_access_receipt(Charitable_Donation $donation) { charitable_get_deprecated()->deprecated_function(__FUNCTION__, '1.4.0', 'Charitable_Donation::is_from_current_user()'); return $donation->is_from_current_user(); }
public function test_get_valid_donation_statuses() { $this->assertCount(5, Charitable_Donation::get_valid_donation_statuses()); }
/** * Get items * * @see Pronamic_Pay_PaymentDataInterface::get_items() * @return Pronamic_IDeal_Items */ public function get_items() { $donation = new Charitable_Donation($this->donation_id); // Items $items = new Pronamic_IDeal_Items(); // Item // We only add one total item, because iDEAL cant work with negative price items (discount) $item = new Pronamic_IDeal_Item(); $item->setNumber($this->get_order_id()); $item->setDescription($this->get_description()); // @see http://plugins.trac.wordpress.org/browser/woocommerce/tags/1.5.2.1/classes/class-wc-order.php#L50 $item->setPrice($donation->get_total_donation_amount()); $item->setQuantity(1); $items->addItem($item); return $items; }
/** * Receives verified IPN data from PayPal and processes the donation. * * @return void * @access public * @static * @since 1.0.0 */ public static function process_web_accept($data, $donation_id) { if (!isset($data['invoice'])) { return; } $gateway = new Charitable_Gateway_Paypal(); $donation = new Charitable_Donation($donation_id); if ('paypal' != $donation->get_gateway()) { return; } $donation_key = $data['invoice']; $amount = $data['mc_gross']; $payment_status = strtolower($data['payment_status']); $currency_code = strtoupper($data['mc_currency']); $business_email = isset($data['business']) && is_email($data['business']) ? trim($data['business']) : trim($data['receiver_email']); /* Verify that the business email matches the PayPal email in the settings */ if (strcasecmp($business_email, trim($gateway->get_value('paypal_email'))) != 0) { $message = sprintf('%s %s', __('Invalid Business email in the IPN response. IPN data:', 'charitable'), json_encode($data)); Charitable_Donation::update_donation_log($donation_id, $message); $donation->update_status('charitable-failed'); return; } /* Verify that the currency matches. */ if ($currency_code != charitable_get_currency()) { $message = sprintf('%s %s', __('The currency in the IPN response does not match the site currency. IPN data:', 'charitable'), json_encode($data)); Charitable_Donation::update_donation_log($donation_id, $message); $donation->update_status('charitable-failed'); return; } /* Process a refunded donation. */ if (in_array($payment_status, array('refunded', 'reversed'))) { /* It's a partial refund. */ if ($amount < $donation->get_total_donation_amount()) { $message = sprintf('%s: #%s', __('Partial PayPal refund processed', 'charitable'), isset($data['parent_txn_id']) ? $data['parent_txn_id'] : ''); } else { $message = sprintf('%s #%s %s: %s', __('PayPal Payment', 'charitable'), isset($data['parent_txn_id']) ? $data['parent_txn_id'] : '', __('refunded with reason', 'charitable'), isset($data['reason_code']) ? $data['reason_code'] : ''); } $donation->process_refund($amount, $message); return; } /* Mark a payment as failed. */ if (in_array($payment_status, array('declined', 'failed', 'denied', 'expired', 'voided'))) { $message = sprintf('%s: %s', __('The donation has failed with the following status', 'charitable'), $payment_status); Charitable_Donation::update_donation_log($donation_id, $message); $donation->update_status('charitable-failed'); return; } /* If we have already processed this donation, stop here. */ if ('charitable-completed' == get_post_status($donation_id)) { return; } /* Verify that the donation key matches the one stored for the donation. */ if ($donation_key != $donation->get_donation_key()) { $message = sprintf('%s %s', __('Donation key in the IPN response does not match the donation. IPN data:', 'charitable'), json_encode($data)); Charitable_Donation::update_donation_log($donation_id, $message); $donation->update_status('charitable-failed'); return; } /* Verify that the amount in the IPN matches the amount we expected. */ if ($amount < $donation->get_total_donation_amount()) { $message = sprintf('%s %s', __('The amount in the IPN response does not match the expected donation amount. IPN data:', 'charitable'), json_encode($data)); Charitable_Donation::update_donation_log($donation_id, $message); $donation->update_status('charitable-failed'); return; } /* Process a completed donation. */ if ('completed' == $payment_status) { $message = sprintf('%s: %s', __('PayPal Transaction ID', 'charitable'), $data['txn_id']); Charitable_Donation::update_donation_log($donation_id, $message); $donation->update_status('charitable-completed'); return; } /* If the donation is set to pending but has a pending_reason provided, save that to the log. */ if ('pending' == $payment_status) { if (isset($data['pending_reason'])) { $message = $gateway->get_pending_reason_note(strtolower($data['pending_reason'])); Charitable_Donation::update_donation_log($donation_id, $message); } $donation->update_status('charitable-pending'); } }
/** * Returns the array of view options for this campaign. * * @param array $views * @return array * @access public * @since 1.0.0 */ public function view_options($views) { $current = isset($_GET['post-status']) ? $_GET['post-status'] : ''; $statuses = Charitable_Donation::get_valid_donation_statuses(); $donations = new Charitable_Donations(); $status_count = $donations->count_by_status(); $views = array(); $views['all'] = sprintf('<a href="%s"%s>%s <span class="count">(%s)</span></a>', esc_url(remove_query_arg(array('post_status', 'paged'))), $current === 'all' || $current == '' ? ' class="current"' : '', __('All', 'charitable'), $donations->count_all()); foreach ($statuses as $status => $label) { $views[$status] = sprintf('<a href="%s"%s>%s <span class="count">(%s)</span></a>', esc_url(add_query_arg(array('post_status' => $status, 'paged' => false))), $current === $status ? ' class="current"' : '', $label, isset($status_count[$status]) ? $status_count[$status]->num_donations : 0); } return $views; }
/** * Update lead status of the specified payment * * @see https://github.com/Charitable/Charitable/blob/1.1.4/includes/gateways/class-charitable-gateway-paypal.php#L229-L357 * @param Pronamic_Pay_Payment $payment */ public static function status_update(Pronamic_Pay_Payment $payment) { $donation_id = $payment->get_source_id(); $donation = new Charitable_Donation($donation_id); switch ($payment->get_status()) { case Pronamic_WP_Pay_Statuses::CANCELLED: $donation->update_status('charitable-cancelled'); break; case Pronamic_WP_Pay_Statuses::EXPIRED: $donation->update_status('charitable-failed'); break; case Pronamic_WP_Pay_Statuses::FAILURE: $donation->update_status('charitable-failed'); break; case Pronamic_WP_Pay_Statuses::SUCCESS: $donation->update_status('charitable-completed'); break; case Pronamic_WP_Pay_Statuses::OPEN: default: $donation->update_status('charitable-pending'); break; } }
/** * Return the number of users who have donated to the given campaign. * * @global wpdb $wpdb * @param int $campaign_id * @param boolean $include_all If false, only * @return int * @since 1.0.0 */ public function count_campaign_donors($campaign_id, $include_all = false) { global $wpdb; $statuses = $include_all ? array() : Charitable_Donation::get_approval_statuses(); list($status_clause, $parameters) = $this->get_donation_status_clause($statuses); array_unshift($parameters, $campaign_id); $sql = "SELECT COUNT( DISTINCT cd.donor_id ) \n\t\t\t\tFROM {$this->table_name} cd\n\t\t\t\tINNER JOIN {$wpdb->posts} p ON p.ID = cd.donation_id\n\t\t\t\tWHERE cd.campaign_id = %d\n\t\t\t\t{$status_clause};"; return $wpdb->get_var($wpdb->prepare($sql, $parameters)); }