Completed
Push — master ( 9b0072...eab05a )
by Martijn van
02:21
created

MaintenanceModeExtension::getClientIp()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
nop 0
1
<?php
2
3
/**
4
 * Class MaintenanceModeExtension.
5
 *
6
 * throw a 503 if mysite/down exists
7
 *
8
 * @property Controller $owner
9
 */
10
class MaintenanceModeExtension extends Extension
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
11
{
12
13
    /**
14
     * @throws SS_HTTPResponse_Exception
15
     */
16
    public function onBeforeInit()
17
    {
18
        if($this->isDownForMaintenance() && !$this->clientIpIsAllowedInMaintenanceMode())
19
        {
20
            $this->throw503();
21
        }
22
    }
23
24
    /**
25
     * @return bool
26
     */
27
    public function isDownForMaintenance()
28
    {
29
        return file_exists(BASE_PATH.'/mysite/down');
30
    }
31
32
    /**
33
     * Somehow $this->owner->httpError keeps the website spinning.
34
     *
35
     * Maybe not very Silverstripe'sch, but at least this works
36
     *
37
     * @throws SS_HTTPResponse_Exception
38
     */
39
    protected function throw503()
40
    {
41
        $message   = 'Website is down for maintenance';
42
        $errorFile = $this->get503File();
43
        $content   = is_file($errorFile) ? file_get_contents($errorFile) : '<h1>'.$message.'</h1>';
44
45
        throw new SS_HTTPResponse_Exception(new SS_HTTPResponse($content, 503, $message));
46
    }
47
48
    /**
49
     * @return string
50
     */
51
    protected function get503File()
52
    {
53
        $custom = BASE_PATH.(string)Config::inst()->get('MaintenanceMode', 'file');
54
55
        return is_file($custom) ? $custom : BASE_PATH.'/assets/error-503.html';
56
    }
57
58
    /**
59
     * @return bool
60
     */
61
    protected function clientIpIsAllowedInMaintenanceMode()
62
    {
63
        $ip      = $this->getClientIp();
64
        $allowed = $this->getAllowedIpAddresses();
65
66
        return (bool)$allowed && $ip && in_array($ip, $allowed);
0 ignored issues
show
Bug Best Practice introduced by
The expression $ip of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
67
    }
68
69
    /**
70
     * @return string|false
71
     */
72
    protected function getClientIp()
73
    {
74
        $request = $this->owner->getRequest();
75
76
        return (bool)$request ? $request->getIP() : false;
77
    }
78
79
    /**
80
     * @return array
81
     */
82
    protected function getAllowedIpAddresses()
83
    {
84
        return (array)Config::inst()->get('MaintenanceMode', 'allowed_ips');
85
    }
86
}
87