Completed
Push — master ( 5a1126...6e76a7 )
by Eric
02:38
created

AbstractGenericVisitor::leaveGenericScope()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Ivory Serializer package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ivory\Serializer\Visitor;
13
14
use Ivory\Serializer\Context\ContextInterface;
15
use Ivory\Serializer\Mapping\ClassMetadataInterface;
16
use Ivory\Serializer\Mapping\TypeMetadataInterface;
17
18
/**
19
 * @author GeLo <[email protected]>
20
 */
21
abstract class AbstractGenericVisitor extends AbstractVisitor
22
{
23
    /**
24
     * @var \SplStack
25
     */
26
    private $stack;
27
28
    /**
29
     * @var mixed
30
     */
31
    protected $result;
32
33
    /**
34
     * {@inheritdoc}
35
     */
36
    public function prepare($data, ContextInterface $context)
37
    {
38
        $this->stack = new \SplStack();
39
40
        return parent::prepare($data, $context);
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function visitArray($data, TypeMetadataInterface $type, ContextInterface $context)
47
    {
48
        $result = [];
49
50
        if (!empty($data)) {
51
            $this->enterGenericScope();
52
            $result = parent::visitArray($data, $type, $context);
53
            $this->leaveGenericScope();
54
        }
55
56
        return $this->visitData($result, $type, $context);
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function visitData($data, TypeMetadataInterface $type, ContextInterface $context)
63
    {
64
        if ($this->result === null) {
65
            $this->result = $data;
66
        }
67
68
        return $data;
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74
    public function startVisitingObject($data, ClassMetadataInterface $class, ContextInterface $context)
75
    {
76
        if (!parent::startVisitingObject($data, $class, $context)) {
77
            return false;
78
        }
79
80
        $this->enterGenericScope();
81
        $this->result = $this->createResult($class->getName());
82
83
        return true;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function finishVisitingObject($data, ClassMetadataInterface $class, ContextInterface $context)
90
    {
91
        parent::finishVisitingObject($data, $class, $context);
92
93
        return $this->leaveGenericScope();
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99
    public function getResult()
100
    {
101
        return $this->result;
102
    }
103
104
    /**
105
     * @param string $class
106
     *
107
     * @return mixed
108
     */
109
    abstract protected function createResult($class);
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    protected function doVisitArray($data, TypeMetadataInterface $type, ContextInterface $context)
115
    {
116
        $this->result = [];
117
118
        foreach ($data as $key => $value) {
119
            $this->result[$this->navigate($key, $context, $type->getOption('key'))] = $this->navigate(
120
                $value,
121
                $context,
122
                $type->getOption('value')
123
            );
124
        }
125
126
        return $this->result;
127
    }
128
129
    private function enterGenericScope()
130
    {
131
        $this->stack->push($this->result);
132
    }
133
134
    /**
135
     * @return mixed
136
     */
137
    private function leaveGenericScope()
138
    {
139
        $result = $this->result;
140
        $this->result = $this->stack->pop();
141
142
        if ($this->result === null) {
143
            $this->result = $result;
144
        }
145
146
        return $result;
147
    }
148
}
149