Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/magento
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ try {
$handler = new \Magento\Framework\App\ErrorHandler();
set_error_handler([$handler, 'handler']);
$application = new Magento\Framework\Console\Cli('Magento CLI');
$application->run();
$application->run(new Magento\Framework\Console\Input);
} catch (\Exception $e) {
while ($e) {
echo $e->getMessage();
Expand Down
32 changes: 32 additions & 0 deletions lib/internal/Magento/Framework/Console/Input.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Framework\Console;

use Symfony\Component\Console\Helper\DialogHelper;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\OutputInterface;

class Input extends ArgvInput
{
/**
* Prompt for option value and set as default
*
* @param DialogHelper $dialog
* @param OutputInterface $output
* @param string $name
* @param boolean $isHidden
* @return void
*/
public function promptForOption(DialogHelper $dialog, OutputInterface $output, $name, $isHidden = false)
{
$method = $isHidden ? 'askHiddenResponse' : 'ask';
$this->definition->getOption($name)->setDefault($dialog->$method(
$output,
'<info>' . ucwords(str_replace('-', ' ', $name)) . '</info>: '
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function __construct(InstallerFactory $installerFactory, UserValidationRu
protected function configure()
{
$this->setName('admin:user:create')
->setDescription('Creates an administrator')
->setDescription('Creates an administrator. Values for required options will be prompted, if not specified')
->setDefinition($this->getOptionsList());
parent::configure();
}
Expand All @@ -55,6 +55,7 @@ protected function configure()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->setMissingValues($input, $output);
$errors = $this->validate($input);
if ($errors) {
$output->writeln('<error>' . implode('</error>' . PHP_EOL . '<error>', $errors) . '</error>');
Expand Down Expand Up @@ -123,4 +124,31 @@ public function validate(InputInterface $input)

return $errors;
}

/**
* Get admin user data
*
* @param InputInterface $input
* @param OutputInterface $output
* @return void
*/
protected function setMissingValues(InputInterface &$input, OutputInterface $output)
{
if (!method_exists($input, 'promptForOption')) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for not being more specific earlier, but better way to achieve this is to introduce new interface, i.e. InputInteractiveInterface, which extends InputInterface. Then here either check is $input an instance of this interface or even better do type hinting to InputInteractiveInterface in the method signature. The latter is not always possible, so either way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify the question please? Literally, there should be an interface with the promptForOption method and here you should either have it in protected function setMissingValues(InputInteractiveInterface &$input, OutputInterface $output) (better) or call instanceof (still ok).

Copy link
Copy Markdown
Contributor

@vrann vrann Mar 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please let me know does this makes sense to you. I don't want to add too much work :)

return;
}
$dialog = $this->getHelper('dialog');
$keys = [
AdminAccount::KEY_FIRST_NAME,
AdminAccount::KEY_LAST_NAME,
AdminAccount::KEY_USER,
AdminAccount::KEY_EMAIL,
AdminAccount::KEY_PASSWORD,
];
foreach ($keys as $key) {
if (!$input->getOption($key)) {
$input->promptForOption($dialog, $output, $key, $key === AdminAccount::KEY_PASSWORD);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check that input actually implements the interface which has promptForOption method

}
}
}
}
48 changes: 48 additions & 0 deletions setup/src/Magento/Setup/Console/Input/PromptableInputOption.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Setup\Console\Input;

use Symfony\Component\Console\Helper\DialogHelper;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\ConsoleOutput;

class PromptableInputOption extends InputOption
{

/**
* Ignore the default param since we will prompt for it instead
*
* @param string
* @param string|array
* @param int
* @param string
* @param mixed
*/
public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
{
parent::__construct($name, $shortcut, $mode, $description, null);
}

/**
* Prompt for the value to be used if none given, instead of using a default
*
* @return mixed
*/
public function getDefault()
{
$default = parent::getDefault();
if ($default !== null) {
return $default;
}
$dialog = new DialogHelper;
$this->setDefault($dialog->ask(
new ConsoleOutput,
'<info>' . ucwords(str_replace('-', ' ', $this->getName())) . '</info>: '
));
return parent::getDefault();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
*/
namespace Magento\Setup\Test\Unit\Console\Command;

use Magento\Framework\Console\Input;
use Magento\Setup\Model\AdminAccount;
use Magento\Setup\Console\Command\AdminUserCreateCommand;
use Magento\Setup\Mvc\Bootstrap\InitParamListener;
use Magento\User\Model\UserValidationRules;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\DialogHelper;
use Symfony\Component\Console\Tester\CommandTester;

class AdminUserCreateCommandTest extends \PHPUnit_Framework_TestCase
Expand All @@ -27,6 +30,7 @@ public function setUp()
{
$this->installerFactoryMock = $this->getMock(\Magento\Setup\Model\InstallerFactory::class, [], [], '', false);
$this->command = new AdminUserCreateCommand($this->installerFactoryMock, new UserValidationRules());
$this->command->setHelperSet(new HelperSet([new DialogHelper]));
}

public function testExecute()
Expand Down Expand Up @@ -119,4 +123,34 @@ public function validateDataProvider()
[['John', 'Doe', 'admin', 'test@test.com', '123123q', '123123q'], []],
];
}

public function testExecuteWithPrompts()
{
$data = [
AdminAccount::KEY_USER => 'user',
AdminAccount::KEY_PASSWORD => '123123q',
AdminAccount::KEY_EMAIL => 'test@test.com',
AdminAccount::KEY_FIRST_NAME => 'John',
AdminAccount::KEY_LAST_NAME => 'Doe',
];
$commandTester = new CommandTester($this->command);
$installerMock = $this->getMock('Magento\Setup\Model\Installer', [], [], '', false);
$installerMock->expects($this->once())->method('installAdminUser')->with($data);
$this->installerFactoryMock->expects($this->once())->method('create')->willReturn($installerMock);

$helper = $this->command->getHelper('dialog');
$helper->setInputStream($this->getInputStream("John\nDoe\nuser\ntest@test.com\n123123q\n"));

$commandTester->execute([], ['interactive' => new Input]);
$this->assertContains('Created Magento administrator user named user', $commandTester->getDisplay());
}

protected function getInputStream($input)
{
$stream = fopen('php://memory', 'r+', false);
fputs($stream, $input);
rewind($stream);

return $stream;
}
}