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

Object::setModel()   D

Complexity

Conditions 23
Paths 147

Size

Total Lines 83
Code Lines 66

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 83
rs 4.5607
cc 23
eloc 66
nc 147
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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