Moving <td>, fixing bug 5019
[moodle.git] / mod / data / view.php
CommitLineData
3d4b223a 1<?php // $Id$
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
25 require_once('../../config.php');
26 require_once('lib.php');
27 require_once($CFG->libdir.'/blocklib.php');
a593aeee 28 require_once("$CFG->libdir/rsslib.php");
3d4b223a 29
3d4b223a 30 require_once('pagelib.php');
7ddda9db 31
3d4b223a 32
3d4b223a 33 $id = optional_param('id', 0, PARAM_INT); // course module id
34 $d = optional_param('d', 0, PARAM_INT); // database id
35 $search = optional_param('search','',PARAM_NOTAGS); //search string
36 $page = optional_param('page', 0, PARAM_INT); //offset of the current record
37 $rid = optional_param('rid', 0, PARAM_INT); //record id
473dd288 38 $approve = optional_param('approve', 0, PARAM_INT); //approval recordid
39 $delete = optional_param('delete', 0, PARAM_INT); //delete recordid
3d4b223a 40 $perpagemenu = optional_param('perpage1', 0, PARAM_INT); //value from drop down
e0279f63 41 $sort = optional_param('sort',-1,PARAM_INT); //sort by field
cf3e199b 42 $order = optional_param('order','ASC',PARAM_ALPHA); //sort order
f4e101bd 43 $group = optional_param('group','0',PARAM_INT); //groupid
cf3e199b 44
5f5bcda8 45
3d4b223a 46 if ($id) {
47 if (! $cm = get_record('course_modules', 'id', $id)) {
48 error('Course Module ID was incorrect');
49 }
50 if (! $course = get_record('course', 'id', $cm->course)) {
51 error('Course is misconfigured');
52 }
53 if (! $data = get_record('data', 'id', $cm->instance)) {
54 error('Course module is incorrect');
55 }
56
57 } else {
58 if (! $data = get_record('data', 'id', $d)) {
59 error('Data ID is incorrect');
60 }
61 if (! $course = get_record('course', 'id', $data->course)) {
62 error('Course is misconfigured');
63 }
64 if (! $cm = get_coursemodule_from_instance('data', $data->id, $course->id)) {
65 error('Course Module ID was incorrect');
66 }
67 }
68
7ddda9db 69 require_course_login($course, true, $cm);
70
3d4b223a 71 if (isteacher($course->id)) {
ed69c723 72 if (!record_exists('data_fields','dataid',$data->id)) { // Brand new database!
5bac6d10 73 redirect($CFG->wwwroot.'/mod/data/field.php?d='.$data->id); // Redirect to field entry
3d4b223a 74 }
75 }
e0279f63 76
77 /// If we haven't set a sort field use the default sort field
78 if ($sort == -1) {
79 $sort = $data->defaultsort;
80 $order = ($data->defaultsortdir == 0) ? 'ASC' : 'DESC';
81 }
3d4b223a 82
83 //set user preference if available
473dd288 84 if (isset($_GET['updatepref'])){
3d4b223a 85
86 if (!$perpage = $perpagemenu){ //if menu not in use, use the text field
87 $perpage = (int)optional_param('perpage',10);
88 }
89 $perpage = ($perpage <= 0) ? 10 : $perpage ;
90 set_user_preference('data_perpage', $perpage);
91 }
92
93 $d = $data->id;//set this so tabs can work properly
ed69c723 94
3d4b223a 95 add_to_log($course->id, 'data', 'view', "view.php?id=$cm->id", $data->id, $cm->id);
96
97
98// Initialize $PAGE, compute blocks
99 $PAGE = page_create_instance($data->id);
100 $pageblocks = blocks_setup($PAGE);
101 $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), 210);
102
103 if (!empty($edit) && $PAGE->user_allowed_editing()) {
104 if ($edit == 'on') {
105 $USER->editing = true;
106 } else if ($edit == 'off') {
107 $USER->editing = false;
108 }
109 }
3d4b223a 110
c853304e 111/// RSS meta
112 $rssmeta = '';
113 if (isset($CFG->enablerssfeeds) && isset($CFG->data_enablerssfeeds) && $data->rssarticles > 0) {
114 $rsspath = rss_get_url($course->id, $USER->id, 'data', $data->id);
115 $rssmeta = '<link rel="alternate" type="application/rss+xml" ';
116 $rssmeta .= 'title ="'.$course->shortname.': %fullname%" href="'.$rsspath.'" />';
117 }
118
119/// Print the page header
1cfc979a 120 $PAGE->print_header($course->shortname.': %fullname%', '', $rssmeta);
c853304e 121
3d4b223a 122 echo '<table id="layout-table"><tr>';
123
124 if(!empty($CFG->showblocksonmodpages) && (blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $PAGE->user_is_editing())) {
125 echo '<td style="width: '.$blocks_preferred_width.'px;" id="left-column">';
126 blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT);
127 echo '</td>';
128 }
129
130 echo '<td id="middle-column">';
131
132 print_heading(format_string($data->name));
a593aeee 133
a593aeee 134 // Do we need to show a link to the RSS feed for the records?
135 if (isset($CFG->enablerssfeeds) && isset($CFG->data_enablerssfeeds) && $data->rssarticles > 0) {
136 echo '<div style="float:right;">';
ed69c723 137 rss_print_link($course->id, $USER->id, 'data', $data->id, get_string('rsstype'));
a593aeee 138 echo '</div>';
139 echo '<div style="clear:both;"></div>';
140 }
141
dbdfc3db 142 if ($data->intro and empty($sort) and empty($search) and empty($page) and empty($rid)) {
56135f6b 143 print_simple_box(format_text($data->intro), 'center', '70%', '', 5, 'generalbox', 'intro');
56135f6b 144 }
145
3d4b223a 146/// Check to see if groups are being used here
147 if ($groupmode = groupmode($course, $cm)) { // Groups are being used
ed69c723 148 $currentgroup = setup_and_print_groups($course, $groupmode,
149 'view.php?d='.$data->id.'&amp;search='.s($search).'&amp;sort='.s($sort).
150 '&amp;order='.s($order).'&amp;');
3d4b223a 151 } else {
152 $currentgroup = 0;
153 }
154
155 if ($currentgroup) {
5d9a7c35 156 $groupselect = " AND (r.groupid = '$currentgroup' OR r.groupid = 0)";
3d4b223a 157 $groupparam = "&amp;groupid=$currentgroup";
158 } else {
159 $groupselect = "";
160 $groupparam = "";
161 }
162
163/// Print the tabs
164
165 $currenttab = 'browse';
166 include('tabs.php');
167
75c42c87 168 $perpage = get_user_preferences('data_perpage', 10); //get default per page
169
473dd288 170/// Approve any requested records
3d4b223a 171
473dd288 172 if ($approve && confirm_sesskey() && isteacher($course->id)) {
173 if ($record = get_record('data_records', 'id', $approve)) { // Need to check this is valid
174 if ($record->dataid == $data->id) { // Must be from this database
175 $newrecord->id = $record->id;
176 $newrecord->approved = 1;
177 if (update_record('data_records', $newrecord)) {
178 notify(get_string('recordapproved','data'), 'notifysuccess');
179 }
75c42c87 180 if ($perpage == 1) {
181 $rid = $approve;
182 }
473dd288 183 }
184 }
cf3e199b 185 }
ed69c723 186
473dd288 187/// Delete any requested records
188
189 if ($delete && confirm_sesskey()) {
75c42c87 190 if (isteacher($course->id) or data_isowner($delete)){
f0497d6f 191 if ($confirm = optional_param('confirm',0,PARAM_INT)) {
192 if ($contents = get_records('data_content','recordid', $delete)) {
193 foreach ($contents as $content) { // Delete files or whatever else this field allows
194 if ($field = data_get_field_from_id($content->fieldid, $data)) { // Might not be there
195 $field->delete_content($content->recordid);
3d4b223a 196 }
197 }
f0497d6f 198 }
199 delete_records('data_content','recordid',$delete);
200 delete_records('data_records','id',$delete);
0a09100f 201
f0497d6f 202 add_to_log($course->id, 'data', 'record delete', "view.php?id=$cm->id", $data->id, $cm->id);
0a09100f 203
75c42c87 204 notify(get_string('recorddeleted','data'), 'notifysuccess');
205
206 if ($perpage == 1) {
207 $rid = $delete;
208 }
f0497d6f 209
210 } else { // Print a confirmation page
211 notice_yesno(get_string('confirmdeleterecord','data'),
212 'view.php?d='.$data->id.'&amp;delete='.$delete.'&amp;confirm=1&amp;sesskey='.sesskey(),
213 'view.php?d='.$data->id);
214
3d4b223a 215 print_footer($course);
216 exit;
217 }
218 }
219 }
220
75c42c87 221// If not teacher, check whether user has sufficient records to view
222 if (!isteacher($course->id) and data_numentries($data) < $data->requiredentriestoview){
2b1d7c8e 223 notify (($data->requiredentriestoview - data_numentries($data)).'&nbsp;'.get_string('insufficiententries','data'));
af25f45e 224 echo '</td></tr></table>';
3d4b223a 225 print_footer($course);
226 exit;
227 }
228
75c42c87 229 if ($rid) { //set per page to 1, if looking for 1 specific record
0997e51a 230 set_user_preference('data_perpage', DATA_PERPAGE_SINGLE);
3d4b223a 231 }
3515ae35 232
3d4b223a 233 $perpage = get_user_preferences('data_perpage', 10); //get default per page
3d4b223a 234
f4e101bd 235 $baseurl = 'view.php?d='.$data->id.'&amp;search='.s($search).'&amp;sort='.s($sort).'&amp;order='.s($order).'&amp;group='.$currentgroup.'&amp;';
3d4b223a 236
3d4b223a 237
33819735 238/// Calculate all the records we're going to show.
239
4431d2e0 240 if ((!isteacher($course->id)) && ($data->approval)) {
241 if (isloggedin()) {
242 $approvesql = ' AND (r.approved=1 OR r.userid='.$USER->id.') ';
243 } else {
244 $approvesql = ' AND r.approved=1 ';
245 }
cf3e199b 246 } else {
247 $approvesql = '';
248 }
249
250 if ($rid){ //only used for single mode, but rid should not appear in multi view anyway
251 $ridsql = 'AND r.id < '.$rid.' ';
3d4b223a 252
cf3e199b 253 } else {
254 $ridsql = '';
3d4b223a 255 }
3d4b223a 256
cf3e199b 257 if ($sort) { //supports (sort and search)
cf3e199b 258 //first find the field that we are sorting
0997e51a 259 $sortfield = data_get_field_from_id($sort, $data);
cf3e199b 260 $sortcontent = $sortfield->get_sort_field();
cf3e199b 261 ///SEARCH AND SORT SQL
262 $sql = 'SELECT DISTINCT c.recordid, c.recordid
263 FROM '.$CFG->prefix.'data_content c, '
264 .$CFG->prefix.'data_records r, '
265 .$CFG->prefix.'data_content c1
266 WHERE c.recordid = r.id
267 AND c1.recordid = r.id
268 AND r.dataid = '.$data->id.'
f4e101bd 269 AND c.fieldid = '.$sort.' '.$groupselect.'
cf3e199b 270 AND ((c1.content LIKE "%'.$search.'%") OR
271 (c1.content1 LIKE "%'.$search.'%") OR
272 (c1.content2 LIKE "%'.$search.'%") OR
273 (c1.content3 LIKE "%'.$search.'%") OR
274 (c1.content4 LIKE "%'.$search.'%")) '.$approvesql.'
275 ORDER BY c.'.$sortcontent.' '.$order.' ';
276
277 $sqlcount = 'SELECT COUNT(DISTINCT c.recordid)
278 FROM '.$CFG->prefix.'data_content c, '
279 .$CFG->prefix.'data_records r, '
280 .$CFG->prefix.'data_content c1
281 WHERE c.recordid = r.id
282 AND c1.recordid = r.id
283 AND r.dataid = '.$data->id.'
f4e101bd 284 AND c.fieldid = '.$sort.' '.$groupselect.'
cf3e199b 285 AND ((c1.content LIKE "%'.$search.'%") OR
286 (c1.content1 LIKE "%'.$search.'%") OR
287 (c1.content2 LIKE "%'.$search.'%") OR
288 (c1.content3 LIKE "%'.$search.'%") OR
4d423a0b 289 (c1.content4 LIKE "%'.$search.'%")) '.$approvesql;
cf3e199b 290
291 //sqlindex is used to find the number of entries smaller than the current rid
292 //useful for zooming into single view from multi view (so we can keep track
293 //of exact and relative position of records
294 $sqlindex = 'SELECT COUNT(DISTINCT c.recordid)
295 FROM '.$CFG->prefix.'data_content c, '
296 .$CFG->prefix.'data_records r, '
297 .$CFG->prefix.'data_content c1
298 WHERE c.recordid = r.id
299 AND c1.recordid = r.id
300 AND r.dataid = '.$data->id.'
f4e101bd 301 AND c.fieldid = '.$sort.' '.$ridsql.' '.$groupselect.'
cf3e199b 302 AND ((c1.content LIKE "%'.$search.'%") OR
303 (c1.content1 LIKE "%'.$search.'%") OR
304 (c1.content2 LIKE "%'.$search.'%") OR
305 (c1.content3 LIKE "%'.$search.'%") OR
4d423a0b 306 (c1.content4 LIKE "%'.$search.'%")) '.$approvesql;
cf3e199b 307
308 } else if ($search){ //search only, no sort. if in search mode, only search text fields
309
310 $sql = 'SELECT DISTINCT c.recordid, c.recordid
311 FROM '.$CFG->prefix.'data_content c, '
312 .$CFG->prefix.'data_fields f, '
313 .$CFG->prefix.'data_records r
f4e101bd 314 WHERE c.recordid = r.id '.$groupselect.' '.$approvesql.' AND
cf3e199b 315 c.fieldid = f.id AND f.dataid = '
1291b2d5 316 .$data->id.' AND c.content LIKE "%'.$search.'%" ORDER BY r.id '.$order.' ';
cf3e199b 317
318 $sqlcount = 'SELECT COUNT(DISTINCT c.recordid)
319 FROM '.$CFG->prefix.'data_content c, '
320 .$CFG->prefix.'data_fields f, '
321 .$CFG->prefix.'data_records r
f4e101bd 322 WHERE c.recordid = r.id '.$groupselect.' '.$approvesql.' AND
cf3e199b 323 c.fieldid = f.id AND f.dataid = '
4d423a0b 324 .$data->id.' AND c.content LIKE "%'.$search.'%"';
cf3e199b 325
326 $sqlindex = 'SELECT COUNT(DISTINCT c.recordid)
327 FROM '.$CFG->prefix.'data_content c, '
328 .$CFG->prefix.'data_fields f, '
329 .$CFG->prefix.'data_records r
f4e101bd 330 WHERE c.recordid = r.id '.$groupselect.' '.$approvesql.' AND
cf3e199b 331 c.fieldid = f.id AND f.dataid = '
4d423a0b 332 .$data->id.' '.$ridsql.' AND c.content LIKE "%'.$search.'%"';
cf3e199b 333
334 } else { //else get everything, no search, no sort
335
f4e101bd 336 $sql = 'SELECT * FROM '.$CFG->prefix.'data_records r WHERE r.dataid ='.$data->id.' '.$groupselect.' '.$approvesql.' ORDER BY r.id '.$order.' ';
4d423a0b 337 $sqlcount = 'SELECT COUNT(r.id) FROM '.$CFG->prefix
338 .'data_records r WHERE r.dataid ='.$data->id.' '.$groupselect.' '.$approvesql;
cf3e199b 339
4d423a0b 340 $sqlindex = 'SELECT COUNT(r.id) FROM '.$CFG->prefix
341 .'data_records r WHERE r.dataid ='.$data->id.' '.$groupselect.' '.$ridsql.' '.$approvesql;
cf3e199b 342 }
343
344 if ($rid) { //this is used in zooming
345 $page = count_records_sql($sqlindex);
3d4b223a 346 }
347
348 $limit = $perpage > 1 ? sql_paging_limit($page * $perpage, $perpage)
0997e51a 349 : $limit = sql_paging_limit($page, DATA_PERPAGE_SINGLE);
3d4b223a 350
351 $sql = $sql . $limit;
cf3e199b 352
3d4b223a 353 $totalcount = count_records_sql($sqlcount);
354
355 if (!$records = get_records_sql($sql)){
356 if ($search){
357 notify(get_string('nomatch','data'));
dbdfc3db 358 } else {
3d4b223a 359 notify(get_string('norecords','data'));
360 }
361
362 data_print_preference_form($data, $perpage, $search);
af25f45e 363 echo '</td></tr></table>';
3d4b223a 364 print_footer($course);
365 exit;
366 }
cf3e199b 367
33819735 368/// Print header for list view, and paging bar
369 if ($perpage > 1) {
3d4b223a 370 $listmode = 'listtemplate';
33819735 371 print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar='page');
372 echo $data->listtemplateheader;
3d4b223a 373 if (empty($data->listtemplate)){
374 notify(get_string('nolisttemplate','data'));
375 }
33819735 376 } else {
3d4b223a 377 $listmode = 'singletemplate';
378 if (empty($data->singletemplate)){
379 notify(get_string('nosingletemplate','data'));
380 }
33819735 381 print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar='page');
3d4b223a 382 }
68c88622 383
3d4b223a 384
33819735 385/// Print the template, substituting in all our data
f4e101bd 386 data_print_template($records, $data, $search, $listmode, $sort, $page, $rid, $order, $currentgroup);
3d4b223a 387
33819735 388/// Print footer
3d4b223a 389 if ($perpage > 1){
33819735 390 echo $data->listtemplatefooter;
3d4b223a 391 }
392
33819735 393 print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar='page');
394
cf3e199b 395 data_print_preference_form($data, $perpage, $search, $sort, $order);
af25f45e 396
3d4b223a 397 print_footer($course);
398
0997e51a 399?>