Completed
Pull Request — master (#142)
by Robbie
10:23
created

GitHubMarkdownService::toHtml()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 9.2
c 0
b 0
f 0
cc 2
eloc 14
nc 3
nop 1
1
<?php
2
3
use GuzzleHttp\Client;
4
use GuzzleHttp\Exception\ClientException;
5
6
/**
7
 * A GitHub service for communicating with the GitHub API to render Markdown. Uses Guzzle as the
8
 * transport method.
9
 *
10
 * @package mysite
11
 */
12
class GitHubMarkdownService extends Object
13
{
14
    /**
15
     * The Guzzle client
16
     *
17
     * @var GuzzleHttp\Client
18
     */
19
    protected $client;
20
21
    /**
22
     * The GitHub repository context
23
     *
24
     * @var string
25
     */
26
    protected $context;
27
28
    /**
29
     * GitHub API configuration
30
     * @var string
31
     */
32
    const API_BASE_URI        = 'https://api.github.com';
33
    const API_REQUEST_METHOD  = 'POST';
34
    const API_RENDER_ENDPOINT = '/markdown';
35
36
    /**
37
     * Use GitHub's API to render markdown to HTML
38
     *
39
     * @param  string $markdown Markdown
40
     * @return string           HTML
41
     */
42
    public function toHtml($markdown)
43
    {
44
        $body = '';
45
        try {
46
            /** @var Psr\Http\Message\ResponseInterface $response */
47
            $response = $this->getClient()
48
                ->request(
49
                    $this->getRequestMethod(),
50
                    $this->getEndpoint(),
51
                    array(
52
                        'headers' => $this->getHeaders(),
53
                        'body' => $this->getPayload($markdown)
54
                    )
55
                );
56
57
            $body = (string) $response->getBody();
58
        } catch (ClientException $ex) {
59
            user_error($ex->getMessage());
60
        }
61
62
        return $body;
63
    }
64
65
    /**
66
     * Get the GitHub repository context
67
     * @return string
68
     */
69
    public function getContext()
70
    {
71
        return $this->context;
72
    }
73
74
    /**
75
     * Set the GitHub repository context
76
     * @param  string $context
77
     * @return $this
78
     */
79
    public function setContext($context)
80
    {
81
        $this->context = $context;
82
        return $this;
83
    }
84
85
    /**
86
     * Get an instance of a GuzzleHttp client
87
     * @return GuzzleHttp\Client
88
     */
89
    public function getClient()
90
    {
91
        if (is_null($this->client)) {
92
            $this->client = new Client(
93
                array(
94
                    'base_uri' => $this->getBaseUri()
95
                )
96
            );
97
        }
98
99
        return $this->client;
100
    }
101
102
    /**
103
     * Get the GitHub base URI
104
     * @return string
105
     */
106
    public function getBaseUri()
107
    {
108
        return self::API_BASE_URI;
109
    }
110
111
    /**
112
     * Get the HTTP request method to use for the request
113
     * @return string
114
     */
115
    public function getRequestMethod()
116
    {
117
        return self::API_REQUEST_METHOD;
118
    }
119
120
    /**
121
     * Get the markdown parse endpoint for GitHub's API
122
     * @return string
123
     */
124
    public function getEndpoint()
125
    {
126
        $endpoint = self::API_RENDER_ENDPOINT;
127
        if (!$this->getContext()) {
128
            $endpoint .= '/raw';
129
        }
130
        return $endpoint;
131
    }
132
133
    /**
134
     * Get any custom headers to use for the request
135
     * @return array
136
     */
137
    public function getHeaders()
138
    {
139
        return array(
140
            'User-Agent'   => 'silverstripe/addons-site',
141
            'Content-Type' => 'text/x-markdown'
142
        );
143
    }
144
145
    /**
146
     * Get the payload for for the GitHub Markdown API endpoint, either in "GFM" mode if there is a repository
147
     * context, or in raw mode if not.
148
     *
149
     * @see https://developer.github.com/v3/markdown/
150
     * @param  string $markdown
151
     * @return string           JSON or markdown
152
     */
153
    public function getPayload($markdown)
154
    {
155
        if ($this->getContext()) {
156
            return Convert::raw2json(
157
                array(
158
                    'text'    => $markdown,
159
                    'mode'    => 'gfm',
160
                    'context' => $this->getContext()
161
                )
162
            );
163
        }
164
165
        return $markdown;
166
    }
167
}
168