-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
/
Copy pathActiveFixture.php
162 lines (147 loc) · 5.66 KB
/
ActiveFixture.php
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
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
namespace yii\test;
use yii\base\InvalidConfigException;
use yii\db\ActiveRecord;
use yii\db\TableSchema;
/**
* ActiveFixture represents a fixture backed up by a [[modelClass|ActiveRecord class]] or a [[tableName|database table]].
*
* Either [[modelClass]] or [[tableName]] must be set. You should also provide fixture data in the file
* specified by [[dataFile]] or overriding [[getData()]] if you want to use code to generate the fixture data.
*
* When the fixture is being loaded, it will first call [[resetTable()]] to remove any existing data in the table.
* It will then populate the table with the data returned by [[getData()]].
*
* After the fixture is loaded, you can access the loaded data via the [[data]] property. If you set [[modelClass]],
* you will also be able to retrieve an instance of [[modelClass]] with the populated data via [[getModel()]].
*
* For more details and usage information on ActiveFixture, see the [guide article on fixtures](guide:test-fixtures).
*
* @property-read TableSchema $tableSchema The schema information of the database table associated with this
* fixture.
*
* @author Qiang Xue <[email protected]>
* @since 2.0
*/
class ActiveFixture extends BaseActiveFixture
{
/**
* @var string|null the name of the database table that this fixture is about. If this property is not set,
* the table name will be determined via [[modelClass]].
* @see modelClass
*/
public $tableName;
/**
* @var string|bool|null the file path or [path alias](guide:concept-aliases) of the data file that contains the fixture data
* to be returned by [[getData()]]. If this is not set, it will default to `FixturePath/data/TableName.php`,
* where `FixturePath` stands for the directory containing this fixture class, and `TableName` stands for the
* name of the table associated with this fixture. You can set this property to be false to prevent loading any data.
*/
public $dataFile;
/**
* @var TableSchema the table schema for the table associated with this fixture
*/
private $_table;
/**
* {@inheritdoc}
*/
public function init()
{
parent::init();
if ($this->tableName === null) {
if ($this->modelClass === null) {
throw new InvalidConfigException('Either "modelClass" or "tableName" must be set.');
}
/** @var ActiveRecord $modelClass */
$modelClass = $this->modelClass;
$this->db = $modelClass::getDb();
}
}
/**
* Loads the fixture.
*
* It populate the table with the data returned by [[getData()]].
*
* If you override this method, you should consider calling the parent implementation
* so that the data returned by [[getData()]] can be populated into the table.
*/
public function load()
{
$this->data = [];
$table = $this->getTableSchema();
foreach ($this->getData() as $alias => $row) {
$primaryKeys = $this->db->schema->insert($table->fullName, $row);
$this->data[$alias] = array_merge($row, $primaryKeys);
}
}
/**
* 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 an array of data rows (column name => column value), each corresponding to a row in the table.
*
* If the data file does not exist, an empty array will be returned.
*
* @return array the data rows to be inserted into the database table.
*/
protected function getData()
{
if ($this->dataFile === null) {
if ($this->dataDirectory !== null) {
$dataFile = $this->getTableSchema()->fullName . '.php';
} else {
$class = new \ReflectionClass($this);
$dataFile = dirname($class->getFileName()) . '/data/' . $this->getTableSchema()->fullName . '.php';
}
return $this->loadData($dataFile, false);
}
return parent::getData();
}
/**
* {@inheritdoc}
*/
public function unload()
{
$this->resetTable();
parent::unload();
}
/**
* Removes all existing data from the specified table and resets sequence number to 1 (if any).
* This method is called before populating fixture data into the table associated with this fixture.
*/
protected function resetTable()
{
$table = $this->getTableSchema();
$this->db->createCommand()->delete($table->fullName)->execute();
if ($table->sequenceName !== null) {
$this->db->createCommand()->executeResetSequence($table->fullName, 1);
}
}
/**
* @return TableSchema the schema information of the database table associated with this fixture.
* @throws \yii\base\InvalidConfigException if the table does not exist
*/
public function getTableSchema()
{
if ($this->_table !== null) {
return $this->_table;
}
$db = $this->db;
$tableName = $this->tableName;
if ($tableName === null) {
/* @var $modelClass \yii\db\ActiveRecord */
$modelClass = $this->modelClass;
$tableName = $modelClass::tableName();
}
$this->_table = $db->getSchema()->getTableSchema($tableName);
if ($this->_table === null) {
throw new InvalidConfigException("Table does not exist: {$tableName}");
}
return $this->_table;
}
}