Passed
Push — master ( 9d605b...f6d124 )
by Andreas
02:52
created

dbobject   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 149
Duplicated Lines 0 %

Test Coverage

Coverage 95.77%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 67
dl 0
loc 149
ccs 68
cts 71
cp 0.9577
rs 9.6
c 1
b 0
f 0
wmc 35

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __debugInfo() 0 13 2
A __get_changed_associations() 0 3 1
A __isset() 0 3 1
B __get() 0 29 9
C __set() 0 44 17
A populate_from_entity() 0 5 2
A injectObjectManager() 0 7 2
A initialize() 0 3 1
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 string $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
    protected array $changed_associations = [];
29
30
    /**
31
     * {@inheritDoc}
32
     */
33 81
    public function injectObjectManager(ObjectManager $objectmanager, ClassMetadata $classmetadata)
34
    {
35 81
        if ($objectmanager !== connection::get_em()) {
0 ignored issues
show
introduced by
The condition $objectmanager !== midga...ge\connection::get_em() is always true.
Loading history...
36
            throw new \RuntimeException("Trying to use midgard_dbobject with different ObjectManager instances");
37
        }
38
39 81
        $this->cm = $classmetadata;
40
    }
41
42 26
    public function __get_changed_associations() : array
43
    {
44 26
        return $this->changed_associations;
45
    }
46
47
    /**
48
     * Filter out internal stuff for var_dump
49
     *
50
     * This is not 100% accurate right now (e.g. metadata is not handled totally correctly), but at least it
51
     * prevents killing the server by dumping recursively linked EntityManagers and the like
52
     *
53
     * @return array
54
     */
55 1
    public function __debugInfo()
56
    {
57 1
        $this->initialize();
58 1
        $properties = array_merge($this->cm->getFieldNames(), $this->cm->getAssociationNames(), array_keys($this->cm->midgard['field_aliases']));
59 1
        $properties = array_filter($properties, function ($input) {
60 1
            return strpos($input, 'metadata_') === false;
61 1
        });
62 1
        $ret = [];
63 1
        foreach ($properties as $property) {
64 1
            $ret[$property] = $this->__get($property);
65
        }
66
67 1
        return $ret;
68
    }
69
70 124
    public function __set($field, $value)
71
    {
72 124
        $this->initialize();
73
74 124
        if (   !$this->cm->hasField($field)
75 124
            && isset($this->cm->midgard['field_aliases'][$field])) {
76
            $field = $this->cm->midgard['field_aliases'][$field];
77
        }
78 124
        if ($this->cm->isSingleValuedAssociation($field)) {
79
            // mgd api only allows setting links identifiers, doctrine wants objects,
80
            // so it seems we need an expensive and pretty useless conversion..
81 56
            if (empty($value)) {
82 36
                $value = null;
83
            } else {
84 36
                if (   !\is_object($this->$field)
85 36
                    || $this->$field->id != $value) {
86 36
                    $this->changed_associations[$field] = true;
87
                }
88 36
                $classname = $this->cm->getAssociationTargetClass($field);
89 56
                $value = connection::get_em()->getReference($classname, $value);
90
            }
91 124
        } elseif ($this->cm->hasField($field)) {
92 123
            $mapping = $this->cm->getFieldMapping($field);
93
94 123
            if (   $mapping['type'] === 'string'
95 123
                || $mapping['type'] == 'text') {
96 122
                $value = (string) $value;
97 118
            } elseif ($mapping['type'] === 'integer') {
98 118
                $value = (int) $value;
99 99
            } elseif ($mapping['type'] === 'boolean') {
100 40
                $value = (boolean) $value;
101 99
            } elseif ($mapping['type'] === 'float') {
102 8
                $value = (float) $value;
103 99
            } elseif ($mapping['type'] === 'datetime') {
104 99
                if (   \is_string($value)
105 99
                    && $value !== '0000-00-00 00:00:00') {
106 7
                    $value = new midgard_datetime($value);
107 98
                } elseif (!($value instanceof midgard_datetime)) {
108 1
                    $value = new midgard_datetime('0001-01-01 00:00:00');
109
                }
110
            }
111
        }
112
113 124
        $this->$field = $value;
114
    }
115
116 135
    public function __get($field)
117
    {
118 135
        $this->initialize();
119
120 135
        if (   !$this->cm->hasField($field)
121 135
            && isset($this->cm->midgard['field_aliases'][$field])) {
122
            $field = $this->cm->midgard['field_aliases'][$field];
123
        }
124
125 135
        if ($this->cm->isSingleValuedAssociation($field)) {
126
            // mgd api only allows returning link identifiers, doctrine has objects,
127
            // so it seems we need a pretty useless conversion..
128 107
            if (is_object($this->$field)) {
129 36
                return (int) $this->$field->id;
130
            }
131 107
            return 0;
132
        }
133 134
        if (   $this->$field === null
134 134
            && $this->cm->isIdentifier($field)) {
135 101
            return 0;
136
        }
137 132
        if (   $this->$field instanceof midgard_datetime
138 132
            && $this->$field->format('U') == -62169984000) {
139
            //This is mainly needed for working with converted Legacy databases. Midgard2 somehow handles this internally
140
            //@todo Find a nicer solution and research how QB handles this
141 1
            $this->$field->setDate(1, 1, 1);
142
        }
143
144 132
        return $this->$field;
145
    }
146
147 121
    public function __isset($field)
148
    {
149 121
        return property_exists($this, $field);
150
    }
151
152 53
    protected function populate_from_entity(dbobject $entity)
153
    {
154 53
        $this->initialize();
155 53
        foreach ($this->cm->reflFields as $name => $field) {
156 53
            $this->$name = $entity->$name;
157
        }
158
    }
159
160 139
    protected function initialize()
161
    {
162 139
        $this->cm ??= connection::get_em()->getClassMetadata(get_class($this));
163
    }
164
}
165