Passed
Push — master ( 622e79...efafc0 )
by Andreas
03:31
created

dbobject::populate_from_entity()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 2
b 0
f 0
nc 2
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 2
rs 10
1
<?php
2
/**
3
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
4
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
6
 */
7
namespace midgard\portable\api;
8
9
use midgard\portable\storage\connection;
10
use Doctrine\Persistence\ObjectManagerAware;
11
use Doctrine\Persistence\ObjectManager;
12
use Doctrine\Persistence\Mapping\ClassMetadata;
13
use midgard_datetime;
14
15
abstract class dbobject implements ObjectManagerAware
16
{
17
    protected $guid = '';
18
19
    /**
20
     *
21
     * @var ClassMetadata
22
     */
23
    protected $cm;
24
25
    /**
26
     * Simple map of association fields changed during the object's lifetime
27
     *
28
     * We need this for some workarounds for proxy-related problems during changeset calculation
29
     *
30
     * @var array
31
     */
32
    protected $changed_associations = [];
33
34
    /**
35
     * {@inheritDoc}
36
     */
37 82
    public function injectObjectManager(ObjectManager $objectmanager, ClassMetadata $classmetadata)
38
    {
39 82
        if ($objectmanager !== connection::get_em()) {
0 ignored issues
show
introduced by
The condition $objectmanager !== midga...ge\connection::get_em() is always true.
Loading history...
40
            throw new \RuntimeException("Trying to use midgard_dbobject with different ObjectManager instances");
41
        }
42
43 82
        $this->cm = $classmetadata;
44 82
    }
45
46
    /**
47
     * @return array
48
     */
49 27
    public function __get_changed_associations()
50
    {
51 27
        return $this->changed_associations;
52
    }
53
54
    /**
55
     * Filter out internal stuff for var_dump
56
     *
57
     * This is not 100% accurate right now (e.g. metadata is not handled totally correctly), but at least it
58
     * prevents killing the server by dumping recursively linked EntityManagers and the like
59
     *
60
     * @return array
61
     */
62 1
    public function __debugInfo()
63
    {
64 1
        $this->initialize();
65 1
        $properties = array_merge($this->cm->getFieldNames(), $this->cm->getAssociationNames(), array_keys($this->cm->midgard['field_aliases']));
66
        $properties = array_filter($properties, function ($input) {
67 1
            return strpos($input, 'metadata_') === false;
68 1
        });
69 1
        $ret = [];
70 1
        foreach ($properties as $property) {
71 1
            $ret[$property] = $this->__get($property);
72
        }
73
74 1
        return $ret;
75
    }
76
77 125
    public function __set($field, $value)
78
    {
79 125
        $this->initialize();
80
81 125
        if (   !$this->cm->hasField($field)
82 125
            && isset($this->cm->midgard['field_aliases'][$field])) {
83
            $field = $this->cm->midgard['field_aliases'][$field];
84
        }
85 125
        if ($this->cm->isSingleValuedAssociation($field)) {
86
            // mgd api only allows setting links identifiers, doctrine wants objects,
87
            // so it seems we need an expensive and pretty useless conversion..
88 57
            if (empty($value)) {
89 37
                $value = null;
90
            } else {
91 36
                if (   !\is_object($this->$field)
92 36
                    || $this->$field->id != $value) {
93 36
                    $this->changed_associations[$field] = true;
94
                }
95 36
                $classname = $this->cm->getAssociationTargetClass($field);
96 57
                $value = connection::get_em()->getReference($classname, $value);
97
            }
98 125
        } elseif ($this->cm->hasField($field)) {
99 124
            $mapping = $this->cm->getFieldMapping($field);
100
101 124
            if (   $mapping['type'] === 'string'
102 124
                || $mapping['type'] == 'text') {
103 123
                $value = (string) $value;
104 119
            } elseif ($mapping['type'] === 'integer') {
105 119
                $value = (int) $value;
106 100
            } elseif ($mapping['type'] === 'boolean') {
107 41
                $value = (boolean) $value;
108 100
            } elseif ($mapping['type'] === 'float') {
109 8
                $value = (float) $value;
110 100
            } elseif ($mapping['type'] === 'midgard_datetime') {
111 100
                if (   \is_string($value)
112 100
                    && $value !== '0000-00-00 00:00:00') {
113 7
                    $value = new midgard_datetime($value);
114 99
                } elseif (!($value instanceof midgard_datetime)) {
115 1
                    $value = new midgard_datetime('0001-01-01 00:00:00');
116
                }
117
            }
118
        }
119
120 125
        $this->$field = $value;
121 125
    }
122
123 136
    public function __get($field)
124
    {
125 136
        $this->initialize();
126
127 136
        if (   !$this->cm->hasField($field)
128 136
            && isset($this->cm->midgard['field_aliases'][$field])) {
129
            $field = $this->cm->midgard['field_aliases'][$field];
130
        }
131
132 136
        if ($this->cm->isSingleValuedAssociation($field)) {
133
            // mgd api only allows returning link identifiers, doctrine has objects,
134
            // so it seems we need a pretty useless conversion..
135 108
            if (is_object($this->$field)) {
136 36
                return (int) $this->$field->id;
137
            }
138 108
            return 0;
139
        }
140 135
        if (   $this->$field === null
141 135
            && $this->cm->isIdentifier($field)) {
142 102
            return 0;
143
        }
144 133
        if (   $this->$field instanceof midgard_datetime
145 133
            && $this->$field->format('U') == -62169984000) {
146
            //This is mainly needed for working with converted Legacy databases. Midgard2 somehow handles this internally
147
            //@todo Find a nicer solution and research how QB handles this
148 1
            $this->$field->setDate(1, 1, 1);
149
        }
150
151 133
        return $this->$field;
152
    }
153
154 122
    public function __isset($field)
155
    {
156 122
        return property_exists($this, $field);
157
    }
158
159 54
    protected function populate_from_entity(dbobject $entity)
160
    {
161 54
        $this->initialize();
162 54
        foreach ($this->cm->reflFields as $name => $field) {
163 54
            $this->$name = $entity->$name;
164
        }
165 54
    }
166
167 140
    protected function initialize()
168
    {
169 140
        if ($this->cm === null) {
170 136
            $this->cm = connection::get_em()->getClassMetadata(get_class($this));
171
        }
172 140
    }
173
}
174