Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 49 |
|
0.00% |
0 / 16 |
CRAP | |
0.00% |
0 / 1 |
state_helper | |
0.00% |
0 / 49 |
|
0.00% |
0 / 16 |
420 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
is_action_in_progress | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
new_provider | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
new_definition_value | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
update_type | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
storage_index | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
set_storage_index | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
remove_storage_index | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
set_remove_storage_index | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
file_index | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
set_file_index | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
storages | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
init | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
20 | |||
clear_state | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
load_state | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
save_state | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * |
4 | * This file is part of the phpBB Forum Software package. |
5 | * |
6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
7 | * @license GNU General Public License, version 2 (GPL-2.0) |
8 | * |
9 | * For full copyright and license information, please see |
10 | * the docs/CREDITS.txt file. |
11 | * |
12 | */ |
13 | |
14 | namespace phpbb\storage; |
15 | |
16 | use phpbb\config\config; |
17 | use phpbb\config\db_text; |
18 | use phpbb\di\service_collection; |
19 | use phpbb\request\request; |
20 | use phpbb\storage\exception\action_in_progress_exception; |
21 | use phpbb\storage\exception\no_action_in_progress_exception; |
22 | |
23 | class state_helper |
24 | { |
25 | /** @var config */ |
26 | protected $config; |
27 | |
28 | /** @var db_text $config_text */ |
29 | protected $config_text; |
30 | |
31 | /** @var service_collection */ |
32 | protected $provider_collection; |
33 | |
34 | /** |
35 | * @param config $config |
36 | * @param db_text $config_text |
37 | * @param service_collection $provider_collection |
38 | */ |
39 | public function __construct(config $config, db_text $config_text, service_collection $provider_collection) |
40 | { |
41 | $this->config = $config; |
42 | $this->config_text = $config_text; |
43 | $this->provider_collection = $provider_collection; |
44 | } |
45 | |
46 | /** |
47 | * Returns if there is an action in progress |
48 | * |
49 | * @return bool |
50 | */ |
51 | public function is_action_in_progress(): bool |
52 | { |
53 | return !empty(json_decode($this->config_text->get('storage_update_state'), true)); |
54 | } |
55 | |
56 | /** |
57 | * Get new provider for the specified storage |
58 | * |
59 | * @param string $storage_name |
60 | * |
61 | * @return string |
62 | */ |
63 | public function new_provider(string $storage_name): string |
64 | { |
65 | $state = $this->load_state(); |
66 | |
67 | return $state['storages'][$storage_name]['provider']; |
68 | } |
69 | |
70 | /** |
71 | * Get new definition value for the specified storage |
72 | * |
73 | * @param string $storage_name |
74 | * @param string $definition |
75 | * |
76 | * @return string |
77 | */ |
78 | public function new_definition_value(string $storage_name, string $definition): string |
79 | { |
80 | $state = $this->load_state(); |
81 | |
82 | return $state['storages'][$storage_name]['config'][$definition]; |
83 | } |
84 | |
85 | /** |
86 | * Get the update type |
87 | * |
88 | * @return update_type |
89 | */ |
90 | public function update_type(): update_type |
91 | { |
92 | $state = $this->load_state(); |
93 | |
94 | return update_type::from($state['update_type']); |
95 | } |
96 | |
97 | /** |
98 | * Get the current storage index |
99 | * |
100 | * @return int |
101 | */ |
102 | public function storage_index(): int |
103 | { |
104 | $state = $this->load_state(); |
105 | |
106 | return $state['storage_index']; |
107 | } |
108 | |
109 | /** |
110 | * Update the storage index |
111 | * |
112 | * @param int $storage_index |
113 | * |
114 | * @return void |
115 | */ |
116 | public function set_storage_index(int $storage_index): void |
117 | { |
118 | $state = $this->load_state(); |
119 | |
120 | $state['storage_index'] = $storage_index; |
121 | |
122 | $this->save_state($state); |
123 | } |
124 | |
125 | /** |
126 | * Get the current remove storage index |
127 | * |
128 | * @return int |
129 | */ |
130 | public function remove_storage_index(): int |
131 | { |
132 | $state = $this->load_state(); |
133 | |
134 | return $state['remove_storage_index']; |
135 | } |
136 | |
137 | /** |
138 | * Update the remove storage index |
139 | * |
140 | * @param int $storage_index |
141 | * |
142 | * @return void |
143 | */ |
144 | public function set_remove_storage_index(int $storage_index): void |
145 | { |
146 | $state = $this->load_state(); |
147 | |
148 | $state['remove_storage_index'] = $storage_index; |
149 | |
150 | $this->save_state($state); |
151 | } |
152 | |
153 | /** |
154 | * Get the file index |
155 | * |
156 | * @return int |
157 | */ |
158 | public function file_index(): int |
159 | { |
160 | $state = $this->load_state(); |
161 | |
162 | return $state['file_index']; |
163 | } |
164 | |
165 | /** |
166 | * Set the file index |
167 | * |
168 | * @param int $file_index |
169 | * @return void |
170 | */ |
171 | public function set_file_index(int $file_index): void |
172 | { |
173 | $state = $this->load_state(); |
174 | |
175 | $state['file_index'] = $file_index; |
176 | |
177 | $this->save_state($state); |
178 | } |
179 | |
180 | /** |
181 | * Get the storage names to be updated |
182 | * |
183 | * @return array |
184 | */ |
185 | public function storages(): array |
186 | { |
187 | $state = $this->load_state(); |
188 | |
189 | return array_keys($state['storages']); |
190 | } |
191 | |
192 | /** |
193 | * Start a indexing or delete process. |
194 | * |
195 | * @param update_type $update_type |
196 | * @param array $modified_storages |
197 | * @param request $request |
198 | * |
199 | * @throws action_in_progress_exception If there is an action in progress |
200 | * @throws \JsonException |
201 | */ |
202 | public function init(update_type $update_type, array $modified_storages, request $request): void |
203 | { |
204 | // Is not possible to start a new process when there is one already running |
205 | if ($this->is_action_in_progress()) |
206 | { |
207 | throw new action_in_progress_exception(); |
208 | } |
209 | |
210 | $state = [ |
211 | // Save the value of the checkbox, to remove all files from the |
212 | // old storage once they have been successfully moved |
213 | 'update_type' => $update_type->value, |
214 | 'storages' => [], |
215 | 'storage_index' => 0, |
216 | 'file_index' => 0, |
217 | 'remove_storage_index' => 0, |
218 | ]; |
219 | |
220 | // Save in the state the selected storages and their new configuration |
221 | foreach ($modified_storages as $storage_name) |
222 | { |
223 | $state['storages'][$storage_name] = []; |
224 | |
225 | $state['storages'][$storage_name]['provider'] = $request->variable([$storage_name, 'provider'], ''); |
226 | |
227 | $options = $this->provider_collection->get_by_class($request->variable([$storage_name, 'provider'], ''))->get_options(); |
228 | |
229 | foreach (array_keys($options) as $definition) |
230 | { |
231 | /** @psalm-suppress InvalidArrayOffset */ |
232 | $state['storages'][$storage_name]['config'][$definition] = $request->variable([$storage_name, $definition], ''); |
233 | } |
234 | } |
235 | |
236 | $this->save_state($state); |
237 | } |
238 | |
239 | /** |
240 | * Clear the state |
241 | * |
242 | * @throws \JsonException |
243 | */ |
244 | public function clear_state(): void |
245 | { |
246 | $this->save_state(); |
247 | } |
248 | |
249 | /** |
250 | * Load the state from the database |
251 | * |
252 | * @return array |
253 | * |
254 | * @throws no_action_in_progress_exception If there is no action in progress |
255 | */ |
256 | private function load_state(): array |
257 | { |
258 | // Is not possible to execute an action over state if is empty |
259 | if (!$this->is_action_in_progress()) |
260 | { |
261 | throw new no_action_in_progress_exception(); |
262 | } |
263 | |
264 | return json_decode($this->config_text->get('storage_update_state'), true) ?? []; |
265 | } |
266 | |
267 | /** |
268 | * Save the specified state in the database |
269 | * |
270 | * @param array $state |
271 | * |
272 | * @throws \JsonException |
273 | */ |
274 | private function save_state(array $state = []): void |
275 | { |
276 | $this->config_text->set('storage_update_state', json_encode($state, JSON_THROW_ON_ERROR)); |
277 | } |
278 | } |