Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
43.64% |
48 / 110 |
|
42.86% |
3 / 7 |
CRAP | |
0.00% |
0 / 1 |
check | |
43.64% |
48 / 110 |
|
42.86% |
3 / 7 |
203.08 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
configure | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
execute | |
50.00% |
8 / 16 |
|
0.00% |
0 / 1 |
13.12 | |||
check_ext | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
42 | |||
check_core | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
5 | |||
check_all_ext | |
0.00% |
0 / 35 |
|
0.00% |
0 / 1 |
56 | |||
display_versions | |
93.33% |
14 / 15 |
|
0.00% |
0 / 1 |
4.00 |
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\console\command\update; |
15 | |
16 | use phpbb\config\config; |
17 | use phpbb\exception\exception_interface; |
18 | use phpbb\language\language; |
19 | use phpbb\user; |
20 | use Symfony\Component\Console\Command\Command as symfony_command; |
21 | use Symfony\Component\Console\Input\InputInterface; |
22 | use Symfony\Component\Console\Input\InputArgument; |
23 | use Symfony\Component\Console\Input\InputOption; |
24 | use Symfony\Component\Console\Output\OutputInterface; |
25 | use Symfony\Component\Console\Style\SymfonyStyle; |
26 | use Symfony\Component\DependencyInjection\ContainerInterface; |
27 | |
28 | class check extends \phpbb\console\command\command |
29 | { |
30 | /** @var config */ |
31 | protected $config; |
32 | |
33 | /** @var ContainerInterface */ |
34 | protected $phpbb_container; |
35 | |
36 | /** |
37 | * @var language |
38 | */ |
39 | private $language; |
40 | |
41 | /** |
42 | * Construct method |
43 | */ |
44 | public function __construct(user $user, config $config, ContainerInterface $phpbb_container, language $language) |
45 | { |
46 | $this->config = $config; |
47 | $this->phpbb_container = $phpbb_container; |
48 | $this->language = $language; |
49 | |
50 | $this->language->add_lang(array('acp/common', 'acp/extensions')); |
51 | |
52 | parent::__construct($user); |
53 | } |
54 | |
55 | /** |
56 | * Configures the service. |
57 | * |
58 | * Sets the name and description of the command. |
59 | * |
60 | * @return void |
61 | */ |
62 | protected function configure() |
63 | { |
64 | $this |
65 | ->setName('update:check') |
66 | ->setDescription($this->language->lang('CLI_DESCRIPTION_UPDATE_CHECK')) |
67 | ->addArgument('ext-name', InputArgument::OPTIONAL, $this->language->lang('CLI_DESCRIPTION_UPDATE_CHECK_ARGUMENT_1')) |
68 | ->addOption('stability', null, InputOption::VALUE_REQUIRED, $this->language->lang('CLI_DESCRIPTION_UPDATE_CHECK_OPTION_STABILITY')) |
69 | ->addOption('cache', 'c', InputOption::VALUE_NONE, $this->language->lang('CLI_DESCRIPTION_UPDATE_CHECK_OPTION_CACHE')) |
70 | ; |
71 | } |
72 | |
73 | /** |
74 | * Executes the command. |
75 | * |
76 | * Checks if an update is available. |
77 | * If at least one is available, a message is printed and if verbose mode is set the list of possible updates is printed. |
78 | * If their is none, nothing is printed unless verbose mode is set. |
79 | * |
80 | * @param InputInterface $input Input stream, used to get the options. |
81 | * @param OutputInterface $output Output stream, used to print messages. |
82 | * @return int 0 if the board is up to date, 1 if it is not and 2 if an error occurred. |
83 | * @throws \RuntimeException |
84 | */ |
85 | protected function execute(InputInterface $input, OutputInterface $output) |
86 | { |
87 | $io = new SymfonyStyle($input, $output); |
88 | |
89 | $recheck = true; |
90 | if ($input->getOption('cache')) |
91 | { |
92 | $recheck = false; |
93 | } |
94 | |
95 | $stability = null; |
96 | if ($input->getOption('stability')) |
97 | { |
98 | $stability = $input->getOption('stability'); |
99 | if (!($stability == 'stable') && !($stability == 'unstable')) |
100 | { |
101 | $io->error($this->language->lang('CLI_ERROR_INVALID_STABILITY', $stability)); |
102 | return symfony_command::FAILURE; |
103 | } |
104 | } |
105 | |
106 | $ext_name = $input->getArgument('ext-name'); |
107 | if ($ext_name != null) |
108 | { |
109 | if ($ext_name == 'all') |
110 | { |
111 | return $this->check_all_ext($io, $stability, $recheck); |
112 | } |
113 | else |
114 | { |
115 | return $this->check_ext($input, $io, $stability, $recheck, $ext_name); |
116 | } |
117 | } |
118 | else |
119 | { |
120 | return $this->check_core($input, $io, $stability, $recheck); |
121 | } |
122 | } |
123 | |
124 | /** |
125 | * Check if a given extension is up to date |
126 | * |
127 | * @param InputInterface $input Input stream, used to get the options. |
128 | * @param SymfonyStyle $io IO handler, for formatted and unified IO |
129 | * @param string $stability Force a given stability |
130 | * @param bool $recheck Disallow the use of the cache |
131 | * @param string $ext_name The extension name |
132 | * @return int |
133 | */ |
134 | protected function check_ext(InputInterface $input, SymfonyStyle $io, $stability, $recheck, $ext_name) |
135 | { |
136 | try |
137 | { |
138 | $ext_manager = $this->phpbb_container->get('ext.manager'); |
139 | $md_manager = $ext_manager->create_extension_metadata_manager($ext_name); |
140 | $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); |
141 | |
142 | $metadata = $md_manager->get_metadata('all'); |
143 | if ($input->getOption('verbose')) |
144 | { |
145 | $io->title($md_manager->get_metadata('display-name')); |
146 | |
147 | $io->note($this->language->lang('CURRENT_VERSION') . $this->language->lang('COLON') . ' ' . $metadata['version']); |
148 | } |
149 | |
150 | if (!empty($updates_available)) |
151 | { |
152 | if ($input->getOption('verbose')) |
153 | { |
154 | $io->caution($this->language->lang('NOT_UP_TO_DATE', $metadata['name'])); |
155 | |
156 | $this->display_versions($io, $updates_available); |
157 | } |
158 | |
159 | return symfony_command::FAILURE; |
160 | } |
161 | else |
162 | { |
163 | if ($input->getOption('verbose')) |
164 | { |
165 | $io->success($this->language->lang('UPDATE_NOT_NEEDED')); |
166 | } |
167 | |
168 | return symfony_command::SUCCESS; |
169 | } |
170 | } |
171 | catch (\RuntimeException $e) |
172 | { |
173 | $io->error($this->language->lang('EXTENSION_NOT_INSTALLED', $ext_name)); |
174 | |
175 | return symfony_command::FAILURE; |
176 | } |
177 | } |
178 | |
179 | /** |
180 | * Check if the core is up to date |
181 | * |
182 | * @param InputInterface $input Input stream, used to get the options. |
183 | * @param SymfonyStyle $io IO handler, for formatted and unified IO |
184 | * @param string $stability Force a given stability |
185 | * @param bool $recheck Disallow the use of the cache |
186 | * @return int |
187 | */ |
188 | protected function check_core(InputInterface $input, SymfonyStyle $io, $stability, $recheck) |
189 | { |
190 | $version_helper = $this->phpbb_container->get('version_helper'); |
191 | $version_helper->force_stability($stability); |
192 | |
193 | $updates_available = $version_helper->get_suggested_updates($recheck); |
194 | |
195 | if ($input->getOption('verbose')) |
196 | { |
197 | $io->title('phpBB core'); |
198 | |
199 | $io->note( $this->language->lang('CURRENT_VERSION') . $this->language->lang('COLON') . ' ' . $this->config['version']); |
200 | } |
201 | |
202 | if (!empty($updates_available)) |
203 | { |
204 | $io->caution($this->language->lang('UPDATE_NEEDED')); |
205 | |
206 | if ($input->getOption('verbose')) |
207 | { |
208 | $this->display_versions($io, $updates_available); |
209 | } |
210 | |
211 | return symfony_command::FAILURE; |
212 | } |
213 | else |
214 | { |
215 | if ($input->getOption('verbose')) |
216 | { |
217 | $io->success($this->language->lang('UPDATE_NOT_NEEDED')); |
218 | } |
219 | |
220 | return symfony_command::SUCCESS; |
221 | } |
222 | } |
223 | |
224 | /** |
225 | * Check if all the available extensions are up to date |
226 | * |
227 | * @param SymfonyStyle $io IO handler, for formatted and unified IO |
228 | * @param string $stability Stability specifier string |
229 | * @param bool $recheck Disallow the use of the cache |
230 | * @return int |
231 | */ |
232 | protected function check_all_ext(SymfonyStyle $io, $stability, $recheck) |
233 | { |
234 | /** @var \phpbb\extension\manager $ext_manager */ |
235 | $ext_manager = $this->phpbb_container->get('ext.manager'); |
236 | |
237 | $rows = []; |
238 | |
239 | foreach ($ext_manager->all_available() as $ext_name => $ext_path) |
240 | { |
241 | $row = []; |
242 | $row[] = sprintf("<info>%s</info>", $ext_name); |
243 | $md_manager = $ext_manager->create_extension_metadata_manager($ext_name); |
244 | try |
245 | { |
246 | $metadata = $md_manager->get_metadata('all'); |
247 | if (isset($metadata['extra']['version-check'])) |
248 | { |
249 | try { |
250 | $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); |
251 | if (!empty($updates_available)) |
252 | { |
253 | $versions = array_map(function($entry) |
254 | { |
255 | return $entry['current']; |
256 | }, $updates_available); |
257 | |
258 | $row[] = sprintf("<comment>%s</comment>", $metadata['version']); |
259 | $row[] = implode(', ', $versions); |
260 | } |
261 | else |
262 | { |
263 | $row[] = sprintf("<info>%s</info>", $metadata['version']); |
264 | $row[] = ''; |
265 | } |
266 | } catch (\RuntimeException $e) { |
267 | $row[] = $metadata['version']; |
268 | $row[] = ''; |
269 | } |
270 | } |
271 | else |
272 | { |
273 | $row[] = $metadata['version']; |
274 | $row[] = ''; |
275 | } |
276 | } |
277 | catch (exception_interface $e) |
278 | { |
279 | $exception_message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters())); |
280 | $row[] = '<error>' . $exception_message . '</error>'; |
281 | } |
282 | catch (\RuntimeException $e) |
283 | { |
284 | $row[] = '<error>' . $e->getMessage() . '</error>'; |
285 | } |
286 | |
287 | $rows[] = $row; |
288 | } |
289 | |
290 | $io->table([ |
291 | $this->language->lang('EXTENSION_NAME'), |
292 | $this->language->lang('CURRENT_VERSION'), |
293 | $this->language->lang('LATEST_VERSION'), |
294 | ], $rows); |
295 | |
296 | return symfony_command::SUCCESS; |
297 | } |
298 | |
299 | /** |
300 | * Display the details of the available updates |
301 | * |
302 | * @param SymfonyStyle $io IO handler, for formatted and unified IO |
303 | * @param array $updates_available The list of the available updates |
304 | */ |
305 | protected function display_versions(SymfonyStyle $io, $updates_available) |
306 | { |
307 | $io->section($this->language->lang('UPDATES_AVAILABLE')); |
308 | |
309 | $rows = []; |
310 | foreach ($updates_available as $version_data) |
311 | { |
312 | $row = ['', '', '']; |
313 | $row[0] = $version_data['current']; |
314 | |
315 | if (isset($version_data['announcement'])) |
316 | { |
317 | $row[1] = $version_data['announcement']; |
318 | } |
319 | |
320 | if (isset($version_data['download'])) |
321 | { |
322 | $row[2] = $version_data['download']; |
323 | } |
324 | |
325 | $rows[] = $row; |
326 | } |
327 | |
328 | $io->table([ |
329 | $this->language->lang('VERSION'), |
330 | $this->language->lang('ANNOUNCEMENT_TOPIC'), |
331 | $this->language->lang('DOWNLOAD_LATEST'), |
332 | ], $rows); |
333 | } |
334 | } |