Passed
Push — 5.x ( 71aac6...923942 )
by Jeroen
13:50 queued 13s
created

Seeder::seed()   B

Complexity

Conditions 9
Paths 1

Size

Total Lines 59
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 9.015

Importance

Changes 0
Metric Value
cc 9
eloc 33
nc 1
nop 1
dl 0
loc 59
ccs 33
cts 35
cp 0.9429
crap 9.015
rs 8.0555
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Elgg\Database;
4
5
use Elgg\Cli\Command;
6
use Elgg\Cli\Progress;
7
use Elgg\Database\Seeds\Seed;
8
use Elgg\EventsService;
9
use Elgg\I18n\Translator;
10
use Elgg\Invoker;
11
12
/**
13
 * Seeder class
14
 *
15
 * Populates the database with rows for testing
16
 *
17
 * @internal
18
 */
19
class Seeder {
20
21
	protected EventsService $events;
22
23
	protected Progress $progress;
24
	
25
	protected Invoker $invoker;
26
	
27
	protected Translator $translator;
28
29
	/**
30
	 * Seeder constructor.
31
	 *
32
	 * @param EventsService $events     Events service
33
	 * @param Progress      $progress   Progress helper
34
	 * @param Invoker       $invoker    Invoker service
35
	 * @param Translator    $translator Translator
36
	 */
37 4
	public function __construct(
38
		EventsService $events,
39
		Progress $progress,
40
		Invoker $invoker,
41
		Translator $translator
42
	) {
43 4
		$this->events = $events;
44 4
		$this->progress = $progress;
45 4
		$this->invoker = $invoker;
46 4
		$this->translator = $translator;
47
	}
48
49
	/**
50
	 * Load seed scripts
51
	 *
52
	 * @param array $options options for seeding
53
	 *                       - limit: the max number of entities to seed
54
	 *                       - image_folder: a global (local) image folder to use for image seeding (user/group profile icon, etc)
55
	 *                       - type: only seed this content type
56
	 *                       - create: create new entities (default: false)
57
	 *                       - create_since: lower bound creation time (default: now)
58
	 *                       - create_until: upper bound creation time (default: now)
59
	 *
60
	 * @return void
61
	 */
62 1
	public function seed(array $options = []): void {
63 1
		$this->invoker->call(ELGG_IGNORE_ACCESS | ELGG_SHOW_DISABLED_ENTITIES | ELGG_DISABLE_SYSTEM_LOG, function() use ($options) {
64 1
			$defaults = [
65 1
				'limit' => null,
66 1
				'image_folder' => elgg_get_config('seeder_local_image_folder'),
67 1
				'type' => '',
68 1
				'create' => false,
69 1
				'create_since' => 'now',
70 1
				'create_until' => 'now',
71 1
				'interactive' => true,
72 1
				'cli_command' => null,
73 1
			];
74 1
			$options = array_merge($defaults, $options);
75
76
			// set global configuration
77 1
			if ($options['image_folder'] !== $defaults['image_folder']) {
78 1
				elgg_set_config('seeder_local_image_folder', $options['image_folder']);
79
			}
80
			
81 1
			unset($options['image_folder']);
82
83
			// fetch CLI command
84 1
			$cli_command = $options['cli_command'];
85 1
			unset($options['cli_command']);
86
87
			// interactive mode
88 1
			$interactive = $options['interactive'] && empty($options['type']);
89 1
			unset($options['interactive']);
90
91 1
			$seeds = $this->getSeederClasses();
92 1
			foreach ($seeds as $seed) {
93 1
				$seed_options = $options;
94
95
				// check for type limitation
96 1
				if (!empty($seed_options['type']) && $seed_options['type'] !== $seed::getType()) {
97
					continue;
98
				}
99
100
				// check the seed limit
101 1
				$seed_options['limit'] = $seed_options['limit'] ?? $seed::getDefaultLimit();
102 1
				if ($interactive && $cli_command instanceof Command) {
103 1
					$seed_options['limit'] = (int) $cli_command->ask($this->translator->translate('cli:database:seed:ask:limit', [$seed::getType()]), $seed_options['limit'], false, false);
104
				}
105
106 1
				if ($seed_options['limit'] < 1) {
107
					// skip seeding
108
					continue;
109
				}
110
				
111
				/* @var $seeder Seed */
112 1
				$seeder = new $seed($seed_options);
113
114 1
				$progress_bar = $this->progress->start($seed, $seed_options['limit']);
115
116 1
				$seeder->setProgressBar($progress_bar);
117
118 1
				$seeder->seed();
119
120 1
				$this->progress->finish($progress_bar);
121
			}
122 1
		});
123
	}
124
125
	/**
126
	 * Remove all seeded entities
127
	 *
128
	 * @param array $options unseeding options
129
	 *                       - type: only unseed this content type
130
	 *
131
	 * @return void
132
	 */
133 1
	public function unseed(array $options = []): void {
134 1
		$this->invoker->call(ELGG_IGNORE_ACCESS | ELGG_SHOW_DISABLED_ENTITIES | ELGG_DISABLE_SYSTEM_LOG, function() use ($options) {
135 1
			$defaults = [
136 1
				'type' => '',
137 1
			];
138 1
			$options = array_merge($defaults, $options);
139
140 1
			$seeds = $this->getSeederClasses();
141
142 1
			foreach ($seeds as $seed) {
143
				// check for type limitation
144 1
				if (!empty($options['type']) && $options['type'] !== $seed::getType()) {
145
					continue;
146
				}
147
148
				/* @var $seeder Seed */
149 1
				$seeder = new $seed();
150
151 1
				$progress_bar = $this->progress->start($seed, $seeder->getCount());
152
153 1
				$seeder->setProgressBar($progress_bar);
154
155 1
				$seeder->unseed();
156
157 1
				$this->progress->finish($progress_bar);
158
			}
159 1
		});
160
	}
161
	
162
	/**
163
	 * Get the class names of all registered seeders (verified to work for seeding)
164
	 *
165
	 * @return string[]
166
	 */
167 3
	public function getSeederClasses(): array {
168 3
		$result = [];
169
		
170 3
		$seeds = $this->events->triggerResults('seeds', 'database', [], []);
171 3
		foreach ($seeds as $seed) {
172 3
			if (!class_exists($seed)) {
173
				elgg_log("Seeding class {$seed} not found", 'ERROR');
174
				continue;
175
			}
176
			
177 3
			if (!is_subclass_of($seed, Seed::class)) {
178
				elgg_log("Seeding class {$seed} does not extend " . Seed::class, 'ERROR');
179
				continue;
180
			}
181
			
182 3
			$result[] = $seed;
183
		}
184
		
185 3
		return $result;
186
	}
187
}
188