Completed
Push — master ( a95f7d...eaa6fe )
by Danilo
02:55
created

Database::getDns()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 22
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
cc 5
eloc 10
nc 3
nop 1
1
<?php
2
3
/*
4
 * This file is part of the PhpBotFramework.
5
 *
6
 * PhpBotFramework is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation, version 3.
9
 *
10
 * PhpBotFramework is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public License
16
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
namespace PhpBotFramework\Database;
20
21
use PhpBotFramework\BasicBot;
22
use PhpBotFramework\Exceptions\BotException;
23
24
define('PDO_DEFAULT_ADAPTER', 'mysql');
25
26
/** \class Database Database connection handler
27
 */
28
class Database
29
{
30
    use User;
31
32
    /** @} */
33
34
    /** PDO connection to the database. */
35
    public $pdo;
36
37
    /** \brief Table contaning bot users data in the SQL database. */
38
    public $user_table = 'User';
39
40
    /**
41
     * \addtogroup Database
42
     * @{
43
     */
44
45
    /**
46
     * @internal
47
     * \brief Create a Database handler object.
48
     * @param BasicBot $bot Reference to the bot that use this object.
49
     */
50
    public function __construct(BasicBot &$bot)
51
    {
52
        $this->bot = $bot;
0 ignored issues
show
Bug introduced by
The property bot does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
53
    }
54
55
    /**
56
     * \brief Open a database connection using PDO.
57
     * \details Provides a simple way to initialize a database connection
58
     * and create a PDO instance.
59
     * @param array $params Parameters for initialize connection.
60
     * Index required:
61
     *     - <code>username</code>
62
     *     - <code>password</code> (can be an empty string)
63
     * Optional index:
64
     *     - <code>dbname</code>
65
     *     - <code>adapter</code> <b>Default</b>: <code>mysql</code>
66
     *     - <code>host</code> <b>Default</b>: <code>localhost</code>
67
     *     - <code>options</code> (<i>Array of options passed when creating PDO object</i>)
68
     * @return bool True when the connection is succefully created.
69
     */
70
    public function connect(array $params) : bool
71
    {
72
        $params = $this->addDefaultValue($params);
73
        $config = $this->getDns($params);
74
75
        try {
76
            $this->pdo = new \PDO($config, $params['username'], $params['password'], $params['options']);
77
            $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
78
79
            return true;
80
        } catch (\PDOException $e) {
81
            echo 'Unable to connect to database, an error occured:' . $e->getMessage();
82
        }
83
84
        return false;
85
    }
86
87
    /**
88
     * @internal
89
     * \brief Add default connection value to parameter passed to PDO.
90
     * @param array $params Parameter for PDO connection.
91
     * @return array Parameter with defaults value.
92
     */
93
    protected function addDefaultValue(array $params) : array
94
    {
95
        static $defaults = [ 'adapter' => PDO_DEFAULT_ADAPTER, 'host' => 'localhost', 'options' => [] ];
96
        return array_merge($defaults, $params);
97
    }
98
99
    /**
100
     * @internal
101
     * \brief Returns a string that can passed to PDO as DNS parameter in order to open connection.
102
     * @param array $params Array containing parameter of the connection
103
     * @return string Parameters contained in array $params sanitized in a string that can be passed as DNS param of PDO object creation.
104
     */
105
    protected function getDns($params) : string
106
    {
107
        $response = $params['adapter'] . ':';
108
        unset($params['adapter']);
109
        $fields = [];
110
111
        foreach ($params as $field => $value) {
112
            /**
113
             *Check if the current field matches one of the fields
114
             * that are passed to PDO in another way and so don't need
115
             * to be included in the string.
116
             */
117
            if ($field === 'username' || $field === 'password' || $field === 'options') {
118
                unset($params[$field]);
119
                continue;
120
            }
121
122
            $fields[] = $field . '=' . $value;
123
        }
124
125
        return $response . join(';', $fields);
126
    }
127
128
    /**
129
     * @internal
130
     * \brief Sanitize name of the user table depending on database used.
131
     */
132
    protected function sanitizeUserTable()
133
    {
134
        static $is_sanitized = false;
135
136
        if ($is_sanitized) {
137
            return;
138
        }
139
140
        if ($this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME) === 'mysql') {
141
            $this->user_table = "`$this->user_table`";
142
        } else {
143
            $this->user_table = '"' . $this->user_table . '"';
144
        }
145
146
        $is_sanitized = true;
147
    }
148
149
    /** @} */
150
}
151