Completed
Push — middleware-wip ( 4a8d7b...75f70c )
by Romain
03:04
created

FormMetadataObject::setObject()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
/*
3
 * 2017 Romain CANON <[email protected]>
4
 *
5
 * This file is part of the TYPO3 FormZ project.
6
 * It is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License, either
8
 * version 3 of the License, or any later version.
9
 *
10
 * For the full copyright and license information, see:
11
 * http://www.gnu.org/licenses/gpl-3.0.html
12
 */
13
14
namespace Romm\Formz\Domain\Model\DataObject;
15
16
use Romm\Formz\Core\Core;
17
use Romm\Formz\Domain\Model\FormMetadata;
18
use Romm\Formz\Exceptions\EntryNotFoundException;
19
use TYPO3\CMS\Core\Type\TypeInterface;
20
use TYPO3\CMS\Core\Utility\ArrayUtility;
21
22
/**
23
 * Store and retrieve arbitrary data using the setter/getter functions.
24
 */
25
class FormMetadataObject implements TypeInterface
26
{
27
    /**
28
     * @var array
29
     */
30
    protected $metadata = [];
31
32
    /**
33
     * @var FormMetadata
34
     */
35
    protected $object;
36
37
    /**
38
     * @param string $data
39
     */
40
    public function __construct($data = null)
41
    {
42
        if ($data) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
43
            $data = unserialize($data);
44
45
            if (is_array($data)
46
                && isset($data['metadata'])
47
            ) {
48
                $this->metadata = $data['metadata'];
49
            }
50
        }
51
    }
52
53
    /**
54
     * @param string $key
55
     * @return mixed
56
     * @throws EntryNotFoundException
57
     */
58
    public function get($key)
59
    {
60
        if (false === $this->has($key)) {
61
            throw EntryNotFoundException::metadataNotFound($key);
62
        }
63
64
        return ArrayUtility::getValueByPath($this->metadata, $key, '.');
65
    }
66
67
    /**
68
     * @param string $key
69
     * @return bool
70
     */
71
    public function has($key)
72
    {
73
        return ArrayUtility::isValidPath($this->metadata, $key, '.');
74
    }
75
76
    /**
77
     * @param string $key
78
     * @param mixed  $value
79
     */
80
    public function set($key, $value)
81
    {
82
        $this->metadata = ArrayUtility::setValueByPath($this->metadata, $key, $value, '.');
83
    }
84
85
    /**
86
     * @param string $key
87
     */
88
    public function remove($key)
89
    {
90
        if ($this->has($key)) {
91
            $this->metadata = ArrayUtility::removeByPath($this->metadata, $key, '.');
92
        }
93
    }
94
95
    /**
96
     * Persists the last changes of this instance in database.
97
     */
98
    public function persist()
99
    {
100
        $persistenceManager = Core::get()->getPersistenceManager();
101
102
        if (null === $this->object->getUid()) {
103
            $persistenceManager->add($this->object);
104
        } else {
105
            $persistenceManager->update($this->object);
106
        }
107
108
        $persistenceManager->persistAll();
109
    }
110
111
    /**
112
     * @return array
113
     */
114
    public function getMetadata()
115
    {
116
        return $this->metadata;
117
    }
118
119
    /**
120
     * @param FormMetadata $metadata
121
     */
122
    public function setObject(FormMetadata $metadata)
123
    {
124
        if (null !== $this->object) {
125
            throw new \Exception('todo'); // @todo
126
        }
127
128
        $this->object = $metadata;
129
    }
130
131
    /**
132
     * @return string
133
     */
134
    public function __toString()
135
    {
136
        return serialize(['metadata' => $this->metadata]);
137
    }
138
139
    /**
140
     * @see deepClone()
141
     */
142
    public function __clone()
143
    {
144
        $this->deepClone($this->metadata);
145
    }
146
147
    /**
148
     * When the metadata is fetched from persistence, the `metadata` array can
149
     * contain object instances, meaning that by default the original references
150
     * to these objects are used in the clean properties, resulting in the
151
     * object modification not being detected.
152
     *
153
     * In this function, we clone every object that is found, to solve the issue
154
     * above.
155
     *
156
     * @param mixed $entry
157
     * @param array $path
158
     */
159
    protected function deepClone($entry, array $path = [])
160
    {
161
        if (is_array($entry)) {
162
            foreach ($entry as $key => $item) {
163
                $path[] = $key;
164
                $this->deepClone($item, $path);
165
            }
166
        } elseif (is_object($entry)) {
167
            $this->set(implode('.', $path), clone $entry);
168
        }
169
    }
170
}
171