Passed
Push — main ( 3f5d4e...df4575 )
by James Ekow Abaka
01:53
created

DatabaseItem::push()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
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
abstract class DatabaseItem
11
{    
12
    private ?DatabaseItem $encapsulated = null;
13
    private ChangeLogger $driver;
14
    protected $new = false;
15
    private $changes = array();
16
    protected $home;
17
    protected DatabaseItemFactory $factory;
18
    private EncapsulatedStack $stack;   
19
    
20
    public function setFactory(DatabaseItemFactory $factory)
21
    {
22
        $this->factory = $factory;
23
    }
24
25
    protected function addChange($property, $attribute, $value)
26
    {
27
        if (!$this->isNew()) {
28
            $currentDescription = $this->buildDescription();
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
        return $this;
45
    }
46
47
    public function isNew()
48
    {
49
        return $this->new;
50
    }
51
52
    protected function getDriver()
53
    {
54
        return $this->driver;
55
    }
56
57
    public function setDriver($driver)
58
    {
59
        $this->driver = $driver;
60
    }
61
    
62
    public function setStack(EncapsulatedStack $stack): void
63
    {
64
        $this->stack = $stack;
65
        if ($this->stack->hasItems()) {
66
            $this->encapsulated = $this->stack->top();            
67
        }
68
    }
69
70
    public function __call($method, $arguments)
71
    {
72
        if (!is_object($this->encapsulated)) {
73
            throw new SyntaxErrorException("Failed to call method '{$method}'", $this->home ?? '');
74
        } else if (method_exists($this->encapsulated, $method)) {
75
            $method = new \ReflectionMethod($this->encapsulated, $method);
76
            $this->commit();
77
            $this->stack->pop();
78
            return $method->invokeArgs($this->encapsulated, $arguments);
79
        } else {
80
            $this->commit();
81
            $this->stack->pop();
82
            return $this->encapsulated->__call($method, $arguments);
83
        }
84
    }
85
86
    public function commit()
87
    {
88
        if ($this instanceof Commitable && $this->isNew()) {
89
            $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

89
            $this->/** @scrutinizer ignore-call */ 
90
                   commitNew();
Loading history...
90
            $this->new = false;
91
        }
92
93
        foreach ($this->changes as $change) {
94
            $this->driver->{$change['method']}($change['args']);
95
        }
96
97
        return $this;
98
    }
99
100
    public function rename($newName)
101
    {
102
        return $this->addChange('name', 'name', $newName);
103
    }
104
    
105
    public function setHome(string $home): void
106
    {
107
        $this->home = $home;
108
    }
109
        
110
    abstract public function init();
111
//    abstract public function commitNew();
112
    abstract protected function buildDescription();
113
}
114