1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Vox\Webservice\Proxy; |
4
|
|
|
|
5
|
|
|
use ProxyManager\Configuration; |
6
|
|
|
use ProxyManager\Factory\AccessInterceptorValueHolderFactory; |
7
|
|
|
use ProxyManager\Proxy\AccessInterceptorValueHolderInterface; |
8
|
|
|
use Vox\Metadata\PropertyMetadata; |
9
|
|
|
use Vox\Webservice\Mapping\BelongsTo; |
10
|
|
|
use Vox\Webservice\Mapping\HasMany; |
11
|
|
|
use Vox\Webservice\Mapping\HasOne; |
12
|
|
|
use Vox\Webservice\Metadata\TransferMetadata; |
13
|
|
|
use Vox\Webservice\TransferManagerInterface; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* a proxy factory for the transfers, it uses the ocramius proxy generator |
17
|
|
|
* |
18
|
|
|
* @author Jhonatan Teixeira <[email protected]> |
19
|
|
|
*/ |
20
|
|
|
class ProxyFactory implements ProxyFactoryInterface |
21
|
|
|
{ |
22
|
|
|
/** |
23
|
|
|
* @var AccessInterceptorValueHolderFactory |
24
|
|
|
*/ |
25
|
|
|
private $accessInterceptorFactory; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* @var Configuration |
29
|
|
|
*/ |
30
|
|
|
private $proxyConfig; |
31
|
|
|
|
32
|
15 |
|
public function __construct(Configuration $proxyConfig = null) |
33
|
|
|
{ |
34
|
15 |
|
$this->accessInterceptorFactory = new AccessInterceptorValueHolderFactory($proxyConfig); |
35
|
15 |
|
$this->proxyConfig = $proxyConfig; |
36
|
15 |
|
} |
37
|
|
|
|
38
|
14 |
|
public function createProxy($class, TransferManagerInterface $transferManager): AccessInterceptorValueHolderInterface |
39
|
|
|
{ |
40
|
14 |
|
$className = is_object($class) ? get_class($class) : $class; |
41
|
14 |
|
$metadata = $transferManager->getClassMetadata($className); |
42
|
14 |
|
$object = is_object($class) ? $class : new $class(); |
43
|
|
|
|
44
|
14 |
|
$interceptors = []; |
45
|
|
|
|
46
|
14 |
|
foreach ($metadata->propertyMetadata as $name => $config) { |
47
|
14 |
|
$getter = sprintf('get%s', ucfirst($name)); |
48
|
|
|
|
49
|
14 |
|
if (isset($metadata->methodMetadata[$getter])) { |
50
|
14 |
|
$interceptors[$getter] = $this->createGetterInterceptor($metadata, $name, $object, $transferManager); |
51
|
|
|
} |
52
|
|
|
} |
53
|
|
|
|
54
|
14 |
|
return $this->accessInterceptorFactory->createProxy($object, $interceptors); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
private function createGetterInterceptor( |
58
|
|
|
TransferMetadata $metadata, |
59
|
|
|
string $name, |
60
|
|
|
$object, |
61
|
|
|
TransferManagerInterface $transferManager |
62
|
|
|
): callable { |
63
|
9 |
|
return function () use ($metadata, $name, $object, $transferManager) { |
64
|
|
|
/* @var $propertyMetadata PropertyMetadata */ |
65
|
5 |
|
$propertyMetadata = $metadata->propertyMetadata[$name]; |
66
|
5 |
|
$type = $propertyMetadata->getParsedType(); |
67
|
|
|
|
68
|
5 |
|
if (class_exists($type)) { |
69
|
4 |
|
$this->fetchBelongsTo($metadata, $propertyMetadata, $transferManager, $object, $type); |
70
|
4 |
|
$this->fetchHasOne($metadata, $propertyMetadata, $transferManager, $object, $type); |
71
|
4 |
|
$this->fetchHasMany($metadata, $propertyMetadata, $transferManager, $object, $type); |
72
|
|
|
} |
73
|
9 |
|
}; |
74
|
|
|
} |
75
|
|
|
|
76
|
4 |
View Code Duplication |
private function fetchBelongsTo( |
|
|
|
|
77
|
|
|
TransferMetadata $metadata, |
78
|
|
|
PropertyMetadata $propertyMetadata, |
79
|
|
|
TransferManagerInterface $transferManager, |
80
|
|
|
$object, |
81
|
|
|
string $type |
82
|
|
|
) { |
83
|
4 |
|
$belongsTo = $propertyMetadata->getAnnotation(BelongsTo::class); |
84
|
|
|
|
85
|
4 |
|
if ($belongsTo instanceof BelongsTo && empty($propertyMetadata->getValue($object))) { |
86
|
4 |
|
$idValue = $metadata->propertyMetadata[$belongsTo->foreignField]->getValue($object); |
87
|
|
|
|
88
|
4 |
|
if (!$idValue) { |
89
|
|
|
return; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
$data = $transferManager |
93
|
4 |
|
->find($type, $idValue); |
94
|
|
|
|
95
|
4 |
|
$propertyMetadata->setValue($object, $data); |
96
|
|
|
} |
97
|
4 |
|
} |
98
|
|
|
|
99
|
4 |
View Code Duplication |
private function fetchHasOne( |
|
|
|
|
100
|
|
|
TransferMetadata $metadata, |
101
|
|
|
PropertyMetadata $propertyMetadata, |
102
|
|
|
TransferManagerInterface $transferManager, |
103
|
|
|
$object, |
104
|
|
|
string $type |
105
|
|
|
) { |
106
|
4 |
|
$hasOne = $propertyMetadata->getAnnotation(HasOne::class); |
107
|
4 |
|
$id = $metadata->id->getValue($object); |
108
|
|
|
|
109
|
4 |
|
if ($hasOne instanceof HasOne && !empty($id)) { |
110
|
2 |
|
$data = $transferManager->getRepository($type) |
111
|
2 |
|
->findOneBy([$hasOne->foreignField => $id]); |
112
|
|
|
|
113
|
2 |
|
$propertyMetadata->setValue($object, $data); |
114
|
|
|
} |
115
|
4 |
|
} |
116
|
|
|
|
117
|
4 |
View Code Duplication |
private function fetchHasMany( |
|
|
|
|
118
|
|
|
TransferMetadata $metadata, |
119
|
|
|
PropertyMetadata $propertyMetadata, |
120
|
|
|
TransferManagerInterface $transferManager, |
121
|
|
|
$object, |
122
|
|
|
string $type |
123
|
|
|
) { |
124
|
4 |
|
$hasMany = $propertyMetadata->getAnnotation(HasMany::class); |
125
|
4 |
|
$id = $metadata->id->getValue($object); |
126
|
|
|
|
127
|
4 |
|
if ($hasMany instanceof HasMany && !empty($id)) { |
128
|
2 |
|
$data = $transferManager->getRepository($type) |
129
|
2 |
|
->findBy([$hasMany->foreignField => $metadata->id->getValue($object)]); |
130
|
|
|
|
131
|
2 |
|
$propertyMetadata->setValue($object, $data); |
132
|
|
|
} |
133
|
4 |
|
} |
134
|
|
|
|
135
|
|
|
public function registerProxyAutoloader() |
136
|
|
|
{ |
137
|
|
|
if ($this->proxyConfig) { |
138
|
|
|
spl_autoload_register($this->proxyConfig->getProxyAutoloader()); |
139
|
|
|
} |
140
|
|
|
} |
141
|
|
|
} |
142
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.