Passed
Pull Request — master (#507)
by
unknown
09:28
created

Cloudflare::encode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 6
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 6
b 0
f 0
nc 2
nop 1
dl 0
loc 8
ccs 4
cts 5
cp 0.8
crap 2.032
rs 10
1
<?php
2
3
/*
4
 * This file is part of the FOSHttpCache package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\HttpCache\ProxyClient;
13
14
use FOS\HttpCache\ProxyClient\Invalidation\ClearCapable;
15
use FOS\HttpCache\ProxyClient\Invalidation\PurgeCapable;
16
use FOS\HttpCache\ProxyClient\Invalidation\TagCapable;
17
18
/**
19
 * Cloudflare HTTP cache invalidator.
20
 *
21
 * Additional constructor options:
22
 * - zone_identifier       Identifier for your Cloudflare zone you want to purge the cache for
23
 * - authentication_token  API authorization token, requires Zone.Cache Purge permissions
24
 *
25
 * @author Simon Jones <[email protected]>
26
 */
27
class Cloudflare extends HttpProxyClient implements ClearCapable, PurgeCapable, TagCapable
28
{
29
    /**
30
     * @see https://api.cloudflare.com/#getting-started-endpoints
31
     */
32
    private const API_ENDPOINT = 'https://api.cloudflare.com/client/v4';
33
34
    /**
35
     * Batch URL purge limit.
36
     *
37
     * @see https://api.cloudflare.com/#zone-purge-files-by-url
38
     */
39
    private const URL_BATCH_PURGE_LIMIT = 30;
40
41
    /**
42
     * Array of data to send to Cloudflare for purge by URLs request.
43
     *
44
     * @var array
45
     */
46
    private $purgeByUrlsData = [];
47
48
    /**
49
     * JSON encode data.
50
     *
51
     * @param $data
52
     *
53
     * @return string
54
     *
55
     * @throws InvalidArgumentException
56
     */
57 3
    protected function encode($data)
58
    {
59 3
        $json = json_encode($data, JSON_UNESCAPED_SLASHES);
60 3
        if (false === $json) {
61
            throw new \InvalidArgumentException(sprintf('Cannot encode "$data": %s', json_last_error_msg()));
62
        }
63
64 3
        return $json;
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     *
70
     * @see https://api.cloudflare.com/#zone-purge-files-by-cache-tags,-host-or-prefix
71
     */
72 1
    public function invalidateTags(array $tags)
73
    {
74 1
        $this->queueRequest(
75 1
            'POST',
76 1
            sprintf(self::API_ENDPOINT.'/zones/%s/purge_cache', $this->options['zone_identifier']),
77 1
            [],
78 1
            false,
79 1
            $this->encode(['tags' => $tags])
80
        );
81
82 1
        return $this;
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     *
88
     * @see https://api.cloudflare.com/#zone-purge-files-by-url
89
     */
90 1
    public function purge($url, array $headers = [])
91
    {
92 1
        if (!empty($headers)) {
93 1
            $this->purgeByUrlsData[] = [
94 1
                'url' => $url,
95 1
                'headers' => $headers,
96
            ];
97
        } else {
98 1
            $this->purgeByUrlsData[] = $url;
99
        }
100
101 1
        return $this;
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     *
107
     * @see https://api.cloudflare.com/#zone-purge-all-files
108
     */
109 1
    public function clear()
110
    {
111 1
        $this->queueRequest(
112 1
            'POST',
113 1
            sprintf(self::API_ENDPOINT.'/zones/%s/purge_cache', $this->options['zone_identifier']),
114 1
            ['Accept' => 'application/json'],
115 1
            false,
116 1
            $this->encode(['purge_everything' => true])
117
        );
118
119 1
        return $this;
120
    }
121
122
    /**
123
     * {@inheritdoc} Always provides authentication token
124
     */
125 3
    protected function queueRequest($method, $url, array $headers, $validateHost = true, $body = null)
126
    {
127 3
        parent::queueRequest(
128 3
            $method,
129
            $url,
130 3
            $headers + ['Authorization' => 'Bearer '.$this->options['authentication_token']],
131
            $validateHost,
132
            $body
133
        );
134 3
    }
135
136
    /**
137
     * {@inheritdoc} Queue requests for purge by URLs
138
     */
139 1
    public function flush()
140
    {
141
        // Queue requests for purge by URL
142 1
        foreach (\array_chunk($this->purgeByUrlsData, self::URL_BATCH_PURGE_LIMIT) as $urlChunk) {
143 1
            $this->queueRequest(
144 1
                'POST',
145 1
                sprintf(self::API_ENDPOINT.'/zones/%s/purge_cache', $this->options['zone_identifier']),
146 1
                [],
147 1
                false,
148 1
                $this->encode(['files' => $urlChunk])
149
            );
150
        }
151
152 1
        return parent::flush();
153
    }
154
155
    /**
156
     * {@inheritdoc}
157
     */
158 3
    protected function configureOptions()
159
    {
160 3
        $resolver = parent::configureOptions();
161
162 3
        $resolver->setRequired([
163 3
            'authentication_token',
164
            'zone_identifier',
165
        ]);
166
167 3
        return $resolver;
168
    }
169
}
170