Completed
Pull Request — master (#444)
by Yanick
02:33
created

LiteSpeed::flush()   A

Complexity

Conditions 4
Paths 12

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 30
rs 9.44
c 0
b 0
f 0
cc 4
nc 12
nop 0
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\Exception\ExceptionCollection;
15
use FOS\HttpCache\ProxyClient\Invalidation\ClearCapable;
16
use FOS\HttpCache\ProxyClient\Invalidation\PurgeCapable;
17
use FOS\HttpCache\ProxyClient\Invalidation\TagCapable;
18
19
/**
20
 * LiteSpeed Web Server (LSWS) invalidator.
21
 *
22
 * @author Yanick Witschi <[email protected]>
23
 */
24
class LiteSpeed extends HttpProxyClient implements PurgeCapable, TagCapable, ClearCapable
25
{
26
    private $headerLines = [];
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public function clear()
32
    {
33
        $this->addHeaderLine('X-LiteSpeed-Purge', '*');
34
35
        return $this;
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function purge($url, array $headers = [])
42
    {
43
        $urlParts = parse_url($url);
44
        $host = null;
45
46
        if (isset($urlParts['host'])) {
47
            $host = $urlParts['host'];
48
            $url = $urlParts['path'];
49
        }
50
51
        $this->addHeaderLine('X-LiteSpeed-Purge', $url, $host);
52
53
        return $this;
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59
    protected function configureOptions()
60
    {
61
        $resolver = parent::configureOptions();
62
63
        $resolver->setRequired(['document_root']);
64
        $resolver->setDefaults([
65
            'target_dir' => '',
66
            'base_uri' => '/',
67
        ]);
68
69
        $resolver->setAllowedTypes('document_root', 'string');
70
        $resolver->setAllowedTypes('target_dir', 'string');
71
        $resolver->setAllowedTypes('base_uri', 'string');
72
73
        return $resolver;
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79
    public function invalidateTags(array $tags)
80
    {
81
        $this->addHeaderLine('X-LiteSpeed-Purge', implode(', ', preg_filter('/^/', 'tag=', $tags)));
82
83
        return $this;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function flush()
90
    {
91
        $filenames = array();
92
93
        $url = '/';
94
95
        if ($this->options['target_dir']) {
96
            $url .= $this->options['target_dir'].'/';
97
        }
98
99
        foreach ($this->headerLines as $host => $lines) {
100
101
            $filename = $this->createFileForHost($host);
102
103
            $this->queueRequest('GET', $url.$filename, []);
104
105
            $filenames[] = $filename;
106
        }
107
108
        try {
109
            return parent::flush();
110
        } finally {
111
            // Reset
112
            $this->headerLines = [];
113
114
            foreach ($filenames as $filename) {
115
                unlink($this->getFilePath().'/'.$filename);
116
            }
117
        }
118
    }
119
120
    private function addHeaderLine($header, $value, $host = null)
121
    {
122
        if (null === $host) {
123
            $host = $this->options['base_uri'];
124
        }
125
126
        if (!isset($this->headerLines[$host])) {
127
            $this->headerLines[$host] = array();
128
        }
129
130
        $this->headerLines[$host][] = $header.': '.$value;
131
    }
132
133
    /**
134
     * Creates the file and returns the file name.
135
     *
136
     * @param string $host
137
     * @return string
138
     */
139
    private function createFileForHost($host)
140
    {
141
        $content = '<?php'."\n\n";
142
143
        foreach ($this->headerLines[$host] as $header) {
144
            $content .= sprintf('header(\'%s\');', addslashes($header))."\n";
145
        }
146
147
        // Generate a reasonably random file name, no need to be cryptographically safe here
148
        $filename = 'fos_cache_litespeed_purger_'.substr(sha1(uniqid('', true).mt_rand()), 0, mt_rand(10, 40)) . '.php';
149
150
        file_put_contents($this->getFilePath().'/'.$filename, $content);
151
152
        return $filename;
153
    }
154
155
    /**
156
     * @return string
157
     */
158
    private function getFilePath()
159
    {
160
        $path = $this->options['document_root'];
161
162
        if ($this->options['target_dir']) {
163
            $path .= '/'.$this->options['target_dir'];
164
        }
165
166
        return $path;
167
    }
168
}
169