From 9c61ba4d88d7eb01b1e851c49f33136209ba14c8 Mon Sep 17 00:00:00 2001 From: skodak Date: Thu, 21 Dec 2006 08:12:10 +0000 Subject: [PATCH] MDL-7996 Add ods export support --- grade/index.php | 3 + grade/lib.php | 70 +++++++- lang/en_utf8/moodle.php | 1 + lib/odslib.class.php | 345 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 417 insertions(+), 2 deletions(-) create mode 100644 lib/odslib.class.php diff --git a/grade/index.php b/grade/index.php index 13b5e27aaa..5d6e798a6c 100644 --- a/grade/index.php +++ b/grade/index.php @@ -37,6 +37,9 @@ if ($action == 'stats') { grade_stats(); exit(); + } else if ($action == 'ods') { + grade_download('ods', $id); + exit(); } else if ($action == 'excel') { grade_download('xls', $id); exit(); diff --git a/grade/lib.php b/grade/lib.php index 9f81bd9f0b..d862d72223 100644 --- a/grade/lib.php +++ b/grade/lib.php @@ -1290,7 +1290,67 @@ function grade_download($download, $id) { } // a new Moodle nesting record? ;-) /// OK, we have all the data, now present it to the user - if ($download == "xls" and confirm_sesskey()) { +/// OK, we have all the data, now present it to the user + if ($download == "ods" and confirm_sesskey()) { + require_once("../lib/odslib.class.php"); + + /// Calculate file name + $downloadfilename = clean_filename("$course->shortname $strgrades.ods"); + /// Creating a workbook + $workbook = new MoodleODSWorkbook("-"); + /// Sending HTTP headers + $workbook->send($downloadfilename); + /// Adding the worksheet + $myxls =& $workbook->add_worksheet($strgrades); + + /// Print names of all the fields + $myxls->write_string(0,0,get_string("firstname")); + $myxls->write_string(0,1,get_string("lastname")); + $myxls->write_string(0,2,get_string("idnumber")); + $myxls->write_string(0,3,get_string("institution")); + $myxls->write_string(0,4,get_string("department")); + $myxls->write_string(0,5,get_string("email")); + $pos=6; + foreach ($columns as $column) { + $myxls->write_string(0,$pos++,strip_tags($column)); + } + $myxls->write_string(0,$pos,get_string("total")); + + /// Print all the lines of data. + $i = 0; + if (!empty($grades)) { + foreach ($grades as $studentid => $studentgrades) { + $i++; + $student = $students[$studentid]; + if (empty($totals[$student->id])) { + $totals[$student->id] = ''; + } + + $myxls->write_string($i,0,$student->firstname); + $myxls->write_string($i,1,$student->lastname); + $myxls->write_string($i,2,$student->idnumber); + $myxls->write_string($i,3,$student->institution); + $myxls->write_string($i,4,$student->department); + $myxls->write_string($i,5,$student->email); + $j=6; + foreach ($studentgrades as $grade) { + if (is_numeric($grade)) { + $myxls->write_number($i,$j++,strip_tags($grade)); + } + else { + $myxls->write_string($i,$j++,strip_tags($grade)); + } + } + $myxls->write_number($i,$j,$totals[$student->id]); + } + } + + /// Close the workbook + $workbook->close(); + + exit; + + } else if ($download == "xls" and confirm_sesskey()) { require_once("../lib/excellib.class.php"); /// Calculate file name @@ -2893,7 +2953,7 @@ function grade_set_letter_grades() { function grade_download_form($type='both') { global $course,$USER, $action, $cview; - if ($type != 'both' and $type != 'excel' and $type != 'text') { + if ($type != 'both' and $type != 'ods' and $type != 'excel' and $type != 'text') { $type = 'both'; } @@ -2902,6 +2962,12 @@ function grade_download_form($type='both') { $options['id'] = $course->id; $options['sesskey'] = $USER->sesskey; + if ($type == 'both' || $type == 'ods') { + $options['action'] = 'ods'; + echo ''; + print_single_button("index.php", $options, get_string("downloadods")); + echo ''; + } if ($type == 'both' || $type == 'excel') { $options['action'] = 'excel'; echo ''; diff --git a/lang/en_utf8/moodle.php b/lang/en_utf8/moodle.php index a75c455290..047d5a3bc5 100644 --- a/lang/en_utf8/moodle.php +++ b/lang/en_utf8/moodle.php @@ -375,6 +375,7 @@ $string['documentation'] = 'Moodle Documentation'; $string['donotask'] = 'Do Not Ask'; $string['down'] = 'Down'; $string['downloadexcel'] = 'Download in Excel format'; +$string['downloadods'] = 'Download in ODS format'; $string['downloadtext'] = 'Download in text format'; $string['doyouagree'] = 'Have you read these conditions and understood them?'; $string['duplicate'] = 'Duplicate'; diff --git a/lib/odslib.class.php b/lib/odslib.class.php new file mode 100644 index 0000000000..6ebc8f8721 --- /dev/null +++ b/lib/odslib.class.php @@ -0,0 +1,345 @@ +filename = $filename; + } + + /* Create one Moodle Worksheet + * @param string $name Name of the sheet + */ + function &add_worksheet($name = '') { + /// Create the Moodle Worksheet. Returns one pointer to it + $ws =& new MoodleODSWorksheet($name); + $this->worksheets[] =& $ws; + return $ws; + } + + /* Close the Moodle Workbook + */ + function close() { + global $CFG; + require_once($CFG->libdir.'/filelib.php'); + + $dir = 'temp/ods/'.time(); + make_upload_directory($dir, false); + make_upload_directory($dir.'/META-INF', false); + $dir = "$CFG->dataroot/$dir"; + $files = array(); + + $handle = fopen("$dir/mimetype", 'w'); + fwrite($handle, get_ods_mimetype()); + $files[] = "$dir/mimetype"; + + $handle = fopen("$dir/content.xml", 'w'); + fwrite($handle, get_ods_content($this->worksheets)); + $files[] = "$dir/content.xml"; + + $handle = fopen("$dir/meta.xml", 'w'); + fwrite($handle, get_ods_meta()); + $files[] = "$dir/meta.xml"; + + $handle = fopen("$dir/styles.xml", 'w'); + fwrite($handle, get_ods_styles()); + $files[] = "$dir/styles.xml"; + + $handle = fopen("$dir/META-INF/manifest.xml", 'w'); + fwrite($handle, get_ods_manifest()); + $files[] = "$dir/META-INF"; + + $filename = "$dir/result.ods"; + zip_files($files, $filename); + + $handle = fopen($filename, 'rb'); + $contents = fread($handle, filesize($filename)); + fclose($handle); + + remove_dir($dir); // cleanup the temp directory + + send_file($contents, $this->filename, 0, 0, true, true, 'application/vnd.oasis.opendocument.spreadsheet'); + } + + /* Not required to use + * @param string $name Name of the downloaded file + */ + function send($filename) { + $this->filename = $filename; + } + +} + +class MoodleODSWorksheet { + var $data = array(); + var $name; + + + /* Constructs one Moodle Worksheet. + * @param string $filename The name of the file + */ + function ODSWorksheet($name) { + $this->name = $name; + } + + /* Write one string somewhere in the worksheet + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $str The string to write + * @param mixed $format The XF format for the cell + */ + function write_string($row, $col, $str, $format=0) { + if (!array_key_exists($row, $this->data)) { + $this->data[$row] = array(); + } + $this->data[$row][$col] = new object(); + $this->data[$row][$col]->value = $str; + $this->data[$row][$col]->type = 'string'; + } + + /* Write one number somewhere in the worksheet + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param float $num The number to write + * @param mixed $format The XF format for the cell + */ + function write_number($row, $col, $num, $format=0) { + if (!array_key_exists($row, $this->data)) { + $this->data[$row] = array(); + } + $this->data[$row][$col] = new object(); + $this->data[$row][$col]->value = $num; + $this->data[$row][$col]->type = 'float'; + } + + /* Write one url somewhere in the worksheet + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $url The url to write + * @param mixed $format The XF format for the cell + */ + function write_url($row, $col, $url, $format=0) { + if (!array_key_exists($row, $this->data)) { + $this->data[$row] = array(); + } + $this->data[$row][$col] = new object(); + $this->data[$row][$col]->value = $url; + $this->data[$row][$col]->type = 'string'; + } + + /* Write one blanck somewhere in the worksheet + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param mixed $format The XF format for the cell + */ + function write_blank($row, $col, $format=0) { + if (array_key_exists($row, $this->data)) { + unset($this->data[$row][$col]); + } + } + + /* Write anything somewhere in the worksheet + * Type will be automatically detected + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param mixed $token What we are writing + * @param mixed $format The XF format for the cell + */ + function write($row, $col, $token, $format=0) { + + /// Analyse what are we trying to send + if (preg_match("/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/", $token)) { + /// Match number + return $this->write_number($row, $col, $token, $format); + } elseif (preg_match("/^[fh]tt?p:\/\//", $token)) { + /// Match http or ftp URL + return $this->write_url($row, $col, $token, '', $format); + } elseif (preg_match("/^mailto:/", $token)) { + /// Match mailto: + return $this->write_url($row, $col, $token, '', $format); + } elseif (preg_match("/^(?:in|ex)ternal:/", $token)) { + /// Match internal or external sheet link + return $this->write_url($row, $col, $token, '', $format); + } elseif (preg_match("/^=/", $token)) { + /// Match formula + return $this->write_formula($row, $col, $token, $format); + } elseif (preg_match("/^@/", $token)) { + /// Match formula + return $this->write_formula($row, $col, $token, $format); + } elseif ($token == '') { + /// Match blank + return $this->write_blank($row, $col, $format); + } else { + /// Default: match string + return $this->write_string($row, $col, $token, $format); + } + } +} + +function get_ods_content(&$worksheets) { + +/// header + $buffer = + '' + . '' + . '' + . ''; + + foreach($worksheets as $ws) { + /// worksheet header + $buffer .= ''; + + $nr = 0; + $nc = 0; + foreach($ws->data as $rkey=>$row) { + if ($rkey > $nr) { + $nr = $rkey; + } + foreach($row as $ckey=>$col) { + if ($ckey > $nc) { + $nc = $ckey; + } + } + } + + for($r=0; $r<=$nr; $r++) { + $buffer .= ''; + for($c=0; $c<=$nc; $c++) { + if (isset($ws->data[$r][$c])) { + $buffer .= '' + . '' . htmlspecialchars($ws->data[$r][$c]->value) . '' + . ''; + } else { + $buffer .= ''; + } + } + $buffer .= ''; + } + /// worksheet footer + $buffer .= ''; + + } + +/// footer + $buffer .= ''; + + return $buffer; +} + +function get_ods_mimetype() { + return 'application/vnd.oasis.opendocument.spreadsheet'; +} + +function get_ods_meta() { + global $CFG; + return + '' + . '' + . '' + . 'Moodle ' . $CFG->version. '' + . 'Moodle ' . $CFG->version . '' + . '' . strftime('%Y-%m-%dT%H:%M:%S') . '' + . '' + . ''; +} + +function get_ods_styles() { + return + '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . ''; +} + +function get_ods_manifest() { + return + '' + . '' + . '' + . '' + . '' + . '' + . ''; +} +?> \ No newline at end of file -- 2.39.5