Skip to content
Permalink
Browse files

Merge from 19_STABLE for MDL-10639.

  • Loading branch information...
scyrma
scyrma committed Feb 5, 2008
1 parent 94b7cd3 commit ee285a20be7ad4b55c13d52a53b6352e74cf315e
Showing with 421 additions and 9 deletions.
  1. +106 −0 grade/edit/outcome/export.php
  2. +250 −0 grade/edit/outcome/import.php
  3. +55 −9 grade/edit/outcome/index.php
  4. +10 −0 lang/en_utf8/grades.php
@@ -0,0 +1,106 @@
<?php // $Id$
// Exports selected outcomes in CSV format.
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->libdir.'/gradelib.php';
$courseid = optional_param('id', 0, PARAM_INT);
$action = optional_param('action', '', PARAM_ALPHA);
$export = required_param('export', PARAM_INT);
/// Make sure they can even access this course
if ($courseid) {
if (!$course = get_record('course', 'id', $courseid)) {
print_error('nocourseid');
}
require_login($course);
$context = get_context_instance(CONTEXT_COURSE, $course->id);
require_capability('moodle/grade:manage', $context);
if (empty($CFG->enableoutcomes)) {
redirect('../../index.php?id='.$courseid);
}
} else {
require_once $CFG->libdir.'/adminlib.php';
admin_externalpage_setup('outcomes');
}
if (!confirm_sesskey()) {
break;
}
// $outcome = grade_outcome::fetch(array('id'=>$outcomeid));
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
header("Content-Type: text/csv; charset=utf-8");
// TODO: make the filename more useful, include a date, a specific name, something...
header('Content-Disposition: attachment; filename=outcomes.csv');
// sending header with clear names, to make 'what is what' as easy as possible to understand
$header = array('outcome_name', 'outcome_shortname', 'outcome_description', 'scale_name', 'scale_items', 'scale_description');
echo format_csv($header, ';', '"');
foreach($export as $outcome_id) {
$outcome = grade_outcome::fetch(array('id' => $outcome_id));
$line = array();
$line[] = $outcome->get_name();
$line[] = $outcome->get_shortname();
$line[] = $outcome->description;
$scale = $outcome->load_scale();
$line[] = $scale->get_name();
$line[] = $scale->compact_items();
$line[] = $scale->description;
echo format_csv($line, ';', '"');
}
/**
* Formats and returns a line of data, in CSV format. This code
* is from http://au2.php.net/manual/en/function.fputcsv.php#77866
*
* @params array-of-string $fields data to be exported
* @params char $delimiter char to be used to separate fields
* @params char $enclosure char used to enclose strings that contains newlines, spaces, tabs or the delimiter char itself
* @returns string one line of csv data
*/
function format_csv($fields = array(), $delimiter = ';', $enclosure = '"') {
$str = '';
$escape_char = '\\';
foreach ($fields as $value) {
if (strpos($value, $delimiter) !== false ||
strpos($value, $enclosure) !== false ||
strpos($value, "\n") !== false ||
strpos($value, "\r") !== false ||
strpos($value, "\t") !== false ||
strpos($value, ' ') !== false) {
$str2 = $enclosure;
$escaped = 0;
$len = strlen($value);
for ($i=0;$i<$len;$i++) {
if ($value[$i] == $escape_char) {
$escaped = 1;
} else if (!$escaped && $value[$i] == $enclosure) {
$str2 .= $enclosure;
} else {
$escaped = 0;
}
$str2 .= $value[$i];
}
$str2 .= $enclosure;
$str .= $str2.$delimiter;
} else {
$str .= $value.$delimiter;
}
}
$str = substr($str,0,-1);
$str .= "\n";
return $str;
}
@@ -0,0 +1,250 @@
<?php // $Id$
// Allows a user to import outcomes (and associated scales)
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
// //
// This program 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 2 of the License, or //
// (at your option) any later version. //
// //
// This program 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: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->libdir.'/gradelib.php';
$courseid = optional_param('id', 0, PARAM_INT);
$action = optional_param('action', '', PARAM_ALPHA);
$scope = optional_param('scope', 'global', PARAM_ALPHA);
/// Make sure they can even access this course
if ($courseid) {
if (!$course = get_record('course', 'id', $courseid)) {
print_error('nocourseid');
}
require_login($course);
$context = get_context_instance(CONTEXT_COURSE, $course->id);
if (empty($CFG->enableoutcomes)) {
redirect('../../index.php?id='.$courseid);
}
} else {
require_once $CFG->libdir.'/adminlib.php';
admin_externalpage_setup('outcomes');
$context = get_context_instance(CONTEXT_SYSTEM);
}
require_capability('moodle/grade:manageoutcomes', $context);
$strgrades = get_string('grades');
$pagename = get_string('outcomes', 'grades');
$navigation = grade_build_nav(__FILE__, $pagename, $courseid);
$strshortname = get_string('shortname');
$strfullname = get_string('fullname');
$strscale = get_string('scale');
$strstandardoutcome = get_string('outcomesstandard', 'grades');
$strcustomoutcomes = get_string('outcomescustom', 'grades');
$strdelete = get_string('delete');
$stredit = get_string('edit');
$srtcreatenewoutcome = get_string('outcomecreate', 'grades');
$stritems = get_string('items', 'grades');
$strcourses = get_string('courses');
$stredit = get_string('edit');
$strexport = get_string('export', 'grades');
if (!confirm_sesskey()) {
break;
}
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
$caneditsystemscales = has_capability('moodle/course:managescales', $systemcontext);
if ($courseid) {
/// Print header
print_header_simple($strgrades.': '.$pagename, ': '.$strgrades, $navigation, '', '', true, '', navmenu($course));
/// Print the plugin selector at the top
print_grade_plugin_selector($courseid, 'edit', 'outcome');
$caneditcoursescales = has_capability('moodle/course:managescales', $context);
$currenttab = 'outcomes';
require('tabs.php');
} else {
admin_externalpage_print_header();
$caneditcoursescales = $caneditsystemscales;
}
if ($_FILES['userfile']['size'] == 0) {
redirect('index.php'. ($courseid ? "?id=$courseid" : ''), get_string('importfilemissing', 'grades'));
}
/// which scope are we importing the outcomes in?
if (isset($courseid) && ($scope == 'local')) {
// custom scale
$local_scope = true;
} elseif (($scope == 'global') && has_capability('moodle/grade:manage', get_context_instance(CONTEXT_SYSTEM))) {
// global scale
$local_scope = false;
} else {
// shouldn't happen .. user might be trying to access this script without the right permissions.
redirect('index.php', get_string('importerror', 'grades'));
}
// open the file, start importing data
if ($handle = fopen($_FILES['userfile']['tmp_name'], 'r')) {
$line = 0; // will keep track of current line, to give better error messages.
$file_headers = '';
// $csv_data needs to have at least these columns, the value is the default position in the data file.
$headers = array('outcome_name' => 0, 'outcome_shortname' => 1, 'scale_name' => 3, 'scale_items' => 4);
$optional_headers = array('outcome_description'=>2, 'scale_description' => 5);
$imported_headers = array(); // will later be initialized with the values found in the file
// data should be separated by a ';'. *NOT* by a comma! TODO: version 2.0
// or whenever we can depend on PHP5, set the second parameter (8192) to 0 (unlimited line length) : the database can store over 128k per line.
while ( $csv_data = fgetcsv($handle, 8192, ';', '"')) { // if the line is over 8k, it won't work...
$line++;
// be tolerant on input, as fgetcsv returns "an array comprising a single null field" on blank lines
if ($csv_data == array(null)) {
continue;
}
// on first run, grab and analyse the header
if ($file_headers == '') {
$file_headers = array_flip($csv_data); // save the header line ... TODO: use the header line to let import work with columns in arbitrary order
$error = false;
foreach($headers as $key => $value) {
// sanity check #1: make sure the file contains all the mandatory headers
if (!array_key_exists($key, $file_headers)) {
$error = true;
break;
}
}
if ($error) {
print_box(get_string('importoutcomenofile', 'grades', $line));
break;
}
foreach(array_merge($headers, $optional_headers) as $header => $position) {
// match given columns to expected columns *into* $headers
$imported_headers[$header] = $file_headers[$header];
}
continue; // we don't import headers
}
// sanity check #2: every line must have the same number of columns as there are
// headers. If not, processing stops.
if ( count($csv_data) != count($file_headers) ) {
print_box(get_string('importoutcomenofile', 'grades', $line));
//print_box(var_export($csv_data, true) ."<br />". var_export($header, true));
break;
}
// sanity check #3: all required fields must be present on the current line.
foreach ($headers as $header => $position) {
if ($csv_data[$imported_headers[$header]] == '') {
print_box(get_string('importoutcomenofile', 'grades', $line));
break;
}
}
//var_dump($csv_data);
//$db->debug = 3498723498237; // .. very large randomly-typed random value
if ($local_scope) {
$outcome = get_records_select('grade_outcomes', 'shortname = "'. $csv_data[$imported_headers['outcome_shortname']] .'" and courseid = '. $courseid );
} else {
$outcome = get_records_select('grade_outcomes', 'shortname = "'. $csv_data[$imported_headers['outcome_shortname']] .'" and courseid is null');
}
//var_export($outcome);
if ($outcome) {
// already exists, print a message and skip.
print_box(get_string('importskippedoutcome', 'grades', $csv_data[$imported_headers['outcome_shortname']]));
continue;
}
// new outcome will be added, search for compatible existing scale...
$scale = get_records_select('scale', 'name ="'. $csv_data[$imported_headers['scale_name']] .'" and scale ="'. $csv_data[$imported_headers['scale_items']] .'" and (courseid = '. $courseid .' or courseid = 0)');
if ($scale) {
// already exists in the right scope: use it.
$scale_id = key($scale);
} else {
if (!has_capability('moodle/course:managescales', $context)) {
print_box(get_string('importskippednomanagescale', 'grades', $csv_data[$imported_headers['outcome_shortname']]));
continue;
} else {
// scale doesn't exists : create it.
$scale_data = array('name' => $csv_data[$imported_headers['scale_name']],
'scale' => $csv_data[$imported_headers['scale_items']],
'description' => $csv_data[$imported_headers['scale_description']],
'userid' => $USER->id);
if ($local_scope) {
$scale_data['courseid'] = $courseid;
} else {
$scale_data['courseid'] = 0; // 'global' : scale use '0', outcomes use null
}
$scale = new grade_scale($scale_data);
$scale_id = $scale->insert();
}
}
// add outcome
$outcome_data = array('shortname' => $csv_data[$imported_headers['outcome_shortname']],
'fullname' => $csv_data[$imported_headers['outcome_name']],
'scaleid' => $scale_id,
'description' => $csv_data[$imported_headers['outcome_description']],
'usermodified' => $USER->id);
if ($local_scope) {
$outcome_data['courseid'] = $courseid;
} else {
$outcome_data['courseid'] = null; // 'global' : scale use '0', outcomes use null
}
$outcome = new grade_outcome($outcome_data);
$outcome_id = $outcome->insert();
$outcome_success_strings = new StdClass();
$outcome_success_strings->name = $outcome_data['fullname'];
$outcome_success_strings->id = $outcome_id;
print_box(get_string('importoutcomesuccess', 'grades', $outcome_success_strings));
}
} else {
print_box(get_string('importoutcomenofile', 'grades', 0));
}
// finish
fclose($handle);
if ($courseid) {
print_footer($course);
} else {
admin_externalpage_print_footer();
}
?>

0 comments on commit ee285a2

Please sign in to comment.
You can’t perform that action at this time.