From 74cd513a8892285032a248322e3ce52b19645075 Mon Sep 17 00:00:00 2001
From: Matt Friedman <maf675@gmail.com>
Date: Wed, 7 Dec 2016 10:13:09 -0800
Subject: [PATCH 1/5] [ticket/14895] CLI reparser:list should display proper
 list

PHPBB3-14895
---
 phpBB/language/en/cli.php                         | 1 +
 phpBB/phpbb/console/command/reparser/list_all.php | 8 ++++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/phpBB/language/en/cli.php b/phpBB/language/en/cli.php
index 6e86c75ec0..9940609364 100644
--- a/phpBB/language/en/cli.php
+++ b/phpBB/language/en/cli.php
@@ -68,6 +68,7 @@ $lang = array_merge($lang, array(
 	'CLI_DESCRIPTION_PURGE_EXTENSION'			=> 'Purges the specified extension.',
 
 	'CLI_DESCRIPTION_REPARSER_LIST'						=> 'Lists the types of text that can be reparsed.',
+	'CLI_DESCRIPTION_REPARSER_AVAILABLE'				=> 'Available reparsers:',
 	'CLI_DESCRIPTION_REPARSER_REPARSE'					=> 'Reparses stored text with the current text_formatter services.',
 	'CLI_DESCRIPTION_REPARSER_REPARSE_ARG_1'			=> 'Type of text to reparse. Leave blank to reparse everything.',
 	'CLI_DESCRIPTION_REPARSER_REPARSE_OPT_DRY_RUN'		=> 'Do not save any changes; just print what would happen',
diff --git a/phpBB/phpbb/console/command/reparser/list_all.php b/phpBB/phpbb/console/command/reparser/list_all.php
index e42c3ac782..7dd0571975 100644
--- a/phpBB/phpbb/console/command/reparser/list_all.php
+++ b/phpBB/phpbb/console/command/reparser/list_all.php
@@ -54,7 +54,7 @@ class list_all extends \phpbb\console\command\command
 	}
 
 	/**
-	* Executes the command reparser:reparse
+	* Executes the command reparser:list
 	*
 	* @param InputInterface $input
 	* @param OutputInterface $output
@@ -62,7 +62,11 @@ class list_all extends \phpbb\console\command\command
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
-		$output->writeln('<info>' . implode(', ', $this->reparser_names) . '</info>');
+		$output->writeln('<info>' . $this->user->lang('CLI_DESCRIPTION_REPARSER_AVAILABLE') . '</info>');
+		foreach ($this->reparser_names as $reparser_name)
+		{
+			$output->writeln($reparser_name);
+		}
 
 		return 0;
 	}

From d275fefc69bae24f547802d824607c9a054ff6d2 Mon Sep 17 00:00:00 2001
From: Matt Friedman <maf675@gmail.com>
Date: Wed, 7 Dec 2016 23:49:54 -0800
Subject: [PATCH 2/5] [ticket/14895] Use SymfonyIO styling

PHPBB3-14895
---
 phpBB/phpbb/console/command/reparser/list_all.php | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/phpBB/phpbb/console/command/reparser/list_all.php b/phpBB/phpbb/console/command/reparser/list_all.php
index 7dd0571975..028468649d 100644
--- a/phpBB/phpbb/console/command/reparser/list_all.php
+++ b/phpBB/phpbb/console/command/reparser/list_all.php
@@ -15,6 +15,7 @@ namespace phpbb\console\command\reparser;
 
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class list_all extends \phpbb\console\command\command
 {
@@ -62,11 +63,9 @@ class list_all extends \phpbb\console\command\command
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
-		$output->writeln('<info>' . $this->user->lang('CLI_DESCRIPTION_REPARSER_AVAILABLE') . '</info>');
-		foreach ($this->reparser_names as $reparser_name)
-		{
-			$output->writeln($reparser_name);
-		}
+		$io = new SymfonyStyle($input, $output);
+		$io->section($this->user->lang('CLI_DESCRIPTION_REPARSER_AVAILABLE'));
+		$io->listing($this->reparser_names);
 
 		return 0;
 	}

From b17fa7dfa588fc191f4ed268b88dcaec40294acb Mon Sep 17 00:00:00 2001
From: Matt Friedman <maf675@gmail.com>
Date: Thu, 8 Dec 2016 14:24:02 -0800
Subject: [PATCH 3/5] [ticket/14895] Use SymfonyStyle in all CLI

PHPBB3-14895
---
 phpBB/phpbb/console/command/cache/purge.php   |  4 +-
 phpBB/phpbb/console/command/config/delete.php |  7 +++-
 phpBB/phpbb/console/command/config/get.php    |  5 ++-
 .../console/command/config/increment.php      |  5 ++-
 phpBB/phpbb/console/command/config/set.php    |  5 ++-
 .../console/command/config/set_atomic.php     |  7 +++-
 .../phpbb/console/command/cron/cron_list.php  | 39 ++++++-------------
 .../phpbb/console/command/db/list_command.php | 30 ++++++++------
 phpBB/phpbb/console/command/db/migrate.php    |  7 +++-
 phpBB/phpbb/console/command/db/revert.php     | 10 +++--
 .../console/command/extension/disable.php     |  7 +++-
 .../console/command/extension/enable.php      |  7 +++-
 .../phpbb/console/command/extension/purge.php |  7 +++-
 .../phpbb/console/command/extension/show.php  | 28 +++++--------
 .../command/fixup/recalculate_email_hash.php  | 15 +++----
 15 files changed, 100 insertions(+), 83 deletions(-)

diff --git a/phpBB/phpbb/console/command/cache/purge.php b/phpBB/phpbb/console/command/cache/purge.php
index d0c2ef6f72..1da97624f5 100644
--- a/phpBB/phpbb/console/command/cache/purge.php
+++ b/phpBB/phpbb/console/command/cache/purge.php
@@ -14,6 +14,7 @@ namespace phpbb\console\command\cache;
 
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class purge extends \phpbb\console\command\command
 {
@@ -84,6 +85,7 @@ class purge extends \phpbb\console\command\command
 
 		$this->log->add('admin', ANONYMOUS, '', 'LOG_PURGE_CACHE', time(), array());
 
-		$output->writeln($this->user->lang('PURGE_CACHE_SUCCESS'));
+		$io = new SymfonyStyle($input, $output);
+		$io->success($this->user->lang('PURGE_CACHE_SUCCESS'));
 	}
 }
diff --git a/phpBB/phpbb/console/command/config/delete.php b/phpBB/phpbb/console/command/config/delete.php
index efd276d7e3..a1ccefe286 100644
--- a/phpBB/phpbb/console/command/config/delete.php
+++ b/phpBB/phpbb/console/command/config/delete.php
@@ -15,6 +15,7 @@ namespace phpbb\console\command\config;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class delete extends command
 {
@@ -47,17 +48,19 @@ class delete extends command
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$key = $input->getArgument('key');
 
 		if (isset($this->config[$key]))
 		{
 			$this->config->delete($key);
 
-			$output->writeln('<info>' . $this->user->lang('CLI_CONFIG_DELETE_SUCCESS', $key) . '</info>');
+			$io->success($this->user->lang('CLI_CONFIG_DELETE_SUCCESS', $key));
 		}
 		else
 		{
-			$output->writeln('<error>' . $this->user->lang('CLI_CONFIG_NOT_EXISTS', $key) . '</error>');
+			$io->error($this->user->lang('CLI_CONFIG_NOT_EXISTS', $key));
 		}
 	}
 }
diff --git a/phpBB/phpbb/console/command/config/get.php b/phpBB/phpbb/console/command/config/get.php
index 9c03b49a3d..b2b824dd12 100644
--- a/phpBB/phpbb/console/command/config/get.php
+++ b/phpBB/phpbb/console/command/config/get.php
@@ -16,6 +16,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class get extends command
 {
@@ -54,6 +55,8 @@ class get extends command
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$key = $input->getArgument('key');
 
 		if (isset($this->config[$key]) && $input->getOption('no-newline'))
@@ -66,7 +69,7 @@ class get extends command
 		}
 		else
 		{
-			$output->writeln('<error>' . $this->user->lang('CLI_CONFIG_NOT_EXISTS', $key) . '</error>');
+			$io->error($this->user->lang('CLI_CONFIG_NOT_EXISTS', $key));
 		}
 	}
 }
diff --git a/phpBB/phpbb/console/command/config/increment.php b/phpBB/phpbb/console/command/config/increment.php
index b4d7438b66..8b3acc1620 100644
--- a/phpBB/phpbb/console/command/config/increment.php
+++ b/phpBB/phpbb/console/command/config/increment.php
@@ -16,6 +16,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class increment extends command
 {
@@ -59,12 +60,14 @@ class increment extends command
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$key = $input->getArgument('key');
 		$increment = $input->getArgument('increment');
 		$use_cache = !$input->getOption('dynamic');
 
 		$this->config->increment($key, $increment, $use_cache);
 
-		$output->writeln('<info>' . $this->user->lang('CLI_CONFIG_INCREMENT_SUCCESS', $key) . '</info>');
+		$io->success($this->user->lang('CLI_CONFIG_INCREMENT_SUCCESS', $key));
 	}
 }
diff --git a/phpBB/phpbb/console/command/config/set.php b/phpBB/phpbb/console/command/config/set.php
index 695de31013..889fb630c6 100644
--- a/phpBB/phpbb/console/command/config/set.php
+++ b/phpBB/phpbb/console/command/config/set.php
@@ -16,6 +16,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class set extends command
 {
@@ -59,12 +60,14 @@ class set extends command
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$key = $input->getArgument('key');
 		$value = $input->getArgument('value');
 		$use_cache = !$input->getOption('dynamic');
 
 		$this->config->set($key, $value, $use_cache);
 
-		$output->writeln('<info>' . $this->user->lang('CLI_CONFIG_SET_SUCCESS', $key) . '</info>');
+		$io->success($this->user->lang('CLI_CONFIG_SET_SUCCESS', $key));
 	}
 }
diff --git a/phpBB/phpbb/console/command/config/set_atomic.php b/phpBB/phpbb/console/command/config/set_atomic.php
index e8c69a0885..475d8a9271 100644
--- a/phpBB/phpbb/console/command/config/set_atomic.php
+++ b/phpBB/phpbb/console/command/config/set_atomic.php
@@ -16,6 +16,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class set_atomic extends command
 {
@@ -65,6 +66,8 @@ class set_atomic extends command
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$key = $input->getArgument('key');
 		$old_value = $input->getArgument('old');
 		$new_value = $input->getArgument('new');
@@ -72,12 +75,12 @@ class set_atomic extends command
 
 		if ($this->config->set_atomic($key, $old_value, $new_value, $use_cache))
 		{
-			$output->writeln('<info>' . $this->user->lang('CLI_CONFIG_SET_SUCCESS', $key) . '</info>');
+			$io->success($this->user->lang('CLI_CONFIG_SET_SUCCESS', $key));
 			return 0;
 		}
 		else
 		{
-			$output->writeln('<error>' . $this->user->lang('CLI_CONFIG_SET_FAILURE', $key) . '</error>');
+			$io->error($this->user->lang('CLI_CONFIG_SET_FAILURE', $key));
 			return 1;
 		}
 	}
diff --git a/phpBB/phpbb/console/command/cron/cron_list.php b/phpBB/phpbb/console/command/cron/cron_list.php
index c515fd9e80..0618cee4db 100644
--- a/phpBB/phpbb/console/command/cron/cron_list.php
+++ b/phpBB/phpbb/console/command/cron/cron_list.php
@@ -14,6 +14,7 @@ namespace phpbb\console\command\cron;
 
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class cron_list extends \phpbb\console\command\command
 {
@@ -55,57 +56,39 @@ class cron_list extends \phpbb\console\command\command
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$tasks = $this->cron_manager->get_tasks();
 
 		if (empty($tasks))
 		{
-			$output->writeln($this->user->lang('CRON_NO_TASKS'));
+			$io->error($this->user->lang('CRON_NO_TASKS'));
 			return;
 		}
 
-		$ready_tasks = array();
-		$not_ready_tasks = array();
+		$ready_tasks = $not_ready_tasks = array();
 		foreach ($tasks as $task)
 		{
 			if ($task->is_ready())
 			{
-				$ready_tasks[] = $task;
+				$ready_tasks[] = $task->get_name();
 			}
 			else
 			{
-				$not_ready_tasks[] = $task;
+				$not_ready_tasks[] = $task->get_name();
 			}
 		}
 
 		if (!empty($ready_tasks))
 		{
-			$output->writeln('<info>' . $this->user->lang('TASKS_READY') . '</info>');
-			$this->print_tasks_names($ready_tasks, $output);
-		}
-
-		if (!empty($ready_tasks) && !empty($not_ready_tasks))
-		{
-			$output->writeln('');
+			$io->section($this->user->lang('TASKS_READY'));
+			$io->listing($ready_tasks);
 		}
 
 		if (!empty($not_ready_tasks))
 		{
-			$output->writeln('<info>' . $this->user->lang('TASKS_NOT_READY') . '</info>');
-			$this->print_tasks_names($not_ready_tasks, $output);
-		}
-	}
-
-	/**
-	* Print a list of cron jobs
-	*
-	* @param array				$tasks A list of task to display
-	* @param OutputInterface	$output An OutputInterface instance
-	*/
-	protected function print_tasks_names(array $tasks, OutputInterface $output)
-	{
-		foreach ($tasks as $task)
-		{
-			$output->writeln($task->get_name());
+			$io->section($this->user->lang('TASKS_NOT_READY'));
+			$io->listing($not_ready_tasks);
 		}
 	}
 }
diff --git a/phpBB/phpbb/console/command/db/list_command.php b/phpBB/phpbb/console/command/db/list_command.php
index 708107b592..77f26dd786 100644
--- a/phpBB/phpbb/console/command/db/list_command.php
+++ b/phpBB/phpbb/console/command/db/list_command.php
@@ -15,6 +15,7 @@ namespace phpbb\console\command\db;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class list_command extends \phpbb\console\command\db\migration_command
 {
@@ -34,6 +35,8 @@ class list_command extends \phpbb\console\command\db\migration_command
 
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$show_installed = !$input->getOption('available');
 		$installed = $available = array();
 
@@ -51,23 +54,28 @@ class list_command extends \phpbb\console\command\db\migration_command
 
 		if ($show_installed)
 		{
-			$output->writeln('<info>' . $this->user->lang('CLI_MIGRATIONS_INSTALLED') . $this->user->lang('COLON') . '</info>');
-			$output->writeln($installed);
+			$io->section($this->user->lang('CLI_MIGRATIONS_INSTALLED'));
 
-			if (empty($installed))
+			if (!empty($installed))
 			{
-				$output->writeln($this->user->lang('CLI_MIGRATIONS_EMPTY'));
+				$io->listing($installed);
+			}
+			else
+			{
+				$io->text($this->user->lang('CLI_MIGRATIONS_EMPTY'));
+				$io->newLine();
 			}
-
-			$output->writeln('');
 		}
 
-		$output->writeln('<info>' . $this->user->lang('CLI_MIGRATIONS_AVAILABLE') . $this->user->lang('COLON') . '</info>');
-		$output->writeln($available);
-
-		if (empty($available))
+		$io->section($this->user->lang('CLI_MIGRATIONS_AVAILABLE'));
+		if (!empty($available))
 		{
-			$output->writeln($this->user->lang('CLI_MIGRATIONS_EMPTY'));
+			$io->listing($available);
+		}
+		else
+		{
+			$io->text($this->user->lang('CLI_MIGRATIONS_EMPTY'));
+			$io->newLine();
 		}
 	}
 }
diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php
index ae4211f7be..f2cc9142a6 100644
--- a/phpBB/phpbb/console/command/db/migrate.php
+++ b/phpBB/phpbb/console/command/db/migrate.php
@@ -15,6 +15,7 @@ namespace phpbb\console\command\db;
 use phpbb\db\output_handler\log_wrapper_migrator_output_handler;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class migrate extends \phpbb\console\command\db\migration_command
 {
@@ -50,6 +51,8 @@ class migrate extends \phpbb\console\command\db\migration_command
 
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$this->migrator->set_output_handler(new log_wrapper_migrator_output_handler($this->language, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem));
 
 		$this->migrator->create_migrations_table();
@@ -66,7 +69,7 @@ class migrate extends \phpbb\console\command\db\migration_command
 			}
 			catch (\phpbb\db\migration\exception $e)
 			{
-				$output->writeln('<error>' . $e->getLocalisedMessage($this->user) . '</error>');
+				$io->error($e->getLocalisedMessage($this->user));
 				$this->finalise_update();
 				return 1;
 			}
@@ -78,6 +81,6 @@ class migrate extends \phpbb\console\command\db\migration_command
 		}
 
 		$this->finalise_update();
-		$output->writeln($this->user->lang['DATABASE_UPDATE_COMPLETE']);
+		$io->success($this->language->lang('INLINE_UPDATE_SUCCESSFUL'));
 	}
 }
diff --git a/phpBB/phpbb/console/command/db/revert.php b/phpBB/phpbb/console/command/db/revert.php
index 3fa2e17515..7977afc319 100644
--- a/phpBB/phpbb/console/command/db/revert.php
+++ b/phpBB/phpbb/console/command/db/revert.php
@@ -16,6 +16,7 @@ use phpbb\db\output_handler\log_wrapper_migrator_output_handler;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class revert extends \phpbb\console\command\db\migration_command
 {
@@ -52,6 +53,8 @@ class revert extends \phpbb\console\command\db\migration_command
 
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$name = str_replace('/', '\\', $input->getArgument('name'));
 
 		$this->migrator->set_output_handler(new log_wrapper_migrator_output_handler($this->language, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem));
@@ -60,12 +63,12 @@ class revert extends \phpbb\console\command\db\migration_command
 
 		if (!in_array($name, $this->load_migrations()))
 		{
-			$output->writeln('<error>' . $this->user->lang('MIGRATION_NOT_VALID', $name) . '</error>');
+			$io->error($this->language->lang('MIGRATION_NOT_VALID', $name));
 			return 1;
 		}
 		else if ($this->migrator->migration_state($name) === false)
 		{
-			$output->writeln('<error>' . $this->user->lang('MIGRATION_NOT_INSTALLED', $name) . '</error>');
+			$io->error($this->language->lang('MIGRATION_NOT_INSTALLED', $name));
 			return 1;
 		}
 
@@ -78,11 +81,12 @@ class revert extends \phpbb\console\command\db\migration_command
 		}
 		catch (\phpbb\db\migration\exception $e)
 		{
-			$output->writeln('<error>' . $e->getLocalisedMessage($this->user) . '</error>');
+			$io->error($e->getLocalisedMessage($this->user));
 			$this->finalise_update();
 			return 1;
 		}
 
 		$this->finalise_update();
+		$io->success($this->language->lang('INLINE_UPDATE_SUCCESSFUL'));
 	}
 }
diff --git a/phpBB/phpbb/console/command/extension/disable.php b/phpBB/phpbb/console/command/extension/disable.php
index 1eee16cbd9..d022755753 100644
--- a/phpBB/phpbb/console/command/extension/disable.php
+++ b/phpBB/phpbb/console/command/extension/disable.php
@@ -15,6 +15,7 @@ namespace phpbb\console\command\extension;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class disable extends command
 {
@@ -33,19 +34,21 @@ class disable extends command
 
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$name = $input->getArgument('extension-name');
 		$this->manager->disable($name);
 		$this->manager->load_extensions();
 
 		if ($this->manager->is_enabled($name))
 		{
-			$output->writeln('<error>' . $this->user->lang('CLI_EXTENSION_DISABLE_FAILURE', $name) . '</error>');
+			$io->error($this->user->lang('CLI_EXTENSION_DISABLE_FAILURE', $name));
 			return 1;
 		}
 		else
 		{
 			$this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_DISABLE', time(), array($name));
-			$output->writeln('<info>' . $this->user->lang('CLI_EXTENSION_DISABLE_SUCCESS', $name) . '</info>');
+			$io->success($this->user->lang('CLI_EXTENSION_DISABLE_SUCCESS', $name));
 			return 0;
 		}
 	}
diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php
index 59ff11e9b7..14077d688b 100644
--- a/phpBB/phpbb/console/command/extension/enable.php
+++ b/phpBB/phpbb/console/command/extension/enable.php
@@ -15,6 +15,7 @@ namespace phpbb\console\command\extension;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class enable extends command
 {
@@ -33,6 +34,8 @@ class enable extends command
 
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$name = $input->getArgument('extension-name');
 		$this->manager->enable($name);
 		$this->manager->load_extensions();
@@ -40,12 +43,12 @@ class enable extends command
 		if ($this->manager->is_enabled($name))
 		{
 			$this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($name));
-			$output->writeln('<info>' . $this->user->lang('CLI_EXTENSION_ENABLE_SUCCESS', $name) . '</info>');
+			$io->success($this->user->lang('CLI_EXTENSION_ENABLE_SUCCESS', $name));
 			return 0;
 		}
 		else
 		{
-			$output->writeln('<error>' . $this->user->lang('CLI_EXTENSION_ENABLE_FAILURE', $name) . '</error>');
+			$io->error($this->user->lang('CLI_EXTENSION_ENABLE_FAILURE', $name));
 			return 1;
 		}
 	}
diff --git a/phpBB/phpbb/console/command/extension/purge.php b/phpBB/phpbb/console/command/extension/purge.php
index 517e9a74c9..25bde503f7 100644
--- a/phpBB/phpbb/console/command/extension/purge.php
+++ b/phpBB/phpbb/console/command/extension/purge.php
@@ -15,6 +15,7 @@ namespace phpbb\console\command\extension;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class purge extends command
 {
@@ -33,19 +34,21 @@ class purge extends command
 
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$name = $input->getArgument('extension-name');
 		$this->manager->purge($name);
 		$this->manager->load_extensions();
 
 		if ($this->manager->is_enabled($name))
 		{
-			$output->writeln('<error>' . $this->user->lang('CLI_EXTENSION_PURGE_FAILURE', $name) . '</error>');
+			$io->error($this->user->lang('CLI_EXTENSION_PURGE_FAILURE', $name));
 			return 1;
 		}
 		else
 		{
 			$this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_PURGE', time(), array($name));
-			$output->writeln('<info>' . $this->user->lang('CLI_EXTENSION_PURGE_SUCCESS', $name) . '</info>');
+			$io->success($this->user->lang('CLI_EXTENSION_PURGE_SUCCESS', $name));
 			return 0;
 		}
 	}
diff --git a/phpBB/phpbb/console/command/extension/show.php b/phpBB/phpbb/console/command/extension/show.php
index f9322034d7..7bad0c0a5a 100644
--- a/phpBB/phpbb/console/command/extension/show.php
+++ b/phpBB/phpbb/console/command/extension/show.php
@@ -14,6 +14,7 @@ namespace phpbb\console\command\extension;
 
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class show extends command
 {
@@ -27,36 +28,27 @@ class show extends command
 
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$this->manager->load_extensions();
 		$all = array_keys($this->manager->all_available());
 
 		if (empty($all))
 		{
-			$output->writeln('<comment>' . $this->user->lang('CLI_EXTENSION_NOT_FOUND') . '</comment>');
+			$io->note($this->user->lang('CLI_EXTENSION_NOT_FOUND'));
 			return 3;
 		}
 
 		$enabled = array_keys($this->manager->all_enabled());
-		$this->print_extension_list($output, $this->user->lang('CLI_EXTENSIONS_ENABLED') . $this->user->lang('COLON'), $enabled);
-
-		$output->writeln('');
+		$io->section($this->user->lang('CLI_EXTENSIONS_ENABLED'));
+		$io->listing($enabled);
 
 		$disabled = array_keys($this->manager->all_disabled());
-		$this->print_extension_list($output, $this->user->lang('CLI_EXTENSIONS_DISABLED') . $this->user->lang('COLON'), $disabled);
-
-		$output->writeln('');
+		$io->section($this->user->lang('CLI_EXTENSIONS_DISABLED'));
+		$io->listing($disabled);
 
 		$purged = array_diff($all, $enabled, $disabled);
-		$this->print_extension_list($output, $this->user->lang('CLI_EXTENSIONS_AVAILABLE') . $this->user->lang('COLON'), $purged);
-	}
-
-	protected function print_extension_list(OutputInterface $output, $type, array $extensions)
-	{
-		$output->writeln("<info>$type</info>");
-
-		foreach ($extensions as $extension)
-		{
-			$output->writeln(" - $extension");
-		}
+		$io->section($this->user->lang('CLI_EXTENSIONS_AVAILABLE'));
+		$io->listing($purged);
 	}
 }
diff --git a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
index ec4e1b0ee7..043f181e72 100644
--- a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
+++ b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
@@ -14,6 +14,7 @@ namespace phpbb\console\command\fixup;
 
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 class recalculate_email_hash extends \phpbb\console\command\command
 {
@@ -37,6 +38,8 @@ class recalculate_email_hash extends \phpbb\console\command\command
 
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
+		$io = new SymfonyStyle($input, $output);
+
 		$sql = 'SELECT user_id, user_email, user_email_hash
 			FROM ' . USERS_TABLE . '
 			WHERE user_type <> ' . USER_IGNORE . "
@@ -59,17 +62,15 @@ class recalculate_email_hash extends \phpbb\console\command\command
 
 				if ($output->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG)
 				{
-					$output->writeln(sprintf(
-						'user_id %d, email %s => %s',
-						$row['user_id'],
-						$row['user_email'],
-						$user_email_hash
-					));
+					$io->table(
+						array('user_id', 'user_email', 'user_email_hash'),
+						array(array($row['user_id'], $row['user_email'], $user_email_hash))
+					);
 				}
 			}
 		}
 		$this->db->sql_freeresult($result);
 
-		$output->writeln('<info>' . $this->user->lang('CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS') . '</info>');
+		$io->success($this->user->lang('CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS'));
 	}
 }

From cbf6d71f6859fd6c036967ed19082f3e54efc328 Mon Sep 17 00:00:00 2001
From: Matt Friedman <maf675@gmail.com>
Date: Thu, 8 Dec 2016 14:25:09 -0800
Subject: [PATCH 4/5] [ticket/14895] Fix issues in CLI classes

PHPBB3-14895
---
 .../default/container/services_console.yml    | 10 +-------
 phpBB/phpbb/console/command/cache/purge.php   |  4 ++--
 .../phpbb/console/command/config/command.php  |  2 +-
 phpBB/phpbb/console/command/config/delete.php |  2 +-
 phpBB/phpbb/console/command/config/get.php    |  2 +-
 .../console/command/config/increment.php      |  2 +-
 phpBB/phpbb/console/command/config/set.php    |  2 +-
 .../phpbb/console/command/cron/cron_list.php  |  2 +-
 phpBB/phpbb/console/command/db/migrate.php    |  6 ++---
 .../console/command/db/migration_command.php  |  2 +-
 phpBB/phpbb/console/command/db/revert.php     | 24 +++----------------
 .../console/command/dev/migration_tips.php    |  2 +-
 .../command/fixup/recalculate_email_hash.php  |  2 +-
 13 files changed, 18 insertions(+), 44 deletions(-)

diff --git a/phpBB/config/default/container/services_console.yml b/phpBB/config/default/container/services_console.yml
index 0c609a8051..e25ab4f03f 100644
--- a/phpBB/config/default/container/services_console.yml
+++ b/phpBB/config/default/container/services_console.yml
@@ -111,15 +111,7 @@ services:
 
     console.command.db.revert:
         class: phpbb\console\command\db\revert
-        arguments:
-            - '@user'
-            - '@language'
-            - '@migrator'
-            - '@ext.manager'
-            - '@config'
-            - '@cache'
-            - '@filesystem'
-            - '%core.root_path%'
+        parent: console.command.db.migrate
         tags:
             - { name: console.command }
 
diff --git a/phpBB/phpbb/console/command/cache/purge.php b/phpBB/phpbb/console/command/cache/purge.php
index 1da97624f5..b7a51b2bb4 100644
--- a/phpBB/phpbb/console/command/cache/purge.php
+++ b/phpBB/phpbb/console/command/cache/purge.php
@@ -40,7 +40,7 @@ class purge extends \phpbb\console\command\command
 	* @param \phpbb\cache\driver\driver_interface	$cache	Cache instance
 	* @param \phpbb\db\driver\driver_interface		$db		Database connection
 	* @param \phpbb\auth\auth						$auth	Auth instance
-	* @param \phpbb\log\log							$log	Logger instance
+	* @param \phpbb\log\log_interface				$log	Logger instance
 	* @param \phpbb\config\config					$config	Config instance
 	*/
 	public function __construct(\phpbb\user $user, \phpbb\cache\driver\driver_interface $cache, \phpbb\db\driver\driver_interface $db, \phpbb\auth\auth $auth, \phpbb\log\log_interface $log, \phpbb\config\config $config)
@@ -72,7 +72,7 @@ class purge extends \phpbb\console\command\command
 	* @param InputInterface  $input  An InputInterface instance
 	* @param OutputInterface $output An OutputInterface instance
 	*
-	* @return null
+	* @return void
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
diff --git a/phpBB/phpbb/console/command/config/command.php b/phpBB/phpbb/console/command/config/command.php
index f0ad5d4d19..19f67d3b6c 100644
--- a/phpBB/phpbb/console/command/config/command.php
+++ b/phpBB/phpbb/console/command/config/command.php
@@ -17,7 +17,7 @@ abstract class command extends \phpbb\console\command\command
 	/** @var \phpbb\config\config */
 	protected $config;
 
-	function __construct(\phpbb\user $user, \phpbb\config\config $config)
+	public function __construct(\phpbb\user $user, \phpbb\config\config $config)
 	{
 		$this->config = $config;
 
diff --git a/phpBB/phpbb/console/command/config/delete.php b/phpBB/phpbb/console/command/config/delete.php
index a1ccefe286..2da0801337 100644
--- a/phpBB/phpbb/console/command/config/delete.php
+++ b/phpBB/phpbb/console/command/config/delete.php
@@ -43,7 +43,7 @@ class delete extends command
 	* @param InputInterface  $input  An InputInterface instance
 	* @param OutputInterface $output An OutputInterface instance
 	*
-	* @return null
+	* @return void
 	* @see \phpbb\config\config::delete()
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
diff --git a/phpBB/phpbb/console/command/config/get.php b/phpBB/phpbb/console/command/config/get.php
index b2b824dd12..f065787110 100644
--- a/phpBB/phpbb/console/command/config/get.php
+++ b/phpBB/phpbb/console/command/config/get.php
@@ -50,7 +50,7 @@ class get extends command
 	* @param InputInterface  $input  An InputInterface instance
 	* @param OutputInterface $output An OutputInterface instance
 	*
-	* @return null
+	* @return void
 	* @see \phpbb\config\config::offsetGet()
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
diff --git a/phpBB/phpbb/console/command/config/increment.php b/phpBB/phpbb/console/command/config/increment.php
index 8b3acc1620..647380a0bf 100644
--- a/phpBB/phpbb/console/command/config/increment.php
+++ b/phpBB/phpbb/console/command/config/increment.php
@@ -55,7 +55,7 @@ class increment extends command
 	* @param InputInterface  $input  An InputInterface instance
 	* @param OutputInterface $output An OutputInterface instance
 	*
-	* @return null
+	* @return void
 	* @see \phpbb\config\config::increment()
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
diff --git a/phpBB/phpbb/console/command/config/set.php b/phpBB/phpbb/console/command/config/set.php
index 889fb630c6..e9f7f8f91e 100644
--- a/phpBB/phpbb/console/command/config/set.php
+++ b/phpBB/phpbb/console/command/config/set.php
@@ -55,7 +55,7 @@ class set extends command
 	* @param InputInterface  $input  An InputInterface instance
 	* @param OutputInterface $output An OutputInterface instance
 	*
-	* @return null
+	* @return void
 	* @see \phpbb\config\config::set()
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
diff --git a/phpBB/phpbb/console/command/cron/cron_list.php b/phpBB/phpbb/console/command/cron/cron_list.php
index 0618cee4db..8f9d63eda2 100644
--- a/phpBB/phpbb/console/command/cron/cron_list.php
+++ b/phpBB/phpbb/console/command/cron/cron_list.php
@@ -52,7 +52,7 @@ class cron_list extends \phpbb\console\command\command
 	* @param InputInterface  $input  An InputInterface instance
 	* @param OutputInterface $output An OutputInterface instance
 	*
-	* @return null
+	* @return void
 	*/
 	protected function execute(InputInterface $input, OutputInterface $output)
 	{
diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php
index f2cc9142a6..4270e2d703 100644
--- a/phpBB/phpbb/console/command/db/migrate.php
+++ b/phpBB/phpbb/console/command/db/migrate.php
@@ -31,21 +31,21 @@ class migrate extends \phpbb\console\command\db\migration_command
 	/** @var \phpbb\language\language */
 	protected $language;
 
-	function __construct(\phpbb\user $user, \phpbb\language\language $language, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path)
+	public function __construct(\phpbb\user $user, \phpbb\language\language $language, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path)
 	{
 		$this->language = $language;
 		$this->log = $log;
 		$this->filesystem = $filesystem;
 		$this->phpbb_root_path = $phpbb_root_path;
 		parent::__construct($user, $migrator, $extension_manager, $config, $cache);
-		$this->user->add_lang(array('common', 'install', 'migrator'));
+		$this->language->add_lang(array('common', 'install', 'migrator'));
 	}
 
 	protected function configure()
 	{
 		$this
 			->setName('db:migrate')
-			->setDescription($this->user->lang('CLI_DESCRIPTION_DB_MIGRATE'))
+			->setDescription($this->language->lang('CLI_DESCRIPTION_DB_MIGRATE'))
 		;
 	}
 
diff --git a/phpBB/phpbb/console/command/db/migration_command.php b/phpBB/phpbb/console/command/db/migration_command.php
index b951560588..851f404fab 100644
--- a/phpBB/phpbb/console/command/db/migration_command.php
+++ b/phpBB/phpbb/console/command/db/migration_command.php
@@ -26,7 +26,7 @@ abstract class migration_command extends \phpbb\console\command\command
 	/** @var \phpbb\cache\service */
 	protected $cache;
 
-	function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache)
+	public function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache)
 	{
 		$this->migrator = $migrator;
 		$this->extension_manager = $extension_manager;
diff --git a/phpBB/phpbb/console/command/db/revert.php b/phpBB/phpbb/console/command/db/revert.php
index 7977afc319..3c79d8c554 100644
--- a/phpBB/phpbb/console/command/db/revert.php
+++ b/phpBB/phpbb/console/command/db/revert.php
@@ -18,35 +18,17 @@ use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
 
-class revert extends \phpbb\console\command\db\migration_command
+class revert extends \phpbb\console\command\db\migrate
 {
-	/** @var string phpBB root path */
-	protected $phpbb_root_path;
-
-	/** @var  \phpbb\filesystem\filesystem_interface */
-	protected $filesystem;
-
-	/** @var \phpbb\language\language */
-	protected $language;
-
-	function __construct(\phpbb\user $user, \phpbb\language\language $language, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path)
-	{
-		$this->filesystem = $filesystem;
-		$this->language = $language;
-		$this->phpbb_root_path = $phpbb_root_path;
-		parent::__construct($user, $migrator, $extension_manager, $config, $cache);
-		$this->user->add_lang(array('common', 'migrator'));
-	}
-
 	protected function configure()
 	{
 		$this
 			->setName('db:revert')
-			->setDescription($this->user->lang('CLI_DESCRIPTION_DB_REVERT'))
+			->setDescription($this->language->lang('CLI_DESCRIPTION_DB_REVERT'))
 			->addArgument(
 				'name',
 				InputArgument::REQUIRED,
-				$this->user->lang('CLI_MIGRATION_NAME')
+				$this->language->lang('CLI_MIGRATION_NAME')
 			)
 		;
 	}
diff --git a/phpBB/phpbb/console/command/dev/migration_tips.php b/phpBB/phpbb/console/command/dev/migration_tips.php
index f9047bdac8..2ca0ddde2f 100644
--- a/phpBB/phpbb/console/command/dev/migration_tips.php
+++ b/phpBB/phpbb/console/command/dev/migration_tips.php
@@ -20,7 +20,7 @@ class migration_tips extends \phpbb\console\command\command
 	/** @var \phpbb\extension\manager */
 	protected $extension_manager;
 
-	function __construct(\phpbb\user $user, \phpbb\extension\manager $extension_manager)
+	public function __construct(\phpbb\user $user, \phpbb\extension\manager $extension_manager)
 	{
 		$this->extension_manager = $extension_manager;
 		parent::__construct($user);
diff --git a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
index 043f181e72..6f7096296d 100644
--- a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
+++ b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
@@ -21,7 +21,7 @@ class recalculate_email_hash extends \phpbb\console\command\command
 	/** @var \phpbb\db\driver\driver_interface */
 	protected $db;
 
-	function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db)
+	public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db)
 	{
 		$this->db = $db;
 

From 6a5b99b12b1812202843613994480cc6caf93354 Mon Sep 17 00:00:00 2001
From: Matt Friedman <maf675@gmail.com>
Date: Thu, 8 Dec 2016 16:49:50 -0800
Subject: [PATCH 5/5] [ticket/14895] Fix broken tests

PHPBB3-14895
---
 phpBB/phpbb/console/command/cron/cron_list.php | 4 ++--
 tests/console/cron/cron_list_test.php          | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/phpBB/phpbb/console/command/cron/cron_list.php b/phpBB/phpbb/console/command/cron/cron_list.php
index 8f9d63eda2..ea61e45235 100644
--- a/phpBB/phpbb/console/command/cron/cron_list.php
+++ b/phpBB/phpbb/console/command/cron/cron_list.php
@@ -81,13 +81,13 @@ class cron_list extends \phpbb\console\command\command
 
 		if (!empty($ready_tasks))
 		{
-			$io->section($this->user->lang('TASKS_READY'));
+			$io->title($this->user->lang('TASKS_READY'));
 			$io->listing($ready_tasks);
 		}
 
 		if (!empty($not_ready_tasks))
 		{
-			$io->section($this->user->lang('TASKS_NOT_READY'));
+			$io->title($this->user->lang('TASKS_NOT_READY'));
 			$io->listing($not_ready_tasks);
 		}
 	}
diff --git a/tests/console/cron/cron_list_test.php b/tests/console/cron/cron_list_test.php
index 3bbe2078ba..fdc9a05cb2 100644
--- a/tests/console/cron/cron_list_test.php
+++ b/tests/console/cron/cron_list_test.php
@@ -50,19 +50,19 @@ class phpbb_console_command_cron_list_test extends phpbb_test_case
 	public function test_only_ready()
 	{
 		$this->initiate_test(2, 0);
-		$this->assertContains('TASKS_READY command1 command2', preg_replace('/\s+/', ' ', trim($this->command_tester->getDisplay())));
+		$this->assertContains('TASKS_READY command1 command2', preg_replace('/[\s*=]+/', ' ', trim($this->command_tester->getDisplay())));
 	}
 
 	public function test_only_not_ready()
 	{
 		$this->initiate_test(0, 2);
-		$this->assertContains('TASKS_NOT_READY command1 command2', preg_replace('/\s+/', ' ', trim($this->command_tester->getDisplay())));
+		$this->assertContains('TASKS_NOT_READY command1 command2', preg_replace('/[\s*=]+/', ' ', trim($this->command_tester->getDisplay())));
 	}
 
 	public function test_both_ready()
 	{
 		$this->initiate_test(2, 2);
-		$this->assertSame('TASKS_READY command1 command2 TASKS_NOT_READY command3 command4', preg_replace('/\s+/', ' ', trim($this->command_tester->getDisplay())));
+		$this->assertSame('TASKS_READY command1 command2 TASKS_NOT_READY command3 command4', preg_replace('/[\s*=]+/', ' ', trim($this->command_tester->getDisplay())));
 	}
 
 	public function get_cron_manager(array $tasks)