CreateAction.php 1.93 KB
Newer Older
Qiang Xue committed
1 2 3 4 5 6 7 8 9 10
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\rest;

use Yii;
Qiang Xue committed
11
use yii\base\Model;
Qiang Xue committed
12 13 14 15 16 17 18 19 20 21 22 23 24
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.
	 */
Qiang Xue committed
25
	public $scenario = Model::SCENARIO_DEFAULT;
Qiang Xue committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
	/**
	 * @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) {
Qiang Xue committed
44
			call_user_func($this->checkAccess, $this->id);
Qiang Xue committed
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 80
		}

		/**
		 * @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;
	}
}