Passed
Push — master ( 6b14e1...b6a74c )
by Daimona
12:28
created

TaskManager::runSubtasks()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
nc 1
nop 1
dl 0
loc 7
rs 10
c 1
b 0
f 0
1
<?php declare( strict_types=1 );
2
3
namespace BotRiconferme;
4
5
use BotRiconferme\Task\CloseOld;
6
use BotRiconferme\Task\StartNew;
7
use BotRiconferme\Task\StartVote;
8
use BotRiconferme\Task\Subtask\ArchivePages;
9
use BotRiconferme\Task\Subtask\ClosePages;
10
use BotRiconferme\Task\Subtask\CreatePages;
11
use BotRiconferme\Task\Subtask\FailedUpdates;
12
use BotRiconferme\Task\Subtask\OpenUpdates;
13
use BotRiconferme\Task\Subtask\SimpleUpdates;
14
use BotRiconferme\Task\Subtask\Subtask;
15
use BotRiconferme\Task\Subtask\UserNotice;
16
use BotRiconferme\Task\Task;
17
use BotRiconferme\Task\UpdateList;
18
use BotRiconferme\TaskHelper\TaskDataProvider;
19
use BotRiconferme\TaskHelper\TaskResult;
20
use BotRiconferme\Wiki\Page\PageBotList;
21
use BotRiconferme\Wiki\WikiGroup;
22
use Psr\Log\LoggerInterface;
23
24
/**
25
 * Wrapper for single tasks
26
 * @todo Reduce duplication with Task class and subclasses
27
 */
28
class TaskManager {
29
	// Run modes
30
	public const MODE_COMPLETE = 'full process';
31
	public const MODE_TASK = 'single task';
32
	public const MODE_SUBTASK = 'single subtask';
33
34
	/** @var string[] */
35
	private const TASKS_MAP = [
36
		'start-new' => StartNew::class,
37
		'close-old' => CloseOld::class,
38
		'update-list' => UpdateList::class,
39
		'start-vote' => StartVote::class
40
	];
41
	private const SUBTASKS_MAP = [
42
		'archive-pages' => ArchivePages::class,
43
		'close-pages' => ClosePages::class,
44
		'create-pages' => CreatePages::class,
45
		'failed-updates' => FailedUpdates::class,
46
		'simple-updates' => SimpleUpdates::class,
47
		'open-updates' => OpenUpdates::class,
48
		'user-notice' => UserNotice::class
49
	];
50
	/** @var TaskDataProvider */
51
	private $provider;
52
	/** @var LoggerInterface */
53
	private $logger;
54
	/** @var WikiGroup */
55
	private $wikiGroup;
56
	/** @var MessageProvider */
57
	private $messageProvider;
58
	/** @var PageBotList */
59
	private $pageBotList;
60
61
	/**
62
	 * @param LoggerInterface $logger
63
	 * @param WikiGroup $wikiGroup
64
	 * @param MessageProvider $mp
65
	 * @param PageBotList $pbl
66
	 */
67
	public function __construct(
68
		LoggerInterface $logger,
69
		WikiGroup $wikiGroup,
70
		MessageProvider $mp,
71
		PageBotList $pbl
72
	) {
73
		$this->logger = $logger;
74
		$this->wikiGroup = $wikiGroup;
75
		$this->messageProvider = $mp;
76
		$this->pageBotList = $pbl;
77
		$this->provider = new TaskDataProvider(
78
			$this->logger,
79
			$this->wikiGroup,
80
			$this->messageProvider,
81
			$pbl
82
		);
83
	}
84
85
	/**
86
	 * Main entry point
87
	 *
88
	 * @param string $mode One of the MODE_ constants
89
	 * @param string[] $tasks Only used in MODE_TASK and MODE_SUBTASK
90
	 * @return TaskResult
91
	 */
92
	public function run( string $mode, array $tasks = [] ) : TaskResult {
93
		if ( $mode === self::MODE_COMPLETE ) {
94
			return $this->runAllTasks();
95
		}
96
		if ( !$tasks ) {
97
			throw new \BadMethodCallException( 'MODE_TASK and MODE_SUBTASK need at least a (sub)task name.' );
98
		}
99
		return $mode === self::MODE_TASK ? $this->runTasks( $tasks ) : $this->runSubtasks( $tasks );
100
	}
101
102
	/**
103
	 * Run everything
104
	 *
105
	 * @return TaskResult
106
	 */
107
	protected function runAllTasks() : TaskResult {
108
		$orderedList = [
109
			'update-list',
110
			'start-new',
111
			'start-vote',
112
			'close-old'
113
		];
114
115
		return $this->runTasks( $orderedList );
116
	}
117
118
	/**
119
	 * Run $tasks in the given order
120
	 *
121
	 * @param array $tasks
122
	 * @return TaskResult
123
	 */
124
	private function runTasks( array $tasks ) : TaskResult {
125
		$res = new TaskResult( TaskResult::STATUS_GOOD );
126
		do {
127
			$res->merge( $this->runTask( current( $tasks ) ) );
128
		} while ( $res->isOK() && next( $tasks ) );
129
130
		return $res;
131
	}
132
133
	/**
134
	 * Run a single task
135
	 *
136
	 * @param string $name
137
	 * @return TaskResult
138
	 */
139
	protected function runTask( string $name ) : TaskResult {
140
		if ( !isset( self::TASKS_MAP[ $name ] ) ) {
141
			throw new \InvalidArgumentException( "'$name' is not a valid task." );
142
		}
143
144
		return $this->getTaskInstance( $name )->run();
145
	}
146
147
	/**
148
	 * Run $subtasks in the given order
149
	 *
150
	 * @param string[] $subtasks
151
	 * @return TaskResult
152
	 */
153
	private function runSubtasks( array $subtasks ) : TaskResult {
154
		$res = new TaskResult( TaskResult::STATUS_GOOD );
155
		do {
156
			$res->merge( $this->runSubtask( current( $subtasks ) ) );
157
		} while ( $res->isOK() && next( $subtasks ) );
158
159
		return $res;
160
	}
161
162
	/**
163
	 * Run a single subtask
164
	 *
165
	 * @param string $name
166
	 * @return TaskResult
167
	 */
168
	protected function runSubtask( string $name ) : TaskResult {
169
		if ( !isset( self::SUBTASKS_MAP[ $name ] ) ) {
170
			throw new \InvalidArgumentException( "'$name' is not a valid subtask." );
171
		}
172
173
		$class = self::SUBTASKS_MAP[ $name ];
174
		return $this->getSubtaskInstance( $class )->run();
175
	}
176
177
	/**
178
	 * Helper to make type inferencing easier
179
	 *
180
	 * @param string $name
181
	 * @return Task
182
	 */
183
	private function getTaskInstance( string $name ) : Task {
184
		$class = self::TASKS_MAP[ $name ];
185
		/** @var Task $ret */
186
		$ret = new $class(
187
			$this->logger,
188
			$this->wikiGroup,
189
			$this->provider,
190
			$this->messageProvider,
191
			$this->pageBotList
192
		);
193
		return $ret;
194
	}
195
196
	/**
197
	 * Helper to make type inferencing easier
198
	 *
199
	 * @param string $class
200
	 * @return Subtask
201
	 */
202
	private function getSubtaskInstance( string $class ) : Subtask {
203
		/** @var Subtask $ret */
204
		$ret = new $class(
205
			$this->logger,
206
			$this->wikiGroup,
207
			$this->provider,
208
			$this->messageProvider,
209
			$this->pageBotList
210
		);
211
		return $ret;
212
	}
213
}
214