Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from tuyakhov/rest_actions
Json api actions
- Loading branch information
Showing
14 changed files
with
443 additions
and
100 deletions.
There are no files selected for viewing
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
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,69 @@ | ||
<?php | ||
/** | ||
* @author Anton Tuyakhov <atuyakhov@gmail.com> | ||
*/ | ||
|
||
namespace tuyakhov\jsonapi\actions; | ||
|
||
use tuyakhov\jsonapi\ResourceInterface; | ||
use yii\db\ActiveRecordInterface; | ||
use yii\db\BaseActiveRecord; | ||
use yii\helpers\ArrayHelper; | ||
|
||
class Action extends \yii\rest\Action | ||
{ | ||
/** | ||
* Links the relationships with primary model. | ||
* @var callable | ||
*/ | ||
public $linkRelationships; | ||
|
||
/** | ||
* @var bool Weather allow to do a full replacement of a to-many relationship | ||
*/ | ||
public $allowFullReplacement = true; | ||
|
||
/** | ||
* Links the relationships with primary model. | ||
* @param $model ActiveRecordInterface | ||
* @param array $data | ||
*/ | ||
protected function linkRelationships($model, array $data = []) | ||
{ | ||
if ($this->linkRelationships !== null) { | ||
call_user_func($this->linkRelationships, $this, $model, $data); | ||
return; | ||
} | ||
|
||
if (!$model instanceof ResourceInterface) { | ||
return; | ||
} | ||
|
||
foreach ($data as $name => $relationship) { | ||
if (!$related = $model->getRelation($name, false)) { | ||
continue; | ||
} | ||
/** @var BaseActiveRecord $relatedClass */ | ||
$relatedClass = new $related->modelClass; | ||
$relationships = ArrayHelper::keyExists($relatedClass->formName(), $relationship) ? $relationship[$relatedClass->formName()] : []; | ||
|
||
$ids = []; | ||
foreach ($relationships as $index => $relObject) { | ||
if (!isset($relObject['id'])) { | ||
continue; | ||
} | ||
$ids[] = $relObject['id']; | ||
} | ||
|
||
if (!$records = $relatedClass::find()->andWhere(['in', $relatedClass::primaryKey(), $ids])->all()) { | ||
continue; | ||
} | ||
|
||
if ($related->multiple && !$this->allowFullReplacement) { | ||
continue; | ||
} | ||
$model->unlinkAll($name); | ||
$model->setResourceRelationship($name, $records); | ||
} | ||
} | ||
} |
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,61 @@ | ||
<?php | ||
/** | ||
* @author Anton Tuyakhov <atuyakhov@gmail.com> | ||
*/ | ||
|
||
namespace tuyakhov\jsonapi\actions; | ||
|
||
use Yii; | ||
use yii\base\Model; | ||
use yii\helpers\Url; | ||
use yii\web\ServerErrorHttpException; | ||
|
||
class CreateAction extends Action | ||
{ | ||
/** | ||
* @var string the scenario to be assigned to the new model before it is validated and saved. | ||
*/ | ||
public $scenario = Model::SCENARIO_DEFAULT; | ||
|
||
/** | ||
* @var string the name of the view action. This property is need to create the URL when the model is successfully created. | ||
*/ | ||
public $viewAction = 'view'; | ||
|
||
/** | ||
* Links the relationships with primary model. | ||
* @var callable | ||
*/ | ||
public $linkRelationships; | ||
|
||
/** | ||
* Creates a new resource. | ||
* @return \yii\db\ActiveRecordInterface the model newly created | ||
* @throws ServerErrorHttpException if there is any error when creating the model | ||
*/ | ||
public function run() | ||
{ | ||
if ($this->checkAccess) { | ||
call_user_func($this->checkAccess, $this->id); | ||
} | ||
|
||
/* @var $model \yii\db\ActiveRecord */ | ||
$model = new $this->modelClass([ | ||
'scenario' => $this->scenario, | ||
]); | ||
|
||
$request = Yii::$app->getRequest(); | ||
$model->load($request->getBodyParams()); | ||
if ($model->save()) { | ||
$this->linkRelationships($model, $request->getBodyParam('relationships')); | ||
$response = Yii::$app->getResponse(); | ||
$response->setStatusCode(201); | ||
$id = implode(',', array_values($model->getPrimaryKey(true))); | ||
$response->getHeaders()->set('Location', Url::toRoute([$this->viewAction, 'id' => $id], true)); | ||
} elseif (!$model->hasErrors()) { | ||
throw new ServerErrorHttpException('Failed to create the object for unknown reason.'); | ||
} | ||
|
||
return $model; | ||
} | ||
} |
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,46 @@ | ||
<?php | ||
/** | ||
* @author Anton Tuyakhov <atuyakhov@gmail.com> | ||
*/ | ||
|
||
namespace tuyakhov\jsonapi\actions; | ||
|
||
use yii\base\Model; | ||
use yii\db\ActiveRecord; | ||
use Yii; | ||
use yii\web\ServerErrorHttpException; | ||
|
||
class UpdateAction extends Action | ||
{ | ||
/** | ||
* @var string the scenario to be assigned to the model before it is validated and updated. | ||
*/ | ||
public $scenario = Model::SCENARIO_DEFAULT; | ||
|
||
/** | ||
* Updates an existing resource. | ||
* @param string $id the primary key of the model. | ||
* @return \yii\db\ActiveRecordInterface the model being updated | ||
* @throws ServerErrorHttpException if there is any error when updating the model | ||
*/ | ||
public function run($id) | ||
{ | ||
/* @var $model ActiveRecord */ | ||
$model = $this->findModel($id); | ||
|
||
if ($this->checkAccess) { | ||
call_user_func($this->checkAccess, $this->id, $model); | ||
} | ||
|
||
$request = Yii::$app->getRequest(); | ||
$model->scenario = $this->scenario; | ||
$model->load($request->getBodyParams()); | ||
if ($model->save() === false && !$model->hasErrors()) { | ||
throw new ServerErrorHttpException('Failed to update the object for unknown reason.'); | ||
} | ||
|
||
$this->linkRelationships($model, $request->getBodyParam('relationships')); | ||
|
||
return $model; | ||
} | ||
} |
Oops, something went wrong.