Passed
Push — master ( 842f16...60595a )
by Rubén
12:20 queued 11s
created

lib/SP/Storage/Database/MySQLHandler.php (5 issues)

Severity
1
<?php
2
/**
3
 * sysPass
4
 *
5
 * @author    nuxsmin
6
 * @link      https://syspass.org
7
 * @copyright 2012-2019, Rubén Domínguez nuxsmin@$syspass.org
8
 *
9
 * This file is part of sysPass.
10
 *
11
 * sysPass is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation, either version 3 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * sysPass is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 *  along with sysPass.  If not, see <http://www.gnu.org/licenses/>.
23
 */
24
25
namespace SP\Storage\Database;
26
27
use Exception;
28
use PDO;
29
30
defined('APP_ROOT') || die();
31
32
/**
33
 * Class MySQLHandler
34
 *
35
 * Esta clase se encarga de crear las conexiones a la BD
36
 */
37
final class MySQLHandler implements DBStorageInterface
38
{
39
    const STATUS_OK = 0;
40
    const STATUS_KO = 1;
41
    const PDO_OPTS = [
42
        PDO::ATTR_EMULATE_PREPARES => false,
43
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
44
        PDO::MYSQL_ATTR_FOUND_ROWS => true,
45
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ
46
    ];
47
    /**
48
     * @var PDO
49
     */
50
    private $db;
51
    /**
52
     * @var int
53
     */
54
    private $dbStatus = self::STATUS_KO;
55
    /**
56
     * @var DatabaseConnectionData
57
     */
58
    private $connectionData;
59
60
    /**
61
     * MySQLHandler constructor.
62
     *
63
     * @param DatabaseConnectionData $connectionData
64
     */
65
    public function __construct(DatabaseConnectionData $connectionData)
66
    {
67
        $this->connectionData = $connectionData;
68
    }
69
70
    /**
71
     * Devuelve el estado de conexión a la BBDD
72
     *
73
     * OK -> 0
74
     * KO -> 1
75
     *
76
     * @return int
77
     */
78
    public function getDbStatus()
79
    {
80
        return $this->dbStatus;
81
    }
82
83
    /**
84
     * Realizar la conexión con la BBDD.
85
     * Esta función utiliza PDO para conectar con la base de datos.
86
     *
87
     * @return PDO
88
     * @throws DatabaseException
89
     */
90
    public function getConnection()
91
    {
92
        if (!$this->db) {
93
            if (null === $this->connectionData->getDbUser()
94
                || null === $this->connectionData->getDbPass()
0 ignored issues
show
The condition null === $this->connectionData->getDbPass() is always false.
Loading history...
95
                || null === $this->connectionData->getDbName()
0 ignored issues
show
The condition null === $this->connectionData->getDbName() is always false.
Loading history...
96
                || (null === $this->connectionData->getDbHost() && null === $this->connectionData->getDbSocket())
0 ignored issues
show
The condition null === $this->connectionData->getDbHost() is always false.
Loading history...
97
            ) {
98
                throw new DatabaseException(
99
                    __u('Unable to connect to DB'),
100
                    DatabaseException::CRITICAL,
101
                    __u('Please, check the connection parameters'));
102
            }
103
104
            try {
105
                $this->db = new PDO(
106
                    $this->getConnectionUri(),
107
                    $this->connectionData->getDbUser(),
108
                    $this->connectionData->getDbPass(),
109
                    self::PDO_OPTS
110
                );
111
112
                // Set prepared statement emulation depending on server version
113
                $serverVersion = $this->db->getAttribute(PDO::ATTR_SERVER_VERSION);
114
                $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, version_compare($serverVersion, '5.1.17', '<'));
115
116
                $this->dbStatus = self::STATUS_OK;
117
            } catch (Exception $e) {
118
                throw new DatabaseException(
119
                    __u('Unable to connect to DB'),
120
                    DatabaseException::CRITICAL,
121
                    sprintf('Error %s: %s', $e->getCode(), $e->getMessage()),
122
                    $e->getCode(),
123
                    $e
124
                );
125
            }
126
        }
127
128
        return $this->db;
129
    }
130
131
    /**
132
     * @return string
133
     */
134
    public function getConnectionUri()
135
    {
136
        $dsn = ['charset=utf8'];
137
138
        if (empty($this->connectionData->getDbSocket())) {
139
            $dsn[] = 'host=' . $this->connectionData->getDbHost();
140
141
            if (null !== $this->connectionData->getDbPort()) {
0 ignored issues
show
The condition null !== $this->connectionData->getDbPort() is always true.
Loading history...
142
                $dsn[] = 'port=' . $this->connectionData->getDbPort();
143
            }
144
        } else {
145
            $dsn[] = 'unix_socket=' . $this->connectionData->getDbSocket();
146
        }
147
148
        if (!empty($this->connectionData->getDbName())) {
149
            $dsn[] = 'dbname=' . $this->connectionData->getDbName();
150
        }
151
152
        return 'mysql:' . implode(';', $dsn);
153
    }
154
155
    /**
156
     * Obtener una conexión PDO sin seleccionar la BD
157
     *
158
     * @return PDO
159
     * @throws DatabaseException
160
     */
161
    public function getConnectionSimple()
162
    {
163
        if (!$this->db) {
164
            if (null === $this->connectionData->getDbHost() && null === $this->connectionData->getDbSocket()) {
0 ignored issues
show
The condition null === $this->connectionData->getDbHost() is always false.
Loading history...
165
                throw new DatabaseException(
166
                    __u('Unable to connect to DB'),
167
                    DatabaseException::CRITICAL,
168
                    __u('Please, check the connection parameters'));
169
            }
170
171
            try {
172
                $opts = [PDO::ATTR_EMULATE_PREPARES => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION];
173
174
                $this->db = new PDO($this->getConnectionUri(), $this->connectionData->getDbUser(), $this->connectionData->getDbPass(), $opts);
175
                $this->dbStatus = self::STATUS_OK;
176
            } catch (Exception $e) {
177
                throw new DatabaseException(
178
                    __u('Unable to connect to DB'),
179
                    DatabaseException::CRITICAL,
180
                    sprintf('Error %s: %s', $e->getCode(), $e->getMessage()),
181
                    $e->getCode(),
182
                    $e
183
                );
184
            }
185
        }
186
187
        return $this->db;
188
    }
189
190
    /**
191
     * @return string
192
     */
193
    public function getDatabaseName()
194
    {
195
        return $this->connectionData->getDbName();
196
    }
197
}