Even nicer interface with help
[moodle.git] / lib / datalib.php
CommitLineData
df28d6c5 1<?PHP // $Id$
2
3/// FUNCTIONS FOR DATABASE HANDLING ////////////////////////////////
4
5function 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 25function 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 75function 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)) {
c2cb4545 86 case "text":
87 $type = "TEXT";
4e56c82d 88 $signed = "";
c2cb4545 89 break;
a3fb1c45 90 case "integer":
92230499 91 $type = "INTEGER($size)";
a3fb1c45 92 break;
92230499 93 case "varchar":
94 $type = "VARCHAR($size)";
4e56c82d 95 $signed = "";
a3fb1c45 96 break;
97 }
98
99 if (!empty($oldfield)) {
100 $operation = "CHANGE $oldfield $field";
101 } else {
102 $operation = "ADD $field";
103 }
104
105 $default = "DEFAULT '$default'";
106
107 if (!empty($after)) {
31ce4b53 108 $after = "AFTER `$after`";
a3fb1c45 109 }
110
fdc47ee6 111 return execute_sql("ALTER TABLE {$CFG->prefix}$table $operation $type $signed $default $null $after");
a3fb1c45 112 break;
113
5a4d292b 114 case "postgres7": // From Petri Asikainen
8a230a7d 115 //Check db-version
116 $dbinfo = $db->ServerInfo();
117 $dbver = substr($dbinfo[version],0,3);
118
119 $field = "$field";
5a4d292b 120 //to prevent conflicts with reserved words
5a4d292b 121 $oldfield = "\"$oldfield\"";
122
123 switch (strtolower($type)) {
124 case "integer":
125 if ($size <= 2) {
126 $type = "INT2";
127 }
128 if ($size <= 4) {
129 $type = "INT";
130 }
131 if ($size > 4) {
132 $type = "INT8";
133 }
134 break;
135 case "varchar":
136 $type = "VARCHAR($size)";
137 break;
138 }
139
8a230a7d 140 $default = "'$default'";
5a4d292b 141
142 //After is not implemented in postgesql
143 //if (!empty($after)) {
144 // $after = "AFTER '$after'";
145 //}
146
cefc7e81 147 if ($oldfield != "\"\"") {
5a4d292b 148 execute_sql("ALTER TABLE {$CFG->prefix}$table RENAME COLUMN $oldfield TO $field");
149 } else {
150 execute_sql("ALTER TABLE {$CFG->prefix}$table ADD COLUMN $field $type");
151 }
152
8a230a7d 153 if ($dbver >= "7.3") {
154 // modifying 'not null' is posible before 7.3
155 //update default values to table
156 if ($null == "NOT NULL") {
157 execute_sql("UPDATE {$CFG->prefix}$table SET $field=$default where $field IS NULL");
158 execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET $null");
159 } else {
160 execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field DROP NOT NULL");
161 }
5a4d292b 162 }
8a230a7d 163
fdc47ee6 164 return execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET DEFAULT $default");
5a4d292b 165
166 break;
a3fb1c45 167
168 default:
169 switch (strtolower($type)) {
a3fb1c45 170 case "integer":
a3fb1c45 171 $type = "INTEGER";
172 break;
92230499 173 case "varchar":
174 $type = "VARCHAR";
175 break;
a3fb1c45 176 }
177
178 $default = "DEFAULT '$default'";
179
180 if (!empty($after)) {
31ce4b53 181 $after = "AFTER $after";
a3fb1c45 182 }
183
184 if (!empty($oldfield)) {
185 execute_sql("ALTER TABLE {$CFG->prefix}$table RENAME COLUMN $oldfield $field");
186 } else {
187 execute_sql("ALTER TABLE {$CFG->prefix}$table ADD COLUMN $field $type");
188 }
189
190 execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET $null");
fdc47ee6 191 return execute_sql("ALTER TABLE {$CFG->prefix}$table ALTER COLUMN $field SET $default");
a3fb1c45 192 break;
193
194 }
195}
196
197
198
199/// GENERIC FUNCTIONS TO CHECK AND COUNT RECORDS ////////////////////////////////////////
df28d6c5 200
5c63e0c4 201function record_exists($table, $field1="", $value1="", $field2="", $value2="", $field3="", $value3="") {
df28d6c5 202/// Returns true or false depending on whether the specified record exists
203
204 global $CFG;
205
5c63e0c4 206 if ($field1) {
207 $select = "WHERE $field1 = '$value1'";
9fa49e22 208 if ($field2) {
df28d6c5 209 $select .= " AND $field2 = '$value2'";
9fa49e22 210 if ($field3) {
df28d6c5 211 $select .= " AND $field3 = '$value3'";
212 }
213 }
5c63e0c4 214 } else {
215 $select = "";
df28d6c5 216 }
217
218 return record_exists_sql("SELECT * FROM $CFG->prefix$table $select LIMIT 1");
219}
220
221
222function record_exists_sql($sql) {
223/// Returns true or false depending on whether the specified record exists
224/// The sql statement is provided as a string.
225
226 global $db;
227
228 $rs = $db->Execute($sql);
e53b0823 229 if (empty($rs)) return false;
df28d6c5 230
231 if ( $rs->RecordCount() ) {
232 return true;
233 } else {
234 return false;
235 }
236}
237
238
5c63e0c4 239function count_records($table, $field1="", $value1="", $field2="", $value2="", $field3="", $value3="") {
df28d6c5 240/// Get all the records and count them
241
242 global $CFG;
243
5c63e0c4 244 if ($field1) {
245 $select = "WHERE $field1 = '$value1'";
9fa49e22 246 if ($field2) {
df28d6c5 247 $select .= " AND $field2 = '$value2'";
9fa49e22 248 if ($field3) {
df28d6c5 249 $select .= " AND $field3 = '$value3'";
250 }
251 }
5c63e0c4 252 } else {
253 $select = "";
df28d6c5 254 }
255
256 return count_records_sql("SELECT COUNT(*) FROM $CFG->prefix$table $select");
257}
258
9fa49e22 259function count_records_select($table, $select="") {
260/// Get all the records and count them
261
262 global $CFG;
263
d26d7ed0 264 if ($select) {
265 $select = "WHERE $select";
266 }
267
9fa49e22 268 return count_records_sql("SELECT COUNT(*) FROM $CFG->prefix$table $select");
269}
270
271
df28d6c5 272function count_records_sql($sql) {
273/// Get all the records and count them
274/// The sql statement is provided as a string.
275
276 global $db;
277
278 $rs = $db->Execute("$sql");
e53b0823 279 if (empty($rs)) return 0;
df28d6c5 280
281 return $rs->fields[0];
282}
283
a3fb1c45 284
285
286
287/// GENERIC FUNCTIONS TO GET, INSERT, OR UPDATE DATA ///////////////////////////////////
288
5c63e0c4 289function get_record($table, $field1, $value1, $field2="", $value2="", $field3="", $value3="") {
df28d6c5 290/// Get a single record as an object
291
292 global $CFG;
293
5c63e0c4 294 $select = "WHERE $field1 = '$value1'";
df28d6c5 295
9fa49e22 296 if ($field2) {
df28d6c5 297 $select .= " AND $field2 = '$value2'";
9fa49e22 298 if ($field3) {
df28d6c5 299 $select .= " AND $field3 = '$value3'";
300 }
301 }
302
303 return get_record_sql("SELECT * FROM $CFG->prefix$table $select");
304}
305
306function get_record_sql($sql) {
307/// Get a single record as an object
308/// The sql statement is provided as a string.
4d7a3735 309/// A LIMIT is normally added to only look for 1 record
df28d6c5 310
4d7a3735 311 global $db, $CFG;
df28d6c5 312
4d7a3735 313 if ($CFG->debug > 7) { // Debugging mode - don't use limit
314 $limit = "";
315 } else {
316 $limit = " LIMIT 1"; // Workaround - limit to one record
317 }
318
7618a8eb 319 if (!$rs = $db->Execute("$sql$limit")) {
320 if ($CFG->debug > 7) { // Debugging mode - print checks
321 $db->debug=true;
322 $db->Execute("$sql$limit");
323 $db->debug=false;
324 }
325 return false;
326 }
4d7a3735 327
7618a8eb 328 if (!$recordcount = $rs->RecordCount()) {
329 return false; // Found no records
4d7a3735 330 }
df28d6c5 331
7618a8eb 332 if ($recordcount == 1) { // Found one record
df28d6c5 333 return (object)$rs->fields;
4d7a3735 334
7618a8eb 335 } else { // Error: found more than one record
336 notify("Error: Turn off debugging to hide this error.");
337 notify("$sql$limit");
4d7a3735 338 if ($records = $rs->GetAssoc(true)) {
7618a8eb 339 notify("Found more than one record in get_record_sql !");
4d7a3735 340 print_object($records);
4d7a3735 341 } else {
7618a8eb 342 notify("Very strange error in get_record_sql !");
343 print_object($rs);
4d7a3735 344 }
7618a8eb 345 print_continue("$CFG->wwwroot/admin/config.php");
df28d6c5 346 }
347}
348
18496c59 349function get_record_select($table, $select="", $fields="*") {
350/// Gets one record from a table, as an object
351/// "select" is a fragment of SQL to define the selection criteria
352
353 global $CFG;
354
355 if ($select) {
356 $select = "WHERE $select";
357 }
358
359 return get_record_sql("SELECT $fields FROM $CFG->prefix$table $select");
360}
361
362
0eeac484 363function get_records($table, $field="", $value="", $sort="", $fields="*", $limitfrom="", $limitnum="") {
df28d6c5 364/// Get a number of records as an array of objects
365/// Can optionally be sorted eg "time ASC" or "time DESC"
366/// If "fields" is specified, only those fields are returned
367/// The "key" is the first column returned, eg usually "id"
0eeac484 368/// limitfrom and limitnum must both be specified or not at all
df28d6c5 369
370 global $CFG;
371
9fa49e22 372 if ($field) {
df28d6c5 373 $select = "WHERE $field = '$value'";
5c63e0c4 374 } else {
375 $select = "";
df28d6c5 376 }
5c63e0c4 377
74a0363f 378 if ($limitfrom !== "") {
0eeac484 379 switch ($CFG->dbtype) {
380 case "mysql":
381 $limit = "LIMIT $limitfrom,$limitnum";
382 break;
383 case "postgres7":
384 $limit = "LIMIT $limitnum OFFSET $limitfrom";
385 break;
386 default:
387 $limit = "LIMIT $limitnum,$limitfrom";
388 }
389 } else {
390 $limit = "";
391 }
392
df28d6c5 393 if ($sort) {
5c63e0c4 394 $sort = "ORDER BY $sort";
df28d6c5 395 }
396
0eeac484 397 return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sort $limit");
df28d6c5 398}
399
9fa49e22 400function get_records_select($table, $select="", $sort="", $fields="*") {
401/// Get a number of records as an array of objects
402/// Can optionally be sorted eg "time ASC" or "time DESC"
403/// "select" is a fragment of SQL to define the selection criteria
404/// The "key" is the first column returned, eg usually "id"
405
406 global $CFG;
407
d26d7ed0 408 if ($select) {
409 $select = "WHERE $select";
5c63e0c4 410 }
411
412 if ($sort) {
413 $sort = "ORDER BY $sort";
d26d7ed0 414 }
415
5c63e0c4 416 return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sort");
9fa49e22 417}
418
df28d6c5 419
420function get_records_list($table, $field="", $values="", $sort="", $fields="*") {
9fa49e22 421/// Get a number of records as an array of objects
422/// Differs from get_records() in that the values variable
423/// can be a comma-separated list of values eg "4,5,6,10"
424/// Can optionally be sorted eg "time ASC" or "time DESC"
425/// The "key" is the first column returned, eg usually "id"
df28d6c5 426
427 global $CFG;
428
9fa49e22 429 if ($field) {
df28d6c5 430 $select = "WHERE $field in ($values)";
5c63e0c4 431 } else {
432 $select = "";
df28d6c5 433 }
5c63e0c4 434
df28d6c5 435 if ($sort) {
5c63e0c4 436 $sort = "ORDER BY $sort";
df28d6c5 437 }
438
5c63e0c4 439 return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sort");
df28d6c5 440}
441
442
9fa49e22 443
df28d6c5 444function get_records_sql($sql) {
9fa49e22 445/// Get a number of records as an array of objects
446/// The "key" is the first column returned, eg usually "id"
447/// The sql statement is provided as a string.
df28d6c5 448
449 global $db;
450
451 $rs = $db->Execute("$sql");
e53b0823 452 if (empty($rs)) return false;
df28d6c5 453
454 if ( $rs->RecordCount() > 0 ) {
455 if ($records = $rs->GetAssoc(true)) {
456 foreach ($records as $key => $record) {
457 $objects[$key] = (object) $record;
458 }
459 return $objects;
460 } else {
461 return false;
462 }
463 } else {
464 return false;
465 }
466}
467
9fa49e22 468function get_records_menu($table, $field="", $value="", $sort="", $fields="*") {
469/// Get a number of records as an array of objects
470/// Can optionally be sorted eg "time ASC" or "time DESC"
471/// If "fields" is specified, only those fields are returned
472/// The "key" is the first column returned, eg usually "id"
473
474 global $CFG;
475
476 if ($field) {
477 $select = "WHERE $field = '$value'";
5c63e0c4 478 } else {
479 $select = "";
9fa49e22 480 }
5c63e0c4 481
9fa49e22 482 if ($sort) {
5c63e0c4 483 $sort = "ORDER BY $sort";
9fa49e22 484 }
485
5c63e0c4 486 return get_records_sql_menu("SELECT $fields FROM $CFG->prefix$table $select $sort");
9fa49e22 487}
488
489function get_records_select_menu($table, $select="", $sort="", $fields="*") {
490/// Get a number of records as an array of objects
491/// Can optionally be sorted eg "time ASC" or "time DESC"
492/// "select" is a fragment of SQL to define the selection criteria
493/// Returns associative array of first two fields
494
495 global $CFG;
496
d26d7ed0 497 if ($select) {
498 $select = "WHERE $select";
499 }
500
5c63e0c4 501 if ($sort) {
502 $sort = "ORDER BY $sort";
503 }
504
505 return get_records_sql_menu("SELECT $fields FROM $CFG->prefix$table $select $sort");
9fa49e22 506}
507
508
df28d6c5 509function get_records_sql_menu($sql) {
9fa49e22 510/// Given an SQL select, this function returns an associative
511/// array of the first two columns. This is most useful in
512/// combination with the choose_from_menu function to create
513/// a form menu.
df28d6c5 514
515 global $db;
516
517 $rs = $db->Execute("$sql");
e53b0823 518 if (empty($rs)) return false;
df28d6c5 519
520 if ( $rs->RecordCount() > 0 ) {
521 while (!$rs->EOF) {
522 $menu[$rs->fields[0]] = $rs->fields[1];
523 $rs->MoveNext();
524 }
525 return $menu;
526
527 } else {
528 return false;
529 }
530}
531
ec2a28a6 532function get_field($table, $return, $field1, $value1, $field2="", $value2="", $field3="", $value3="") {
df28d6c5 533/// Get a single field from a database record
534
535 global $db, $CFG;
536
ec2a28a6 537 $select = "WHERE $field1 = '$value1'";
538
539 if ($field2) {
540 $select .= " AND $field2 = '$value2'";
541 if ($field3) {
542 $select .= " AND $field3 = '$value3'";
543 }
544 }
545
546 $rs = $db->Execute("SELECT $return FROM $CFG->prefix$table $select");
e53b0823 547 if (empty($rs)) return false;
df28d6c5 548
549 if ( $rs->RecordCount() == 1 ) {
550 return $rs->fields["$return"];
551 } else {
552 return false;
553 }
554}
555
ec2a28a6 556function set_field($table, $newfield, $newvalue, $field1, $value1, $field2="", $value2="", $field3="", $value3="") {
df28d6c5 557/// Set a single field in a database record
558
559 global $db, $CFG;
560
ec2a28a6 561 $select = "WHERE $field1 = '$value1'";
562
563 if ($field2) {
564 $select .= " AND $field2 = '$value2'";
565 if ($field3) {
566 $select .= " AND $field3 = '$value3'";
567 }
568 }
569
570 return $db->Execute("UPDATE $CFG->prefix$table SET $newfield = '$newvalue' $select");
df28d6c5 571}
572
573
5c63e0c4 574function delete_records($table, $field1="", $value1="", $field2="", $value2="", $field3="", $value3="") {
df28d6c5 575/// Delete one or more records from a table
576
577 global $db, $CFG;
578
5c63e0c4 579 if ($field1) {
580 $select = "WHERE $field1 = '$value1'";
9fa49e22 581 if ($field2) {
df28d6c5 582 $select .= " AND $field2 = '$value2'";
9fa49e22 583 if ($field3) {
df28d6c5 584 $select .= " AND $field3 = '$value3'";
585 }
586 }
5c63e0c4 587 } else {
588 $select = "";
df28d6c5 589 }
590
591 return $db->Execute("DELETE FROM $CFG->prefix$table $select");
592}
593
30f89d68 594function delete_records_select($table, $select="") {
595/// Delete one or more records from a table
596/// "select" is a fragment of SQL to define the selection criteria
597
598 global $CFG, $db;
599
600 if ($select) {
601 $select = "WHERE $select";
602 }
603
604 return $db->Execute("DELETE FROM $CFG->prefix$table $select");
605}
606
df28d6c5 607
608function insert_record($table, $dataobject, $returnid=true) {
609/// Insert a record into a table and return the "id" field if required
610/// If the return ID isn't required, then this just reports success as true/false.
611/// $dataobject is an object containing needed data
612
613 global $db, $CFG;
614
615 // Determine all the fields needed
616 if (! $columns = $db->MetaColumns("$CFG->prefix$table")) {
617 return false;
618 }
df28d6c5 619 $data = (array)$dataobject;
620
b3fa6684 621 // Pull out data from the dataobject that matches the fields in the table.
622 // If fields are missing or empty, then try to set the defaults explicitly
623 // because some databases (eg PostgreSQL) don't always set them properly
df28d6c5 624 foreach ($columns as $column) {
9655b654 625 if(isset($column->primary_key) and $column->primary_key == 1) {
626 $pkey = $column->name; // take column name of primary key
627 }
b3fa6684 628 if ($column->name <> "id") {
629 if (isset($data[$column->name])) {
50913937 630 if ((string)$data[$column->name] == "" and !empty($column->has_default) and !empty($column->default_value)) {
b3fa6684 631 $ddd[$column->name] = $column->default_value;
632 } else {
dc8791f3 633 $ddd[$column->name] = $data[$column->name];
b3fa6684 634 }
635 } else {
92230499 636 if (!empty($column->has_default) and !empty($column->default_value)) {
b3fa6684 637 $ddd[$column->name] = $column->default_value;
638 }
639 }
df28d6c5 640 }
641 }
642
b3fa6684 643
df28d6c5 644 // Construct SQL queries
645 if (! $numddd = count($ddd)) {
646 return false;
647 }
648
649 $count = 0;
650 $inscolumns = "";
651 $insvalues = "";
652 $select = "";
653
654 foreach ($ddd as $key => $value) {
3c72e2f9 655 if (!is_null($value)){
656 if ($select) {
657 $inscolumns .= ", ";
658 $insvalues .= ", ";
659 $select .= " AND ";
660 }
661 $inscolumns .= "$key";
662 $insvalues .= "'$value'";
663 $select .= "$key = '$value'";
df28d6c5 664 }
665 }
666
667 if (! $rs = $db->Execute("INSERT INTO $CFG->prefix$table ($inscolumns) VALUES ($insvalues)")) {
668 return false;
669 }
670
671 if ($returnid) {
64929926 672 if ($CFG->dbtype == "mysql" ) {
99988d1a 673 return $db->Insert_ID(); // ADOdb has stored the ID for us, but it isn't reliable
674 }
1523be78 675
9655b654 676 if ($CFG->dbtype == "postgres7" and isset($pkey)){
677 $oid = $db->Insert_ID();
28ba0d55 678 if ($rs = $db->Execute("SELECT $pkey FROM $CFG->prefix$table WHERE oid = $oid")) {
9655b654 679 if ($rs->RecordCount() == 1) {
680 return $rs->fields[0];
681 } else {
682 return false;
683 }
684 }
685 }
1523be78 686 // Try to pull the record out again to find the id. This is the most cross-platform method.
df28d6c5 687 if ($rs = $db->Execute("SELECT id FROM $CFG->prefix$table WHERE $select")) {
1523be78 688 if ($rs->RecordCount() == 1) {
689 return $rs->fields[0];
690 }
df28d6c5 691 }
1523be78 692
693 return false;
694
df28d6c5 695 } else {
696 return true;
697 }
698}
699
700
701function update_record($table, $dataobject) {
702/// Update a record in a table
703/// $dataobject is an object containing needed data
ebc3bd2b 704/// Relies on $dataobject having a variable "id" to
705/// specify the record to update
df28d6c5 706
707 global $db, $CFG;
708
709 if (! isset($dataobject->id) ) {
710 return false;
711 }
712
713 // Determine all the fields in the table
714 if (!$columns = $db->MetaColumns("$CFG->prefix$table")) {
715 return false;
716 }
717 $data = (array)$dataobject;
718
719 // Pull out data matching these fields
720 foreach ($columns as $column) {
92230499 721 if ($column->name <> "id" and isset($data[$column->name]) ) {
df28d6c5 722 $ddd[$column->name] = $data[$column->name];
723 }
724 }
725
726 // Construct SQL queries
727 $numddd = count($ddd);
728 $count = 0;
729 $update = "";
730
731 foreach ($ddd as $key => $value) {
732 $count++;
733 $update .= "$key = '$value'";
734 if ($count < $numddd) {
735 $update .= ", ";
736 }
737 }
738
739 if ($rs = $db->Execute("UPDATE $CFG->prefix$table SET $update WHERE id = '$dataobject->id'")) {
740 return true;
741 } else {
742 return false;
743 }
744}
745
746
df28d6c5 747
748
749/// USER DATABASE ////////////////////////////////////////////////
750
751function get_user_info_from_db($field, $value) {
752/// Get a complete user record, which includes all the info
753/// in the user record, as well as membership information
754/// Suitable for setting as $USER session cookie.
755
18496c59 756 if (!$field or !$value) {
df28d6c5 757 return false;
df28d6c5 758 }
759
18496c59 760 if (! $user = get_record_select("user", "$field = '$value' AND deleted <> '1'")) {
761 return false;
762 }
df28d6c5 763
18496c59 764 // Add membership information
df28d6c5 765
18496c59 766 if ($site = get_site()) { // Everyone is always a member of the top course
767 $user->student[$site->id] = true;
768 }
df28d6c5 769
f53af941 770 if ($students = get_records("user_students", "userid", $user->id)) {
771 foreach ($students as $student) {
a6d82c3f 772 if (get_field("course", "visible", "id", $student->course)) {
773 $user->student[$student->course] = true;
774 $user->zoom[$student->course] = $student->zoom;
775 }
f53af941 776 }
18496c59 777 }
df28d6c5 778
f53af941 779 if ($teachers = get_records("user_teachers", "userid", $user->id)) {
780 foreach ($teachers as $teacher) {
781 $user->teacher[$teacher->course] = true;
73047f2f 782 if ($teacher->editall) {
783 $user->teacheredit[$teacher->course] = true;
784 }
f53af941 785 }
18496c59 786 }
df28d6c5 787
f53af941 788 if ($admins = get_records("user_admins", "userid", $user->id)) {
789 foreach ($admins as $admin) {
790 $user->admin = true;
791 break;
792 }
df28d6c5 793 }
18496c59 794
b86fc0e2 795 if ($displays = get_records("course_display", "userid", $user->id)) {
796 foreach ($displays as $display) {
797 $user->display[$display->course] = $display->display;
798 }
799 }
800
18496c59 801 return $user;
df28d6c5 802}
803
804function update_user_in_db() {
805/// Updates user record to record their last access
806
807 global $db, $USER, $REMOTE_ADDR, $CFG;
808
809 if (!isset($USER->id))
810 return false;
811
812 $timenow = time();
813 if ($db->Execute("UPDATE {$CFG->prefix}user SET lastIP='$REMOTE_ADDR', lastaccess='$timenow'
814 WHERE id = '$USER->id' ")) {
815 return true;
816 } else {
817 return false;
818 }
819}
820
821
822function adminlogin($username, $md5password) {
823/// Does this username and password specify a valid admin user?
824
825 global $CFG;
826
9fa49e22 827 return record_exists_sql("SELECT u.id
828 FROM {$CFG->prefix}user u,
829 {$CFG->prefix}user_admins a
ebc3bd2b 830 WHERE u.id = a.userid
df28d6c5 831 AND u.username = '$username'
832 AND u.password = '$md5password'");
833}
834
835
9fa49e22 836function get_guest() {
837 return get_user_info_from_db("username", "guest");
838}
839
840
df28d6c5 841function get_admin () {
842/// Returns $user object of the main admin user
843
844 global $CFG;
845
846 if ( $admins = get_admins() ) {
847 foreach ($admins as $admin) {
848 return $admin; // ie the first one
849 }
850 } else {
851 return false;
852 }
853}
854
855function get_admins() {
856/// Returns list of all admins
857
858 global $CFG;
859
ebc3bd2b 860 return get_records_sql("SELECT u.*
861 FROM {$CFG->prefix}user u,
862 {$CFG->prefix}user_admins a
863 WHERE a.userid = u.id
864 ORDER BY u.id ASC");
df28d6c5 865}
866
1924074c 867function get_creators() {
868/// Returns list of all admins
869
870 global $CFG;
871
872 return get_records_sql("SELECT u.*
873 FROM {$CFG->prefix}user u,
874 {$CFG->prefix}user_coursecreators a
875 WHERE a.userid = u.id
876 ORDER BY u.id ASC");
877}
df28d6c5 878
879function get_teacher($courseid) {
880/// Returns $user object of the main teacher for a course
881
882 global $CFG;
883
884 if ( $teachers = get_course_teachers($courseid, "t.authority ASC")) {
885 foreach ($teachers as $teacher) {
886 if ($teacher->authority) {
887 return $teacher; // the highest authority teacher
888 }
889 }
890 } else {
891 return false;
892 }
893}
894
0a08581d 895function get_recent_enrolments($courseid, $timestart) {
896/// Searches logs to find all enrolments since a certain date
897/// and returns the data (used to print recent activity)
898
899 global $CFG;
900
901 return get_records_sql("SELECT u.id, u.firstname, u.lastname
902 FROM {$CFG->prefix}user u,
903 {$CFG->prefix}user_students s,
904 {$CFG->prefix}log l
905 WHERE l.time > '$timestart'
906 AND l.course = '$courseid'
907 AND l.module = 'course'
908 AND l.action = 'enrol'
909 AND l.info = u.id
910 AND u.id = s.userid
64cbb55c 911 AND s.course = '$courseid'
0a08581d 912 GROUP BY l.info
913 ORDER BY l.time ASC");
914}
915
2d0b30a0 916function get_course_students($courseid, $sort="u.lastaccess DESC") {
df28d6c5 917/// Returns list of all students in this course
adaf3928 918/// if courseid = 0 then return ALL students in all courses
df28d6c5 919
920 global $CFG;
921
688d06f4 922 return get_records_sql("SELECT u.id, u.username, u.firstname, u.lastname, u.maildisplay, u.mailformat,
9d6f5d42 923 u.email, u.city, u.country, u.lastaccess, u.lastlogin, u.picture
924 FROM {$CFG->prefix}user u,
925 {$CFG->prefix}user_students s
2d0b30a0 926 WHERE s.course = '$courseid' AND s.userid = u.id AND u.deleted = '0'
df28d6c5 927 ORDER BY $sort");
928}
929
2d0b30a0 930function get_course_teachers($courseid, $sort="t.authority ASC") {
df28d6c5 931/// Returns list of all teachers in this course
adaf3928 932/// if courseid = 0 then return ALL teachers in all courses
df28d6c5 933
934 global $CFG;
935
73047f2f 936 return get_records_sql("SELECT u.*,t.authority,t.role,t.editall
688d06f4 937 FROM {$CFG->prefix}user u,
938 {$CFG->prefix}user_teachers t
2d0b30a0 939 WHERE t.course = '$courseid' AND t.userid = u.id AND u.deleted = '0'
df28d6c5 940 ORDER BY $sort");
941}
942
943function get_course_users($courseid, $sort="u.lastaccess DESC") {
353d0338 944/// Returns all the users of a course: students and teachers
945/// If the "course" is actually the site, then return all site users.
946
947 $site = get_site();
948
949 if ($courseid == $site->id) {
950 return get_site_users($sort);
951 }
952
953 /// Using this method because the single SQL just would not always work!
df28d6c5 954
955 $teachers = get_course_teachers($courseid, $sort);
956 $students = get_course_students($courseid, $sort);
957
958 if ($teachers and $students) {
959 return array_merge($teachers, $students);
960 } else if ($teachers) {
961 return $teachers;
962 } else {
963 return $students;
964 }
965
353d0338 966 /// Why wouldn't this work?
967 /// return get_records_sql("SELECT u.* FROM user u, user_students s, user_teachers t
968 /// WHERE (s.course = '$courseid' AND s.userid = u.id) OR
969 /// (t.course = '$courseid' AND t.userid = u.id)
970 /// ORDER BY $sort");
df28d6c5 971}
972
2d0b30a0 973function get_site_users($sort="u.lastaccess DESC") {
974/// Returns a list of all active users who are enrolled
975/// or teaching in courses on this server
976
353d0338 977 global $CFG, $db;
978
979 //$db->debug = true;
2d0b30a0 980
688d06f4 981 return get_records_sql("SELECT u.id, u.username, u.firstname, u.lastname, u.maildisplay, u.mailformat,
bbf9b162 982 u.email, u.city, u.country, u.lastaccess, u.lastlogin, u.picture
983 FROM {$CFG->prefix}user u,
984 {$CFG->prefix}user_students s,
353d0338 985 {$CFG->prefix}user_teachers t,
986 {$CFG->prefix}user_coursecreators c,
987 {$CFG->prefix}user_admins a
bbf9b162 988 WHERE s.userid = u.id
989 OR t.userid = u.id
353d0338 990 OR a.userid = u.id
991 OR c.userid = u.id
992 GROUP BY u.id
993 ORDER BY $sort ");
2d0b30a0 994}
995
9fa49e22 996
5a741655 997function get_users($get=true, $search="", $confirmed=false, $exceptions="", $sort="firstname ASC") {
998/// Returns a subset of users,
999/// $get - if false then only a count of the records is returned
1000/// $search is a simple string to search for
1001/// $confirmed is a switch to allow/disallow unconfirmed users
1002/// $exceptions is a list of IDs to ignore, eg 2,4,5,8,9,10
1003/// $sort is a sorting criteria to use
e384fb7b 1004
1005 if ($search) {
1006 $search = " AND (firstname LIKE '%$search%'
1007 OR lastname LIKE '%$search%'
1008 OR email LIKE '%$search%') ";
1009 }
1010
5a741655 1011 if ($confirmed) {
1012 $confirmed = " AND confirmed = '1' ";
1013 }
1014
1015 if ($exceptions) {
1016 $exceptions = " AND id NOT IN ($exceptions) ";
1017 }
1018
1019 if ($sort and $get) {
1020 $sort = " ORDER BY $sort ";
1021 } else {
1022 $sort = "";
1023 }
1024
1025 if ($get) {
1026 return get_records_select("user", "username <> 'guest' AND deleted = 0 $search $confirmed $exceptions $sort");
1027 } else {
1028 return count_records_select("user", "username <> 'guest' AND deleted = 0 $search $confirmed $exceptions $sort");
1029 }
9fa49e22 1030}
1031
5a741655 1032
c750592a 1033function get_users_listing($sort, $dir="ASC", $page=1, $recordsperpage=20, $search="") {
9fa49e22 1034 global $CFG;
31fefa63 1035
c2a96d6b 1036 switch ($CFG->dbtype) {
1037 case "mysql":
1038 $limit = "LIMIT $page,$recordsperpage";
1039 break;
1040 case "postgres7":
a918234e 1041 $limit = "LIMIT $recordsperpage OFFSET ".($page);
c2a96d6b 1042 break;
1043 default:
1044 $limit = "LIMIT $recordsperpage,$page";
31fefa63 1045 }
c2a96d6b 1046
c750592a 1047 if ($search) {
1048 $search = " AND (firstname LIKE '%$search%'
1049 OR lastname LIKE '%$search%'
1050 OR email LIKE '%$search%') ";
1051 }
1052
9fa49e22 1053 return get_records_sql("SELECT id, username, email, firstname, lastname, city, country, lastaccess
1054 FROM {$CFG->prefix}user
1055 WHERE username <> 'guest'
c750592a 1056 AND deleted <> '1' $search
31fefa63 1057 ORDER BY $sort $dir $limit");
9fa49e22 1058
1059}
1060
1061function get_users_confirmed() {
1062 global $CFG;
1063 return get_records_sql("SELECT *
1064 FROM {$CFG->prefix}user
1065 WHERE confirmed = 1
1066 AND deleted = 0
1067 AND username <> 'guest'
1068 AND username <> 'changeme'");
1069}
1070
1071
99988d1a 1072function get_users_unconfirmed($cutofftime=2000000000) {
9fa49e22 1073 global $CFG;
1074 return get_records_sql("SELECT *
1075 FROM {$CFG->prefix}user
1076 WHERE confirmed = 0
1077 AND firstaccess > 0
1078 AND firstaccess < '$cutofftime'");
1079}
1080
1081
1082function get_users_longtimenosee($cutofftime) {
1083 global $CFG;
31fefa63 1084
1085 $db->debug = true;
9fa49e22 1086 return get_records_sql("SELECT u.*
1087 FROM {$CFG->prefix}user u,
1088 {$CFG->prefix}user_students s
31fefa63 1089 WHERE u.lastaccess > '0'
1090 AND u.lastaccess < '$cutofftime'
97485d07 1091 AND u.id = s.userid
1092 GROUP BY u.id");
9fa49e22 1093}
1094
1095
02ebf404 1096
1097/// OTHER SITE AND COURSE FUNCTIONS /////////////////////////////////////////////
1098
1099
1100function get_site () {
1101/// Returns $course object of the top-level site.
1102
1103 if ( $course = get_record("course", "category", 0)) {
1104 return $course;
1105 } else {
1106 return false;
1107 }
1108}
1109
1110
1111function get_courses($categoryid="all", $sort="sortorder ASC", $fields="*") {
1112/// Returns list of courses, for whole site, or category
1113
1114 if ($categoryid == "all") {
1115 $courses = get_records("course", "", "", $sort, $fields);
1116 } else {
1117 $courses = get_records("course", "category", "$categoryid", $sort, $fields);
1118 }
1119
1120 if ($courses) { /// Remove unavailable courses from the list
1121 foreach ($courses as $key => $course) {
1122 if (!$course->visible) {
1123 if (!isteacher($course->id)) {
1124 unset($courses[$key]);
1125 }
1126 }
1127 }
1128 }
1129 return $courses;
1130}
1131
1132
1133function get_my_courses($userid, $sort="c.fullname ASC") {
1134 global $CFG;
1135
1136 return get_records_sql("SELECT c.*
1137 FROM {$CFG->prefix}course c,
1138 {$CFG->prefix}user_students s,
1139 {$CFG->prefix}user_teachers t
1140 WHERE (s.userid = '$userid' AND s.course = c.id)
1141 OR (t.userid = '$userid' AND t.course = c.id)
1142 GROUP BY c.id
1143 ORDER BY $sort");
1144}
1145
1146
1147function get_courses_search($search, $sort="fullname ASC", $page=0, $recordsperpage=50) {
1148/// Returns a list of courses that match a search
1149
1150 global $CFG;
1151
1152 switch ($CFG->dbtype) {
1153 case "mysql":
1154 $limit = "LIMIT $page,$recordsperpage";
1155 break;
1156 case "postgres7":
1157 $limit = "LIMIT $recordsperpage OFFSET ".($page * $recordsperpage);
1158 break;
1159 default:
1160 $limit = "LIMIT $recordsperpage,$page";
1161 }
1162
1163 //to allow caseinsensitive search for postgesql
1164 if ($CFG->dbtype == "postgres7") {
1165 $LIKE = "ILIKE";
1166 } else {
1167 $LIKE = "LIKE";
1168 }
1169
1170 $fullnamesearch = "";
1171 $summarysearch = "";
1172
1173 $searchterms = explode(" ", $search); // Search for words independently
1174
1175 foreach ($searchterms as $searchterm) {
1176 if ($fullnamesearch) {
1177 $fullnamesearch .= " AND ";
1178 }
1179 $fullnamesearch .= " fullname $LIKE '%$searchterm%' ";
1180
1181 if ($summarysearch) {
1182 $summarysearch .= " AND ";
1183 }
1184 $summarysearch .= " summary $LIKE '%$searchterm%' ";
1185 }
1186
1187
1188 $courses = get_records_sql("SELECT *
1189 FROM {$CFG->prefix}course
1190 WHERE ($fullnamesearch OR $summarysearch)
1191 ORDER BY $sort $limit");
1192
1193 if ($courses) { /// Remove unavailable courses from the list
1194 foreach ($courses as $key => $course) {
1195 if (!$course->visible) {
1196 if (!isteacher($course->id)) {
1197 unset($courses[$key]);
1198 }
1199 }
1200 }
1201 }
1202
1203 return $courses;
1204}
1205
1206
1207function get_categories($parent="none", $sort="sortorder ASC") {
1208/// Returns a sorted list of categories
1209
1210 if ($parent == "none") {
1211 $categories = get_records("course_categories", "", "", $sort);
1212 } else {
1213 $categories = get_records("course_categories", "parent", $parent, $sort);
1214 }
1215 if ($categories) { /// Remove unavailable categories from the list
1216 $admin = isadmin();
1217 foreach ($categories as $key => $category) {
1218 if (!$category->visible) {
1219 if (!$admin) {
1220 unset($categories[$key]);
1221 }
1222 }
1223 }
1224 }
1225 return $categories;
1226}
1227
1228
1229function fix_course_sortorder($categoryid, $sort="sortorder ASC") {
1230/// Given a category object, this function makes sure the courseorder
1231/// variable reflects the real world.
1232
1233 if (!$courses = get_records("course", "category", "$categoryid", "$sort", "id, sortorder")) {
1234 return true;
1235 }
1236
1237 $count = 0;
1238 $modified = false;
1239
1240 foreach ($courses as $course) {
1241 if ($course->sortorder != $count) {
1242 set_field("course", "sortorder", $count, "id", $course->id);
1243 $modified = true;
1244 }
1245 $count++;
1246 }
1247
1248 if ($modified) {
1249 set_field("course_categories", "timemodified", time(), "id", $categoryid);
1250 }
1251
1252 return true;
1253}
1254
1255function make_default_scale() {
1256/// This function creates a default separated/connected scale
1257/// so there's something in the database. The locations of
1258/// strings and files is a bit odd, but this is because we
1259/// need to maintain backward compatibility with many different
1260/// existing language translations and older sites.
1261
1262 global $CFG;
1263
1264 $defaultscale = NULL;
1265 $defaultscale->courseid = 0;
1266 $defaultscale->userid = 0;
1267 $defaultscale->name = get_string("separateandconnected");
1268 $defaultscale->scale = get_string("postrating1", "forum").",".
1269 get_string("postrating2", "forum").",".
1270 get_string("postrating3", "forum");
1271 $defaultscale->timemodified = time();
1272
1273 /// Read in the big description from the file. Note this is not
1274 /// HTML (despite the file extension) but Moodle format text.
1275 $parentlang = get_string("parentlang");
1276 if (is_readable("$CFG->dirroot/lang/$CFG->lang/help/forum/ratings.html")) {
1277 $file = file("$CFG->dirroot/lang/$CFG->lang/help/forum/ratings.html");
1278 } else if ($parentlang and is_readable("$CFG->dirroot/lang/$parentlang/help/forum/ratings.html")) {
1279 $file = file("$CFG->dirroot/lang/$parentlang/help/forum/ratings.html");
1280 } else if (is_readable("$CFG->dirroot/lang/en/help/forum/ratings.html")) {
1281 $file = file("$CFG->dirroot/lang/en/help/forum/ratings.html");
1282 } else {
1283 $file = "";
1284 }
1285
1286 $defaultscale->description = addslashes(implode("", $file));
1287
1288 if ($defaultscale->id = insert_record("scale", $defaultscale)) {
94d782eb 1289 execute_sql("UPDATE {$CFG->prefix}forum SET scale = '$defaultscale->id'", false);
02ebf404 1290 }
1291}
1292
1293function get_scales_menu($courseid=0) {
1294/// Returns a menu of all available scales
1295/// from the site as well as the given course
1296
1297 global $CFG;
1298
1299 $sql = "SELECT id, name FROM {$CFG->prefix}scale
1300 WHERE courseid = '0' or courseid = '$courseid'
1301 ORDER BY courseid ASC, name ASC";
1302
1303 if ($scales = get_records_sql_menu("$sql")) {
1304 return $scales;
1305 }
1306
1307 make_default_scale();
1308
1309 return get_records_sql_menu("$sql");
1310}
1311
df28d6c5 1312/// MODULE FUNCTIONS /////////////////////////////////////////////////
1313
9fa49e22 1314function get_course_mods($courseid) {
1315/// Just gets a raw list of all modules in a course
1316 global $CFG;
1317
7acaa63d 1318 return get_records_sql("SELECT cm.*, m.name as modname
1319 FROM {$CFG->prefix}modules m,
1320 {$CFG->prefix}course_modules cm
9fa49e22 1321 WHERE cm.course = '$courseid'
1322 AND cm.deleted = '0'
1323 AND cm.module = m.id ");
1324}
1325
df28d6c5 1326function get_coursemodule_from_instance($modulename, $instance, $courseid) {
1327/// Given an instance of a module, finds the coursemodule description
1328
1329 global $CFG;
1330
1331 return get_record_sql("SELECT cm.*, m.name
7acaa63d 1332 FROM {$CFG->prefix}course_modules cm,
1333 {$CFG->prefix}modules md,
1334 {$CFG->prefix}$modulename m
df28d6c5 1335 WHERE cm.course = '$courseid' AND
1336 cm.deleted = '0' AND
1337 cm.instance = m.id AND
1338 md.name = '$modulename' AND
1339 md.id = cm.module AND
1340 m.id = '$instance'");
1341
1342}
1343
cccb016a 1344function get_all_instances_in_course($modulename, $course) {
df28d6c5 1345/// Returns an array of all the active instances of a particular
cccb016a 1346/// module in a given course, sorted in the order they are defined
1347/// in the course. Returns false on any errors.
1348/// $course is a course object, this depends on an accurate $course->modinfo
df28d6c5 1349
1350 global $CFG;
1351
cccb016a 1352 if (!$modinfo = unserialize($course->modinfo)) {
1353 return array();
1acfbce5 1354 }
1355
cccb016a 1356 if (!$rawmods = get_records_sql("SELECT cm.id as coursemodule, m.*,cw.section,cm.visible as visible
7acaa63d 1357 FROM {$CFG->prefix}course_modules cm,
1358 {$CFG->prefix}course_sections cw,
1359 {$CFG->prefix}modules md,
1360 {$CFG->prefix}$modulename m
cccb016a 1361 WHERE cm.course = '$course->id' AND
df28d6c5 1362 cm.instance = m.id AND
1363 cm.deleted = '0' AND
1364 cm.section = cw.id AND
1365 md.name = '$modulename' AND
cccb016a 1366 md.id = cm.module")) {
1367 return array();
1368 }
1369
1370 // Hide non-visible instances from students
1371 if (isteacher($course->id)) {
1372 $invisible = -1;
1373 } else {
1374 $invisible = 0;
1375 }
1376
1377 foreach ($modinfo as $mod) {
1378 if ($mod->mod == $modulename and $mod->visible > $invisible) {
1379 $outputarray[] = $rawmods[$mod->cm];
1380 }
1381 }
1382
1383 return $outputarray;
df28d6c5 1384
1385}
1386
9fa49e22 1387
580f2fbc 1388function instance_is_visible($moduletype, $module) {
1389/// Given a valid module object with info about the id and course,
1390/// and the module's type (eg "forum") returns whether the object
1391/// is visible or not
1392
1393 global $CFG;
1394
86e6076b 1395 if ($records = get_records_sql("SELECT cm.instance, cm.visible
580f2fbc 1396 FROM {$CFG->prefix}course_modules cm,
580f2fbc 1397 {$CFG->prefix}modules m
1398 WHERE cm.course = '$module->course' AND
1399 cm.module = m.id AND
1400 m.name = '$moduletype' AND
86e6076b 1401 cm.instance = '$module->id'")) {
580f2fbc 1402
1403 foreach ($records as $record) { // there should only be one - use the first one
1404 return $record->visible;
1405 }
1406 }
1407
1408 return true; // visible by default!
1409}
1410
a3fb1c45 1411
1412
1413
9fa49e22 1414/// LOG FUNCTIONS /////////////////////////////////////////////////////
1415
1416
1417function add_to_log($course, $module, $action, $url="", $info="") {
1418/// Add an entry to the log table. These are "action" focussed rather
1419/// than web server hits, and provide a way to easily reconstruct what
1420/// any particular student has been doing.
1421///
1422/// course = the course id
1423/// module = forum, journal, resource, course, user etc
1424/// action = view, edit, post (often but not always the same as the file.php)
1425/// url = the file and parameters used to see the results of the action
1426/// info = additional description information
1427
31fefa63 1428 global $db, $CFG, $USER, $REMOTE_ADDR;
9fa49e22 1429
1430 if (isset($USER->realuser)) { // Don't log
1431 return;
1432 }
1433
61e96406 1434 $userid = empty($USER->id) ? "" : $USER->id;
1435
9fa49e22 1436 $timenow = time();
1437 $info = addslashes($info);
1438
31fefa63 1439 $result = $db->Execute("INSERT INTO {$CFG->prefix}log (time,
ebc3bd2b 1440 userid,
1441 course,
1442 ip,
1443 module,
1444 action,
1445 url,
1446 info)
1447 VALUES ('$timenow',
61e96406 1448 '$userid',
ebc3bd2b 1449 '$course',
1450 '$REMOTE_ADDR',
1451 '$module',
1452 '$action',
1453 '$url',
1454 '$info')");
1455
ce78926d 1456 if (!$result and ($CFG->debug > 7)) {
9fa49e22 1457 echo "<P>Error: Could not insert a new entry to the Moodle log</P>"; // Don't throw an error
1458 }
1459}
1460
1461
1462function get_logs($select, $order) {
1463 global $CFG;
1464
1465 return get_records_sql("SELECT l.*, u.firstname, u.lastname, u.picture
1466 FROM {$CFG->prefix}log l,
1467 {$CFG->prefix}user u
1468 $select $order");
1469}
1470
1471function get_logs_usercourse($userid, $courseid, $coursestart) {
1472 global $CFG;
1473
da0c90c3 1474 if ($courseid) {
1475 $courseselect = " AND course = '$courseid' ";
1476 }
1477
9fa49e22 1478 return get_records_sql("SELECT floor((`time` - $coursestart)/86400) as day, count(*) as num
1479 FROM {$CFG->prefix}log
ebc3bd2b 1480 WHERE userid = '$userid'
da0c90c3 1481 AND `time` > '$coursestart' $courseselect
9fa49e22 1482 GROUP BY day ");
1483}
1484
1485function get_logs_userday($userid, $courseid, $daystart) {
1486 global $CFG;
1487
7e4a6488 1488 if ($courseid) {
1489 $courseselect = " AND course = '$courseid' ";
1490 }
1491
9fa49e22 1492 return get_records_sql("SELECT floor((`time` - $daystart)/3600) as hour, count(*) as num
1493 FROM {$CFG->prefix}log
ebc3bd2b 1494 WHERE userid = '$userid'
7e4a6488 1495 AND `time` > '$daystart' $courseselect
9fa49e22 1496 GROUP BY hour ");
1497}
1498
a3fb1c45 1499/// GENERAL HELPFUL THINGS ///////////////////////////////////
1500
1501function print_object($object) {
1502/// Mostly just for debugging
1503
2b051f1c 1504 echo "<PRE>";
1505 print_r($object);
1506 echo "</PRE>";
a3fb1c45 1507}
1508
1509
9fa49e22 1510
9d5b689c 1511// vim:autoindent:expandtab:shiftwidth=4:tabstop=4:tw=140:
df28d6c5 1512?>