66namespace tuyakhov \jsonapi \actions ;
77
88use tuyakhov \jsonapi \ResourceInterface ;
9+ use yii \base \Model ;
910use yii \data \ActiveDataProvider ;
1011use yii \db \BaseActiveRecord ;
1112use yii \helpers \ArrayHelper ;
1213use yii \rest \Action ;
1314use yii \web \BadRequestHttpException ;
1415use yii \web \NotFoundHttpException ;
1516
17+ /**
18+ * UpdateRelationshipAction implements the API endpoint for updating relationships.
19+ * @link http://jsonapi.org/format/#crud-updating-relationships
20+ */
1621class UpdateRelationshipAction extends Action
1722{
1823 /**
19- * @param $id
20- * @param $name
21- * @return array|null|ActiveDataProvider|\yii\db\ActiveRecord|\yii\db\ActiveRecordInterface
24+ * Prepares the relationships to link with primary model.
25+ * @var callable
26+ */
27+ public $ prepareRelationships ;
28+ /**
29+ * Update of relationships independently.
30+ * @param string $id an ID of the primary resource
31+ * @param string $name a name of the related resource
32+ * @return ActiveDataProvider|BaseActiveRecord
2233 * @throws BadRequestHttpException
2334 * @throws NotFoundHttpException
2435 */
@@ -34,22 +45,12 @@ public function run($id, $name)
3445 if (!$ related = $ model ->getRelation ($ name , false )) {
3546 throw new NotFoundHttpException ('Relationship does not exist ' );
3647 }
37- $ relatedClass = $ related ->modelClass ;
3848
39- $ data = \Yii::$ app ->getRequest ()->getBodyParams ();
40- $ data = ArrayHelper::isIndexed ($ data ) ? $ data : [$ data ];
41-
42- $ ids = [];
43- foreach ($ data as $ index => $ relationshipObject ) {
44- if (!isset ($ relationshipObject ['id ' ])) {
45- continue ;
46- }
47- $ ids [] = $ relationshipObject ['id ' ];
49+ if ($ this ->checkAccess ) {
50+ call_user_func ($ this ->checkAccess , $ this ->id , $ model , $ name );
4851 }
49- /** @var BaseActiveRecord $relatedClass */
50- $ relationships = $ relatedClass ::find ()
51- ->andWhere (['in ' , $ relatedClass ::primaryKey (), $ ids ])
52- ->all ();
52+
53+ $ relationships = $ this ->prepareRelationships ($ related );
5354
5455 if (!empty ($ relationships )) {
5556 $ model ->unlinkAll ($ name );
@@ -64,4 +65,34 @@ public function run($id, $name)
6465 return $ related ->one ();
6566 }
6667 }
68+
69+ protected function prepareRelationships ($ related )
70+ {
71+ if ($ this ->prepareRelationships !== null ) {
72+ return call_user_func ($ this ->prepareRelationships , $ this , $ related );
73+ }
74+
75+ /** @var BaseActiveRecord $relatedClass */
76+ $ relatedClass = new $ related ->modelClass ;
77+
78+ $ data = \Yii::$ app ->getRequest ()->getBodyParams ();
79+
80+ $ data = ArrayHelper::keyExists ($ relatedClass ->formName (), $ data ) ? $ data [$ relatedClass ->formName ()] : [];
81+
82+ if (!ArrayHelper::isIndexed ($ data )) {
83+ $ data = [$ data ];
84+ }
85+
86+ $ ids = [];
87+ foreach ($ data as $ index => $ relationshipObject ) {
88+ if (!isset ($ relationshipObject ['id ' ])) {
89+ continue ;
90+ }
91+ $ ids [] = $ relationshipObject ['id ' ];
92+ }
93+
94+ return $ relatedClass ::find ()
95+ ->andWhere (['in ' , $ relatedClass ::primaryKey (), $ ids ])
96+ ->all ();
97+ }
6798}
0 commit comments