GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

FileController::unifiedAction()   F
last analyzed

Complexity

Conditions 19
Paths 54

Size

Total Lines 129

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 129
rs 3.6133
c 0
b 0
f 0
cc 19
nc 54
nop 2

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
namespace app\modules\data\controllers;
4
5
use app\modules\data\components\ExportableInterface;
6
use Yii;
7
use app\modules\data\models\Import;
8
use app\modules\data\models\Export;
9
use app\models\BaseObject;
10
use app\modules\data\models\ImportModel;
11
use app\backgroundtasks\helpers\BackgroundTasks;
12
use yii\base\ErrorException;
13
use yii\data\ActiveDataProvider;
14
use yii\filters\AccessControl;
15
use yii\helpers\ArrayHelper;
16
use yii\web\HttpException;
17
use yii\web\UploadedFile;
18
19
/**
20
 * Class FileController
21
 * @package app\modules\data\controllers
22
 */
23
class FileController  extends \app\backend\components\BackendController
24
{
25
    /**
26
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array<strin...g,boolean|string[]>[]>>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
27
     */
28 View Code Duplication
    public function behaviors()
29
    {
30
        return [
31
            'access' => [
32
                'class' => AccessControl::className(),
0 ignored issues
show
Deprecated Code introduced by
The method yii\base\BaseObject::className() has been deprecated with message: since 2.0.14. On PHP >=5.5, use `::class` instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
33
                'rules' => [
34
                    [
35
                        'allow' => true,
36
                        'roles' => ['data manage'],
37
                    ],
38
                ],
39
            ],
40
        ];
41
    }
42
43
    /**
44
     * @return string
45
     */
46
    public function actionIndex()
47
    {
48
        $objects = new ActiveDataProvider([
49
            'query' => BaseObject::find()->with(['lastExport', 'lastImport']),
50
            'pagination' => [
51
                'pageSize' => 10,
52
            ],
53
            'sort' => false,
54
        ]);
55
56
        return $this->render('index', ['objects' => $objects]);
57
    }
58
59
    /**
60
     * Unified action for import and export
61
     * @param $id
62
     * @param $importMode
63
     * @return string|\yii\web\Response
64
     * @throws ErrorException
65
     */
66
    private function unifiedAction($id, $importMode)
67
    {
68
        $object = BaseObject::findById($id);
69
        /* @var $className \app\modules\data\models\Import */
70
        $className =
71
            $importMode ?
72
            'app\modules\data\models\Import' :
73
            'app\modules\data\models\Export';
74
75
        if ($object !== null) {
76
            $model = new ImportModel(['object' => $id]);
77
78
            $fields = \app\modules\data\components\Import::getFields($model->object);
79
80
81
            if (\Yii::$app->request->isPost) {
82
                if (
83
                    $model->load(\Yii::$app->request->post()) && $model->validate()
84
                ) {
85
                    $import = $className::find()->where(
86
                        [
87
                            'user_id' => Yii::$app->user->id,
88
                            'object_id' => $id,
89
                        ]
90
                    )->one();
91
92
                    if ($import === null) {
93
                        $import = new $className(
94
                            [
95
                                'user_id' => Yii::$app->user->id,
96
                                'object_id' => $id,
97
                            ]
98
                        );
99
                    }
100
101
                    $import->filename = null;
102
                    if ($importMode === true) {
103
                        $file = UploadedFile::getInstance($model, 'file');
104
                        $model->type = $file->extension;
105
                        $filename = $model->getFilename('Import');
106
                        $import->filename = $filename;
107
                        $fullFilename =
108
                            Yii::$app->getModule('data')->importDir .
109
                            '/' .
110
                            $filename;
111
                        if ($file->saveAs($fullFilename) === false) {
112
                            throw new ErrorException("Unable to save file");
113
                        }
114
                    }
115
116
                    $import->status = $className::STATUS_PROCESS;
117
118
                    $task_options = Yii::$app->request->post('Task', []);
119
120
                    if ($import->save()) {
121
                        BackgroundTasks::addTask([
122
                            'name' =>
123
                                $importMode ? 'import' : 'export',
124
                            'description' =>
125
                                ($importMode ? 'import' : 'export') .
126
                                " {$model->object}",
127
                            'action' =>
128
                                'data/file/' .
129
                                ($importMode ? 'import' : 'export'),
130
                            'params' =>
131
                                $model->serialize(),
132
                            'init_event' =>
133
                                ($importMode ? 'import' : 'export'),
134
                        ],
135
                        [
136
                            'create_notification' => isset($task_options['create_notification']) && 1 == $task_options['create_notification'] ? true : false,
137
                        ]);
138
                        \Yii::$app->session->setFlash(
139
                            'info',
140
                            \Yii::t('app', 'Task is queued. Come back later.')
141
                        );
142
                    } else {
143
                        \Yii::$app->session->setFlash(
144
                            'error',
145
                            \Yii::t('app', 'Import Error')
146
                        );
147
                    }
148
149
150
151
                    return $this->redirect(['/data/file']);
152
                }
153
            }
154
155
            $availablePropertyGroups = [];
156
157
            /** @var \app\modules\shop\models\Product $exampleModel - product for example */
158
            $exampleModel = new $object->object_class;
159
            if ($exampleModel->hasMethod('getPropertyGroups')) {
160
                $availablePropertyGroups = $exampleModel->getPropertyGroups(
0 ignored issues
show
Documentation Bug introduced by
The method getPropertyGroups does not exist on object<app\modules\shop\models\Product>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
161
                        false,
162
                        true
163
                    );
164
            }
165
166
            \Yii::$app->session->setFlash(
167
                'info',
168
                \Yii::t('app', 'Specify fields to import and select the file')
169
            );
170
171
            $fields['additionalFields'] = [];
172
            if ($exampleModel instanceof ExportableInterface) {
173
                $fields['additionalFields'] = $exampleModel::exportableAdditionalFields();
174
            }
175
176
            if ($model->type === null) {
177
                $model->type = Yii::$app->modules['data']->defaultType;
178
            }
179
180
            return $this->render('import-export', [
181
                'model' => $model,
182
                'object' => $object,
183
                'fields' => $fields,
184
                'availablePropertyGroups' => $availablePropertyGroups,
185
                'importMode' => $importMode,
186
            ]);
187
        } else {
188
            \Yii::$app->session->setFlash(
189
                'error',
190
                \Yii::t('app', 'Object not found')
191
            );
192
            return $this->redirect(['/data/file']);
193
        }
194
    }
195
196
    /**
197
     * @param $id
198
     * @return string|\yii\web\Response
199
     * @throws ErrorException
200
     */
201
    public function actionImport($id)
202
    {
203
        return $this->unifiedAction($id, true);
204
    }
205
206
    /**
207
     * @param $id
208
     * @return string|\yii\web\Response
209
     * @throws ErrorException
210
     */
211
    public function actionExport($id)
212
    {
213
        return $this->unifiedAction($id, false);
214
    }
215
216
    /**
217
     * @param $dir
218
     * @param $file
219
     * @throws HttpException
220
     */
221
    public function actionDownloadFile($dir, $file)
222
    {
223
        $errors = [];
224
        switch ($dir) {
225
            case 'import':
226
                $filePath =  Yii::$app->getModule('data')->importDir.'/'.$file;;
227
                break;
228
            case 'export':
229
                $filePath =  Yii::$app->getModule('data')->exportDir.'/'.$file;;
230
                break;
231
            default :
232
                $filePath = false;
233
                break;
234
        }
235
236
        if (in_array($dir, ['import', 'export']) === false) {
237
            $errors[] = 'path not found';
238
        }
239
        if (!is_file($filePath)) {
240
            $errors[] = 'file not found';
241
        }
242
        if ($errors !== []) {
243
            throw new HttpException(403, implode(', ', $errors));
244
        }
245
246
        Yii::$app->response->sendFile($filePath, $file);
247
    }
248
}
249