MicrosoftTeamsMessage::fact()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
1
<?php
2
3
namespace NotificationChannels\MicrosoftTeams;
4
5
use NotificationChannels\MicrosoftTeams\Exceptions\CouldNotSendNotification;
6
7
class MicrosoftTeamsMessage
8
{
9
    /** @var array Params payload. */
10
    protected $payload = [];
11
12
    /** @var string webhook url of recipient. */
13
    protected $webhookUrl = null;
14
15
    /**
16
     * @param string $content
17
     *
18
     * @return self
19
     */
20
    public static function create(string $content = ''): self
21
    {
22
        return new self($content);
23
    }
24
25
    /**
26
     * Message constructor.
27
     *
28
     * @param string $content
29
     */
30 40
    public function __construct(string $content = '')
31
    {
32 40
        $this->payload['@type'] = 'MessageCard';
33 40
        $this->payload['@context'] = 'https://schema.org/extensions';
34 40
        $this->payload['summary'] = 'Incoming Notification';
35 40
        $this->payload['themeColor'] = $this->generateThemeColourCode('primary');
36 40
        $this->content($content);
37 40
    }
38
39
    /**
40
     * Set a title.
41
     *
42
     * @param string $title - title
43
     * @param array $params - optional section can be defined (e.g. [$section = '1'].
44
     *
45
     * @return MicrosoftTeamsMessage $this
46
     */
47 9
    public function title(string $title, array $params = []): self
48
    {
49
        // if section is defined add it to specified section
50 9
        if (isset($params['section'])) {
51 4
            $sectionId = $params['section'];
52 4
            $this->payload['sections'][$sectionId]['title'] = $title;
53
        } else {
54 5
            $this->payload['title'] = $title;
55 5
            $this->payload['summary'] = $title;
56
        }
57
58 9
        return $this;
59
    }
60
61
    /**
62
     * Set a summary.
63
     *
64
     * @param string $summary - summary
65
     *
66
     * @return MicrosoftTeamsMessage $this
67
     */
68 1
    public function summary(string $summary): self
69
    {
70 1
        $this->payload['summary'] = $summary;
71
72 1
        return $this;
73
    }
74
75
    /**
76
     * Add a type which is used as theme color.
77
     *
78
     * @param string $type - type of the card
79
     *
80
     * @return MicrosoftTeamsMessage $this
81
     */
82 2
    public function type(string $type): self
83
    {
84 2
        $this->payload['themeColor'] = $this->generateThemeColourCode($type);
85
86 2
        return $this;
87
    }
88
89
    /**
90
     * Notification message (Supports Markdown).
91
     *
92
     * @param string $content
93
     * @param array $params - optional section can be defined (e.g. [$section = '1'].
94
     *
95
     * @return MicrosoftTeamsMessage $this
96
     */
97 40
    public function content(string $content, array $params = []): self
98
    {
99
        // if section is defined add it to specified section
100 40
        if (isset($params['section'])) {
101 3
            $sectionId = $params['section'];
102 3
            $this->payload['sections'][$sectionId]['text'] = $content;
103
        } else {
104 40
            $this->payload['text'] = $content;
105
        }
106
107 40
        return $this;
108
    }
109
110
    /**
111
     * Add an action.
112
     *
113
     * @param string $name - name of the action
114
     * @param string $type - defaults to 'OpenUri' should be one of the following types:
115
     *  - OpenUri: Opens a URI in a separate browser or app; optionally targets different URIs based on operating systems
116
     *  - HttpPOST: Sends a POST request to a URL
117
     *  - ActionCard: Presents one or more input types and associated actions
118
     *  - InvokeAddInCommand: Opens an Outlook add-in task pane.
119
     * * @param array $params - optional params (needed for complex types and for section)
120
     * For more information check out: https://docs.microsoft.com/en-us/outlook/actionable-messages/message-card-reference
121
     *
122
     * @return MicrosoftTeamsMessage $this
123
     */
124 10
    public function action(string $name, $type = 'OpenUri', array $params = []): self
125
    {
126
127
        // fill required values for all types
128
        $newAction = [
129 10
            '@type' => $type,
130 10
            'name' => $name,
131
        ];
132
133
        // fill additional params (needed for other types than 'OpenUri')
134 10
        if (! empty($params)) {
135 10
            $newAction = array_merge($newAction, $params);
136
        }
137
138
        // if section is defined add it to specified section
139 10
        if (isset($params['section'])) {
140
            // remove unsued property from newAction array
141 3
            unset($newAction['section']);
142 3
            $sectionId = $params['section'];
143 3
            $this->payload['sections'][$sectionId]['potentialAction'][] = (object) $newAction;
144
        } else {
145 7
            $this->payload['potentialAction'][] = (object) $newAction;
146
        }
147
148 10
        return $this;
149
    }
150
151
    /**
152
     * Add a button.
153
     * Wrapper for a potential action by just providing $text and $url params.
154
     *
155
     * @param string $text - label of the button
156
     * @param string $url - url to forward to
157
     * @param array $params - optional params (needed for more complex types  and for section)
158
     * For more information check out: https://docs.microsoft.com/en-us/outlook/actionable-messages/message-card-reference#openuri-action
159
     *
160
     * @return MicrosoftTeamsMessage $this
161
     */
162 8
    public function button(string $text, string $url = '', array $params = []): self
163
    {
164
165
        // fill targets that is needed for a button
166
        $newButton = [
167
            'targets' => [
168
                (object) [
169 8
                    'os'=> 'default',
170 8
                    'uri' => $url,
171
                ],
172
            ],
173
        ];
174
175
        // fill additional params (if any)
176 8
        if (! empty($params)) {
177 4
            $newButton = array_merge($newButton, $params);
178
        }
179
180 8
        $this->action($text, 'OpenUri', $newButton);
181
182 8
        return $this;
183
    }
184
185
    /**
186
     * Add a startGroup property which marks the start of a logical group of information (only for sections).
187
     *
188
     * @param string|int $sectionId - in which section to put the property, defaults to standard_section
189
     *
190
     * @return MicrosoftTeamsMessage $this
191
     */
192 3
    public function addStartGroupToSection($sectionId = 'standard_section'): self
193
    {
194 3
        $this->payload['sections'][$sectionId]['startGroup'] = true;
195
196 3
        return $this;
197
    }
198
199
    /**
200
     * Add an activity to a section.
201
     *
202
     * @param string $activityImage
203
     * @param string $activityTitle
204
     * @param string $activitySubtitle
205
     * @param string $activityText
206
     * @param string|int $sectionId - in which section to put the property, defaults to standard_section
207
     *
208
     * @return MicrosoftTeamsMessage $this
209
     */
210 2
    public function activity(string $activityImage = '', string $activityTitle = '', string $activitySubtitle = '', string $activityText = '', $sectionId = 'standard_section'): self
211
    {
212 2
        $this->payload['sections'][$sectionId]['activityImage'] = $activityImage;
213 2
        $this->payload['sections'][$sectionId]['activityTitle'] = $activityTitle;
214 2
        $this->payload['sections'][$sectionId]['activitySubtitle'] = $activitySubtitle;
215 2
        $this->payload['sections'][$sectionId]['activityText'] = $activityText;
216
217 2
        return $this;
218
    }
219
220
    /**
221
     * Add a fact to a section (Supports Markdown).
222
     *
223
     * @param string $name
224
     * @param string $value
225
     * @param string|int $sectionId - in which section to put the property, defaults to standard_section
226
     *
227
     * @return MicrosoftTeamsMessage $this
228
     */
229 4
    public function fact(string $name, string $value, $sectionId = 'standard_section'): self
230
    {
231 4
        $newFact = compact('name', 'value');
232 4
        $this->payload['sections'][$sectionId]['facts'][] = $newFact;
233
234 4
        return $this;
235
    }
236
237
    /**
238
     * Add an image to a section.
239
     *
240
     * @param string $imageUri - The URL to the image.
241
     * @param string $title - A short description of the image. Typically, title is displayed in a tooltip as the user hovers their mouse over the image
242
     * @param string|int $sectionId - in which section to put the property, defaults to standard_section
243
     *
244
     * @return MicrosoftTeamsMessage $this
245
     */
246 4
    public function image(string $imageUri, string $title = '', $sectionId = 'standard_section'): self
247
    {
248
        $newImage = [
249 4
            'image' => $imageUri,
250 4
            'title' => $title,
251
        ];
252 4
        $this->payload['sections'][$sectionId]['images'][] = $newImage;
253
254 4
        return $this;
255
    }
256
257
    /**
258
     * Add a hero image to a section.
259
     *
260
     * @param string $imageUri - The URL to the image.
261
     * @param string $title - A short description of the image. Typically, title is displayed in a tooltip as the user hovers their mouse over the image
262
     * @param string|int $sectionId - in which section to put the property, defaults to standard_section
263
     *
264
     * @return MicrosoftTeamsMessage $this
265
     */
266 3
    public function heroImage(string $imageUri, string $title = '', $sectionId = 'standard_section'): self
267
    {
268
        $newImage = [
269 3
            'image' => $imageUri,
270 3
            'title' => $title,
271
        ];
272 3
        $this->payload['sections'][$sectionId]['heroImage'] = $newImage;
273
274 3
        return $this;
275
    }
276
277
    /**
278
     * Additional options to pass to message payload object.
279
     *
280
     * @param array $options
281
     * @param string|int $sectionId - optional in which section to put the property
282
     *
283
     * @return MicrosoftTeamsMessage $this
284
     */
285 3
    public function options(array $options, $sectionId = null): self
286
    {
287 3
        if ($sectionId) {
288 1
            $this->payload['sections'][$sectionId] = array_merge($this->payload['sections'][$sectionId], $options);
289
        }
290 3
        $this->payload = array_merge($this->payload, $options);
291
292 3
        return $this;
293
    }
294
295
    /**
296
     * Recipient's webhook url.
297
     *
298
     * @param $webhookUrl - url of webhook
299
     *
300
     * @throws CouldNotSendNotification
301
     *
302
     * @return MicrosoftTeamsMessage $this
303
     */
304 7
    public function to(?string $webhookUrl): self
305
    {
306 7
        if (! $webhookUrl) {
307 2
            throw CouldNotSendNotification::microsoftTeamsWebhookUrlMissing();
308
        }
309 5
        $this->webhookUrl = $webhookUrl;
310
311 5
        return $this;
312
    }
313
314
    /**
315
     * Get webhook url.
316
     *
317
     * @return string $webhookUrl
318
     */
319 4
    public function getWebhookUrl(): string
320
    {
321 4
        return $this->webhookUrl;
322
    }
323
324
    /**
325
     * Determine if webhook url is not given.
326
     *
327
     * @return bool
328
     */
329 4
    public function toNotGiven(): bool
330
    {
331 4
        return ! $this->webhookUrl;
332
    }
333
334
    /**
335
     * Get payload value for given key.
336
     *
337
     * @param string $key
338
     *
339
     * @return mixed|null
340
     */
341 30
    public function getPayloadValue(string $key)
342
    {
343 30
        return $this->payload[$key] ?? null;
344
    }
345
346
    /**
347
     * Generate a colour code use given by name of type, fallback to primary
348
     * if named color not found the type should be a hex color code.
349
     *
350
     * @param string $type
351
     *
352
     * @return string
353
     */
354 40
    private function generateThemeColourCode($type = 'primary'): string
355
    {
356
        $namedColors = [
357 40
            'primary' => '#1976D2',
358
            'secondary' => '#424242',
359
            'accent' => '#82B1FF',
360
            'error' => '#FF5252',
361
            'info' => '#2196F3',
362
            'success' => '#4CAF50',
363
            'warning' => '#FFC107',
364
        ];
365
366 40
        return $namedColors[$type] ?? $type;
367
    }
368
369
    /**
370
     * Returns params payload.
371
     *
372
     * @return array
373
     */
374 5
    public function toArray(): array
375
    {
376 5
        return $this->payload;
377
    }
378
}
379