Completed
Push — master ( 00ed35...63fbb3 )
by Oscar
10:20
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
    private $addWww;
20
21
    /**
22
     * Configure whether the www subdomain should be added or removed.
23
     *
24
     * @param bool $addWww
25
     */
26
    public function __construct($addWww = false)
27
    {
28
        $this->addWww = (boolean) $addWww;
29
    }
30
31
    /**
32
     * Execute the middleware.
33
     *
34
     * @param RequestInterface  $request
35
     * @param ResponseInterface $response
36
     * @param callable          $next
37
     *
38
     * @return ResponseInterface
39
     */
40
    public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next)
41
    {
42
        $uri = $request->getUri();
43
        $host = $uri->getHost();
44
45
        if ($this->addWww) {
46
            if ($this->canAddWww($host)) {
47
                $host = "www.{$host}";
48
            }
49
        } elseif (strpos($host, 'www.') === 0) {
50
            $host = substr($host, 4);
51
        }
52
53
        //redirect
54
        if (is_int($this->redirectStatus) && ($uri->getHost() !== $host)) {
55
            return self::getRedirectResponse($this->redirectStatus, $uri->withHost($host), $response);
56
        }
57
58
        return $next($request->withUri($uri->withHost($host)), $response);
59
    }
60
61
    /**
62
     * Check whether the domain can add a www. subdomain.
63
     * Returns false if:
64
     * - the host is "localhost"
65
     * - the host is a ip
66
     * - the host has already a subdomain, for example "subdomain.example.com".
67
     * 
68
     * @param string $host
69
     *
70
     * @return bool
71
     */
72
    private function canAddWww($host)
73
    {
74
        if (empty($host) || filter_var($host, FILTER_VALIDATE_IP)) {
75
            return false;
76
        }
77
78
        $host = array_reverse(explode('.', $host));
79
80
        switch (count($host)) {
81
            case 1: //localhost
82
                return false;
83
84
            case 2: //example.com
85
                return true;
86
87
            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...
88
                //example.co.uk
89
                if ($host[1] === 'co') {
90
                    return true;
91
                }
92
93
            default:
94
                return false;
95
        }
96
    }
97
}
98