Completed
Pull Request — master (#650)
by Jeroen De
19:07 queued 01:42
created

AddCommentUseCase   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 9
dl 0
loc 85
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
C addComment() 0 46 9
A requestIsAllowed() 0 3 1
A newCommentFromRequest() 0 7 1
A commentCanBePublic() 0 4 2
A commentTextPassesValidation() 0 3 1
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\DonationContext\UseCases\AddComment;
6
7
use WMDE\Fundraising\Frontend\DonationContext\Authorization\DonationAuthorizer;
8
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonationComment;
9
use WMDE\Fundraising\Frontend\DonationContext\Domain\Repositories\DonationRepository;
10
use WMDE\Fundraising\Frontend\DonationContext\Domain\Repositories\GetDonationException;
11
use WMDE\Fundraising\Frontend\DonationContext\Domain\Repositories\StoreDonationException;
12
use WMDE\Fundraising\Frontend\Validation\TextPolicyValidator;
13
14
/**
15
 * @license GNU GPL v2+
16
 * @author Jeroen De Dauw < [email protected] >
17
 * @author Gabriel Birke < [email protected] >
18
 */
19
class AddCommentUseCase {
20
21
	private $donationRepository;
22
	private $authorizationService;
23
	private $textPolicyValidator;
24
	private $commentValidator;
25
26
	public function __construct( DonationRepository $repository, DonationAuthorizer $authorizationService,
27
		TextPolicyValidator $textPolicyValidator, AddCommentValidator $commentValidator ) {
28
29
		$this->donationRepository = $repository;
30
		$this->authorizationService = $authorizationService;
31
		$this->textPolicyValidator = $textPolicyValidator;
32
		$this->commentValidator = $commentValidator;
33
	}
34
35
	public function addComment( AddCommentRequest $addCommentRequest ): AddCommentResponse {
36
		if ( !$this->requestIsAllowed( $addCommentRequest ) ) {
37
			return AddCommentResponse::newFailureResponse( 'comment_failure_access_denied' );
38
		}
39
40
		$validationResult = $this->commentValidator->validate( $addCommentRequest );
41
		if ( !$validationResult->isSuccessful() ) {
42
			return AddCommentResponse::newFailureResponse( $validationResult->getFirstViolation() );
43
		}
44
45
		try {
46
			$donation = $this->donationRepository->getDonationById( $addCommentRequest->getDonationId() );
47
		}
48
		catch ( GetDonationException $ex ) {
49
			return AddCommentResponse::newFailureResponse( 'comment_failure_donation_error' );
50
		}
51
52
		if ( $donation === null ) {
53
			return AddCommentResponse::newFailureResponse( 'comment_failure_donation_not_found' );
54
		}
55
56
		if ( $donation->getComment() !== null ) {
57
			return AddCommentResponse::newFailureResponse( 'comment_failure_donation_has_comment' );
58
		}
59
60
		$successMessage = 'comment_success_ok';
61
		if ( $donation->needsModeration() ) {
62
			$successMessage = 'comment_success_needs_moderation';
63
		}
64
65
		$donation->addComment( $this->newCommentFromRequest( $addCommentRequest ) );
66
67
		if ( !$this->commentTextPassesValidation( $addCommentRequest->getCommentText() ) ) {
68
			$donation->markForModeration();
69
			$successMessage = 'comment_success_needs_moderation';
70
		}
71
72
		try {
73
			$this->donationRepository->storeDonation( $donation );
74
		}
75
		catch ( StoreDonationException $ex ) {
76
			return AddCommentResponse::newFailureResponse( 'comment_failure_save_error' );
77
		}
78
79
		return AddCommentResponse::newSuccessResponse( $successMessage );
80
	}
81
82
	private function requestIsAllowed( AddCommentRequest $addCommentRequest ): bool {
83
		return $this->authorizationService->userCanModifyDonation( $addCommentRequest->getDonationId() );
84
	}
85
86
	private function newCommentFromRequest( AddCommentRequest $request ): DonationComment {
87
		return new DonationComment(
88
			$request->getCommentText(),
89
			$this->commentCanBePublic( $request ),
90
			$request->getAuthorDisplayName()
91
		);
92
	}
93
94
	private function commentCanBePublic( AddCommentRequest $request ): bool {
95
		return $request->isPublic()
96
			&& $this->commentTextPassesValidation( $request->getCommentText() );
97
	}
98
99
	private function commentTextPassesValidation( string $text ): bool {
100
		return $this->textPolicyValidator->textIsHarmless( $text );
101
	}
102
103
}