-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathSQLiteDatabaseConfigurationHelper.php
More file actions
208 lines (184 loc) · 5.95 KB
/
SQLiteDatabaseConfigurationHelper.php
File metadata and controls
208 lines (184 loc) · 5.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<?php
/**
* This is a helper class for the SS installer.
*
* It does all the specific checking for SQLiteDatabase
* to ensure that the configuration is setup correctly.
*
* @package sqlite3
*/
class SQLiteDatabaseConfigurationHelper implements DatabaseConfigurationHelper {
/**
* Ensure that one of the database classes
* is available. If it is, we assume the PHP module for this
* database has been setup correctly.
*
* @param array $databaseConfig Associative array of database configuration, e.g. "type", "path" etc
* @return boolean
*/
public function requireDatabaseFunctions($databaseConfig) {
if($databaseConfig['type'] == 'SQLitePDODatabase' || version_compare(phpversion(), '5.3.0', '<')) return class_exists('PDO') ? true : false;
return class_exists('SQLite3');
}
/**
* Ensure that the database server exists.
* @param array $databaseConfig Associative array of db configuration, e.g. "type", "path" etc
* @return array Result - e.g. array('success' => true, 'error' => 'details of error')
*/
public function requireDatabaseServer($databaseConfig) {
$path = $databaseConfig['path'];
$error = null;
if(!$path) {
$success = false;
$error = 'No database path provided';
}
// check if parent folder is writeable
elseif(is_writable(dirname($path))) {
$success = true;
} else {
$success = false;
$error = 'Webserver can\'t write database file to path "' . $path . '"';
}
return array(
'success' => $success,
'error' => $error
);
}
/**
* Ensure a database connection is possible using credentials provided.
*
* @todo Validate path
*
* @param array $databaseConfig Associative array of db configuration, e.g. "type", "path" etc
* @return array Result - e.g. array('success' => true, 'error' => 'details of error')
*/
public function requireDatabaseConnection($databaseConfig) {
$success = false;
$error = '';
// arg validation
if(!isset($databaseConfig['path']) || !$databaseConfig['path']) return array(
'success' => false,
'error' => sprintf('Invalid path: "%s"', $databaseConfig['path'])
);
$path = $databaseConfig['path'];
if(!isset($databaseConfig['database']) || !$databaseConfig['database']) return array(
'success' => false,
'error' => sprintf('Invalid database name: "%s"', $databaseConfig['database'])
);
// create and secure db directory
$dirCreated = self::create_db_dir($path);
if(!$dirCreated) return array(
'success' => false,
'error' => sprintf('Cannot create path: "%s"', $path)
);
$dirSecured = self::secure_db_dir($path);
if(!$dirSecured) return array(
'success' => false,
'error' => sprintf('Cannot secure path through .htaccess: "%s"', $path)
);
$file = $path . '/' . $databaseConfig['database'];
$file = preg_replace('/\/$/', '', $file);
if($databaseConfig['type'] == 'SQLitePDODatabase' || version_compare(phpversion(), '5.3.0', '<')) {
$conn = @(new PDO("sqlite:$file"));
} else {
$conn = @(new SQLite3($file, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE));
}
if($conn) {
$success = true;
} else {
$success = false;
$error = '';
}
return array(
'success' => $success,
'connection' => $conn,
'error' => $error
);
}
public function getDatabaseVersion($databaseConfig) {
$version = 0;
if(class_exists('SQLite3')) {
$info = SQLite3::version();
if($info && isset($info['versionString'])) {
$version = trim($info['versionString']);
}
} else {
// Fallback to using sqlite_version() query
$file = $databaseConfig['path'] . '/' . $databaseConfig['database'];
$file = preg_replace('/\/$/', '', $file);
$conn = @(new PDO("sqlite:$file"));
if($conn) {
$result = @$conn->query('SELECT sqlite_version()');
$version = $result->fetchColumn();
}
}
return $version;
}
public function requireDatabaseVersion($databaseConfig) {
$success = false;
$error = '';
$version = $this->getDatabaseVersion($databaseConfig);
if($version) {
$success = version_compare($version, '3.3', '>=');
if(!$success) {
$error = "Your SQLite3 library version is $version. It's recommended you use at least 3.3.";
}
}
return array(
'success' => $success,
'error' => $error
);
}
/**
* Ensure that the database connection is able to use an existing database,
* or be able to create one if it doesn't exist.
*
* Unfortunately, PostgreSQLDatabase doesn't support automatically creating databases
* at the moment, so we can only check that the chosen database exists.
*
* @param array $databaseConfig Associative array of db configuration, e.g. "server", "username" etc
* @return array Result - e.g. array('success' => true, 'alreadyExists' => 'true')
*/
public function requireDatabaseOrCreatePermissions($databaseConfig) {
$success = false;
$alreadyExists = false;
$canCreate = false;
$check = $this->requireDatabaseConnection($databaseConfig);
$conn = $check['connection'];
if($conn) {
$success = true;
$alreadyExists = true;
} else {
$success = false;
$alreadyExists = false;
}
return array(
'success' => $success,
'alreadyExists' => $alreadyExists,
);
}
/**
* Creates the provided directory and prepares it for
* storing SQLlite. Use {@link secure_db_dir()} to
* secure it against unauthorized access.
*
* @param String $path Absolute path, usually with a hidden folder.
* @return boolean
*/
public static function create_db_dir($path) {
return (!file_exists($path)) ? mkdir($path) : true;
}
/**
* Secure the provided directory via web-access
* by placing a .htaccess file in it.
* This is just required if the database directory
* is placed within a publically accessible webroot (the
* default path is in a hidden folder within assets/).
*
* @param String $path Absolute path, containing a SQLite datatbase
* @return boolean
*/
public static function secure_db_dir($path) {
return (is_writeable($path)) ? file_put_contents($path . '/.htaccess', 'deny from all') : false;
}
}