Test Failed
Push — master ( 2a8a67...5ddd1f )
by Alexey
04:25
created

Object   C

Complexity

Total Complexity 59

Size/Duplication

Total Lines 208
Duplicated Lines 12.02 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 25
loc 208
rs 6.1904
c 0
b 0
f 0
wmc 59
lcom 1
cbo 6

3 Methods

Rating   Name   Duplication   Size   Complexity  
B parse() 0 17 6
D parseData() 12 84 25
D setModel() 13 92 28

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Object often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Object, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Pareser object
5
 *
6
 * @author Alexey Krupskiy <[email protected]>
7
 * @link http://inji.ru/
8
 * @copyright 2015 Alexey Krupskiy
9
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
10
 */
11
12
namespace Migrations\Parser;
13
14
class Object extends \Object {
15
16
    public $object;
17
    public $parentObject;
18
    public $parentModel;
19
    public $parentParam;
20
    /**
21
     * @var \Migrations\Walker
22
     */
23
    public $walker;
24
    public $data;
25
26
    public function parse($preset = []) {
27
        $ids = [];
28
        if (is_array($this->data) && !\Tools::isAssoc($this->data)) {
29
            foreach ($this->data as &$data) {
30
                $id = $this->parseData($data, $preset);
31
                if ($id) {
32
                    $ids[] = $id;
33
                }
34
            }
35
        } else {
36
            $id = $this->parseData($this->data, $preset);
37
            if ($id) {
38
                $ids[] = $id;
39
            }
40
        }
41
        return $ids;
42
    }
43
44
    private function parseData($data, $preset) {
45
        $model = $this->setModel($data);
46
        if ($model) {
47
            foreach ($preset as $col => $value) {
48
                $model->{$col} = $value;
49
            }
50
            if (defined('mdebug')) {
51
                echo " -> objectStart ({$this->object->id}) ";
52
            }
53
            $walked = [];
54
            foreach ($this->object->params as $param) {
55
                if (defined('mdebug')) {
56
                    echo " -> param ($param->id,$param->type,$param->value) ";
57
                }
58
                if ($model && $param->type && $param->type != 'item_key') {
59
                    if ($param->type == 'object') {
60
                        $object = \App::$cur->migrations->getMigrationObject($this->walker->migration, $param->value);
61
                        $parser = new \Migrations\Parser\Object;
62
                        $parser->data = &$data[$param->code];
63
                        $parser->object = $object;
64
                        $parser->parentObject = $this;
65
                        $parser->parentModel = $model;
66
                        $parser->walker = $this->walker;
67
                        if (defined('mdebug')) {
68
                            echo " -> objectParse ";
69
                        }
70
                        $parser->parse();
71
                    } else {
72
                        if ($param->type == 'custom') {
73
                            $parserName = $param->value;
74
                        } else {
75
                            $parserName = '\Migrations\Parser\Object\\' . ucfirst($param->type);
76
                        }
77
                        $parser = new $parserName;
78
                        $parser->data = &$data[$param->code];
79
                        $parser->param = $param;
80
                        $parser->model = $model;
81
                        $parser->walker = $this->walker;
82
                        $parser->object = $this;
83
                        if (defined('mdebug')) {
84
                            echo " -> parser ($parserName) ";
85
                        }
86
                        $parser->parse();
87
                    }
88
                }
89
                if (defined('mdebug')) {
90
                    echo " -> paramEnd ($param->id,$param->type,$param->value) ";
91
                }
92
                $walked[$param->code] = true;
93
            }
94
95
            //check unparsed params
96 View Code Duplication
            foreach ($data as $key => $item) {
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...
97
                //skip parsed and attribtes
98
                if ($key == '@attributes' || !empty($walked[$key])) {
99
                    continue;
100
                }
101
                $param = new \Migrations\Migration\Object\Param();
102
                $param->object_id = $this->object->id;
103
                $param->code = $key;
104
                $param->save();
105
                $className = get_class($this->object);
106
                $this->object = $className::get($this->object->id);
107
            }
108
            if ($model) {
109
                if ($this->object->delete_empty && @json_decode($this->object->delete_empty, true)) {
110
                    $deleteIf = json_decode($this->object->delete_empty, true);
111
                    foreach ($deleteIf['params'] as $paramId) {
112
                        if ($model->{$this->object->params[$paramId]->value} === '') {
113
                            if ($model->pk()) {
114
                                $model->delete();
115
                            }
116
                            return 0;
117
                        }
118
                    }
119
                }
120
                if (!$model->pk() || !empty($model->_changedParams)) {
121
                    $model->save();
122
                }
123
                return $model->pk();
124
            }
125
        }
126
        return 0;
127
    }
128
129
    public function setModel($data) {
130
        $model = null;
131
        $keyCol = null;
132
        $uniques = [];
133
        foreach ($this->object->params as $param) {
134
            $options = $param->options ? json_decode($param->options, true) : [];
135
            if ($param->type == 'item_key') {
136
                $keyCol = $param->code;
137
                break;
138
            } elseif (!empty($options['unique'])) {
139
                $uniques[$param->code] = $param;
140
            }
141
        }
142
        if ($keyCol && isset($data[$keyCol])) {
143
            $objectId = \App::$cur->migrations->findObject((string) $data[$keyCol], $this->object->model);
144
            if ($objectId) {
145
                $modelName = $this->object->model;
146
                $model = $modelName::get($objectId->object_id);
147
            } else {
148
                $model = new $this->object->model;
149
                $model->save(['empty' => true]);
150
                $objectId = new \Migrations\Id();
151
                $objectId->object_id = $model->id;
152
                $objectId->parse_id = (string) $data[$keyCol];
153
                $objectId->type = $this->object->model;
154
                $objectId->save();
155
                \App::$cur->migrations->ids['objectIds'][$this->object->model][$model->id] = $objectId;
156
                \App::$cur->migrations->ids['parseIds'][$this->object->model][(string) $data[$keyCol]] = $objectId;
157
            }
158
        } elseif ($uniques) {
159
            $where = [];
160
            foreach ($uniques as $code => $param) {
161
                if (!isset($data[$code])) {
162
                    return;
163
                }
164
                switch ($param->type) {
165
                    case 'objectLink':
166
                        $object = \App::$cur->migrations->getMigrationObject($this->walker->migration, $param->value);
167
                        $objectId = \App::$cur->migrations->findObject((string) $data[$code], $object->model);
168
                        if (!$objectId) {
169
                            return;
170
                        }
171
                        $modelName = $object->model;
172
                        $where[] = [$modelName::index(), $objectId->object_id];
173
                        break;
174
                    case 'relation':
175
                        $modelName = $this->object->model;
176
                        $relation = $modelName::getRelation($param->value);
177
                        $objectId = \App::$cur->migrations->findObject((string) $data[$code], $relation['model']);
178
                        if (!$objectId) {
179
                            return;
180
                        }
181
                        $where[] = [$relation['col'], $objectId->object_id];
182
                        break;
183
                }
184
            }
185
            if ($where) {
186
                if ($this->parentParam) {
187
                    $modelName = $this->parentObject->object->model;
188
                    $relation = $modelName::getRelation($this->parentParam->param->value);
189
                    if (!empty($relation['type']) && $relation['type'] == 'many' && count($where) == 1) {
190
                        $relationName = $this->parentParam->param->value;
191
                        if (!empty($this->parentModel->$relationName(['key' => $where[0][0]])[$where[0][1]])) {
192
                            return $this->parentModel->$relationName(['key' => $where[0][0]])[$where[0][1]];
193 View Code Duplication
                        } else {
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...
194
                            $model = new $this->object->model;
195
                            foreach ($where as $item) {
196
                                $model->{$item[0]} = $item[1];
197
                            }
198
                            return $model;
199
                        }
200
                    } elseif (!empty($relation['type']) && $relation['type'] == 'many') {
201
                        $where[] = [$relation['col'], $this->parentModel->pk()];
202
                    }
203
                } elseif ($this->parentObject) {
204
                    $modelName = $this->parentObject->object->model;
205
                    $where[] = [$modelName::index(), $this->parentModel->pk()];
206
                }
207
            }
208
            if ($where) {
209
                $modelName = $this->object->model;
210
                $model = $modelName::get($where);
211 View Code Duplication
                if (!$model) {
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...
212
                    $model = new $this->object->model;
213
                    foreach ($where as $item) {
214
                        $model->{$item[0]} = $item[1];
215
                    }
216
                }
217
            }
218
        }
219
        return $model;
220
    }
221
}