Passed
Push — 3.0 ( 1eb04a...9ca0ec )
by Vermeulen
02:07
created

anonymous//src/Helpers/Form.php$0   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 12
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 10
c 0
b 0
f 0
wmc 2
1
<?php
2
3
namespace BFW\Helpers;
4
5
use \DateTime;
6
use \Exception;
7
8
/**
9
 * Class to manage html forms
10
 * Only manage form's token.
11
 */
12
class Form
13
{
14
    /**
15
     * @const ERR_NO_TOKEN Exception code if there is no token declared
16
     */
17
    const ERR_NO_TOKEN = 1606001;
18
    
19
    /**
20
     * @const ERR_NO_TOKEN_FOR_FORM_ID Exception code if there is no token for
21
     * the form id.
22
     */
23
    const ERR_NO_TOKEN_FOR_FORM_ID = 1606002;
24
    
25
    /**
26
     * @const ERR_FORM_ID_EMPTY Exception code if the form id is not declared.
27
     */
28
    const ERR_FORM_ID_EMPTY = 1606003;
29
    
30
    /**
31
     * @var string $formId The form id 
32
     */
33
    protected $formId = '';
34
35
    /**
36
     * Constructor
37
     * Define the form's id.
38
     * 
39
     * @param string $formId The form's id
40
     */
41
    public function __construct(string $formId)
42
    {
43
        $this->formId = $formId;
44
        
45
        if (empty($this->formId)) {
46
            throw new Exception('Form id is empty.', $this::ERR_FORM_ID_EMPTY);
47
        }
48
    }
49
    
50
    /**
51
     * Getter accessor to the property formId
52
     * 
53
     * @return string
54
     */
55
    public function getFormId(): string
56
    {
57
        return $this->formId;
58
    }
59
60
    /**
61
     * Save the form's token
62
     * 
63
     * @param object $saveInfos Infos about token (id and expire time)
64
     * 
65
     * @return void
66
     */
67
    protected function saveToken($saveInfos)
68
    {
69
        //Default to session
70
        $this->saveTokenInSession($saveInfos);
71
    }
72
73
    /**
74
     * Save a token in php session
75
     * 
76
     * @global array $_SESSION
77
     * 
78
     * @param object $saveInfos Infos about token (id and expire time)
79
     * 
80
     * @return void
81
     */
82
    protected function saveTokenInSession($saveInfos)
83
    {
84
        global $_SESSION;
85
86
        $_SESSION['formsTokens'][$this->formId] = $saveInfos;
87
    }
88
89
    /**
90
     * Get the token informations
91
     * 
92
     * @return object
93
     */
94
    protected function obtainToken()
95
    {
96
        return $this->obtainTokenFromSession();
97
    }
98
99
    /**
100
     * Get a token from the session
101
     * 
102
     * @global array $_SESSION
103
     * 
104
     * @return object
105
     * 
106
     * @throws \Exception If there are no token
107
     */
108
    protected function obtainTokenFromSession()
109
    {
110
        global $_SESSION;
111
112
        if (!isset($_SESSION['formsTokens'])) {
113
            throw new Exception('no token found', $this::ERR_NO_TOKEN);
114
        }
115
116
        if (!isset($_SESSION['formsTokens'][$this->formId])) {
117
            throw new Exception(
118
                'no token found for the form id '.$this->formId,
119
                $this::ERR_NO_TOKEN_FOR_FORM_ID
120
            );
121
        }
122
123
        return $_SESSION['formsTokens'][$this->formId];
124
    }
125
126
    /**
127
     * Create a token for the form and return the token
128
     * 
129
     * @return string
130
     * 
131
     * @throws \Exception If the form id is undefined
132
     */
133
    public function createToken(): string
134
    {
135
        $saveInfos = new class(uniqid(rand(), true)) {
136
            protected $token;
137
            protected $date;
138
            
139
            public function __construct($token)
140
            {
141
                $this->token = $token;
142
                $this->date  = new DateTime;
143
            }
144
            
145
            public function __get($name) {
146
                return $this->{$name};
147
            }
148
        };
149
150
        $this->saveToken($saveInfos);
151
        return $saveInfos->token;
0 ignored issues
show
Bug Best Practice introduced by
The property $token is declared protected in anonymous//src/Helpers/Form.php$0. Since you implement __get, consider adding a @property or @property-read.
Loading history...
152
    }
153
154
    /**
155
     * Check the token receive with the generated token
156
     * 
157
     * @param string $tokenToCheck The token receive from user
158
     * @param int $timeExpire (default 15) time on minute during which the
159
     *  token is valid
160
     * 
161
     * @throws \Exception If the token not exist
162
     * 
163
     * @return boolean
164
     */
165
    public function checkToken(string $tokenToCheck, int $timeExpire = 15): bool
166
    {
167
        //Throw Exception
168
        $tokenInfos = $this->obtainToken();
169
170
        $token      = $tokenInfos->token;
171
        $dateCreate = $tokenInfos->date;
172
173
        if ($token !== $tokenToCheck) {
174
            return false;
175
        }
176
177
        $limitDate = new DateTime;
178
        $limitDate->modify('-'.$timeExpire.' minutes');
179
        
180
        unset($_SESSION['formsTokens'][$this->formId]);
181
        
182
        if ($dateCreate < $limitDate) {
183
            return false;
184
        }
185
186
        return true;
187
    }
188
    
189
    /**
190
     * Check if the form has a token
191
     * 
192
     * @return boolean
193
     */
194
    public function hasToken(): bool
195
    {
196
        try {
197
            $this->obtainToken();
198
        } catch (Exception $e) {
199
            return false;
200
        }
201
        
202
        return true;
203
    }
204
}
205