Completed
Push — master ( 4f9f1a...c1b5ff )
by Jeroen De
19s
created

DoctrineDonationRepository::updateComment()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 9
nc 2
nop 2
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\DonationContext\DataAccess;
6
7
use Doctrine\ORM\EntityManager;
8
use Doctrine\ORM\ORMException;
9
use WMDE\Euro\Euro;
10
use WMDE\Fundraising\Entities\Donation as DoctrineDonation;
11
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\Donation;
12
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonationComment;
13
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonationPayment;
14
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonationTrackingInfo;
15
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\Donor;
16
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonorAddress;
17
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonorName;
18
use WMDE\Fundraising\Frontend\DonationContext\Domain\Repositories\DonationRepository;
19
use WMDE\Fundraising\Frontend\DonationContext\Domain\Repositories\GetDonationException;
20
use WMDE\Fundraising\Frontend\DonationContext\Domain\Repositories\StoreDonationException;
21
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\BankData;
22
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\BankTransferPayment;
23
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\CreditCardPayment;
24
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\CreditCardTransactionData;
25
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\DirectDebitPayment;
26
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\Iban;
27
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PaymentMethod;
28
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PaymentType;
29
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PaymentWithoutAssociatedData;
30
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PayPalData;
31
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PayPalPayment;
32
use WMDE\Fundraising\Frontend\PaymentContext\Infrastructure\CreditCardExpiry;
33
34
/**
35
 * @license GNU GPL v2+
36
 * @author Kai Nissen < [email protected] >
37
 * @author Jeroen De Dauw < [email protected] >
38
 */
39
class DoctrineDonationRepository implements DonationRepository {
40
41
	private $entityManager;
42
43
	public function __construct( EntityManager $entityManager ) {
0 ignored issues
show
Bug introduced by
You have injected the EntityManager via parameter $entityManager. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

Loading history...
44
		$this->entityManager = $entityManager;
45
	}
46
47
	public function storeDonation( Donation $donation ) {
48
		if ( $donation->getId() === null ) {
49
			$this->insertDonation( $donation );
50
		}
51
		else {
52
			$this->updateDonation( $donation );
53
		}
54
	}
55
56
	private function insertDonation( Donation $donation ) {
57
		$doctrineDonation = new DoctrineDonation();
58
		$this->updateDonationEntity( $doctrineDonation, $donation );
59
60
		try {
61
			$this->entityManager->persist( $doctrineDonation );
62
			$this->entityManager->flush();
63
		}
64
		catch ( ORMException $ex ) {
65
			throw new StoreDonationException( $ex );
66
		}
67
68
		$donation->assignId( $doctrineDonation->getId() );
69
	}
70
71
	private function updateDonation( Donation $donation ) {
72
		$doctrineDonation = $this->getDoctrineDonationById( $donation->getId() );
73
74
		if ( $doctrineDonation === null ) {
75
			throw new StoreDonationException();
76
		}
77
78
		$this->updateDonationEntity( $doctrineDonation, $donation );
79
80
		try {
81
			$this->entityManager->persist( $doctrineDonation );
82
			$this->entityManager->flush();
83
		}
84
		catch ( ORMException $ex ) {
85
			throw new StoreDonationException( $ex );
86
		}
87
	}
88
89
	private function updateDonationEntity( DoctrineDonation $doctrineDonation, Donation $donation ) {
90
		$doctrineDonation->setId( $donation->getId() );
91
		$this->updatePaymentInformation( $doctrineDonation, $donation );
92
		$this->updateDonorInformation( $doctrineDonation, $donation->getDonor() );
93
		$this->updateComment( $doctrineDonation, $donation->getComment() );
94
		$doctrineDonation->setDonorOptsIntoNewsletter( $donation->getOptsIntoNewsletter() );
95
96
		$doctrineDonation->encodeAndSetData( array_merge(
97
			$doctrineDonation->getDecodedData(),
98
			$this->getDataMap( $donation )
99
		) );
100
	}
101
102
	private function updatePaymentInformation( DoctrineDonation $doctrineDonation, Donation $donation ) {
103
		$doctrineDonation->setStatus( $donation->getStatus() );
104
		$doctrineDonation->setAmount( $donation->getAmount()->getEuroString() );
105
		$doctrineDonation->setPaymentIntervalInMonths( $donation->getPaymentIntervalInMonths() );
106
107
		$doctrineDonation->setPaymentType( $donation->getPaymentType() );
108
		$doctrineDonation->setBankTransferCode( $this->getBankTransferCode( $donation->getPaymentMethod() ) );
109
	}
110
111
	private function updateDonorInformation( DoctrineDonation $doctrineDonation, Donor $donor = null ) {
112
		if ( $donor === null ) {
113
			$doctrineDonation->setDonorFullName( 'Anonym' );
114
		} else {
115
			$doctrineDonation->setDonorCity( $donor->getPhysicalAddress()->getCity() );
116
			$doctrineDonation->setDonorEmail( $donor->getEmailAddress() );
117
			$doctrineDonation->setDonorFullName( $donor->getName()->getFullName() );
118
		}
119
	}
120
121
	private function updateComment( DoctrineDonation $doctrineDonation, DonationComment $comment = null ) {
122
		if ( $comment === null ) {
123
			$doctrineDonation->setIsPublic( false );
124
			$doctrineDonation->setComment( '' );
125
			$doctrineDonation->setPublicRecord( '' );
126
		} else {
127
			$doctrineDonation->setIsPublic( $comment->isPublic() );
128
			$doctrineDonation->setComment( $comment->getCommentText() );
129
			$doctrineDonation->setPublicRecord( $comment->getAuthorDisplayName() );
130
		}
131
	}
132
133
	private function getBankTransferCode( PaymentMethod $paymentMethod ): string {
134
		if ( $paymentMethod instanceof BankTransferPayment ) {
135
			return $paymentMethod->getBankTransferCode();
136
		}
137
138
		return '';
139
	}
140
141
	private function getDataMap( Donation $donation ): array {
142
		return array_merge(
143
			$this->getDataFieldsFromTrackingInfo( $donation->getTrackingInfo() ),
144
			$this->getDataFieldsForPaymentData( $donation->getPaymentMethod() ),
145
			$this->getDataFieldsFromDonor( $donation->getDonor() )
146
		);
147
	}
148
149
	private function getDataFieldsFromTrackingInfo( DonationTrackingInfo $trackingInfo ): array {
150
		return [
151
			'layout' => $trackingInfo->getLayout(),
152
			'impCount' => $trackingInfo->getTotalImpressionCount(),
153
			'bImpCount' => $trackingInfo->getSingleBannerImpressionCount(),
154
			'tracking' => $trackingInfo->getTracking(),
155
			'skin' => $trackingInfo->getSkin(),
156
			'color' => $trackingInfo->getColor(),
157
			'source' => $trackingInfo->getSource(),
158
		];
159
	}
160
161
	private function getDataFieldsForPaymentData( PaymentMethod $paymentMethod ): array {
162
		if ( $paymentMethod instanceof DirectDebitPayment ) {
163
			return $this->getDataFieldsFromBankData( $paymentMethod->getBankData() );
164
		}
165
166
		if ( $paymentMethod instanceof PayPalPayment ) {
167
			return $this->getDataFieldsFromPayPalData( $paymentMethod->getPayPalData() );
0 ignored issues
show
Bug introduced by
It seems like $paymentMethod->getPayPalData() can be null; however, getDataFieldsFromPayPalData() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
168
		}
169
170
		if ( $paymentMethod instanceof CreditCardPayment ) {
171
			return $this->getDataFieldsFromCreditCardData( $paymentMethod->getCreditCardData() );
0 ignored issues
show
Bug introduced by
It seems like $paymentMethod->getCreditCardData() can be null; however, getDataFieldsFromCreditCardData() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
172
		}
173
174
		return [];
175
	}
176
177
	private function getDataFieldsFromBankData( BankData $bankData ): array {
178
		return [
179
			'iban' => $bankData->getIban()->toString(),
180
			'bic' => $bankData->getBic(),
181
			'konto' => $bankData->getAccount(),
182
			'blz' => $bankData->getBankCode(),
183
			'bankname' => $bankData->getBankName(),
184
		];
185
	}
186
187
	private function getDataFieldsFromDonor( Donor $personalInfo = null ): array {
188
		if ( $personalInfo === null ) {
189
			return [ 'adresstyp' => 'anonym' ];
190
		}
191
192
		return array_merge(
193
			$this->getDataFieldsFromPersonName( $personalInfo->getName() ),
194
			$this->getDataFieldsFromAddress( $personalInfo->getPhysicalAddress() ),
195
			[ 'email' => $personalInfo->getEmailAddress() ]
196
		);
197
	}
198
199
	private function getDataFieldsFromPersonName( DonorName $name ) {
200
		return [
201
			'adresstyp' => $name->getPersonType(),
202
			'anrede' => $name->getSalutation(),
203
			'titel' => $name->getTitle(),
204
			'vorname' => $name->getFirstName(),
205
			'nachname' => $name->getLastName(),
206
			'firma' => $name->getCompanyName(),
207
		];
208
	}
209
210
	private function getDataFieldsFromAddress( DonorAddress $address ) {
211
		return [
212
			'strasse' => $address->getStreetAddress(),
213
			'plz' => $address->getPostalCode(),
214
			'ort' => $address->getCity(),
215
			'country' => $address->getCountryCode(),
216
		];
217
	}
218
219
	private function getDataFieldsFromPayPalData( PayPalData $payPalData ) {
220
		return [
221
			'paypal_payer_id' => $payPalData->getPayerId(),
222
			'paypal_subscr_id' => $payPalData->getSubscriberId(),
223
			'paypal_payer_status' => $payPalData->getPayerStatus(),
224
			'paypal_address_status' => $payPalData->getAddressStatus(),
225
			'paypal_mc_gross' => $payPalData->getAmount()->getEuroString(),
226
			'paypal_mc_currency' => $payPalData->getCurrencyCode(),
227
			'paypal_mc_fee' => $payPalData->getFee()->getEuroString(),
228
			'paypal_settle_amount' => $payPalData->getSettleAmount()->getEuroString(),
229
			'paypal_first_name' => $payPalData->getFirstName(),
230
			'paypal_last_name' => $payPalData->getLastName(),
231
			'paypal_address_name' => $payPalData->getAddressName(),
232
			'ext_payment_id' => $payPalData->getPaymentId(),
233
			'ext_subscr_id' => $payPalData->getSubscriberId(),
234
			'ext_payment_type' => $payPalData->getPaymentType(),
235
			'ext_payment_status' => $payPalData->getPaymentStatus(),
236
			'ext_payment_account' => $payPalData->getPayerId(),
237
			'ext_payment_timestamp' => $payPalData->getPaymentTimestamp()
238
		];
239
	}
240
241
	private function getDataFieldsFromCreditCardData( CreditCardTransactionData $ccData ) {
242
		return [
243
			'ext_payment_id' => $ccData->getTransactionId(),
244
			'ext_payment_status' => $ccData->getTransactionStatus(),
245
			'ext_payment_timestamp' => $ccData->getTransactionTimestamp()->format( \DateTime::ATOM ),
246
			'mcp_amount' => $ccData->getAmount()->getEuroString(),
247
			'ext_payment_account' => $ccData->getCustomerId(),
248
			'mcp_sessionid' => $ccData->getSessionId(),
249
			'mcp_auth' => $ccData->getAuthId(),
250
			'mcp_title' => $ccData->getTitle(),
251
			'mcp_country' => $ccData->getCountryCode(),
252
			'mcp_currency' => $ccData->getCurrencyCode(),
253
			'mcp_cc_expiry_date' => $this->getExpirationDateAsString( $ccData->getCardExpiry() )
254
		];
255
	}
256
257
	private function getExpirationDateAsString( CreditCardExpiry $cardExpiry = null ): string {
258
		if ( $cardExpiry === null ) {
259
			return '';
260
		}
261
262
		return implode( '/', [ $cardExpiry->getMonth(), $cardExpiry->getYear() ] );
263
	}
264
265
	/**
266
	 * @param int $id
267
	 *
268
	 * @return Donation|null
269
	 * @throws GetDonationException
270
	 */
271
	public function getDonationById( int $id ) {
272
		try {
273
			$donation = $this->getDoctrineDonationById( $id );
274
		}
275
		catch ( ORMException $ex ) {
276
			throw new GetDonationException( $ex );
277
		}
278
279
		if ( $donation === null ) {
280
			return null;
281
		}
282
283
		return $this->newDonationDomainObject( $donation );
284
	}
285
286
	/**
287
	 * @param int $id
288
	 * @return DoctrineDonation|null
289
	 * @throws ORMException
290
	 */
291
	public function getDoctrineDonationById( int $id ) {
292
		return $this->entityManager->getRepository( DoctrineDonation::class )->findOneBy( [
293
			'id' => $id,
294
			'deletionTime' => null
295
		] );
296
	}
297
298
	private function newDonationDomainObject( DoctrineDonation $dd ): Donation {
299
		return new Donation(
300
			$dd->getId(),
301
			$dd->getStatus(),
302
			$this->getDonorFromEntity( $dd ),
303
			$this->getPaymentFromEntity( $dd ),
304
			(bool)$dd->getDonorOptsIntoNewsletter(),
305
			$this->getTrackingInfoFromEntity( $dd ),
306
			$this->getCommentFromEntity( $dd )
307
		);
308
	}
309
310
	/**
311
	 * @param DoctrineDonation $dd
312
	 *
313
	 * @return Donor|null
314
	 */
315
	private function getDonorFromEntity( DoctrineDonation $dd ) {
316
		if ( $dd->getDonorEmail() === null ) {
317
			return null;
318
		}
319
320
		// This should not happen, but it does (but only with PayPal payments in production), so as a step towards fixing this, we log
321
		if ( $this->entityHasMissingFields( $dd ) ) {
322
			error_log( sprintf(
323
				'Entity %d has missing fields. Field data: %s',
324
				$dd->getId(),
325
				var_export( $dd->getDecodedData(), true ) )
326
			);
327
			error_log( implode( "\n", array_map( function( $bt ) {
328
				return sprintf( '%s, line %d, %s', $bt['file'], $bt['line'], $bt['function'] );
329
			}, debug_backtrace() ) ) );
330
			return null;
331
		}
332
333
		return new Donor(
334
			$this->getPersonNameFromEntity( $dd ),
335
			$this->getPhysicalAddressFromEntity( $dd ),
336
			$dd->getDonorEmail()
337
		);
338
	}
339
340
	private function getPaymentFromEntity( DoctrineDonation $dd ): DonationPayment {
341
		return new DonationPayment(
342
			Euro::newFromString( $dd->getAmount() ),
343
			$dd->getPaymentIntervalInMonths(),
344
			$this->getPaymentMethodFromEntity( $dd )
345
		);
346
	}
347
348
	private function getPaymentMethodFromEntity( DoctrineDonation $dd ): PaymentMethod {
349
		if ( $dd->getPaymentType() === PaymentType::BANK_TRANSFER ) {
350
			return new BankTransferPayment( $dd->getBankTransferCode() );
351
		}
352
353
		if ( $dd->getPaymentType() === PaymentType::DIRECT_DEBIT ) {
354
			return new DirectDebitPayment( $this->getBankDataFromEntity( $dd ) );
0 ignored issues
show
Bug introduced by
It seems like $this->getBankDataFromEntity($dd) can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
355
		}
356
357
		if ( $dd->getPaymentType() === PaymentType::PAYPAL ) {
358
			return new PayPalPayment( $this->getPayPalDataFromEntity( $dd ) );
359
		}
360
361
		if ( $dd->getPaymentType() === PaymentType::CREDIT_CARD ) {
362
			return new CreditCardPayment( $this->getCreditCardDataFromEntity( $dd ) );
363
		}
364
365
		return new PaymentWithoutAssociatedData( $dd->getPaymentType() );
366
	}
367
368
	private function getPersonNameFromEntity( DoctrineDonation $dd ): DonorName {
369
		$data = $dd->getDecodedData();
370
371
		$name = $data['adresstyp'] === DonorName::PERSON_COMPANY
372
			? DonorName::newCompanyName() : DonorName::newPrivatePersonName();
373
374
		$name->setSalutation( $data['anrede'] );
375
		$name->setTitle( $data['titel'] );
376
		$name->setFirstName( $data['vorname'] );
377
		$name->setLastName( $data['nachname'] );
378
		$name->setCompanyName( $data['firma'] );
379
380
		return $name->freeze()->assertNoNullFields();
381
	}
382
383
	private function getPhysicalAddressFromEntity( DoctrineDonation $dd ): DonorAddress {
384
		$data = $dd->getDecodedData();
385
386
		$address = new DonorAddress();
387
388
		$address->setStreetAddress( $data['strasse'] );
389
		$address->setCity( $data['ort'] );
390
		$address->setPostalCode( $data['plz'] );
391
		$address->setCountryCode( $data['country'] );
392
393
		return $address->freeze()->assertNoNullFields();
394
	}
395
396
	/**
397
	 * @param DoctrineDonation $dd
398
	 *
399
	 * @return BankData|null
400
	 */
401
	private function getBankDataFromEntity( DoctrineDonation $dd ) {
402
		$data = $dd->getDecodedData();
403
404
		if ( array_key_exists( 'iban', $data ) ) {
405
			$bankData = new BankData();
406
407
			$bankData->setIban( new Iban( $data['iban'] ) );
408
			$bankData->setBic( $data['bic'] );
409
			$bankData->setAccount( $data['konto'] );
410
			$bankData->setBankCode( $data['blz'] );
411
			$bankData->setBankName( $data['bankname'] );
412
413
			return $bankData->freeze()->assertNoNullFields();
414
		}
415
416
		return null;
417
	}
418
419
	private function getTrackingInfoFromEntity( DoctrineDonation $dd ): DonationTrackingInfo {
420
		$data = $dd->getDecodedData();
421
422
		$trackingInfo = new DonationTrackingInfo();
423
424
		$trackingInfo->setLayout( $data['layout'] );
425
		$trackingInfo->setTotalImpressionCount( $data['impCount'] );
426
		$trackingInfo->setSingleBannerImpressionCount( $data['bImpCount'] );
427
		$trackingInfo->setTracking( $data['tracking'] );
428
		$trackingInfo->setSkin( $data['skin'] );
429
		$trackingInfo->setColor( $data['color'] );
430
		$trackingInfo->setSource( $data['source'] );
431
432
		return $trackingInfo->freeze()->assertNoNullFields();
433
	}
434
435
	/**
436
	 * @param DoctrineDonation $dd
437
	 * @return PayPalData|null
438
	 */
439
	private function getPayPalDataFromEntity( DoctrineDonation $dd ) {
440
		$data = $dd->getDecodedData();
441
442
		if ( array_key_exists( 'paypal_payer_id', $data ) ) {
443
			return ( new PayPalData() )
444
				->setPayerId( $data['paypal_payer_id'] )
445
				->setSubscriberId( $data['paypal_subscr_id'] )
446
				->setPayerStatus( $data['paypal_payer_status'] )
447
				->setAddressStatus( $data['paypal_address_status'] )
448
				->setAmount( Euro::newFromString( $data['paypal_mc_gross'] ) )
449
				->setCurrencyCode( $data['paypal_mc_currency'] )
450
				->setFee( Euro::newFromString( $data['paypal_mc_fee'] ) )
451
				->setSettleAmount( Euro::newFromString( $data['paypal_settle_amount'] ) )
452
				->setFirstName( $data['paypal_first_name'] )
453
				->setLastName( $data['paypal_last_name'] )
454
				->setAddressName( $data['paypal_address_name'] )
455
				->setPaymentId( $data['ext_payment_id'] )
456
				->setPaymentType( $data['ext_payment_type'] )
457
				->setPaymentStatus( $data['ext_payment_status'] )
458
				->setPaymentTimestamp( $data['ext_payment_timestamp'] )
459
				->freeze()->assertNoNullFields();
460
		}
461
462
		return null;
463
	}
464
465
	/**
466
	 * @param DoctrineDonation $dd
467
	 * @return CreditCardTransactionData|null
468
	 */
469
	private function getCreditCardDataFromEntity( DoctrineDonation $dd ) {
470
		$data = $dd->getDecodedData();
471
472
		if ( array_key_exists( 'mcp_auth', $data ) ) {
473
			return ( new CreditCardTransactionData() )
474
				->setTransactionId( $data['ext_payment_id'] )
475
				->setTransactionStatus( $data['ext_payment_status'] )
476
				->setTransactionTimestamp( new \DateTime( $data['ext_payment_timestamp'] ) )
477
				->setAmount( Euro::newFromString( $data['mcp_amount'] ) )
478
				->setCustomerId( $data['ext_payment_account'] )
479
				->setSessionId( $data['mcp_sessionid'] )
480
				->setAuthId( $data['mcp_auth'] )
481
				->setCardExpiry( CreditCardExpiry::newFromString( $data['mcp_cc_expiry_date'] ) )
482
				->setTitle( $data['mcp_title'] )
483
				->setCountryCode( $data['mcp_country'] )
484
				->setCurrencyCode( $data['mcp_currency'] )
485
				->freeze();
486
		}
487
488
		return null;
489
	}
490
491
	/**
492
	 * @param DoctrineDonation $dd
493
	 * @return DonationComment|null
494
	 */
495
	private function getCommentFromEntity( DoctrineDonation $dd ) {
496
		if ( $dd->getComment() === '' ) {
497
			return null;
498
		}
499
500
		return new DonationComment(
501
			$dd->getComment(),
502
			$dd->getIsPublic(),
503
			$dd->getPublicRecord()
504
		);
505
	}
506
507
	private function entityHasMissingFields( DoctrineDonation $dd ): bool {
508
		$data = $dd->getDecodedData();
509
		return
510
			!isset( $data['anrede'] ) || $data['anrede'] === null ||
511
			!isset( $data['titel'] ) || $data['titel'] === null ||
512
			!isset( $data['vorname'] ) || $data['vorname'] === null ||
513
			!isset( $data['nachname'] ) || $data['nachname'] === null ||
514
			!isset( $data['firma'] ) || $data['firma'] === null;
515
	}
516
517
}
518