Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2150 mathias 1
<?php
2
	// db settings
3
	$dbserver = 'localhost';
4
	$dbuser = 'root';
5
	$dbpassword = 'root';
6
 
7
	error_reporting(E_ALL);
8
 
9
	/*
10
		Simple protocol:
11
			- Inputs via POST variables.
12
			- Output is a string that can be evaluated into a JSON
13
			  First element of the array contains return status.
14
 
15
		This simplified tutorial code should not be deployed without a security review.
16
	*/
17
 
18
	@include "json.php";
19
 
20
	// set up response encoding
21
	header("Content-Type: text/html; charset=utf-8");
22
 
23
	// util
24
	function getPostString($inName) {
25
		// make sure input strings are 'clean'
26
		return mysql_real_escape_string(@$_POST[$inName]);
27
	}
28
 
29
	// used for json encoding
30
	$json = new Services_JSON();
31
 
32
	function echoJson($inData) {
33
		global $json;
34
		// delay in ms
35
		$delay = getPostString('delay');
36
		if (!empty($delay))
37
			usleep($delay * 1000);
38
		echo '/* ' . $json->encode($inData) . ' */';
39
	}
40
 
41
	function error($inMessage) {
42
		$inMessage = str_replace('"', '\\"', $inMessage);
43
		error_log($inMessage);
44
		//echo '/* ({error: true, message: "' . $inMessage . '"}) */';
45
		echoJson(array('error' => true, 'message' => $inMessage));
46
		exit;
47
	}
48
 
49
 
50
	function getArray($inResult, $inArray="true") {
51
		$o = Array();
52
		while ($row = ($inArray ? mysql_fetch_row($inResult) : mysql_fetch_object($inResult)))
53
			$o[] = $row;
54
		return $o;
55
	}
56
 
57
	// connect to DB
58
	mysql_connect($dbserver, $dbuser, $dbpassword);
59
 
60
	// select DB
61
	$database = getPostString("database");
62
	$database = ($database ? $database : $db);
63
	if (!mysql_select_db($database))
64
		error('failed to select db: ' . mysql_error());
65
 
66
	// select table
67
	$table = getPostString("table");
68
	$table = ($table ? $table : $dbtable);
69
 
70
	// cache
71
	$colCache = NULL;
72
	$pkCache = NULL;
73
 
74
	// set UTF8 output (MySql > 4.0)
75
	mysql_query("SET NAMES UTF8");
76
 
77
	// server, database, table meta data
78
	function getDatabases() {
79
		$result = mysql_query("SHOW DATABASES");
80
		$output = Array();
81
		while ($row = mysql_fetch_row($result)) {
82
			$r = strtolower($row[0]);
83
			if ($r != 'mysql' && $r != 'information_schema')
84
				$output[] = $row[0];
85
		}
86
		return $output;
87
	}
88
 
89
	function getTables() {
90
		global $database;
91
		$result = mysql_query("SHOW TABLES FROM $database");
92
		$output = Array();
93
		while ($row = mysql_fetch_row($result))
94
			$output[] = $row[0];
95
		return $output;
96
	}
97
 
98
	function getColumns() {
99
		global $table, $colCache;
100
		if (!$colCache) {
101
			$result = mysql_query("SHOW COLUMNS FROM `$table`");
102
			return getArray($result, false);
103
			$colCache = getArray($result, false);
104
		}
105
		return $colCache;
106
	}
107
 
108
	// returns object: $this->name, $this->index
109
	function getPk() {
110
		global $pkCache;
111
		if (!$pkCache) {
112
			$k = '';
113
			$columns = getColumns();
114
			for ($i=0; $i < count($columns); $i++) {
115
				$c = $columns[$i];
116
				if ($c->Key == 'PRI') {
117
					$k = $c->Field;
118
					break;
119
				}
120
			}
121
			$pkCache->index = $i;
122
			$pkCache->name = $k;
123
		}
124
		return $pkCache;
125
	}
126
 
127
	function getTableInfo() {
128
		global $table, $database;
129
		$c = getColumns();
130
		$r = rowcount();
131
		return array("count" => $r, "columns" => $c, "database" => $database, "table" => $table);
132
	}
133
 
134
	function getOldPostPkValue() {
135
		$pk = getPk();
136
		return getPostString('_o' . $pk->index);
137
	}
138
 
139
	function getNewPostPkValue() {
140
		$pk = getPk();
141
		return getPostString('_' . $pk->index);
142
	}
143
 
144
	function getPostColumns() {
145
		$columns = getColumns();
146
		for ($i=0, $a=array(), $p; (($p=getPostString("_".$i)) != ''); $i++) {
147
			$r = new stdClass();
148
			$r->name = $columns[$i]->Field;
149
			$r->value = $p;
150
			$a[] = $r;
151
		}
152
		return $a;
153
	}
154
 
155
	function getOrderBy() {
156
		$ob = getPostString("orderby");
157
		if (is_numeric($ob)) {
158
			$columns = getColumns();
159
			$ob = $columns[intval($ob)-1]->Field;
160
		}
161
		return $ob;
162
	}
163
 
164
	function getWhere() {
165
		$w = getPostString("where");
166
		return ($w ? " WHERE $w" : "");
167
	}
168
 
169
	// basic operations
170
	function rowcount()	{
171
		global $table;
172
		$query = "SELECT COUNT(*) FROM `$table`" . getWhere();
173
		$result = mysql_query($query);
174
		if (!$result)
175
			error("failed to perform query: $query. " . mysql_error());
176
		if ($row = mysql_fetch_row($result))
177
			return $row[0];
178
		else
179
			return 0;
180
	}
181
 
182
	function select($inQuery = '') {
183
		global $table;
184
		// built limit clause
185
		$lim = (int)getPostString("limit");
186
		$off = (int)getPostString("offset");
187
		$limit = ($lim || $off ? " LIMIT $off, $lim" : "");
188
		// build order by clause
189
		$desc = (boolean)getPostString("desc");
190
		$ob = getOrderBy();
191
		$orderby = ($ob ? " ORDER BY `" . $ob . "`" . ($desc ? " DESC" : "") : "");
192
		// build query
193
		$query = ($inQuery ? $inQuery : "SELECT * FROM `$table`" . getWhere() . $orderby . $limit);
194
		// execute query
195
		if (!$result = mysql_query($query))
196
			error("failed to perform query: $query. " . mysql_error());
197
		// fetch each result row
198
		return getArray($result);
199
	}
200
 
201
	function reflectRow() {
202
		global $table;
203
		$pk = getPk();
204
		$key = getNewPostPkValue();
205
		$where = "`$pk->name`=\"$key\"";
206
		return select("SELECT * FROM `$table` WHERE $where LIMIT 1");
207
	}
208
 
209
	function update() {
210
		// build set clause
211
		for ($i=0, $set = array(), $cols = getPostColumns(), $v; ($v=$cols[$i]); $i++)
212
			$set[] = "`$v->name` = '$v->value'";
213
		$set = implode(', ', $set);
214
		// our table
215
		global $table;
216
		// build query
217
		$pk = getPk();
218
		$pkValue = getOldPostPkValue();
219
		$query = "UPDATE `$table` SET $set WHERE `$pk->name` = '$pkValue' LIMIT 1";
220
		// execute query
221
		if (!mysql_query($query))
222
			error("failed to perform query: [$query]. " .
223
					"MySql says: [" . mysql_error() ."]");
224
		else {
225
			return reflectRow();
226
		}
227
	}
228
 
229
	function insert() {
230
		global $table;
231
		// build values clause
232
		for ($i=0, $values = array(), $cols = getPostColumns(), $v; ($v=$cols[$i]); $i++)
233
			$values[] = $v->value;
234
		$values = '"' . implode('", "', $values) . '"';
235
		// build query
236
		$query = "INSERT INTO `$table` VALUES($values)";
237
		// execute query
238
		if (!mysql_query($query))
239
			error("failed to perform query: [$query]. " .
240
					"MySql says: [" . mysql_error() ."]");
241
		else {
242
			return reflectRow();
243
		}
244
	}
245
 
246
	function delete() {
247
		global $table;
248
		// build query
249
		$n = getPostString("count");
250
		$pk = getPk();
251
		for ($i = 0, $deleted=array(); $i < $n; $i++) {
252
			$key = getPostString("_$i");
253
			array_push($deleted, $key);
254
			$query = "DELETE FROM `$table` WHERE `$pk->name`=\"$key\" LIMIT 1";
255
			// execute query
256
			if (!mysql_query($query) || mysql_affected_rows() != 1)
257
				error("failed to perform query: [$query]. " .
258
					"Affected rows: " . mysql_affected_rows() .". " .
259
					"MySql says: [" . mysql_error() ."]");
260
		}
261
		return $deleted;
262
	}
263
 
264
	// find (full text search)
265
	function findData($inFindCol, $inFind, $inOrderBy, $inFullText) {
266
		global $table;
267
		$where = ($inFullText ? "WHERE MATCH(`$inFindCol`) AGAINST ('$inFind')" : "WHERE $inFindCol LIKE '$inFind'");
268
		$query = "SELECT * FROM $table $where $inOrderBy";
269
		$result = mysql_query($query);
270
		// return rows
271
		return getArray($result);
272
	}
273
 
274
	// binary search through sorted data, supports start point ($inFindFrom) and direction ($inFindForward)
275
	function findRow($inData, $inFindFrom=-1, $inFindForward) {
276
		$b = -1;
277
		$l = count($inData);
278
		if (!$inData)
279
			return $b;
280
		if (!$inFindFrom==-1 || $l < 2)
281
			$b = 0;
282
		else {
283
			// binary search
284
			$t = $l-1;
285
			$b = 0;
286
			while ($b <= $t) {
287
				$p = floor(($b+$t)/2);
288
				$d = $inData[$p][0];
289
				if ($d < $inFindFrom)
290
					$b = $p + 1;
291
				else if ($d > $inFindFrom)
292
					$t = $p - 1;
293
				else {
294
					$b = $p;
295
					break;
296
				}
297
			}
298
			if ($inFindFrom == $inData[$b][0]) {
299
				// add or subtract 1
300
				$b = ($inFindForward ? ($b+1 > $l-1 ? 0 : $b+1) : ($b-1 < 0 ? $l-1 : $b-1) );
301
			}
302
			else if (!$inFindForward)
303
				// subtract 1
304
				$b = ($b-1 < 0 ? $l-1 : $b-1);
305
		}
306
		return $inData[$b][0];
307
	}
308
 
309
	function buildFindWhere($inFindData, $inKey, $inCol) {
310
		$o = Array();
311
		foreach($inFindData as $row)
312
			$o[] = $inCol . "='" . $row[$inKey] . "'";
313
		return (count($o) ? ' WHERE ' . implode(' OR ', $o) : '');
314
	}
315
 
316
	function find($inFindCol, $inFind='', $inOb='', $inFindFrom=0, $inFindForward=true, $inFullText=true) {
317
		global $table;
318
		// build order by clause
319
		$desc = (boolean)getPostString("desc");
320
		if (!$inOb)
321
			$inOb = getOrderBy();
322
		if ($inOb)
323
			$inOb = "`" . $inOb . "`"	;
324
		$orderby = ($inOb ? " ORDER BY $inOb " . ($desc ? " DESC" : "") : "");
325
		// update inputs from post
326
		if (!$inFind)
327
			$inFind = getPostString('findText');
328
		if (!$inFindCol)
329
			$inFindCol = getPostString('findCol');
330
		if (empty($inFindFrom))
331
			$inFindFrom = getPostString('findFrom');
332
		$ff = getPostString('findForward');
333
		if ($ff)
334
			$inFindForward = (strtolower($ff) == 'true' ? true : false);
335
		$ft = getPostString('findFullText');
336
		if ($ft)
337
			$inFullText = (strtolower($ft) == 'true' ? true : false);
338
 
339
		// get find data
340
		$f = findData($inFindCol, $inFind, $orderby,  $inFullText);
341
		$pk = getPk();
342
 
343
		// execute query
344
		$where = buildFindWhere($f, $pk->index, 'f');
345
		$query = "SELECT Row, f FROM (SELECT @row := @row + 1 AS Row, $pk->name as f FROM `$table` $orderby) AS tempTable $where";
346
		mysql_query('SET @row = -1;');
347
		if (!$result = mysql_query($query))
348
			error("failed to perform query: $query. " . mysql_error());
349
 
350
		// return row number
351
		return findRow(getArray($result), $inFindFrom, $inFindForward);
352
	}
353
 
354
	// our command list
355
	$cmds = array(
356
		"count" => "rowcount",
357
		"select" => "select",
358
		"update" => "update",
359
		"insert" => "insert",
360
		"delete" => "delete",
361
		"find" => "find",
362
		"databases" => "getDatabases",
363
		"tables" => "getTables",
364
		"columns" => "getColumns",
365
		"info" => "getTableInfo"
366
	);
367
 
368
	// process input params
369
	$cmd = @$_POST["command"];
370
 
371
	//$cmd="select";
372
 
373
	// dispatch command
374
	$func = @$cmds[$cmd];
375
	if (function_exists($func))
376
		echoJson(call_user_func($func));
377
	else
378
		error("bad command");
379
?>