Selaa lähdekoodia

Refactored code

Maurits van der Schee 9 vuotta sitten
vanhempi
commit
aa38cb63e0
4 muutettua tiedostoa jossa 188 lisäystä ja 142 poistoa
  1. 1
    1
      .htaccess
  2. 187
    2
      index.php
  3. 0
    95
      list.php
  4. 0
    44
      read.php

+ 1
- 1
.htaccess Näytä tiedosto

@@ -1,5 +1,5 @@
1 1
 RewriteEngine On
2
-RewriteBase /api/
2
+#RewriteBase /api/
3 3
 
4 4
 RewriteCond %{REQUEST_METHOD} GET
5 5
 RewriteCond %{REQUEST_FILENAME} !-f

+ 187
- 2
index.php Näytä tiedosto

@@ -1,6 +1,191 @@
1 1
 <?php
2 2
 include "config.php";
3 3
 
4
-$action = preg_replace('/[^a-z]/','',isset($_GET["action"])?$_GET["action"]:'list');
4
+function connectDatabase($hostname,$username,$password,$database) {
5
+	global $config;
6
+	$mysqli = new mysqli($hostname,$username,$password,$database);
7
+	if ($mysqli->connect_errno) {
8
+		die('Connect failed: '.$mysqli->connect_error);
9
+	}
10
+	return $mysqli;
11
+}
12
+
13
+function parseGetParameter($name,$characters,$default) {
14
+	$value = isset($_GET[$name])?$_GET[$name]:$default;
15
+	return $characters?preg_replace("/[^$characters]/",'',$value):$value;
16
+}
5 17
 
6
-if (in_array($action,array('list','read','create','update','delete'))) include $action.'.php';
18
+function applyWhitelist($table,$action,$list) {
19
+	if ($list===false) return $table;
20
+	$list = array_filter($list, function($actions){
21
+		return strpos($actions,$action[0])!==false;
22
+	});
23
+	return array_intersect($table, array_keys($list));
24
+	
25
+}
26
+
27
+function applyBlacklist($table,$action,$list) {
28
+	if ($list===false) return $table;
29
+	$list = array_filter($list, function($actions) use ($action) { 
30
+		return strpos($actions,$action[0])!==false; 
31
+	});
32
+	return array_diff($table, array_keys($list));
33
+}
34
+
35
+function applyWhitelistAndBlacklist($table, $action, $whitelist, $blacklist) {
36
+	$table = applyWhitelist($table, $action, $whitelist);
37
+	$table = applyBlacklist($table, $action, $blacklist);
38
+	if (empty($table)) exitWith404();
39
+	return $table;
40
+}
41
+
42
+function processTableParameter($table,$database,$mysqli) {
43
+	global $config;
44
+	$tablelist = explode(',',$table);
45
+	$tables = array();
46
+	foreach ($tablelist as $table) {
47
+		$table = str_replace('*','%',$table);
48
+		if ($result = $mysqli->query("SELECT `TABLE_NAME` FROM `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_NAME` LIKE '$table' AND `TABLE_SCHEMA` = '$database'")) {
49
+			while ($row = $result->fetch_row()) $tables[] = $row[0];
50
+			$result->close();
51
+		}
52
+	}
53
+	return $tables;
54
+}
55
+
56
+function findPrimaryKey($table,$database,$mysqli) {
57
+	global $config;
58
+	$keys = array();
59
+	if ($result = $mysqli->query("SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `COLUMN_KEY` = 'PRI' AND `TABLE_NAME` = '$table[0]' AND `TABLE_SCHEMA` = '$database'")) {
60
+		while ($row = $result->fetch_row()) $keys[] = $row[0];
61
+		$result->close();
62
+	}
63
+	return count($keys)?$keys[0]:false;
64
+}
65
+
66
+function exitWith404() {
67
+	die(header("Content-Type:",true,404));
68
+} 
69
+
70
+function startOutput($callback) {
71
+	if ($callback) {
72
+		header("Content-Type: application/javascript");
73
+		echo $callback.'(';
74
+	} else {
75
+		header("Content-Type: application/json");
76
+	}
77
+}
78
+
79
+function endOutput($callback) {
80
+	if ($callback) {
81
+	    echo ');';
82
+	}
83
+}
84
+
85
+function processKeyParameter($key,$table,$database,$mysqli) {
86
+	if ($key) {
87
+		$key = array($key,findPrimaryKey($table,$database,$mysqli));
88
+		if ($key[1]===false) exitWith404();
89
+	}
90
+	return $key;
91
+}
92
+
93
+function processFilterParameter($filter) {
94
+	if ($filter) {
95
+		$filter = explode(':',$filter,2);
96
+		if (count($filter)==2) {
97
+			$filter[0] = preg_replace('/[^a-zA-Z0-9\-_]/','',$filter[0]);
98
+			$filter[1] = $mysqli->real_escape_string($filter[1]);
99
+			$filter[2] = 'LIKE';
100
+			if ($match=='any'||$match=='start') $filter[1] .= '%';
101
+			if ($match=='any'||$match=='end') $filter[1] = '%'.$filter[1];
102
+			if ($match=='exact') $filter[2] = '=';
103
+			if ($match=='lower') $filter[2] = '<';
104
+			if ($match=='upto') $filter[2] = '<=';
105
+			if ($match=='from') $filter[2] = '>=';
106
+			if ($match=='higher') $filter[2] = '>';
107
+		} else {
108
+			$filter = false;
109
+		}
110
+	}
111
+	return $filter;
112
+}
113
+
114
+function processPageParameter($page) {
115
+	if ($page) {
116
+		$page = explode(':',$page,2);
117
+		if (count($page)<2) $page[1]=20;
118
+		$page[0] = ($page[0]-1)*$page[1];
119
+	}
120
+	return $page;
121
+}
122
+$action   = parseGetParameter('action', 'a-z', 'list');
123
+$table    = parseGetParameter('table', 'a-zA-Z0-9\-_*,', '*');
124
+$key      = parseGetParameter('key', 'a-zA-Z0-9\-,', false); // auto-increment or uuid 
125
+$callback = parseGetParameter('callback', 'a-zA-Z0-9\-_', false);
126
+$page     = parseGetParameter('page', '0-9', false);
127
+$filter   = parseGetParameter('filter', false, 'start');
128
+$match    = parseGetParameter('match', 'a-z', false);
129
+
130
+$mysqli = connectDatabase($config["hostname"], $config["username"], $config["password"], $config["database"]);
131
+
132
+$table = processTableParameter($table,$config["database"],$mysqli);
133
+$key = processKeyParameter($key,$table,$config["database"],$mysqli);
134
+$filter = processFilterParameter($filter);
135
+$page = processPageParameter($page);
136
+
137
+$table = applyWhitelistAndBlacklist($table,$action,$config['whitelist'],$config['blacklist']);
138
+
139
+startOutput($callback);
140
+switch($action){
141
+	case 'list': 
142
+		echo '{';
143
+		$tables = $table;
144
+		$first_table = true;
145
+		foreach ($tables as $table) {
146
+			if ($first_table) $first_table = false;
147
+			else echo ',';
148
+			echo '"'.$table.'":{';
149
+			if (is_array($page)) {
150
+				$sql = "SELECT COUNT(*) FROM `$table`";
151
+				if (is_array($filter)) $sql .= " WHERE `$filter[0]` $filter[2] '$filter[1]'";
152
+				if ($result = $mysqli->query($sql)) {
153
+					$pages = $result->fetch_row();
154
+					$pages = floor($pages[0]/$page[1])+1;
155
+					echo '"pages":"'.$pages.'",';
156
+				}
157
+			}
158
+			echo '"columns":';
159
+			$sql = "SELECT * FROM `$table`";
160
+			if (is_array($filter)) $sql .= " WHERE `$filter[0]` $filter[2] '$filter[1]'";
161
+			if (is_array($page)) $sql .= " LIMIT $page[1] OFFSET $page[0]";
162
+			if ($result = $mysqli->query($sql)) {
163
+				$fields = array();
164
+				foreach ($result->fetch_fields() as $field) $fields[] = $field->name;
165
+				echo json_encode($fields);
166
+				echo ',"records":[';
167
+				$first_row = true;
168
+				while ($row = $result->fetch_row()) {
169
+					if ($first_row) $first_row = false;
170
+					else echo ',';
171
+					echo json_encode($row);
172
+				}
173
+				$result->close();
174
+			}
175
+			echo ']}';
176
+		}
177
+		echo '}';
178
+		break;
179
+	case 'read': 
180
+		if ($result = $mysqli->query("SELECT * FROM `$table[0]` WHERE `$key[1]` = '$key[0]'")) {
181
+			$value = $result->fetch_assoc();
182
+			echo json_encode($value);
183
+			$result->close();
184
+		}
185
+		break;
186
+	case 'create': break;
187
+	case 'update': break;
188
+	case 'delete': break;
189
+	default: exitWith404();
190
+}
191
+endOutput($callback);

+ 0
- 95
list.php Näytä tiedosto

@@ -1,95 +0,0 @@
1
-<?php
2
-$table = str_replace('*','%',preg_replace('/[^a-zA-Z0-9\-_*,]/','',isset($_GET["table"])?$_GET["table"]:'*'));
3
-$callback = preg_replace('/[^a-zA-Z0-9\-_]/','',isset($_GET["callback"])?$_GET["callback"]:false);
4
-$page = preg_replace('/[^0-9:]/','',isset($_GET["page"])?$_GET["page"]:false);
5
-$filter = isset($_GET["filter"])?$_GET["filter"]:false;
6
-$match = isset($_GET["match"])&&in_array($_GET["match"],array('any','start','end','exact','lower','upto','from','higher'))?$_GET["match"]:'start';
7
-
8
-$mysqli = new mysqli($config["hostname"], $config["username"], $config["password"], $config["database"]);
9
-if ($mysqli->connect_errno) die('Connect failed: '.$mysqli->connect_error);
10
-
11
-$tablelist = explode(',',$table);
12
-$tables = array();
13
-
14
-foreach ($tablelist as $table) {
15
-    if ($result = $mysqli->query("SELECT `TABLE_NAME` FROM `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_NAME` LIKE '$table' AND `TABLE_SCHEMA` = '$config[database]'")) {
16
-        while ($row = $result->fetch_row()) $tables[] = $row[0];
17
-        $result->close();
18
-    }
19
-}
20
-
21
-if ($config["list_whitelist"]!==false) $tables = array_intersect($tables, $config["list_whitelist"]);
22
-if ($config["list_blacklist"]!==false) $tables = array_diff($tables, $config["list_blacklist"]);
23
-
24
-if (empty($tables)) {
25
-    die(header("Content-Type:",true,404));
26
-} if ($callback) {
27
-    header("Content-Type: application/javascript");
28
-    echo $callback.'(';
29
-} else {
30
-    header("Content-Type: application/json");
31
-}
32
-
33
-if ($filter) {
34
-    $filter = explode(':',$filter,2);
35
-    if (count($filter)==2) {
36
-        $filter[0] = preg_replace('/[^a-zA-Z0-9\-_]/','',$filter[0]);
37
-        $filter[1] = $mysqli->real_escape_string($filter[1]);
38
-        $filter[2] = 'LIKE';
39
-        if ($match=='any'||$match=='start') $filter[1] .= '%';
40
-        if ($match=='any'||$match=='end') $filter[1] = '%'.$filter[1];
41
-        if ($match=='exact') $filter[2] = '=';
42
-        if ($match=='lower') $filter[2] = '<';
43
-        if ($match=='upto') $filter[2] = '<=';
44
-        if ($match=='from') $filter[2] = '>=';
45
-        if ($match=='higher') $filter[2] = '>';
46
-    } else {
47
-        $filter = false;
48
-    }
49
-}
50
-
51
-if ($page) {
52
-    $page = explode(':',$page,2);
53
-    if (count($page)<2) $page[1]=20;
54
-    $page[0] = ($page[0]-1)*$page[1];
55
-}
56
-
57
-echo '{';
58
-$first_table = true;
59
-foreach ($tables as $table) {
60
-    if ($first_table) $first_table = false;
61
-    else echo ',';
62
-    echo '"'.$table.'":{';
63
-    if (is_array($page)) {
64
-        $sql = "SELECT COUNT(*) FROM `$table`";
65
-        if (is_array($filter)) $sql .= " WHERE `$filter[0]` $filter[2] '$filter[1]'";
66
-        if ($result = $mysqli->query($sql)) {
67
-            $pages = $result->fetch_row();
68
-            $pages = floor($pages[0]/$page[1])+1;
69
-            echo '"pages":"'.$pages.'",';
70
-        }
71
-    }
72
-    echo '"columns":';
73
-    $sql = "SELECT * FROM `$table`";
74
-    if (is_array($filter)) $sql .= " WHERE `$filter[0]` $filter[2] '$filter[1]'";
75
-    if (is_array($page)) $sql .= " LIMIT $page[1] OFFSET $page[0]";
76
-    if ($result = $mysqli->query($sql)) {
77
-        $fields = array();
78
-        foreach ($result->fetch_fields() as $field) $fields[] = $field->name;
79
-        echo json_encode($fields);
80
-        echo ',"records":[';
81
-        $first_row = true;
82
-        while ($row = $result->fetch_row()) {
83
-            if ($first_row) $first_row = false;
84
-            else echo ',';
85
-            echo json_encode($row);
86
-        }
87
-        $result->close();
88
-    }
89
-    echo ']}';
90
-}
91
-echo '}';
92
-
93
-if ($callback) {
94
-    echo ');';
95
-}

+ 0
- 44
read.php Näytä tiedosto

@@ -1,44 +0,0 @@
1
-<?php
2
-$key = preg_replace('/[^a-zA-Z0-9\-_]/','',isset($_GET["key"])?$_GET["key"]:false);
3
-$table = preg_replace('/[^a-zA-Z0-9\-_]/','',isset($_GET["table"])?$_GET["table"]:false);
4
-$callback = preg_replace('/[^a-zA-Z0-9\-_]/','',isset($_GET["callback"])?$_GET["callback"]:false);
5
-
6
-$mysqli = new mysqli($config["hostname"], $config["username"], $config["password"], $config["database"]);
7
-if ($mysqli->connect_errno) die('Connect failed: '.$mysqli->connect_error);
8
-
9
-$tables = array();
10
-
11
-if ($result = $mysqli->query("SELECT `TABLE_NAME` FROM `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_NAME` = '$table' AND `TABLE_SCHEMA` = '$config[database]'")) {
12
-    while ($row = $result->fetch_row()) $tables[] = $row[0];
13
-    $result->close();
14
-}
15
-
16
-$keys = array();
17
-
18
-if ($result = $mysqli->query("SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `COLUMN_KEY` = 'PRI' AND `TABLE_NAME` = '$table' AND `TABLE_SCHEMA` = '$config[database]'")) {
19
-	while ($row = $result->fetch_row()) $keys[] = $row[0];
20
-	$result->close();
21
-}
22
-
23
-if ($config["read_whitelist"]!==false) $tables = array_intersect($tables, $config["read_whitelist"]);
24
-if ($config["read_blacklist"]!==false) $tables = array_diff($tables, $config["read_blacklist"]);
25
-
26
-if (empty($tables) || empty($keys)) {
27
-    die(header("Content-Type:",true,404));
28
-} if ($callback) {
29
-    header("Content-Type: application/javascript");
30
-    echo $callback.'(';
31
-} else {
32
-    header("Content-Type: application/json");
33
-}
34
-
35
-if ($result = $mysqli->query("SELECT * FROM `$tables[0]` WHERE `$keys[0]` = '$key'")) {
36
-	$value = $result->fetch_assoc();
37
-    if ($value) echo json_encode($value);
38
-    else die(header("Content-Type:",true,404));
39
-    $result->close();
40
-}
41
-
42
-if ($callback) {
43
-    echo ');';
44
-}

Loading…
Peruuta
Tallenna