Completed
Push — master ( b2aa64...db9a1b )
by Alexey
05:01
created

Object   B

Complexity

Total Complexity 42

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 3
Bugs 2 Features 0
Metric Value
wmc 42
c 3
b 2
f 0
lcom 1
cbo 5
dl 0
loc 171
rs 8.295

3 Methods

Rating   Name   Duplication   Size   Complexity  
B parse() 0 18 5
C parseData() 0 58 14
D setModel() 0 83 23

How to fix   Complexity   

Complex Class

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
    public $data;
21
22
    public function parse($preset = [])
23
    {
24
        $ids = [];
25
        if (!\Tools::isAssoc($this->data)) {
26
            foreach ($this->data as &$data) {
27
                $id = $this->parseData($data, $preset);
28
                if ($id) {
29
                    $ids[] = $id;
30
                }
31
            }
32
        } else {
33
            $id = $this->parseData($this->data, $preset);
34
            if ($id) {
35
                $ids[] = $id;
36
            }
37
        }
38
        return $ids;
39
    }
40
41
    private function parseData($data, $preset)
42
    {
43
        $model = $this->setModel($data);
44
        if ($model) {
45
            foreach ($preset as $col => $value) {
46
                $model->{$col} = $value;
47
            }
48
49
            $walked = [];
50
            foreach ($this->object->params as $param) {
51
                if ($model && $param->type && $param->type != 'item_key') {
52
                    if ($param->type == 'object') {
53
                        $object = \Migrations\Migration\Object::get($param->value);
54
                        $parser = new \Migrations\Parser\Object;
55
                        $parser->data = &$data[$param->code];
56
                        $parser->object = $object;
57
                        $parser->parentObject = $this;
58
                        $parser->parentModel = $model;
59
                        $parser->walker = $this->walker;
0 ignored issues
show
Bug introduced by
The property walker does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
60
                        $parser->parse();
61
                    } else {
62
                        if ($param->type == 'custom') {
63
                            $parserName = $param->value;
64
                        } else {
65
                            $parserName = '\Migrations\Parser\Object\\' . ucfirst($param->type);
66
                        }
67
                        if (!in_array($parserName, ['\Migrations\Parser\Object\ObjectLink','Exchange1c\Parser\Item\Images', '\Migrations\Parser\Object\Value', '\Migrations\Parser\Object\Relation', '\Migrations\Parser\Object\ParamsList'])) {
68
                            var_dump($parserName);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($parserName); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
69
                            exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method parseData() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
70
                        }
71
                        $parser = new $parserName;
72
                        $parser->data = &$data[$param->code];
73
                        $parser->param = $param;
74
                        $parser->model = $model;
75
                        $parser->object = $this;
76
                        $parser->parse();
77
                    }
78
                }
79
                $walked[$param->code] = true;
80
            }
81
            //check unparsed params
82
            foreach ($data as $key => $item) {
83
                //skip parsed and attribtes
84
                if ($key == '@attributes' || !empty($walked[$key])) {
85
                    continue;
86
                }
87
                $param = new \Migrations\Migration\Object\Param();
88
                $param->object_id = $this->object->id;
89
                $param->code = $key;
90
                $param->save();
91
            }
92
            if ($model) {
93
                $model->save();
94
                return $model->pk();
95
            }
96
        }
97
        return 0;
98
    }
99
100
    private function setModel($data)
101
    {
102
        $model = null;
103
        $keyCol = null;
104
        $uniques = [];
105
        foreach ($this->object->params as $param) {
106
            $options = $param->options ? json_decode($param->options, true) : [];
107
            if ($param->type == 'item_key') {
108
                $keyCol = $param->code;
109
                break;
110
            } elseif (!empty($options['unique'])) {
111
                $uniques[$param->code] = $param;
112
            }
113
        }
114
        if ($keyCol && isset($data[$keyCol])) {
115
            $objectId = \Migrations\Id::get([['parse_id', (string) $data[$keyCol]], ['type', $this->object->model]]);
116
            if ($objectId) {
117
                $modelName = $this->object->model;
118
                $model = $modelName::get($objectId->object_id);
119
            } else {
120
                $model = new $this->object->model;
121
                $model->save(['empty' => true]);
122
                $objectId = new \Migrations\Id();
123
                $objectId->object_id = $model->id;
124
                $objectId->parse_id = (string) $data[$keyCol];
125
                $objectId->type = $this->object->model;
126
                $objectId->save();
127
            }
128
        } elseif ($uniques) {
129
            $where = [];
130
            foreach ($uniques as $code => $param) {
131
                if (!isset($data[$code])) {
132
                    return;
133
                }
134
                switch ($param->type) {
135
                    case 'objectLink':
136
                        $object = \Migrations\Migration\Object::get($param->value);
137
                        $objectId = \Migrations\Id::get([['parse_id', (string) $data[$code]], ['type', $object->model]]);
138
                        if (!$objectId) {
139
                            return;
140
                        }
141
                        $modelName = $object->model;
142
                        $model = $modelName::get($objectId->object_id);
143
                        $where[] = [$model->index(), $model->pk()];
144
                        break;
145
                    case 'relation':
146
                        $modelName = $this->object->model;
147
                        $relation = $modelName::getRelation($param->value);
148
                        $objectId = \Migrations\Id::get([['parse_id', (string) $data[$code]], ['type', $relation['model']]]);
149
                        if (!$objectId) {
150
                            return;
151
                        }
152
                        $modelName = $relation['model'];
153
                        $model = $modelName::get($objectId->object_id);
154
                        $where[] = [$relation['col'], $model->pk()];
155
                        break;
156
                }
157
            }
158
            if ($where) {
159
                if ($this->parentParam) {
160
                    $modelName = $this->parentObject->object->model;
161
                    $relation = $modelName::getRelation($this->parentParam->param->value);
162
                    if (!empty($relation['type']) && $relation['type'] == 'many') {
163
                        $where[] = [$relation['col'], $this->parentModel->pk()];
164
                    }
165
                } elseif ($this->parentObject) {
166
                    $modelName = $this->parentObject->object->model;
167
                    $where[] = [$modelName::index(), $this->parentModel->pk()];
168
                }
169
            }
170
            if ($where) {
171
                $modelName = $this->object->model;
172
                $model = $modelName::get($where);
173
                if (!$model) {
174
                    $model = new $this->object->model;
175
                    foreach ($where as $item) {
176
                        $model->{$item[0]} = $item[1];
177
                    }
178
                }
179
            }
180
        }
181
        return $model;
182
    }
183
184
}
185