Passed
Pull Request — master (#46)
by Paweł
02:52
created

AccountController::findOrCreateModel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Created for IG Monitoring.
4
 * User: jakim <[email protected]>
5
 * Date: 06.05.2018
6
 */
7
8
namespace app\modules\api\v1\controllers;
9
10
11
use app\models\Tag;
12
use app\modules\api\v1\components\ActiveController;
13
use app\modules\api\v1\models\Account;
14
use yii\helpers\ArrayHelper;
15
use yii\helpers\Inflector;
16
use yii\helpers\StringHelper;
17
use yii\helpers\Url;
18
use yii\web\ServerErrorHttpException;
19
20
class AccountController extends ActiveController
21
{
22
    public $modelClass = Account::class;
23
24
    public function actions()
25
    {
26
        $actions = parent::actions();
27
        unset($actions['create']);
28
29
        return $actions;
30
    }
31
32
    public function actionCreate()
33
    {
34
        $bodyParams = \Yii::$app->getRequest()->getBodyParams();
35
36
        $username = ArrayHelper::getValue($bodyParams, 'username');
37
        $tags = ArrayHelper::remove($bodyParams, 'tags', '');
38
39
        $account = $this->findOrCreateModel($username);
40
        $isNewRecord = $account->isNewRecord;
41
42
        $account->load($bodyParams, '');
43
        if ($account->save()) {
44
            $this->linkTags($tags, $account);
45
46
            $response = \Yii::$app->getResponse();
47
            $response->setStatusCode($isNewRecord ? 201 : 200);
48
49
            // TODO uncomment after create "view" endpoint
50
//            $id = implode(',', array_values($model->getPrimaryKey(true)));
51
//            $response->getHeaders()->set('Location', Url::toRoute(['view', 'id' => $id], true));
52
53
        } elseif (!$account->hasErrors()) {
54
            throw new ServerErrorHttpException('Failed to create the object for unknown reason.');
55
        }
56
57
        return $account;
58
    }
59
60
    protected function linkTags(string $tags, Account $account): void
61
    {
62
        $tags = StringHelper::explode($tags, ',', true, true);
63
        $tags = array_unique($tags);
64
65
        foreach ($tags as $name) {
66
            try {
67
                $tag = Tag::findOne(['slug' => Inflector::slug($name)]);
68
                if ($tag === null) {
69
                    $tag = new Tag();
70
                    $tag->name = $name;
71
                    $tag->insert();
72
                }
73
                $account->link('tags', $tag);
74
            } catch (\Throwable $exception) {
75
                \Yii::error(sprintf('API: account tag error: %s', $exception->getMessage()), __METHOD__);
76
                continue;
77
            }
78
        }
79
    }
80
81
    /**
82
     * @param $username
83
     * @return \app\modules\api\v1\models\Account|null
84
     */
85
    protected function findOrCreateModel($username)
86
    {
87
        $account = Account::findOne(['username' => $username]);
88
89
        if ($account === null) {
90
            $account = new Account();
91
            $account->setScenario($this->createScenario);
92
        }
93
94
        return $account;
95
    }
96
}