|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00018 require_once(dirname(__FILE__).'/../../../config.php'); 00019 require_once($CFG->dirroot.'/lib/formslib.php'); 00020 require_once($CFG->dirroot.'/grade/lib.php'); 00021 require_once($CFG->libdir.'/gradelib.php'); 00022 require_once('import_outcomes_form.php'); 00023 00024 $courseid = optional_param('courseid', 0, PARAM_INT); 00025 $action = optional_param('action', '', PARAM_ALPHA); 00026 $scope = optional_param('scope', 'global', PARAM_ALPHA); 00027 00028 $PAGE->set_url('/grade/edit/outcome/import.php', array('courseid' => $courseid)); 00029 00031 if ($courseid) { 00032 if (!$course = $DB->get_record('course', array('id' => $courseid))) { 00033 print_error('nocourseid'); 00034 } 00035 require_login($course); 00036 $context = get_context_instance(CONTEXT_COURSE, $course->id); 00037 00038 if (empty($CFG->enableoutcomes)) { 00039 redirect('../../index.php?id='.$courseid); 00040 } 00041 00042 } else { 00043 require_once $CFG->libdir.'/adminlib.php'; 00044 admin_externalpage_setup('outcomes'); 00045 $context = get_context_instance(CONTEXT_SYSTEM); 00046 } 00047 00048 require_capability('moodle/grade:manageoutcomes', $context); 00049 00050 $navigation = grade_build_nav(__FILE__, get_string('outcomes', 'grades'), $courseid); 00051 00052 $upload_form = new import_outcomes_form(); 00053 00054 // display import form 00055 if (!$upload_form->get_data()) { 00056 print_grade_page_head($courseid, 'outcome', 'import', get_string('importoutcomes', 'grades')); 00057 $upload_form->display(); 00058 echo $OUTPUT->footer(); 00059 die; 00060 } 00061 print_grade_page_head($courseid, 'outcome', 'import', get_string('importoutcomes', 'grades')); 00062 00063 $imported_file = $CFG->tempdir . '/outcomeimport/importedfile_'.time().'.csv'; 00064 make_temp_directory('outcomeimport'); 00065 00066 // copying imported file 00067 if (!$upload_form->save_file('userfile', $imported_file, true)) { 00068 redirect('import.php'. ($courseid ? "?courseid=$courseid" : ''), get_string('importfilemissing', 'grades')); 00069 } 00070 00072 if (isset($courseid) && ($scope == 'custom')) { 00073 // custom scale 00074 $local_scope = true; 00075 } elseif (($scope == 'global') && has_capability('moodle/grade:manage', get_context_instance(CONTEXT_SYSTEM))) { 00076 // global scale 00077 $local_scope = false; 00078 } else { 00079 // shouldn't happen .. user might be trying to access this script without the right permissions. 00080 redirect('index.php', get_string('importerror', 'grades')); 00081 } 00082 00083 // open the file, start importing data 00084 if ($handle = fopen($imported_file, 'r')) { 00085 $line = 0; // will keep track of current line, to give better error messages. 00086 $file_headers = ''; 00087 00088 // $csv_data needs to have at least these columns, the value is the default position in the data file. 00089 $headers = array('outcome_name' => 0, 'outcome_shortname' => 1, 'scale_name' => 3, 'scale_items' => 4); 00090 $optional_headers = array('outcome_description'=>2, 'scale_description' => 5); 00091 $imported_headers = array(); // will later be initialized with the values found in the file 00092 00093 $fatal_error = false; 00094 00095 // data should be separated by a ';'. *NOT* by a comma! TODO: version 2.0 00096 // 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. 00097 while ( $csv_data = fgetcsv($handle, 8192, ';', '"')) { // if the line is over 8k, it won't work... 00098 $line++; 00099 00100 // be tolerant on input, as fgetcsv returns "an array comprising a single null field" on blank lines 00101 if ($csv_data == array(null)) { 00102 continue; 00103 } 00104 00105 // on first run, grab and analyse the header 00106 if ($file_headers == '') { 00107 00108 $file_headers = array_flip($csv_data); // save the header line ... TODO: use the header line to let import work with columns in arbitrary order 00109 00110 $error = false; 00111 foreach($headers as $key => $value) { 00112 // sanity check #1: make sure the file contains all the mandatory headers 00113 if (!array_key_exists($key, $file_headers)) { 00114 $error = true; 00115 break; 00116 } 00117 } 00118 if ($error) { 00119 echo $OUTPUT->box_start('generalbox importoutcomenofile buttons'); 00120 echo get_string('importoutcomenofile', 'grades', $line); 00121 echo $OUTPUT->single_button(new moodle_url('/grade/edit/outcome/import.php', array('courseid'=> $courseid)), get_string('back'), 'get'); 00122 echo $OUTPUT->box_end(); 00123 $fatal_error = true; 00124 break; 00125 } 00126 00127 foreach(array_merge($headers, $optional_headers) as $header => $position) { 00128 // match given columns to expected columns *into* $headers 00129 $imported_headers[$header] = $file_headers[$header]; 00130 } 00131 00132 continue; // we don't import headers 00133 } 00134 00135 // sanity check #2: every line must have the same number of columns as there are 00136 // headers. If not, processing stops. 00137 if ( count($csv_data) != count($file_headers) ) { 00138 echo $OUTPUT->box_start('generalbox importoutcomenofile'); 00139 echo get_string('importoutcomenofile', 'grades', $line); 00140 echo $OUTPUT->single_button(new moodle_url('/grade/edit/outcome/import.php', array('courseid'=> $courseid)), get_string('back'), 'get'); 00141 echo $OUTPUT->box_end(); 00142 $fatal_error = true; 00143 //echo $OUTPUT->box(var_export($csv_data, true) ."<br />". var_export($header, true)); 00144 break; 00145 } 00146 00147 // sanity check #3: all required fields must be present on the current line. 00148 foreach ($headers as $header => $position) { 00149 if ($csv_data[$imported_headers[$header]] == '') { 00150 echo $OUTPUT->box_start('generalbox importoutcomenofile'); 00151 echo get_string('importoutcomenofile', 'grades', $line); 00152 echo $OUTPUT->single_button(new moodle_url('/grade/edit/outcome/import.php', array('courseid'=> $courseid)), get_string('back'), 'get'); 00153 echo $OUTPUT->box_end(); 00154 $fatal_error = true; 00155 break; 00156 } 00157 } 00158 00159 // MDL-17273 errors in csv are not preventing import from happening. We break from the while loop here 00160 if ($fatal_error) { 00161 break; 00162 } 00163 $params = array($csv_data[$imported_headers['outcome_shortname']]); 00164 $wheresql = 'shortname = ? '; 00165 00166 if ($local_scope) { 00167 $params[] = $courseid; 00168 $wheresql .= ' AND courseid = ?'; 00169 } else { 00170 $wheresql .= ' AND courseid IS NULL'; 00171 } 00172 00173 $outcome = $DB->get_records_select('grade_outcomes', $wheresql, $params); 00174 00175 if ($outcome) { 00176 // already exists, print a message and skip. 00177 echo $OUTPUT->box(get_string('importskippedoutcome', 'grades', $csv_data[$imported_headers['outcome_shortname']])); 00178 continue; 00179 } 00180 00181 // new outcome will be added, search for compatible existing scale... 00182 $params = array($csv_data[$imported_headers['scale_name']], $csv_data[$imported_headers['scale_items']], $courseid); 00183 $wheresql = 'name = ? AND scale = ? AND (courseid = ? OR courseid = 0)'; 00184 $scale = $DB->get_records_select('scale', $wheresql, $params); 00185 00186 if ($scale) { 00187 // already exists in the right scope: use it. 00188 $scale_id = key($scale); 00189 } else { 00190 if (!has_capability('moodle/course:managescales', $context)) { 00191 echo $OUTPUT->box(get_string('importskippednomanagescale', 'grades', $csv_data[$imported_headers['outcome_shortname']])); 00192 continue; 00193 } else { 00194 // scale doesn't exists : create it. 00195 $scale_data = array('name' => $csv_data[$imported_headers['scale_name']], 00196 'scale' => $csv_data[$imported_headers['scale_items']], 00197 'description' => $csv_data[$imported_headers['scale_description']], 00198 'userid' => $USER->id); 00199 00200 if ($local_scope) { 00201 $scale_data['courseid'] = $courseid; 00202 } else { 00203 $scale_data['courseid'] = 0; // 'global' : scale use '0', outcomes use null 00204 } 00205 $scale = new grade_scale($scale_data); 00206 $scale_id = $scale->insert(); 00207 } 00208 } 00209 00210 // add outcome 00211 $outcome_data = array('shortname' => $csv_data[$imported_headers['outcome_shortname']], 00212 'fullname' => $csv_data[$imported_headers['outcome_name']], 00213 'scaleid' => $scale_id, 00214 'description' => $csv_data[$imported_headers['outcome_description']], 00215 'usermodified' => $USER->id); 00216 00217 if ($local_scope) { 00218 $outcome_data['courseid'] = $courseid; 00219 } else { 00220 $outcome_data['courseid'] = null; // 'global' : scale use '0', outcomes use null 00221 } 00222 $outcome = new grade_outcome($outcome_data); 00223 $outcome_id = $outcome->insert(); 00224 00225 $outcome_success_strings = new StdClass(); 00226 $outcome_success_strings->name = $outcome_data['fullname']; 00227 $outcome_success_strings->id = $outcome_id; 00228 echo $OUTPUT->box(get_string('importoutcomesuccess', 'grades', $outcome_success_strings)); 00229 } 00230 } else { 00231 echo $OUTPUT->box(get_string('importoutcomenofile', 'grades', 0)); 00232 } 00233 00234 // finish 00235 fclose($handle); 00236 // delete temp file 00237 unlink($imported_file); 00238 00239 echo $OUTPUT->footer();