DeleteRelationshipAction   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 28
c 1
b 0
f 0
dl 0
loc 73
rs 10
wmc 12

2 Methods

Rating   Name   Duplication   Size   Complexity  
B unlinkRelationships() 0 27 8
A run() 0 22 4
1
<?php
2
/**
3
 * @author Anton Tuyakhov <[email protected]>
4
 */
5
6
namespace tuyakhov\jsonapi\actions;
7
8
use Yii;
9
use yii\data\ActiveDataProvider;
10
use yii\db\ActiveRecordInterface;
11
use yii\db\ActiveRelationTrait;
12
use yii\db\BaseActiveRecord;
13
use yii\helpers\ArrayHelper;
14
use yii\web\ForbiddenHttpException;
15
use yii\web\NotFoundHttpException;
16
17
/**
18
 * Deletes the specified members from a relationship
19
 * @link http://jsonapi.org/format/#crud-updating-relationships
20
 */
21
class DeleteRelationshipAction extends Action
22
{
23
    /**
24
     * Removes the relationships from primary model.
25
     * @var callable
26
     */
27
    public $unlinkRelationships;
28
29
    /**
30
     * @param string $id an ID of the primary resource
31
     * @param string $name a name of the related resource
32
     * @return ActiveDataProvider
33
     * @throws ForbiddenHttpException
34
     * @throws NotFoundHttpException
35
     * @throws \yii\base\InvalidConfigException
36
     */
37
    public function run($id, $name)
38
    {
39
        /** @var BaseActiveRecord $model */
40
        $model = $this->findModel($id);
41
42
        if (!$related = $model->getRelation($name, false)) {
43
            throw new NotFoundHttpException('Relationship does not exist');
44
        }
45
46
        if (!$related->multiple) {
47
            throw new ForbiddenHttpException('Unsupported request to update relationship');
48
        }
49
50
        if ($this->checkAccess) {
51
            call_user_func($this->checkAccess, $this->id, $model, $name);
52
        }
53
54
        $this->unlinkRelationships($model, [$name => Yii::$app->getRequest()->getBodyParams()]);
55
56
57
        return new ActiveDataProvider([
58
            'query' => $related
59
        ]);
60
    }
61
62
    /**
63
     * Removes the relationships from primary model.
64
     * @param $model ActiveRecordInterface
65
     * @param array $data relationship links
66
     */
67
    protected function unlinkRelationships($model, array $data = [])
68
    {
69
        if ($this->unlinkRelationships !== null) {
70
            call_user_func($this->unlinkRelationships, $this, $model, $data);
71
            return;
72
        }
73
74
        foreach ($data as $name => $relationship) {
75
            /** @var $related ActiveRelationTrait */
76
            if (!$related = $model->getRelation($name, false)) {
77
                continue;
78
            }
79
            /** @var BaseActiveRecord $relatedClass */
80
            $relatedClass = new $related->modelClass;
81
            $relationships = ArrayHelper::keyExists($relatedClass->formName(), $relationship) ? $relationship[$relatedClass->formName()] : [];
82
83
            $ids = [];
84
            foreach ($relationships as $index => $relObject) {
85
                if (!isset($relObject['id'])) {
86
                    continue;
87
                }
88
                $ids[] = $relObject['id'];
89
            }
90
91
            $records = $relatedClass::find()->andWhere(['in', $relatedClass::primaryKey(), $ids])->all();
92
            foreach ($records as $record) {
93
                $model->unlink($name, $record, $this->enableResourceDeleting);
94
            }
95
        }
96
    }
97
}