Completed
Push — master ( 206c33...9e77c2 )
by Oscar
05:44
created

Www::addWww()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4286
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace Psr7Middlewares\Middleware;
4
5
use Psr7Middlewares\Utils;
6
use Psr\Http\Message\RequestInterface;
7
use Psr\Http\Message\ResponseInterface;
8
9
/**
10
 * Middleware to redirect to force www subdomain or remove it.
11
 */
12
class Www
13
{
14
    use Utils\RedirectTrait;
15
16
    /**
17
     * @var bool Add or remove www
18
     */
19
    protected $addWww;
20
21
    /**
22
     * Constructor. Configure whether add or remove www.
23
     *
24
     * @param bool $addWww
25
     */
26
    public function __construct($addWww = false)
27
    {
28
        $this->addWww($addWww);
29
    }
30
31
    /**
32
     * Configure whether the www subdomain should be added or removed.
33
     *
34
     * @param bool $addWww
35
     *
36
     * @return self
37
     */
38
    public function addWww($addWww)
39
    {
40
        $this->addWww = (boolean) $addWww;
41
42
        return $this;
43
    }
44
45
    /**
46
     * Execute the middleware.
47
     *
48
     * @param RequestInterface  $request
49
     * @param ResponseInterface $response
50
     * @param callable          $next
51
     *
52
     * @return ResponseInterface
53
     */
54
    public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next)
55
    {
56
        $uri = $request->getUri();
57
        $host = $uri->getHost();
58
59
        if ($this->addWww) {
60
            if ($this->canAddWww($host)) {
61
                $host = "www.{$host}";
62
            }
63
        } elseif (strpos($host, 'www.') === 0) {
64
            $host = substr($host, 4);
65
        }
66
67
        //redirect
68
        if (is_int($this->redirectStatus) && ($uri->getHost() !== $host)) {
69
            return self::getRedirectResponse($this->redirectStatus, $uri->withHost($host), $response);
70
        }
71
72
        return $next($request->withUri($uri->withHost($host)), $response);
73
    }
74
75
    /**
76
     * Check whether the domain can add a www. subdomain.
77
     * Returns false if:
78
     * - the host is "localhost"
79
     * - the host is a ip
80
     * - the host has already a subdomain, for example "subdomain.example.com".
81
     * 
82
     * @param string $host
83
     *
84
     * @return bool
85
     */
86
    public function canAddWww($host)
87
    {
88
        if (empty($host) || filter_var($host, FILTER_VALIDATE_IP)) {
89
            return false;
90
        }
91
92
        $host = array_reverse(explode('.', $host));
93
94
        switch (count($host)) {
95
            case 1: //localhost
96
                return false;
97
98
            case 2: //example.com
99
                return true;
100
101
            case 3:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
102
                //example.co.uk
103
                if ($host[1] === 'co') {
104
                    return true;
105
                }
106
107
            default:
108
                return false;
109
        }
110
    }
111
}
112