Passed
Push — master ( 3384db...78f140 )
by Paul
04:58
created

CreateReview::sendEmailNotification()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 0
cts 15
cp 0
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 11
nc 16
nop 2
crap 30
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Handlers;
4
5
use Exception;
6
use GeminiLabs\SiteReviews\Commands\CreateReview as Command;
7
use GeminiLabs\SiteReviews\Database\OptionManager;
8
use GeminiLabs\SiteReviews\Modules\Email;
9
use GeminiLabs\SiteReviews\Modules\Session;
10
use ReflectionException;
11
12
class CreateReview
13
{
14
	/**
15
	 * @return void|string
16
	 */
17
	public function handle( Command $command )
18
	{
19
		$post_id = glsr_db()->createReview( $this->normalize( $command ), $command );
20
		glsr_db()->setReviewMeta( $post_id, $command->category );
21
		$this->sendNotification( $post_id, $command );
22
		$successMessage = apply_filters( 'site-reviews/local/review/submitted/message',
23
			__( 'Your review has been submitted!', 'site-reviews' ),
24
			$command
25
		);
26
		do_action( 'site-reviews/local/review/submitted', $successMessage, $command );
27
		if( $command->ajaxRequest ) {
28
			glsr( Session::class )->clear();
29
			return $successMessage;
30
		}
31
		glsr( Session::class )->set( $command->formId.'-message', $successMessage );
32
		wp_safe_redirect( $command->referrer );
33
		exit;
1 ignored issue
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
34
	}
35
36
	/**
37
	 * @return \GeminiLabs\SiteReviews\Email
0 ignored issues
show
Bug introduced by
The type GeminiLabs\SiteReviews\Email was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
38
	 */
39
	protected function createEmailNotification( Command $command, array $args = [] )
40
	{
41
		$email = [
42
			'to' => $args['recipient'],
43
			'subject' => $args['notification_title'],
44
			'template' => 'review-notification',
45
			'template-tags' => [
46
				'review_author' => $command->author,
47
				'review_content' => $command->content,
48
				'review_email' => $command->email,
49
				'review_ip' => $command->ipAddress,
50
				'review_link' => sprintf( '<a href="%1$s">%1$s</a>', $args['notification_link'] ),
51
				'review_rating' => $command->rating,
52
				'review_title' => $command->title,
53
			],
54
		];
55
		return glsr( Email::class )->compose( $email );
56
	}
57
58
	/**
59
	 * @return string
60
	 */
61
	protected function createWebhookNotification( Command $command, array $args )
62
	{
63
		$fields = [];
64
		$fields[] = ['title' => str_repeat( ':star:', (int) $command->rating )];
65
		if( $command->title ) {
66
			$fields[] = ['title' => $command->title];
67
		}
68
		if( $command->content ) {
69
			$fields[] = ['value' => $command->content];
70
		}
71
		if( $command->email ) {
72
			$command->email = ' <'.$command->email.'>';
73
		}
74
		if( $command->author ) {
75
			$fields[] = ['value' => trim( $command->author.$command->email.' - '.$command->ipAddress )];
76
		}
77
		$fields[] = ['value' => sprintf( '<%s|%s>', $args['notification_link'], __( 'View Review', 'site-reviews' ))];
78
		return json_encode([
79
			'icon_url' => glsr()->url.'assets/img/icon.png',
80
			'username' => glsr()->name,
81
			'attachments' => [[
82
				'pretext' => $args['notification_title'],
83
				'color' => '#665068',
84
				'fallback' => $this->createEmailNotification( $command, $args )->read( 'plaintext' ),
85
				'fields' => $fields,
86
			]],
87
		]);
88
	}
89
90
	/**
91
	 * @return array
92
	 */
93
	protected function normalize( Command $command )
94
	{
95
		$review = [
96
			'author' => $command->author,
97
			'assigned_to' => $command->assignedTo,
98
			'avatar' => get_avatar_url( $command->email ),
99
			'content' => $command->content,
100
			'email' => $command->email,
101
			'ip_address' => $command->ipAddress,
102
			'rating' => $command->rating,
103
			'review_type' => 'local',
104
			'title' => $command->title,
105
		];
106
		return apply_filters( 'site-reviews/local/review', $review, $command );
107
	}
108
109
	/**
110
	 * @param int $post_id
111
	 * @return void|bool|array|WP_Error
0 ignored issues
show
Bug introduced by
The type GeminiLabs\SiteReviews\Handlers\WP_Error was not found. Did you mean WP_Error? If so, make sure to prefix the type with \.
Loading history...
112
	 */
113
	protected function sendNotification( $post_id, Command $command )
114
	{
115
		$notificationType = glsr( OptionManager::class )->get( 'settings.general.notification' );
116
		if( !in_array( $notificationType, ['default','custom','webhook'] ))return;
117
		$assignedToTitle = get_the_title( (int) $command->assignedTo );
118
		$notificationSubject = _nx(
119
			'New %s-star review',
120
			'New %s-star review of: %s',
121
			(int) empty( $assignedToTitle ),
122
			'The text is different depending on whether or not the review has been assigned to a post.',
123
			'site-reviews'
124
		);
125
		$notificationTitle = sprintf( '[%s] %s',
126
			wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ),
0 ignored issues
show
Bug introduced by
It seems like get_option('blogname') can also be of type false; however, parameter $string of wp_specialchars_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

126
			wp_specialchars_decode( /** @scrutinizer ignore-type */ get_option( 'blogname' ), ENT_QUOTES ),
Loading history...
127
			sprintf( $notificationSubject, $command->rating, $assignedToTitle )
128
		);
129
		$args = [
130
			'notification_link' => esc_url( admin_url( sprintf( 'post.php?post=%s&action=edit', $post_id ))),
131
			'notification_title' => $notificationTitle,
132
			'notification_type' => $notificationType,
133
		];
134
		return $args['notification_type'] == 'webhook'
135
			? $this->sendWebhookNotification( $command, $args )
136
			: $this->sendEmailNotification( $command, $args );
137
	}
138
139
	/**
140
	 * @return bool
141
	 */
142
	protected function sendEmailNotification( Command $command, array $args )
143
	{
144
		$args['recipient'] = $args['notification_type'] === 'default'
145
			? get_option( 'admin_email' )
146
			: glsr( OptionManager::class )->get( 'settings.general.notification_email' );
147
		$result = !empty( $args['recipient'] )
148
			? $this->createEmailNotification( $command, $args )->send()
149
			: false;
150
		if( $result === null ) {
151
			glsr_log( __( 'Email notification was not sent: missing email, subject, or message.', 'site-reviews' ), 'error' );
152
		}
153
		if( $result === false ) {
154
			glsr_log( __( 'Email notification was not sent: wp_mail() failed.', 'site-reviews' ), 'error' );
155
		}
156
		return (bool) $result;
157
	}
158
159
	/**
160
	 * @return array|WP_Error
161
	 */
162
	protected function sendWebhookNotification( Command $command, array $args )
163
	{
164
		$notification = $this->createWebhookNotification( $command, $args );
165
		$result = wp_remote_post( $endpoint, [
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $endpoint seems to be never defined.
Loading history...
166
			'method' => 'POST',
167
			'timeout' => 45,
168
			'redirection' => 5,
169
			'httpversion' => '1.0',
170
			'blocking' => false,
171
			'sslverify' => false,
172
			'headers' => ['Content-Type' => 'application/json'],
173
			'body' => apply_filters( 'site-reviews/webhook/notification', $notification, $command ),
174
		]);
175
		if( is_wp_error( $result )) {
176
			glsr_log( $result->get_error_message(), 'error' );
177
		}
178
		return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result also could return the type WP_Error which is incompatible with the documented return type GeminiLabs\SiteReviews\Handlers\WP_Error|array.
Loading history...
179
	}
180
}
181