Passed
Push — 2.x ( 34ebf1...cd0557 )
by Terry
02:02
created

FirewallTrait::setCheckpoint()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the Shieldon package.
4
 *
5
 * (c) Terry L. <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * php version 7.1.0
11
 *
12
 * @category  Web-security
13
 * @package   Shieldon
14
 * @author    Terry Lin <[email protected]>
15
 * @copyright 2019 terrylinooo
16
 * @license   https://github.com/terrylinooo/shieldon/blob/2.x/LICENSE MIT
17
 * @link      https://github.com/terrylinooo/shieldon
18
 * @see       https://shieldon.io
19
 */
20
21
declare(strict_types=1);
22
23
namespace Shieldon\Firewall;
24
25
use function count;
26
use function explode;
27
28
/*
29
 * FirewallTrait
30
 */
31
trait FirewallTrait
32
{
33
    /**
34
     * Shieldon instance.
35
     *
36
     * @var object
37
     */
38
    protected $kernel;
39
40
    /**
41
     * Configuration data of Shieldon.
42
     *
43
     * @var array
44
     */
45
    protected $configuration = [];
46
47
    /**
48
     * If status is false and then Sheldon will stop working.
49
     *
50
     * @var bool
51
     */
52
    protected $status = true;
53
    
54
    /**
55
     * The configuation file's path.
56
     *
57
     * @var string
58
     */
59
    protected $directory = '/tmp';
60
61
    /**
62
     * The filename of the configuration file.
63
     *
64
     * @var string
65
     */
66
    protected $filename = 'config.firewall.json';
67
68
    /**
69
     * A file that confirms the required dictories or database tables 
70
     * have been created.
71
     *
72
     * @var string
73
     */
74
    protected $checkpoint = 'driver_initialized.txt';
75
    
76
    /**
77
     * The prefix of the database tables, or the name of file directory.
78
     *
79
     * @var string
80
     */
81
    protected $channel = '';
82
83
    /**
84
     * Get the Shieldon instance.
85
     *
86
     * @return object
87
     */
88
    public function getKernel()
89
    {
90
        return $this->kernel;
91
    }
92
93
    /**
94
     * Get the configuation settings.
95
     *
96
     * @return array
97
     */
98
    public function getConfiguration(): array
99
    {
100
        return $this->configuration;
101
    }
102
103
    /**
104
     * Get the directory where the data stores.
105
     *
106
     * @return string
107
     */
108
    public function getDirectory(): string
109
    {
110
        return $this->directory;
111
    }
112
113
    /**
114
     * Get the filename where the configuration saves.
115
     *
116
     * @return string
117
     */
118
    public function getFileName(): string
119
    {
120
        return $this->filename;
121
    }
122
123
    /**
124
     * Get a variable from configuration.
125
     *
126
     * @param string $field The field of the configuration.
127
     *
128
     * @return mixed
129
     */
130
    public function getConfig(string $field)
131
    {
132
        $v = explode('.', $field);
133
        $c = count($v);
134
135
        switch ($c) {
136
            case 1:
137
                return $this->configuration[$v[0]] ?? '';
138
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
139
140
            case 2:
141
                return $this->configuration[$v[0]][$v[1]] ?? '';
142
                break;
143
144
            case 3:
145
                return $this->configuration[$v[0]][$v[1]][$v[2]] ?? '';
146
                break;
147
148
            case 4:
149
                return $this->configuration[$v[0]][$v[1]][$v[2]][$v[3]] ?? '';
150
                break;
151
152
            case 5:
153
                return $this->configuration[$v[0]][$v[1]][$v[2]][$v[3]][$v[4]] ?? '';
154
                break;
155
        }
156
        return '';
157
    }
158
159
    /**
160
     * Set a variable to the configuration.
161
     *
162
     * @param string $field The field of the configuration.
163
     * @param mixed  $value The vale of a field in the configuration.
164
     *
165
     * @return void
166
     */
167
    public function setConfig(string $field, $value): void
168
    {
169
        $v = explode('.', $field);
170
        $c = count($v);
171
172
        switch ($c) {
173
            case 1:
174
                $this->configuration[$v[0]] = $value;
175
                break;
176
177
            case 2:
178
                $this->configuration[$v[0]][$v[1]] = $value;
179
                break;
180
181
            case 3:
182
                $this->configuration[$v[0]][$v[1]][$v[2]] = $value;
183
                break;
184
185
            case 4:
186
                $this->configuration[$v[0]][$v[1]][$v[2]][$v[3]] = $value;
187
                break;
188
189
            case 5:
190
                $this->configuration[$v[0]][$v[1]][$v[2]][$v[3]][$v[4]] = $value;
191
                break;
192
        }
193
    }
194
195
    /**
196
     * Get options from the configuration file.
197
     * This method is same as `$this->getConfig()` but returning value from array directly.
198
     *
199
     * @param string $option  The option of the section in the the configuration.
200
     * @param string $section The section in the configuration.
201
     *
202
     * @return mixed
203
     */
204
    protected function getOption(string $option, string $section = '')
205
    {
206
        if (!empty($this->configuration[$section][$option])) {
207
            return $this->configuration[$section][$option];
208
        }
209
210
        if (!empty($this->configuration[$option]) && $section === '') {
211
            return $this->configuration[$option];
212
        }
213
214
        return false;
215
    }
216
217
    /**
218
     * Update configuration file.
219
     *
220
     * @return void
221
     */
222
    protected function updateConfig(): void
223
    {
224
        $configFilePath = $this->directory . '/' . $this->filename;
225
226
        if (!file_exists($configFilePath)) {
227
            if (!is_dir($this->directory)) {
228
229
                // @codeCoverageIgnoreStart
230
        
231
                $originalUmask = umask(0);
232
                @mkdir($this->directory, 0777, true);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for mkdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

232
                /** @scrutinizer ignore-unhandled */ @mkdir($this->directory, 0777, true);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
233
                umask($originalUmask);
234
235
                // @codeCoverageIgnoreEnd
236
            }
237
        }
238
239
        file_put_contents($configFilePath, json_encode($this->configuration));
240
    }
241
242
    /**
243
     * Get the filename of the checkpoint file.
244
     *
245
     * @return string
246
     */
247
    protected function getCheckpoint(): string
248
    {
249
        $driverType = $this->getOption('driver_type');
250
251
        return $this->directory . '/' . $this->channel .  '_' . $driverType . '_' . $this->checkpoint;
0 ignored issues
show
Bug introduced by
Are you sure $driverType of type false|mixed can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

251
        return $this->directory . '/' . $this->channel .  '_' . /** @scrutinizer ignore-type */ $driverType . '_' . $this->checkpoint;
Loading history...
252
    }
253
254
    /**
255
     * Are database tables created? 
256
     *
257
     * @return bool
258
     */
259
    protected function hasCheckpoint(): bool
260
    {
261
        if (file_exists($this->getCheckpoint())) {
262
            return true;
263
        }
264
265
        return false;
266
    }
267
268
    /**
269
     * Are database tables created?
270
     * 
271
     * @param bool $create Is create the checkpoint file, or not.
272
     *
273
     * @return void
274
     */
275
    protected function setCheckpoint(bool $create = true): void
276
    {
277
        if ($create) {
278
            file_put_contents($this->getCheckpoint(), date('Y-m-d H:i:s'));
279
        }
280
    }
281
}
282