Passed
Push — main ( a0e9c5...805967 )
by Paul
07:42
created

Slack::moderationLinks()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 24
ccs 0
cts 22
cp 0
rs 9.7
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 6
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Modules;
4
5
use GeminiLabs\SiteReviews\Contracts\WebhookContract;
6
use GeminiLabs\SiteReviews\Defaults\SlackDefaults;
7
use GeminiLabs\SiteReviews\Helpers\Arr;
8
use GeminiLabs\SiteReviews\Review;
9
10
class Slack implements WebhookContract
11
{
12
    /**
13
     * @var array
14
     */
15
    public $args;
16
17
    /**
18
     * @var array
19
     */
20
    public $notification;
21
22
    /**
23
     * @var Review
24
     */
25
    public $review;
26
27
    /**
28
     * @var string
29
     */
30
    public $webhook;
31
32
    public function __construct()
33
    {
34
        $this->webhook = glsr_get_option('general.notification_slack');
35
    }
36
37
    /**
38
     * @return WebhookContract
39
     */
40
    public function compose(Review $review, array $args)
41
    {
42
        if (empty($this->webhook)) {
43
            return $this;
44
        }
45
        $this->args = glsr(SlackDefaults::class)->restrict($args);
46
        $this->review = $review;
47
        $blocks = [
48
            $this->header(),
49
            $this->title(),
50
            $this->assignedLinks(),
51
            $this->content(),
52
            $this->fields(),
53
            $this->moderationLinks(),
54
        ];
55
        $blocks = array_values(array_filter($blocks));
56
        $notification = compact('blocks');
57
        $this->notification = glsr()->filterArray('slack/notification', $notification, $this);
58
        return $this;
59
    }
60
61
    public function send(): bool
62
    {
63
        if (empty($this->webhook)) {
64
            $result = new \WP_Error('slack', 'Slack notification was not sent: missing webhook');
65
        } else {
66
            $result = wp_remote_post($this->webhook, [
67
                'blocking' => false,
68
                'body' => wp_json_encode($this->notification),
69
                'headers' => [
70
                    'Content-Type' => 'application/json',
71
                ],
72
            ]);
73
        }
74
        if (is_wp_error($result)) {
75
            glsr_log()->error($result->get_error_message())->debug($this->notification);
76
            return false;
77
        }
78
        return true;
79
    }
80
81
    protected function assignedLinks(): array
82
    {
83
        if (empty($this->args['assigned_links'])) {
84
            return [];
85
        }
86
        return [
87
           'type' => 'section',
88
           'text' => [
89
               'type' => 'mrkdwn',
90
               'text' => sprintf(__('Review of %s', 'site-reviews'), $this->args['assigned_links']),
91
           ],
92
        ];
93
    }
94
95
    protected function content(): array
96
    {
97
        if (empty(trim($this->review->content))) {
98
            return [];
99
        }
100
        return [
101
            'type' => 'section',
102
            'text' => [
103
                'type' => 'mrkdwn',
104
                'text' => trim($this->review->content),
105
            ],
106
        ];
107
    }
108
109
    protected function fields(): array
110
    {
111
        $fields = [
112
            'name' => [
113
                'name' => 'Name',
114
                'value' => $this->review->name,
115
            ],
116
            'email' => [
117
                'name' => 'Email',
118
                'value' => $this->review->email,
119
            ],
120
            'ip_address' => [
121
                'name' => 'IP Address',
122
                'value' => $this->review->ip_address,
123
            ],
124
        ];
125
        $fields = glsr()->filterArray('slack/fields', $fields, $this->review);
126
        foreach ($fields as $key => $values) {
127
            $name = Arr::get($values, 'name');
128
            $value = Arr::get($values, 'value');
129
            if (empty($name) || empty($value)) {
130
                continue;
131
            }
132
            $fields[$key] = [
133
                'type' => 'mrkdwn',
134
                'text' => sprintf('*%s:* %s', $name, $value),
135
            ];
136
        }
137
        $fields = array_values($fields);
138
        if (empty($fields)) {
139
            return [];
140
        }
141
        return [
142
            'type' => 'section',
143
            'fields' => $fields,
144
        ];
145
    }
146
147
    protected function moderationLinks(): array
148
    {
149
        $elements = [];
150
        if (!$this->review->is_approved) {
151
            $elements[] = [
152
                'type' => 'button',
153
                'text' => [
154
                    'type' => 'plain_text',
155
                    'text' => __('Approve Review', 'site-reviews'),
156
                ],
157
                'url' => $this->review->approveUrl(),
158
            ];
159
        }
160
        $elements[] = [
161
            'type' => 'button',
162
            'text' => [
163
                'type' => 'plain_text',
164
                'text' => __('Edit Review', 'site-reviews'),
165
            ],
166
            'url' => $this->review->editUrl(),
167
        ];
168
        return [
169
            'type' => 'actions',
170
            'elements' => $elements,
171
        ];
172
    }
173
174
    protected function header(): array
175
    {
176
        return [
177
            'type' => 'header',
178
            'text' => [
179
                'type' => 'plain_text',
180
                'text' => $this->args['header'],
181
            ],
182
        ];
183
    }
184
185
    protected function rating(): string
186
    {
187
        $solidStars = str_repeat('★', $this->review->rating);
188
        $emptyStars = str_repeat('☆', max(0, glsr()->constant('MAX_RATING', Rating::class) - $this->review->rating));
189
        $stars = $solidStars.$emptyStars;
190
        return glsr()->filterString('slack/stars', $stars, $this->review->rating, glsr()->constant('MAX_RATING', Rating::class));
191
    }
192
193
    protected function title(): array
194
    {
195
        $title = trim($this->review->title);
196
        if (empty($title)) {
197
            $title = __('(no title)', 'site-reviews');
198
        }
199
        return [
200
            'type' => 'section',
201
            'text' => [
202
                'type' => 'mrkdwn',
203
                'text' => sprintf("*%s*\n%s", $title, $this->rating()),
204
            ],
205
        ];
206
    }
207
}
208