Passed
Pull Request — master (#70)
by Andrew
05:24
created

Publisher::generatePageResponse()   C

Complexity

Conditions 8
Paths 80

Size

Total Lines 50
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 37
nc 80
nop 1
dl 0
loc 50
rs 6.3636
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\StaticPublishQueue;
4
5
use SilverStripe\Control\Director;
6
use SilverStripe\Control\HTTPApplication;
7
use SilverStripe\Control\HTTPRequestBuilder;
8
use SilverStripe\Control\HTTPResponse;
9
use SilverStripe\Control\HTTPResponse_Exception;
10
use SilverStripe\Core\Config\Configurable;
11
use SilverStripe\Core\CoreKernel;
12
use SilverStripe\Core\Injector\Injectable;
13
use SilverStripe\Core\Manifest\ModuleLoader;
14
use SilverStripe\ORM\DataObject;
15
use SilverStripe\ORM\FieldType\DBDatetime;
16
use SilverStripe\ORM\FieldType\DBField;
17
use SilverStripe\StaticPublishQueue\Contract\StaticPublisher;
18
use SilverStripe\View\ArrayData;
19
use SilverStripe\View\Requirements;
20
use SilverStripe\View\Requirements_Backend;
21
use SilverStripe\View\SSViewer;
22
23
abstract class Publisher implements StaticPublisher
24
{
25
    use Injectable;
26
    use Configurable;
27
28
    /**
29
     * @var array
30
     * @config
31
     */
32
    private static $static_publisher_themes = [];
0 ignored issues
show
introduced by
The private property $static_publisher_themes is not used, and could be removed.
Loading history...
33
34
    /**
35
     * @var string
36
     *
37
     * @config
38
     */
39
    private static $static_base_url = null;
0 ignored issues
show
introduced by
The private property $static_base_url is not used, and could be removed.
Loading history...
40
41
    /**
42
     * @config
43
     *
44
     * @var Boolean Use domain based cacheing (put cache files into a domain subfolder)
45
     * This must be true if you are using this with the "subsites" module.
46
     * Please note that this form of caching requires all URLs to be provided absolute
47
     * (not relative to the webroot) via {@link SiteTree->AbsoluteLink()}.
48
     */
49
    private static $domain_based_caching = false;
0 ignored issues
show
introduced by
The private property $domain_based_caching is not used, and could be removed.
Loading history...
50
51
    /**
52
     * @param string $url
53
     * @return HTTPResponse
54
     */
55
    public function generatePageResponse($url)
56
    {
57
        if (Director::is_relative_url($url)) {
58
            $url = Director::absoluteURL($url);
59
        }
60
        $urlParts = parse_url($url);
61
        if (!empty($urlParts['query'])) {
62
            parse_str($urlParts['query'], $getVars);
63
        } else {
64
            $getVars = [];
65
        }
66
        // back up requirements backend
67
        $origRequirements = Requirements::backend();
68
        $origThemes = SSViewer::get_themes();
69
        Requirements::set_backend(Requirements_Backend::create());
70
        $themes = self::config()->get('static_publisher_themes');
71
        if ($themes) {
72
            SSViewer::set_themes($themes);
73
        }
74
        try {
75
            // try to add all the server vars that would be needed to create a static cache
76
            $request = HTTPRequestBuilder::createFromVariables(
77
                [
78
                '_SERVER' => [
79
                    'REQUEST_URI' => isset($urlParts['path']) ? $urlParts['path'] : '',
80
                    'REQUEST_METHOD' => 'GET',
81
                    'REMOTE_ADDR' => '127.0.0.1',
82
                    'HTTPS' => $urlParts['scheme'] == 'https' ? 'on' : 'off',
83
                    'QUERY_STRING' => isset($urlParts['query']) ? $urlParts['query'] : '',
84
                    'REQUEST_TIME' => DBDatetime::now()->getTimestamp(),
85
                    'REQUEST_TIME_FLOAT' => (float) DBDatetime::now()->getTimestamp(),
86
                    'HTTP_HOST' => $urlParts['host'],
87
                    'HTTP_USER_AGENT' => 'silverstripe/staticpublisher',
88
                ],
89
                '_GET' => $getVars,
90
                '_POST' => [],
91
                ],
92
                ''
93
            );
94
            $app = $this->getHTTPApplication();
95
            $response = $app->handle($request);
96
        } catch (HTTPResponse_Exception $e) {
97
            $response = $e->getResponse();
98
        } finally {
99
            // restore backends
100
            SSViewer::set_themes($origThemes);
101
            Requirements::set_backend($origRequirements);
102
            DataObject::singleton()->flushCache();
103
        }
104
        return $response;
105
    }
106
107
    /**
108
     * @return HTTPApplication
109
     */
110
    protected function getHTTPApplication()
111
    {
112
        $kernel = new CoreKernel(BASE_PATH);
113
        return new HTTPApplication($kernel);
114
    }
115
116
    /**
117
     * Generate the templated content for a PHP script that can serve up the
118
     * given piece of content with the given age and expiry.
119
     *
120
     * @param HTTPResponse $response
121
     *
122
     * @return string
123
     */
124
    protected function generatePHPCacheFile($response)
125
    {
126
        $cacheConfig = [
127
            'responseCode' => $response->getStatusCode(),
128
            'headers' => [],
129
        ];
130
131
        foreach ($response->getHeaders() as $header => $value) {
132
            if (!in_array($header, [ 'cache-control' ])) {
133
                $cacheConfig['headers'][] = sprintf('%s: %s', $header, $value);
134
            }
135
        }
136
137
        return "<?php\n\nreturn " . var_export($cacheConfig, true) . ';';
138
    }
139
140
    /**
141
     * Generate the templated content for a PHP script that can serve up a 301
142
     * redirect to the given destination.
143
     *
144
     * @param string $destination
145
     *
146
     * @return string
147
     */
148
    protected function generatePHPCacheRedirection($destination, $statusCode)
149
    {
150
        $templateResource = ModuleLoader::getModule('silverstripe/staticpublishqueue')
151
            ->getResource('templates/CachedPHPRedirection.tmpl');
152
        $template = file_get_contents($templateResource->getPath());
153
154
        return str_replace(
155
            array('**DESTINATION**', '**STATUS_CODE**'),
156
            array($destination, $statusCode),
157
            $template
158
        );
159
    }
160
161
    /**
162
     * @param string $destination
163
     * @return string
164
     */
165
    protected function generateHTMLCacheRedirection($destination)
166
    {
167
        return SSViewer::execute_template(
168
            'SilverStripe\\StaticPublishQueue\\HTMLRedirection',
169
            ArrayData::create([
170
                'URL' => DBField::create_field('Varchar', $destination),
171
            ])
172
        );
173
    }
174
}
175