df28d6c5 |
1 | <?PHP // $Id$ |
2 | |
3 | /// FUNCTIONS FOR DATABASE HANDLING //////////////////////////////// |
4 | |
5 | function execute_sql($command, $feedback=true) { |
6 | /// Completely general function - it just runs some SQL and reports success. |
7 | |
8 | global $db; |
9 | |
10 | $result = $db->Execute("$command"); |
11 | |
12 | if ($result) { |
13 | if ($feedback) { |
14 | echo "<P><FONT COLOR=green><B>".get_string("success")."</B></FONT></P>"; |
15 | } |
16 | return true; |
17 | } else { |
18 | if ($feedback) { |
19 | echo "<P><FONT COLOR=red><B>".get_string("error")."</B></FONT></P>"; |
20 | } |
21 | return false; |
22 | } |
23 | } |
24 | |
2b051f1c |
25 | function modify_database($sqlfile="", $sqlstring="") { |
26 | /// Assumes that the input text (file or string consists of |
27 | /// a number of SQL statements ENDING WITH SEMICOLONS. The |
28 | /// semicolons MUST be the last character in a line. |
df28d6c5 |
29 | /// Lines that are blank or that start with "#" are ignored. |
30 | /// Only tested with mysql dump files (mysqldump -p -d moodle) |
31 | |
32 | global $CFG; |
33 | |
2b051f1c |
34 | $success = true; // Let's be optimistic :-) |
35 | |
36 | if (!empty($sqlfile)) { |
37 | if (!is_readable($sqlfile)) { |
38 | $success = false; |
39 | echo "<P>Tried to modify database, but \"$sqlfile\" doesn't exist!</P>"; |
40 | return $success; |
41 | } else { |
42 | $lines = file($sqlfile); |
43 | } |
44 | } else { |
45 | $lines[] = $sqlstring; |
46 | } |
47 | |
48 | $command = ""; |
49 | |
50 | foreach ($lines as $line) { |
51 | $line = rtrim($line); |
52 | $length = strlen($line); |
53 | |
54 | if ($length and $line[0] <> "#") { |
55 | if (substr($line, $length-1, 1) == ";") { |
56 | $line = substr($line, 0, $length-1); // strip ; |
57 | $command .= $line; |
58 | $command = str_replace("prefix_", $CFG->prefix, $command); // Table prefixes |
59 | if (! execute_sql($command)) { |
60 | $success = false; |
df28d6c5 |
61 | } |
2b051f1c |
62 | $command = ""; |
63 | } else { |
64 | $command .= $line; |
df28d6c5 |
65 | } |
66 | } |
df28d6c5 |
67 | } |
68 | |
69 | return $success; |
2b051f1c |
70 | |
df28d6c5 |
71 | } |
72 | |
a3fb1c45 |
73 | /// FUNCTIONS TO MODIFY TABLES //////////////////////////////////////////// |
74 | |
92230499 |
75 | function table_column($table, $oldfield, $field, $type="integer", $size="10", |
76 | $signed="unsigned", $default="0", $null="not null", $after="") { |
a3fb1c45 |
77 | /// Add a new field to a table, or modify an existing one (if oldfield is defined). |
8a230a7d |
78 | global $CFG, $db; |
a3fb1c45 |
79 | |
80 | switch (strtolower($CFG->dbtype)) { |
81 | |
82 | case "mysql": |
83 | case "mysqlt": |
84 | |
85 | switch (strtolower($type)) { |
a3fb1c45 |
86 | case "integer": |
92230499 |
87 | $type = "INTEGER($size)"; |
a3fb1c45 |
88 | break; |
92230499 |
89 | case "varchar": |
90 | $type = "VARCHAR($size)"; |
a3fb1c45 |
91 | break; |
92 | } |
93 | |
94 | if (!empty($oldfield)) { |
95 | $operation = "CHANGE $oldfield $field"; |
96 | } else { |
97 | $operation = "ADD $field"; |
98 | } |
99 | |
100 | $default = "DEFAULT '$default'"; |
101 | |
102 | if (!empty($after)) { |
31ce4b53 |
103 | $after = "AFTER `$after`"; |
a3fb1c45 |
104 | } |
105 | |
106 | execute_sql("ALTER TABLE {$CFG->prefix}$table $operation $type $signed $default $null $after"); |
107 | break; |
108 | |
5a4d292b |
109 | case "postgres7": // From Petri Asikainen |
8a230a7d |
110 | //Check db-version |
111 | $dbinfo = $db->ServerInfo(); |
112 | $dbver = substr($dbinfo[version],0,3); |
113 | |
114 | $field = "$field"; |
5a4d292b |
115 | //to prevent conflicts with reserved words |
5a4d292b |
116 | $oldfield = "\"$oldfield\""; |
117 | |
118 | switch (strtolower($type)) { |
119 | case "integer": |
120 | if ($size <= 2) { |
121 | $type = "INT2"; |
122 | } |
123 | if ($size <= 4) { |
124 | $type = "INT"; |
125 | } |
126 | if ($size > 4) { |
127 | $type = "INT8"; |
128 | } |
129 | break; |
130 | case "varchar": |
131 | $type = "VARCHAR($size)"; |
132 | break; |
133 | } |
134 | |
8a230a7d |
135 | $default = "'$default'"; |
5a4d292b |
136 | |
137 | //After is not implemented in postgesql |
138 | //if (!empty($after)) { |
139 | // $after = "AFTER '$after'"; |
140 | //} |
141 | |
cefc7e81 |
142 | if ($oldfield != "\"\"") { |
5a4d292b |
143 | execute_sql("ALTER TABLE {$CFG->prefix}$table RENAME COLUMN $oldfield TO $field"); |
144 | } else { |
145 | execute_sql("ALTER TABLE {$CFG->prefix}$table ADD COLUMN $field $type"); |
146 | } |
147 | |
8a230a7d |
148 | if ($dbver >= "7.3") { |
149 | // modifying 'not null' is posible before 7.3 |
150 | //update default values to table |
151 | if ($null == "NOT NULL") { |
152 | execute_sql("UPDATE {$CFG->prefix}$table SET $field=$default where $field IS NULL"); |
153 | execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET $null"); |
154 | } else { |
155 | execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field DROP NOT NULL"); |
156 | } |
5a4d292b |
157 | } |
8a230a7d |
158 | |
159 | execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET DEFAULT $default"); |
5a4d292b |
160 | |
161 | break; |
a3fb1c45 |
162 | |
163 | default: |
164 | switch (strtolower($type)) { |
a3fb1c45 |
165 | case "integer": |
a3fb1c45 |
166 | $type = "INTEGER"; |
167 | break; |
92230499 |
168 | case "varchar": |
169 | $type = "VARCHAR"; |
170 | break; |
a3fb1c45 |
171 | } |
172 | |
173 | $default = "DEFAULT '$default'"; |
174 | |
175 | if (!empty($after)) { |
31ce4b53 |
176 | $after = "AFTER $after"; |
a3fb1c45 |
177 | } |
178 | |
179 | if (!empty($oldfield)) { |
180 | execute_sql("ALTER TABLE {$CFG->prefix}$table RENAME COLUMN $oldfield $field"); |
181 | } else { |
182 | execute_sql("ALTER TABLE {$CFG->prefix}$table ADD COLUMN $field $type"); |
183 | } |
184 | |
185 | execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET $null"); |
186 | execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET $default"); |
187 | break; |
188 | |
189 | } |
190 | } |
191 | |
192 | |
193 | |
194 | /// GENERIC FUNCTIONS TO CHECK AND COUNT RECORDS //////////////////////////////////////// |
df28d6c5 |
195 | |
5c63e0c4 |
196 | function record_exists($table, $field1="", $value1="", $field2="", $value2="", $field3="", $value3="") { |
df28d6c5 |
197 | /// Returns true or false depending on whether the specified record exists |
198 | |
199 | global $CFG; |
200 | |
5c63e0c4 |
201 | if ($field1) { |
202 | $select = "WHERE $field1 = '$value1'"; |
9fa49e22 |
203 | if ($field2) { |
df28d6c5 |
204 | $select .= " AND $field2 = '$value2'"; |
9fa49e22 |
205 | if ($field3) { |
df28d6c5 |
206 | $select .= " AND $field3 = '$value3'"; |
207 | } |
208 | } |
5c63e0c4 |
209 | } else { |
210 | $select = ""; |
df28d6c5 |
211 | } |
212 | |
213 | return record_exists_sql("SELECT * FROM $CFG->prefix$table $select LIMIT 1"); |
214 | } |
215 | |
216 | |
217 | function record_exists_sql($sql) { |
218 | /// Returns true or false depending on whether the specified record exists |
219 | /// The sql statement is provided as a string. |
220 | |
221 | global $db; |
222 | |
223 | $rs = $db->Execute($sql); |
e53b0823 |
224 | if (empty($rs)) return false; |
df28d6c5 |
225 | |
226 | if ( $rs->RecordCount() ) { |
227 | return true; |
228 | } else { |
229 | return false; |
230 | } |
231 | } |
232 | |
233 | |
5c63e0c4 |
234 | function count_records($table, $field1="", $value1="", $field2="", $value2="", $field3="", $value3="") { |
df28d6c5 |
235 | /// Get all the records and count them |
236 | |
237 | global $CFG; |
238 | |
5c63e0c4 |
239 | if ($field1) { |
240 | $select = "WHERE $field1 = '$value1'"; |
9fa49e22 |
241 | if ($field2) { |
df28d6c5 |
242 | $select .= " AND $field2 = '$value2'"; |
9fa49e22 |
243 | if ($field3) { |
df28d6c5 |
244 | $select .= " AND $field3 = '$value3'"; |
245 | } |
246 | } |
5c63e0c4 |
247 | } else { |
248 | $select = ""; |
df28d6c5 |
249 | } |
250 | |
251 | return count_records_sql("SELECT COUNT(*) FROM $CFG->prefix$table $select"); |
252 | } |
253 | |
9fa49e22 |
254 | function count_records_select($table, $select="") { |
255 | /// Get all the records and count them |
256 | |
257 | global $CFG; |
258 | |
d26d7ed0 |
259 | if ($select) { |
260 | $select = "WHERE $select"; |
261 | } |
262 | |
9fa49e22 |
263 | return count_records_sql("SELECT COUNT(*) FROM $CFG->prefix$table $select"); |
264 | } |
265 | |
266 | |
df28d6c5 |
267 | function count_records_sql($sql) { |
268 | /// Get all the records and count them |
269 | /// The sql statement is provided as a string. |
270 | |
271 | global $db; |
272 | |
273 | $rs = $db->Execute("$sql"); |
e53b0823 |
274 | if (empty($rs)) return 0; |
df28d6c5 |
275 | |
276 | return $rs->fields[0]; |
277 | } |
278 | |
a3fb1c45 |
279 | |
280 | |
281 | |
282 | /// GENERIC FUNCTIONS TO GET, INSERT, OR UPDATE DATA /////////////////////////////////// |
283 | |
5c63e0c4 |
284 | function get_record($table, $field1, $value1, $field2="", $value2="", $field3="", $value3="") { |
df28d6c5 |
285 | /// Get a single record as an object |
286 | |
287 | global $CFG; |
288 | |
5c63e0c4 |
289 | $select = "WHERE $field1 = '$value1'"; |
df28d6c5 |
290 | |
9fa49e22 |
291 | if ($field2) { |
df28d6c5 |
292 | $select .= " AND $field2 = '$value2'"; |
9fa49e22 |
293 | if ($field3) { |
df28d6c5 |
294 | $select .= " AND $field3 = '$value3'"; |
295 | } |
296 | } |
297 | |
298 | return get_record_sql("SELECT * FROM $CFG->prefix$table $select"); |
299 | } |
300 | |
301 | function get_record_sql($sql) { |
302 | /// Get a single record as an object |
303 | /// The sql statement is provided as a string. |
dc7e8cb5 |
304 | /// A LIMIT is added to keep limit the returned records to 1 |
df28d6c5 |
305 | |
306 | global $db; |
307 | |
dc7e8cb5 |
308 | $rs = $db->Execute("$sql LIMIT 1"); |
e53b0823 |
309 | if (empty($rs)) return false; |
df28d6c5 |
310 | |
311 | if ( $rs->RecordCount() == 1 ) { |
312 | return (object)$rs->fields; |
313 | } else { |
314 | return false; |
315 | } |
316 | } |
317 | |
18496c59 |
318 | function get_record_select($table, $select="", $fields="*") { |
319 | /// Gets one record from a table, as an object |
320 | /// "select" is a fragment of SQL to define the selection criteria |
321 | |
322 | global $CFG; |
323 | |
324 | if ($select) { |
325 | $select = "WHERE $select"; |
326 | } |
327 | |
328 | return get_record_sql("SELECT $fields FROM $CFG->prefix$table $select"); |
329 | } |
330 | |
331 | |
df28d6c5 |
332 | function get_records($table, $field="", $value="", $sort="", $fields="*") { |
333 | /// Get a number of records as an array of objects |
334 | /// Can optionally be sorted eg "time ASC" or "time DESC" |
335 | /// If "fields" is specified, only those fields are returned |
336 | /// The "key" is the first column returned, eg usually "id" |
337 | |
338 | global $CFG; |
339 | |
9fa49e22 |
340 | if ($field) { |
df28d6c5 |
341 | $select = "WHERE $field = '$value'"; |
5c63e0c4 |
342 | } else { |
343 | $select = ""; |
df28d6c5 |
344 | } |
5c63e0c4 |
345 | |
df28d6c5 |
346 | if ($sort) { |
5c63e0c4 |
347 | $sort = "ORDER BY $sort"; |
df28d6c5 |
348 | } |
349 | |
5c63e0c4 |
350 | return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sort"); |
df28d6c5 |
351 | } |
352 | |
9fa49e22 |
353 | function get_records_select($table, $select="", $sort="", $fields="*") { |
354 | /// Get a number of records as an array of objects |
355 | /// Can optionally be sorted eg "time ASC" or "time DESC" |
356 | /// "select" is a fragment of SQL to define the selection criteria |
357 | /// The "key" is the first column returned, eg usually "id" |
358 | |
359 | global $CFG; |
360 | |
d26d7ed0 |
361 | if ($select) { |
362 | $select = "WHERE $select"; |
5c63e0c4 |
363 | } |
364 | |
365 | if ($sort) { |
366 | $sort = "ORDER BY $sort"; |
d26d7ed0 |
367 | } |
368 | |
5c63e0c4 |
369 | return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sort"); |
9fa49e22 |
370 | } |
371 | |
df28d6c5 |
372 | |
373 | function get_records_list($table, $field="", $values="", $sort="", $fields="*") { |
9fa49e22 |
374 | /// Get a number of records as an array of objects |
375 | /// Differs from get_records() in that the values variable |
376 | /// can be a comma-separated list of values eg "4,5,6,10" |
377 | /// Can optionally be sorted eg "time ASC" or "time DESC" |
378 | /// The "key" is the first column returned, eg usually "id" |
df28d6c5 |
379 | |
380 | global $CFG; |
381 | |
9fa49e22 |
382 | if ($field) { |
df28d6c5 |
383 | $select = "WHERE $field in ($values)"; |
5c63e0c4 |
384 | } else { |
385 | $select = ""; |
df28d6c5 |
386 | } |
5c63e0c4 |
387 | |
df28d6c5 |
388 | if ($sort) { |
5c63e0c4 |
389 | $sort = "ORDER BY $sort"; |
df28d6c5 |
390 | } |
391 | |
5c63e0c4 |
392 | return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sort"); |
df28d6c5 |
393 | } |
394 | |
395 | |
9fa49e22 |
396 | |
df28d6c5 |
397 | function get_records_sql($sql) { |
9fa49e22 |
398 | /// Get a number of records as an array of objects |
399 | /// The "key" is the first column returned, eg usually "id" |
400 | /// The sql statement is provided as a string. |
df28d6c5 |
401 | |
402 | global $db; |
403 | |
404 | $rs = $db->Execute("$sql"); |
e53b0823 |
405 | if (empty($rs)) return false; |
df28d6c5 |
406 | |
407 | if ( $rs->RecordCount() > 0 ) { |
408 | if ($records = $rs->GetAssoc(true)) { |
409 | foreach ($records as $key => $record) { |
410 | $objects[$key] = (object) $record; |
411 | } |
412 | return $objects; |
413 | } else { |
414 | return false; |
415 | } |
416 | } else { |
417 | return false; |
418 | } |
419 | } |
420 | |
9fa49e22 |
421 | function get_records_menu($table, $field="", $value="", $sort="", $fields="*") { |
422 | /// Get a number of records as an array of objects |
423 | /// Can optionally be sorted eg "time ASC" or "time DESC" |
424 | /// If "fields" is specified, only those fields are returned |
425 | /// The "key" is the first column returned, eg usually "id" |
426 | |
427 | global $CFG; |
428 | |
429 | if ($field) { |
430 | $select = "WHERE $field = '$value'"; |
5c63e0c4 |
431 | } else { |
432 | $select = ""; |
9fa49e22 |
433 | } |
5c63e0c4 |
434 | |
9fa49e22 |
435 | if ($sort) { |
5c63e0c4 |
436 | $sort = "ORDER BY $sort"; |
9fa49e22 |
437 | } |
438 | |
5c63e0c4 |
439 | return get_records_sql_menu("SELECT $fields FROM $CFG->prefix$table $select $sort"); |
9fa49e22 |
440 | } |
441 | |
442 | function get_records_select_menu($table, $select="", $sort="", $fields="*") { |
443 | /// Get a number of records as an array of objects |
444 | /// Can optionally be sorted eg "time ASC" or "time DESC" |
445 | /// "select" is a fragment of SQL to define the selection criteria |
446 | /// Returns associative array of first two fields |
447 | |
448 | global $CFG; |
449 | |
d26d7ed0 |
450 | if ($select) { |
451 | $select = "WHERE $select"; |
452 | } |
453 | |
5c63e0c4 |
454 | if ($sort) { |
455 | $sort = "ORDER BY $sort"; |
456 | } |
457 | |
458 | return get_records_sql_menu("SELECT $fields FROM $CFG->prefix$table $select $sort"); |
9fa49e22 |
459 | } |
460 | |
461 | |
df28d6c5 |
462 | function get_records_sql_menu($sql) { |
9fa49e22 |
463 | /// Given an SQL select, this function returns an associative |
464 | /// array of the first two columns. This is most useful in |
465 | /// combination with the choose_from_menu function to create |
466 | /// a form menu. |
df28d6c5 |
467 | |
468 | global $db; |
469 | |
470 | $rs = $db->Execute("$sql"); |
e53b0823 |
471 | if (empty($rs)) return false; |
df28d6c5 |
472 | |
473 | if ( $rs->RecordCount() > 0 ) { |
474 | while (!$rs->EOF) { |
475 | $menu[$rs->fields[0]] = $rs->fields[1]; |
476 | $rs->MoveNext(); |
477 | } |
478 | return $menu; |
479 | |
480 | } else { |
481 | return false; |
482 | } |
483 | } |
484 | |
ec2a28a6 |
485 | function get_field($table, $return, $field1, $value1, $field2="", $value2="", $field3="", $value3="") { |
df28d6c5 |
486 | /// Get a single field from a database record |
487 | |
488 | global $db, $CFG; |
489 | |
ec2a28a6 |
490 | $select = "WHERE $field1 = '$value1'"; |
491 | |
492 | if ($field2) { |
493 | $select .= " AND $field2 = '$value2'"; |
494 | if ($field3) { |
495 | $select .= " AND $field3 = '$value3'"; |
496 | } |
497 | } |
498 | |
499 | $rs = $db->Execute("SELECT $return FROM $CFG->prefix$table $select"); |
e53b0823 |
500 | if (empty($rs)) return false; |
df28d6c5 |
501 | |
502 | if ( $rs->RecordCount() == 1 ) { |
503 | return $rs->fields["$return"]; |
504 | } else { |
505 | return false; |
506 | } |
507 | } |
508 | |
ec2a28a6 |
509 | function set_field($table, $newfield, $newvalue, $field1, $value1, $field2="", $value2="", $field3="", $value3="") { |
df28d6c5 |
510 | /// Set a single field in a database record |
511 | |
512 | global $db, $CFG; |
513 | |
ec2a28a6 |
514 | $select = "WHERE $field1 = '$value1'"; |
515 | |
516 | if ($field2) { |
517 | $select .= " AND $field2 = '$value2'"; |
518 | if ($field3) { |
519 | $select .= " AND $field3 = '$value3'"; |
520 | } |
521 | } |
522 | |
523 | return $db->Execute("UPDATE $CFG->prefix$table SET $newfield = '$newvalue' $select"); |
df28d6c5 |
524 | } |
525 | |
526 | |
5c63e0c4 |
527 | function delete_records($table, $field1="", $value1="", $field2="", $value2="", $field3="", $value3="") { |
df28d6c5 |
528 | /// Delete one or more records from a table |
529 | |
530 | global $db, $CFG; |
531 | |
5c63e0c4 |
532 | if ($field1) { |
533 | $select = "WHERE $field1 = '$value1'"; |
9fa49e22 |
534 | if ($field2) { |
df28d6c5 |
535 | $select .= " AND $field2 = '$value2'"; |
9fa49e22 |
536 | if ($field3) { |
df28d6c5 |
537 | $select .= " AND $field3 = '$value3'"; |
538 | } |
539 | } |
5c63e0c4 |
540 | } else { |
541 | $select = ""; |
df28d6c5 |
542 | } |
543 | |
544 | return $db->Execute("DELETE FROM $CFG->prefix$table $select"); |
545 | } |
546 | |
30f89d68 |
547 | function delete_records_select($table, $select="") { |
548 | /// Delete one or more records from a table |
549 | /// "select" is a fragment of SQL to define the selection criteria |
550 | |
551 | global $CFG, $db; |
552 | |
553 | if ($select) { |
554 | $select = "WHERE $select"; |
555 | } |
556 | |
557 | return $db->Execute("DELETE FROM $CFG->prefix$table $select"); |
558 | } |
559 | |
df28d6c5 |
560 | |
561 | function insert_record($table, $dataobject, $returnid=true) { |
562 | /// Insert a record into a table and return the "id" field if required |
563 | /// If the return ID isn't required, then this just reports success as true/false. |
564 | /// $dataobject is an object containing needed data |
565 | |
566 | global $db, $CFG; |
567 | |
568 | // Determine all the fields needed |
569 | if (! $columns = $db->MetaColumns("$CFG->prefix$table")) { |
570 | return false; |
571 | } |
df28d6c5 |
572 | $data = (array)$dataobject; |
573 | |
b3fa6684 |
574 | // Pull out data from the dataobject that matches the fields in the table. |
575 | // If fields are missing or empty, then try to set the defaults explicitly |
576 | // because some databases (eg PostgreSQL) don't always set them properly |
df28d6c5 |
577 | foreach ($columns as $column) { |
9655b654 |
578 | if(isset($column->primary_key) and $column->primary_key == 1) { |
579 | $pkey = $column->name; // take column name of primary key |
580 | } |
b3fa6684 |
581 | if ($column->name <> "id") { |
582 | if (isset($data[$column->name])) { |
50913937 |
583 | if ((string)$data[$column->name] == "" and !empty($column->has_default) and !empty($column->default_value)) { |
b3fa6684 |
584 | $ddd[$column->name] = $column->default_value; |
585 | } else { |
dc8791f3 |
586 | $ddd[$column->name] = $data[$column->name]; |
b3fa6684 |
587 | } |
588 | } else { |
92230499 |
589 | if (!empty($column->has_default) and !empty($column->default_value)) { |
b3fa6684 |
590 | $ddd[$column->name] = $column->default_value; |
591 | } |
592 | } |
df28d6c5 |
593 | } |
594 | } |
595 | |
b3fa6684 |
596 | |
df28d6c5 |
597 | // Construct SQL queries |
598 | if (! $numddd = count($ddd)) { |
599 | return false; |
600 | } |
601 | |
602 | $count = 0; |
603 | $inscolumns = ""; |
604 | $insvalues = ""; |
605 | $select = ""; |
606 | |
607 | foreach ($ddd as $key => $value) { |
3c72e2f9 |
608 | if (!is_null($value)){ |
609 | if ($select) { |
610 | $inscolumns .= ", "; |
611 | $insvalues .= ", "; |
612 | $select .= " AND "; |
613 | } |
614 | $inscolumns .= "$key"; |
615 | $insvalues .= "'$value'"; |
616 | $select .= "$key = '$value'"; |
df28d6c5 |
617 | } |
618 | } |
619 | |
620 | if (! $rs = $db->Execute("INSERT INTO $CFG->prefix$table ($inscolumns) VALUES ($insvalues)")) { |
621 | return false; |
622 | } |
623 | |
624 | if ($returnid) { |
64929926 |
625 | if ($CFG->dbtype == "mysql" ) { |
99988d1a |
626 | return $db->Insert_ID(); // ADOdb has stored the ID for us, but it isn't reliable |
627 | } |
1523be78 |
628 | |
9655b654 |
629 | if ($CFG->dbtype == "postgres7" and isset($pkey)){ |
630 | $oid = $db->Insert_ID(); |
28ba0d55 |
631 | if ($rs = $db->Execute("SELECT $pkey FROM $CFG->prefix$table WHERE oid = $oid")) { |
9655b654 |
632 | if ($rs->RecordCount() == 1) { |
633 | return $rs->fields[0]; |
634 | } else { |
635 | return false; |
636 | } |
637 | } |
638 | } |
1523be78 |
639 | // Try to pull the record out again to find the id. This is the most cross-platform method. |
df28d6c5 |
640 | if ($rs = $db->Execute("SELECT id FROM $CFG->prefix$table WHERE $select")) { |
1523be78 |
641 | if ($rs->RecordCount() == 1) { |
642 | return $rs->fields[0]; |
643 | } |
df28d6c5 |
644 | } |
1523be78 |
645 | |
646 | return false; |
647 | |
df28d6c5 |
648 | } else { |
649 | return true; |
650 | } |
651 | } |
652 | |
653 | |
654 | function update_record($table, $dataobject) { |
655 | /// Update a record in a table |
656 | /// $dataobject is an object containing needed data |
ebc3bd2b |
657 | /// Relies on $dataobject having a variable "id" to |
658 | /// specify the record to update |
df28d6c5 |
659 | |
660 | global $db, $CFG; |
661 | |
662 | if (! isset($dataobject->id) ) { |
663 | return false; |
664 | } |
665 | |
666 | // Determine all the fields in the table |
667 | if (!$columns = $db->MetaColumns("$CFG->prefix$table")) { |
668 | return false; |
669 | } |
670 | $data = (array)$dataobject; |
671 | |
672 | // Pull out data matching these fields |
673 | foreach ($columns as $column) { |
92230499 |
674 | if ($column->name <> "id" and isset($data[$column->name]) ) { |
df28d6c5 |
675 | $ddd[$column->name] = $data[$column->name]; |
676 | } |
677 | } |
678 | |
679 | // Construct SQL queries |
680 | $numddd = count($ddd); |
681 | $count = 0; |
682 | $update = ""; |
683 | |
684 | foreach ($ddd as $key => $value) { |
685 | $count++; |
686 | $update .= "$key = '$value'"; |
687 | if ($count < $numddd) { |
688 | $update .= ", "; |
689 | } |
690 | } |
691 | |
692 | if ($rs = $db->Execute("UPDATE $CFG->prefix$table SET $update WHERE id = '$dataobject->id'")) { |
693 | return true; |
694 | } else { |
695 | return false; |
696 | } |
697 | } |
698 | |
699 | |
df28d6c5 |
700 | |
701 | |
702 | /// USER DATABASE //////////////////////////////////////////////// |
703 | |
704 | function get_user_info_from_db($field, $value) { |
705 | /// Get a complete user record, which includes all the info |
706 | /// in the user record, as well as membership information |
707 | /// Suitable for setting as $USER session cookie. |
708 | |
18496c59 |
709 | if (!$field or !$value) { |
df28d6c5 |
710 | return false; |
df28d6c5 |
711 | } |
712 | |
18496c59 |
713 | if (! $user = get_record_select("user", "$field = '$value' AND deleted <> '1'")) { |
714 | return false; |
715 | } |
df28d6c5 |
716 | |
18496c59 |
717 | // Add membership information |
df28d6c5 |
718 | |
18496c59 |
719 | if ($site = get_site()) { // Everyone is always a member of the top course |
720 | $user->student[$site->id] = true; |
721 | } |
df28d6c5 |
722 | |
f53af941 |
723 | if ($students = get_records("user_students", "userid", $user->id)) { |
724 | foreach ($students as $student) { |
a6d82c3f |
725 | if (get_field("course", "visible", "id", $student->course)) { |
726 | $user->student[$student->course] = true; |
727 | $user->zoom[$student->course] = $student->zoom; |
728 | } |
f53af941 |
729 | } |
18496c59 |
730 | } |
df28d6c5 |
731 | |
f53af941 |
732 | if ($teachers = get_records("user_teachers", "userid", $user->id)) { |
733 | foreach ($teachers as $teacher) { |
734 | $user->teacher[$teacher->course] = true; |
735 | } |
18496c59 |
736 | } |
df28d6c5 |
737 | |
f53af941 |
738 | if ($admins = get_records("user_admins", "userid", $user->id)) { |
739 | foreach ($admins as $admin) { |
740 | $user->admin = true; |
741 | break; |
742 | } |
df28d6c5 |
743 | } |
18496c59 |
744 | |
b86fc0e2 |
745 | if ($displays = get_records("course_display", "userid", $user->id)) { |
746 | foreach ($displays as $display) { |
747 | $user->display[$display->course] = $display->display; |
748 | } |
749 | } |
750 | |
18496c59 |
751 | return $user; |
df28d6c5 |
752 | } |
753 | |
754 | function update_user_in_db() { |
755 | /// Updates user record to record their last access |
756 | |
757 | global $db, $USER, $REMOTE_ADDR, $CFG; |
758 | |
759 | if (!isset($USER->id)) |
760 | return false; |
761 | |
762 | $timenow = time(); |
763 | if ($db->Execute("UPDATE {$CFG->prefix}user SET lastIP='$REMOTE_ADDR', lastaccess='$timenow' |
764 | WHERE id = '$USER->id' ")) { |
765 | return true; |
766 | } else { |
767 | return false; |
768 | } |
769 | } |
770 | |
771 | |
772 | function adminlogin($username, $md5password) { |
773 | /// Does this username and password specify a valid admin user? |
774 | |
775 | global $CFG; |
776 | |
9fa49e22 |
777 | return record_exists_sql("SELECT u.id |
778 | FROM {$CFG->prefix}user u, |
779 | {$CFG->prefix}user_admins a |
ebc3bd2b |
780 | WHERE u.id = a.userid |
df28d6c5 |
781 | AND u.username = '$username' |
782 | AND u.password = '$md5password'"); |
783 | } |
784 | |
785 | |
786 | function get_site () { |
787 | /// Returns $course object of the top-level site. |
788 | |
789 | if ( $course = get_record("course", "category", 0)) { |
790 | return $course; |
791 | } else { |
792 | return false; |
793 | } |
794 | } |
795 | |
9fa49e22 |
796 | |
797 | function get_courses($category=0, $sort="fullname ASC") { |
798 | /// Returns list of courses |
799 | |
800 | if ($category > 0) { // Return all courses in one category |
a6d82c3f |
801 | $courses = get_records("course", "category", $category, $sort); |
9fa49e22 |
802 | |
803 | } else if ($category < 0) { // Return all courses, even the site |
a6d82c3f |
804 | $courses = get_records("course", "", "", $sort); |
9fa49e22 |
805 | |
806 | } else { // Return all courses, except site |
a6d82c3f |
807 | $courses = get_records_select("course", "category > 0", $sort); |
808 | } |
809 | |
810 | if ($courses) { /// Remove unavailable courses from the list |
811 | foreach ($courses as $key => $course) { |
812 | if (!$course->visible) { |
813 | if (!isteacher($course->id)) { |
814 | unset($courses[$key]); |
815 | } |
816 | } |
817 | } |
9fa49e22 |
818 | } |
a6d82c3f |
819 | return $courses; |
9fa49e22 |
820 | } |
821 | |
822 | function get_categories() { |
823 | return get_records("course_categories", "", "", "name"); |
824 | } |
825 | |
826 | |
827 | function get_guest() { |
828 | return get_user_info_from_db("username", "guest"); |
829 | } |
830 | |
831 | |
df28d6c5 |
832 | function get_admin () { |
833 | /// Returns $user object of the main admin user |
834 | |
835 | global $CFG; |
836 | |
837 | if ( $admins = get_admins() ) { |
838 | foreach ($admins as $admin) { |
839 | return $admin; // ie the first one |
840 | } |
841 | } else { |
842 | return false; |
843 | } |
844 | } |
845 | |
846 | function get_admins() { |
847 | /// Returns list of all admins |
848 | |
849 | global $CFG; |
850 | |
ebc3bd2b |
851 | return get_records_sql("SELECT u.* |
852 | FROM {$CFG->prefix}user u, |
853 | {$CFG->prefix}user_admins a |
854 | WHERE a.userid = u.id |
855 | ORDER BY u.id ASC"); |
df28d6c5 |
856 | } |
857 | |
1924074c |
858 | function get_creators() { |
859 | /// Returns list of all admins |
860 | |
861 | global $CFG; |
862 | |
863 | return get_records_sql("SELECT u.* |
864 | FROM {$CFG->prefix}user u, |
865 | {$CFG->prefix}user_coursecreators a |
866 | WHERE a.userid = u.id |
867 | ORDER BY u.id ASC"); |
868 | } |
df28d6c5 |
869 | |
870 | function get_teacher($courseid) { |
871 | /// Returns $user object of the main teacher for a course |
872 | |
873 | global $CFG; |
874 | |
875 | if ( $teachers = get_course_teachers($courseid, "t.authority ASC")) { |
876 | foreach ($teachers as $teacher) { |
877 | if ($teacher->authority) { |
878 | return $teacher; // the highest authority teacher |
879 | } |
880 | } |
881 | } else { |
882 | return false; |
883 | } |
884 | } |
885 | |
2d0b30a0 |
886 | function get_course_students($courseid, $sort="u.lastaccess DESC") { |
df28d6c5 |
887 | /// Returns list of all students in this course |
adaf3928 |
888 | /// if courseid = 0 then return ALL students in all courses |
df28d6c5 |
889 | |
890 | global $CFG; |
891 | |
9d6f5d42 |
892 | return get_records_sql("SELECT u.id, u.username, u.firstname, u.lastname, u.maildisplay, |
893 | u.email, u.city, u.country, u.lastaccess, u.lastlogin, u.picture |
894 | FROM {$CFG->prefix}user u, |
895 | {$CFG->prefix}user_students s |
2d0b30a0 |
896 | WHERE s.course = '$courseid' AND s.userid = u.id AND u.deleted = '0' |
df28d6c5 |
897 | ORDER BY $sort"); |
898 | } |
899 | |
2d0b30a0 |
900 | function get_course_teachers($courseid, $sort="t.authority ASC") { |
df28d6c5 |
901 | /// Returns list of all teachers in this course |
adaf3928 |
902 | /// if courseid = 0 then return ALL teachers in all courses |
df28d6c5 |
903 | |
904 | global $CFG; |
905 | |
906 | return get_records_sql("SELECT u.*,t.authority,t.role FROM {$CFG->prefix}user u, {$CFG->prefix}user_teachers t |
2d0b30a0 |
907 | WHERE t.course = '$courseid' AND t.userid = u.id AND u.deleted = '0' |
df28d6c5 |
908 | ORDER BY $sort"); |
909 | } |
910 | |
911 | function get_course_users($courseid, $sort="u.lastaccess DESC") { |
353d0338 |
912 | /// Returns all the users of a course: students and teachers |
913 | /// If the "course" is actually the site, then return all site users. |
914 | |
915 | $site = get_site(); |
916 | |
917 | if ($courseid == $site->id) { |
918 | return get_site_users($sort); |
919 | } |
920 | |
921 | /// Using this method because the single SQL just would not always work! |
df28d6c5 |
922 | |
923 | $teachers = get_course_teachers($courseid, $sort); |
924 | $students = get_course_students($courseid, $sort); |
925 | |
926 | if ($teachers and $students) { |
927 | return array_merge($teachers, $students); |
928 | } else if ($teachers) { |
929 | return $teachers; |
930 | } else { |
931 | return $students; |
932 | } |
933 | |
353d0338 |
934 | /// Why wouldn't this work? |
935 | /// return get_records_sql("SELECT u.* FROM user u, user_students s, user_teachers t |
936 | /// WHERE (s.course = '$courseid' AND s.userid = u.id) OR |
937 | /// (t.course = '$courseid' AND t.userid = u.id) |
938 | /// ORDER BY $sort"); |
df28d6c5 |
939 | } |
940 | |
2d0b30a0 |
941 | function get_site_users($sort="u.lastaccess DESC") { |
942 | /// Returns a list of all active users who are enrolled |
943 | /// or teaching in courses on this server |
944 | |
353d0338 |
945 | global $CFG, $db; |
946 | |
947 | //$db->debug = true; |
2d0b30a0 |
948 | |
bbf9b162 |
949 | return get_records_sql("SELECT u.id, u.username, u.firstname, u.lastname, u.maildisplay, |
950 | u.email, u.city, u.country, u.lastaccess, u.lastlogin, u.picture |
951 | FROM {$CFG->prefix}user u, |
952 | {$CFG->prefix}user_students s, |
353d0338 |
953 | {$CFG->prefix}user_teachers t, |
954 | {$CFG->prefix}user_coursecreators c, |
955 | {$CFG->prefix}user_admins a |
bbf9b162 |
956 | WHERE s.userid = u.id |
957 | OR t.userid = u.id |
353d0338 |
958 | OR a.userid = u.id |
959 | OR c.userid = u.id |
960 | GROUP BY u.id |
961 | ORDER BY $sort "); |
2d0b30a0 |
962 | } |
963 | |
9fa49e22 |
964 | |
5a741655 |
965 | function get_users($get=true, $search="", $confirmed=false, $exceptions="", $sort="firstname ASC") { |
966 | /// Returns a subset of users, |
967 | /// $get - if false then only a count of the records is returned |
968 | /// $search is a simple string to search for |
969 | /// $confirmed is a switch to allow/disallow unconfirmed users |
970 | /// $exceptions is a list of IDs to ignore, eg 2,4,5,8,9,10 |
971 | /// $sort is a sorting criteria to use |
e384fb7b |
972 | |
973 | if ($search) { |
974 | $search = " AND (firstname LIKE '%$search%' |
975 | OR lastname LIKE '%$search%' |
976 | OR email LIKE '%$search%') "; |
977 | } |
978 | |
5a741655 |
979 | if ($confirmed) { |
980 | $confirmed = " AND confirmed = '1' "; |
981 | } |
982 | |
983 | if ($exceptions) { |
984 | $exceptions = " AND id NOT IN ($exceptions) "; |
985 | } |
986 | |
987 | if ($sort and $get) { |
988 | $sort = " ORDER BY $sort "; |
989 | } else { |
990 | $sort = ""; |
991 | } |
992 | |
993 | if ($get) { |
994 | return get_records_select("user", "username <> 'guest' AND deleted = 0 $search $confirmed $exceptions $sort"); |
995 | } else { |
996 | return count_records_select("user", "username <> 'guest' AND deleted = 0 $search $confirmed $exceptions $sort"); |
997 | } |
9fa49e22 |
998 | } |
999 | |
5a741655 |
1000 | |
c750592a |
1001 | function get_users_listing($sort, $dir="ASC", $page=1, $recordsperpage=20, $search="") { |
9fa49e22 |
1002 | global $CFG; |
31fefa63 |
1003 | |
c2a96d6b |
1004 | switch ($CFG->dbtype) { |
1005 | case "mysql": |
1006 | $limit = "LIMIT $page,$recordsperpage"; |
1007 | break; |
1008 | case "postgres7": |
a918234e |
1009 | $limit = "LIMIT $recordsperpage OFFSET ".($page); |
c2a96d6b |
1010 | break; |
1011 | default: |
1012 | $limit = "LIMIT $recordsperpage,$page"; |
31fefa63 |
1013 | } |
c2a96d6b |
1014 | |
c750592a |
1015 | if ($search) { |
1016 | $search = " AND (firstname LIKE '%$search%' |
1017 | OR lastname LIKE '%$search%' |
1018 | OR email LIKE '%$search%') "; |
1019 | } |
1020 | |
9fa49e22 |
1021 | return get_records_sql("SELECT id, username, email, firstname, lastname, city, country, lastaccess |
1022 | FROM {$CFG->prefix}user |
1023 | WHERE username <> 'guest' |
c750592a |
1024 | AND deleted <> '1' $search |
31fefa63 |
1025 | ORDER BY $sort $dir $limit"); |
9fa49e22 |
1026 | |
1027 | } |
1028 | |
1029 | function get_users_confirmed() { |
1030 | global $CFG; |
1031 | return get_records_sql("SELECT * |
1032 | FROM {$CFG->prefix}user |
1033 | WHERE confirmed = 1 |
1034 | AND deleted = 0 |
1035 | AND username <> 'guest' |
1036 | AND username <> 'changeme'"); |
1037 | } |
1038 | |
1039 | |
99988d1a |
1040 | function get_users_unconfirmed($cutofftime=2000000000) { |
9fa49e22 |
1041 | global $CFG; |
1042 | return get_records_sql("SELECT * |
1043 | FROM {$CFG->prefix}user |
1044 | WHERE confirmed = 0 |
1045 | AND firstaccess > 0 |
1046 | AND firstaccess < '$cutofftime'"); |
1047 | } |
1048 | |
1049 | |
1050 | function get_users_longtimenosee($cutofftime) { |
1051 | global $CFG; |
31fefa63 |
1052 | |
1053 | $db->debug = true; |
9fa49e22 |
1054 | return get_records_sql("SELECT u.* |
1055 | FROM {$CFG->prefix}user u, |
1056 | {$CFG->prefix}user_students s |
31fefa63 |
1057 | WHERE u.lastaccess > '0' |
1058 | AND u.lastaccess < '$cutofftime' |
97485d07 |
1059 | AND u.id = s.userid |
1060 | GROUP BY u.id"); |
9fa49e22 |
1061 | } |
1062 | |
1063 | |
df28d6c5 |
1064 | /// MODULE FUNCTIONS ///////////////////////////////////////////////// |
1065 | |
9fa49e22 |
1066 | function get_course_mods($courseid) { |
1067 | /// Just gets a raw list of all modules in a course |
1068 | global $CFG; |
1069 | |
7acaa63d |
1070 | return get_records_sql("SELECT cm.*, m.name as modname |
1071 | FROM {$CFG->prefix}modules m, |
1072 | {$CFG->prefix}course_modules cm |
9fa49e22 |
1073 | WHERE cm.course = '$courseid' |
1074 | AND cm.deleted = '0' |
1075 | AND cm.module = m.id "); |
1076 | } |
1077 | |
df28d6c5 |
1078 | function get_coursemodule_from_instance($modulename, $instance, $courseid) { |
1079 | /// Given an instance of a module, finds the coursemodule description |
1080 | |
1081 | global $CFG; |
1082 | |
1083 | return get_record_sql("SELECT cm.*, m.name |
7acaa63d |
1084 | FROM {$CFG->prefix}course_modules cm, |
1085 | {$CFG->prefix}modules md, |
1086 | {$CFG->prefix}$modulename m |
df28d6c5 |
1087 | WHERE cm.course = '$courseid' AND |
1088 | cm.deleted = '0' AND |
1089 | cm.instance = m.id AND |
1090 | md.name = '$modulename' AND |
1091 | md.id = cm.module AND |
1092 | m.id = '$instance'"); |
1093 | |
1094 | } |
1095 | |
cccb016a |
1096 | function get_all_instances_in_course($modulename, $course) { |
df28d6c5 |
1097 | /// Returns an array of all the active instances of a particular |
cccb016a |
1098 | /// module in a given course, sorted in the order they are defined |
1099 | /// in the course. Returns false on any errors. |
1100 | /// $course is a course object, this depends on an accurate $course->modinfo |
df28d6c5 |
1101 | |
1102 | global $CFG; |
1103 | |
cccb016a |
1104 | if (!$modinfo = unserialize($course->modinfo)) { |
1105 | return array(); |
1acfbce5 |
1106 | } |
1107 | |
cccb016a |
1108 | if (!$rawmods = get_records_sql("SELECT cm.id as coursemodule, m.*,cw.section,cm.visible as visible |
7acaa63d |
1109 | FROM {$CFG->prefix}course_modules cm, |
1110 | {$CFG->prefix}course_sections cw, |
1111 | {$CFG->prefix}modules md, |
1112 | {$CFG->prefix}$modulename m |
cccb016a |
1113 | WHERE cm.course = '$course->id' AND |
df28d6c5 |
1114 | cm.instance = m.id AND |
1115 | cm.deleted = '0' AND |
1116 | cm.section = cw.id AND |
1117 | md.name = '$modulename' AND |
cccb016a |
1118 | md.id = cm.module")) { |
1119 | return array(); |
1120 | } |
1121 | |
1122 | // Hide non-visible instances from students |
1123 | if (isteacher($course->id)) { |
1124 | $invisible = -1; |
1125 | } else { |
1126 | $invisible = 0; |
1127 | } |
1128 | |
1129 | foreach ($modinfo as $mod) { |
1130 | if ($mod->mod == $modulename and $mod->visible > $invisible) { |
1131 | $outputarray[] = $rawmods[$mod->cm]; |
1132 | } |
1133 | } |
1134 | |
1135 | return $outputarray; |
df28d6c5 |
1136 | |
1137 | } |
1138 | |
9fa49e22 |
1139 | |
580f2fbc |
1140 | function instance_is_visible($moduletype, $module) { |
1141 | /// Given a valid module object with info about the id and course, |
1142 | /// and the module's type (eg "forum") returns whether the object |
1143 | /// is visible or not |
1144 | |
1145 | global $CFG; |
1146 | |
86e6076b |
1147 | if ($records = get_records_sql("SELECT cm.instance, cm.visible |
580f2fbc |
1148 | FROM {$CFG->prefix}course_modules cm, |
580f2fbc |
1149 | {$CFG->prefix}modules m |
1150 | WHERE cm.course = '$module->course' AND |
1151 | cm.module = m.id AND |
1152 | m.name = '$moduletype' AND |
86e6076b |
1153 | cm.instance = '$module->id'")) { |
580f2fbc |
1154 | |
1155 | foreach ($records as $record) { // there should only be one - use the first one |
1156 | return $record->visible; |
1157 | } |
1158 | } |
1159 | |
1160 | return true; // visible by default! |
1161 | } |
1162 | |
a3fb1c45 |
1163 | |
1164 | |
1165 | |
9fa49e22 |
1166 | /// LOG FUNCTIONS ///////////////////////////////////////////////////// |
1167 | |
1168 | |
1169 | function add_to_log($course, $module, $action, $url="", $info="") { |
1170 | /// Add an entry to the log table. These are "action" focussed rather |
1171 | /// than web server hits, and provide a way to easily reconstruct what |
1172 | /// any particular student has been doing. |
1173 | /// |
1174 | /// course = the course id |
1175 | /// module = forum, journal, resource, course, user etc |
1176 | /// action = view, edit, post (often but not always the same as the file.php) |
1177 | /// url = the file and parameters used to see the results of the action |
1178 | /// info = additional description information |
1179 | |
31fefa63 |
1180 | global $db, $CFG, $USER, $REMOTE_ADDR; |
9fa49e22 |
1181 | |
1182 | if (isset($USER->realuser)) { // Don't log |
1183 | return; |
1184 | } |
1185 | |
61e96406 |
1186 | $userid = empty($USER->id) ? "" : $USER->id; |
1187 | |
9fa49e22 |
1188 | $timenow = time(); |
1189 | $info = addslashes($info); |
1190 | |
31fefa63 |
1191 | $result = $db->Execute("INSERT INTO {$CFG->prefix}log (time, |
ebc3bd2b |
1192 | userid, |
1193 | course, |
1194 | ip, |
1195 | module, |
1196 | action, |
1197 | url, |
1198 | info) |
1199 | VALUES ('$timenow', |
61e96406 |
1200 | '$userid', |
ebc3bd2b |
1201 | '$course', |
1202 | '$REMOTE_ADDR', |
1203 | '$module', |
1204 | '$action', |
1205 | '$url', |
1206 | '$info')"); |
1207 | |
ce78926d |
1208 | if (!$result and ($CFG->debug > 7)) { |
9fa49e22 |
1209 | echo "<P>Error: Could not insert a new entry to the Moodle log</P>"; // Don't throw an error |
1210 | } |
1211 | } |
1212 | |
1213 | |
1214 | function get_logs($select, $order) { |
1215 | global $CFG; |
1216 | |
1217 | return get_records_sql("SELECT l.*, u.firstname, u.lastname, u.picture |
1218 | FROM {$CFG->prefix}log l, |
1219 | {$CFG->prefix}user u |
1220 | $select $order"); |
1221 | } |
1222 | |
1223 | function get_logs_usercourse($userid, $courseid, $coursestart) { |
1224 | global $CFG; |
1225 | |
1226 | return get_records_sql("SELECT floor((`time` - $coursestart)/86400) as day, count(*) as num |
1227 | FROM {$CFG->prefix}log |
ebc3bd2b |
1228 | WHERE userid = '$userid' |
9fa49e22 |
1229 | AND course = '$courseid' |
1230 | AND `time` > '$coursestart' |
1231 | GROUP BY day "); |
1232 | } |
1233 | |
1234 | function get_logs_userday($userid, $courseid, $daystart) { |
1235 | global $CFG; |
1236 | |
1237 | return get_records_sql("SELECT floor((`time` - $daystart)/3600) as hour, count(*) as num |
1238 | FROM {$CFG->prefix}log |
ebc3bd2b |
1239 | WHERE userid = '$userid' |
9fa49e22 |
1240 | AND course = '$courseid' |
1241 | AND `time` > '$daystart' |
1242 | GROUP BY hour "); |
1243 | } |
1244 | |
a3fb1c45 |
1245 | /// GENERAL HELPFUL THINGS /////////////////////////////////// |
1246 | |
1247 | function print_object($object) { |
1248 | /// Mostly just for debugging |
1249 | |
2b051f1c |
1250 | echo "<PRE>"; |
1251 | print_r($object); |
1252 | echo "</PRE>"; |
a3fb1c45 |
1253 | } |
1254 | |
1255 | |
9fa49e22 |
1256 | |
9d5b689c |
1257 | // vim:autoindent:expandtab:shiftwidth=4:tabstop=4:tw=140: |
df28d6c5 |
1258 | ?> |