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): int |
| 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 | } |