Support custom save function
[misc/kostenrechnung] / ajax / ajax.php
1 <?php
2
3 require_once('../init.php');
4
5 function fetch($mask)
6 {
7   $fields = array("to_char(sys_edit,'DD.MM.YYYY HH24:mm') AS sys_edit", 'sys_user');
8   foreach ($mask['edit'] as $field => $info) {
9     if ($info['sql'] === false) continue;
10     if ($info['type'] == 'date')
11       $fields[] = sprintf("to_char(%s,'DD.MM.YYYY') AS %s",
12                           empty($info['sql']) ? $field : $info['sql'],
13                           $field);
14     elseif ($info['type'] != 'passwd')
15       $fields[] = empty($info['sql']) ? $field : $info['sql'] . ' AS ' . $field;
16   }
17
18   $sql = sprintf('SELECT id,%s FROM %s WHERE id = %d',
19                  implode(',', $fields),
20                  $mask['table'], $_POST['id']);
21
22   $sth = pg_query($sql);
23   if ($sth === false) return false;
24
25   $row = pg_fetch_assoc($sth);
26
27   foreach ($mask['edit'] as $field => $info)
28     if ($info['type'] == 'boolean')
29       $row[$field] = $row[$field]?true:false;
30     elseif ($info['type'] == 'passwd')
31       $row[$field] = '';
32     elseif (array_key_exists('format', $info))
33       $row[$field] = sprintf($info['format'], $row[$field]);
34
35   return $row;
36 }
37
38 function details($mask)
39 {
40   if (empty($_POST['id']))
41     return array('error' => 'Missing ID');
42
43   $fields = array();
44   foreach ($mask['details']['list'] as $field => $info) {
45     if ($info['type'] == 'date')
46       $fields[] = sprintf("to_char(%s,'DD.MM.YYYY') AS %s",
47                           empty($info['sql']) ? $field : $info['sql'],
48                           $field);
49     elseif (!array_key_exists('fetch',$info))
50       $fields[] = empty($info['sql']) ? $field : $info['sql'] . ' AS ' . $field;
51   }
52
53   if (count($fields)) {
54     $sql = sprintf('SELECT id,%s FROM %s WHERE id = %d',
55                    implode(',', $fields),
56                    $mask['table'], $_POST['id']);
57
58     $sth = pg_query($sql);
59
60     if (!$sth)
61       return array('error' => pg_last_error(),
62                    'sql' => $sql);
63
64     $row = pg_fetch_assoc($sth);
65   } else {
66     $row = array();
67   }
68
69   foreach ($mask['details']['list'] as $field => $info)
70     if (array_key_exists('format', $info))
71       $row[$field] = sprintf($info['format'], $row[$field]);
72     elseif (array_key_exists('fetch', $info))
73       $row[$field] = $info['fetch']();
74
75   return $row;
76 }
77
78 function format_decimal($value)
79 {
80   $value = str_replace(',','.',$value);
81   return sprintf("%.2f", $value);
82 }
83
84 function save($mask)
85 {
86   if (array_key_exists('save', $mask))
87     return $mask['save']($mask);
88
89   if (empty($_POST['id']))
90     return array('error' => 'Missing ID');
91
92   $update = array(sprintf("sys_user = '%s'", pg_escape_string($_SESSION['sys']['login'])),
93                   "sys_edit = now()");
94
95   foreach ($mask['edit'] as $field => $info) {
96     if ($info['required'] === true && !strlen($_POST[$field]))
97       return array('error' => sprintf('Pflichtfeld %s nicht ausgefüllt', $info['name']),
98                    'errormsg' => 'Pflichtfelder nicht ausgefüllt');
99
100     if ($info['type'] == 'boolean') {
101       $update[] = sprintf("%s=%d", $field, $_POST[$field] == 'on'?1:0);
102     } elseif ($info['type'] == 'number' || $info['type'] == 'hidden' || ($info['type'] == 'select' && $info['options_string'] !== true)) {
103       if (empty($_POST[$field]) && $info['null'] === true)
104         $update[] = sprintf("%s=NULL", $field);
105       else
106         $update[] = sprintf("%s=%d", $field, $_POST[$field]);
107     } elseif ($info['type'] == 'decimal') {
108       if (empty($_POST[$field]) && $info['null'] === true)
109         $update[] = sprintf("%s=NULL", $field);
110       else
111         $update[] = sprintf("%s=%s", $field, format_decimal($_POST[$field]));
112     } elseif ($info['type'] == 'passwd') {
113       if (!empty($_POST[$field]))
114         $update[] = sprintf("%s='%s'", $field,
115                             pg_escape_string(passwd(empty($_POST['login'])?$_SESSION['sys']['login']:$_POST['login'],
116                                                     $_POST[$field])));
117     } else {
118       if (empty($_POST[$field]) && $info['null'] === true)
119         $update[] = sprintf("%s=NULL", $field);
120       else
121         $update[] = sprintf("%s='%s'", $field, pg_escape_string($_POST[$field]));
122     }
123   }
124
125   $sql = sprintf('UPDATE %s SET %s WHERE id = %d',
126                  empty($mask['edit_table']) ? $mask['table'] : $mask['edit_table'],
127                  implode(', ', $update),
128                  intval($_POST['id']));
129
130   $sth = pg_query($sql);
131
132   if ($sth === false) {
133     error_log($sql . ': ' . pg_last_error());
134     return array('error' => pg_last_error(),
135                  'sql' => $sql);
136   }
137
138   return array('status' => true);
139 }
140
141 function insert($mask)
142 {
143   if (array_key_exists('insert', $mask))
144     return $mask['insert']($mask);
145
146   $fields = array('sys_user','sys_edit');
147   $values = array("'".pg_escape_string($_SESSION['sys']['login'])."'", 'now()');
148
149   foreach ($mask['edit'] as $field => $info) {
150     if ($info['required'] === true && !strlen($_POST[$field]))
151       return array('error' => sprintf('Pflichtfeld %s nicht ausgefüllt', $info['name']),
152                    'errormsg' => 'Pflichtfelder nicht ausgefüllt');
153
154     if ($info['type'] == 'boolean') {
155       $fields[] = $field;
156       $values[] = $_POST[$field] == 'on'?1:0;
157     } elseif ($info['type'] == 'number' || $info['type'] == 'hidden' || ($info['type'] == 'select' && $info['options_string'] !== true)) {
158       $fields[] = $field;
159       if (empty($_POST[$field]) && $info['null'] === true)
160         $values[] = 'NULL';
161       else
162         $values[] = intval($_POST[$field]);
163     } elseif ($info['type'] == 'decimal') {
164       $fields[] = $field;
165       if (empty($_POST[$field]) && $info['null'] === true)
166         $values[] = 'NULL';
167       else
168         $values[] = format_decimal($_POST[$field]);
169     } elseif ($info['type'] == 'passwd') {
170       if (!empty($_POST[$field])) {
171         $fields[] = $field;
172         $values[] = sprintf("'%s'", pg_escape_string(passwd(empty($_POST['login'])?$_SESSION['sys']['login']:$_POST['login'],
173                                                             $_POST[$field])));
174       }
175     } else {
176       $fields[] = $field;
177       if (empty($_POST[$field]) && $info['null'] === true)
178         $values[] = 'NULL';
179       else
180         $values[] = sprintf("'%s'", pg_escape_string($_POST[$field]));
181     }
182   }
183
184   $sql = sprintf('INSERT INTO %s (%s) VALUES (%s)',
185                  empty($mask['edit_table']) ? $mask['table'] : $mask['edit_table'],
186                  implode(',', $fields),
187                  implode(',', $values));
188
189   $sth = pg_query($sql);
190
191   if ($sth === false) {
192     error_log($sql . ': ' . pg_last_error());
193     return array('error' => pg_last_error(),
194                  'sql' => $sql);
195   }
196
197   return array('status' => true);
198 }
199
200 function delete_or_copy($mask)
201 {
202   if (empty($_POST['id']))
203     return array('error' => 'Missing ID');
204
205   if (!empty($mask['edit_table']))
206     return array('error' => 'Cannot handle deletion for secondary table');
207
208   if (DELETE_COPY === true) {
209     $sql = sprintf("INSERT INTO %s_deleted SELECT * FROM %s WHERE id = %d",
210                    $mask['table'], $mask['table'], $_POST['id']);
211
212     $sth = pg_query($sql);
213
214     if ($sth === false) {
215       error_log($sql . ': ' . pg_last_error());
216       return array('error' => pg_last_error(),
217                    'sql' => $sql);
218     }
219
220     $sql = sprintf("UPDATE %s_deleted SET sys_user='%s',sys_edit=now() WHERE id = %d",
221                    $mask['table'], $_SESSION['sys']['login'], $_POST['id']);
222
223     $sth = pg_query($sql);
224
225     if ($sth === false) {
226       error_log($sql . ': ' . pg_last_error());
227       return array('error' => pg_last_error(),
228                    'sql' => $sql);
229     }
230   }
231
232   $sql = sprintf("DELETE FROM %s WHERE id = %d", $mask['table'], $_POST['id']);
233
234   $sth = pg_query($sql);
235
236   if ($sth === false) {
237     error_log($sql . ': ' . pg_last_error());
238     return array('error' => pg_last_error(),
239                  'sql' => $sql);
240   }
241
242   return array('status' => true);
243 }
244
245 function set_variable($name,$mask)
246 {
247   if (!array_key_exists('variables',$mask))
248     return array('error' => 'Unknown variable ' . htmlspecialchars($_POST['name']));
249
250   if (!array_key_exists($_POST['name'],$mask['variables']))
251     return array('error' => 'Unknown variable ' . htmlspecialchars($_POST['name']));
252
253   $_SESSION[$name . '.' . $_POST['name']] = $_POST['value'];
254
255   if (array_key_exists('postcall',$mask['variables'][$_POST['name']]))
256     $mask['variables'][$_POST['name']]['postcall']();
257
258   return array('status' => true);
259 }
260
261 function get_infos($mask)
262 {
263   if (!array_key_exists('info',$mask))
264     return array('error' => 'Unknown callback ' . htmlspecialchars($_POST['name']));
265
266   if (!array_key_exists($_POST['name'],$mask['info']))
267     return array('error' => 'Unknown callback ' . htmlspecialchars($_POST['name']));
268
269   if (!array_key_exists('sql',$mask['info'][$_POST['name']]))
270     return array('error' => 'Unknown callback ' . htmlspecialchars($_POST['name']));
271
272   $sql = $mask['info'][$_POST['name']]['sql'];
273
274   while (preg_match('/\{([^\}]*)\}/', $sql, $matches))
275     $sql = str_replace('{'.$matches[1].'}', $_POST[$matches[1]], $sql);
276
277   return array('info' => query_db($sql),
278                'parameter' => $_POST);
279 }
280
281 if (empty($_POST['func']))
282   exit;
283
284 if (empty($_POST['source']))
285   exit;
286
287 connect_db();
288 if (load_mask($_POST['source']) === false) exit;
289
290 $data = array('error' => 'Unknown function');
291
292 if ($_POST['func'] == 'fetch') {
293   $data = fetch($mask);
294 } elseif ($_POST['func'] == 'details') {
295   $data = details($mask);
296 } elseif ($_POST['func'] == 'save') {
297   $data = save($mask);
298 } elseif ($_POST['func'] == 'insert') {
299   $data = insert($mask);
300 } elseif ($_POST['func'] == 'delete') {
301   $data = delete_or_copy($mask);
302 } elseif ($_POST['func'] == 'setvar') {
303   $data = set_variable($_POST['source'],$mask);
304 } elseif ($_POST['func'] == 'info') {
305   $data = get_infos($mask);
306 }
307
308 format_ajax($data);
309
310 ?>