119 lines
3.6KB

  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\test;
  8. use Yii;
  9. use yii\base\ArrayAccessTrait;
  10. use yii\base\InvalidConfigException;
  11. /**
  12. * BaseActiveFixture is the base class for fixture classes that support accessing fixture data as ActiveRecord objects.
  13. *
  14. * @author Qiang Xue <qiang.xue@gmail.com>
  15. * @since 2.0
  16. */
  17. abstract class BaseActiveFixture extends DbFixture implements \IteratorAggregate, \ArrayAccess, \Countable
  18. {
  19. use ArrayAccessTrait;
  20. /**
  21. * @var string the AR model class associated with this fixture.
  22. */
  23. public $modelClass;
  24. /**
  25. * @var array the data rows. Each array element represents one row of data (column name => column value).
  26. */
  27. public $data = [];
  28. /**
  29. * @var string|boolean the file path or path alias of the data file that contains the fixture data
  30. * to be returned by [[getData()]]. You can set this property to be false to prevent loading any data.
  31. */
  32. public $dataFile;
  33. /**
  34. * @var \yii\db\ActiveRecord[] the loaded AR models
  35. */
  36. private $_models = [];
  37. /**
  38. * Returns the AR model by the specified model name.
  39. * A model name is the key of the corresponding data row in [[data]].
  40. * @param string $name the model name.
  41. * @return null|\yii\db\ActiveRecord the AR model, or null if the model cannot be found in the database
  42. * @throws \yii\base\InvalidConfigException if [[modelClass]] is not set.
  43. */
  44. public function getModel($name)
  45. {
  46. if (!isset($this->data[$name])) {
  47. return null;
  48. }
  49. if (array_key_exists($name, $this->_models)) {
  50. return $this->_models[$name];
  51. }
  52. if ($this->modelClass === null) {
  53. throw new InvalidConfigException('The "modelClass" property must be set.');
  54. }
  55. $row = $this->data[$name];
  56. /* @var $modelClass \yii\db\ActiveRecord */
  57. $modelClass = $this->modelClass;
  58. /* @var $model \yii\db\ActiveRecord */
  59. $model = new $modelClass;
  60. $keys = [];
  61. foreach ($model->primaryKey() as $key) {
  62. $keys[$key] = isset($row[$key]) ? $row[$key] : null;
  63. }
  64. return $this->_models[$name] = $modelClass::findOne($keys);
  65. }
  66. /**
  67. * Loads the fixture.
  68. *
  69. * The default implementation simply stores the data returned by [[getData()]] in [[data]].
  70. * You should usually override this method by putting the data into the underlying database.
  71. */
  72. public function load()
  73. {
  74. $this->data = $this->getData();
  75. }
  76. /**
  77. * Returns the fixture data.
  78. *
  79. * The default implementation will try to return the fixture data by including the external file specified by [[dataFile]].
  80. * The file should return the data array that will be stored in [[data]] after inserting into the database.
  81. *
  82. * @return array the data to be put into the database
  83. * @throws InvalidConfigException if the specified data file does not exist.
  84. */
  85. protected function getData()
  86. {
  87. if ($this->dataFile === false || $this->dataFile === null) {
  88. return [];
  89. }
  90. $dataFile = Yii::getAlias($this->dataFile);
  91. if (is_file($dataFile)) {
  92. return require($dataFile);
  93. } else {
  94. throw new InvalidConfigException("Fixture data file does not exist: {$this->dataFile}");
  95. }
  96. }
  97. /**
  98. * @inheritdoc
  99. */
  100. public function unload()
  101. {
  102. parent::unload();
  103. $this->data = [];
  104. $this->_models = [];
  105. }
  106. }