Completed
Pull Request — master (#444)
by Yanick
03:18 queued 01:23
created

LiteSpeed::flush()   A

Complexity

Conditions 4
Paths 12

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

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