Issues (17)

src/actions/Action.php (1 issue)

Labels
Severity
1
<?php
2
/**
3
 * @author Anton Tuyakhov <[email protected]>
4
 */
5
6
namespace tuyakhov\jsonapi\actions;
7
8
use tuyakhov\jsonapi\ResourceInterface;
9
use tuyakhov\jsonapi\ResourceTrait;
10
use yii\db\ActiveRecordInterface;
11
use yii\db\BaseActiveRecord;
12
use yii\helpers\ArrayHelper;
13
14
class Action extends \yii\rest\Action
15
{
16
    /**
17
     * Links the relationships with primary model.
18
     * @var callable
19
     */
20
    public $linkRelationships;
21
22
    /**
23
     * @var bool Weather allow to do a full replacement of a to-many relationship
24
     */
25
    public $allowFullReplacement = true;
26
27
    /**
28
     * @var bool Weather allow to delete the underlying resource if a relationship is deleted (as a garbage collection measure)
29
     */
30
    public $enableResourceDeleting = false;
31
32
    /**
33
     * Links the relationships with primary model.
34
     * @param $model ActiveRecordInterface
35
     * @param array $data relationship links
36
     */
37
    protected function linkRelationships($model, array $data = [])
38
    {
39
        if ($this->linkRelationships !== null) {
40
            call_user_func($this->linkRelationships, $this, $model, $data);
41
            return;
42
        }
43
44
        if (!$model instanceof ResourceInterface) {
45
            return;
46
        }
47
48
        foreach ($data as $name => $relationship) {
49
            if (!$related = $model->getRelation($name, false)) {
0 ignored issues
show
The method getRelation() does not exist on tuyakhov\jsonapi\ResourceInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to tuyakhov\jsonapi\ResourceInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

49
            if (!$related = $model->/** @scrutinizer ignore-call */ getRelation($name, false)) {
Loading history...
50
                continue;
51
            }
52
            /** @var BaseActiveRecord $relatedClass */
53
            $relatedClass = new $related->modelClass;
54
            $relationships = ArrayHelper::keyExists($relatedClass->formName(), $relationship) ? $relationship[$relatedClass->formName()] : [];
55
56
            $ids = [];
57
            foreach ($relationships as $index => $relObject) {
58
                if (!isset($relObject['id'])) {
59
                    continue;
60
                }
61
                $ids[] = $relObject['id'];
62
            }
63
64
            if ($related->multiple && !$this->allowFullReplacement) {
65
                continue;
66
            }
67
            $records = $relatedClass::find()->andWhere(['in', $relatedClass::primaryKey(), $ids])->all();
68
69
            /** @see ResourceTrait::$allowDeletingResources */
70
            if (method_exists($model, 'setAllowDeletingResources')) {
71
                $model->setAllowDeletingResources($this->enableResourceDeleting);
72
            }
73
74
            $model->setResourceRelationship($name, $records);
75
        }
76
    }
77
}