Passed
Push — main ( c93099...0e69d1 )
by James Ekow Abaka
17:15
created

DatabaseItem   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Importance

Changes 4
Bugs 1 Features 0
Metric Value
eloc 50
dl 0
loc 110
rs 10
c 4
b 1
f 0
wmc 20

12 Methods

Rating   Name   Duplication   Size   Complexity  
A setFactory() 0 3 1
A isNew() 0 3 1
A init() 0 4 2
A setChangeLogger() 0 3 1
A rename() 0 3 1
A getStack() 0 3 1
A commit() 0 12 4
A addChange() 0 21 2
A __call() 0 13 3
A getChangeLogger() 0 3 1
A setHome() 0 3 1
A setStack() 0 5 2
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 = false;
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
Bug introduced by
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;
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 (method_exists($this->encapsulated, $method)) {
81
            $method = new \ReflectionMethod($this->encapsulated, $method);
82
            $this->commit();
83
            $this->stack->pop();
84
            return $method->invokeArgs($this->encapsulated, $arguments);
85
        } else {
86
            $this->commit();
87
            $this->stack->pop();
88
            return $this->encapsulated->__call($method, $arguments);
89
        }
90
    }
91
92
    public function commit(): DatabaseItem
93
    {
94
        if ($this instanceof Commitable && $this->isNew()) {
95
            $this->commitNew();
0 ignored issues
show
Bug introduced by
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

95
            $this->/** @scrutinizer ignore-call */ 
96
                   commitNew();
Loading history...
96
            $this->new = false;
97
        }
98
99
        foreach ($this->changes as $change) {
100
            $this->changeLogger->{$change['method']}($change['args']);
101
        }
102
103
        return $this;
104
    }
105
106
    public function rename($newName): DatabaseItem
107
    {
108
        return $this->addChange('name', 'name', $newName);
109
    }
110
    
111
    public function setHome(string $home): void
112
    {
113
        $this->home = $home;
114
    }
115
116
    public function init(): void
117
    {
118
        if ($this instanceof Initializable) {
119
            $this->initialize();
0 ignored issues
show
Bug introduced by
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

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