Database::configBuilder()   B
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 36
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 22
nc 6
nop 1
dl 0
loc 36
rs 8.5806
c 0
b 0
f 0
1
<?php
2
/*
3
 * This file is part of the Divergence package.
4
 *
5
 * (c) Henry Paradiz <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace Divergence\CLI\Controllers\Commands;
11
12
use PDO;
13
use Divergence\CLI\Env;
14
use Divergence\CLI\Command;
15
use Divergence\CLI\ConfigWriter;
16
17
class Database
18
{
19
    public static function wizard($config)
20
    {
21
        $climate = Command::getClimate();
22
        do {
23
            $config = Database::configBuilder($config);
24
            $climate->info('For your reference the config is:');
25
26
            /* do not remove */
27
            dump($config);
28
            
29
            $retest = true;
0 ignored issues
show
Unused Code introduced by
The assignment to $retest is dead and can be removed.
Loading history...
30
            do { // retest config until success or abort
31
                $climate->inline('Testing config.......... ');
32
                $valid = static::connectionTester($config);
33
                if ($valid) {
34
                    $climate->green('Success.');
35
                    return $config;
36
                } else {
37
                    $climate->red('Failed.');
38
                    $input = $climate->confirm('Test again?');
39
                    $input->defaultTo('y');
40
                    $retest = $input->confirmed();
41
                }
42
            } while ($retest);
43
            $input = $climate->confirm('Continue with untested config?');
44
            $input->defaultTo('n');
45
            if ($input->confirmed()) {
46
                $valid = true; // human override
47
            }
48
        } while (!$valid);
49
50
        return $config;
51
    }
52
53
    /*
54
     *  Asks the user to define a database config with some simple helpers
55
     */
56
    public static function configBuilder($defaults)
57
    {
58
        $climate = Command::getClimate();
59
        
60
        $new = [];
61
62
        // hostname or socket
63
        $input = $climate->input(sprintf('Hostname (You can also provide a socket) <yellow>[<bold>%s</bold>]</yellow>', $defaults['host']));
64
        $input->defaultTo($defaults['host']);
65
        $new['host'] = $input->prompt();
66
        if (substr($new['host'], -5) === '.sock') { // if ends with .sock treat as socket
67
            $new['socket'] = $new['host'];
68
            unset($new['host']);
69
        }
70
71
        // database name
72
        $input = $climate->input(sprintf('Database name <yellow>[<bold>%s</bold>]</yellow>', $defaults['database']));
73
        $input->defaultTo($defaults['database']);
74
        $new['database'] = $input->prompt();
75
76
        // database username
77
        $input = $climate->input(sprintf('Database username <yellow>[<bold>%s</bold>]</yellow>', $defaults['username']));
78
        $input->defaultTo($defaults['username']);
79
        $new['username'] = $input->prompt();
80
81
        // database password
82
        $input = $climate->input('Database password: ');
83
        $new['password'] = $input->prompt();
84
        if (!$new['password']) {
85
            $input = $climate->confirm('Generate one?');
86
            $input->defaultTo('y');
87
            if ($input->confirmed()) {
88
                $new['password'] = static::createPassword();
89
            }
90
        }
91
        return $new;
92
    }
93
94
    /*
95
     * Tries to connect to a database from a config
96
     */
97
    public static function connectionTester($config)
98
    {
99
        if ($config['socket']) {
100
            $DSN = 'mysql:unix_socket=' . $config['socket'] . ';dbname=' . $config['database'];
101
        } else {
102
            $DSN = 'mysql:host=' . $config['host'] . ';port=' . $config['port'] .';dbname=' . $config['database'];
103
        }
104
        
105
        try {
106
            new PDO($DSN, $config['username'], $config['password']);
107
        } catch (\PDOException $e) {
108
            return false;
109
        }
110
111
        return true;
112
    }
113
114
    /*
115
     *  Uses ascii table chars decimal 33 (!) -> 126 (~)
116
     *  covers basic symbols and letters
117
     */
118
    public static function createPassword($length=20)
119
    {
120
        $password = '';
121
        while (strlen($password)<$length) {
122
            $password .= chr(mt_rand(33, 126));
123
        }
124
        return $password;
125
    }
126
}
127