Completed
Push — master ( 25648a...558e7e )
by Jeroen De
14s
created

AddDonationUseCase::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 12
nc 1
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\DonationContext\UseCases\AddDonation;
6
7
use WMDE\Fundraising\Frontend\DonationContext\Authorization\DonationTokenFetcher;
8
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\Donation;
9
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonationPayment;
10
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonationTrackingInfo;
11
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\Donor;
12
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonorAddress;
13
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonorName;
14
use WMDE\Fundraising\Frontend\DonationContext\Domain\Repositories\DonationRepository;
15
use WMDE\Fundraising\Frontend\DonationContext\Infrastructure\DonationConfirmationMailer;
16
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\BankTransferPayment;
17
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\DirectDebitPayment;
18
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PaymentMethod;
19
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PaymentType;
20
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PaymentWithoutAssociatedData;
21
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PayPalData;
22
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PayPalPayment;
23
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\SofortPayment;
24
use WMDE\Fundraising\Frontend\PaymentContext\Domain\TransferCodeGenerator;
25
26
/**
27
 * @license GNU GPL v2+
28
 * @author Kai Nissen < [email protected] >
29
 * @author Jeroen De Dauw < [email protected] >
30
 */
31
class AddDonationUseCase {
32
33
	private $donationRepository;
34
	private $donationValidator;
35
	private $policyValidator;
36
	private $referrerGeneralizer;
37
	private $mailer;
38
	private $transferCodeGenerator;
39
	private $tokenFetcher;
40
	private $initialDonationStatusPicker;
41
42
	public function __construct( DonationRepository $donationRepository, AddDonationValidator $donationValidator,
43
								 AddDonationPolicyValidator $policyValidator, ReferrerGeneralizer $referrerGeneralizer,
44
								 DonationConfirmationMailer $mailer, TransferCodeGenerator $transferCodeGenerator,
45
								 DonationTokenFetcher $tokenFetcher, InitialDonationStatusPicker $initialDonationStatusPicker ) {
46
		$this->donationRepository = $donationRepository;
47
		$this->donationValidator = $donationValidator;
48
		$this->policyValidator = $policyValidator;
49
		$this->referrerGeneralizer = $referrerGeneralizer;
50
		$this->mailer = $mailer;
51
		$this->transferCodeGenerator = $transferCodeGenerator;
52
		$this->tokenFetcher = $tokenFetcher;
53
		$this->initialDonationStatusPicker = $initialDonationStatusPicker;
54
	}
55
56
	public function addDonation( AddDonationRequest $donationRequest ): AddDonationResponse {
57
		$validationResult = $this->donationValidator->validate( $donationRequest );
58
59
		if ( $validationResult->hasViolations() ) {
60
			return AddDonationResponse::newFailureResponse( $validationResult->getViolations() );
61
		}
62
63
		$donation = $this->newDonationFromRequest( $donationRequest );
64
65
		if ( $this->policyValidator->needsModeration( $donationRequest ) ) {
66
			$donation->notifyOfPolicyValidationFailure();
67
		}
68
69
		if ( $this->policyValidator->isAutoDeleted( $donationRequest ) ) {
70
			$donation->markAsDeleted();
71
		}
72
73
		// TODO: handle exceptions
74
		$this->donationRepository->storeDonation( $donation );
75
76
		// TODO: handle exceptions
77
		$tokens = $this->tokenFetcher->getTokens( $donation->getId() );
78
79
		// TODO: handle exceptions
80
		$this->sendDonationConfirmationEmail( $donation );
81
82
		return AddDonationResponse::newSuccessResponse(
83
			$donation,
84
			$tokens->getUpdateToken(),
85
			$tokens->getAccessToken()
86
		);
87
	}
88
89
	private function newDonationFromRequest( AddDonationRequest $donationRequest ): Donation {
90
		return new Donation(
91
			null,
92
			( $this->initialDonationStatusPicker )( $donationRequest->getPaymentType() ),
93
			$this->getPersonalInfoFromRequest( $donationRequest ),
94
			$this->getPaymentFromRequest( $donationRequest ),
95
			$donationRequest->getOptIn() === '1',
96
			$this->newTrackingInfoFromRequest( $donationRequest )
97
		);
98
	}
99
100
	private function getPersonalInfoFromRequest( AddDonationRequest $request ): ?Donor {
101
		if ( $request->donorIsAnonymous() ) {
102
			return null;
103
		}
104
		return new Donor(
105
			$this->getNameFromRequest( $request ),
106
			$this->getPhysicalAddressFromRequest( $request ),
107
			$request->getDonorEmailAddress()
108
		);
109
	}
110
111
	private function getPhysicalAddressFromRequest( AddDonationRequest $request ): DonorAddress {
112
		$address = new DonorAddress();
113
114
		$address->setStreetAddress( $request->getDonorStreetAddress() );
115
		$address->setPostalCode( $request->getDonorPostalCode() );
116
		$address->setCity( $request->getDonorCity() );
117
		$address->setCountryCode( $request->getDonorCountryCode() );
118
119
		return $address->freeze()->assertNoNullFields();
120
	}
121
122
	private function getNameFromRequest( AddDonationRequest $request ): DonorName {
123
		$name = $request->donorIsCompany() ? DonorName::newCompanyName() : DonorName::newPrivatePersonName();
124
125
		$name->setSalutation( $request->getDonorSalutation() );
126
		$name->setTitle( $request->getDonorTitle() );
127
		$name->setCompanyName( $request->getDonorCompany() );
128
		$name->setFirstName( $request->getDonorFirstName() );
129
		$name->setLastName( $request->getDonorLastName() );
130
131
		return $name->freeze()->assertNoNullFields();
132
	}
133
134
	private function getPaymentFromRequest( AddDonationRequest $donationRequest ): DonationPayment {
135
		return new DonationPayment(
136
			$donationRequest->getAmount(),
137
			$donationRequest->getInterval(),
138
			$this->getPaymentMethodFromRequest( $donationRequest )
139
		);
140
	}
141
142
	private function getPaymentMethodFromRequest( AddDonationRequest $donationRequest ): PaymentMethod {
143
		$paymentType = $donationRequest->getPaymentType();
144
145
		switch ( $paymentType ) {
146
			case PaymentType::BANK_TRANSFER:
147
				return new BankTransferPayment( $this->transferCodeGenerator->generateTransferCode() );
148
			case PaymentType::DIRECT_DEBIT:
149
				return new DirectDebitPayment( $donationRequest->getBankData() );
150
			case PaymentType::PAYPAL:
151
				return new PayPalPayment( new PayPalData() );
152
			case PaymentType::SOFORT:
153
				return new SofortPayment( $this->transferCodeGenerator->generateTransferCode() );
154
			default:
155
				return new PaymentWithoutAssociatedData( $paymentType );
156
		}
157
	}
158
159
	private function newTrackingInfoFromRequest( AddDonationRequest $request ): DonationTrackingInfo {
160
		$trackingInfo = new DonationTrackingInfo();
161
162
		$trackingInfo->setTracking( $request->getTracking() );
163
		$trackingInfo->setSource( $this->referrerGeneralizer->generalize( $request->getSource() ) );
164
		$trackingInfo->setTotalImpressionCount( $request->getTotalImpressionCount() );
165
		$trackingInfo->setSingleBannerImpressionCount( $request->getSingleBannerImpressionCount() );
166
		$trackingInfo->setColor( $request->getColor() );
0 ignored issues
show
Deprecated Code introduced by
The method WMDE\Fundraising\Fronten...tionRequest::getColor() has been deprecated.

This method has been deprecated.

Loading history...
167
		$trackingInfo->setSkin( $request->getSkin() );
0 ignored issues
show
Deprecated Code introduced by
The method WMDE\Fundraising\Fronten...ationRequest::getSkin() has been deprecated.

This method has been deprecated.

Loading history...
168
		$trackingInfo->setLayout( $request->getLayout() );
0 ignored issues
show
Deprecated Code introduced by
The method WMDE\Fundraising\Fronten...ionRequest::getLayout() has been deprecated.

This method has been deprecated.

Loading history...
169
170
		return $trackingInfo->freeze()->assertNoNullFields();
171
	}
172
173
	/**
174
	 * @param Donation $donation
175
	 *
176
	 * @throws \RuntimeException
177
	 */
178
	private function sendDonationConfirmationEmail( Donation $donation ): void {
179
		if ( $donation->getDonor() !== null && !$donation->hasExternalPayment() ) {
180
			$this->mailer->sendConfirmationMailFor( $donation );
181
		}
182
	}
183
184
}