-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathPreviewer.php
More file actions
61 lines (52 loc) · 1.92 KB
/
Copy pathPreviewer.php
File metadata and controls
61 lines (52 loc) · 1.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
declare(strict_types=1);
namespace SlackPhp\BlockKit;
use SlackPhp\BlockKit\Surfaces;
use function rawurlencode;
use function strtr;
/**
* Provides the ability to preview a surface in Slack's Block Kit Builder by generating a URL.
*/
final class Previewer
{
private const BUILDER_URL = 'https://app.slack.com/block-kit-builder';
public static function new(): self
{
return new self();
}
public function preview(Surfaces\Surface $surface): string
{
// Prepare/validate the surface.
if ($surface instanceof Surfaces\Message) {
// Block Kit Builder doesn't support message directives or fallback text.
$surface = (clone $surface)
->responseType(null)
->deleteOriginal(null)
->replaceOriginal(null)
->text(null)
->mrkdwn(null)
->threadTs(null);
} elseif ($surface instanceof Surfaces\Attachment) {
// Block Kit Builder can only show an attachment within a message.
$surface = (new Surfaces\Message())->attachments($surface);
} elseif ($surface instanceof Surfaces\WorkflowStep) {
throw new Exception('The "workflow_step" surface is not compatible with Block Kit Builder');
}
// Generate the Block Kit Builder URL.
return self::BUILDER_URL . '#' . $this->encode($surface);
}
/**
* Encodes a surface into a format understood by Slack and capable of being transmitted in a URL fragment.
*
* 1. Encode the surface as JSON.
* 2. URL encode the JSON.
* 3. Convert encoded entities for double quotes and colons back to their original characters.
*
* @param Surfaces\Surface $surface
* @return string
*/
private function encode(Surfaces\Surface $surface): string
{
return strtr(rawurlencode($surface->toJson()), ['%22' => '"', '%3A' => ':']);
}
}