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 | use Faker\Factory; |
||
4 | use Faker\Generator; |
||
5 | |||
6 | App::uses('ShellModelTruncator', 'FakeSeeder.Lib'); |
||
7 | App::uses('ShellSeedProcessor', 'FakeSeeder.Lib'); |
||
8 | |||
9 | /** |
||
10 | * Seeder Task Base |
||
11 | * |
||
12 | * Base class for specific seeder tasks to base upon. |
||
13 | * Extending classes should be named after the model they seed + "SeederTask", |
||
14 | * e.g. "ArticleSeederTask". |
||
15 | * |
||
16 | * @todo Consider implementing a minimum amount of records |
||
17 | */ |
||
18 | abstract class SeederTaskBase extends AppShell { |
||
19 | |||
20 | /** |
||
21 | * Faker (generator) instance |
||
22 | * |
||
23 | * @var null|Generator |
||
24 | */ |
||
25 | public $faker = null; |
||
26 | |||
27 | /** |
||
28 | * The seeds to be seeded |
||
29 | * |
||
30 | * @var array |
||
31 | */ |
||
32 | public $seeds = array(); |
||
33 | |||
34 | /** |
||
35 | * The config key to read, 'FakeSeeder.$_configKey.valueKey' |
||
36 | * |
||
37 | * Does not need to be set, uses the name of the seeder class by default, e.g. "Article" for "ArticleSeederShell". |
||
38 | * |
||
39 | * @var string |
||
40 | */ |
||
41 | protected $_configKey = ''; |
||
42 | |||
43 | /** |
||
44 | * The name of the model to seed |
||
45 | * |
||
46 | * Does not need to be set, uses the name of the seeder class by default, e.g. "Article" for "ArticleSeederTask". |
||
47 | * |
||
48 | * @var string |
||
49 | */ |
||
50 | protected $_modelName = ''; |
||
51 | |||
52 | /** |
||
53 | * Models to truncate |
||
54 | * |
||
55 | * Does not need to be set, uses the name of the seeder class by default, e.g. "Article" for "ArticleSeederTask". |
||
56 | * |
||
57 | * @var array |
||
58 | */ |
||
59 | protected $_modelsToTruncate = array(); |
||
60 | |||
61 | /** |
||
62 | * Fixture records which are processed additionally and before the faked ones |
||
63 | * |
||
64 | * @var array |
||
65 | */ |
||
66 | protected $_fixtureRecords = array(); |
||
67 | |||
68 | /** |
||
69 | * The fields and their formatter |
||
70 | * |
||
71 | * @var array |
||
72 | */ |
||
73 | protected $_fieldFormatters = array(); |
||
74 | |||
75 | /** |
||
76 | * The seeding mode, optional. |
||
77 | * |
||
78 | * @var null|string |
||
79 | */ |
||
80 | protected $_mode = null; |
||
81 | |||
82 | /** |
||
83 | * The locale to use for Faker, optional |
||
84 | * |
||
85 | * @var null|int |
||
86 | */ |
||
87 | protected $_locale = null; |
||
88 | |||
89 | /** |
||
90 | * Set the minimum record count for a seeder task, null means no minimum. |
||
91 | * |
||
92 | * @var null|int |
||
93 | */ |
||
94 | protected $_minRecords = null; |
||
95 | |||
96 | /** |
||
97 | * Set the maximum record count for a seeder task, null means no maximum. |
||
98 | * |
||
99 | * @var null|int |
||
100 | */ |
||
101 | protected $_maxRecords = null; |
||
102 | |||
103 | /** |
||
104 | * The records to seed, optional |
||
105 | * |
||
106 | * @var null|int |
||
107 | */ |
||
108 | protected $_records = null; |
||
109 | |||
110 | /** |
||
111 | * Whether or not to validate the seeding data when saving, optional |
||
112 | * |
||
113 | * @var null|bool|string |
||
114 | * @see Model::saveAll() See for possible values for `validate`. |
||
115 | */ |
||
116 | protected $_validateSeeding = null; |
||
117 | |||
118 | /** |
||
119 | * The seeding number for Faker to use |
||
120 | * |
||
121 | * @var null|bool|int |
||
122 | * @see Generator::seed Faker's seed method. |
||
123 | */ |
||
124 | protected $_seedingNumber = null; |
||
125 | |||
126 | /** |
||
127 | * Whether or not to truncate the model , optional. |
||
128 | * |
||
129 | * @var null|bool |
||
130 | */ |
||
131 | protected $_noTruncate = null; |
||
132 | |||
133 | /** |
||
134 | * Task execution method |
||
135 | * |
||
136 | * @return void |
||
137 | */ |
||
138 | public function execute() { |
||
139 | $this->_getFaker(); |
||
140 | |||
141 | // Disable FK constraints |
||
142 | |||
143 | if ($this->getNoTruncate() === false) { |
||
144 | $this->_truncateModels(); |
||
145 | } |
||
146 | |||
147 | // Process the fixtures before the fake seeds |
||
148 | $seedProcessor = $this->_getSeedProcessor(); |
||
149 | $seedProcessor->processFixtures(); |
||
150 | $seedProcessor->sowSeeds(); |
||
151 | |||
152 | // Enable FK constraints, if necessary |
||
153 | } |
||
154 | |||
155 | /** |
||
156 | * Get a ShellSeedProcessor instance |
||
157 | * |
||
158 | * @return ShellSeedProcessor An instance of ShellSeedProcessor. |
||
159 | */ |
||
160 | protected function _getSeedProcessor() { |
||
161 | return new ShellSeedProcessor($this); |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * Get the Faker generator with the (optionally) configured locale |
||
166 | * |
||
167 | * @return Generator |
||
168 | */ |
||
169 | protected function _getFaker() { |
||
170 | $locale = $this->getLocale(); |
||
171 | $seed = $this->getSeedingNumber(); |
||
172 | |||
173 | $this->out(__('Create Faker instance with "%s" locale...', $locale), 1, Shell::VERBOSE); |
||
174 | |||
175 | $this->faker = Factory::create($locale); |
||
176 | if (!empty($seed)) { |
||
177 | $this->out(__("Use seed '%s' for Faker.", $seed), 1, Shell::VERBOSE); |
||
178 | $this->faker->seed($seed); |
||
179 | } |
||
180 | return $this->faker; |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * Truncate the models |
||
185 | * |
||
186 | * @return void |
||
187 | * @see ShellModelTruncator::truncateModels |
||
188 | */ |
||
189 | protected function _truncateModels() { |
||
190 | $modelsToTruncate = $this->getModelsToTruncate(); |
||
191 | |||
192 | $modelTruncator = $this->_getModelTruncator(); |
||
193 | $modelTruncator->truncateModels($modelsToTruncate); |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * Get an instance of the ShellModelTruncator, for delegating the model truncation |
||
198 | * |
||
199 | * @return ShellModelTruncator The shell model truncator instance. |
||
200 | */ |
||
201 | protected function _getModelTruncator() { |
||
202 | return new ShellModelTruncator($this); |
||
203 | } |
||
204 | |||
205 | /** |
||
206 | * Get models to truncate |
||
207 | * |
||
208 | * Returns the ones set in $_modelsToTruncate oo |
||
209 | * gets the model name based on the current |
||
210 | * seeder shell task name. |
||
211 | * |
||
212 | * @return array The models to truncate. |
||
213 | */ |
||
214 | public function getModelsToTruncate() { |
||
215 | if (!empty($this->_modelsToTruncate)) { |
||
216 | return $this->_modelsToTruncate; |
||
217 | } |
||
218 | |||
219 | $modelName = $this->getModelName(); |
||
220 | return array($modelName); |
||
221 | } |
||
222 | |||
223 | /** |
||
224 | * Set/get the fixture records |
||
225 | * |
||
226 | * @return array The fixture records. |
||
227 | */ |
||
228 | public function fixtureRecords() { |
||
229 | return $this->_fixtureRecords; |
||
230 | } |
||
231 | |||
232 | /** |
||
233 | * Set/get the field formatters |
||
234 | * |
||
235 | * @return array The formatters per field. |
||
236 | * @link https://github.com/fzaninotto/Faker#formatters |
||
237 | */ |
||
238 | abstract public function fieldFormatters(); |
||
239 | |||
240 | /** |
||
241 | * Merges the given field formatters with the exiting ones |
||
242 | * |
||
243 | * @param array $fieldFormatters The field formatters to merge. |
||
244 | * @return array The merged field formatters. |
||
245 | */ |
||
246 | protected function _mergeFieldFormatters($fieldFormatters) { |
||
247 | $this->_fieldFormatters = array_merge( |
||
248 | $this->_fieldFormatters, |
||
249 | $fieldFormatters |
||
250 | ); |
||
251 | return $this->_fieldFormatters; |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * Set/get state per record |
||
256 | * |
||
257 | * Can be overridden to return some state with data per record. |
||
258 | * |
||
259 | * @return array The state per record. |
||
260 | */ |
||
261 | public function recordState() { |
||
262 | return array(); |
||
263 | } |
||
264 | |||
265 | /** |
||
266 | * Get the model name |
||
267 | * |
||
268 | * @return string The model name. |
||
269 | */ |
||
270 | public function getModelName() { |
||
271 | $modelName = $this->_getSeederNamePrefix(); |
||
272 | if (!empty($this->_modelName)) { |
||
273 | $modelName = $this->_modelName; |
||
274 | } |
||
275 | |||
276 | return $modelName; |
||
277 | } |
||
278 | |||
279 | /** |
||
280 | * Get the seeding mode |
||
281 | * |
||
282 | * @return mixed The the seeding mode. |
||
283 | */ |
||
284 | public function getSeedingMode() { |
||
285 | $configKey = 'mode'; |
||
286 | $propertyName = '_mode'; |
||
287 | $defaultValue = 'manual'; |
||
288 | return $this->_getParameter($configKey, $propertyName, $defaultValue); |
||
289 | } |
||
290 | |||
291 | /** |
||
292 | * Get the locale to use for Faker |
||
293 | * |
||
294 | * @return string The locale for Faker. |
||
295 | */ |
||
296 | public function getLocale() { |
||
297 | $configKey = 'locale'; |
||
298 | $propertyName = '_locale'; |
||
299 | $defaultValue = 'en_US'; |
||
300 | return $this->_getParameter($configKey, $propertyName, $defaultValue); |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * Get record count to create |
||
305 | * |
||
306 | * @return mixed The amount of records to create. |
||
307 | */ |
||
308 | public function getRecordsCount() { |
||
309 | $configKey = 'records'; |
||
310 | $propertyName = '_records'; |
||
311 | $defaultValue = 10; |
||
312 | |||
313 | $records = $this->_getParameter($configKey, $propertyName, $defaultValue); |
||
314 | |||
315 | $records = $this->_enforceRecordMaximum($records); |
||
316 | $records = $this->_enforceRecordMinimum($records); |
||
317 | return $records; |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * Enforce the maximum amount of records to be seeded |
||
322 | * |
||
323 | * @param int $records The amount of records to check/reduce. |
||
324 | * @return int The enforced maximum amount of records. |
||
325 | */ |
||
326 | View Code Duplication | protected function _enforceRecordMaximum($records) { |
|
0 ignored issues
–
show
|
|||
327 | if (isset($this->_maxRecords) && $records > $this->_maxRecords) { |
||
328 | $this->out(__('%s records exceed the allowed maximum amount. Reducing it to %s records.', |
||
329 | $records, $this->_maxRecords), 1, Shell::VERBOSE); |
||
330 | |||
331 | return $this->_maxRecords; |
||
332 | } |
||
333 | |||
334 | return $records; |
||
335 | } |
||
336 | |||
337 | /** |
||
338 | * Enforce the minimum amount of records to be seeded |
||
339 | * |
||
340 | * @param int $records The amount of records to check/increase. |
||
341 | * @return int The enforced minimum amount of records. |
||
342 | */ |
||
343 | View Code Duplication | protected function _enforceRecordMinimum($records) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
344 | if (isset($this->_minRecords) && $records < $this->_minRecords) { |
||
345 | $this->out(__('%s records fall below the allowed minimum amount. Increasing it to %s records.', |
||
346 | $records, $this->_minRecords), 1, Shell::VERBOSE); |
||
347 | |||
348 | return $this->_minRecords; |
||
349 | } |
||
350 | |||
351 | return $records; |
||
352 | } |
||
353 | |||
354 | /** |
||
355 | * Get whether or not to validate seeding |
||
356 | * |
||
357 | * @return bool|string Whether or not to validate seeding. |
||
358 | * @see Model::saveAll() See for possible values for `validate`. |
||
359 | */ |
||
360 | public function getValidateSeeding() { |
||
361 | $configKey = 'validate'; |
||
362 | $propertyName = '_validateSeeding'; |
||
363 | $defaultValue = 'first'; |
||
364 | return $this->_getParameter($configKey, $propertyName, $defaultValue); |
||
365 | } |
||
366 | |||
367 | /** |
||
368 | * Get the seed number for Faker to use |
||
369 | * |
||
370 | * @return bool|string The seed number for Faker to use |
||
371 | * @see Generator::seed Faker's seed method. |
||
372 | */ |
||
373 | public function getSeedingNumber() { |
||
374 | $configKey = 'seed'; |
||
375 | $propertyName = '_seedingNumber'; |
||
376 | $defaultValue = null; |
||
377 | return $this->_getParameter($configKey, $propertyName, $defaultValue); |
||
378 | } |
||
379 | |||
380 | /** |
||
381 | * Get whether or not to truncate the model |
||
382 | * |
||
383 | * @return bool Whether or not to truncate the model |
||
384 | */ |
||
385 | public function getNoTruncate() { |
||
386 | $configKey = 'no-truncate'; |
||
387 | $propertyName = '_noTruncate'; |
||
388 | $defaultValue = false; |
||
389 | return $this->_getParameter($configKey, $propertyName, $defaultValue); |
||
390 | } |
||
391 | |||
392 | /** |
||
393 | * Get the value of a parameter |
||
394 | * |
||
395 | * Inspects |
||
396 | * 1. The CLI parameters, e.g. "--records" |
||
397 | * 2. The seeder specific configuration, e.g. "FakeSeeder.Article.records" |
||
398 | * 3. The general seeder configuration, e.g "FakeSeeder.records" |
||
399 | * 4. The seeder shell task class properties, e.g. "$_records" |
||
400 | * 4. Falls back to an optional default value |
||
401 | * |
||
402 | * @param string $configKey The name of the config key to check. |
||
403 | * @param string $propertyName The name of the class property to check. |
||
404 | * @param string $defaultValue The default value to use as fallback, optional. |
||
405 | * @return mixed The value of the parameter. |
||
406 | */ |
||
407 | protected function _getParameter($configKey, $propertyName, $defaultValue = null) { |
||
408 | // If given as CLI parameter, use that value |
||
409 | if ($this->params[$configKey]) { |
||
410 | $this->out(__('Parameter "%s" given through CLI parameter: "%s"', $configKey, $this->params[$configKey]), 1, Shell::VERBOSE); |
||
411 | return $this->params[$configKey]; |
||
412 | } |
||
413 | |||
414 | // If set in the seeder specific configuration, use that value |
||
415 | $localeConfigKey = sprintf('%s.%s', $this->_getSeederConfigKey(), $configKey); |
||
416 | View Code Duplication | if (Configure::check($localeConfigKey)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
417 | $this->out(__('Parameter "%s" configured in seeder specific configuration: "%s"', $configKey, Configure::read($localeConfigKey)), 1, Shell::VERBOSE); |
||
418 | return Configure::read($localeConfigKey); |
||
419 | } |
||
420 | |||
421 | // If set in the general FakeSeeder configuration, use that value |
||
422 | $localeConfigKey = sprintf('%s.%s', $this->_getSeederShellName(), $configKey); |
||
423 | View Code Duplication | if (Configure::check($localeConfigKey)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
424 | $this->out(__('Parameter "%s" configured in general seeder configuration: "%s"', $configKey, Configure::read($localeConfigKey)), 1, Shell::VERBOSE); |
||
425 | return Configure::read($localeConfigKey); |
||
426 | } |
||
427 | |||
428 | // If set in the seeder class, use that value |
||
429 | if ($this->{$propertyName}) { |
||
430 | $this->out(__('Parameter "%s" set in class: "%s"', $configKey, $this->{$propertyName}), 1, Shell::VERBOSE); |
||
431 | return $this->{$propertyName}; |
||
432 | } |
||
433 | |||
434 | $this->out(__('Parameter "%s" not given/configured, falling back to default "%s".', $configKey, $defaultValue), 1, Shell::VERBOSE); |
||
435 | // Otherwise use the default value as fallback |
||
436 | return $defaultValue; |
||
437 | } |
||
438 | |||
439 | /** |
||
440 | * Get the seeder specific config key |
||
441 | * |
||
442 | * Can be overridden by setting $_configKey |
||
443 | * |
||
444 | * @return string The seeder specific config key. |
||
445 | * @see ::$_configKey |
||
446 | */ |
||
447 | protected function _getSeederConfigKey() { |
||
448 | $configKey = $this->_getSeederNamePrefix(); |
||
449 | if (!empty($this->_configKey)) { |
||
450 | $configKey = $this->_configKey; |
||
451 | } |
||
452 | |||
453 | return sprintf('%s.%s', $this->_getSeederShellName(), $configKey); |
||
454 | } |
||
455 | |||
456 | /** |
||
457 | * Get the prefix of the seeder (class) shell task name |
||
458 | * |
||
459 | * "Article" for "ArticleSeederTask". |
||
460 | * |
||
461 | * @return string The prefix of the seeder (class) shell task name. |
||
462 | */ |
||
463 | protected function _getSeederNamePrefix() { |
||
464 | $className = get_class($this); |
||
465 | $seederName = substr($className, 0, -10); |
||
466 | return $seederName; |
||
467 | } |
||
468 | |||
469 | /** |
||
470 | * Get the name of the seeder shell |
||
471 | * |
||
472 | * @return string The name of the seeder shell. |
||
473 | * @todo Return actual name of the seeder shell (not task!). |
||
474 | */ |
||
475 | protected function _getSeederShellName() { |
||
476 | return 'FakeSeeder'; |
||
477 | } |
||
478 | } |
||
479 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.