Issues (90)

src/database/DatabaseItem.php (3 issues)

Labels
Severity
1
<?php
2
3
namespace yentu\database;
4
5
use yentu\exceptions\SyntaxErrorException;
6
use yentu\factories\DatabaseItemFactory;
7
use yentu\ChangeLogger;
8
9
10
class DatabaseItem
11
{    
12
    private ?DatabaseItem $encapsulated = null;
13
    private ChangeLogger $changeLogger;
14
    protected ?bool $new = null;
15
    private array $changes = [];
16
    protected string $home;
17
    protected DatabaseItemFactory $factory;
18
    private EncapsulatedStack $stack;   
19
    
20
    public function setFactory(DatabaseItemFactory $factory): void
21
    {
22
        $this->factory = $factory;
23
    }
24
25
    protected function addChange($property, $attribute, $value): DatabaseItem
26
    {
27
        if (!$this->isNew()) {
28
            $currentDescription = $this->buildDescription();
0 ignored issues
show
The method buildDescription() does not exist on yentu\database\DatabaseItem. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

28
            /** @scrutinizer ignore-call */ 
29
            $currentDescription = $this->buildDescription();
Loading history...
29
            $newDescription = $currentDescription;
30
            $newDescription[$attribute] = $value;
31
            $class = new \ReflectionClass($this);
32
            $name = $class->getShortName();
33
34
            $this->changes[] = \yentu\Parameters::wrap(array(
35
                'method' => "change{$name}" . str_replace('_', '', $attribute),
36
                'args' => array(
37
                    'from' => $currentDescription,
38
                    'to' => $newDescription
39
                )
40
            ));
41
        }
42
43
        (new \ReflectionProperty($this, $property))->setValue($this, $value);
44
45
        return $this;
46
    }
47
48
    public function isNew(): bool
49
    {
50
        return $this->new ?? false;
51
    }
52
53
    protected function getChangeLogger(): ChangeLogger
54
    {
55
        return $this->changeLogger;
56
    }
57
58
    public function setChangeLogger($changeLogger): void
59
    {
60
        $this->changeLogger = $changeLogger;
61
    }
62
    
63
    public function setStack(EncapsulatedStack $stack): void
64
    {
65
        $this->stack = $stack;
66
        if ($this->stack->hasItems()) {
67
            $this->encapsulated = $this->stack->top();            
68
        }
69
    }
70
71
    public function getStack(): EncapsulatedStack
72
    {
73
        return $this->stack;
74
    }
75
76
    public function __call($method, $arguments)
77
    {
78
        if (!is_object($this->encapsulated)) {
79
            throw new SyntaxErrorException("Failed to call method '{$method}'.", $this->home ?? '');
80
        } else if (!$this->stack->hasItems()) {
81
            throw new SyntaxErrorException("The method '{$method}' does not exist.", $this->home ?? '');
82
        } else if (method_exists($this->encapsulated, $method)) {
83
            $method = new \ReflectionMethod($this->encapsulated, $method);
84
            $this->commit();
85
            $this->stack->pop();
86
            return $method->invokeArgs($this->encapsulated, $arguments);
87
        } else {
88
            $this->commit();
89
            $this->stack->pop();
90
            return $this->encapsulated->__call($method, $arguments);
91
        }
92
    }
93
94
    public function commit(): DatabaseItem
95
    {
96
        if ($this instanceof Commitable && $this->isNew()) {
97
            $this->commitNew();
0 ignored issues
show
The method commitNew() does not exist on yentu\database\DatabaseItem. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

97
            $this->/** @scrutinizer ignore-call */ 
98
                   commitNew();
Loading history...
98
            $this->new = false;
99
        }
100
101
        foreach ($this->changes as $change) {
102
            $this->changeLogger->{$change['method']}($change['args']);
103
        }
104
105
        return $this;
106
    }
107
108
    public function rename($newName): DatabaseItem
109
    {
110
        return $this->addChange('name', 'name', $newName);
111
    }
112
    
113
    public function setHome(string $home): void
114
    {
115
        $this->home = $home;
116
    }
117
118
    public function init(): void
119
    {
120
        if ($this instanceof Initializable) {
121
            $this->initialize();
0 ignored issues
show
The method initialize() does not exist on yentu\database\DatabaseItem. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

121
            $this->/** @scrutinizer ignore-call */ 
122
                   initialize();
Loading history...
122
        }
123
    }
124
}
125