CreateAction.php 1.89 KB
Newer Older
Qiang Xue committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\rest;

use Yii;
use yii\db\ActiveRecord;

/**
 * CreateAction implements the API endpoint for creating a new model from the given data.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class CreateAction extends Action
{
	/**
	 * @var string the scenario to be assigned to the new model before it is validated and saved.
	 */
	public $scenario = 'api-create';
	/**
	 * @var boolean whether to start a DB transaction when saving the model.
	 */
	public $transactional = true;
	/**
	 * @var string the name of the view action. This property is need to create the URL when the mode is successfully created.
	 */
	public $viewAction = 'view';


	/**
	 * Creates a new model.
	 * @return \yii\db\ActiveRecordInterface the model newly created
	 * @throws \Exception if there is any error when creating the model
	 */
	public function run()
	{
		if ($this->checkAccess) {
			call_user_func($this->checkAccess, $this);
		}

		/**
		 * @var \yii\db\ActiveRecord $model
		 */
		$model = new $this->modelClass([
			'scenario' => $this->scenario,
		]);

		$model->load(Yii::$app->getRequest()->getBodyParams(), '');

		if ($this->transactional && $model instanceof ActiveRecord) {
			if ($model->validate()) {
				$transaction = $model->getDb()->beginTransaction();
				try {
					$model->insert(false);
					$transaction->commit();
				} catch (\Exception $e) {
					$transaction->rollback();
					throw $e;
				}
			}
		} else {
			$model->save();
		}

		if (!$model->hasErrors()) {
			$response = Yii::$app->getResponse();
			$response->setStatusCode(201);
			$id = implode(',', array_values($model->getPrimaryKey(true)));
			$response->getHeaders()->set('Location', $this->controller->createAbsoluteUrl([$this->viewAction, 'id' => $id]));
		}

		return $model;
	}
}