Commit | Line | Data |
---|---|---|
1adbd2c3 | 1 | <?php |
3d4b223a | 2 | /////////////////////////////////////////////////////////////////////////// |
3 | // // | |
4 | // NOTICE OF COPYRIGHT // | |
5 | // // | |
6 | // Moodle - Modular Object-Oriented Dynamic Learning Environment // | |
7 | // http://moodle.org // | |
8 | // // | |
9 | // Copyright (C) 2005 Martin Dougiamas http://dougiamas.com // | |
10 | // // | |
11 | // This program is free software; you can redistribute it and/or modify // | |
12 | // it under the terms of the GNU General Public License as published by // | |
13 | // the Free Software Foundation; either version 2 of the License, or // | |
14 | // (at your option) any later version. // | |
15 | // // | |
16 | // This program is distributed in the hope that it will be useful, // | |
17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of // | |
18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // | |
19 | // GNU General Public License for more details: // | |
20 | // // | |
21 | // http://www.gnu.org/copyleft/gpl.html // | |
22 | // // | |
23 | /////////////////////////////////////////////////////////////////////////// | |
24 | ||
3681f9a9 | 25 | require_once(dirname(__FILE__) . '/../../config.php'); |
26 | require_once($CFG->dirroot . '/mod/data/lib.php'); | |
27 | require_once($CFG->libdir . '/rsslib.php'); | |
4e1132a8 | 28 | require_once($CFG->libdir . '/completionlib.php'); |
9f7f1a74 | 29 | |
3d45b8e5 | 30 | /// One of these is necessary! |
d53e5129 | 31 | $id = optional_param('id', 0, PARAM_INT); // course module id |
32 | $d = optional_param('d', 0, PARAM_INT); // database id | |
33 | $rid = optional_param('rid', 0, PARAM_INT); //record id | |
34 | $mode = optional_param('mode', '', PARAM_ALPHA); // Force the browse mode ('single') | |
35 | $filter = optional_param('filter', 0, PARAM_BOOL); | |
36 | // search filter will only be applied when $filter is true | |
3d45b8e5 | 37 | |
d2b23346 | 38 | $edit = optional_param('edit', -1, PARAM_BOOL); |
7900ecb0 | 39 | $page = optional_param('page', 0, PARAM_INT); |
3d45b8e5 | 40 | /// These can be added to perform an action on a record |
473dd288 | 41 | $approve = optional_param('approve', 0, PARAM_INT); //approval recordid |
d0372ed6 | 42 | $disapprove = optional_param('disapprove', 0, PARAM_INT); // disapproval recordid |
473dd288 | 43 | $delete = optional_param('delete', 0, PARAM_INT); //delete recordid |
cf9ecfda AG |
44 | $multidelete = optional_param_array('delcheck', null, PARAM_INT); |
45 | $serialdelete = optional_param('serialdelete', null, PARAM_RAW); | |
aab98aaf | 46 | |
3d4b223a | 47 | if ($id) { |
f9d5371b | 48 | if (! $cm = get_coursemodule_from_id('data', $id)) { |
29c1bb15 | 49 | print_error('invalidcoursemodule'); |
3d4b223a | 50 | } |
3223bc9e | 51 | if (! $course = $DB->get_record('course', array('id'=>$cm->course))) { |
29c1bb15 | 52 | print_error('coursemisconf'); |
3d4b223a | 53 | } |
3223bc9e | 54 | if (! $data = $DB->get_record('data', array('id'=>$cm->instance))) { |
29c1bb15 | 55 | print_error('invalidcoursemodule'); |
3d4b223a | 56 | } |
3d45b8e5 | 57 | $record = NULL; |
3d4b223a | 58 | |
3d45b8e5 | 59 | } else if ($rid) { |
3223bc9e | 60 | if (! $record = $DB->get_record('data_records', array('id'=>$rid))) { |
29c1bb15 | 61 | print_error('invalidrecord', 'data'); |
3d45b8e5 | 62 | } |
3223bc9e | 63 | if (! $data = $DB->get_record('data', array('id'=>$record->dataid))) { |
29c1bb15 | 64 | print_error('invalidid', 'data'); |
3d45b8e5 | 65 | } |
3223bc9e | 66 | if (! $course = $DB->get_record('course', array('id'=>$data->course))) { |
29c1bb15 | 67 | print_error('coursemisconf'); |
3d45b8e5 | 68 | } |
69 | if (! $cm = get_coursemodule_from_instance('data', $data->id, $course->id)) { | |
29c1bb15 | 70 | print_error('invalidcoursemodule'); |
3d45b8e5 | 71 | } |
72 | } else { // We must have $d | |
3223bc9e | 73 | if (! $data = $DB->get_record('data', array('id'=>$d))) { |
29c1bb15 | 74 | print_error('invalidid', 'data'); |
3d4b223a | 75 | } |
3223bc9e | 76 | if (! $course = $DB->get_record('course', array('id'=>$data->course))) { |
29c1bb15 | 77 | print_error('coursemisconf'); |
3d4b223a | 78 | } |
79 | if (! $cm = get_coursemodule_from_instance('data', $data->id, $course->id)) { | |
29c1bb15 | 80 | print_error('invalidcoursemodule'); |
3d4b223a | 81 | } |
3d45b8e5 | 82 | $record = NULL; |
3d4b223a | 83 | } |
84 | ||
7ddda9db | 85 | require_course_login($course, true, $cm); |
aab98aaf | 86 | |
36051c9e DC |
87 | require_once($CFG->dirroot . '/comment/lib.php'); |
88 | comment::init(); | |
e998effa | 89 | |
0b3b8c30 | 90 | $context = context_module::instance($cm->id); |
20821a12 | 91 | require_capability('mod/data:viewentry', $context); |
3d1c33ef | 92 | |
3d45b8e5 | 93 | /// If we have an empty Database then redirect because this page is useless without data |
0468976c | 94 | if (has_capability('mod/data:managetemplates', $context)) { |
3223bc9e | 95 | if (!$DB->record_exists('data_fields', array('dataid'=>$data->id))) { // Brand new database! |
5bac6d10 | 96 | redirect($CFG->wwwroot.'/mod/data/field.php?d='.$data->id); // Redirect to field entry |
3d4b223a | 97 | } |
98 | } | |
e0279f63 | 99 | |
3d45b8e5 | 100 | |
101 | /// Check further parameters that set browsing preferences | |
102 | if (!isset($SESSION->dataprefs)) { | |
103 | $SESSION->dataprefs = array(); | |
e0279f63 | 104 | } |
3d45b8e5 | 105 | if (!isset($SESSION->dataprefs[$data->id])) { |
106 | $SESSION->dataprefs[$data->id] = array(); | |
107 | $SESSION->dataprefs[$data->id]['search'] = ''; | |
7900ecb0 | 108 | $SESSION->dataprefs[$data->id]['search_array'] = array(); |
3d45b8e5 | 109 | $SESSION->dataprefs[$data->id]['sort'] = $data->defaultsort; |
7900ecb0 | 110 | $SESSION->dataprefs[$data->id]['advanced'] = 0; |
3d45b8e5 | 111 | $SESSION->dataprefs[$data->id]['order'] = ($data->defaultsortdir == 0) ? 'ASC' : 'DESC'; |
3d4b223a | 112 | } |
de8ff581 | 113 | |
eeeb4f2a | 114 | // reset advanced form |
115 | if (!is_null(optional_param('resetadv', null, PARAM_RAW))) { | |
116 | $SESSION->dataprefs[$data->id]['search_array'] = array(); | |
117 | // we need the redirect to cleanup the form state properly | |
118 | redirect("view.php?id=$cm->id&mode=$mode&search=&advanced=1"); | |
119 | } | |
120 | ||
de8ff581 | 121 | $advanced = optional_param('advanced', -1, PARAM_INT); |
122 | if ($advanced == -1) { | |
123 | $advanced = $SESSION->dataprefs[$data->id]['advanced']; | |
124 | } else { | |
125 | if (!$advanced) { | |
126 | // explicitly switched to normal mode - discard all advanced search settings | |
127 | $SESSION->dataprefs[$data->id]['search_array'] = array(); | |
128 | } | |
832123e1 | 129 | $SESSION->dataprefs[$data->id]['advanced'] = $advanced; |
de8ff581 | 130 | } |
131 | ||
7900ecb0 | 132 | $search_array = $SESSION->dataprefs[$data->id]['search_array']; |
eeeb4f2a | 133 | |
7900ecb0 | 134 | if (!empty($advanced)) { |
135 | $search = ''; | |
69c0a609 | 136 | $vals = array(); |
3223bc9e | 137 | $fields = $DB->get_records('data_fields', array('dataid'=>$data->id)); |
8429163d | 138 | |
7900ecb0 | 139 | //Added to ammend paging error. This error would occur when attempting to go from one page of advanced |
140 | //search results to another. All fields were reset in the page transfer, and there was no way of determining | |
141 | //whether or not the user reset them. This would cause a blank search to execute whenever the user attempted | |
142 | //to see any page of results past the first. | |
143 | //This fix works as follows: | |
144 | //$paging flag is set to false when page 0 of the advanced search results is viewed for the first time. | |
145 | //Viewing any page of results after page 0 passes the false $paging flag though the URL (see line 523) and the | |
146 | //execution falls through to the second condition below, allowing paging to be set to true. | |
147 | //Paging remains true and keeps getting passed though the URL until a new search is performed | |
148 | //(even if page 0 is revisited). | |
8429163d | 149 | //A false $paging flag generates advanced search results based on the fields input by the user. |
7900ecb0 | 150 | //A true $paging flag generates davanced search results from the $SESSION global. |
8429163d | 151 | |
7900ecb0 | 152 | $paging = optional_param('paging', NULL, PARAM_BOOL); |
153 | if($page == 0 && !isset($paging)) { | |
154 | $paging = false; | |
155 | } | |
156 | else { | |
157 | $paging = true; | |
158 | } | |
714bec74 | 159 | if (!empty($fields)) { |
7900ecb0 | 160 | foreach($fields as $field) { |
2d9b3ef2 | 161 | $searchfield = data_get_field_from_id($field->id, $data); |
7900ecb0 | 162 | //Get field data to build search sql with. If paging is false, get from user. |
163 | //If paging is true, get data from $search_array which is obtained from the $SESSION (see line 116). | |
164 | if(!$paging) { | |
165 | $val = $searchfield->parse_search_field(); | |
714bec74 | 166 | } else { |
7900ecb0 | 167 | //Set value from session if there is a value @ the required index. |
714bec74 | 168 | if (isset($search_array[$field->id])) { |
7900ecb0 | 169 | $val = $search_array[$field->id]->data; |
714bec74 | 170 | } else { //If there is not an entry @ the required index, set value to blank. |
7900ecb0 | 171 | $val = ''; |
172 | } | |
7900ecb0 | 173 | } |
714bec74 | 174 | if (!empty($val)) { |
39790bd8 | 175 | $search_array[$field->id] = new stdClass(); |
e3487936 | 176 | list($search_array[$field->id]->sql, $search_array[$field->id]->params) = $searchfield->generate_sql('c'.$field->id, $val); |
714bec74 | 177 | $search_array[$field->id]->data = $val; |
69c0a609 | 178 | $vals[] = $val; |
714bec74 | 179 | } else { |
180 | // clear it out | |
181 | unset($search_array[$field->id]); | |
7900ecb0 | 182 | } |
183 | } | |
184 | } | |
714bec74 | 185 | |
186 | if (!$paging) { | |
187 | // name searching | |
188 | $fn = optional_param('u_fn', '', PARAM_NOTAGS); | |
189 | $ln = optional_param('u_ln', '', PARAM_NOTAGS); | |
190 | } else { | |
de8ff581 | 191 | $fn = isset($search_array[DATA_FIRSTNAME]) ? $search_array[DATA_FIRSTNAME]->data : ''; |
192 | $ln = isset($search_array[DATA_LASTNAME]) ? $search_array[DATA_LASTNAME]->data : ''; | |
714bec74 | 193 | } |
194 | if (!empty($fn)) { | |
39790bd8 | 195 | $search_array[DATA_FIRSTNAME] = new stdClass(); |
e3487936 | 196 | $search_array[DATA_FIRSTNAME]->sql = ''; |
197 | $search_array[DATA_FIRSTNAME]->params = array(); | |
198 | $search_array[DATA_FIRSTNAME]->field = 'u.firstname'; | |
199 | $search_array[DATA_FIRSTNAME]->data = $fn; | |
69c0a609 | 200 | $vals[] = $fn; |
714bec74 | 201 | } else { |
202 | unset($search_array[DATA_FIRSTNAME]); | |
203 | } | |
204 | if (!empty($ln)) { | |
39790bd8 | 205 | $search_array[DATA_LASTNAME] = new stdClass(); |
e3487936 | 206 | $search_array[DATA_LASTNAME]->sql = ''; |
1e72829d | 207 | $search_array[DATA_LASTNAME]->params = array(); |
e3487936 | 208 | $search_array[DATA_LASTNAME]->field = 'u.lastname'; |
209 | $search_array[DATA_LASTNAME]->data = $ln; | |
69c0a609 | 210 | $vals[] = $ln; |
714bec74 | 211 | } else { |
212 | unset($search_array[DATA_LASTNAME]); | |
213 | } | |
214 | ||
7900ecb0 | 215 | $SESSION->dataprefs[$data->id]['search_array'] = $search_array; // Make it sticky |
714bec74 | 216 | |
69c0a609 | 217 | // in case we want to switch to simple search later - there might be multiple values there ;-) |
218 | if ($vals) { | |
219 | $val = reset($vals); | |
220 | if (is_string($val)) { | |
221 | $search = $val; | |
222 | } | |
223 | } | |
224 | ||
714bec74 | 225 | } else { |
7900ecb0 | 226 | $search = optional_param('search', $SESSION->dataprefs[$data->id]['search'], PARAM_NOTAGS); |
227 | //Paging variable not used for standard search. Set it to null. | |
228 | $paging = NULL; | |
229 | } | |
230 | ||
d53e5129 | 231 | // Disable search filters if $filter is not true: |
32d799c6 | 232 | if (! $filter) { |
233 | $search = ''; | |
234 | } | |
d53e5129 | 235 | |
2f1e464a | 236 | if (core_text::strlen($search) < 2) { |
76a2fd82 | 237 | $search = ''; |
238 | } | |
3d45b8e5 | 239 | $SESSION->dataprefs[$data->id]['search'] = $search; // Make it sticky |
240 | ||
241 | $sort = optional_param('sort', $SESSION->dataprefs[$data->id]['sort'], PARAM_INT); | |
242 | $SESSION->dataprefs[$data->id]['sort'] = $sort; // Make it sticky | |
243 | ||
244 | $order = (optional_param('order', $SESSION->dataprefs[$data->id]['order'], PARAM_ALPHA) == 'ASC') ? 'ASC': 'DESC'; | |
245 | $SESSION->dataprefs[$data->id]['order'] = $order; // Make it sticky | |
246 | ||
247 | ||
248 | $oldperpage = get_user_preferences('data_perpage_'.$data->id, 10); | |
249 | $perpage = optional_param('perpage', $oldperpage, PARAM_INT); | |
250 | ||
251 | if ($perpage < 2) { | |
252 | $perpage = 2; | |
253 | } | |
254 | if ($perpage != $oldperpage) { | |
255 | set_user_preference('data_perpage_'.$data->id, $perpage); | |
256 | } | |
257 | ||
3d4b223a | 258 | add_to_log($course->id, 'data', 'view', "view.php?id=$cm->id", $data->id, $cm->id); |
259 | ||
260 | ||
a9f19d81 DC |
261 | $urlparams = array('d' => $data->id); |
262 | if ($record) { | |
263 | $urlparams['rid'] = $record->id; | |
264 | } | |
265 | if ($page) { | |
266 | $urlparams['page'] = $page; | |
267 | } | |
268 | if ($mode) { | |
269 | $urlparams['mode'] = $mode; | |
270 | } | |
271 | if ($filter) { | |
272 | $urlparams['filter'] = $filter; | |
273 | } | |
3d4b223a | 274 | // Initialize $PAGE, compute blocks |
a9f19d81 | 275 | $PAGE->set_url('/mod/data/view.php', $urlparams); |
3d4b223a | 276 | |
d2b23346 | 277 | if (($edit != -1) and $PAGE->user_allowed_editing()) { |
278 | $USER->editing = $edit; | |
3d4b223a | 279 | } |
3d4b223a | 280 | |
0b3b8c30 | 281 | $courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id))); |
8ebbb06a | 282 | |
b0100852 | 283 | /// RSS and CSS and JS meta |
68635e6f | 284 | $meta = ''; |
64452eb4 | 285 | if (!empty($CFG->enablerssfeeds) && !empty($CFG->data_enablerssfeeds) && $data->rssarticles > 0) { |
7a241d81 | 286 | $rsstitle = $courseshortname . ': ' . format_string($data->name); |
43b92251 | 287 | rss_add_http_header($context, 'mod_data', $data, $rsstitle); |
68635e6f | 288 | } |
289 | if ($data->csstemplate) { | |
c0467479 | 290 | $PAGE->requires->css('/mod/data/css.php?d='.$data->id); |
c853304e | 291 | } |
b0100852 | 292 | if ($data->jstemplate) { |
60409fe1 | 293 | $PAGE->requires->js('/mod/data/js.php?d='.$data->id, true); |
b0100852 | 294 | } |
295 | ||
6553cda7 | 296 | // Mark as viewed |
297 | $completion = new completion_info($course); | |
298 | $completion->set_module_viewed($cm); | |
299 | ||
c853304e | 300 | /// Print the page header |
b7b2d0f3 | 301 | // Note: MDL-19010 there will be further changes to printing header and blocks. |
302 | // The code will be much nicer than this eventually. | |
8ebbb06a | 303 | $title = $courseshortname.': ' . format_string($data->name); |
3681f9a9 | 304 | |
59e2121e | 305 | if ($PAGE->user_allowed_editing()) { |
e08bb715 JF |
306 | // Change URL parameter and block display string value depending on whether editing is enabled or not |
307 | if ($PAGE->user_is_editing()) { | |
308 | $urlediting = 'off'; | |
309 | $strediting = get_string('blockseditoff'); | |
310 | } else { | |
311 | $urlediting = 'on'; | |
312 | $strediting = get_string('blocksediton'); | |
313 | } | |
314 | $url = new moodle_url($CFG->wwwroot.'/mod/data/view.php', array('id' => $cm->id, 'edit' => $urlediting)); | |
315 | $PAGE->set_button($OUTPUT->single_button($url, $strediting)); | |
3681f9a9 | 316 | } |
aab98aaf | 317 | |
29b64a22 | 318 | if ($mode == 'asearch') { |
319 | $PAGE->navbar->add(get_string('search')); | |
320 | } | |
321 | ||
b0ff558c | 322 | $PAGE->set_title($title); |
323 | $PAGE->set_heading($course->fullname); | |
dd88de0e | 324 | |
b0ff558c | 325 | echo $OUTPUT->header(); |
1adbd2c3 | 326 | |
3b27b0fe | 327 | /// Check to see if groups are being used here |
13534ef7 ML |
328 | $currentgroup = groups_get_activity_group($cm); |
329 | $groupmode = groups_get_activity_groupmode($cm); | |
cf9ecfda | 330 | $canmanageentries = has_capability('mod/data:manageentries', $context); |
76fb0443 AG |
331 | // If a student is not part of a group and seperate groups is enabled, we don't |
332 | // want them seeing all records. | |
cf9ecfda | 333 | if ($currentgroup == 0 && $groupmode == 1 && !$canmanageentries) { |
76fb0443 AG |
334 | $canviewallrecords = false; |
335 | } else { | |
336 | $canviewallrecords = true; | |
337 | } | |
3b27b0fe | 338 | |
e822f07b | 339 | // detect entries not approved yet and show hint instead of not found error |
cf9ecfda | 340 | if ($record and $data->approval and !$record->approved and $record->userid != $USER->id and !$canmanageentries) { |
ebb621f6 | 341 | if (!$currentgroup or $record->groupid == $currentgroup or $record->groupid == 0) { |
342 | print_error('notapproved', 'data'); | |
343 | } | |
344 | } | |
345 | ||
66e2b9f8 | 346 | echo $OUTPUT->heading(format_string($data->name), 2); |
aab98aaf | 347 | |
a593aeee | 348 | // Do we need to show a link to the RSS feed for the records? |
9e86f2e7 AD |
349 | //this links has been Settings (database activity administration) block |
350 | /*if (!empty($CFG->enablerssfeeds) && !empty($CFG->data_enablerssfeeds) && $data->rssarticles > 0) { | |
a593aeee | 351 | echo '<div style="float:right;">'; |
aa60291e | 352 | rss_print_link($context->id, $USER->id, 'mod_data', $data->id, get_string('rsstype')); |
a593aeee | 353 | echo '</div>'; |
354 | echo '<div style="clear:both;"></div>'; | |
9e86f2e7 | 355 | }*/ |
aab98aaf | 356 | |
9e08cf6e | 357 | if ($data->intro and empty($page) and empty($record) and $mode != 'single') { |
39790bd8 | 358 | $options = new stdClass(); |
ea6073bb | 359 | $options->noclean = true; |
56135f6b | 360 | } |
f7a00e9d | 361 | echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro'); |
3eb032d7 | 362 | |
66e2b9f8 AD |
363 | $returnurl = $CFG->wwwroot . '/mod/data/view.php?d='.$data->id.'&search='.s($search).'&sort='.s($sort).'&order='.s($order).'&'; |
364 | groups_print_activity_menu($cm, $returnurl); | |
56135f6b | 365 | |
473dd288 | 366 | /// Delete any requested records |
367 | ||
cf9ecfda | 368 | if ($delete && confirm_sesskey() && ($canmanageentries or data_isowner($delete))) { |
3d45b8e5 | 369 | if ($confirm = optional_param('confirm',0,PARAM_INT)) { |
cf9ecfda AG |
370 | if (data_delete_record($delete, $data, $course->id, $cm->id)) { |
371 | echo $OUTPUT->notification(get_string('recorddeleted','data'), 'notifysuccess'); | |
3d4b223a | 372 | } |
3d45b8e5 | 373 | } else { // Print a confirmation page |
3223bc9e | 374 | if ($deleterecord = $DB->get_record('data_records', array('id'=>$delete))) { // Need to check this is valid |
64452eb4 | 375 | if ($deleterecord->dataid == $data->id) { // Must be from this database |
e822f07b | 376 | $deletebutton = new single_button(new moodle_url('/mod/data/view.php?d='.$data->id.'&delete='.$delete.'&confirm=1'), get_string('delete'), 'post'); |
cd6137d7 | 377 | echo $OUTPUT->confirm(get_string('confirmdeleterecord','data'), |
e822f07b | 378 | $deletebutton, 'view.php?d='.$data->id); |
3d45b8e5 | 379 | |
64452eb4 | 380 | $records[] = $deleterecord; |
3f9672d3 | 381 | echo data_print_template('singletemplate', $records, $data, '', 0, true); |
64452eb4 | 382 | |
7b30ba8b | 383 | echo $OUTPUT->footer(); |
64452eb4 | 384 | exit; |
385 | } | |
386 | } | |
387 | } | |
388 | } | |
389 | ||
390 | ||
cf9ecfda AG |
391 | // Multi-delete. |
392 | if ($serialdelete) { | |
393 | $multidelete = json_decode($serialdelete); | |
394 | } | |
395 | ||
396 | if ($multidelete && confirm_sesskey() && $canmanageentries) { | |
397 | if ($confirm = optional_param('confirm', 0, PARAM_INT)) { | |
398 | foreach ($multidelete as $value) { | |
399 | data_delete_record($value, $data, $course->id, $cm->id); | |
400 | } | |
401 | } else { | |
402 | $validrecords = array(); | |
403 | $recordids = array(); | |
404 | foreach ($multidelete as $value) { | |
405 | if ($deleterecord = $DB->get_record('data_records', array('id'=>$value))) { // Need to check this is valid | |
406 | if ($deleterecord->dataid == $data->id) { // Must be from this database | |
407 | $validrecords[] = $deleterecord; | |
408 | $recordids[] = $deleterecord->id; | |
409 | } | |
410 | } | |
411 | } | |
412 | ||
413 | $serialiseddata = json_encode($recordids); | |
414 | $submitactions = array('d' => $data->id, 'sesskey' => sesskey(), 'confirm' => '1', 'serialdelete' => $serialiseddata); | |
415 | $action = new moodle_url('/mod/data/view.php', $submitactions); | |
416 | $cancelurl = new moodle_url('/mod/data/view.php', array('d' => $data->id)); | |
417 | $deletebutton = new single_button($action, get_string('delete')); | |
418 | echo $OUTPUT->confirm(get_string('confirmdeleterecords', 'data'), $deletebutton, $cancelurl); | |
419 | echo data_print_template('listtemplate', $validrecords, $data, '', 0, false); | |
420 | echo $OUTPUT->footer(); | |
421 | exit; | |
422 | } | |
423 | } | |
424 | ||
425 | ||
2742ffe7 | 426 | //if data activity closed dont let students in |
4a9eecc4 | 427 | $showactivity = true; |
cf9ecfda | 428 | if (!$canmanageentries) { |
2742ffe7 AD |
429 | $timenow = time(); |
430 | if (!empty($data->timeavailablefrom) && $data->timeavailablefrom > $timenow) { | |
4a9eecc4 AD |
431 | echo $OUTPUT->notification(get_string('notopenyet', 'data', userdate($data->timeavailablefrom))); |
432 | $showactivity = false; | |
2742ffe7 | 433 | } else if (!empty($data->timeavailableto) && $timenow > $data->timeavailableto) { |
4a9eecc4 AD |
434 | echo $OUTPUT->notification(get_string('expired', 'data', userdate($data->timeavailableto))); |
435 | $showactivity = false; | |
2742ffe7 AD |
436 | } |
437 | } | |
64452eb4 | 438 | |
4a9eecc4 AD |
439 | if ($showactivity) { |
440 | // Print the tabs | |
64452eb4 | 441 | if ($record or $mode == 'single') { |
442 | $currenttab = 'single'; | |
7900ecb0 | 443 | } elseif($mode == 'asearch') { |
444 | $currenttab = 'asearch'; | |
445 | } | |
446 | else { | |
64452eb4 | 447 | $currenttab = 'list'; |
448 | } | |
aab98aaf | 449 | include('tabs.php'); |
64452eb4 | 450 | |
cf9ecfda AG |
451 | $url = new moodle_url('/mod/data/view.php', array('d' => $data->id, 'sesskey' => sesskey())); |
452 | echo html_writer::start_tag('form', array('action' => $url, 'method' => 'post')); | |
453 | ||
eeeb4f2a | 454 | if ($mode == 'asearch') { |
455 | $maxcount = 0; | |
8429163d | 456 | |
eeeb4f2a | 457 | } else { |
d0372ed6 | 458 | // Approve or disapprove any requested records |
e3487936 | 459 | $params = array(); // named params array |
64452eb4 | 460 | |
8429163d | 461 | $approvecap = has_capability('mod/data:approve', $context); |
bb5740f4 | 462 | |
d0372ed6 HB |
463 | if (($approve || $disapprove) && confirm_sesskey() && $approvecap) { |
464 | $newapproved = $approve ? 1 : 0; | |
465 | $recordid = $newapproved ? $approve : $disapprove; | |
466 | if ($approverecord = $DB->get_record('data_records', array('id' => $recordid))) { // Need to check this is valid | |
7900ecb0 | 467 | if ($approverecord->dataid == $data->id) { // Must be from this database |
39790bd8 | 468 | $newrecord = new stdClass(); |
7900ecb0 | 469 | $newrecord->id = $approverecord->id; |
d0372ed6 | 470 | $newrecord->approved = $newapproved; |
dd88de0e | 471 | $DB->update_record('data_records', $newrecord); |
d0372ed6 HB |
472 | $msgkey = $newapproved ? 'recordapproved' : 'recorddisapproved'; |
473 | echo $OUTPUT->notification(get_string($msgkey, 'data'), 'notifysuccess'); | |
64452eb4 | 474 | } |
475 | } | |
3d4b223a | 476 | } |
8429163d | 477 | |
c861f079 | 478 | $numentries = data_numentries($data); |
479 | /// Check the number of entries required against the number of entries already made (doesn't apply to teachers) | |
cf9ecfda | 480 | if ($data->requiredentries > 0 && $numentries < $data->requiredentries && !$canmanageentries) { |
eeeb4f2a | 481 | $data->entriesleft = $data->requiredentries - $numentries; |
482 | $strentrieslefttoadd = get_string('entrieslefttoadd', 'data', $data); | |
4102b449 | 483 | echo $OUTPUT->notification($strentrieslefttoadd); |
c861f079 | 484 | } |
485 | ||
486 | /// Check the number of entries required before to view other participant's entries against the number of entries already made (doesn't apply to teachers) | |
487 | $requiredentries_allowed = true; | |
cf9ecfda | 488 | if ($data->requiredentriestoview > 0 && $numentries < $data->requiredentriestoview && !$canmanageentries) { |
c861f079 | 489 | $data->entrieslefttoview = $data->requiredentriestoview - $numentries; |
490 | $strentrieslefttoaddtoview = get_string('entrieslefttoaddtoview', 'data', $data); | |
4102b449 | 491 | echo $OUTPUT->notification($strentrieslefttoaddtoview); |
eeeb4f2a | 492 | $requiredentries_allowed = false; |
493 | } | |
3d4b223a | 494 | |
e2c5f386 AG |
495 | // Initialise the first group of params for advanced searches. |
496 | $initialparams = array(); | |
497 | ||
bb5740f4 | 498 | /// setup group and approve restrictions |
499 | if (!$approvecap && $data->approval) { | |
7900ecb0 | 500 | if (isloggedin()) { |
e3487936 | 501 | $approveselect = ' AND (r.approved=1 OR r.userid=:myid1) '; |
502 | $params['myid1'] = $USER->id; | |
e2c5f386 | 503 | $initialparams['myid1'] = $params['myid1']; |
7900ecb0 | 504 | } else { |
505 | $approveselect = ' AND r.approved=1 '; | |
506 | } | |
4431d2e0 | 507 | } else { |
7900ecb0 | 508 | $approveselect = ' '; |
4431d2e0 | 509 | } |
3d4b223a | 510 | |
7900ecb0 | 511 | if ($currentgroup) { |
e3487936 | 512 | $groupselect = " AND (r.groupid = :currentgroup OR r.groupid = 0)"; |
513 | $params['currentgroup'] = $currentgroup; | |
e2c5f386 | 514 | $initialparams['currentgroup'] = $params['currentgroup']; |
64452eb4 | 515 | } else { |
76fb0443 AG |
516 | if ($canviewallrecords) { |
517 | $groupselect = ' '; | |
518 | } else { | |
519 | // If separate groups are enabled and the user isn't in a group or | |
520 | // a teacher, manager, admin etc, then just show them entries for 'All participants'. | |
521 | $groupselect = " AND r.groupid = 0"; | |
522 | } | |
64452eb4 | 523 | } |
3d45b8e5 | 524 | |
5e1f1a6e | 525 | // Init some variables to be used by advanced search |
526 | $advsearchselect = ''; | |
527 | $advwhere = ''; | |
528 | $advtables = ''; | |
529 | $advparams = array(); | |
e2c5f386 AG |
530 | // This is used for the initial reduction of advanced search results with required entries. |
531 | $entrysql = ''; | |
a327f25e | 532 | $namefields = get_all_user_name_fields(true, 'u'); |
5e1f1a6e | 533 | |
7900ecb0 | 534 | /// Find the field we are sorting on |
3239b010 | 535 | if ($sort <= 0 or !$sortfield = data_get_field_from_id($sort, $data)) { |
bb5740f4 | 536 | |
537 | switch ($sort) { | |
538 | case DATA_LASTNAME: | |
539 | $ordering = "u.lastname $order, u.firstname $order"; | |
540 | break; | |
541 | case DATA_FIRSTNAME: | |
542 | $ordering = "u.firstname $order, u.lastname $order"; | |
543 | break; | |
544 | case DATA_APPROVED: | |
545 | $ordering = "r.approved $order, r.timecreated $order"; | |
546 | break; | |
3239b010 | 547 | case DATA_TIMEMODIFIED: |
548 | $ordering = "r.timemodified $order"; | |
549 | break; | |
550 | case DATA_TIMEADDED: | |
bb5740f4 | 551 | default: |
3239b010 | 552 | $sort = 0; |
bb5740f4 | 553 | $ordering = "r.timecreated $order"; |
714bec74 | 554 | } |
555 | ||
a327f25e | 556 | $what = ' DISTINCT r.id, r.approved, r.timecreated, r.timemodified, r.userid, ' . $namefields; |
714bec74 | 557 | $count = ' COUNT(DISTINCT c.recordid) '; |
eb6e0c61 | 558 | $tables = '{data_content} c,{data_records} r, {user} u '; |
714bec74 | 559 | $where = 'WHERE c.recordid = r.id |
e3487936 | 560 | AND r.dataid = :dataid |
eb6e0c61 | 561 | AND r.userid = u.id '; |
e3487936 | 562 | $params['dataid'] = $data->id; |
714bec74 | 563 | $sortorder = ' ORDER BY '.$ordering.', r.id ASC '; |
564 | $searchselect = ''; | |
565 | ||
566 | // If requiredentries is not reached, only show current user's entries | |
567 | if (!$requiredentries_allowed) { | |
e3487936 | 568 | $where .= ' AND u.id = :myid2 '; |
e2c5f386 | 569 | $entrysql = ' AND r.userid = :myid3 '; |
e3487936 | 570 | $params['myid2'] = $USER->id; |
e2c5f386 | 571 | $initialparams['myid3'] = $params['myid2']; |
714bec74 | 572 | } |
573 | ||
574 | if (!empty($advanced)) { //If advanced box is checked. | |
e3487936 | 575 | $i = 0; |
714bec74 | 576 | foreach($search_array as $key => $val) { //what does $search_array hold? |
577 | if ($key == DATA_FIRSTNAME or $key == DATA_LASTNAME) { | |
e3487936 | 578 | $i++; |
800bb0f7 | 579 | $searchselect .= " AND ".$DB->sql_like($val->field, ":search_flname_$i", false); |
e3487936 | 580 | $params['search_flname_'.$i] = "%$val->data%"; |
714bec74 | 581 | continue; |
582 | } | |
5e1f1a6e | 583 | $advtables .= ', {data_content} c'.$key.' '; |
584 | $advwhere .= ' AND c'.$key.'.recordid = r.id'; | |
585 | $advsearchselect .= ' AND ('.$val->sql.') '; | |
586 | $advparams = array_merge($advparams, $val->params); | |
714bec74 | 587 | } |
588 | } else if ($search) { | |
a327f25e AG |
589 | $searchselect = " AND (".$DB->sql_like('c.content', ':search1', false)." |
590 | OR ".$DB->sql_like('u.firstname', ':search2', false)." | |
591 | OR ".$DB->sql_like('u.lastname', ':search3', false)." ) "; | |
e3487936 | 592 | $params['search1'] = "%$search%"; |
593 | $params['search2'] = "%$search%"; | |
594 | $params['search3'] = "%$search%"; | |
714bec74 | 595 | } else { |
596 | $searchselect = ' '; | |
597 | } | |
598 | ||
3239b010 | 599 | } else { |
7900ecb0 | 600 | |
6e6878b5 EL |
601 | $sortcontent = $DB->sql_compare_text('c.' . $sortfield->get_sort_field()); |
602 | $sortcontentfull = $sortfield->get_sort_sql($sortcontent); | |
714bec74 | 603 | |
a327f25e AG |
604 | $what = ' DISTINCT r.id, r.approved, r.timecreated, r.timemodified, r.userid, ' . $namefields . ', |
605 | ' . $sortcontentfull . ' AS sortorder '; | |
7900ecb0 | 606 | $count = ' COUNT(DISTINCT c.recordid) '; |
eb6e0c61 | 607 | $tables = '{data_content} c, {data_records} r, {user} u '; |
7900ecb0 | 608 | $where = 'WHERE c.recordid = r.id |
e3487936 | 609 | AND r.dataid = :dataid |
eb6e0c61 | 610 | AND r.userid = u.id '; |
e2c5f386 AG |
611 | if (!$advanced) { |
612 | $where .= 'AND c.fieldid = :sort'; | |
613 | } | |
e3487936 | 614 | $params['dataid'] = $data->id; |
615 | $params['sort'] = $sort; | |
0a498686 | 616 | $sortorder = ' ORDER BY sortorder '.$order.' , r.id ASC '; |
7900ecb0 | 617 | $searchselect = ''; |
714bec74 | 618 | |
87518137 | 619 | // If requiredentries is not reached, only show current user's entries |
620 | if (!$requiredentries_allowed) { | |
e2c5f386 AG |
621 | $where .= ' AND u.id = :myid2'; |
622 | $entrysql = ' AND r.userid = :myid3'; | |
e3487936 | 623 | $params['myid2'] = $USER->id; |
e2c5f386 | 624 | $initialparams['myid3'] = $params['myid2']; |
87518137 | 625 | } |
db546510 | 626 | $i = 0; |
714bec74 | 627 | if (!empty($advanced)) { //If advanced box is checked. |
628 | foreach($search_array as $key => $val) { //what does $search_array hold? | |
629 | if ($key == DATA_FIRSTNAME or $key == DATA_LASTNAME) { | |
e3487936 | 630 | $i++; |
800bb0f7 | 631 | $searchselect .= " AND ".$DB->sql_like($val->field, ":search_flname_$i", false); |
e3487936 | 632 | $params['search_flname_'.$i] = "%$val->data%"; |
714bec74 | 633 | continue; |
634 | } | |
5e1f1a6e | 635 | $advtables .= ', {data_content} c'.$key.' '; |
636 | $advwhere .= ' AND c'.$key.'.recordid = r.id AND c'.$key.'.fieldid = '.$key; | |
637 | $advsearchselect .= ' AND ('.$val->sql.') '; | |
638 | $advparams = array_merge($advparams, $val->params); | |
7900ecb0 | 639 | } |
714bec74 | 640 | } else if ($search) { |
eb6e0c61 | 641 | $searchselect = " AND (".$DB->sql_like('c.content', ':search1', false)." OR ".$DB->sql_like('u.firstname', ':search2', false)." OR ".$DB->sql_like('u.lastname', ':search3', false)." ) "; |
e3487936 | 642 | $params['search1'] = "%$search%"; |
643 | $params['search2'] = "%$search%"; | |
644 | $params['search3'] = "%$search%"; | |
7900ecb0 | 645 | } else { |
646 | $searchselect = ' '; | |
714bec74 | 647 | } |
7900ecb0 | 648 | } |
3d4b223a | 649 | |
7900ecb0 | 650 | /// To actually fetch the records |
3d45b8e5 | 651 | |
5e1f1a6e | 652 | $fromsql = "FROM $tables $advtables $where $advwhere $groupselect $approveselect $searchselect $advsearchselect"; |
5e1f1a6e | 653 | $allparams = array_merge($params, $advparams); |
3d45b8e5 | 654 | |
76fb0443 | 655 | // Provide initial sql statements and parameters to reduce the number of total records. |
e2c5f386 | 656 | $initialselect = $groupselect . $approveselect . $entrysql; |
76fb0443 | 657 | |
e2c5f386 | 658 | $recordids = data_get_all_recordids($data->id, $initialselect, $initialparams); |
db546510 | 659 | $newrecordids = data_get_advance_search_ids($recordids, $search_array, $data->id); |
0ba303e8 | 660 | $totalcount = count($newrecordids); |
e2c5f386 | 661 | $selectdata = $where . $groupselect . $approveselect; |
db546510 | 662 | |
663 | if (!empty($advanced)) { | |
664 | $advancedsearchsql = data_get_advanced_search_sql($sort, $data, $newrecordids, $selectdata, $sortorder); | |
665 | $sqlselect = $advancedsearchsql['sql']; | |
666 | $allparams = array_merge($allparams, $advancedsearchsql['params']); | |
667 | } else { | |
668 | $sqlselect = "SELECT $what $fromsql $sortorder"; | |
669 | } | |
3d45b8e5 | 670 | |
db546510 | 671 | /// Work out the paging numbers and counts |
5e1f1a6e | 672 | if (empty($searchselect) && empty($advsearchselect)) { |
eeeb4f2a | 673 | $maxcount = $totalcount; |
674 | } else { | |
db546510 | 675 | $maxcount = count($recordids); |
eeeb4f2a | 676 | } |
3d4b223a | 677 | |
7900ecb0 | 678 | if ($record) { // We need to just show one, so where is it in context? |
679 | $nowperpage = 1; | |
680 | $mode = 'single'; | |
db79db63 AG |
681 | $page = 0; |
682 | // TODO MDL-33797 - Reduce this or consider redesigning the paging system. | |
683 | if ($allrecordids = $DB->get_fieldset_sql($sqlselect, $allparams)) { | |
684 | $page = (int)array_search($record->id, $allrecordids); | |
685 | unset($allrecordids); | |
686 | } | |
7900ecb0 | 687 | } else if ($mode == 'single') { // We rely on ambient $page settings |
688 | $nowperpage = 1; | |
3d45b8e5 | 689 | |
7900ecb0 | 690 | } else { |
691 | $nowperpage = $perpage; | |
692 | } | |
3d45b8e5 | 693 | |
7900ecb0 | 694 | /// Get the actual records |
8429163d | 695 | |
5e1f1a6e | 696 | if (!$records = $DB->get_records_sql($sqlselect, $allparams, $page * $nowperpage, $nowperpage)) { |
eeeb4f2a | 697 | // Nothing to show! |
7900ecb0 | 698 | if ($record) { // Something was requested so try to show that at least (bug 5132) |
cf9ecfda | 699 | if ($canmanageentries || empty($data->approval) || |
7900ecb0 | 700 | $record->approved || (isloggedin() && $record->userid == $USER->id)) { |
701 | if (!$currentgroup || $record->groupid == $currentgroup || $record->groupid == 0) { | |
eeeb4f2a | 702 | // OK, we can show this one |
703 | $records = array($record->id => $record); | |
704 | $totalcount = 1; | |
7900ecb0 | 705 | } |
3dec563c | 706 | } |
707 | } | |
eeeb4f2a | 708 | } |
709 | ||
710 | if (empty($records)) { | |
711 | if ($maxcount){ | |
39790bd8 | 712 | $a = new stdClass(); |
eeeb4f2a | 713 | $a->max = $maxcount; |
714 | $a->reseturl = "view.php?id=$cm->id&mode=$mode&search=&advanced=0"; | |
4102b449 | 715 | echo $OUTPUT->notification(get_string('foundnorecords','data', $a)); |
7900ecb0 | 716 | } else { |
4102b449 | 717 | echo $OUTPUT->notification(get_string('norecords','data')); |
7900ecb0 | 718 | } |
cf3e199b | 719 | |
eeeb4f2a | 720 | } else { // We have some records to print |
721 | ||
722 | if ($maxcount != $totalcount) { | |
39790bd8 | 723 | $a = new stdClass(); |
eeeb4f2a | 724 | $a->num = $totalcount; |
725 | $a->max = $maxcount; | |
726 | $a->reseturl = "view.php?id=$cm->id&mode=$mode&search=&advanced=0"; | |
4102b449 | 727 | echo $OUTPUT->notification(get_string('foundrecords', 'data', $a), 'notifysuccess'); |
eeeb4f2a | 728 | } |
68c88622 | 729 | |
c04b01f4 AD |
730 | if ($mode == 'single') { // Single template |
731 | $baseurl = 'view.php?d=' . $data->id . '&mode=single&'; | |
2d9b3ef2 | 732 | if (!empty($search)) { |
c04b01f4 AD |
733 | $baseurl .= 'filter=1&'; |
734 | } | |
735 | if (!empty($page)) { | |
736 | $baseurl .= 'page=' . $page; | |
2d9b3ef2 | 737 | } |
929d7a83 | 738 | echo $OUTPUT->paging_bar($totalcount, $page, $nowperpage, $baseurl); |
3d45b8e5 | 739 | |
7900ecb0 | 740 | if (empty($data->singletemplate)){ |
4102b449 | 741 | echo $OUTPUT->notification(get_string('nosingletemplate','data')); |
7900ecb0 | 742 | data_generate_default_template($data, 'singletemplate', 0, false, false); |
743 | } | |
3d4b223a | 744 | |
d251b259 AD |
745 | //data_print_template() only adds ratings for singletemplate which is why we're attaching them here |
746 | //attach ratings to data records | |
747 | require_once($CFG->dirroot.'/rating/lib.php'); | |
2b04c41c SH |
748 | if ($data->assessed != RATING_AGGREGATE_NONE) { |
749 | $ratingoptions = new stdClass; | |
195a0848 | 750 | $ratingoptions->context = $context; |
2c2ff8d5 | 751 | $ratingoptions->component = 'mod_data'; |
2b04c41c | 752 | $ratingoptions->ratingarea = 'entry'; |
198ff498 AD |
753 | $ratingoptions->items = $records; |
754 | $ratingoptions->aggregate = $data->assessed;//the aggregation method | |
755 | $ratingoptions->scaleid = $data->scale; | |
756 | $ratingoptions->userid = $USER->id; | |
757 | $ratingoptions->returnurl = $CFG->wwwroot.'/mod/data/'.$baseurl; | |
758 | $ratingoptions->assesstimestart = $data->assesstimestart; | |
759 | $ratingoptions->assesstimefinish = $data->assesstimefinish; | |
198ff498 AD |
760 | |
761 | $rm = new rating_manager(); | |
762 | $records = $rm->get_ratings($ratingoptions); | |
763 | } | |
d251b259 | 764 | |
7900ecb0 | 765 | data_print_template('singletemplate', $records, $data, $search, $page); |
3d45b8e5 | 766 | |
929d7a83 | 767 | echo $OUTPUT->paging_bar($totalcount, $page, $nowperpage, $baseurl); |
3d45b8e5 | 768 | |
7900ecb0 | 769 | } else { // List template |
770 | $baseurl = 'view.php?d='.$data->id.'&'; | |
771 | //send the advanced flag through the URL so it is remembered while paging. | |
772 | $baseurl .= 'advanced='.$advanced.'&'; | |
2d9b3ef2 | 773 | if (!empty($search)) { |
774 | $baseurl .= 'filter=1&'; | |
775 | } | |
7900ecb0 | 776 | //pass variable to allow determining whether or not we are paging through results. |
777 | $baseurl .= 'paging='.$paging.'&'; | |
3d45b8e5 | 778 | |
929d7a83 | 779 | echo $OUTPUT->paging_bar($totalcount, $page, $nowperpage, $baseurl); |
3d45b8e5 | 780 | |
7900ecb0 | 781 | if (empty($data->listtemplate)){ |
4102b449 | 782 | echo $OUTPUT->notification(get_string('nolisttemplate','data')); |
7900ecb0 | 783 | data_generate_default_template($data, 'listtemplate', 0, false, false); |
784 | } | |
785 | echo $data->listtemplateheader; | |
786 | data_print_template('listtemplate', $records, $data, $search, $page); | |
787 | echo $data->listtemplatefooter; | |
788 | ||
929d7a83 | 789 | echo $OUTPUT->paging_bar($totalcount, $page, $nowperpage, $baseurl); |
3d45b8e5 | 790 | } |
3d45b8e5 | 791 | |
3d45b8e5 | 792 | } |
7900ecb0 | 793 | } |
8429163d | 794 | |
7900ecb0 | 795 | $search = trim($search); |
796 | if (empty($records)) { | |
797 | $records = array(); | |
f852d652 | 798 | } |
799 | ||
db22e31b AG |
800 | if ($mode != 'single' && $canmanageentries) { |
801 | echo html_writer::empty_tag('input', array('type' => 'button', 'id' => 'checkall', 'value' => get_string('selectall'))); | |
802 | echo html_writer::empty_tag('input', array('type' => 'button', 'id' => 'checknone', 'value' => get_string('deselectall'))); | |
803 | echo html_writer::empty_tag('input', array('class' => 'form-submit', 'type' => 'submit', 'value' => get_string('deleteselected'))); | |
804 | ||
805 | $module = array('name'=>'mod_data', 'fullpath'=>'/mod/data/module.js'); | |
806 | $PAGE->requires->js_init_call('M.mod_data.init_view', null, false, $module); | |
807 | } | |
808 | echo html_writer::end_tag('form'); | |
809 | ||
dfdd9c9b | 810 | if ($mode == '' && !empty($CFG->enableportfolios) && !empty($records)) { |
c3e1b5bd PL |
811 | require_once($CFG->libdir . '/portfoliolib.php'); |
812 | $button = new portfolio_add_button(); | |
37743241 | 813 | $button->set_callback_options('data_portfolio_caller', array('id' => $cm->id), 'mod_data'); |
c3e1b5bd PL |
814 | if (data_portfolio_caller::has_files($data)) { |
815 | $button->set_formats(array(PORTFOLIO_FORMAT_RICHHTML, PORTFOLIO_FORMAT_LEAP2A)); // no plain html for us | |
816 | } | |
817 | echo $button->to_html(PORTFOLIO_ADD_FULL_FORM); | |
818 | } | |
819 | ||
7900ecb0 | 820 | //Advanced search form doesn't make sense for single (redirects list view) |
eeeb4f2a | 821 | if (($maxcount || $mode == 'asearch') && $mode != 'single') { |
7900ecb0 | 822 | data_print_preference_form($data, $perpage, $search, $sort, $order, $search_array, $advanced, $mode); |
64452eb4 | 823 | } |
4a9eecc4 | 824 | } |
d4a03c00 | 825 | |
4a9eecc4 | 826 | echo $OUTPUT->footer(); |