~ubuntu-branches/ubuntu/jaunty/moodle/jaunty

« back to all changes in this revision

Viewing changes to mod/data/lib.php

  • Committer: Bazaar Package Importer
  • Author(s): Jordan Mantha, Matt Oquist
  • Date: 2009-02-25 15:16:22 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20090225151622-0ekt1liwhv2obfza
Tags: 1.9.4.dfsg-0ubuntu1
* Merge with Debian git (Closes LP: #322961, #239481, #334611):
  - use Ubuntu's smarty lib directory for linking
  - use internal yui library 
  - add update-notifier support back in

[Matt Oquist]
  * renamed prerm script
  * significantly rewrote postinst and other maintainer scripts to improve
    user experience and package maintainability
    (Closes LP: #225662, #325450, #327843, #303078, #234609)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php  // $Id: lib.php,v 1.113.2.6 2007/05/15 18:27:04 skodak Exp $
 
1
<?php  // $Id: lib.php,v 1.137.2.44 2009/01/08 01:01:05 jerome Exp $
2
2
///////////////////////////////////////////////////////////////////////////
3
3
//                                                                       //
4
4
// NOTICE OF COPYRIGHT                                                   //
22
22
//                                                                       //
23
23
///////////////////////////////////////////////////////////////////////////
24
24
 
25
 
/// Some constants
 
25
// Some constants
26
26
define ('DATA_MAX_ENTRIES', 50);
27
27
define ('DATA_PERPAGE_SINGLE', 1);
28
 
 
29
 
class data_field_base {     /// Base class for Database Field Types (see field/*/field.class.php)
30
 
 
31
 
    var $type = 'unknown';  /// Subclasses must override the type with their name
32
 
    var $data = NULL;       /// The database object that this field belongs to
33
 
    var $field = NULL;      /// The field object itself, if we know it
34
 
 
35
 
    var $iconwidth = 16;    /// Width of the icon for this fieldtype
36
 
    var $iconheight = 16;   /// Width of the icon for this fieldtype
37
 
 
38
 
 
39
 
/// Constructor function
 
28
define ('DATA_FIRSTNAME', -1);
 
29
define ('DATA_LASTNAME', -2);
 
30
define ('DATA_APPROVED', -3);
 
31
define ('DATA_TIMEADDED', 0);
 
32
define ('DATA_TIMEMODIFIED', -4);
 
33
 
 
34
define ('DATA_CAP_EXPORT', 'mod/data:viewalluserpresets');
 
35
// Users having assigned the default role "Non-editing teacher" can export database records
 
36
// Using the mod/data capability "viewalluserpresets" for Moodle 1.9.x, so no change in the role system is required.
 
37
// In Moodle >= 2, new roles may be introduced and used instead. 
 
38
 
 
39
class data_field_base {     // Base class for Database Field Types (see field/*/field.class.php)
 
40
 
 
41
    var $type = 'unknown';  // Subclasses must override the type with their name
 
42
    var $data = NULL;       // The database object that this field belongs to
 
43
    var $field = NULL;      // The field object itself, if we know it
 
44
 
 
45
    var $iconwidth = 16;    // Width of the icon for this fieldtype
 
46
    var $iconheight = 16;   // Width of the icon for this fieldtype
 
47
 
 
48
 
 
49
// Constructor function
40
50
    function data_field_base($field=0, $data=0) {   // Field or data or both, each can be id or object
41
 
 
42
51
        if (empty($field) && empty($data)) {
43
52
            error('Programmer error: You must specify field and/or data when defining field class. ');
44
53
        }
45
 
 
46
54
        if (!empty($field)) {
47
55
            if (is_object($field)) {
48
56
                $this->field = $field;  // Programmer knows what they are doing, we hope
55
63
                }
56
64
            }
57
65
        }
58
 
 
59
66
        if (empty($this->data)) {         // We need to define this properly
60
67
            if (!empty($data)) {
61
68
                if (is_object($data)) {
67
74
                error('Data id or object must be provided to field class');
68
75
            }
69
76
        }
70
 
 
71
77
        if (empty($this->field)) {         // We need to define some default values
72
78
            $this->define_default_field();
73
79
        }
74
80
    }
75
81
 
76
82
 
77
 
/// This field just sets up a default field object
 
83
// This field just sets up a default field object
78
84
    function define_default_field() {
79
85
        if (empty($this->data->id)) {
80
86
            notify('Programmer error: dataid not defined in field class');
88
94
        $this->field->param3 = '';
89
95
        $this->field->name = '';
90
96
        $this->field->description = '';
91
 
 
92
97
        return true;
93
98
    }
94
99
 
95
 
/// Set up the field object according to data in an object.  Now is the time to clean it!
 
100
// Set up the field object according to data in an object. Now is the time to clean it!
96
101
    function define_field($data) {
97
102
        $this->field->type        = $this->type;
98
103
        $this->field->dataid      = $this->data->id;
119
124
        return true;
120
125
    }
121
126
 
122
 
/// Insert a new field in the database
123
 
/// We assume the field object is already defined as $this->field
 
127
// Insert a new field in the database
 
128
// We assume the field object is already defined as $this->field
124
129
    function insert_field() {
125
130
        if (empty($this->field)) {
126
131
            notify('Programmer error: Field has not been defined yet!  See define_field()');
135
140
    }
136
141
 
137
142
 
138
 
/// Update a field in the database
 
143
// Update a field in the database
139
144
    function update_field() {
140
145
        if (!update_record('data_fields', $this->field)) {
141
146
            notify('updating of new field failed!');
144
149
        return true;
145
150
    }
146
151
 
147
 
/// Delete a field completely
 
152
// Delete a field completely
148
153
    function delete_field() {
149
154
        if (!empty($this->field->id)) {
150
155
            delete_records('data_fields', 'id', $this->field->id);
153
158
        return true;
154
159
    }
155
160
 
156
 
/// Print the relevant form element in the ADD template for this field
 
161
// Print the relevant form element in the ADD template for this field
157
162
    function display_add_field($recordid=0){
158
163
        if ($recordid){
159
164
            $content = get_field('data_content', 'content', 'fieldid', $this->field->id, 'recordid', $recordid);
168
173
        return $str;
169
174
    }
170
175
 
171
 
/// Print the relevant form element to define the attributes for this field
172
 
/// viewable by teachers only.
 
176
// Print the relevant form element to define the attributes for this field
 
177
// viewable by teachers only.
173
178
    function display_edit_field() {
174
179
        global $CFG;
175
180
 
195
200
 
196
201
        require_once($CFG->dirroot.'/mod/data/field/'.$this->type.'/mod.html');
197
202
 
198
 
        echo '<div align="center">';
 
203
        echo '<div class="mdl-align">';
199
204
        echo '<input type="submit" value="'.$savebutton.'" />'."\n";
200
205
        echo '<input type="submit" name="cancel" value="'.get_string('cancel').'" />'."\n";
201
206
        echo '</div>';
205
210
        print_simple_box_end();
206
211
    }
207
212
 
208
 
/// Display the content of the field in browse mode
 
213
// Display the content of the field in browse mode
209
214
    function display_browse_field($recordid, $template) {
210
215
        if ($content = get_record('data_content','fieldid', $this->field->id, 'recordid', $recordid)) {
211
216
            if (isset($content->content)) {
225
230
        return false;
226
231
    }
227
232
 
228
 
/// Update the content of one data field in the data_content table
229
 
    function update_content($recordid, $value, $name=''){
 
233
// Update the content of one data field in the data_content table
 
234
    function update_content($recordid, $value, $name='') {
230
235
        $content = new object();
231
236
        $content->fieldid = $this->field->id;
232
237
        $content->recordid = $recordid;
240
245
        }
241
246
    }
242
247
 
243
 
/// Delete all content associated with the field
 
248
// Delete all content associated with the field
244
249
    function delete_content($recordid=0) {
245
250
 
246
251
        $this->delete_content_files($recordid);
252
257
        }
253
258
    }
254
259
 
255
 
/// Deletes any files associated with this field
 
260
// Deletes any files associated with this field
256
261
    function delete_content_files($recordid='') {
257
262
        global $CFG;
258
263
 
267
272
    }
268
273
 
269
274
 
270
 
/// Check if a field from an add form is empty
 
275
// Check if a field from an add form is empty
271
276
    function notemptyfield($value, $name) {
272
277
        return !empty($value);
273
278
    }
274
279
 
275
 
/// Just in case a field needs to print something before the whole form
 
280
// Just in case a field needs to print something before the whole form
276
281
    function print_before_form() {
277
282
    }
278
283
 
279
 
/// Just in case a field needs to print something after the whole form
 
284
// Just in case a field needs to print something after the whole form
280
285
    function print_after_form() {
281
286
    }
282
287
 
283
288
 
284
 
/// Returns the sortable field for the content. By default, it's just content
285
 
/// but for some plugins, it could be content 1 - content4
 
289
// Returns the sortable field for the content. By default, it's just content
 
290
// but for some plugins, it could be content 1 - content4
286
291
    function get_sort_field() {
287
292
        return 'content';
288
293
    }
289
294
 
290
 
/// Returns the SQL needed to refer to the column.  Some fields may need to CAST() etc.
 
295
// Returns the SQL needed to refer to the column.  Some fields may need to CAST() etc.
291
296
    function get_sort_sql($fieldname) {
292
297
        return $fieldname;
293
298
    }
294
299
 
295
 
/// Returns the name/type of the field
296
 
    function name(){
 
300
// Returns the name/type of the field
 
301
    function name() {
297
302
        return get_string('name'.$this->type, 'data');
298
303
    }
299
304
 
300
 
/// Prints the respective type icon
 
305
// Prints the respective type icon
301
306
    function image() {
302
307
        global $CFG;
303
308
 
307
312
        return $str;
308
313
    }
309
314
 
310
 
 
311
 
}  //end of major class data_field_base
312
 
 
313
 
 
314
 
 
315
 
/*****************************************************************************
316
 
/* Given a template and a dataid, generate a default case template               *
317
 
 * input @param template - addtemplate, singletemplate, listtempalte, rsstemplate*
318
 
 *       @param dataid                                                       *
319
 
 * output null                                                               *
320
 
 *****************************************************************************/
 
315
//  Per default, it is assumed that fields support text exporting. Override this (return false) on fields not supporting text exporting. 
 
316
    function text_export_supported() {
 
317
        return true;
 
318
    }
 
319
 
 
320
//  Per default, return the record's text value only from the "content" field. Override this in fields class if necesarry. 
 
321
    function export_text_value($record) {
 
322
        if ($this->text_export_supported()) {
 
323
            return $record->content;
 
324
        }
 
325
    }
 
326
 
 
327
}
 
328
 
 
329
 
 
330
/*
 
331
/* Given a template and a dataid, generate a default case template
 
332
 * input @param template - addtemplate, singletemplate, listtempalte, rsstemplate
 
333
 *       @param dataid
 
334
 * output null
 
335
 */
321
336
function data_generate_default_template(&$data, $template, $recordid=0, $form=false, $update=true) {
322
337
 
323
338
    if (!$data && !$template) {
327
342
        return '';
328
343
    }
329
344
 
330
 
    //get all the fields for that database
 
345
    // get all the fields for that database
331
346
    if ($fields = get_records('data_fields', 'dataid', $data->id, 'id')) {
332
347
 
333
348
        $str = '<div class="defaulttemplate">';
350
365
            $str .= '</td>';
351
366
 
352
367
            $str .='<td>';
353
 
            if ($form) {   /// Print forms instead of data
 
368
            if ($form) {   // Print forms instead of data
354
369
                $fieldobj = data_get_field($field, $data);
355
370
                $str .= $fieldobj->display_add_field($recordid);
356
371
 
357
 
            } else {           /// Just print the tag
 
372
            } else {           // Just print the tag
358
373
                $str .= '[['.$field->name.']]';
359
374
            }
360
375
            $str .= '</td></tr>';
364
379
            $str .= '<tr><td align="center" colspan="2">##edit##  ##more##  ##delete##  ##approve##</td></tr>';
365
380
        } else if ($template == 'singletemplate') {
366
381
            $str .= '<tr><td align="center" colspan="2">##edit##  ##delete##  ##approve##</td></tr>';
 
382
        } else if ($template == 'asearchtemplate') {
 
383
            $str .= '<tr><td valign="top" align="right">'.get_string('authorfirstname', 'data').': </td><td>##firstname##</td></tr>';
 
384
            $str .= '<tr><td valign="top" align="right">'.get_string('authorlastname', 'data').': </td><td>##lastname##</td></tr>';
367
385
        }
368
386
 
369
387
        $str .= '</table>';
455
473
 
456
474
 
457
475
/************************************************************************
458
 
 * given a field name *
 
476
 * given a field name                                                   *
459
477
 * this function creates an instance of the particular subfield class   *
460
478
 ************************************************************************/
461
479
function data_get_field_from_name($name, $data){
462
480
    $field = get_record('data_fields','name',$name);
463
 
 
464
481
    if ($field) {
465
482
        return data_get_field($field, $data);
466
483
    } else {
469
486
}
470
487
 
471
488
/************************************************************************
472
 
 * given a field id *
 
489
 * given a field id                                                     *
473
490
 * this function creates an instance of the particular subfield class   *
474
491
 ************************************************************************/
475
 
function data_get_field_from_id($fieldid, $data){
 
492
function data_get_field_from_id($fieldid, $data) {
476
493
    $field = get_record('data_fields','id',$fieldid);
477
 
 
478
494
    if ($field) {
479
495
        return data_get_field($field, $data);
480
496
    } else {
483
499
}
484
500
 
485
501
/************************************************************************
486
 
 * given a field id *
 
502
 * given a field id                                                     *
487
503
 * this function creates an instance of the particular subfield class   *
488
504
 ************************************************************************/
489
505
function data_get_field_new($type, $data) {
490
506
    global $CFG;
491
 
 
492
507
    require_once($CFG->dirroot.'/mod/data/field/'.$type.'/field.class.php');
493
508
    $newfield = 'data_field_'.$type;
494
509
    $newfield = new $newfield(0, $data);
502
517
 ************************************************************************/
503
518
function data_get_field($field, $data) {
504
519
    global $CFG;
505
 
 
506
520
    if ($field) {
507
521
        require_once('field/'.$field->type.'/field.class.php');
508
522
        $newfield = 'data_field_'.$field->type;
519
533
 ***************************************************************************/
520
534
function data_isowner($rid){
521
535
    global $USER;
522
 
 
523
536
    if (empty($USER->id)) {
524
537
        return false;
525
538
    }
536
549
 * input object $data                                                  *
537
550
 * output bool                                                         *
538
551
 ***********************************************************************/
539
 
function data_atmaxentries($data){
540
 
    if (!$data->maxentries){
 
552
function data_atmaxentries($data) {
 
553
    if (!$data->maxentries) {
541
554
        return false;
542
 
 
543
555
    } else {
544
556
        return (data_numentries($data) >= $data->maxentries);
545
557
    }
551
563
 * uses global $CFG, $USER                                            *
552
564
 * output int                                                         *
553
565
 **********************************************************************/
554
 
function data_numentries($data){
 
566
function data_numentries($data) {
555
567
    global $USER;
556
568
    global $CFG;
557
569
    $sql = 'SELECT COUNT(*) FROM '.$CFG->prefix.'data_records WHERE dataid='.$data->id.' AND userid='.$USER->id;
564
576
 * input @param int $dataid, $groupid                           *
565
577
 * output bool                                                  *
566
578
 ****************************************************************/
567
 
function data_add_record($data, $groupid=0){
 
579
function data_add_record($data, $groupid=0) {
568
580
    global $USER;
569
 
 
570
581
    $cm = get_coursemodule_from_instance('data', $data->id);
571
582
    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
572
 
 
573
583
    $record = new object();
574
584
    $record->userid = $USER->id;
575
585
    $record->dataid = $data->id;
592
602
 *       @param string $template                                   *
593
603
 * output bool                                                     *
594
604
 *******************************************************************/
595
 
function data_tags_check($dataid, $template){
596
 
    //first get all the possible tags
 
605
function data_tags_check($dataid, $template) {
 
606
    // first get all the possible tags
597
607
    $fields = get_records('data_fields','dataid',$dataid);
598
 
    ///then we generate strings to replace
599
 
    $tagsok = true; //let's be optimistic
600
 
    foreach ($fields as $field){
 
608
    // then we generate strings to replace
 
609
    $tagsok = true; // let's be optimistic
 
610
    foreach ($fields as $field) {
601
611
        $pattern="/\[\[".$field->name."\]\]/i";
602
 
        if (preg_match_all($pattern, $template, $dummy)>1){
 
612
        if (preg_match_all($pattern, $template, $dummy)>1) {
603
613
            $tagsok = false;
604
614
            notify ('[['.$field->name.']] - '.get_string('multipletags','data'));
605
615
        }
606
616
    }
607
 
    //else return true
 
617
    // else return true
608
618
    return $tagsok;
609
619
}
610
620
 
613
623
 ************************************************************************/
614
624
function data_add_instance($data) {
615
625
    global $CFG;
616
 
 
617
626
    if (empty($data->assessed)) {
618
627
        $data->assessed = 0;
619
628
    }
620
629
 
621
630
    $data->timemodified = time();
622
 
 
623
631
    if (! $data->id = insert_record('data', $data)) {
624
632
        return false;
625
633
    }
626
634
 
 
635
    $data = stripslashes_recursive($data);
 
636
    data_grade_item_update($data);
627
637
    return $data->id;
628
638
}
629
639
 
632
642
 ************************************************************************/
633
643
function data_update_instance($data) {
634
644
    global $CFG;
635
 
 
 
645
    $data->timemodified = time();
636
646
    $data->id = $data->instance;
637
647
 
638
648
    if (empty($data->assessed)) {
639
649
        $data->assessed = 0;
640
650
    }
641
 
 
642
 
    $data->timemodified = time();
643
 
 
644
 
    if (! $data->instance = update_record('data', $data)) {
 
651
    if (empty($data->notification)) {
 
652
        $data->notification = 0;
 
653
    }
 
654
    if (! update_record('data', $data)) {
645
655
        return false;
646
656
    }
647
 
    return $data->instance;
648
657
 
 
658
    $data = stripslashes_recursive($data);
 
659
    data_grade_item_update($data);
 
660
    return true;
649
661
}
650
662
 
651
663
/************************************************************************
652
664
 * deletes an instance of a data                                        *
653
665
 ************************************************************************/
654
 
function data_delete_instance($id) {    //takes the dataid
 
666
function data_delete_instance($id) {    // takes the dataid
655
667
 
656
668
    global $CFG;
657
 
 
658
669
    if (! $data = get_record('data', 'id', $id)) {
659
670
        return false;
660
671
    }
661
672
 
662
 
    /// Delete all the associated information
663
 
 
 
673
    // Delete all the associated information
664
674
    // get all the records in this data
665
675
    $sql = 'SELECT c.* FROM '.$CFG->prefix.'data_records r LEFT JOIN '.
666
676
           $CFG->prefix.'data_content c ON c.recordid = r.id WHERE r.dataid = '.$id;
667
677
 
668
 
    if ($contents = get_records_sql($sql)){
669
 
 
670
 
        foreach($contents as $content){
671
 
 
 
678
    if ($contents = get_records_sql($sql)) {
 
679
        foreach($contents as $content) {
672
680
            $field = get_record('data_fields','id',$content->fieldid);
673
 
            if ($g = data_get_field($field, $data)){
 
681
            if ($g = data_get_field($field, $data)) {
674
682
                $g->delete_content_files($id, $content->recordid, $content->content);
675
683
            }
676
684
            //delete the content itself
683
691
    delete_records('data_fields','dataid',$id);
684
692
 
685
693
    // Delete the instance itself
686
 
 
687
 
    if (! delete_records('data', 'id', $id)) {
688
 
        return false;
689
 
    }
690
 
    return true;
 
694
    $result = delete_records('data', 'id', $id);
 
695
    data_grade_item_delete($data);
 
696
    return $result;
691
697
}
692
698
 
693
699
/************************************************************************
694
700
 * returns a summary of data activity of this user                      *
695
701
 ************************************************************************/
696
702
function data_user_outline($course, $user, $mod, $data) {
697
 
 
698
703
    global $CFG;
699
 
 
700
704
    if ($countrecords = count_records('data_records', 'dataid', $data->id, 'userid', $user->id)) {
701
705
        $result = new object();
702
706
        $result->info = get_string('numrecords', 'data', $countrecords);
707
711
        return $result;
708
712
    }
709
713
    return NULL;
710
 
 
711
714
}
712
715
 
713
716
/************************************************************************
714
717
 * Prints all the records uploaded by this user                         *
715
718
 ************************************************************************/
716
719
function data_user_complete($course, $user, $mod, $data) {
717
 
 
718
720
    if ($records = get_records_select('data_records', 'dataid = '.$data->id.' AND userid = '.$user->id,
719
721
                                                      'timemodified DESC')) {
720
 
 
721
722
        data_print_template('singletemplate', $records, $data);
722
 
 
723
 
    }
 
723
    }
 
724
}
 
725
 
 
726
/**
 
727
 * Return grade for given user or all users.
 
728
 *
 
729
 * @param int $dataid id of data
 
730
 * @param int $userid optional user id, 0 means all users
 
731
 * @return array array of grades, false if none
 
732
 */
 
733
function data_get_user_grades($data, $userid=0) {
 
734
    global $CFG;
 
735
    $user = $userid ? "AND u.id = $userid" : "";
 
736
    $sql = "SELECT u.id, u.id AS userid, avg(drt.rating) AS rawgrade
 
737
              FROM {$CFG->prefix}user u, {$CFG->prefix}data_records dr,
 
738
                   {$CFG->prefix}data_ratings drt
 
739
             WHERE u.id = dr.userid AND dr.id = drt.recordid
 
740
                   AND drt.userid != u.id AND dr.dataid = $data->id
 
741
                   $user
 
742
          GROUP BY u.id";
 
743
    return get_records_sql($sql);
 
744
}
 
745
 
 
746
/**
 
747
 * Update grades by firing grade_updated event
 
748
 *
 
749
 * @param object $data null means all databases
 
750
 * @param int $userid specific user only, 0 mean all
 
751
 */
 
752
function data_update_grades($data=null, $userid=0, $nullifnone=true) {
 
753
    global $CFG;
 
754
    if (!function_exists('grade_update')) { //workaround for buggy PHP versions
 
755
        require_once($CFG->libdir.'/gradelib.php');
 
756
    }
 
757
 
 
758
    if ($data != null) {
 
759
        if ($grades = data_get_user_grades($data, $userid)) {
 
760
            data_grade_item_update($data, $grades);
 
761
        } else if ($userid and $nullifnone) {
 
762
            $grade = new object();
 
763
            $grade->userid   = $userid;
 
764
            $grade->rawgrade = NULL;
 
765
            data_grade_item_update($data, $grade);
 
766
        } else {
 
767
            data_grade_item_update($data);
 
768
        }
 
769
    } else {
 
770
        $sql = "SELECT d.*, cm.idnumber as cmidnumber
 
771
                  FROM {$CFG->prefix}data d, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m
 
772
                 WHERE m.name='data' AND m.id=cm.module AND cm.instance=d.id";
 
773
        if ($rs = get_recordset_sql($sql)) {
 
774
            while ($data = rs_fetch_next_record($rs)) {
 
775
                if ($data->assessed) {
 
776
                    data_update_grades($data, 0, false);
 
777
                } else {
 
778
                    data_grade_item_update($data);
 
779
                }
 
780
            }
 
781
            rs_close($rs);
 
782
        }
 
783
    }
 
784
}
 
785
 
 
786
/**
 
787
 * Update/create grade item for given data
 
788
 *
 
789
 * @param object $data object with extra cmidnumber
 
790
 * @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
 
791
 * @return object grade_item
 
792
 */
 
793
function data_grade_item_update($data, $grades=NULL) {
 
794
    global $CFG;
 
795
    if (!function_exists('grade_update')) { //workaround for buggy PHP versions
 
796
        require_once($CFG->libdir.'/gradelib.php');
 
797
    }
 
798
    $params = array('itemname'=>$data->name, 'idnumber'=>$data->cmidnumber);
 
799
    if (!$data->assessed or $data->scale == 0) {
 
800
        $params['gradetype'] = GRADE_TYPE_NONE;
 
801
    } else if ($data->scale > 0) {
 
802
        $params['gradetype'] = GRADE_TYPE_VALUE;
 
803
        $params['grademax']  = $data->scale;
 
804
        $params['grademin']  = 0;
 
805
    } else if ($data->scale < 0) {
 
806
        $params['gradetype'] = GRADE_TYPE_SCALE;
 
807
        $params['scaleid']   = -$data->scale;
 
808
    }
 
809
    if ($grades  === 'reset') {
 
810
        $params['reset'] = true;
 
811
        $grades = NULL;
 
812
    }
 
813
 
 
814
    return grade_update('mod/data', $data->course, 'mod', 'data', $data->id, 0, $grades, $params);
 
815
}
 
816
 
 
817
/**
 
818
 * Delete grade item for given data
 
819
 *
 
820
 * @param object $data object
 
821
 * @return object grade_item
 
822
 */
 
823
function data_grade_item_delete($data) {
 
824
    global $CFG;
 
825
    require_once($CFG->libdir.'/gradelib.php');
 
826
    return grade_update('mod/data', $data->course, 'mod', 'data', $data->id, 0, NULL, array('deleted'=>1));
724
827
}
725
828
 
726
829
/************************************************************************
727
830
 * returns a list of participants of this database                      *
728
831
 ************************************************************************/
729
832
function data_get_participants($dataid) {
730
 
//Returns the users with data in one data
731
 
//(users with records in data_records, data_comments and data_ratings)
 
833
// Returns the users with data in one data
 
834
// (users with records in data_records, data_comments and data_ratings)
732
835
    global $CFG;
733
 
 
734
836
    $records = get_records_sql("SELECT DISTINCT u.id, u.id
735
837
                                FROM {$CFG->prefix}user u,
736
838
                                     {$CFG->prefix}data_records r
737
839
                                WHERE r.dataid = '$dataid'
738
840
                                  AND u.id = r.userid");
739
 
 
740
841
    $comments = get_records_sql("SELECT DISTINCT u.id, u.id
741
842
                                 FROM {$CFG->prefix}user u,
742
843
                                      {$CFG->prefix}data_records r,
744
845
                                 WHERE r.dataid = '$dataid'
745
846
                                   AND u.id = r.userid
746
847
                                   AND r.id = c.recordid");
747
 
 
748
848
    $ratings = get_records_sql("SELECT DISTINCT u.id, u.id
749
849
                                FROM {$CFG->prefix}user u,
750
850
                                     {$CFG->prefix}data_records r,
753
853
                                  AND u.id = r.userid
754
854
                                  AND r.id = a.recordid");
755
855
    $participants = array();
756
 
 
757
 
    if ($records){
 
856
    if ($records) {
758
857
        foreach ($records as $record) {
759
858
            $participants[$record->id] = $record;
760
859
        }
761
860
    }
762
 
    if ($comments){
 
861
    if ($comments) {
763
862
        foreach ($comments as $comment) {
764
863
            $participants[$comment->id] = $comment;
765
864
        }
766
865
    }
767
 
    if ($ratings){
 
866
    if ($ratings) {
768
867
        foreach ($ratings as $rating) {
769
868
            $participants[$rating->id] = $rating;
770
869
        }
771
870
    }
772
 
 
773
871
    return $participants;
774
872
}
775
873
 
776
 
function data_get_coursemodule_info($coursemodule) {
777
 
/// Given a course_module object, this function returns any
778
 
/// "extra" information that may be needed when printing
779
 
/// this activity in a course listing.
780
 
///
781
 
/// See get_array_of_activities() in course/lib.php
782
 
///
783
 
 
784
 
   global $CFG;
785
 
 
786
 
   $info = NULL;
787
 
 
788
 
   return $info;
789
 
}
790
 
 
791
 
///junk functions
 
874
// junk functions
792
875
/************************************************************************
793
876
 * takes a list of records, the current data, a search string,          *
794
877
 * and mode to display prints the translated template                   *
798
881
 *       @param string $template                                        *
799
882
 * output null                                                          *
800
883
 ************************************************************************/
801
 
function data_print_template($template, $records, $data, $search='',$page=0, $return=false) {
 
884
function data_print_template($template, $records, $data, $search='', $page=0, $return=false) {
802
885
    global $CFG;
803
 
 
804
886
    $cm = get_coursemodule_from_instance('data', $data->id);
805
887
    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
806
 
 
807
888
    static $fields = NULL;
808
889
    static $isteacher;
809
890
    static $dataid = NULL;
810
 
 
811
891
    if (empty($dataid)) {
812
892
        $dataid = $data->id;
813
893
    } else if ($dataid != $data->id) {
814
894
        $fields = NULL;
815
895
    }
816
 
 
817
896
    if (empty($fields)) {
818
897
        $fieldrecords = get_records('data_fields','dataid', $data->id);
819
898
        foreach ($fieldrecords as $fieldrecord) {
821
900
        }
822
901
        $isteacher = has_capability('mod/data:managetemplates', $context);
823
902
    }
824
 
 
825
903
    if (empty($records)) {
826
904
        return;
827
905
    }
828
 
 
829
 
    foreach ($records as $record) {   /// Might be just one for the single template
830
 
 
831
 
    /// Replacing tags
 
906
    foreach ($records as $record) {   // Might be just one for the single template
 
907
    // Replacing tags
832
908
        $patterns = array();
833
909
        $replacement = array();
834
 
 
835
 
    /// Then we generate strings to replace for normal tags
 
910
    // Then we generate strings to replace for normal tags
836
911
        foreach ($fields as $field) {
837
912
            $patterns[]='[['.$field->field->name.']]';
838
913
            $replacement[] = highlight($search, $field->display_browse_field($record->id, $template));
839
914
        }
840
 
 
841
 
    /// Replacing special tags (##Edit##, ##Delete##, ##More##)
 
915
    // Replacing special tags (##Edit##, ##Delete##, ##More##)
842
916
        $patterns[]='##edit##';
843
917
        $patterns[]='##delete##';
844
918
        if (has_capability('mod/data:manageentries', $context) or data_isowner($record->id)) {
850
924
            $replacement[] = '';
851
925
            $replacement[] = '';
852
926
        }
 
927
 
 
928
        $moreurl = $CFG->wwwroot . '/mod/data/view.php?d=' . $data->id . '&amp;rid=' . $record->id;
 
929
        if ($search) {
 
930
            $moreurl .= '&amp;filter=1';
 
931
        }
853
932
        $patterns[]='##more##';
854
 
        $replacement[] = '<a href="'.$CFG->wwwroot.'/mod/data/view.php?d='.$data->id.'&amp;rid='.$record->id.'"><img src="'.$CFG->pixpath.'/i/search.gif" class="iconsmall" alt="'.get_string('more', 'data').'" title="'.get_string('more', 'data').'" /></a>';
 
933
        $replacement[] = '<a href="' . $moreurl . '"><img src="' . $CFG->pixpath . '/i/search.gif" class="iconsmall" alt="' . get_string('more', 'data') . '" title="' . get_string('more', 'data') . '" /></a>';
855
934
 
856
935
        $patterns[]='##moreurl##';
857
 
        $replacement[] = $CFG->wwwroot.'/mod/data/view.php?d='.$data->id.'&amp;rid='.$record->id;
 
936
        $replacement[] = $moreurl;
858
937
 
859
938
        $patterns[]='##user##';
860
939
        $replacement[] = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$record->userid.
861
940
                               '&amp;course='.$data->course.'">'.fullname($record).'</a>';
 
941
        
 
942
        $patterns[] = '##timeadded##';
 
943
        $replacement[] = userdate($record->timecreated); 
 
944
 
 
945
        $patterns[] = '##timemodified##';
 
946
        $replacement [] = userdate($record->timemodified);
862
947
 
863
948
        $patterns[]='##approve##';
864
 
        if (has_capability('mod/data:approve', $context) && ($data->approval) && (!$record->approved)){
865
 
            $replacement[] = '<a href="'.$CFG->wwwroot.'/mod/data/view.php?d='.$data->id.'&amp;approve='.$record->id.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/i/approve.gif" class="iconsmall" alt="'.get_string('approve').'" /></a>';
 
949
        if (has_capability('mod/data:approve', $context) && ($data->approval) && (!$record->approved)) {
 
950
            $replacement[] = '<span class="approve"><a href="'.$CFG->wwwroot.'/mod/data/view.php?d='.$data->id.'&amp;approve='.$record->id.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/i/approve.gif" class="icon" alt="'.get_string('approve').'" /></a></span>';
866
951
        } else {
867
952
            $replacement[] = '';
868
953
        }
875
960
            $replacement[] = '';
876
961
        }
877
962
 
878
 
        ///actual replacement of the tags
 
963
        // actual replacement of the tags
879
964
        $newtext = str_ireplace($patterns, $replacement, $data->{$template});
880
965
 
881
 
        /// no more html formatting and filtering - see MDL-6635
 
966
        // no more html formatting and filtering - see MDL-6635
882
967
        if ($return) {
883
968
            return $newtext;
884
969
        } else {
885
970
            echo $newtext;
886
 
 
887
971
            // hack alert - return is always false in singletemplate anyway ;-)
888
972
            /**********************************
889
973
             *    Printing Ratings Form       *
891
975
            if ($template == 'singletemplate') {    //prints ratings options
892
976
                data_print_ratings($data, $record);
893
977
            }
894
 
 
895
978
            /**********************************
896
979
             *    Printing Ratings Form       *
897
980
             *********************************/
898
981
            if (($template == 'singletemplate') && ($data->comments)) {    //prints ratings options
899
 
 
900
982
                data_print_comments($data, $record, $page);
901
983
            }
902
984
        }
904
986
}
905
987
 
906
988
 
907
 
function data_print_show_all_form($data, $perpage, $sort, $order, $mode) {
908
 
    echo '<div align="center">';
909
 
    echo '<form id="options" action="view.php" method="get">';
910
 
    echo '<div>';
911
 
    echo '<input type="hidden" name="d" value="'.$data->id.'" />';
912
 
    echo '<input type="hidden" name="perpage" value="'.$perpage.'" />';
913
 
    echo '<input type="hidden" name="search" value="" />'; // clear search
914
 
    echo '<input type="hidden" name="sort" value="'.$sort.'" />';
915
 
    echo '<input type="hidden" name="order" value="'.$order.'" />';    
916
 
    echo '<input type="hidden" name="mode" value="'.$mode.'" />';   
917
 
    echo '<input type="submit" value="'.get_string('showall','data').'" />';
918
 
 
919
 
    echo '</div>';
920
 
    echo '</form>';
921
 
    echo '</div>';      
922
 
}
923
 
 
924
 
 
925
989
/************************************************************************
926
990
 * function that takes in the current data, number of items per page,   *
927
991
 * a search string and prints a preference box in view.php              *
 
992
 *                                                                      *
 
993
 * This preference box prints a searchable advanced search template if  *
 
994
 *     a) A template is defined                                         *
 
995
 *  b) The advanced search checkbox is checked.                         *
 
996
 *                                                                      *
928
997
 * input @param object $data                                            *
929
998
 *       @param int $perpage                                            *
930
999
 *       @param string $search                                          *
931
1000
 * output null                                                          *
932
1001
 ************************************************************************/
933
 
function data_print_preference_form($data, $perpage, $search, $sort='', $order='ASC', $mode='single'){
934
 
    echo '<br /><div class="datapreferences" style="text-align:center">';
 
1002
function data_print_preference_form($data, $perpage, $search, $sort='', $order='ASC', $search_array = '', $advanced = 0, $mode= '') {
 
1003
    global $CFG;
 
1004
    $cm = get_coursemodule_from_instance('data', $data->id);
 
1005
    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
 
1006
    echo '<br /><div class="datapreferences">';
935
1007
    echo '<form id="options" action="view.php" method="get">';
936
 
    echo '<fieldset class="invisiblefieldset">';
 
1008
    echo '<div>';
937
1009
    echo '<input type="hidden" name="d" value="'.$data->id.'" />';
 
1010
    if ($mode =='asearch') {
 
1011
        $advanced = 1;
 
1012
        echo '<input type="hidden" name="mode" value="list" />';
 
1013
    }
938
1014
    echo '<label for="pref_perpage">'.get_string('pagesize','data').'</label> ';
939
1015
    $pagesizes = array(2=>2,3=>3,4=>4,5=>5,6=>6,7=>7,8=>8,9=>9,10=>10,15=>15,
940
1016
                       20=>20,30=>30,40=>40,50=>50,100=>100,200=>200,300=>300,400=>400,500=>500,1000=>1000);
941
1017
    choose_from_menu($pagesizes, 'perpage', $perpage, '', '', '0', false, false, 0, 'pref_perpage');
942
 
    echo '&nbsp;&nbsp;&nbsp;<label for="pref_search">'.get_string('search').'</label> <input type="text" size="16" name="search" id= "pref_search" value="'.s($search).'" />';
 
1018
     echo '<div id="reg_search" style="display: ';
 
1019
    if ($advanced) {
 
1020
        echo 'none';
 
1021
    }
 
1022
    else {
 
1023
        echo 'inline';
 
1024
    }
 
1025
    echo ';" >&nbsp;&nbsp;&nbsp;<label for="pref_search">'.get_string('search').'</label> <input type="text" size="16" name="search" id= "pref_search" value="'.s($search).'" /></div>';
943
1026
    echo '&nbsp;&nbsp;&nbsp;<label for="pref_sortby">'.get_string('sortby').'</label> ';
944
 
    //foreach field, print the option
945
 
    $fields = get_records('data_fields','dataid',$data->id, 'name');
946
 
    echo '<select name="sort" id="pref_sortby"><option value="0">'.get_string('dateentered','data').'</option>';
947
 
    foreach ($fields as $field) {
948
 
        if ($field->id == $sort) {
949
 
            echo '<option value="'.$field->id.'" selected="selected">'.$field->name.'</option>';
 
1027
    // foreach field, print the option
 
1028
    echo '<select name="sort" id="pref_sortby">';
 
1029
    if ($fields = get_records('data_fields','dataid',$data->id, 'name')) {
 
1030
        echo '<optgroup label="'.get_string('fields', 'data').'">';
 
1031
        foreach ($fields as $field) {
 
1032
            if ($field->id == $sort) {
 
1033
                echo '<option value="'.$field->id.'" selected="selected">'.$field->name.'</option>';
 
1034
            } else {
 
1035
                echo '<option value="'.$field->id.'">'.$field->name.'</option>';
 
1036
            }
 
1037
        }
 
1038
        echo '</optgroup>';
 
1039
    }
 
1040
    $options = array();
 
1041
    $options[DATA_TIMEADDED]    = get_string('timeadded', 'data');
 
1042
    $options[DATA_TIMEMODIFIED] = get_string('timemodified', 'data');
 
1043
    $options[DATA_FIRSTNAME]    = get_string('authorfirstname', 'data');
 
1044
    $options[DATA_LASTNAME]     = get_string('authorlastname', 'data');
 
1045
    if ($data->approval and has_capability('mod/data:approve', $context)) {
 
1046
        $options[DATA_APPROVED] = get_string('approved', 'data');
 
1047
    }
 
1048
    echo '<optgroup label="'.get_string('other', 'data').'">';
 
1049
    foreach ($options as $key => $name) {
 
1050
        if ($key == $sort) {
 
1051
            echo '<option value="'.$key.'" selected="selected">'.$name.'</option>';
950
1052
        } else {
951
 
            echo '<option value="'.$field->id.'">'.$field->name.'</option>';
 
1053
            echo '<option value="'.$key.'">'.$name.'</option>';
952
1054
        }
953
1055
    }
 
1056
    echo '</optgroup>';
954
1057
    echo '</select>';
955
1058
    echo '<label for="pref_order" class="accesshide">'.get_string('order').'</label>';
956
1059
    echo '<select id="pref_order" name="order">';
965
1068
        echo '<option value="DESC">'.get_string('descending','data').'</option>';
966
1069
    }
967
1070
    echo '</select>';
968
 
    //print ASC or DESC
969
 
    echo '&nbsp;&nbsp;&nbsp;';
970
 
    echo '<input type="hidden" name="mode" value="'.$mode.'" />';  
971
 
    echo '<input type="submit" value="'.get_string('savesettings','data').'" />';
972
 
    echo '</fieldset>';
 
1071
 
 
1072
    if ($advanced) {
 
1073
        $checked = ' checked="checked" ';
 
1074
    }
 
1075
    else {
 
1076
        $checked = '';
 
1077
    }
 
1078
    print '
 
1079
        <script type="text/javascript">
 
1080
        //<![CDATA[
 
1081
        <!-- Start
 
1082
        // javascript for hiding/displaying advanced search form
 
1083
 
 
1084
        function showHideAdvSearch(checked) {
 
1085
            var divs = document.getElementsByTagName(\'div\');
 
1086
            for(i=0;i<divs.length;i++) {
 
1087
                if(divs[i].id.match(\'data_adv_form\')) {
 
1088
                    if(checked) {
 
1089
                        divs[i].style.display = \'inline\';
 
1090
                    }
 
1091
                    else {
 
1092
                        divs[i].style.display = \'none\';
 
1093
                    }
 
1094
                }
 
1095
                else if (divs[i].id.match(\'reg_search\')) {
 
1096
                    if (!checked) {
 
1097
                        divs[i].style.display = \'inline\';
 
1098
                    }
 
1099
                    else {
 
1100
                        divs[i].style.display = \'none\';
 
1101
                    }
 
1102
                }
 
1103
            }
 
1104
        }
 
1105
        //  End -->
 
1106
        //]]>
 
1107
        </script>';
 
1108
    echo '&nbsp;<input type="hidden" name="advanced" value="0" />';
 
1109
    echo '&nbsp;<input type="hidden" name="filter" value="1" />';
 
1110
    echo '&nbsp;<input type="checkbox" id="advancedcheckbox" name="advanced" value="1" '.$checked.' onchange="showHideAdvSearch(this.checked);" /><label for="advancedcheckbox">'.get_string('advancedsearch', 'data').'</label>';
 
1111
    echo '&nbsp;<input type="submit" value="'.get_string('savesettings','data').'" />';
 
1112
    echo '<br />';
 
1113
    echo '<div class="dataadvancedsearch" id="data_adv_form" style="display: ';
 
1114
    if ($advanced) {
 
1115
        echo 'inline';
 
1116
    }
 
1117
    else {
 
1118
        echo 'none';
 
1119
    }
 
1120
    echo ';margin-left:auto;margin-right:auto;" >';
 
1121
    echo '<table class="boxaligncenter">';
 
1122
    // print ASC or DESC
 
1123
    echo '<tr><td colspan="2">&nbsp;</td></tr>';
 
1124
    $i = 0;
 
1125
 
 
1126
    // Determine if we are printing all fields for advanced search, or the template for advanced search
 
1127
    // If a template is not defined, use the deafault template and display all fields.
 
1128
    if(empty($data->asearchtemplate)) {
 
1129
        data_generate_default_template($data, 'asearchtemplate');
 
1130
    }
 
1131
 
 
1132
    static $fields = NULL;
 
1133
    static $isteacher;
 
1134
    static $dataid = NULL;
 
1135
    if (empty($dataid)) {
 
1136
        $dataid = $data->id;
 
1137
    } else if ($dataid != $data->id) {
 
1138
        $fields = NULL;
 
1139
    }
 
1140
 
 
1141
    if (empty($fields)) {
 
1142
        $fieldrecords = get_records('data_fields','dataid', $data->id);
 
1143
        foreach ($fieldrecords as $fieldrecord) {
 
1144
            $fields[]= data_get_field($fieldrecord, $data);
 
1145
        }
 
1146
        $isteacher = has_capability('mod/data:managetemplates', $context);
 
1147
    }
 
1148
 
 
1149
    // Replacing tags
 
1150
    $patterns = array();
 
1151
    $replacement = array();
 
1152
 
 
1153
    // Then we generate strings to replace for normal tags
 
1154
    foreach ($fields as $field) {
 
1155
        $fieldname = $field->field->name;
 
1156
        $fieldname = preg_quote($fieldname, '/');
 
1157
        $patterns[] = "/\[\[$fieldname\]\]/i";
 
1158
        $searchfield = data_get_field_from_id($field->field->id, $data);
 
1159
        if (!empty($search_array[$field->field->id]->data)) {
 
1160
            $replacement[] = $searchfield->display_search_field($search_array[$field->field->id]->data);
 
1161
        } else {
 
1162
            $replacement[] = $searchfield->display_search_field();
 
1163
        }
 
1164
    }
 
1165
    $fn = !empty($search_array[DATA_FIRSTNAME]->data) ? $search_array[DATA_FIRSTNAME]->data : '';
 
1166
    $ln = !empty($search_array[DATA_LASTNAME]->data) ? $search_array[DATA_LASTNAME]->data : '';
 
1167
    $patterns[]    = '/##firstname##/';
 
1168
    $replacement[] = '<input type="text" size="16" name="u_fn" value="'.$fn.'" />';
 
1169
    $patterns[]    = '/##lastname##/';
 
1170
    $replacement[] = '<input type="text" size="16" name="u_ln" value="'.$ln.'" />';
 
1171
 
 
1172
    // actual replacement of the tags
 
1173
    $newtext = preg_replace($patterns, $replacement, $data->asearchtemplate);
 
1174
    $options = new object();
 
1175
    $options->para=false;
 
1176
    $options->noclean=true;
 
1177
    echo '<tr><td>';
 
1178
    echo format_text($newtext, FORMAT_HTML, $options);
 
1179
    echo '</td></tr>';
 
1180
    echo '<tr><td colspan="4" style="text-align: center;"><br/><input type="submit" value="'.get_string('savesettings','data').'" /><input type="submit" name="resetadv" value="'.get_string('resetsettings','data').'" /></td></tr>';
 
1181
    echo '</table>';
 
1182
    echo '</div>';
 
1183
    echo '</div>';
973
1184
    echo '</form>';
974
1185
    echo '</div>';
975
1186
}
979
1190
 
980
1191
    $cm = get_coursemodule_from_instance('data', $data->id);
981
1192
    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
982
 
 
983
 
    if ($data->assessed and !empty($USER->id)
984
 
      and (has_capability('mod/data:rate', $context) or has_capability('mod/data:viewrating', $context) or data_isowner($record->id))) {
 
1193
    if ($data->assessed and !empty($USER->id) and (has_capability('mod/data:rate', $context) or has_capability('mod/data:viewrating', $context) or data_isowner($record->id))) {
985
1194
        if ($ratingsscale = make_grades_menu($data->scale)) {
986
1195
            $ratingsmenuused = false;
987
 
 
988
1196
            echo '<div class="ratings" style="text-align:center">';
989
1197
            echo '<form id="form" method="post" action="rate.php">';
990
 
 
 
1198
            echo '<input type="hidden" name="dataid" value="'.$data->id.'" />';
991
1199
            if (has_capability('mod/data:rate', $context) and !data_isowner($record->id)) {
992
1200
                data_print_ratings_mean($record->id, $ratingsscale, has_capability('mod/data:viewrating', $context));
993
1201
                echo '&nbsp;';
994
1202
                data_print_rating_menu($record->id, $USER->id, $ratingsscale);
995
1203
                $ratingsmenuused = true;
996
 
 
997
1204
            } else {
998
1205
                data_print_ratings_mean($record->id, $ratingsscale, true);
999
1206
            }
1000
 
 
1001
1207
            if ($data->scale < 0) {
1002
1208
                if ($scale = get_record('scale', 'id', abs($data->scale))) {
1003
1209
                    print_scale_menu_helpbutton($data->course, $scale );
1015
1221
}
1016
1222
 
1017
1223
function data_print_ratings_mean($recordid, $scale, $link=true) {
1018
 
/// Print the multiple ratings on a post given to the current user by others.
1019
 
/// Scale is an array of ratings
 
1224
// Print the multiple ratings on a post given to the current user by others.
 
1225
// Scale is an array of ratings
1020
1226
 
1021
1227
    static $strrate;
1022
 
 
1023
1228
    $mean = data_get_ratings_mean($recordid, $scale);
1024
 
 
1025
1229
    if ($mean !== "") {
1026
 
 
1027
1230
        if (empty($strratings)) {
1028
1231
            $strratings = get_string("ratings", "data");
1029
1232
        }
1030
 
 
1031
1233
        echo "$strratings: ";
1032
1234
        if ($link) {
1033
1235
            link_to_popup_window ("/mod/data/report.php?id=$recordid", "ratings", $mean, 400, 600);
1039
1241
 
1040
1242
 
1041
1243
function data_get_ratings_mean($recordid, $scale, $ratings=NULL) {
1042
 
/// Return the mean rating of a post given to the current user by others.
1043
 
/// Scale is an array of possible ratings in the scale
1044
 
/// Ratings is an optional simple array of actual ratings (just integers)
1045
 
 
 
1244
// Return the mean rating of a post given to the current user by others.
 
1245
// Scale is an array of possible ratings in the scale
 
1246
// Ratings is an optional simple array of actual ratings (just integers)
1046
1247
    if (!$ratings) {
1047
1248
        $ratings = array();
1048
1249
        if ($rates = get_records("data_ratings", "recordid", $recordid)) {
1051
1252
            }
1052
1253
        }
1053
1254
    }
1054
 
 
1055
1255
    $count = count($ratings);
1056
 
 
1057
1256
    if ($count == 0) {
1058
1257
        return "";
1059
 
 
1060
1258
    } else if ($count == 1) {
1061
1259
        return $scale[$ratings[0]];
1062
 
 
1063
1260
    } else {
1064
1261
        $total = 0;
1065
1262
        foreach ($ratings as $rating) {
1066
1263
            $total += $rating;
1067
1264
        }
1068
1265
        $mean = round( ((float)$total/(float)$count) + 0.001);  // Little fudge factor so that 0.5 goes UP
1069
 
 
1070
1266
        if (isset($scale[$mean])) {
1071
1267
            return $scale[$mean]." ($count)";
1072
1268
        } else {
1077
1273
 
1078
1274
 
1079
1275
function data_print_rating_menu($recordid, $userid, $scale) {
1080
 
/// Print the menu of ratings as part of a larger form.
1081
 
/// If the post has already been - set that value.
1082
 
/// Scale is an array of ratings
1083
 
 
 
1276
// Print the menu of ratings as part of a larger form.
 
1277
// If the post has already been - set that value.
 
1278
// Scale is an array of ratings
1084
1279
    static $strrate;
1085
 
 
1086
1280
    if (!$rating = get_record("data_ratings", "userid", $userid, "recordid", $recordid)) {
1087
 
        $rating->rating = 0;
 
1281
        $rating->rating = -999;
1088
1282
    }
1089
 
 
1090
1283
    if (empty($strrate)) {
1091
1284
        $strrate = get_string("rate", "data");
1092
1285
    }
1093
 
 
1094
 
    choose_from_menu($scale, $recordid, $rating->rating, "$strrate...");
 
1286
    choose_from_menu($scale, $recordid, $rating->rating, "$strrate...", '', -999);
1095
1287
}
1096
1288
 
1097
1289
 
1098
1290
function data_get_ratings($recordid, $sort="u.firstname ASC") {
1099
 
/// Returns a list of ratings for a particular post - sorted.
 
1291
// Returns a list of ratings for a particular post - sorted.
1100
1292
    global $CFG;
1101
1293
    return get_records_sql("SELECT u.*, r.rating
1102
1294
                              FROM {$CFG->prefix}data_ratings r,
1104
1296
                             WHERE r.recordid = $recordid
1105
1297
                               AND r.userid = u.id
1106
1298
                             ORDER BY $sort");
1107
 
 
1108
1299
}
1109
1300
 
1110
1301
 
1111
 
//prints all comments + a text box for adding additional comment
 
1302
// prints all comments + a text box for adding additional comment
1112
1303
function data_print_comments($data, $record, $page=0, $mform=false) {
1113
 
 
1114
1304
    global $CFG;
1115
 
 
1116
1305
    echo '<a name="comments"></a>';
1117
 
 
1118
1306
    if ($comments = get_records('data_comments','recordid',$record->id)) {
1119
1307
        foreach ($comments as $comment) {
1120
1308
            data_print_comment($data, $comment, $page);
1121
1309
        }
1122
1310
        echo '<br />';
1123
1311
    }
1124
 
 
1125
1312
    if (!isloggedin() or isguest()) {
1126
1313
        return;
1127
1314
    }
1128
 
 
1129
1315
    $editor = optional_param('addcomment', 0, PARAM_BOOL);
1130
 
 
1131
1316
    if (!$mform and !$editor) {
1132
1317
        echo '<div class="newcomment" style="text-align:center">';
1133
1318
        echo '<a href="view.php?d='.$data->id.'&amp;page='.$page.'&amp;mode=single&amp;addcomment=1">'.get_string('addcomment', 'data').'</a>';
1144
1329
    }
1145
1330
}
1146
1331
 
1147
 
//prints a single comment entry
 
1332
// prints a single comment entry
1148
1333
function data_print_comment($data, $comment, $page=0) {
1149
 
 
1150
1334
    global $USER, $CFG;
1151
 
 
1152
1335
    $cm = get_coursemodule_from_instance('data', $data->id);
1153
1336
    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
1154
 
 
1155
1337
    $stredit = get_string('edit');
1156
1338
    $strdelete = get_string('delete');
1157
 
 
1158
1339
    $user = get_record('user','id',$comment->userid);
1159
 
 
1160
1340
    echo '<table cellspacing="0" align="center" width="50%" class="datacomment forumpost">';
1161
 
 
1162
1341
    echo '<tr class="header"><td class="picture left">';
1163
 
    print_user_picture($comment->userid, $data->course, $user->picture);
 
1342
    print_user_picture($user, $data->course, $user->picture);
1164
1343
    echo '</td>';
1165
 
 
1166
1344
    echo '<td class="topic starter" align="left"><div class="author">';
1167
1345
    $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $context));
1168
1346
    $by = new object();
1171
1349
    $by->date = userdate($comment->modified);
1172
1350
    print_string('bynameondate', 'data', $by);
1173
1351
    echo '</div></td></tr>';
1174
 
 
1175
1352
    echo '<tr><td class="left side">';
1176
 
    if ($groups = user_group($data->course, $comment->userid)) {
 
1353
    if ($groups = groups_get_all_groups($data->course, $comment->userid, $cm->groupingid)) {
1177
1354
        print_group_picture($groups, $data->course, false, false, true);
1178
1355
    } else {
1179
1356
        echo '&nbsp;';
1180
1357
    }
1181
1358
 
1182
 
/// Actual content
1183
 
 
 
1359
// Actual content
1184
1360
    echo '</td><td class="content" align="left">'."\n";
1185
 
 
1186
1361
    // Print whole message
1187
1362
    echo format_text($comment->content, $comment->format);
1188
1363
 
1189
 
/// Commands
1190
 
 
 
1364
// Commands
1191
1365
    echo '<div class="commands">';
1192
1366
    if (data_isowner($comment->recordid) or has_capability('mod/data:managecomments', $context)) {
1193
1367
            echo '<a href="'.$CFG->wwwroot.'/mod/data/comment.php?rid='.$comment->recordid.'&amp;mode=edit&amp;commentid='.$comment->id.'&amp;page='.$page.'">'.$stredit.'</a>';
1195
1369
    }
1196
1370
 
1197
1371
    echo '</div>';
1198
 
 
1199
1372
    echo '</td></tr></table>'."\n\n";
1200
1373
}
1201
1374
 
1211
1384
 
1212
1385
function data_fieldname_exists($name, $dataid, $fieldid=0) {
1213
1386
    global $CFG;
1214
 
 
1215
1387
    $LIKE = sql_ilike();
1216
1388
    if ($fieldid) {
1217
1389
        return record_exists_sql("SELECT * from {$CFG->prefix}data_fields df
1231
1403
                $str .= $inner . ',';
1232
1404
            }
1233
1405
            $str = substr($str, 0, -1);
1234
 
 
1235
1406
            $fieldinput->$key = $str;
1236
1407
        }
1237
1408
    }
1250
1421
 * @return boolean      - data module was converted or not
1251
1422
 */
1252
1423
function data_convert_to_roles($data, $teacherroles=array(), $studentroles=array(), $cmid=NULL) {
1253
 
 
1254
1424
    global $CFG;
1255
 
 
1256
1425
    if (!isset($data->participants) && !isset($data->assesspublic)
1257
1426
            && !isset($data->groupmode)) {
1258
1427
        // We assume that this database has already been converted to use the
1260
1429
        // upgraded to use Roles.
1261
1430
        return false;
1262
1431
    }
1263
 
 
1264
1432
    if (empty($cmid)) {
1265
1433
        // We were not given the course_module id. Try to find it.
1266
1434
        if (!$cm = get_coursemodule_from_instance('data', $data->id)) {
1272
1440
    }
1273
1441
    $context = get_context_instance(CONTEXT_MODULE, $cmid);
1274
1442
 
1275
 
 
1276
1443
    // $data->participants:
1277
1444
    // 1 - Only teachers can add entries
1278
1445
    // 3 - Teachers and students can add entries
1352
1519
        $cm = get_record('course_modules', 'id', $cmid);
1353
1520
    }
1354
1521
 
1355
 
    // $cm->groupmode:
1356
 
    // 0 - No groups
1357
 
    // 1 - Separate groups
1358
 
    // 2 - Visible groups
1359
1522
    switch ($cm->groupmode) {
1360
 
        case 0:
 
1523
        case NOGROUPS:
1361
1524
            break;
1362
 
        case 1:
 
1525
        case SEPARATEGROUPS:
1363
1526
            foreach ($studentroles as $studentrole) {
1364
1527
                assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $studentrole->id, $context->id);
1365
1528
            }
1367
1530
                assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $teacherrole->id, $context->id);
1368
1531
            }
1369
1532
            break;
1370
 
        case 2:
 
1533
        case VISIBLEGROUPS:
1371
1534
            foreach ($studentroles as $studentrole) {
1372
1535
                assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $studentrole->id, $context->id);
1373
1536
            }
1384
1547
 */
1385
1548
function data_preset_name($shortname, $path) {
1386
1549
 
1387
 
    /// We are looking inside the preset itself as a first choice, but also in normal data directory
1388
 
    $string = get_string('presetname'.$shortname, 'data', NULL, $path.'/lang/');
 
1550
    // We are looking inside the preset itself as a first choice, but also in normal data directory
 
1551
    $string = get_string('modulename', 'datapreset_'.$shortname);
1389
1552
 
1390
1553
    if (substr($string, 0, 1) == '[') {
1391
1554
        return $shortname;
1399
1562
 */
1400
1563
function data_get_available_presets($context) {
1401
1564
    global $CFG, $USER;
1402
 
 
1403
1565
    $presets = array();
1404
 
 
1405
1566
    if ($dirs = get_list_of_plugins('mod/data/preset')) {
1406
1567
        foreach ($dirs as $dir) {
1407
1568
            $fulldir = $CFG->dirroot.'/mod/data/preset/'.$dir;
1408
 
 
1409
1569
            if (is_directory_a_preset($fulldir)) {
1410
1570
                $preset = new object;
1411
1571
                $preset->path = $fulldir;
1427
1587
    if ($userids = get_list_of_plugins('data/preset', '', $CFG->dataroot)) {
1428
1588
        foreach ($userids as $userid) {
1429
1589
            $fulldir = $CFG->dataroot.'/data/preset/'.$userid;
1430
 
 
1431
1590
            if ($userid == 0 || $USER->id == $userid || has_capability('mod/data:viewalluserpresets', $context)) {
1432
 
 
1433
1591
                if ($dirs = get_list_of_plugins('data/preset/'.$userid, '', $CFG->dataroot)) {
1434
1592
                    foreach ($dirs as $dir) {
1435
1593
                        $fulldir = $CFG->dataroot.'/data/preset/'.$userid.'/'.$dir;
1436
 
 
1437
1594
                        if (is_directory_a_preset($fulldir)) {
1438
1595
                            $preset = new object;
1439
1596
                            $preset->path = $fulldir;
1454
1611
            }
1455
1612
        }
1456
1613
    }
1457
 
 
1458
1614
    return $presets;
1459
1615
}
1460
1616
 
1461
1617
 
1462
1618
function data_print_header($course, $cm, $data, $currenttab='') {
1463
 
 
1464
1619
    global $CFG, $displaynoticegood, $displaynoticebad;
1465
 
 
1466
 
    $strdata = get_string('modulenameplural','data');
1467
 
 
1468
 
    print_header_simple($data->name, '', "<a href='index.php?id=$course->id'>$strdata</a> -> $data->name",
 
1620
    $navigation = build_navigation('', $cm);
 
1621
    print_header_simple($data->name, '', $navigation,
1469
1622
            '', '', true, update_module_button($cm->id, $course->id, get_string('modulename', 'data')),
1470
1623
            navmenu($course, $cm));
1471
 
 
1472
1624
    print_heading(format_string($data->name));
1473
1625
 
1474
 
/// Groups needed for Add entry tab
1475
 
    $groupmode = groupmode($course, $cm);
1476
 
    $currentgroup = get_and_set_current_group($course, $groupmode);
1477
 
 
1478
 
    /// Print the tabs
1479
 
 
 
1626
// Groups needed for Add entry tab
 
1627
    $currentgroup = groups_get_activity_group($cm);
 
1628
    $groupmode = groups_get_activity_groupmode($cm);
 
1629
    // Print the tabs
1480
1630
    if ($currenttab) {
1481
 
        include_once('tabs.php');
 
1631
        include('tabs.php');
1482
1632
    }
1483
 
 
1484
 
    /// Print any notices
1485
 
 
 
1633
    // Print any notices
1486
1634
    if (!empty($displaynoticegood)) {
1487
1635
        notify($displaynoticegood, 'notifysuccess');    // good (usually green)
1488
1636
    } else if (!empty($displaynoticebad)) {
1492
1640
 
1493
1641
function data_user_can_add_entry($data, $currentgroup, $groupmode) {
1494
1642
    global $USER;
1495
 
 
1496
1643
    if (!$cm = get_coursemodule_from_instance('data', $data->id)) {
1497
1644
        error('Course Module ID was incorrect');
1498
1645
    }
1499
1646
    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
1500
 
 
1501
1647
    if (!has_capability('mod/data:writeentry', $context) and !has_capability('mod/data:manageentries',$context)) {
1502
1648
        return false;
1503
1649
    }
1504
 
 
1505
1650
    if (!$groupmode or has_capability('moodle/site:accessallgroups', $context)) {
1506
1651
        return true;
1507
1652
    }
1508
1653
 
1509
1654
    if ($currentgroup) {
1510
 
        return ismember($currentgroup);
 
1655
        return groups_is_member($currentgroup);
1511
1656
    } else {
1512
1657
        //else it might be group 0 in visible mode
1513
1658
        if ($groupmode == VISIBLEGROUPS){
1518
1663
    }
1519
1664
}
1520
1665
 
1521
 
// pulled directly out of preset.php Penny 20070426
1522
1666
 
1523
1667
function is_directory_a_preset($directory) {
1524
1668
    $directory = rtrim($directory, '/\\') . '/';
1525
 
    if (file_exists($directory.'singletemplate.html') &&
1526
 
            file_exists($directory.'listtemplate.html') &&
1527
 
            file_exists($directory.'listtemplateheader.html') &&
1528
 
            file_exists($directory.'listtemplatefooter.html') &&
1529
 
            file_exists($directory.'addtemplate.html') &&
1530
 
            file_exists($directory.'rsstemplate.html') &&
1531
 
            file_exists($directory.'rsstitletemplate.html') &&
1532
 
            file_exists($directory.'csstemplate.css') &&
1533
 
            file_exists($directory.'jstemplate.js') &&
1534
 
            file_exists($directory.'preset.xml')) return true;
1535
 
    else return false;
 
1669
    $status = file_exists($directory.'singletemplate.html') &&
 
1670
              file_exists($directory.'listtemplate.html') &&
 
1671
              file_exists($directory.'listtemplateheader.html') &&
 
1672
              file_exists($directory.'listtemplatefooter.html') &&
 
1673
              file_exists($directory.'addtemplate.html') &&
 
1674
              file_exists($directory.'rsstemplate.html') &&
 
1675
              file_exists($directory.'rsstitletemplate.html') &&
 
1676
              file_exists($directory.'csstemplate.css') &&
 
1677
              file_exists($directory.'jstemplate.js') &&
 
1678
              file_exists($directory.'preset.xml');
 
1679
    return $status;
1536
1680
}
1537
1681
 
1538
1682
 
1539
1683
function clean_preset($folder) {
1540
 
    if (@unlink($folder.'/singletemplate.html') &&
1541
 
        @unlink($folder.'/listtemplate.html') &&
1542
 
        @unlink($folder.'/listtemplateheader.html') &&
1543
 
        @unlink($folder.'/listtemplatefooter.html') &&
1544
 
        @unlink($folder.'/addtemplate.html') &&
1545
 
        @unlink($folder.'/rsstemplate.html') &&
1546
 
        @unlink($folder.'/rsstitletemplate.html') &&
1547
 
        @unlink($folder.'/csstemplate.css') &&
1548
 
        @unlink($folder.'/jstemplate.js') &&
1549
 
        @unlink($folder.'/preset.xml')) {
1550
 
        return true;
1551
 
    }
1552
 
    return false;
1553
 
}
1554
 
 
1555
 
 
1556
 
function data_presets_export($course, $cm, $data) {
1557
 
    global $CFG;
1558
 
    /* Info Collected. Now need to make files in moodledata/temp */
1559
 
    $tempfolder = $CFG->dataroot.'/temp';
1560
 
    $singletemplate     = fopen($tempfolder.'/singletemplate.html', 'w');
1561
 
    $listtemplate       = fopen($tempfolder.'/listtemplate.html', 'w');
1562
 
    $listtemplateheader = fopen($tempfolder.'/listtemplateheader.html', 'w');
1563
 
    $listtemplatefooter = fopen($tempfolder.'/listtemplatefooter.html', 'w');
1564
 
    $addtemplate        = fopen($tempfolder.'/addtemplate.html', 'w');
1565
 
    $rsstemplate        = fopen($tempfolder.'/rsstemplate.html', 'w');
1566
 
    $rsstitletemplate   = fopen($tempfolder.'/rsstitletemplate.html', 'w');
1567
 
    $csstemplate        = fopen($tempfolder.'/csstemplate.css', 'w');
1568
 
    $jstemplate         = fopen($tempfolder.'/jstemplate.js', 'w');
1569
 
 
1570
 
    fwrite($singletemplate, $data->singletemplate);
1571
 
    fwrite($listtemplate, $data->listtemplate);
1572
 
    fwrite($listtemplateheader, $data->listtemplateheader);
1573
 
    fwrite($listtemplatefooter, $data->listtemplatefooter);
1574
 
    fwrite($addtemplate, $data->addtemplate);
1575
 
    fwrite($rsstemplate, $data->rsstemplate);
1576
 
    fwrite($rsstitletemplate, $data->rsstitletemplate);
1577
 
    fwrite($csstemplate, $data->csstemplate);
1578
 
    fwrite($jstemplate, $data->jstemplate);
1579
 
 
1580
 
    fclose($singletemplate);
1581
 
    fclose($listtemplate);
1582
 
    fclose($listtemplateheader);
1583
 
    fclose($listtemplatefooter);
1584
 
    fclose($addtemplate);
1585
 
    fclose($rsstemplate);
1586
 
    fclose($rsstitletemplate);
1587
 
    fclose($csstemplate);
1588
 
    fclose($jstemplate);
1589
 
 
1590
 
    /* All the display data is now done. Now assemble preset.xml */
1591
 
    $fields = get_records('data_fields', 'dataid', $data->id);
1592
 
    $presetfile = fopen($tempfolder.'/preset.xml', 'w');
1593
 
    $presetxml = "<preset>\n\n";
1594
 
 
1595
 
    /* Database settings first. Name not included? */
1596
 
    $settingssaved = array('intro', 'comments',
1597
 
            'requiredentries', 'requiredentriestoview', 'maxentries',
1598
 
            'rssarticles', 'approval', 'scale', 'assessed',
1599
 
            'defaultsort', 'defaultsortdir', 'editany');
1600
 
 
1601
 
    $presetxml .= "<settings>\n";
1602
 
    foreach ($settingssaved as $setting) {
1603
 
        $presetxml .= "<$setting>{$data->$setting}</$setting>\n";
1604
 
    }
1605
 
    $presetxml .= "</settings>\n\n";
1606
 
 
1607
 
    /* Now for the fields. Grabs all settings that are non-empty */
1608
 
    if (!empty($fields)) {
1609
 
        foreach ($fields as $field) {
1610
 
            $presetxml .= "<field>\n";
1611
 
            foreach ($field as $key => $value) {
1612
 
                if ($value != '' && $key != 'id' && $key != 'dataid') {
1613
 
                    $presetxml .= "<$key>$value</$key>\n";
1614
 
                }
1615
 
            }
1616
 
            $presetxml .= "</field>\n\n";
1617
 
        }
1618
 
    }
1619
 
 
1620
 
    $presetxml .= "</preset>";
1621
 
    fwrite($presetfile, $presetxml);
1622
 
    fclose($presetfile);
1623
 
 
1624
 
    /* Check all is well */
1625
 
    if (!is_directory_a_preset($tempfolder)) {
1626
 
        error("Not all files generated!");
1627
 
    }
1628
 
 
1629
 
    $filelist = array(
1630
 
            'singletemplate.html',
1631
 
            'listtemplate.html',
1632
 
            'listtemplateheader.html',
1633
 
            'listtemplatefooter.html',
1634
 
            'addtemplate.html',
1635
 
            'rsstemplate.html',
1636
 
            'rsstitletemplate.html',
1637
 
            'csstemplate.css',
1638
 
            'jstemplate.js',
1639
 
            'preset.xml');
1640
 
 
1641
 
    foreach ($filelist as $key => $file) {
1642
 
        $filelist[$key] = $tempfolder.'/'.$filelist[$key];
1643
 
    }
1644
 
 
1645
 
    @unlink($tempfolder.'/export.zip');
1646
 
    $status = zip_files($filelist, $tempfolder.'/export.zip');
1647
 
 
1648
 
    /* made the zip... now return the filename for storage.*/
1649
 
    return $tempfolder.'/export.zip';
1650
 
}
1651
 
 
 
1684
    $status = @unlink($folder.'/singletemplate.html') &&
 
1685
              @unlink($folder.'/listtemplate.html') &&
 
1686
              @unlink($folder.'/listtemplateheader.html') &&
 
1687
              @unlink($folder.'/listtemplatefooter.html') &&
 
1688
              @unlink($folder.'/addtemplate.html') &&
 
1689
              @unlink($folder.'/rsstemplate.html') &&
 
1690
              @unlink($folder.'/rsstitletemplate.html') &&
 
1691
              @unlink($folder.'/csstemplate.css') &&
 
1692
              @unlink($folder.'/jstemplate.js') &&
 
1693
              @unlink($folder.'/preset.xml');
 
1694
 
 
1695
    // optional
 
1696
    @unlink($folder.'/asearchtemplate.html');
 
1697
    return $status;
 
1698
}
1652
1699
 
1653
1700
 
1654
1701
class PresetImporter {
1671
1718
 
1672
1719
        /* Grab XML */
1673
1720
        $presetxml = file_get_contents($this->folder.'/preset.xml');
1674
 
        $parsedxml = xmlize($presetxml);
 
1721
        $parsedxml = xmlize($presetxml, 0);
 
1722
 
 
1723
        $allowed_settings = array('intro', 'comments', 'requiredentries', 'requiredentriestoview',
 
1724
                                  'maxentries', 'rssarticles', 'approval', 'defaultsortdir', 'defaultsort');
1675
1725
 
1676
1726
        /* First, do settings. Put in user friendly array. */
1677
1727
        $settingsarray = $parsedxml['preset']['#']['settings'][0]['#'];
1678
1728
        $settings = new StdClass();
1679
1729
 
1680
1730
        foreach ($settingsarray as $setting => $value) {
 
1731
            if (!is_array($value)) {
 
1732
                continue;
 
1733
            }
 
1734
            if (!in_array($setting, $allowed_settings)) {
 
1735
                // unsupported setting
 
1736
                continue;
 
1737
            }
1681
1738
            $settings->$setting = $value[0]['#'];
1682
1739
        }
1683
1740
 
1685
1742
        $fieldsarray = $parsedxml['preset']['#']['field'];
1686
1743
        $fields = array();
1687
1744
        foreach ($fieldsarray as $field) {
 
1745
            if (!is_array($field)) {
 
1746
                continue;
 
1747
            }
1688
1748
            $f = new StdClass();
1689
1749
            foreach ($field['#'] as $param => $value) {
1690
 
                $f->$param = $value[0]['#'];
 
1750
                if (!is_array($value)) {
 
1751
                    continue;
 
1752
                }
 
1753
                $f->$param = addslashes($value[0]['#']);
1691
1754
            }
1692
1755
            $f->dataid = $this->data->id;
1693
1756
            $f->type = clean_param($f->type, PARAM_ALPHA);
1694
1757
            $fields[] = $f;
1695
1758
        }
1696
 
 
1697
1759
        /* Now add the HTML templates to the settings array so we can update d */
1698
1760
        $settings->singletemplate     = file_get_contents($this->folder."/singletemplate.html");
1699
1761
        $settings->listtemplate       = file_get_contents($this->folder."/listtemplate.html");
1705
1767
        $settings->csstemplate        = file_get_contents($this->folder."/csstemplate.css");
1706
1768
        $settings->jstemplate         = file_get_contents($this->folder."/jstemplate.js");
1707
1769
 
 
1770
        //optional
 
1771
        if (file_exists($this->folder."/asearchtemplate.html")) {
 
1772
            $settings->asearchtemplate = file_get_contents($this->folder."/asearchtemplate.html");
 
1773
        } else {
 
1774
            $settings->asearchtemplate = NULL;
 
1775
        }
 
1776
 
1708
1777
        $settings->instance = $this->data->id;
1709
1778
 
1710
1779
        /* Now we look at the current structure (if any) to work out whether we need to clear db
1711
1780
           or save the data */
1712
 
        $currentfields = array();
1713
 
        $currentfields = get_records('data_fields', 'dataid', $this->data->id);
 
1781
        if (!$currentfields = get_records('data_fields', 'dataid', $this->data->id)) {
 
1782
            $currentfields = array();
 
1783
        }
1714
1784
 
1715
1785
        return array($settings, $fields, $currentfields);
1716
1786
    }
1719
1789
        if (!confirm_sesskey()) {
1720
1790
            error("Sesskey Invalid");
1721
1791
        }
1722
 
 
1723
1792
        $strblank = get_string('blank', 'data');
1724
 
        $strnofields = get_string('nofields', 'data');
1725
1793
        $strcontinue = get_string('continue');
1726
1794
        $strwarning = get_string('mappingwarning', 'data');
1727
1795
        $strfieldmappings = get_string('fieldmappings', 'data');
1728
1796
        $strnew = get_string('new');
1729
 
        $strold = get_string('old');
1730
 
 
1731
1797
        $sesskey = sesskey();
1732
 
 
1733
1798
        list($settings, $newfields,  $currentfields) = $this->get_settings();
1734
 
 
1735
 
        echo '<div style="text-align:center"><form action="preset.php" method="post">';
1736
 
        echo '<fieldset class="invisiblefieldset">';
 
1799
        echo '<div class="presetmapping"><form action="preset.php" method="post">';
 
1800
        echo '<div>';
1737
1801
        echo '<input type="hidden" name="action" value="finishimport" />';
1738
1802
        echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
1739
1803
        echo '<input type="hidden" name="d" value="'.$this->data->id.'" />';
1740
1804
        echo '<input type="hidden" name="fullname" value="'.$this->userid.'/'.$this->shortname.'" />';
1741
 
 
1742
1805
        if (!empty($currentfields) && !empty($newfields)) {
1743
1806
            echo "<h3>$strfieldmappings ";
1744
 
            helpbutton('fieldmappings', '', 'data');
 
1807
            helpbutton('fieldmappings', $strfieldmappings, 'data');
1745
1808
            echo '</h3><table>';
1746
 
 
1747
1809
            foreach ($newfields as $nid => $newfield) {
1748
1810
                echo "<tr><td><label for=\"id_$newfield->name\">$newfield->name</label></td>";
1749
1811
                echo '<td><select name="field_'.$nid.'" id="id_'.$newfield->name.'">';
1750
 
 
1751
1812
                $selected = false;
1752
1813
                foreach ($currentfields as $cid => $currentfield) {
1753
1814
                    if ($currentfield->type == $newfield->type) {
1756
1817
                            $selected=true;
1757
1818
                        }
1758
1819
                        else {
1759
 
                            echo '<option value="$cid">'.$currentfield->name.'</option>';
 
1820
                            echo '<option value="'.$cid.'">'.$currentfield->name.'</option>';
1760
1821
                        }
1761
1822
                    }
1762
1823
                }
1763
 
 
1764
1824
                if ($selected)
1765
1825
                    echo '<option value="-1">-</option>';
1766
1826
                else
1769
1829
            }
1770
1830
            echo '</table>';
1771
1831
            echo "<p>$strwarning</p>";
1772
 
        }
1773
 
        else if (empty($newfields)) {
 
1832
        } else if (empty($newfields)) {
1774
1833
            error("New preset has no defined fields!");
1775
1834
        }
1776
 
        echo '<input type="submit" value="'.$strcontinue.'" /></fieldset></form></div>';
1777
 
 
 
1835
        echo '<div class="overwritesettings"><label for="overwritesettings">'.get_string('overwritesettings', 'data').'</label>';
 
1836
        echo '<input id="overwritesettings" name="overwritesettings" type="checkbox" /></label></div>';
 
1837
        echo '<input class="button" type="submit" value="'.$strcontinue.'" /></div></form></div>';
1778
1838
    }
1779
1839
 
1780
1840
    function import() {
1781
1841
        global $CFG;
1782
 
 
1783
1842
        list($settings, $newfields, $currentfields) = $this->get_settings();
1784
1843
        $preservedfields = array();
1785
 
 
 
1844
        $overwritesettings = optional_param('overwritesettings', 0, PARAM_BOOL);
1786
1845
        /* Maps fields and makes new ones */
1787
1846
        if (!empty($newfields)) {
1788
1847
            /* We require an injective mapping, and need to know what to protect */
1789
1848
            foreach ($newfields as $nid => $newfield) {
1790
1849
                $cid = optional_param("field_$nid", -1, PARAM_INT);
1791
1850
                if ($cid == -1) continue;
1792
 
 
1793
1851
                if (array_key_exists($cid, $preservedfields)) error("Not an injective map");
1794
1852
                else $preservedfields[$cid] = true;
1795
1853
            }
1796
 
 
1797
1854
            foreach ($newfields as $nid => $newfield) {
1798
1855
                $cid = optional_param("field_$nid", -1, PARAM_INT);
1799
 
 
1800
1856
                /* A mapping. Just need to change field params. Data kept. */
1801
1857
                if ($cid != -1 and isset($currentfields[$cid])) {
1802
1858
                    $fieldobject = data_get_field_from_id($currentfields[$cid]->id, $this->data);
1812
1868
                /* Make a new field */
1813
1869
                else {
1814
1870
                    include_once("field/$newfield->type/field.class.php");
1815
 
 
1816
1871
                    if (!isset($newfield->description)) {
1817
1872
                        $newfield->description = '';
1818
1873
                    }
1830
1885
                if (!array_key_exists($cid, $preservedfields)) {
1831
1886
                    /* Data not used anymore so wipe! */
1832
1887
                    print "Deleting field $currentfield->name<br />";
1833
 
 
1834
1888
                    $id = $currentfield->id;
1835
1889
                    //Why delete existing data records and related comments/ratings??
1836
1890
/*
1847
1901
            }
1848
1902
        }
1849
1903
 
1850
 
        data_update_instance(addslashes_object($settings));
1851
 
 
1852
 
        if (strstr($this->folder, '/temp/')) clean_preset($this->folder); /* Removes the temporary files */
 
1904
    // handle special settings here
 
1905
        if (!empty($settings->defaultsort)) {
 
1906
            if (is_numeric($settings->defaultsort)) {
 
1907
                // old broken value
 
1908
                $settings->defaultsort = 0;
 
1909
            } else {
 
1910
                $settings->defaultsort = (int)get_field('data_fields', 'id', 'dataid', $this->data->id, 'name', addslashes($settings->defaultsort));
 
1911
            }
 
1912
        } else {
 
1913
            $settings->defaultsort = 0;
 
1914
        }
 
1915
 
 
1916
        // do we want to overwrite all current database settings?
 
1917
        if ($overwritesettings) {
 
1918
            // all supported settings
 
1919
            $overwrite = array_keys((array)$settings);
 
1920
        } else {
 
1921
            // only templates and sorting
 
1922
            $overwrite = array('singletemplate', 'listtemplate', 'listtemplateheader', 'listtemplatefooter',
 
1923
                               'addtemplate', 'rsstemplate', 'rsstitletemplate', 'csstemplate', 'jstemplate',
 
1924
                               'asearchtemplate', 'defaultsortdir', 'defaultsort');
 
1925
        }
 
1926
 
 
1927
        // now overwrite current data settings
 
1928
        foreach ($this->data as $prop=>$unused) {
 
1929
            if (in_array($prop, $overwrite)) {
 
1930
                $this->data->$prop = $settings->$prop;
 
1931
            }
 
1932
        }
 
1933
 
 
1934
        data_update_instance(addslashes_object($this->data));
 
1935
        if (strstr($this->folder, '/temp/')) {
 
1936
        // Removes the temporary files
 
1937
            clean_preset($this->folder); 
 
1938
        }
1853
1939
        return true;
1854
1940
    }
1855
1941
}
1856
1942
 
1857
1943
function data_preset_path($course, $userid, $shortname) {
1858
1944
    global $USER, $CFG;
1859
 
 
1860
1945
    $context = get_context_instance(CONTEXT_COURSE, $course->id);
1861
 
 
1862
1946
    $userid = (int)$userid;
1863
 
 
1864
1947
    if ($userid > 0 && ($userid == $USER->id || has_capability('mod/data:viewalluserpresets', $context))) {
1865
1948
        return $CFG->dataroot.'/data/preset/'.$userid.'/'.$shortname;
1866
1949
    } else if ($userid == 0) {
1868
1951
    } else if ($userid < 0) {
1869
1952
        return $CFG->dataroot.'/temp/data/'.-$userid.'/'.$shortname;
1870
1953
    }
1871
 
 
1872
1954
    return 'Does it disturb you that this code will never run?';
1873
1955
}
 
1956
 
 
1957
/**
 
1958
 * Implementation of the function for printing the form elements that control
 
1959
 * whether the course reset functionality affects the data.
 
1960
 * @param $mform form passed by reference
 
1961
 */
 
1962
function data_reset_course_form_definition(&$mform) {
 
1963
    $mform->addElement('header', 'dataheader', get_string('modulenameplural', 'data'));
 
1964
    $mform->addElement('checkbox', 'reset_data', get_string('deleteallentries','data'));
 
1965
 
 
1966
    $mform->addElement('checkbox', 'reset_data_notenrolled', get_string('deletenotenrolled', 'data'));
 
1967
    $mform->disabledIf('reset_data_notenrolled', 'reset_data', 'checked');
 
1968
 
 
1969
    $mform->addElement('checkbox', 'reset_data_ratings', get_string('deleteallratings'));
 
1970
    $mform->disabledIf('reset_data_ratings', 'reset_data', 'checked');
 
1971
 
 
1972
    $mform->addElement('checkbox', 'reset_data_comments', get_string('deleteallcomments'));
 
1973
    $mform->disabledIf('reset_data_comments', 'reset_data', 'checked');
 
1974
}
 
1975
 
 
1976
/**
 
1977
 * Course reset form defaults.
 
1978
 */
 
1979
function data_reset_course_form_defaults($course) {
 
1980
    return array('reset_data'=>0, 'reset_data_ratings'=>1, 'reset_data_comments'=>1, 'reset_data_notenrolled'=>0);
 
1981
}
 
1982
 
 
1983
/**
 
1984
 * Removes all grades from gradebook
 
1985
 * @param int $courseid
 
1986
 * @param string optional type
 
1987
 */
 
1988
function data_reset_gradebook($courseid, $type='') {
 
1989
    global $CFG;
 
1990
    $sql = "SELECT d.*, cm.idnumber as cmidnumber, d.course as courseid
 
1991
              FROM {$CFG->prefix}data d, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m
 
1992
             WHERE m.name='data' AND m.id=cm.module AND cm.instance=d.id AND d.course=$courseid";
 
1993
    if ($datas = get_records_sql($sql)) {
 
1994
        foreach ($datas as $data) {
 
1995
            data_grade_item_update($data, 'reset');
 
1996
        }
 
1997
    }
 
1998
}
 
1999
 
 
2000
/**
 
2001
 * Actual implementation of the rest coures functionality, delete all the
 
2002
 * data responses for course $data->courseid.
 
2003
 * @param $data the data submitted from the reset course.
 
2004
 * @return array status array
 
2005
 */
 
2006
function data_reset_userdata($data) {
 
2007
    global $CFG;
 
2008
    require_once($CFG->libdir.'/filelib.php');
 
2009
    $componentstr = get_string('modulenameplural', 'data');
 
2010
    $status = array();
 
2011
    $allrecordssql = "SELECT r.id
 
2012
                        FROM {$CFG->prefix}data_records r
 
2013
                             INNER JOIN {$CFG->prefix}data d ON r.dataid = d.id
 
2014
                       WHERE d.course = {$data->courseid}";
 
2015
    $alldatassql = "SELECT d.id
 
2016
                      FROM {$CFG->prefix}data d
 
2017
                     WHERE d.course={$data->courseid}";
 
2018
    // delete entries if requested
 
2019
    if (!empty($data->reset_data)) {
 
2020
        delete_records_select('data_ratings', "recordid IN ($allrecordssql)");
 
2021
        delete_records_select('data_comments', "recordid IN ($allrecordssql)");
 
2022
        delete_records_select('data_content', "recordid IN ($allrecordssql)");
 
2023
        delete_records_select('data_records', "dataid IN ($alldatassql)");
 
2024
        if ($datas = get_records_sql($alldatassql)) {
 
2025
            foreach ($datas as $dataid=>$unused) {
 
2026
                fulldelete("$CFG->dataroot/$data->courseid/moddata/data/$dataid");
 
2027
            }
 
2028
        }
 
2029
        if (empty($data->reset_gradebook_grades)) {
 
2030
            // remove all grades from gradebook
 
2031
            data_reset_gradebook($data->courseid);
 
2032
        }
 
2033
        $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallentries', 'data'), 'error'=>false);
 
2034
    }
 
2035
 
 
2036
    // remove entries by users not enrolled into course
 
2037
    if (!empty($data->reset_data_notenrolled)) {
 
2038
        $recordssql = "SELECT r.id, r.userid, r.dataid, u.id AS userexists, u.deleted AS userdeleted
 
2039
                         FROM {$CFG->prefix}data_records r
 
2040
                              INNER JOIN {$CFG->prefix}data d ON r.dataid = d.id
 
2041
                              LEFT OUTER JOIN {$CFG->prefix}user u ON r.userid = u.id
 
2042
                        WHERE d.course = {$data->courseid} AND r.userid > 0";
 
2043
        $course_context = get_context_instance(CONTEXT_COURSE, $data->courseid);
 
2044
        $notenrolled = array();
 
2045
        $fields = array();
 
2046
        if ($rs = get_recordset_sql($recordssql)) {
 
2047
            while ($record = rs_fetch_next_record($rs)) {
 
2048
                if (array_key_exists($record->userid, $notenrolled) or !$record->userexists or $record->userdeleted
 
2049
                  or !has_capability('moodle/course:view', $course_context , $record->userid)) {
 
2050
                    delete_records('data_ratings', 'recordid', $record->id);
 
2051
                    delete_records('data_comments', 'recordid', $record->id);
 
2052
                    delete_records('data_content', 'recordid', $record->id);
 
2053
                    delete_records('data_records', 'id', $record->id);
 
2054
                    // HACK: this is ugly - the recordid should be before the fieldid!
 
2055
                    if (!array_key_exists($record->dataid, $fields)) {
 
2056
                        if ($fs = get_records('data_fields', 'dataid', $record->dataid)) {
 
2057
                            $fields[$record->dataid] = array_keys($fs);
 
2058
                        } else {
 
2059
                            $fields[$record->dataid] = array();
 
2060
                        }
 
2061
                    }
 
2062
                    foreach($fields[$record->dataid] as $fieldid) {
 
2063
                        fulldelete("$CFG->dataroot/$data->courseid/moddata/data/$record->dataid/$fieldid/$record->id");
 
2064
                    }
 
2065
                    $notenrolled[$record->userid] = true;
 
2066
                }
 
2067
            }
 
2068
            rs_close($rs);
 
2069
            $status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotenrolled', 'data'), 'error'=>false);
 
2070
        }
 
2071
    }
 
2072
 
 
2073
    // remove all ratings
 
2074
    if (!empty($data->reset_data_ratings)) {
 
2075
        delete_records_select('data_ratings', "recordid IN ($allrecordssql)");
 
2076
        if (empty($data->reset_gradebook_grades)) {
 
2077
            // remove all grades from gradebook
 
2078
            data_reset_gradebook($data->courseid);
 
2079
        }
 
2080
        $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallratings'), 'error'=>false);
 
2081
    }
 
2082
 
 
2083
    // remove all comments
 
2084
    if (!empty($data->reset_data_comments)) {
 
2085
        delete_records_select('data_comments', "recordid IN ($allrecordssql)");
 
2086
        $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallcomments'), 'error'=>false);
 
2087
    }
 
2088
 
 
2089
    // updating dates - shift may be negative too
 
2090
    if ($data->timeshift) {
 
2091
        shift_course_mod_dates('data', array('timeavailablefrom', 'timeavailableto', 'timeviewfrom', 'timeviewto'), $data->timeshift, $data->courseid);
 
2092
        $status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
 
2093
    }
 
2094
    return $status;
 
2095
}
 
2096
 
 
2097
/**
 
2098
 * Returns all other caps used in module
 
2099
 */
 
2100
function data_get_extra_capabilities() {
 
2101
    return array('moodle/site:accessallgroups', 'moodle/site:viewfullnames');
 
2102
}
 
2103
 
 
2104
 
1874
2105
?>