BaseActiveFixture.php 3.1 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
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\test;

use Yii;
use yii\base\ArrayAccessTrait;
use yii\base\InvalidConfigException;

/**
 * BaseActiveFixture is the base class for fixture classes that support accessing fixture data as ActiveRecord objects.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
abstract class BaseActiveFixture extends DbFixture implements \IteratorAggregate, \ArrayAccess, \Countable
{
	use ArrayAccessTrait;

	/**
	 * @var string the AR model class associated with this fixture.
	 */
	public $modelClass;
	/**
	 * @var array the data rows. Each array element represents one row of data (column name => column value).
	 */
	public $data = [];
Qiang Xue committed
32 33 34 35 36
	/**
	 * @var string|boolean the file path or path alias of the data file that contains the fixture data
	 * to be returned by [[getData()]]. You can set this property to be false to prevent loading any data.
	 */
	public $dataFile;
Qiang Xue committed
37 38 39 40 41 42 43 44
	/**
	 * @var \yii\db\ActiveRecord[] the loaded AR models
	 */
	private $_models = [];


	/**
	 * Returns the AR model by the specified model name.
Qiang Xue committed
45
	 * A model name is the key of the corresponding data row in [[data]].
Qiang Xue committed
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
	 * @param string $name the model name.
	 * @return null|\yii\db\ActiveRecord the AR model, or null if the model cannot be found in the database
	 * @throws \yii\base\InvalidConfigException if [[modelClass]] is not set.
	 */
	public function getModel($name)
	{
		if (!isset($this->data[$name])) {
			return null;
		}
		if (array_key_exists($name, $this->_models)) {
			return $this->_models[$name];
		}

		if ($this->modelClass === null) {
			throw new InvalidConfigException('The "modelClass" property must be set.');
		}
		$row = $this->data[$name];
		/** @var \yii\db\ActiveRecord $modelClass */
		$modelClass = $this->modelClass;
		/** @var \yii\db\ActiveRecord $model */
		$model = new $modelClass;
		$keys = [];
		foreach ($model->primaryKey() as $key) {
			$keys[$key] = isset($row[$key]) ? $row[$key] : null;
		}
		return $this->_models[$name] = $modelClass::find($keys);
	}
Qiang Xue committed
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105

	/**
	 * Loads the fixture.
	 *
	 * The default implementation simply stores the data returned by [[getData()]] in [[data]].
	 * You should usually override this method by putting the data into the underlying database.
	 */
	public function load()
	{
		$this->data = $this->getData();
	}

	/**
	 * Returns the fixture data.
	 *
	 * The default implementation will try to return the fixture data by including the external file specified by [[dataFile]].
	 * The file should return the data array that will be stored in [[data]] after inserting into the database.
	 *
	 * @return array the data to be put into the database
	 * @throws InvalidConfigException if the specified data file does not exist.
	 */
	protected function getData()
	{
		if ($this->dataFile === false || $this->dataFile === null) {
			return [];
		}
		$dataFile = Yii::getAlias($this->dataFile);
		if (is_file($dataFile)) {
			return require($dataFile);
		} else {
			throw new InvalidConfigException("Fixture data file does not exist: {$this->dataFile}");
		}
	}
Qiang Xue committed
106
}