-
Notifications
You must be signed in to change notification settings - Fork 11
/
JsonSerializationVisitor.php
107 lines (92 loc) · 4.1 KB
/
JsonSerializationVisitor.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<?php
namespace Adrotec\BreezeJs\Serializer;
use JMS\Serializer\Metadata\ClassMetadata as JMSClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadata;
use JMS\Serializer\Metadata\PropertyMetadata;
use Doctrine\Common\Persistence\Proxy;
use Doctrine\ORM\Proxy\Proxy as ORMProxy;
use JMS\Serializer\Context;
use JMS\Serializer\Naming\PropertyNamingStrategyInterface;
use Doctrine\ORM\EntityManager;
use Adrotec\BreezeJs\Serializer\Context\SaveChangesContextInterface;
class JsonSerializationVisitor extends \JMS\Serializer\JsonSerializationVisitor {
private $entityManager;
public function __construct(PropertyNamingStrategyInterface $namingStrategy, EntityManager $entityManager) {
parent::__construct($namingStrategy);
$this->entityManager = $entityManager;
}
public function visitProperty(PropertyMetadata $propertyMetadata, $data, Context $context) {
$v = $propertyMetadata->getValue($data);
$isSaveChanges = $context instanceof SaveChangesContextInterface;
if ($this->isProxyObject($v) && ($isSaveChanges || !$v->__isInitialized())) {
return;
}
if (!$propertyMetadata->reflection) {
return;
}
return parent::visitProperty($propertyMetadata, $data, $context);
}
private function isProxyObject($object)
{
if ($object instanceof Proxy || $object instanceof ORMProxy) {
return true;
}
return false;
}
public function endVisitingObject(JMSClassMetadata $metadata, $data, array $type, Context $context) {
$rs = parent::endVisitingObject($metadata, $data, $type, $context);
if (empty($rs)) {
return null;
}
$isSaveChanges = $context instanceof SaveChangesContextInterface;
if ($this->isProxyObject($data) && ($isSaveChanges || !$data->__isInitialized())) {
return null;
}
try {
$doctrineMeta = $this->entityManager->getClassMetadata($metadata->name);
if ($doctrineMeta) {
$rs['$type'] = strtr($type['name'], '\\', '.');
foreach ($doctrineMeta->associationMappings as $associationMapping) {
$foreignKey = $associationMapping['fieldName'] . 'Id';
if(isset($rs[$foreignKey])){
continue;
}
$isScalar = in_array((int) $associationMapping['type'], array(ClassMetadata::ONE_TO_ONE, ClassMetadata::MANY_TO_ONE));
$isOwningSide = isset($associationMapping['isOwningSide']) ? $associationMapping['isOwningSide'] : false;
if (!($isScalar && $isOwningSide)) {
continue;
}
try {
$getter = 'get' . $associationMapping['fieldName'];
if (method_exists($data, $getter)) {
$association = $data->$getter();
} else {
$refl = new \ReflectionClass($data);
if ($this->isProxyObject($data)) {
$refl = $refl->getParentClass();
}
try {
$prop = $refl->getProperty($associationMapping['fieldName']);
$prop->setAccessible(true);
$association = $prop->getValue($data);
} catch (\ReflectionException $e) {
}
}
if ($association) {
try {
$id = $association->getId();
$rs[$foreignKey] = $id;
} catch (\Exception $e) {
}
}
} catch (\ReflectionException $e) {
// continue;
}
}
}
} catch (\Exception $e) {
return $rs;
}
return $rs;
}
}