Passed
Pull Request — master (#2028)
by Gabriel
60:53
created

UpdateDonorController::requestNeedsJsonResponse()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\App\Controllers\Donation;
6
7
use Symfony\Component\HttpFoundation\JsonResponse;
8
use Symfony\Component\HttpFoundation\RedirectResponse;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Component\HttpFoundation\Session\SessionInterface;
12
use WMDE\Fundraising\DonationContext\Domain\Model\DonorType;
13
use WMDE\Fundraising\DonationContext\UseCases\UpdateDonor\UpdateDonorRequest;
14
use WMDE\Fundraising\DonationContext\UseCases\UpdateDonor\UpdateDonorResponse;
15
use WMDE\Fundraising\Frontend\App\AccessDeniedException;
16
use WMDE\Fundraising\Frontend\App\Routes;
17
use WMDE\Fundraising\Frontend\Factories\FunFunFactory;
18
use WMDE\Fundraising\Frontend\Infrastructure\AddressType;
19
20
/**
21
 * @license GPL-2.0-or-later
22
 */
23
class UpdateDonorController {
24
25
	public const ADDRESS_CHANGE_SESSION_KEY = 'address_changed';
26
27
	public function index( Request $request, FunFunFactory $ffFactory, SessionInterface $session ): Response {
28
		$updateToken = $request->request->get( 'updateToken', '' );
29
		$accessToken = $request->query->get( 'accessToken', '' );
30
		$responseModel = $ffFactory
31
			->newUpdateDonorUseCase( $updateToken, $accessToken )
32
			->updateDonor( $this->newRequestModel( $request ) );
33
		if ( $this->requestNeedsJsonResponse( $request ) ) {
34
			return $this->createJsonResponse( $responseModel );
35
		}
36
		return $this->createHtmlResponse( $session, $ffFactory, $responseModel, $updateToken, $accessToken );
37
	}
38
39
	private function createJsonResponse( UpdateDonorResponse $responseModel ): JsonResponse {
40
		return new JsonResponse( [
41
			'state' => $responseModel->getDonation() !== null || $responseModel->isSuccessful() ? 'OK' : 'ERR',
42
			'message' => $responseModel->getErrorMessage()
43
		] );
44
	}
45
46
	private function createHtmlResponse(
47
		SessionInterface $session,
48
		FunFunFactory $ffFactory,
49
		UpdateDonorResponse $responseModel,
50
		string $updateToken,
51
		string $accessToken
52
	): Response {
53
		if ( $responseModel->getDonation() === null ) {
54
			throw new AccessDeniedException();
55
		}
56
		if ( $responseModel->isSuccessful() ) {
57
			$session->set(
58
				self::ADDRESS_CHANGE_SESSION_KEY,
59
				true
60
			);
61
			return new RedirectResponse(
62
				$ffFactory->getUrlGenerator()->generateAbsoluteUrl(
63
					Routes::SHOW_DONATION_CONFIRMATION,
64
					[
65
						'id' => $responseModel->getDonation()->getId(),
66
						'accessToken' => $accessToken
67
					]
68
				)
69
			);
70
		}
71
		return new Response(
72
			$ffFactory->newDonorUpdatePresenter()->present(
73
				$responseModel,
74
				$responseModel->getDonation(),
75
				$updateToken,
76
				$accessToken
77
			)
78
		);
79
	}
80
81
	private function newRequestModel( Request $request ): UpdateDonorRequest {
82
		return UpdateDonorRequest::newInstance()
83
			->withType(
84
				$this->getAddressType( $request )
85
			)
86
			->withDonationId( intval( $request->get( 'donation_id', '' ) ) )
87
			->withCity( $request->get( 'city', '' ) )
88
			->withCompanyName( $request->get( 'companyName', '' ) )
89
			->withCountryCode( $request->get( 'country', '' ) )
90
			->withEmailAddress( $request->get( 'email', '' ) )
91
			->withFirstName( $request->get( 'firstName', '' ) )
92
			->withLastName( $request->get( 'lastName', '' ) )
93
			->withPostalCode( $request->get( 'postcode', '' ) )
94
			->withSalutation( $request->get( 'salutation', '' ) )
95
			->withStreetAddress( $request->get( 'street', '' ) )
96
			->withTitle( $request->get( 'title', '' ) );
97
	}
98
99
	/**
100
	 * Get UpdateDonorRequest donor type from HTTP request field.
101
	 *
102
	 * Assumes "Anonymous" when field is not set or invalid.
103
	 *
104
	 * @param Request $request
105
	 *
106
	 * @return DonorType
107
	 */
108
	private function getAddressType( Request $request ): DonorType {
109
		try {
110
			return DonorType::make(
111
				AddressType::presentationAddressTypeToDomainAddressType( $request->get( 'addressType', '' ) )
112
			);
113
		} catch ( \UnexpectedValueException $e ) {
114
			return DonorType::ANONYMOUS();
115
		}
116
	}
117
118
	private function requestNeedsJsonResponse( Request $request ): bool {
119
		$contentTypes = $request->getAcceptableContentTypes();
120
		return count( $contentTypes ) > 0 && $contentTypes[0] === 'application/json';
121
	}
122
}
123