Skip to content

Instantly share code, notes, and snippets.

@tunecino
Created March 22, 2016 20:14
Show Gist options
  • Save tunecino/78583d1979853e5530c4 to your computer and use it in GitHub Desktop.
Save tunecino/78583d1979853e5530c4 to your computer and use it in GitHub Desktop.
<?php
class ImageController extends \yii\rest\ActiveController
{
public $modelClass = 'app\models\Image';
public $relationAttribute = 'imageIds';
public $relations = [
'tags' => 'tag_id',
'owner' => 'owner_id'
];
public function actionRelationships($id = '')
{
$ids = preg_split('/\s*,\s*/', $id, -1, PREG_SPLIT_NO_EMPTY);
$verb = Yii::$app->request->method;
$queryParams = Yii::$app->request->queryParams;
$modelClass = new $this->modelClass;
$linked = false;
foreach ($queryParams as $key => $value)
{
if(!is_scalar($key) or !is_scalar($value))
throw new BadRequestHttpException('Bad Request');
else if (in_array(strtolower($key), $this->relations))
{
$name = array_search($key, $this->relations);
$relation = $modelClass->getRelation($name);
if ($relation !== null)
{
$relatedModelClass = new $relation->modelClass;
$relatedModel = $relatedModelClass::findOne($value);
if (is_null($relatedModel)) throw new NotFoundHttpException("Object not found: $value");
if ($relation->multiple === false)
{
if (isset($relatedModel->{$this->relationAttribute}) && is_array($relatedModel->{$this->relationAttribute}))
{
// one_to_many relation
if ($verb === 'PATCH') {
$relatedModel->{$this->relationAttribute} = array_merge($relatedModel->{$this->relationAttribute}, $ids);
if ($relatedModel->save() === false && !$model->hasErrors())
throw new \yii\web\ServerErrorHttpException('Failed to link objects for unknown reason.');
$linked = true;
}
else throw new \yii\web\ForbiddenHttpException('Not allowed due to objects relation nature');
}
}
else if ($relation->multiple === true && $relation->via !== null)
{
// many_to_many relation
if ($verb === 'PUT') $relatedModel->{$this->relationAttribute} = $ids;
else if ($verb === 'PATCH') $relatedModel->{$this->relationAttribute} = array_merge($relatedModel->{$this->relationAttribute}, $ids);
else if ($verb === 'DELETE') {
if (empty($ids)) $relatedModel->{$this->relationAttribute} = $ids;
else {
$newIds = array_values(array_diff($relatedModel->{$this->relationAttribute}, $ids));
$relatedModel->{$this->relationAttribute} = $newIds;
}
}
if ($relatedModel->save() === false && !$model->hasErrors())
throw new \yii\web\ServerErrorHttpException('Failed to link objects for unknown reason.');
$linked = true;
}
}
}
}
$linked === true ? Yii::$app->Response->setStatusCode(204) : Yii::$app->Response->setStatusCode(304);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment