ControllerPolicyMiddleware::process()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 22
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 22
rs 9.9332
c 0
b 0
f 0
cc 4
nc 3
nop 2
1
<?php
2
3
namespace SilverStripe\ControllerPolicy;
4
5
use SilverStripe\Control\Controller;
6
use SilverStripe\Control\Director;
7
use SilverStripe\Control\HTTPRequest;
8
use SilverStripe\Control\HTTPResponse;
9
use SilverStripe\Control\Middleware\HTTPMiddleware;
10
use SilverStripe\Core\Config\Configurable;
11
12
/**
13
 * This middleware accepts registrations of policies to be applied at the end of the control pipeline.
14
 * The policies will be applied in the order they are added, and will override HTTP::add_cache_headers.
15
 */
16
class ControllerPolicyMiddleware implements HTTPMiddleware
17
{
18
    use Configurable;
19
20
    /**
21
     * Force some domains to be ignored. Accepts one wildcard at the beginning.
22
     *
23
     * @config
24
     * @var array
25
     */
26
    private static $ignore_domain_regexes = [];
0 ignored issues
show
introduced by
The private property $ignore_domain_regexes is not used, and could be removed.
Loading history...
27
28
    /**
29
     * An associative array containing the 'originator' and 'policy' reference.
30
     *
31
     * @var array
32
     */
33
    protected $requestedPolicies = [];
34
35
    /**
36
     * Check if the given domain is on the list of ignored domains.
37
     *
38
     * @param string $domain
39
     * @return boolean
40
     */
41
    public function isIgnoredDomain($domain)
42
    {
43
        if ($ignoreRegexes = $this->config()->get('ignore_domain_regexes')) {
44
            foreach ($ignoreRegexes as $ignore) {
45
                if (preg_match($ignore, $domain) > 0) {
46
                    return true;
47
                }
48
            }
49
        }
50
51
        return false;
52
    }
53
54
    /**
55
     * Add a policy tuple.
56
     *
57
     * @param Controller $originator
58
     * @param array $policy
59
     */
60
    public function requestPolicy($originator, $policy)
61
    {
62
        $this->requestedPolicies[] = ['originator' => $originator, 'policy' => $policy];
63
    }
64
65
    public function clearPolicies()
66
    {
67
        $this->requestedPolicies = [];
68
    }
69
70
    /**
71
     * Apply all the requested policies.
72
     *
73
     * @param  HTTPRequest  $request
74
     * @param  callable $delegate
75
     * @return HTTPResponse
76
     */
77
    public function process(HTTPRequest $request, callable $delegate)
78
    {
79
        /** @var HTTPResponse $response */
80
        $response = $delegate($request);
81
82
        // Ignore by regexes.
83
        if ($this->shouldCheckHttpHost() && $this->isIgnoredDomain($_SERVER['HTTP_HOST'])) {
84
            return $response;
85
        }
86
87
        foreach ($this->requestedPolicies as $requestedPolicy) {
88
            /** @var ControllerPolicy $policyInstance */
89
            $policyInstance = $requestedPolicy['policy'];
90
91
            $policyInstance->applyToResponse(
92
                $requestedPolicy['originator'],
93
                $request,
94
                $response
95
            );
96
        }
97
98
        return $response;
99
    }
100
101
    /**
102
     * Whether the domain regexes should be checked. Can be partially mocked for unit testing.
103
     *
104
     * @return bool
105
     */
106
    public function shouldCheckHttpHost()
107
    {
108
        return !Director::is_cli() && isset($_SERVER['HTTP_HOST']);
109
    }
110
}
111