<?php
namespace Give\Subscriptions\ViewModels;
use Give\API\REST\V3\Routes\Donors\ValueObjects\DonorAnonymousMode;
use Give\Framework\PaymentGateways\Contracts\Subscription\SubscriptionTransactionsSynchronizable;
use Give\Framework\PaymentGateways\PaymentGatewayRegister;
use Give\Framework\Support\Facades\Str;
use Give\Subscriptions\Models\Subscription;
/**
* @since 4.8.0
*/
class SubscriptionViewModel
{
private Subscription $subscription;
private DonorAnonymousMode $anonymousMode;
private bool $includeSensitiveData = false;
/**
* @since 4.8.0
*/
public function __construct(Subscription $subscription)
{
$this->subscription = $subscription;
}
/**
* @since 4.8.0
*/
public function includeSensitiveData(bool $includeSensitiveData = true): SubscriptionViewModel
{
$this->includeSensitiveData = $includeSensitiveData;
return $this;
}
/**
* @since 4.8.0
*/
public function anonymousMode(DonorAnonymousMode $mode): SubscriptionViewModel
{
$this->anonymousMode = $mode;
return $this;
}
/**
* @since 4.14.0 lastName should return only the first letter when sensitive data is not included
* @since 4.10.0 added campaignId
* @since 4.8.0
*/
public function exports(): array
{
$donor = $this->subscription->donor;
$data = array_merge(
$this->subscription->toArray(),
[
'firstName' => $donor ? $donor->firstName : '',
'lastName' => $donor ? $donor->lastName : '',
'gateway' => $this->getGatewayDetails(),
'projectedAnnualRevenue' => $this->subscription->projectedAnnualRevenue(),
'campaignId' => $this->subscription->campaign ? $this->subscription->campaign->id : null,
]
);
if (!$this->includeSensitiveData) {
$sensitiveDataExcluded = [
'transactionId',
'gatewaySubscriptionId',
'lastName',
];
foreach ($sensitiveDataExcluded as $propertyName) {
switch ($propertyName) {
case 'lastName':
$data[$propertyName] = Str::substr($data[$propertyName], 0, 1);
break;
default:
$data[$propertyName] = '';
break;
}
}
}
if (isset($this->anonymousMode) && $this->anonymousMode->isRedacted() && $this->subscription->donor->isAnonymous()) {
$anonymousDataRedacted = [
'donorId',
'firstName',
'lastName',
];
foreach ($anonymousDataRedacted as $propertyName) {
switch ($propertyName) {
case 'donorId':
$data[$propertyName] = 0;
break;
default:
$data[$propertyName] = __('anonymous', 'give');
break;
}
}
}
return $data;
}
/**
* @since 4.14.0 Return gateway details without subscriptionUrl when sensitive data is not included
* @since 4.10.0 Return null if subscription URL is not available
* @since 4.8.0
*/
private function getGatewayDetails(): ?array
{
if (empty($this->subscription->gatewayId) || !give(PaymentGatewayRegister::class)->hasPaymentGateway($this->subscription->gatewayId)) {
return null;
}
if (!$this->includeSensitiveData) {
return $this->subscription->gateway()->toArray();
}
$subscriptionUrl = $this->subscription->gateway()->gatewayDashboardSubscriptionUrl($this->subscription);
return array_merge(
$this->subscription->gateway()->toArray(),
[
'subscriptionUrl' => $subscriptionUrl ?: null,
'canSync' => $this->subscription->gateway()->subscriptionModule instanceof SubscriptionTransactionsSynchronizable
]
);
}
}