Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
201 additions
and
54 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php | ||
/** | ||
* @author Anton Tuyakhov <atuyakhov@gmail.com> | ||
*/ | ||
|
||
namespace tuyakhov\jsonapi\actions; | ||
|
||
use tuyakhov\jsonapi\ResourceInterface; | ||
use yii\data\ActiveDataProvider; | ||
use yii\db\BaseActiveRecord; | ||
use yii\helpers\ArrayHelper; | ||
use yii\rest\Action; | ||
use yii\web\BadRequestHttpException; | ||
use yii\web\NotFoundHttpException; | ||
|
||
class UpdateRelationshipAction extends Action | ||
{ | ||
/** | ||
* @param $id | ||
* @param $name | ||
* @return array|null|ActiveDataProvider|\yii\db\ActiveRecord|\yii\db\ActiveRecordInterface | ||
* @throws BadRequestHttpException | ||
* @throws NotFoundHttpException | ||
*/ | ||
public function run($id, $name) | ||
{ | ||
/** @var BaseActiveRecord $model */ | ||
$model = $this->findModel($id); | ||
|
||
if (!$model instanceof ResourceInterface) { | ||
throw new BadRequestHttpException('Impossible to update relationships for resource'); | ||
} | ||
|
||
if (!$related = $model->getRelation($name, false)) { | ||
throw new NotFoundHttpException('Relationship does not exist'); | ||
} | ||
$relatedClass = $related->modelClass; | ||
|
||
$data = \Yii::$app->getRequest()->getBodyParams(); | ||
$data = ArrayHelper::isIndexed($data) ? $data : [$data]; | ||
|
||
$ids = []; | ||
foreach ($data as $index => $relationshipObject) { | ||
if (!isset($relationshipObject['id'])) { | ||
continue; | ||
} | ||
$ids[] = $relationshipObject['id']; | ||
} | ||
/** @var BaseActiveRecord $relatedClass */ | ||
$relationships = $relatedClass::find() | ||
->andWhere(['in', $relatedClass::primaryKey(), $ids]) | ||
->all(); | ||
|
||
if (!empty($relationships)) { | ||
$model->unlinkAll($name); | ||
$model->setResourceRelationship($name, $relationships); | ||
} | ||
|
||
if ($related->multiple) { | ||
return new ActiveDataProvider([ | ||
'query' => $related | ||
]); | ||
} else { | ||
return $related->one(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
/** | ||
* @author Anton Tuyakhov <atuyakhov@gmail.com> | ||
*/ | ||
|
||
namespace tuyakhov\jsonapi\actions; | ||
|
||
|
||
use tuyakhov\jsonapi\ResourceInterface; | ||
use yii\data\ActiveDataProvider; | ||
use yii\db\ActiveQuery; | ||
use yii\rest\Action; | ||
use yii\web\BadRequestHttpException; | ||
use yii\web\NotFoundHttpException; | ||
|
||
class ViewRelatedAction extends Action | ||
{ | ||
/** | ||
* Prepares the data provider that should return the requested collection of the models. | ||
* @var callable | ||
*/ | ||
public $prepareDataProvider; | ||
|
||
/** | ||
* @param $id | ||
* @param $name | ||
* @return ActiveDataProvider|\yii\db\ActiveRecordInterface | ||
* @throws BadRequestHttpException | ||
* @throws NotFoundHttpException | ||
*/ | ||
public function run($id, $name) | ||
{ | ||
$model = $this->findModel($id); | ||
|
||
if (!$model instanceof ResourceInterface) { | ||
throw new BadRequestHttpException('Impossible to fetch related resource'); | ||
} | ||
|
||
if ($this->checkAccess) { | ||
call_user_func($this->checkAccess, $this->id, $model); | ||
} | ||
|
||
/** @var ActiveQuery $related */ | ||
if (!$related = $model->getRelation($name, false)) { | ||
throw new NotFoundHttpException('Resource does not exist'); | ||
} | ||
|
||
if ($this->prepareDataProvider !== null) { | ||
return call_user_func($this->prepareDataProvider, $this, $related); | ||
} | ||
|
||
if ($related->multiple) { | ||
return new ActiveDataProvider([ | ||
'query' => $related | ||
]); | ||
} else { | ||
return $related->one(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
/** | ||
* @author Anton Tuyakhov <atuyakhov@gmail.com> | ||
*/ | ||
namespace tuyakhov\jsonapi\tests\actions; | ||
|
||
use tuyakhov\jsonapi\tests\TestCase; | ||
use tuyakhov\jsonapi\actions\ViewRelatedAction; | ||
use yii\base\Controller; | ||
use tuyakhov\jsonapi\tests\data\ResourceModel; | ||
use yii\data\ActiveDataProvider; | ||
use \tuyakhov\jsonapi\tests\data\ActiveQuery; | ||
use yii\web\NotFoundHttpException; | ||
|
||
class ViewRelatedActionTest extends TestCase | ||
{ | ||
|
||
public function testSuccess() | ||
{ | ||
$model = new ResourceModel(); | ||
$action = new ViewRelatedAction('test', new Controller('test', \Yii::$app), [ | ||
'modelClass' => ResourceModel::className() | ||
]); | ||
$model->setRelation('multiple', new ActiveQuery(ResourceModel::className(), ['multiple' => true])); | ||
$model->setRelation('single', new ActiveQuery(ResourceModel::className())); | ||
$action->findModel = function ($id, $action) use($model) { | ||
return $model; | ||
}; | ||
|
||
$this->assertInstanceOf(ActiveDataProvider::className(), $action->run(1, 'multiple')); | ||
$this->assertInstanceOf(ResourceModel::className(), $action->run(1, 'single')); | ||
} | ||
|
||
public function testInvalidRelation() | ||
{ | ||
$action = new ViewRelatedAction('test', new Controller('test', \Yii::$app), [ | ||
'modelClass' => ResourceModel::className() | ||
]); | ||
$action->findModel = function ($id, $action) { | ||
return new ResourceModel(); | ||
}; | ||
$this->expectException(NotFoundHttpException::class); | ||
$action->run(1, 'invalid'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
/** | ||
* @author Anton Tuyakhov <atuyakhov@gmail.com> | ||
*/ | ||
namespace tuyakhov\jsonapi\tests\data; | ||
|
||
|
||
class ActiveQuery extends \yii\db\ActiveQuery | ||
{ | ||
public function one($db = null) | ||
{ | ||
return new $this->modelClass; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters