Passed
Branch master (b2f909)
by Andreas
04:01
created

dbobject::__get()   B

Complexity

Conditions 9
Paths 10

Size

Total Lines 29
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 9.0197

Importance

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