This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | App::uses('ShellModelTruncator', 'FakeSeeder.Lib'); |
||
4 | App::uses('Folder', 'Utility'); |
||
5 | |||
6 | /** |
||
7 | * SeederShell |
||
8 | * |
||
9 | * Can either be used to invoke seeder shell tasks directly |
||
10 | * or as base class for seeder suites (logically groups of seeders) to base upon. |
||
11 | * |
||
12 | * @todo Evaluate if it's sensible to split this class into two (shell and base class) |
||
13 | */ |
||
14 | class SeederShell extends AppShell { |
||
15 | |||
16 | /** |
||
17 | * Defined the seeder tasks names without 'SeederTask' suffix to execute in this suite in in sequential order |
||
18 | * |
||
19 | * @var array |
||
20 | * @todo Consider allowing to set the records per seeder, as sub array |
||
21 | */ |
||
22 | protected $_seeders = array(); |
||
23 | |||
24 | /** |
||
25 | * Additional models to truncate |
||
26 | * |
||
27 | * @var array |
||
28 | */ |
||
29 | protected $_modelsToTruncate = array(); |
||
30 | |||
31 | /** |
||
32 | * Initialize seeder shell, make sure it's OK to seed |
||
33 | * |
||
34 | * @return void |
||
35 | */ |
||
36 | public function initialize() { |
||
37 | parent::initialize(); |
||
38 | |||
39 | $this->_checkSeedable(); |
||
40 | } |
||
41 | |||
42 | /** |
||
43 | * Check if seeding the database is allowed |
||
44 | * |
||
45 | * @return void |
||
46 | * ¦todo Consider making this over writable by a CLI parameter, e.g. --force or --ignore-check |
||
47 | */ |
||
48 | protected function _checkSeedable() { |
||
49 | if (Configure::read('FakeSeeder.seedable') !== true) { |
||
50 | $this->_stop(__('Seeding is not activated in configuration in "FakeSeeder.seedable"!')); |
||
51 | } |
||
52 | if (Configure::read('debug') < 1) { |
||
53 | $this->_stop(__('Seeding is allowed only in debug mode!')); |
||
54 | } |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * Get the Console Option Parser |
||
59 | * |
||
60 | * @return ConsoleOptionParser The Console Option Parser. |
||
61 | */ |
||
62 | public function getOptionParser() { |
||
63 | $parser = parent::getOptionParser(); |
||
64 | |||
65 | $parser->description(array( |
||
66 | __('A shell to seed your database with fake and/or fixed data.'), |
||
67 | __(''), |
||
68 | __('Uses Faker to generate the fake data.'), |
||
69 | __('Uses shell tasks for implementing specific seeders.'), |
||
70 | __('Organizes logical groups of seeders in custom seeder shells/suites.'), |
||
71 | )); |
||
72 | $parser->addArguments(array( |
||
73 | 'model' => array( |
||
74 | 'help' => "The name of a seeder shell task without 'SeederTask' suffix.\n" . |
||
75 | "For example 'Article' for 'ArticleSeederTask'.\n" . |
||
76 | "Alternatively the name of a model.\n" . |
||
77 | "It will try to guess the field formatters then.", |
||
78 | 'required' => false, |
||
79 | ) |
||
80 | )); |
||
81 | $parser->addOptions(array( |
||
82 | 'mode' => array( |
||
83 | 'help' => "The seeding mode.\n" . |
||
84 | "'manual' = No Field formatters are guessed.\n" . |
||
85 | "'auto' = All field formatters are guessed.\n" . |
||
86 | "'mixed' = Only missing field formatters are guessed.\n", |
||
87 | 'short' => 'm', |
||
88 | 'choices' => array('manual', 'auto', 'mixed'), |
||
89 | 'default' => '', |
||
90 | ), |
||
91 | 'locale' => array( |
||
92 | 'help' => 'The locale to use for Faker.', |
||
93 | 'short' => 'l', |
||
94 | 'default' => '', |
||
95 | ), |
||
96 | 'records' => array( |
||
97 | 'help' => 'The amount of records to seed.', |
||
98 | 'short' => 'r', |
||
99 | 'default' => '', |
||
100 | ), |
||
101 | 'validate' => array( |
||
102 | 'help' => 'Whether or not to validate when saving the seeding data.', |
||
103 | 'choices' => array('first', true, false), |
||
104 | 'default' => '', |
||
105 | ), |
||
106 | 'seed' => array( |
||
107 | 'help' => 'Set the seed number for Faker to use.', |
||
108 | 'short' => 's', |
||
109 | 'default' => '', |
||
110 | ), |
||
111 | 'no-truncate' => array( |
||
112 | 'help' => 'Prevents that the model gets truncated before seeding.', |
||
113 | 'boolean' => true, |
||
114 | ), |
||
115 | )); |
||
116 | $parser->epilog(array( |
||
117 | __('All shell options can be set through:'), |
||
118 | __('1. CLI parameter, e.g. "--records"'), |
||
119 | __('2. The seeder specific configuration, e.g. "FakeSeeder.Article.records"'), |
||
120 | __('3. The general seeder configuration, e.g "FakeSeeder.records"'), |
||
121 | __('4. The seeder shell task class properties, e.g. "$_records"'), |
||
122 | __('The values are checked in that order. The first value found is taken.'), |
||
123 | __('If no value is set, it will fall back to an optional default value.'), |
||
124 | __(''), |
||
125 | __('When no seeders are set (e.g. in a custom seeder suite) and if called without arguments, ' . |
||
126 | 'it will prompt to execute one of the seeder shell tasks available.'), |
||
127 | )); |
||
128 | |||
129 | return $parser; |
||
130 | } |
||
131 | |||
132 | /** |
||
133 | * Main Seeder method |
||
134 | * |
||
135 | * If invoked with a seeder name an argument, it executes this single seeder shell task. |
||
136 | * If invoked without seeder name as argument, it prompts for a seeder shell to execute. |
||
137 | * |
||
138 | * @return void |
||
139 | * @todo Consider using DB transaction(s) |
||
140 | */ |
||
141 | public function main() { |
||
142 | // TODO Disable FK constraints |
||
143 | |||
144 | if (!empty($this->args[0])) { |
||
145 | // Either execute the given seeder task |
||
146 | $seederName = $this->args[0]; |
||
147 | $this->out(__('Execute %s seeder...', $seederName)); |
||
148 | $this->_executeSeederTask($seederName, $this->params['no-truncate']); |
||
149 | } elseif (!empty($this->_seeders)) { |
||
150 | // Execute all seeders set in $_seeders (only applies for subclasses) |
||
151 | if ($this->params['no-truncate'] === false) { |
||
152 | $this->_truncateModels(); |
||
153 | } |
||
154 | $this->_callSeeders(); |
||
155 | } else { |
||
156 | // Prompt for a seeder shell task to execute |
||
157 | $this->_promptForSeeder(); |
||
158 | } |
||
159 | |||
160 | // TODO Enable FK constraints, if necessary |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * Truncate the models |
||
165 | * |
||
166 | * Merges all the models from all seeders with the additionally configured models. |
||
167 | * |
||
168 | * @return void |
||
169 | * @see ShellModelTruncator::truncateModels |
||
170 | */ |
||
171 | protected function _truncateModels() { |
||
172 | $this->out(__('Truncating models...')); |
||
173 | |||
174 | // Get all models from all seeders |
||
175 | $modelsToTruncate = array(); |
||
176 | foreach ($this->_seeders as $seederName) { |
||
177 | $modelsToTruncate = array_merge( |
||
178 | $modelsToTruncate, |
||
179 | $this->_getModelsToTruncateFromSeederTask($seederName) |
||
180 | ); |
||
181 | } |
||
182 | |||
183 | $modelsToTruncate = array_merge($modelsToTruncate, $this->_modelsToTruncate); |
||
184 | $modelsToTruncate = array_unique($modelsToTruncate); |
||
185 | |||
186 | $modelTruncator = $this->_getModelTruncator(); |
||
187 | $modelTruncator->truncateModels($modelsToTruncate); |
||
188 | |||
189 | $this->out(__('Finished truncating models.')); |
||
190 | } |
||
191 | |||
192 | /** |
||
193 | * Get an instance of the ShellModelTruncator, for delegating the model truncation |
||
194 | * |
||
195 | * @return ShellModelTruncator The shell model truncator instance. |
||
196 | */ |
||
197 | protected function _getModelTruncator() { |
||
198 | return new ShellModelTruncator($this); |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * Get the models to truncate from the seeder task |
||
203 | * |
||
204 | * @param string $seederName The name of the seeder task. |
||
205 | * @return array The models to truncate. |
||
206 | */ |
||
207 | protected function _getModelsToTruncateFromSeederTask($seederName) { |
||
208 | $seederName = $seederName . 'Seeder'; |
||
209 | $seederTask = $this->Tasks->load($seederName); |
||
210 | |||
211 | $models = $seederTask->getModelsToTruncate(); |
||
212 | return $models; |
||
213 | } |
||
214 | |||
215 | /** |
||
216 | * Call the seeders of the suite |
||
217 | * |
||
218 | * Does not execute the data truncation in the seeders as we've done that already. |
||
219 | * |
||
220 | * @return void |
||
221 | */ |
||
222 | protected function _callSeeders() { |
||
223 | $this->out(__('Execute seeders...')); |
||
224 | |||
225 | foreach ($this->_seeders as $seederName) { |
||
226 | $this->out(__('Execute %s seeder...', $seederName)); |
||
227 | $this->_executeSeederTask($seederName, true); |
||
228 | |||
229 | } |
||
230 | $this->out(__('Finished executing seeders.')); |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * Prompts the user with a list of available seeder shell tasks |
||
235 | * |
||
236 | * Only supports app based seeder shell tasks, at the moment. |
||
237 | * |
||
238 | * @return void |
||
239 | */ |
||
240 | protected function _promptForSeeder() { |
||
241 | $seederTasks = $this->_getSeederTasks(); |
||
242 | |||
243 | $this->out(__('Choose one seeder shell task to execute:')); |
||
244 | $taskCount = count($seederTasks); |
||
245 | for ($i = 0; $i < $taskCount; $i++) { |
||
246 | $this->out(sprintf("%d. %s", $i + 1, $seederTasks[$i])); |
||
247 | } |
||
248 | |||
249 | $chosenSeeder = $this->in(__("Enter a number from the list above,\n" . |
||
250 | "type in the name of another seeder shell task,\n" . |
||
251 | "type in the name of a model,\n" . |
||
252 | "or 'q' to exit"), null, 'q'); |
||
253 | |||
254 | if ($chosenSeeder === 'q') { |
||
255 | $this->_stop(); |
||
256 | return; |
||
257 | } |
||
258 | |||
259 | if (!$chosenSeeder || (int)$chosenSeeder > $taskCount) { |
||
260 | $this->err(__d('cake_console', "The seeder shell task name you supplied was empty,\n" . |
||
261 | "or the number you selected was not a valid option. Please try again.")); |
||
262 | $this->_stop(); |
||
263 | return; |
||
264 | } |
||
265 | if ((int)$chosenSeeder > 0 && (int)$chosenSeeder <= $taskCount) { |
||
266 | $chosenSeeder = $seederTasks[(int)$chosenSeeder - 1]; |
||
267 | } |
||
268 | |||
269 | $this->out(__('Execute %s seeder...', $chosenSeeder)); |
||
270 | // Add seeder to argument list, in case it is a model |
||
271 | $this->args[0] = $chosenSeeder; |
||
272 | $this->_executeSeederTask($chosenSeeder, $this->params['no-truncate']); |
||
273 | } |
||
274 | |||
275 | /** |
||
276 | * Get the available seeder shell tasks |
||
277 | * |
||
278 | * Checks for *SeederTask.php files in |
||
279 | * app/Console/Command/Task/. |
||
280 | * |
||
281 | * @return array The available seeder shell tasks. |
||
282 | * @todo Also support plugin shell tasks. |
||
283 | * @todo Improve testability by getting the Folder object from externally. |
||
284 | */ |
||
285 | protected function _getSeederTasks() { |
||
286 | $taskDir = ROOT . DS . APP_DIR . DS . 'Console' . DS . 'Command' . DS . 'Task' . DS; |
||
287 | $dir = new Folder($taskDir); |
||
288 | $files = $dir->find('(.*)SeederTask\.php'); |
||
289 | $seedTasks = array(); |
||
290 | foreach ($files as $file) { |
||
291 | $seedTasks[] = substr(basename($file), 0, -14); |
||
292 | } |
||
293 | sort($seedTasks); |
||
294 | return $seedTasks; |
||
295 | } |
||
296 | |||
297 | /** |
||
298 | * Execute a seeder Task |
||
299 | * |
||
300 | * Loads a task and make sure it is initialized properly |
||
301 | * |
||
302 | * @param string $seederName The name of the seeder task, without SeederTask. |
||
303 | * @param bool $noTruncate Prevents that the model gets truncated before seeding, defaults to true. |
||
304 | * @return void |
||
305 | */ |
||
306 | protected function _executeSeederTask($seederName, $noTruncate = true) { |
||
307 | $seederNameSuffixed = $seederName . 'Seeder'; |
||
308 | try { |
||
309 | $seederTask = $this->Tasks->load($seederNameSuffixed); |
||
310 | } catch (MissingTaskException $e) { |
||
0 ignored issues
–
show
|
|||
311 | $this->out(__( |
||
312 | "No seeder shell tasks named '%s' found. Trying to find a '%s' model.", |
||
313 | $seederNameSuffixed, |
||
314 | $seederName |
||
315 | )); |
||
316 | |||
317 | // Make sure the table/model exists |
||
318 | $model = $this->_loadSeederModel($seederName); |
||
319 | if ($model === false) { |
||
320 | $this->out(__("No model '%s' found , aborting.", $seederName)); |
||
321 | return; |
||
322 | } |
||
323 | |||
324 | // Execute the DynamicModelSeeder if the model exists |
||
325 | $seederTask = $this->Tasks->load('FakeSeeder.DynamicModelSeeder'); |
||
326 | } |
||
327 | // Copy given arguments & parameters |
||
328 | $seederTask->args =& $this->args; |
||
329 | $seederTask->params =& $this->params; |
||
330 | // Overwrite no-truncate to make ake sure a task does not truncates again |
||
331 | // when executed as a site |
||
332 | $seederTask->params['no-truncate'] = $noTruncate; |
||
333 | |||
334 | $seederTask->initialize(); |
||
335 | |||
336 | $seederTask->execute(); |
||
337 | } |
||
338 | |||
339 | /** |
||
340 | * Load a model to seed |
||
341 | * |
||
342 | * @param string $seederName The model to load |
||
343 | * @return |
||
344 | */ |
||
345 | protected function _loadSeederModel($seederName) { |
||
346 | return ClassRegistry::init($seederName); |
||
347 | } |
||
348 | } |
||
349 |
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.