Passed
Pull Request — master (#1)
by Kevin
02:47
created

Proxy::instantiator()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 2
rs 10
1
<?php
2
3
namespace Zenstruck\Foundry;
4
5
use Doctrine\Persistence\ObjectManager;
6
use PHPUnit\Framework\Assert;
7
8
/**
9
 * @author Kevin Bond <[email protected]>
10
 */
11
final class Proxy
12
{
13
    private object $object;
14
    private string $class;
15
    private bool $autoRefresh = true;
16
17 94
    public function __construct(object $object)
18
    {
19 94
        $this->object = $object;
20 94
        $this->class = \get_class($object);
21 94
    }
22
23 34
    public function __call(string $method, array $arguments)
24
    {
25 34
        return $this->object()->{$method}(...$arguments);
26
    }
27
28 2
    public function __get(string $name)
29
    {
30 2
        return $this->object()->{$name};
31
    }
32
33 2
    public function __set(string $name, $value): void
34
    {
35 2
        $this->object()->{$name} = $value;
36 2
    }
37
38 2
    public function __unset(string $name): void
39
    {
40 2
        unset($this->object()->{$name});
41 2
    }
42
43 2
    public function __isset(string $name): bool
44
    {
45 2
        return isset($this->object()->{$name});
46
    }
47
48 4
    public function __toString(): string
49
    {
50 4
        if (!\method_exists($this->object, '__toString')) {
51 2
            throw new \RuntimeException(\sprintf('Proxied object "%s" cannot be converted to a string.', $this->class));
52
        }
53
54 2
        return $this->object()->__toString();
55
    }
56
57 50
    public function object(): object
58
    {
59 50
        if ($this->autoRefresh) {
60 34
            $this->refresh();
61
        }
62
63 50
        return $this->object;
64
    }
65
66 2
    public function save(): self
67
    {
68 2
        $this->objectManager()->persist($this->object);
69 2
        $this->objectManager()->flush();
70
71 2
        return $this;
72
    }
73
74 2
    public function remove(): self
75
    {
76 2
        $this->objectManager()->remove($this->object);
77 2
        $this->objectManager()->flush();
78
79 2
        return $this;
80
    }
81
82 36
    public function refresh(): self
83
    {
84 36
        if ($this->objectManager()->contains($this->object)) {
85 34
            $this->objectManager()->refresh($this->object);
86
87 34
            return $this;
88
        }
89
90 4
        if (!$object = $this->fetchObject()) {
91 2
            throw new \RuntimeException('The object no longer exists.');
92
        }
93
94 2
        $this->object = $object;
95
96 2
        return $this;
97
    }
98
99
    /**
100
     * @param mixed $value
101
     */
102 4
    public function forceSet(string $property, $value): self
103
    {
104 4
        return $this->forceSetAll([$property => $value]);
105
    }
106
107 4
    public function forceSetAll(array $properties): self
108
    {
109 4
        $object = $this->object();
110
111 4
        foreach ($properties as $property => $value) {
112 4
            Instantiator::forceSet($object, $property, $value);
113
        }
114
115 4
        return $this;
116
    }
117
118
    /**
119
     * @return mixed
120
     */
121 2
    public function forceGet(string $property)
122
    {
123 2
        return Instantiator::forceGet($this->object(), $property);
124
    }
125
126 2
    public function repository(): RepositoryProxy
127
    {
128 2
        return PersistenceManager::repositoryFor($this->class);
129
    }
130
131 72
    public function withAutoRefresh(): self
132
    {
133 72
        $this->autoRefresh = true;
134
135 72
        return $this;
136
    }
137
138 16
    public function withoutAutoRefresh(): self
139
    {
140 16
        $this->autoRefresh = false;
141
142 16
        return $this;
143
    }
144
145 2
    public function assertPersisted(): self
146
    {
147
        // todo improve message
148 2
        Assert::assertNotNull($this->fetchObject(), 'The object is not persisted.');
149
150 2
        return $this;
151
    }
152
153 2
    public function assertNotPersisted(): self
154
    {
155
        // todo improve message
156 2
        Assert::assertNull($this->fetchObject(), 'The object is persisted but it should not be.');
157
158 2
        return $this;
159
    }
160
161
    /**
162
     * Todo - move to RepositoryProxy?
163
     */
164 8
    private function fetchObject(): ?object
165
    {
166 8
        $id = $this->objectManager()->getClassMetadata($this->class)->getIdentifierValues($this->object);
167
168 8
        return empty($id) ? null : $this->objectManager()->find($this->class, $id);
169
    }
170
171 40
    private function objectManager(): ObjectManager
172
    {
173 40
        return PersistenceManager::objectManagerFor($this->class);
174
    }
175
}
176