Completed
Push — master ( 1af4f5...caaac4 )
by Andreas
03:43
created

dbobject   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 159
Duplicated Lines 6.29 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 94.25%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 10
loc 159
ccs 82
cts 87
cp 0.9425
rs 8.8
c 1
b 0
f 0
wmc 36
lcom 1
cbo 4

8 Methods

Rating   Name   Duplication   Size   Complexity  
A injectObjectManager() 0 8 2
A __get_changed_associations() 0 4 1
A __debugInfo() 0 14 2
D __set() 5 45 17
D __get() 5 30 9
A __isset() 0 4 1
A populate_from_entity() 0 7 2
A initialize() 0 6 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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\Common\Persistence\ObjectManagerAware;
11
use Doctrine\Common\Persistence\ObjectManager;
12
use Doctrine\Common\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 = array();
33
34
    /**
35
     * {@inheritDoc}
36
     */
37 77
    public function injectObjectManager(ObjectManager $objectmanager, ClassMetadata $classmetadata)
38
    {
39 77
        if ($objectmanager !== connection::get_em()) {
40
            throw new \RuntimeException("Trying to use midgard_dbobject with different ObjectManager instances");
41
        }
42
43 77
        $this->cm = $classmetadata;
44 77
    }
45
46
    /**
47
     * @return array
48
     */
49 26
    public function __get_changed_associations()
50
    {
51 26
        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']));
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
66 1
        $properties = array_filter($properties, function ($input) {
67 1
            return (strpos($input, 'metadata_') === false);
68 1
        });
69 1
        $ret = array();
70 1
        foreach ($properties as $property) {
71 1
            $ret[$property] = $this->__get($property);
72 1
        }
73
74 1
        return $ret;
75
    }
76
77 111
    public function __set($field, $value)
78
    {
79 111
        $this->initialize();
80
81 111 View Code Duplication
        if (   !$this->cm->hasField($field)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
82 111
            && array_key_exists($field, $this->cm->midgard['field_aliases'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
83
            $field = $this->cm->midgard['field_aliases'][$field];
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
84
        }
85 111
        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 52
            if (empty($value)) {
89 35
                $value = null;
90 35
            } else {
91 31
                if (   !is_object($this->$field)
92 31
                    || $this->$field->id != $value) {
93 31
                    $this->changed_associations[$field] = true;
94 31
                }
95 31
                $classname = $this->cm->getAssociationTargetClass($field);
96 31
                $value = connection::get_em()->getReference($classname, $value);
97
            }
98 111
        } elseif ($this->cm->hasField($field)) {
99 110
            $mapping = $this->cm->getFieldMapping($field);
100
101 110
            if (   $mapping['type'] === 'string'
102 110
                || $mapping['type'] == 'text') {
103 109
                $value = (string) $value;
104 110
            } elseif ($mapping['type'] === 'integer') {
105 105
                $value = (int) $value;
106 105
            } elseif ($mapping['type'] === 'boolean') {
107 40
                $value = (boolean) $value;
108 95
            } elseif ($mapping['type'] === 'float') {
109 8
                $value = (float) $value;
110 95
            } elseif ($mapping['type'] === 'midgard_datetime') {
111 95
                if (   is_string($value)
112 95
                    && $value !== '0000-00-00 00:00:00') {
113 7
                    $value = new midgard_datetime($value);
114 95
                } elseif (!($value instanceof midgard_datetime)) {
115 1
                    $value = new midgard_datetime('0001-01-01 00:00:00');
116 1
                }
117 95
            }
118 110
        }
119
120 111
        $this->$field = $value;
121 111
    }
122
123 120
    public function __get($field)
124
    {
125 120
        $this->initialize();
126
127 120 View Code Duplication
        if (   !$this->cm->hasField($field)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
128 120
            && array_key_exists($field, $this->cm->midgard['field_aliases'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
129
            $field = $this->cm->midgard['field_aliases'][$field];
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
130
        }
131
132 120
        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 94
            if (is_object($this->$field)) {
136 31
                return (int) $this->$field->id;
137
            }
138 94
            return 0;
139
        }
140 119
        if (   $this->$field === null
141 119
            && $this->cm->isIdentifier($field)) {
142 97
            return 0;
143
        }
144 117
        if (   $this->$field instanceof midgard_datetime
145 117
            && $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 1
        }
150
151 117
        return $this->$field;
152
    }
153
154 107
    public function __isset($field)
155
    {
156 107
        return property_exists($this, $field);
157
    }
158
159 50
    protected function populate_from_entity(dbobject $entity)
160
    {
161 50
        $this->initialize();
162 50
        foreach ($this->cm->reflFields as $name => $field) {
0 ignored issues
show
Bug introduced by
Accessing reflFields on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
163 50
            $this->$name = $entity->$name;
164 50
        }
165 50
    }
166
167 124
    protected function initialize()
168
    {
169 124
        if ($this->cm === null) {
170 120
            $this->cm = connection::get_em()->getClassMetadata(get_class($this));
171 120
        }
172 124
    }
173
}
174