Completed
Push — master ( 73efce...6751ec )
by JHONATAN
05:35
created

TransferPersister   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 25
dl 0
loc 131
ccs 62
cts 62
cp 1
rs 10
c 1
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A save() 0 21 4
A persistTransfer() 0 18 4
A setIdValueOnAssociation() 0 7 2
C persistAssociation() 0 22 9
A renewState() 0 4 1
A persistHas() 0 16 4
1
<?php
2
3
namespace Vox\Webservice;
4
5
use Doctrine\Common\Collections\Collection;
6
use Metadata\MetadataFactoryInterface;
7
use ProxyManager\Proxy\AccessInterceptorValueHolderInterface;
8
use Traversable;
9
use Vox\Metadata\PropertyMetadata;
10
use Vox\Webservice\Mapping\BelongsTo;
11
use Vox\Webservice\Mapping\HasMany;
12
use Vox\Webservice\Mapping\HasOne;
13
use Vox\Webservice\Metadata\TransferMetadata;
14
15
/**
16
 * The transfer persister will do the work of persisting and assuring the objects are on the
17
 * correct state
18
 * 
19
 * @author Jhonatan Teixeira <[email protected]>
20
 */
21
class TransferPersister implements TransferPersisterInterface
22
{
23
    use MetadataTrait;
24
    
25
    /**
26
     * @var MetadataFactoryInterface
27
     */
28
    private $metadataFactory;
29
    
30
    /**
31
     * @var UnityOfWorkInterface
32
     */
33
    private $unityOfWork;
34
    
35
    /**
36
     * @var WebserviceClientInterface
37
     */
38
    private $webserviceClient;
39
    
40 26
    public function __construct(
41
        MetadataFactoryInterface $metadataFactory,
42
        UnityOfWorkInterface $unityOfWork,
43
        WebserviceClientInterface $webserviceClient
44
    ) {
45 26
        $this->metadataFactory  = $metadataFactory;
46 26
        $this->unityOfWork      = $unityOfWork;
47 26
        $this->webserviceClient = $webserviceClient;
48 26
    }
49
50
    
51 12
    public function save($object)
52
    {
53 12
        $transfer = $object;
54
        
55 12
        if ($object instanceof AccessInterceptorValueHolderInterface) {
56 9
            $transfer = $transfer->getWrappedValueHolderValue();
57
        }
58
        
59 12
        $metadata = $this->getClassMetadata($transfer);
60
        
61 12
        foreach ($metadata->associations as $name => $association) {
62 5
            $assocValue = $association->getValue($transfer);
63
            
64 5
            if (!$assocValue) {
65 4
                continue;
66
            }
67
            
68 4
            $this->persistAssociation($object, $assocValue, $metadata, $association);
69
        }
70
        
71 12
        $this->persistTransfer($object);
72 12
    }
73
    
74 4
    private function persistAssociation($object, $association, TransferMetadata $metadata, PropertyMetadata $property)
75
    {
76 4
        if (is_array($association) || $association instanceof Traversable || $association instanceof Collection) {
77 1
            foreach ($association as $transfer) {
78 1
                $this->persistAssociation($object, $transfer, $metadata, $property);
79
            }
80
81 1
            return;
82
        }
83
        
84 4
        if (!$this->unityOfWork->isNew($association) && !$this->unityOfWork->isDirty($association)) {
85 2
            return;
86
        }
87
        
88 2
        $this->save($association);
89
        
90 2
        if ($property->hasAnnotation(HasOne::class)) {
91 2
            $this->persistHas($object, $association, $property, $property->getAnnotation(HasOne::class));
92
        }
93
        
94 2
        if ($property->hasAnnotation(HasMany::class)) {
95 1
            $this->persistHas($object, $association, $property, $property->getAnnotation(HasMany::class));
96
        }
97
    }
98 2
    
99 1
    private function persistHas($object, $association, PropertyMetadata $property, $annotation)
100
    {
101 2
        $type                  = preg_replace('/\[\]$/', '', $property->type);
102
        $relationClassMetadata = $this->metadataFactory->getMetadataForClass($type);
103 2
        $relationObject        = $property->getValue($object);
104
        $foreignProperty       = $relationClassMetadata->propertyMetadata[$annotation->foreignField];
0 ignored issues
show
Bug introduced by
The property propertyMetadata does not seem to exist on Metadata\ClassHierarchyMetadata.
Loading history...
105
106 2
        if ($relationObject instanceof Traversable || is_array($relationObject)) {
107 2
            foreach ($relationObject as $relationItem) {
108 2
                $this->setIdValueOnAssociation($object, $relationItem, $foreignProperty);
109 2
            }
110
111 2
            return;
112 1
        }
113
114 2
        $this->setIdValueOnAssociation($object, $association, $foreignProperty);
115
    }
116 1
117
    private function setIdValueOnAssociation($object, $association, PropertyMetadata $foreignProperty)
118 1
    {
119 1
        $assocId  = $foreignProperty->getValue($association);
120 1
        $objectId = $this->getIdValue($object);
121 1
122
        if ($assocId !== $objectId) {
123 1
            $foreignProperty->setValue($association, $objectId);
124 1
        }
125 1
    }
126
    
127
    private function persistTransfer($object)
128 1
    {
129
        if ($this->unityOfWork->isNew($object)) {
130
            $this->webserviceClient->post($object);
131 1
            $this->renewState($object);
132 1
            
133
            return;
134 1
        }
135
        
136 1
        if ($this->unityOfWork->isDirty($object)) {
137 1
            $this->webserviceClient->put($object);
138
            $this->renewState($object);
139 1
            
140 1
            return;
141
        }
142 1
        
143
        if ($this->unityOfWork->isRemoved($object)) {
144 12
            $this->webserviceClient->delete(get_class($object), $this->getIdValue($object));
145
        }
146 12
    }
147 4
    
148 4
    private function renewState($object)
149
    {
150 4
        $this->unityOfWork->detach($object);
151
        $this->unityOfWork->attach($object);
152
    }
153
}
154