1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* src/SecurityTxt.php |
4
|
|
|
* |
5
|
|
|
* @package php-security-txt |
6
|
|
|
* @author Austin Heap <[email protected]> |
7
|
|
|
* @version v0.4.0 |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
declare(strict_types = 1); |
11
|
|
|
|
12
|
|
|
namespace AustinHeap\Security\Txt; |
13
|
|
|
|
14
|
|
|
use AustinHeap\Security\Txt\Directives\Acknowledgement; |
15
|
|
|
use AustinHeap\Security\Txt\Directives\Contact; |
16
|
|
|
use AustinHeap\Security\Txt\Directives\Disclosure; |
17
|
|
|
use AustinHeap\Security\Txt\Directives\Encryption; |
18
|
|
|
use Exception; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* SecurityTxt |
22
|
|
|
* |
23
|
|
|
* @link https://github.com/austinheap/php-security-txt |
24
|
|
|
* @link https://packagist.org/packages/austinheap/php-security-txt |
25
|
|
|
* @link https://austinheap.github.io/php-security-txt/classes/AustinHeap.Security.Txt.SecurityTxt.html |
26
|
|
|
*/ |
27
|
|
|
class SecurityTxt implements SecurityTxtInterface |
28
|
|
|
{ |
29
|
|
|
/** |
30
|
|
|
* Directive trait: Contact |
31
|
|
|
*/ |
32
|
|
|
use Contact; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Directive trait: Encryption |
36
|
|
|
*/ |
37
|
|
|
use Encryption; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Directive trait: Disclosure |
41
|
|
|
*/ |
42
|
|
|
use Disclosure; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* Directive trait: Acknowledgement |
46
|
|
|
*/ |
47
|
|
|
use Acknowledgement; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Internal version number. |
51
|
|
|
* |
52
|
|
|
* @var string |
53
|
|
|
*/ |
54
|
|
|
const VERSION = '0.4.0'; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* Internal parent object. |
58
|
|
|
* |
59
|
|
|
* @var \AustinHeap\Security\Txt\Writer|\AustinHeap\Security\Txt\Reader |
60
|
|
|
*/ |
61
|
|
|
private $parent = null; |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Internal Writer object. |
65
|
|
|
* |
66
|
|
|
* @var \AustinHeap\Security\Txt\Writer |
67
|
|
|
*/ |
68
|
|
|
protected $writer = null; |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* Internal Reader object. |
72
|
|
|
* |
73
|
|
|
* @var \AustinHeap\Security\Txt\Reader |
74
|
|
|
*/ |
75
|
|
|
protected $reader = null; |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Internal text cache. |
79
|
|
|
* |
80
|
|
|
* @var string |
81
|
|
|
*/ |
82
|
|
|
protected $text = null; |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Enable debug output. |
86
|
|
|
* |
87
|
|
|
* @var bool |
88
|
|
|
*/ |
89
|
|
|
protected $debug = false; |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Enable built-in comments. |
93
|
|
|
* |
94
|
|
|
* @var bool |
95
|
|
|
*/ |
96
|
|
|
protected $comments = true; |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Create a new SecurityTxt instance. |
100
|
|
|
* |
101
|
|
|
* @param Writer|Reader $parent |
102
|
|
|
* |
103
|
|
|
* @return SecurityTxt|Writer|Reader |
104
|
|
|
*/ |
105
|
|
|
public function __construct(&$parent = null) |
106
|
|
|
{ |
107
|
|
|
if (!defined('PHP_SECURITY_TXT_VERSION')) { |
108
|
|
|
define('PHP_SECURITY_TXT_VERSION', self::VERSION); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
$this->parent = $parent; |
112
|
|
|
|
113
|
|
|
if (func_num_args() == 1) { |
114
|
|
|
if (is_null($this->parent)) { |
115
|
|
|
throw new Exception('Cannot create ' . __CLASS__ . ' with explicitly null $parent class.'); |
116
|
|
|
} else if (!$this->parent instanceof Reader && !$this->parent instanceof Writer) { |
117
|
|
|
throw new Exception('Cannot create ' . __CLASS__ . ' with $parent class: ' . get_class($this->parent)); |
118
|
|
|
} |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
return $this; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Returns the parent's class if it exists. |
126
|
|
|
* |
127
|
|
|
* @return string |
128
|
|
|
*/ |
129
|
|
|
public function getParentClass(): string |
130
|
|
|
{ |
131
|
|
|
return get_class($this->getParent()); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Returns the parent object if it exists. |
136
|
|
|
* |
137
|
|
|
* @return Reader|Writer |
138
|
|
|
*/ |
139
|
|
|
public function getParent() |
140
|
|
|
{ |
141
|
|
|
if (!$this->hasParent()) { |
142
|
|
|
throw new Exception('Parent object is not set.'); |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
return $this->parent; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* Determines if the parent object was set. |
150
|
|
|
* |
151
|
|
|
* @return bool |
152
|
|
|
*/ |
153
|
|
|
public function hasParent(): bool |
154
|
|
|
{ |
155
|
|
|
return !is_null($this->parent); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* Enable the comments flag. |
160
|
|
|
* |
161
|
|
|
* @return \AustinHeap\Security\Txt\SecurityTxt |
162
|
|
|
*/ |
163
|
|
|
public function enableComments(): SecurityTxt |
164
|
|
|
{ |
165
|
|
|
return $this->setComments(true); |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Disable the comments flag. |
170
|
|
|
* |
171
|
|
|
* @return \AustinHeap\Security\Txt\SecurityTxt |
172
|
|
|
*/ |
173
|
|
|
public function disableComments(): SecurityTxt |
174
|
|
|
{ |
175
|
|
|
return $this->setComments(false); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* Set the comments flag. |
180
|
|
|
* |
181
|
|
|
* @param string $comments |
182
|
|
|
* |
183
|
|
|
* @return \AustinHeap\Security\Txt\SecurityTxt |
184
|
|
|
*/ |
185
|
|
|
public function setComments(bool $comments): SecurityTxt |
186
|
|
|
{ |
187
|
|
|
$this->comments = $comments; |
188
|
|
|
|
189
|
|
|
return $this; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Get the comments flag. |
194
|
|
|
* |
195
|
|
|
* @return bool |
196
|
|
|
*/ |
197
|
|
|
public function getComments(): bool |
198
|
|
|
{ |
199
|
|
|
return $this->comments; |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* Enable the debug flag. |
204
|
|
|
* |
205
|
|
|
* @return \AustinHeap\Security\Txt\SecurityTxt |
206
|
|
|
*/ |
207
|
|
|
public function enableDebug(): SecurityTxt |
208
|
|
|
{ |
209
|
|
|
return $this->setDebug(true); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* Disable the debug flag. |
214
|
|
|
* |
215
|
|
|
* @return \AustinHeap\Security\Txt\SecurityTxt |
216
|
|
|
*/ |
217
|
|
|
public function disableDebug(): SecurityTxt |
218
|
|
|
{ |
219
|
|
|
return $this->setDebug(false); |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Set the debug flag. |
224
|
|
|
* |
225
|
|
|
* @param bool $debug |
226
|
|
|
* |
227
|
|
|
* @return \AustinHeap\Security\Txt\SecurityTxt |
228
|
|
|
*/ |
229
|
|
|
public function setDebug(bool $debug): SecurityTxt |
230
|
|
|
{ |
231
|
|
|
$this->debug = $debug; |
232
|
|
|
|
233
|
|
|
return $this; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Get the debug flag. |
238
|
|
|
* |
239
|
|
|
* @return bool |
240
|
|
|
*/ |
241
|
|
|
public function getDebug(): bool |
242
|
|
|
{ |
243
|
|
|
return $this->debug; |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
/** |
247
|
|
|
* Set the text. |
248
|
|
|
* |
249
|
|
|
* @param string $text |
250
|
|
|
* |
251
|
|
|
* @return \AustinHeap\Security\Txt\SecurityTxt |
252
|
|
|
*/ |
253
|
|
|
public function setText(string $text): SecurityTxt |
254
|
|
|
{ |
255
|
|
|
$this->text = $text; |
256
|
|
|
|
257
|
|
|
return $this; |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
/** |
261
|
|
|
* Get the text. |
262
|
|
|
* |
263
|
|
|
* @return string |
264
|
|
|
*/ |
265
|
|
|
public function getText(): string |
266
|
|
|
{ |
267
|
|
|
return $this->text === null ? '' : $this->text; |
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
/** |
271
|
|
|
* Stub generate function. Must be overridden by inheriting class that implements SecurityTxtInterface. |
272
|
|
|
* |
273
|
|
|
* @param bool $test_case |
274
|
|
|
* |
275
|
|
|
* @return Reader|Writer|null |
276
|
|
|
* @throws Exception |
277
|
|
|
*/ |
278
|
|
|
public function execute(bool $test_case = false) |
279
|
|
|
{ |
280
|
|
|
return $this->overrideMissing(__FUNCTION__, $test_case); |
|
|
|
|
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* Stub reset function. Must be overridden by inheriting class that implements SecurityTxtInterface. |
285
|
|
|
* |
286
|
|
|
* @param bool $test_case |
287
|
|
|
* |
288
|
|
|
* @return Reader|Writer|null |
289
|
|
|
* @throws Exception |
290
|
|
|
*/ |
291
|
|
|
public function reset(bool $test_case = false) |
292
|
|
|
{ |
293
|
|
|
return $this->overrideMissing(__FUNCTION__, $test_case); |
|
|
|
|
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
/** |
297
|
|
|
* Throws an exception when the inheriting class did not correctly implement SecurityTxtInterface. |
298
|
|
|
* |
299
|
|
|
* @param string $function |
300
|
|
|
* @param bool $test_case |
301
|
|
|
* |
302
|
|
|
* @return null |
303
|
|
|
* @throws Exception |
304
|
|
|
*/ |
305
|
|
|
public function overrideMissing(string $function, bool $test_case = false) |
306
|
|
|
{ |
307
|
|
|
if ($test_case) { |
308
|
|
|
return null; |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
throw new Exception('Function "' . $function . '" must be overridden by parent SecurityTxtInterface before being called.'); |
312
|
|
|
} |
313
|
|
|
} |
314
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.