Headers::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * ******************************************************************
4
 * Created by   Marko Kungla on 09 Oct 2016
5
 * @package     toolshedr
6
 * Encoding     UTF-8
7
 * File         Headers.php
8
 * Code format  PSR-2 and 12
9
 * *******************************************************************/
10
11
namespace Toolshedr\Core;
12
13
14
class Headers
15
{
16
    /**
17
     * Domains allowed to connect
18
     * @var array
19
     */
20
    private $whitlisted = array();
21
22
    private $http_response_code = 200;
23
    /**
24
     * Headers constructor.
25
     */
26 4
    public function __construct()
27
    {
28 4
        $this->addToWhitelist('localhost');
29 4
    }
30
    
31
    /**
32
     * Whitelist your UI
33
     *
34
     * @param $origin
35
     * @return void
36
     */
37 4
    public function addToWhitelist(string $origin)
38
    {
39 4
        array_push($this->whitlisted, $origin);
40 4
    }
41
42
    /**
43
     * Send all headers
44
     *
45
     * @return void
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
46
     */
47
    public function areOk()
48
    {
49
        header('Access-Control-Allow-Headers: X-Toolshedr-API-KEY');
50
        header('X-Powered-By: Toolshedr Server');
51
        header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
52
53
        return $this->checkOrigin();
54
    }
55
56
    /**
57
     * Is Domain whitelisted
58
     *
59
     * @param string $origin
60
     * @return bool
61
     */
62 1
    public function isWhitelisted(string $origin)
63
    {
64 1
        return in_array($origin, $this->whitlisted);
65
    }
66
    
67
    /**
68
     * Check request origin
69
     *
70
     * @return bool
71
     */
72
    private function checkOrigin()
0 ignored issues
show
Coding Style introduced by
checkOrigin uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
73
    {
74
        if (!empty($_SERVER['HTTP_ORIGIN']) && $this->isWhitelisted($_SERVER['HTTP_ORIGIN'])) {
75
            header(sprintf('Access-Control-Allow-Origin: %s', $_SERVER['HTTP_ORIGIN']));
76
            return true;
77
        } else {
78
            $this->setStatusCode(403);
79
            header(sprintf('Access-Control-Allow-Origin: %s', $_SERVER['HTTP_HOST']));
80
            return false;
81
        }
82
    }
83
84
    /**
85
     * Get White listed domains
86
     * 
87
     * @return array
88
     */
89
    public function getWhitelist()
90
    {
91
        return $this->whitlisted;    
92
    }
93
    
94
    /**
95
     * Set HTTP Status Code
96
     * 
97
     * @param int $code
98
     */
99
    public function setStatusCode(int $code)
100
    {
101
        // Do not allow overwrite previous code other than 200
102
        if($this->http_response_code !== 200) return;
103
104
        $this->http_response_code = $code;
105
       
106
    }
107
108
    /**
109
     * Check does request have required headers
110
     * 
111
     * @return bool
112
     */
113
    public function containsRequiredHeaders()
0 ignored issues
show
Coding Style introduced by
containsRequiredHeaders uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
114
    {
115
        return !empty($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']) && 
116
            $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'] === 'x-toolshedr-api-key';
117
    }
118
119
    /**
120
     * Send remaining headers
121
     * 
122
     * @return void
123
     */
124
    public function send()
125
    {
126
        http_response_code($this->http_response_code);
127
        $this->setContentType('application/json');
128
    }
129
130
    /**
131
     * Set output content type
132
     * 
133
     * @param string $content_type
134
     */
135
    public function setContentType($content_type = 'application/json')
136
    {
137
        header(sprintf('Content-Type: %s', $content_type));
138
    }
139
}
140