Passed
Pull Request — master (#67)
by Aleksei
12:07
created

PhpFileSchemaProvider   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 16
eloc 35
dl 0
loc 80
rs 10
c 2
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A isWritable() 0 3 1
A removeFile() 0 12 4
A read() 0 9 3
A withConfig() 0 13 3
A clear() 0 8 2
A __construct() 0 3 1
A isReadable() 0 3 1
A write() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Cycle\Schema\Provider;
6
7
use Cycle\ORM\Schema;
8
use RuntimeException;
9
use Yiisoft\Aliases\Aliases;
10
use Yiisoft\Yii\Cycle\Schema\Converter\SchemaToPHP;
11
use Yiisoft\Yii\Cycle\Schema\SchemaProviderInterface;
12
13
/**
14
 * Be careful, using this class may be insecure.
15
 */
16
final class PhpFileSchemaProvider implements SchemaProviderInterface
17
{
18
    const MODE_READ_AND_WRITE = 0;
19
    const MODE_WRITE_ONLY = 1;
20
21
    private string $file = '';
22
    private int $mode = self::MODE_READ_AND_WRITE;
23
24
    private Aliases $aliases;
25
26
    public function __construct(Aliases $aliases)
27
    {
28
        $this->aliases = $aliases;
29
    }
30
31
    public function withConfig(array $config): self
32
    {
33
        $new = clone $this;
34
35
        // required option
36
        if ($this->file === '' && !array_key_exists('file', $config)) {
37
            throw new \InvalidArgumentException('The "file" parameter is required.');
38
        }
39
        $new->file = $this->aliases->get($config['file']);
40
41
        $new->mode = $config['mode'] ?? $this->mode;
42
43
        return $new;
44
    }
45
46
    public function read(): ?array
47
    {
48
        if ($this->mode === self::MODE_WRITE_ONLY) {
49
            throw new RuntimeException(__CLASS__ . ' can not read schema.');
50
        }
51
        if (!is_file($this->file)) {
52
            return null;
53
        }
54
        return include $this->file;
55
    }
56
57
    public function write(array $schema): bool
58
    {
59
        $content = (new SchemaToPHP(new Schema($schema)))->convert();
60
        file_put_contents($this->file, $content);
61
        return true;
62
    }
63
64
    private function removeFile(): void
65
    {
66
        if (!file_exists($this->file)) {
67
            return;
68
        }
69
        if (!is_file($this->file)) {
70
            throw new RuntimeException("`$this->file` is not a file.");
71
        }
72
        if (!is_writable($this->file)) {
73
            throw new RuntimeException("File `$this->file` is not writeable.");
74
        }
75
        unlink($this->file);
76
    }
77
78
    public function clear(): bool
79
    {
80
        try {
81
            $this->removeFile();
82
        } catch (\Throwable $e) {
83
            return false;
84
        }
85
        return true;
86
    }
87
88
    public function isWritable(): bool
89
    {
90
        return true;
91
    }
92
93
    public function isReadable(): bool
94
    {
95
        return $this->mode !== self::MODE_WRITE_ONLY;
96
    }
97
}
98