Passed
Push — master ( 59f1bb...5a2178 )
by Daimona
01:35
created

TaskManager::runAllTasks()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 9
rs 10
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';
31
	public const MODE_TASK = 'task';
32
	public const MODE_SUBTASK = '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
	private const FULL_RUN_ORDERED = [
51
		'update-list',
52
		'start-new',
53
		'start-vote',
54
		'close-old'
55
	];
56
	/** @var TaskDataProvider */
57
	private $provider;
58
	/** @var LoggerInterface */
59
	private $logger;
60
	/** @var WikiGroup */
61
	private $wikiGroup;
62
	/** @var MessageProvider */
63
	private $messageProvider;
64
	/** @var PageBotList */
65
	private $pageBotList;
66
67
	/**
68
	 * @param LoggerInterface $logger
69
	 * @param WikiGroup $wikiGroup
70
	 * @param MessageProvider $mp
71
	 * @param PageBotList $pbl
72
	 */
73
	public function __construct(
74
		LoggerInterface $logger,
75
		WikiGroup $wikiGroup,
76
		MessageProvider $mp,
77
		PageBotList $pbl
78
	) {
79
		$this->logger = $logger;
80
		$this->wikiGroup = $wikiGroup;
81
		$this->messageProvider = $mp;
82
		$this->pageBotList = $pbl;
83
		$this->provider = new TaskDataProvider(
84
			$this->logger,
85
			$this->wikiGroup,
86
			$this->messageProvider,
87
			$pbl
88
		);
89
	}
90
91
	/**
92
	 * Main entry point
93
	 *
94
	 * @param string $mode One of the MODE_ constants
95
	 * @param string[] $tasks Only used in MODE_TASK and MODE_SUBTASK
96
	 * @return TaskResult
97
	 */
98
	public function run( string $mode, array $tasks = [] ) : TaskResult {
99
		if ( $mode === self::MODE_COMPLETE ) {
100
			$tasks = self::FULL_RUN_ORDERED;
101
		}
102
		if ( !$tasks ) {
103
			throw new \BadMethodCallException( 'MODE_TASK and MODE_SUBTASK need at least a (sub)task name.' );
104
		}
105
		return $mode === self::MODE_TASK ? $this->runTasks( $tasks ) : $this->runSubtasks( $tasks );
106
	}
107
108
	/**
109
	 * Run $tasks in the given order
110
	 *
111
	 * @param string[] $tasks
112
	 * @return TaskResult
113
	 */
114
	private function runTasks( array $tasks ) : TaskResult {
115
		$res = new TaskResult( TaskResult::STATUS_GOOD );
116
		do {
117
			$res->merge( $this->runTask( current( $tasks ) ) );
118
		} while ( $res->isOK() && next( $tasks ) );
119
120
		return $res;
121
	}
122
123
	/**
124
	 * Run a single task
125
	 *
126
	 * @param string $name
127
	 * @return TaskResult
128
	 */
129
	protected function runTask( string $name ) : TaskResult {
130
		if ( !isset( self::TASKS_MAP[ $name ] ) ) {
131
			throw new \InvalidArgumentException( "'$name' is not a valid task." );
132
		}
133
134
		return $this->getTaskInstance( $name )->run();
135
	}
136
137
	/**
138
	 * Run $subtasks in the given order
139
	 *
140
	 * @param string[] $subtasks
141
	 * @return TaskResult
142
	 */
143
	private function runSubtasks( array $subtasks ) : TaskResult {
144
		$res = new TaskResult( TaskResult::STATUS_GOOD );
145
		do {
146
			$res->merge( $this->runSubtask( current( $subtasks ) ) );
147
		} while ( $res->isOK() && next( $subtasks ) );
148
149
		return $res;
150
	}
151
152
	/**
153
	 * Run a single subtask
154
	 *
155
	 * @param string $name
156
	 * @return TaskResult
157
	 */
158
	protected function runSubtask( string $name ) : TaskResult {
159
		if ( !isset( self::SUBTASKS_MAP[ $name ] ) ) {
160
			throw new \InvalidArgumentException( "'$name' is not a valid subtask." );
161
		}
162
163
		$class = self::SUBTASKS_MAP[ $name ];
164
		return $this->getSubtaskInstance( $class )->run();
165
	}
166
167
	/**
168
	 * Helper to make type inferencing easier
169
	 *
170
	 * @param string $name
171
	 * @return Task
172
	 */
173
	private function getTaskInstance( string $name ) : Task {
174
		$class = self::TASKS_MAP[ $name ];
175
		return new $class(
176
			$this->logger,
177
			$this->wikiGroup,
178
			$this->provider,
179
			$this->messageProvider,
180
			$this->pageBotList
181
		);
182
	}
183
184
	/**
185
	 * Helper to make type inferencing easier
186
	 *
187
	 * @param string $class
188
	 * @return Subtask
189
	 */
190
	private function getSubtaskInstance( string $class ) : Subtask {
191
		return new $class(
192
			$this->logger,
193
			$this->wikiGroup,
194
			$this->provider,
195
			$this->messageProvider,
196
			$this->pageBotList
197
		);
198
	}
199
}
200