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

Discord   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 144
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 3
Bugs 0 Features 1
Metric Value
wmc 15
eloc 72
dl 0
loc 144
ccs 0
cts 88
cp 0
rs 10
c 3
b 0
f 1

9 Methods

Rating   Name   Duplication   Size   Complexity  
A description() 0 9 1
A rating() 0 6 1
A __construct() 0 3 1
A title() 0 6 2
A assignedLinks() 0 6 2
A fields() 0 26 1
A send() 0 18 3
A compose() 0 21 2
A moderationLinks() 0 8 2
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Modules;
4
5
use GeminiLabs\SiteReviews\Contracts\WebhookContract;
6
use GeminiLabs\SiteReviews\Defaults\DiscordDefaults;
7
use GeminiLabs\SiteReviews\Review;
8
9
/**
10
 * @link https://message.style/app/
11
 */
12
class Discord implements WebhookContract
13
{
14
    /**
15
     * @var array
16
     */
17
    public $args;
18
19
    /**
20
     * @var array
21
     */
22
    public $notification;
23
24
    /**
25
     * @var Review
26
     */
27
    public $review;
28
29
    /**
30
     * @var string
31
     */
32
    public $webhook;
33
34
    public function __construct()
35
    {
36
        $this->webhook = glsr_get_option('general.notification_discord');
37
    }
38
39
    /**
40
     * @return WebhookContract
41
     */
42
    public function compose(Review $review, array $args)
43
    {
44
        if (empty($this->webhook)) {
45
            return $this;
46
        }
47
        $this->args = glsr(DiscordDefaults::class)->restrict($args);
48
        $this->review = $review;
49
        $notification = [
50
            'content' => $this->args['header'],
51
            'embeds' => [
52
                [
53
                    'color' => $this->args['color'],
54
                    'description' => $this->description(), // rating and content
55
                    'fields' => $this->fields(),
56
                    'title' => $this->title(),
57
                    // 'url' => '',
58
                ],
59
            ],
60
        ];
61
        $this->notification = glsr()->filterArray('discord/notification', $notification, $this);
62
        return $this;
63
    }
64
65
    public function send(): bool
66
    {
67
        if (empty($this->webhook)) {
68
            $result = new \WP_Error('discord', 'Discord notification was not sent: missing webhook');
69
        } else {
70
            $result = wp_remote_post($this->webhook, [
71
                'blocking' => false,
72
                'body' => wp_json_encode($this->notification),
73
                'headers' => [
74
                    'Content-Type' => 'application/json',
75
                ],
76
            ]);
77
        }
78
        if (is_wp_error($result)) {
79
            glsr_log()->error($result->get_error_message())->debug($this->notification);
80
            return false;
81
        }
82
        return true;
83
    }
84
85
    protected function assignedLinks(): string
86
    {
87
        if (empty($this->args['assigned_links'])) {
88
            return '';
89
        }
90
        return sprintf(__('Review of %s', 'site-reviews'), $this->args['assigned_links']);
91
    }
92
93
    protected function description(): string
94
    {
95
        $parts = [
96
            $this->rating(),
97
            $this->assignedLinks(),
98
            $this->review->content,
99
        ];
100
        $parts = array_filter($parts);
101
        return implode(PHP_EOL.PHP_EOL, $parts);
102
    }
103
104
    protected function fields(): array
105
    {
106
        $fields = [
107
            'name' => [
108
                'name' => 'Name',
109
                'value' => $this->review->name,
110
                'inline' => true,
111
            ],
112
            'email' => [
113
                'name' => 'Email',
114
                'value' => $this->review->email,
115
                'inline' => true,
116
            ],
117
            'ip_address' => [
118
                'name' => 'IP Address',
119
                'value' => $this->review->ip_address,
120
                'inline' => true,
121
            ],
122
        ];
123
        $fields = glsr()->filterArray('discord/fields', $fields, $this->review);
124
        $fields['moderation_links'] = [
125
            'name' => ' ', // because a minimum of 1 char is required
126
            'value' => $this->moderationLinks(),
127
            'inline' => false,
128
        ];
129
        return array_values($fields);
130
    }
131
132
    protected function moderationLinks(): string
133
    {
134
        $links = [];
135
        if (!$this->review->is_approved) {
136
            $links[] = sprintf('[%s](%s)', __('Approve Review', 'site-reviews'), $this->review->approveUrl());
137
        }
138
        $links[] = sprintf('[%s](%s)', __('Edit Review', 'site-reviews'), $this->review->editUrl());
139
        return implode(' | ', $links);
140
    }
141
142
    protected function rating(): string
143
    {
144
        $solidStars = str_repeat('★', $this->review->rating);
145
        $emptyStars = str_repeat('☆', max(0, glsr()->constant('MAX_RATING', Rating::class) - $this->review->rating));
146
        $stars = $solidStars.$emptyStars;
147
        return glsr()->filterString('discord/stars', $stars, $this->review->rating, glsr()->constant('MAX_RATING', Rating::class));
148
    }
149
150
    protected function title(): string
151
    {
152
        $title = trim($this->review->title);
153
        return empty($title)
154
            ? __('(no title)', 'site-reviews')
155
            : $title;
156
    }
157
}
158