File: /var/www/html/wpmuhibbah_err/wp-content/plugins/give/src/DonorDashboards/Repositories/Donations.php
<?php
namespace Give\DonorDashboards\Repositories;
use Give\Framework\Database\DB;
use Give\Receipt\DonationReceipt;
use Give\Receipt\LineItem;
use Give\ValueObjects\Money;
use Give_Payment;
/**
* @since 2.10.0
*/
class Donations
{
/**
* Get donations count for donor
*
* @since 2.10.0
*
* @param int $donorId
*
* @return int
*/
public function getDonationCount($donorId)
{
$aggregate = $this->getDonationAggregate('count(revenue.id)', $donorId);
return $aggregate ? $aggregate->result : null;
}
/**
* Get donor revenue
*
* @since 2.10.0
*
* @param int $donorId
*
* @return string
*/
public function getRevenue($donorId)
{
$currencyCode = give_get_option('currency');
$aggregate = $this->getDonationAggregate('sum(revenue.amount)', $donorId);
return $aggregate ?
$this->getAmountWithSeparators(
Money::ofMinor($aggregate->result, $currencyCode)->getAmount(),
$currencyCode
) :
null;
}
/**
* Get average donor revenue
*
* @since 2.10.0
*
* @param int $donorId
*
* @return string
*/
public function getAverageRevenue($donorId)
{
$currencyCode = give_get_option('currency');
$aggregate = $this->getDonationAggregate('avg(revenue.amount)', $donorId);
return $aggregate ?
$this->getAmountWithSeparators(
Money::ofMinor($aggregate->result, $currencyCode)->getAmount(),
$currencyCode
) :
null;
}
/**
* Generates a donation aggregate for a given donor
*
* @param string $rawAggregate raw SELECT to determine what to aggregate over
* @param int $donorId
*
* @return object
*/
private function getDonationAggregate($rawAggregate, $donorId)
{
global $wpdb;
return DB::get_row(
DB::prepare(
"
SELECT {$rawAggregate} as result
FROM {$wpdb->give_revenue} as revenue
INNER JOIN {$wpdb->posts} as posts ON revenue.donation_id = posts.ID
INNER JOIN {$wpdb->prefix}give_donationmeta as donationmeta ON revenue.donation_id = donationmeta.donation_id
WHERE donationmeta.meta_key = '_give_payment_donor_id'
AND donationmeta.meta_value = %d
AND posts.post_status IN ( 'publish', 'give_subscription', 'pending' )
",
$donorId
)
);
}
/**
* Get all donation ids by donor ID
*
* @since 2.10.0
*
* @param int $donorId
*
* @return int[] Donation IDs
*/
protected function getDonationIDs($donorId)
{
$statusKeys = give_get_payment_status_keys();
$statusQuery = "'" . implode("','", $statusKeys) . "'";
global $wpdb;
return DB::get_col(
DB::prepare(
"
SELECT revenue.donation_id as id
FROM {$wpdb->give_revenue} as revenue
INNER JOIN {$wpdb->posts} as posts ON revenue.donation_id = posts.ID
INNER JOIN {$wpdb->prefix}give_donationmeta as donationmeta ON revenue.donation_id = donationmeta.donation_id
WHERE donationmeta.meta_key = '_give_payment_donor_id'
AND donationmeta.meta_value = %d
AND posts.post_status IN ( {$statusQuery} )
",
$donorId
)
);
}
/**
* Get all donations by donor ID
*
* @since 2.12.2 return null if donation ids is empty
* @since 2.10.0
*
* @param int $donorId
*
* @return array Donations
*/
public function getDonations($donorId)
{
$ids = $this->getDonationIds($donorId);
if (empty($ids)) {
return null;
}
$args = [
'number' => -1,
'post__in' => $ids,
];
$query = new \Give_Payments_Query($args);
$payments = $query->get_payments();
$donations = [];
foreach ($payments as $payment) {
$donations[] = [
'id' => $payment->ID,
'form' => $this->getFormInfo($payment),
'payment' => $this->getPaymentInfo($payment),
'donor' => $this->getDonorInfo($payment),
'receipt' => $this->getReceiptInfo($payment),
];
}
return $donations;
}
/**
* Get form info
*
* @since 2.10.0
*
* @param Give_Payment $payment
*
* @return array Payment form info
*/
protected function getFormInfo($payment)
{
return [
'title' => wp_trim_words($payment->form_title, 6, ' [...]'),
'id' => $payment->form_id,
];
}
/**
* Get payment info
*
* @since 2.10.0
* @since 2.15.0 Use WP time format for donation time.
*
* @param Give_Payment $payment
*
* @return array Payment info
*/
protected function getPaymentInfo($payment)
{
$pdfReceiptUrl = '';
if (class_exists('Give_PDF_Receipts') && function_exists('give_pdf_receipts')) {
$pdfReceiptUrl = html_entity_decode(give_pdf_receipts()->engine->get_pdf_receipt_url($payment->ID));
}
$gateways = give_get_payment_gateways();
return [
'amount' => $this->getFormattedAmount($payment->subtotal, $payment),
'currency' => $payment->currency,
'fee' => $this->getFormattedAmount(($payment->total - $payment->subtotal), $payment),
'total' => $this->getFormattedAmount($payment->total, $payment),
'method' => isset($gateways[$payment->gateway]['checkout_label']) ? $gateways[$payment->gateway]['checkout_label'] : '',
'status' => $this->getFormattedStatus($payment->status),
'date' => date_i18n(give_date_format('checkout'), strtotime($payment->date)),
'time' => date_i18n(get_option('time_format'), strtotime($payment->date)),
'mode' => $payment->get_meta('_give_payment_mode'),
'pdfReceiptUrl' => $pdfReceiptUrl,
'serialCode' => give_is_setting_enabled(give_get_option('sequential-ordering_status', 'disabled'))
? Give()->seq_donation_number->get_serial_code($payment)
: $payment->ID,
];
}
/**
* Get array containing dynamic receipt information
*
* @since 2.25.0 replace wp_strip_all_tags with wp_kses_post
* @since 2.10.0
*
* @param Give_Payment $payment
*
* @return array
*/
protected function getReceiptInfo($payment)
{
$receipt = new DonationReceipt($payment->ID);
/**
* Fire the action for receipt object.
*
* @since 2.7.0
*/
do_action('give_new_receipt', $receipt);
$receiptArr = [];
$sectionIndex = 0;
foreach ($receipt as $section) {
// Continue if section does not have line items.
if ( ! $section->getLineItems()) {
continue;
}
if ('PDFReceipt' === $section->id) {
continue;
}
if ('Subscription' === $section->id) {
continue;
}
$receiptArr[$sectionIndex]['id'] = $section->id;
if ($section->label) {
$receiptArr[$sectionIndex]['label'] = $section->label;
}
/* @var LineItem $lineItem */
foreach ($section as $lineItem) {
// Continue if line item does not have value.
if ( ! $lineItem->value) {
continue;
}
// This class is required to highlight total donation amount in receipt.
$detailRowClass = '';
if (DonationReceipt::DONATIONSECTIONID === $section->id) {
$detailRowClass = 'totalAmount' === $lineItem->id ? ' total' : '';
}
$label = html_entity_decode(wp_strip_all_tags($lineItem->label));
$value = $lineItem->id === 'paymentStatus'
? $this->getFormattedStatus($payment->status)
: html_entity_decode(wp_kses_post($lineItem->value));
$receiptArr[$sectionIndex]['lineItems'][] = [
'class' => $detailRowClass,
'icon' => $this->getIcon($lineItem->icon),
'label' => $label,
'value' => $value,
];
}
$sectionIndex++;
}
return $receiptArr;
}
/**
* Get icon based on icon HTML string
*
* @since 2.10.0
*
* @param string $iconHtml
*
* @return string
*/
protected function getIcon($iconHtml)
{
if (empty($iconHtml)) {
return '';
}
$iconMap = [
'user',
'envelope',
'globe',
'calendar',
'building',
];
foreach ($iconMap as $icon) {
if (strpos($iconHtml, $icon) !== false) {
return $icon;
}
}
return 'globe';
}
/**
* Get formatted status object (used for rendering status correctly in Donor Profile)
*
* @since 2.10.0
*
* @param string $status
*
* @return array Formatted status object (with color and label)
*/
protected function getFormattedStatus($status)
{
$statusMap = [];
$colorMap = [
'publish' => '#7ad03a',
'give_subscription' => '#5bc0de',
'refunded' => '#777',
'failed' => '#a00',
'abandoned' => '#333',
'revoked' => '#d9534f',
'pending' => '#ffba00',
];
foreach (give_get_payment_statuses() as $key => $value) {
if ($status !== $key) {
continue;
}
$color = '#888';
if (in_array($key, array_keys($colorMap))) {
$color = $colorMap[$key];
}
$statusMap[$key] = [
'color' => $color,
'label' => $value,
];
}
return isset($statusMap[$status]) ? $statusMap[$status] : [
'color' => '#FFBA00',
'label' => esc_html__('Unknown', 'give'),
];
}
/**
* @since 2.10.0
*
* @param string $amount
* @param string $currencyCode
*
* @return string
*/
protected function getAmountWithSeparators($amount, $currencyCode)
{
$formatted = give_format_amount(
$amount,
[
'decimal' => false,
'sanitize' => false,
'currency' => $currencyCode,
]
);
return $formatted ?: $amount;
}
/**
* Get formatted payment amount
*
* @since 2.10.0
*
* @param Give_Payment $payment
* @param float $amount
*
* @return string Formatted payment amount (with correct decimals and currency symbol)
*/
protected function getformattedAmount($amount, $payment)
{
return give_currency_filter(
give_format_amount(
$amount,
[
'donation_id' => $payment->ID,
]
),
[
'currency_code' => $payment->currency,
'decode_currency' => true,
'sanitize' => false,
]
);
}
/**
* Get donor info
*
* @since 2.10.0
*
* @param Give_Payment $payment
*
* @return array Donor info
*/
protected function getDonorInfo($payment)
{
return $payment->user_info;
}
}