ShellSeedProcessor   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 202
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 27
lcom 1
cbo 2
dl 0
loc 202
c 0
b 0
f 0
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A processFixtures() 0 7 2
C sowSeeds() 0 37 8
A getFieldFormatters() 0 19 4
A _guessFieldFormatters() 0 10 2
A _getColumnTypeGuesser() 0 3 1
A _getColumns() 0 6 1
A createSeed() 0 10 2
B saveSeeds() 0 21 5
A _getModel() 0 5 1
1
<?php
2
3
App::uses('ColumnTypeGuesser', 'FakeSeeder.Lib');
4
5
/**
6
 * Shell Seed Processor
7
 */
8
class ShellSeedProcessor {
9
10
	/**
11
	 * Aseeder shell task instance
12
	 *
13
	 * @var null|SeederTaskBase
14
	 */
15
	protected $_seeder = null;
16
17
	/**
18
	 * ModelTruncator constructor
19
	 *
20
	 * @param Shell $seeder A seeder shell task
21
	 */
22
	public function __construct($seeder) {
23
		$this->_seeder = $seeder;
0 ignored issues
show
Documentation Bug introduced by
It seems like $seeder of type object<Shell> is incompatible with the declared type null|object<SeederTaskBase> of property $_seeder.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
24
	}
25
26
	/**
27
	 * Process the fixtures
28
	 *
29
	 * @return void
30
	 */
31
	public function processFixtures() {
32
		$fixtures = $this->_seeder->fixtureRecords();
33
		if (empty($fixtures)) {
34
			return;
35
		}
36
		$this->saveSeeds($fixtures);
37
	}
38
39
	/**
40
	 * Sow the seeds
41
	 *
42
	 * @return void
43
	 */
44
	public function sowSeeds() {
45
		$modelName = $this->_seeder->getModelName();
46
		$recordsTotal = $this->_seeder->getRecordsCount();
47
		$this->_seeder->out(__('Sowing %s seeds for model %s', $recordsTotal, $modelName));
48
49
		$fieldFormatters = $this->getFieldFormatters();
50
		if (empty($fieldFormatters)) {
51
			$this->_seeder->out(__('No field formatters configured, aborting.'));
52
			return;
53
		}
54
55
		// Improve seed access
56
		$this->_seeder->seeds = array();
57
		for ($record = 1; $record <= $recordsTotal; $record++) {
58
			$newSeed = $this->createSeed($fieldFormatters);
59
			if (empty($newSeed)) {
60
				$this->_seeder->out(__('Created seed is empty! Check the field formatters.'));
61
				break;
62
			}
63
			$this->_seeder->seeds[] = $newSeed;
64
65
			$this->_seeder->out('.', 0);
66
			$modulo = $record % 50;
67
			if ($modulo == 0 || $record == $recordsTotal) {
68
				$alignSpaces = 0;
69
				if ($modulo !== 0 && $record >= 50) {
70
					$alignSpaces = 50 - $modulo;
71
				}
72
				$alignSpaces = $alignSpaces + strlen($recordsTotal) - strlen($record) + 1;
73
				$alignSpaces = str_repeat(' ', $alignSpaces);
74
				$this->_seeder->out(sprintf('%s%s / %s', $alignSpaces, $record, $recordsTotal));
75
			}
76
		}
77
		$this->saveSeeds($this->_seeder->seeds);
78
79
		$this->_seeder->out(__('Finished sowing %s seeds for model %s', $recordsTotal, $modelName));
80
	}
81
82
	/**
83
	 * Get the field formatters depending on the seeding mode
84
	 *
85
	 * 'manual' = No Field formatters are guessed.
86
	 * 'auto' = All field formatters are guessed.
87
	 * 'mixed' = Only missing field formatters are guessed.
88
	 *
89
	 * @return array The field formatters
90
	 */
91
	public function getFieldFormatters() {
92
		$mode = $this->_seeder->getSeedingMode();
93
		switch ($mode) {
94
			case 'manual':
95
				return $this->_seeder->fieldFormatters();
96
			case 'auto':
97
				return $this->_guessFieldFormatters();
98
			case 'mixed':
99
				// TODO Improve by only guessing those needed
100
				$guesedFormatters = $this->_guessFieldFormatters();
101
				$setFormatters = $this->_seeder->fieldFormatters();
102
				return array_merge(
103
					$guesedFormatters,
104
					$setFormatters
105
				);
106
		}
107
		// TODO Handle invalid mode
108
		return array();
109
	}
110
111
	/**
112
	 * Guess the field formatters based on the column type
113
	 *
114
	 * @return array The guessed field formatters.
115
	 */
116
	protected function _guessFieldFormatters() {
117
		$columns = $this->_getColumns();
118
119
		$columnTypeGuesser = $this->_getColumnTypeGuesser();
120
		$fieldFormatters = array();
121
		foreach ($columns as $columnName => $column) {
122
			$fieldFormatters[$columnName] = $columnTypeGuesser->guessFormat($column);
123
		}
124
		return $fieldFormatters;
125
	}
126
127
	/**
128
	 * Get a ColumnTypeGuesser instance
129
	 *
130
	 * @return ColumnTypeGuesser A ColumnTypeGuesser instance.
131
	 */
132
	protected function _getColumnTypeGuesser() {
133
		return new ColumnTypeGuesser($this->_seeder->faker);
134
	}
135
136
	/**
137
	 * Get the columns (schema)
138
	 *
139
	 * Removes the primary key, though.
140
	 *
141
	 * @return array The columns (schema).
142
	 */
143
	protected function _getColumns() {
144
		$model = $this->_getModel();
145
		$columns = $model->schema();
146
		unset($columns[$model->primaryKey]);
147
		return $columns;
148
	}
149
150
	/**
151
	 * Create seed to sow
152
	 *
153
	 * Gets some (optional) record state data,
154
	 * which can be shared by all field formatters of one record.
155
	 *
156
	 * @param array $fieldFormatters The fields and their formatter
157
	 * @return array A seed to sow.
158
	 */
159
	public function createSeed($fieldFormatters) {
160
		$seed = array();
161
		$modelName = $this->_seeder->getModelName();
162
		$state = $this->_seeder->recordState();
163
164
		foreach ($fieldFormatters as $fieldName => $formatter) {
165
			$seed[$modelName][$fieldName] = $formatter($state);
166
		}
167
		return $seed;
168
	}
169
170
	/**
171
	 * Save the seeds
172
	 *
173
	 * @param array $seeds The seeds to save.
174
	 * @return void
175
	 * @todo Make data saving/validation handling configurable (atomic true/false)
176
	 */
177
	public function saveSeeds($seeds) {
178
		$model = $this->_getModel();
179
		$validate = $this->_seeder->getValidateSeeding();
180
181
		if ($validate === 'false') {
182
			$validate = false;
183
		} elseif ($validate !== 'first' && $validate !== 'only') {
184
			$validate = (bool)$validate;
185
		}
186
187
		$saved = $model->saveAll(
188
			$seeds,
189
			array(
190
				'validate' => $validate
191
			)
192
		);
193
		if (!$saved) {
194
			$this->_seeder->out(__('Seeds could not be saved successfully!'));
195
			$this->_seeder->out(__('Data validation errors: %s', var_export($model->validationErrors, true)), 1, Shell::VERBOSE);
196
		}
197
	}
198
199
	/**
200
	 * Get the model instance
201
	 *
202
	 * @return Model The model instance.
203
	 */
204
	protected function _getModel() {
205
		$modelName = $this->_seeder->getModelName();
206
		$model = ClassRegistry::init($modelName);
207
		return $model;
208
	}
209
}