Completed
Pull Request — master (#9)
by Sander
04:49
created

ConfigGenerateCommand::execute()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 42
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
eloc 23
dl 0
loc 42
ccs 0
cts 31
cp 0
rs 9.552
c 0
b 0
f 0
cc 4
nc 5
nop 2
crap 20
1
<?php
2
/**
3
 * neuralyzer : Data Anonymization Library and CLI Tool
4
 *
5
 * PHP Version 7.1
6
 *
7
 * @author    Emmanuel Dyan
8
 * @author    Rémi Sauvat
9
 * @copyright 2018 Emmanuel Dyan
10
 *
11
 * @package   edyan/neuralyzer
12
 *
13
 * @license   GNU General Public License v2.0
14
 *
15
 * @link      https://github.com/edyan/neuralyzer
16
 */
17
18
namespace Edyan\Neuralyzer\Console\Commands;
19
20
use Edyan\Neuralyzer\Anonymizer\DB;
21
use Symfony\Component\Console\Command\Command;
22
use Symfony\Component\Console\Input\InputInterface;
23
use Symfony\Component\Console\Input\InputOption;
24
use Symfony\Component\Console\Output\OutputInterface;
25
use Symfony\Component\Console\Question\Question;
26
27
/**
28
 * Command to generate a config file from a DB
29
 */
30
class ConfigGenerateCommand extends Command
31
{
32
    /**
33
     * Store the DB Object
34
     *
35
     * @var DB
36
     */
37
    private $db;
38
39
    /**
40
     * Set the command shortcut to be used in configuration
41
     *
42
     * @var string
43
     */
44
    protected $command = 'config:generate';
45
46
47
    /**
48
     * RunCommand constructor.
49
     *
50
     * @param DB $db
51
     */
52
    public function __construct(DB $db)
53
    {
54
        parent::__construct();
55
56
        $this->db = $db;
57
    }
58
59
    /**
60
     * Configure the command
61
     *
62
     * @return void
63
     */
64
    protected function configure(): void
65
    {
66
        // First command : Test the DB Connexion
67
        $this->setName($this->command)
68
            ->setDescription(
69
                'Generate configuration for the Anonymizer'
70
            )->setHelp(
71
                'This command will connect to a DB and extract a list of tables / fields to a yaml file'.PHP_EOL.
72
                "Usage: neuralyzer <info>{$this->command} -u app -p app -f neuralyzer.yml</info>"
73
            )->addOption(
74
                'driver',
75
                'D',
76
                InputOption::VALUE_REQUIRED,
77
                'Driver (check Doctrine documentation to have the list)',
78
                'pdo_mysql'
79
            )->addOption(
80
                'host',
81
                'H',
82
                InputOption::VALUE_REQUIRED,
83
                'Host',
84
                '127.0.0.1'
85
            )->addOption(
86
                'db',
87
                'd',
88
                InputOption::VALUE_REQUIRED,
89
                'Database Name'
90
            )->addOption(
91
                'user',
92
                'u',
93
                InputOption::VALUE_REQUIRED,
94
                'User Name',
95
                get_current_user()
96
            )->addOption(
97
                'password',
98
                'p',
99
                InputOption::VALUE_REQUIRED,
100
                "Password (or it'll be prompted)"
101
            )->addOption(
102
                'file',
103
                'f',
104
                InputOption::VALUE_REQUIRED,
105
                'File',
106
                'neuralyzer.yml'
107
            )->addOption(
108
                'protect',
109
                null,
110
                InputOption::VALUE_NONE,
111
                'Protect IDs and other fields'
112
            )->addOption(
113
                'ignore-table',
114
                null,
115
                InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
116
                'Table to ignore. Can be repeated'
117
            )->addOption(
118
                'ignore-field',
119
                null,
120
                InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
121
                'Field to ignore. Regexp in the form "table.field". Can be repeated'
122
            );
123
    }
124
125
    /**
126
     * @param InputInterface  $input
127
     * @param OutputInterface $output
128
     *
129
     * @throws \Doctrine\DBAL\DBALException
130
     * @throws \Edyan\Neuralyzer\Exception\NeuralizerConfigurationException
131
     */
132
    protected function execute(InputInterface $input, OutputInterface $output): void
133
    {
134
        // Throw an exception immediately if we dont have the required DB parameter
135
        if (empty($input->getOption('db'))) {
136
            throw new \InvalidArgumentException('Database name is required (--db)');
137
        }
138
139
        $password = $input->getOption('password');
140
        if (null === $password){
141
            $question = new Question('Password: ');
142
            $question->setHidden(true)->setHiddenFallback(false);
143
144
            $password = $this->getHelper('question')->ask($input, $output, $question);
145
        }
146
147
        $ignoreFields = $input->getOption('ignore-field');
148
149
        // Now work on the DB
150
        $this->db->initDatabaseConnection(
151
            [
152
                'driver' => $input->getOption('driver'),
153
                'host' => $input->getOption('host'),
154
                'dbname' => $input->getOption('db'),
155
                'user' => $input->getOption('user'),
156
                'password' => $password,
157
            ]
158
        );
159
160
        $writer = new \Edyan\Neuralyzer\Configuration\Writer;
161
        $writer->protectCols($input->getOption('protect'));
162
163
        // Override the protection if fields are defined
164
        if (!empty($ignoreFields)) {
165
            $writer->protectCols(true);
166
            $writer->setProtectedCols($ignoreFields);
167
        }
168
169
        $writer->setIgnoredTables($input->getOption('ignore-table'));
170
        $data = $writer->generateConfFromDB($this->db, new \Edyan\Neuralyzer\Guesser);
171
        $writer->save($data, $input->getOption('file'));
172
173
        $output->writeln('<comment>Configuration written to '.$input->getOption('file').'</comment>');
174
    }
175
}
176