Skip to content

Commit

Permalink
Merge branch 'wip-MDL-40871-master' of git://github.com/abgreeve/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Hemelryk committed Aug 12, 2013
2 parents 1e6ac69 + e727e8f commit f37d532
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 26 deletions.
2 changes: 2 additions & 0 deletions mod/data/lang/en/data.php
Expand Up @@ -69,6 +69,7 @@
$string['configenablerssfeeds'] = 'This switch will enable the possibility of RSS feeds for all databases. You will still need to turn feeds on manually in the settings for each database.';
$string['confirmdeletefield'] = 'You are about to delete this field, are you sure?';
$string['confirmdeleterecord'] = 'Are you sure you want to delete this entry?';
$string['confirmdeleterecords'] = 'Are you sure you want to delete these entries?';
$string['csstemplate'] = 'CSS template';
$string['csvfailed'] = 'Unable to read the raw data from the CSV file';
$string['csvfile'] = 'CSV file';
Expand Down Expand Up @@ -99,6 +100,7 @@
$string['defaultfielddelimiter'] = '(default is the comma character)';
$string['defaultfieldenclosure'] = '(default is none)';
$string['defaultsortfield'] = 'Default sort field';
$string['delcheck'] = 'Bulk delete checkbox';
$string['delete'] = 'Delete';
$string['deleteallentries'] = 'Delete all entries';
$string['deletecomment'] = 'Are you sure you want to delete this comment?';
Expand Down
51 changes: 49 additions & 2 deletions mod/data/lib.php
Expand Up @@ -536,7 +536,13 @@ function data_generate_default_template(&$data, $template, $recordid=0, $form=fa
$table->data[] = $row;
}

$str = html_writer::start_tag('div', array('class' => 'defaulttemplate'));
$str = '';
if ($template == 'listtemplate'){
$str .= '##delcheck##';
$str .= html_writer::empty_tag('br');
}

$str .= html_writer::start_tag('div', array('class' => 'defaulttemplate'));
$str .= html_writer::table($table);
$str .= html_writer::end_tag('div');
if ($template == 'listtemplate'){
Expand Down Expand Up @@ -1160,6 +1166,7 @@ function data_grade_item_delete($data) {
*/
function data_print_template($template, $records, $data, $search='', $page=0, $return=false) {
global $CFG, $DB, $OUTPUT;

$cm = get_coursemodule_from_instance('data', $data->id);
$context = context_module::instance($cm->id);

Expand Down Expand Up @@ -1200,10 +1207,12 @@ function data_print_template($template, $records, $data, $search='', $page=0, $r
$replacement[] = highlight($search, $field->display_browse_field($record->id, $template));
}

$canmanageentries = has_capability('mod/data:manageentries', $context);

// Replacing special tags (##Edit##, ##Delete##, ##More##)
$patterns[]='##edit##';
$patterns[]='##delete##';
if (has_capability('mod/data:manageentries', $context) || (!$readonly && data_isowner($record->id))) {
if ($canmanageentries || (!$readonly && data_isowner($record->id))) {
$replacement[] = '<a href="'.$CFG->wwwroot.'/mod/data/edit.php?d='
.$data->id.'&amp;rid='.$record->id.'&amp;sesskey='.sesskey().'"><img src="'.$OUTPUT->pix_url('t/edit') . '" class="iconsmall" alt="'.get_string('edit').'" title="'.get_string('edit').'" /></a>';
$replacement[] = '<a href="'.$CFG->wwwroot.'/mod/data/view.php?d='
Expand All @@ -1225,6 +1234,13 @@ function data_print_template($template, $records, $data, $search='', $page=0, $r
$patterns[]='##moreurl##';
$replacement[] = $moreurl;

$patterns[]='##delcheck##';
if ($canmanageentries) {
$replacement[] = html_writer::checkbox('delcheck[]', $record->id, false, '', array('class' => 'recordcheckbox'));
} else {
$replacement[] = '';
}

$patterns[]='##user##';
$replacement[] = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$record->userid.
'&amp;course='.$data->course.'">'.fullname($record).'</a>';
Expand Down Expand Up @@ -3634,3 +3650,34 @@ function data_user_can_delete_preset($context, $preset) {
return $candelete;
}
}

/**
* Delete a record entry.
*
* @param int $recordid The ID for the record to be deleted.
* @param object $data The data object for this activity.
* @param int $courseid ID for the current course (for logging).
* @param int $cmid The course module ID.
* @return bool True if the record deleted, false if not.
*/
function data_delete_record($recordid, $data, $courseid, $cmid) {
global $DB;

if ($deleterecord = $DB->get_record('data_records', array('id' => $recordid))) {
if ($deleterecord->dataid == $data->id) {
if ($contents = $DB->get_records('data_content', array('recordid' => $deleterecord->id))) {
foreach ($contents as $content) {
if ($field = data_get_field_from_id($content->fieldid, $data)) {
$field->delete_content($content->recordid);
}
}
$DB->delete_records('data_content', array('recordid'=>$deleterecord->id));
$DB->delete_records('data_records', array('id'=>$deleterecord->id));

add_to_log($courseid, 'data', 'record delete', "view.php?id=$cmid", $data->id, $cmid);
return true;
}
}
}
return false;
}
15 changes: 15 additions & 0 deletions mod/data/module.js
@@ -0,0 +1,15 @@
M.mod_data = {};

M.mod_data.init_view = function(Y) {
Y.on('click', function(e) {
Y.all('input.recordcheckbox').each(function() {
this.set('checked', 'checked');
});
}, '#checkall');

Y.on('click', function(e) {
Y.all('input.recordcheckbox').each(function() {
this.set('checked', '');
});
}, '#checknone');
};
1 change: 1 addition & 0 deletions mod/data/templates.php
Expand Up @@ -253,6 +253,7 @@
// more points to single template - not useable there
echo '<option value="##more##">' .get_string('more', 'data'). ' - ##more##</option>';
echo '<option value="##moreurl##">' .get_string('moreurl', 'data'). ' - ##moreurl##</option>';
echo '<option value="##delcheck##">' .get_string('delcheck', 'data'). ' - ##delcheck##</option>';
}
echo '</optgroup>';
echo '<optgroup label="'.get_string('other', 'data').'">';
Expand Down
107 changes: 107 additions & 0 deletions mod/data/tests/lib_test.php
@@ -0,0 +1,107 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Unit tests for lib.php
*
* @package mod_data
* @category phpunit
* @copyright 2013 Adrian Greeve
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

defined('MOODLE_INTERNAL') || die();

global $CFG;
require_once($CFG->dirroot . '/mod/data/lib.php');

/**
* Unit tests for lib.php
*
* @package mod_data
* @copyright 2013 Adrian Greeve
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class data_lib_testcase extends advanced_testcase {

function test_data_delete_record() {
global $DB;

$this->resetAfterTest();

// Create a record for deleting.
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$record = new stdClass();
$record->course = $course->id;
$record->name = "Mod data delete test";
$record->intro = "Some intro of some sort";

$module = $this->getDataGenerator()->create_module('data', $record);

$field = data_get_field_new('text', $module);

$fielddetail = new stdClass();
$fielddetail->d = $module->id;
$fielddetail->mode = 'add';
$fielddetail->type = 'text';
$fielddetail->sesskey = sesskey();
$fielddetail->name = 'Name';
$fielddetail->description = 'Some name';

$field->define_field($fielddetail);
$field->insert_field();
$recordid = data_add_record($module);

$datacontent = array();
$datacontent['fieldid'] = $field->field->id;
$datacontent['recordid'] = $recordid;
$datacontent['content'] = 'Asterix';

$contentid = $DB->insert_record('data_content', $datacontent);
$cm = get_coursemodule_from_instance('data', $module->id, $course->id);

// Check to make sure that we have a database record.
$data = $DB->get_records('data', array('id' => $module->id));
$this->assertEquals(1, count($data));

$datacontent = $DB->get_records('data_content', array('id' => $contentid));
$this->assertEquals(1, count($datacontent));

$datafields = $DB->get_records('data_fields', array('id' => $field->field->id));
$this->assertEquals(1, count($datafields));

$datarecords = $DB->get_records('data_records', array('id' => $recordid));
$this->assertEquals(1, count($datarecords));

// Test to see if a failed delete returns false.
$result = data_delete_record(8798, $module, $course->id, $cm->id);
$this->assertFalse($result);

// Delete the record.
$result = data_delete_record($recordid, $module, $course->id, $cm->id);

// Check that all of the record is gone.
$datacontent = $DB->get_records('data_content', array('id' => $contentid));
$this->assertEquals(0, count($datacontent));

$datarecords = $DB->get_records('data_records', array('id' => $recordid));
$this->assertEquals(0, count($datarecords));

// Make sure the function returns true on a successful deletion.
$this->assertTrue($result);
}
}
86 changes: 62 additions & 24 deletions mod/data/view.php
Expand Up @@ -40,6 +40,8 @@
/// These can be added to perform an action on a record
$approve = optional_param('approve', 0, PARAM_INT); //approval recordid
$delete = optional_param('delete', 0, PARAM_INT); //delete recordid
$multidelete = optional_param_array('delcheck', null, PARAM_INT);
$serialdelete = optional_param('serialdelete', null, PARAM_RAW);

if ($id) {
if (! $cm = get_coursemodule_from_id('data', $id)) {
Expand Down Expand Up @@ -326,16 +328,17 @@
groups_print_activity_menu($cm, $returnurl);
$currentgroup = groups_get_activity_group($cm);
$groupmode = groups_get_activity_groupmode($cm);
$canmanageentries = has_capability('mod/data:manageentries', $context);
// If a student is not part of a group and seperate groups is enabled, we don't
// want them seeing all records.
if ($currentgroup == 0 && $groupmode == 1 && !has_capability('mod/data:manageentries', $context)) {
if ($currentgroup == 0 && $groupmode == 1 && !$canmanageentries) {
$canviewallrecords = false;
} else {
$canviewallrecords = true;
}

// detect entries not approved yet and show hint instead of not found error
if ($record and $data->approval and !$record->approved and $record->userid != $USER->id and !has_capability('mod/data:manageentries', $context)) {
if ($record and $data->approval and !$record->approved and $record->userid != $USER->id and !$canmanageentries) {
if (!$currentgroup or $record->groupid == $currentgroup or $record->groupid == 0) {
print_error('notapproved', 'data');
}
Expand All @@ -360,26 +363,11 @@

/// Delete any requested records

if ($delete && confirm_sesskey() && (has_capability('mod/data:manageentries', $context) or data_isowner($delete))) {
if ($delete && confirm_sesskey() && ($canmanageentries or data_isowner($delete))) {
if ($confirm = optional_param('confirm',0,PARAM_INT)) {
if ($deleterecord = $DB->get_record('data_records', array('id'=>$delete))) { // Need to check this is valid
if ($deleterecord->dataid == $data->id) { // Must be from this database
if ($contents = $DB->get_records('data_content', array('recordid'=>$deleterecord->id))) {
foreach ($contents as $content) { // Delete files or whatever else this field allows
if ($field = data_get_field_from_id($content->fieldid, $data)) { // Might not be there
$field->delete_content($content->recordid);
}
}
}
$DB->delete_records('data_content', array('recordid'=>$deleterecord->id));
$DB->delete_records('data_records', array('id'=>$deleterecord->id));

add_to_log($course->id, 'data', 'record delete', "view.php?id=$cm->id", $data->id, $cm->id);

echo $OUTPUT->notification(get_string('recorddeleted','data'), 'notifysuccess');
}
if (data_delete_record($delete, $data, $course->id, $cm->id)) {
echo $OUTPUT->notification(get_string('recorddeleted','data'), 'notifysuccess');
}

} else { // Print a confirmation page
if ($deleterecord = $DB->get_record('data_records', array('id'=>$delete))) { // Need to check this is valid
if ($deleterecord->dataid == $data->id) { // Must be from this database
Expand All @@ -398,9 +386,44 @@
}


// Multi-delete.
if ($serialdelete) {
$multidelete = json_decode($serialdelete);
}

if ($multidelete && confirm_sesskey() && $canmanageentries) {
if ($confirm = optional_param('confirm', 0, PARAM_INT)) {
foreach ($multidelete as $value) {
data_delete_record($value, $data, $course->id, $cm->id);
}
} else {
$validrecords = array();
$recordids = array();
foreach ($multidelete as $value) {
if ($deleterecord = $DB->get_record('data_records', array('id'=>$value))) { // Need to check this is valid
if ($deleterecord->dataid == $data->id) { // Must be from this database
$validrecords[] = $deleterecord;
$recordids[] = $deleterecord->id;
}
}
}

$serialiseddata = json_encode($recordids);
$submitactions = array('d' => $data->id, 'sesskey' => sesskey(), 'confirm' => '1', 'serialdelete' => $serialiseddata);
$action = new moodle_url('/mod/data/view.php', $submitactions);
$cancelurl = new moodle_url('/mod/data/view.php', array('d' => $data->id));
$deletebutton = new single_button($action, get_string('delete'));
echo $OUTPUT->confirm(get_string('confirmdeleterecords', 'data'), $deletebutton, $cancelurl);
echo data_print_template('listtemplate', $validrecords, $data, '', 0, false);
echo $OUTPUT->footer();
exit;
}
}


//if data activity closed dont let students in
$showactivity = true;
if (!has_capability('mod/data:manageentries', $context)) {
if (!$canmanageentries) {
$timenow = time();
if (!empty($data->timeavailablefrom) && $data->timeavailablefrom > $timenow) {
echo $OUTPUT->notification(get_string('notopenyet', 'data', userdate($data->timeavailablefrom)));
Expand All @@ -423,6 +446,9 @@
}
include('tabs.php');

$url = new moodle_url('/mod/data/view.php', array('d' => $data->id, 'sesskey' => sesskey()));
echo html_writer::start_tag('form', array('action' => $url, 'method' => 'post'));

if ($mode == 'asearch') {
$maxcount = 0;

Expand All @@ -446,15 +472,15 @@

$numentries = data_numentries($data);
/// Check the number of entries required against the number of entries already made (doesn't apply to teachers)
if ($data->requiredentries > 0 && $numentries < $data->requiredentries && !has_capability('mod/data:manageentries', $context)) {
if ($data->requiredentries > 0 && $numentries < $data->requiredentries && !$canmanageentries) {
$data->entriesleft = $data->requiredentries - $numentries;
$strentrieslefttoadd = get_string('entrieslefttoadd', 'data', $data);
echo $OUTPUT->notification($strentrieslefttoadd);
}

/// Check the number of entries required before to view other participant's entries against the number of entries already made (doesn't apply to teachers)
$requiredentries_allowed = true;
if ($data->requiredentriestoview > 0 && $numentries < $data->requiredentriestoview && !has_capability('mod/data:manageentries', $context)) {
if ($data->requiredentriestoview > 0 && $numentries < $data->requiredentriestoview && !$canmanageentries) {
$data->entrieslefttoview = $data->requiredentriestoview - $numentries;
$strentrieslefttoaddtoview = get_string('entrieslefttoaddtoview', 'data', $data);
echo $OUTPUT->notification($strentrieslefttoaddtoview);
Expand Down Expand Up @@ -665,7 +691,7 @@
if (!$records = $DB->get_records_sql($sqlselect, $allparams, $page * $nowperpage, $nowperpage)) {
// Nothing to show!
if ($record) { // Something was requested so try to show that at least (bug 5132)
if (has_capability('mod/data:manageentries', $context) || empty($data->approval) ||
if ($canmanageentries || empty($data->approval) ||
$record->approved || (isloggedin() && $record->userid == $USER->id)) {
if (!$currentgroup || $record->groupid == $currentgroup || $record->groupid == 0) {
// OK, we can show this one
Expand Down Expand Up @@ -776,8 +802,20 @@
echo $button->to_html(PORTFOLIO_ADD_FULL_FORM);
}


//Advanced search form doesn't make sense for single (redirects list view)
if (($maxcount || $mode == 'asearch') && $mode != 'single') {
if ($canmanageentries) {
echo html_writer::start_tag('div', array('class' => 'form-buttons'));
echo html_writer::empty_tag('input', array('type' => 'button', 'id' => 'checkall', 'value' => get_string('selectall')));
echo html_writer::empty_tag('input', array('type' => 'button', 'id' => 'checknone', 'value' => get_string('deselectall')));
echo html_writer::empty_tag('input', array('class' => 'form-submit', 'type' => 'submit', 'value' => get_string('deleteselected')));
echo html_writer::end_tag('div');

$module = array('name'=>'mod_data', 'fullpath'=>'/mod/data/module.js');
$PAGE->requires->js_init_call('M.mod_data.init_view', null, false, $module);
}
echo html_writer::end_tag('form');
data_print_preference_form($data, $perpage, $search, $sort, $order, $search_array, $advanced, $mode);
}
}
Expand Down

0 comments on commit f37d532

Please sign in to comment.