Passed
Push — master ( 662d52...2a8232 )
by eXeCUT
03:58
created

components/Importer.php (1 issue)

Severity
1
<?php
2
namespace execut\import\components;
3
use execut\import\models\File;
4
use execut\import\models\Log;
5
use yii\base\Component;
6
use yii\db\ActiveQuery;
7
use yii\db\ActiveRecord;
8
use yii\helpers\ArrayHelper;
9
use yii\log\Logger;
10
11
use execut\import\components\parser\exception\Exception;
12
use execut\import\components\parser\Stack;
13
14
class Importer extends Component {
15
    /**
16
     * @var File
17
     */
18
    public $file = null;
19
20
    public $settings = null;
21
    public $checkedFileStatusRows = 1000;
22
    protected $badRows = [];
23
    public $data = [];
24
    public $currentPart = 0;
25
    public $stackSize = 2000;
26
    protected $extractors = null;
27
    public function isBadRow($rowNbr) {
28
        $currentRowNbr = $this->getCurrentStackRowNbr() + $rowNbr;
29
30
        return !empty($this->badRows['_' . $currentRowNbr]);
31
    }
32
33
    public function setIsBadRow($rowNbr) {
34
        $currentRowNbr = $this->getCurrentStackRowNbr() + $rowNbr;
35
36
        echo $currentRowNbr . ' (' . $rowNbr . ') marked is bad ' . "\n";
37
38
        $this->badRows['_' . $currentRowNbr] = true;
39
        return $this;
40
    }
41
42
    public function logError($message, $rowNbr, $model, $columnNbr = null) {
43
        $currentRowNbr = $this->getCurrentStackRowNbr() + $rowNbr;
44
        $attributes = [
45
            'level' => Logger::LEVEL_ERROR,
46
            'category' => 'import.fatalError',
47
            'row_nbr' => $rowNbr,
48
            'column_nbr' => $columnNbr,
49
            'message' => $message,
50
        ];
51
52
        $this->file->logError($attributes);
53
        if ($model instanceof ActiveRecord) {
54
            $modelInfo = get_class($model) . ' #' . $model->primaryKey;
55
        } else {
56
            if (is_string($model)) {
57
                $modelInfo = $model;
58
            } else {
59
                $modelInfo = '';
60
            }
61
        }
62
63
        echo 'Row #' . $currentRowNbr . ': ' . $message . ' ' . $modelInfo . ' ' . var_export($this->data[$currentRowNbr], true) . "\n";
64
    }
65
66
    public function getRows() {
67
        $dataParts = $this->getRowsStacks();
68
69
        return $dataParts[$this->currentPart];
70
    }
71
72
    public function getStacksCount() {
73
        return count($this->getRowsStacks());
74
    }
75
76
    public function run() {
77
        $this->file->triggerLoading();
78
        $extractors = $this->getExtractors();
79
        for ($key = 0; $key < $this->getStacksCount(); $key++) {
80
            $this->currentPart = $key;
81
            foreach ($extractors as $extractor) {
82
                $extractor->reset();
83
            }
84
85
            foreach ($extractors as $extractor) {
86
                if ($extractor->isImport) {
87
                    $models = $extractor->getModels();
0 ignored issues
show
The assignment to $models is dead and can be removed.
Loading history...
88
                }
89
            }
90
91
            $this->file->rows_errors = count($this->badRows);
92
            $this->file->rows_success = ($this->getCurrentStackRowNbr()) + count($this->getRows()) - $this->file->rows_errors + 1;
93
            $this->file->save(false, ['rows_errors', 'rows_success']);
94
            if ($this->file->isStop()) {
95
                $this->file->triggerStop();
96
                return;
97
            }
98
        }
99
100
        foreach ($extractors as $extractor) {
101
            $extractor->deleteOldRecords();
102
        }
103
104
        $this->file->triggerLoaded();
105
    }
106
107
    /**
108
     * @return ModelsExtractor
109
     */
110
    public function getExtractor($id)
111
    {
112
        if ($this->hasExtractor($id)) {
113
            return $this->getExtractors()[$id];
114
        }
115
    }
116
117
    public function hasExtractor($id) {
118
        $extractors = $this->getExtractors();
119
        if (!empty($extractors[$id])) {
120
            return true;
121
        }
122
    }
123
124
    /**
125
     * @return ModelsExtractor[]
126
     */
127
    public function getExtractors()
128
    {
129
        if ($this->extractors !== null) {
130
            return $this->extractors;
131
        }
132
133
        $attributes = $this->settings;
134
135
        $extractors = [];
136
        foreach ($attributes as $extractorId => $params) {
137
            $params['id'] = $extractorId;
138
            $params['importer'] = $this;
139
            if (!empty($params['attributes']['id'])) {
140
                $params['attributes'] = [
141
                    'id' => [
142
                        'isFind' => true,
143
                        'value' => (int) $params['attributes']['id'],
144
                    ],
145
                ];
146
            }
147
148
            $extractor = new ModelsExtractor($params);
149
            if ($extractor->isDelete) {
150
                $extractor->deletedIds = $this->getDeletedIds();
151
            }
152
153
            $extractors[$extractorId] = $extractor;
154
        }
155
156
        return $this->extractors = $extractors;
157
    }
158
159
    public function getDeletedIds() {
160
        $ids = \yii::$app->getModule('import')->getOldIdsByFile($this->file);
161
        $result = [];
162
        foreach ($ids as $id) {
163
            $result[$id] = $id;
164
        }
165
166
        return $result;
167
    }
168
169
    /**
170
     * @return int
171
     */
172
    public function getCurrentStackRowNbr(): int
173
    {
174
        return $this->currentPart * $this->stackSize;
175
    }
176
177
    /**
178
     * @return array
179
     */
180
    protected function getRowsStacks()
181
    {
182
        $dataParts = array_chunk($this->data, $this->stackSize);
183
        return $dataParts;
184
    }
185
}