MDL-7996 Add ods export support - added ods to course logs with other minor fixes, implemented date support and added missing stub functions for better excel class compatibility

This commit is contained in:
skodak 2006-12-21 10:58:18 +00:00
parent 9c61ba4d88
commit ea49a66cea
4 changed files with 349 additions and 19 deletions

View File

@ -352,13 +352,17 @@ function print_log($course, $user=0, $date=0, $order="l.time ASC", $page=0, $per
exit;
}
$courses = array();
if ($course->id == SITEID) {
$courses[0] = '';
if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname,c.visible')) {
if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
foreach ($ccc as $cc) {
$courses[$cc->id] = $cc->shortname;
}
}
} else {
$courses[$course->id] = $course->shortname;
}
$totalcount = $logs['totalcount'];
@ -457,6 +461,8 @@ function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
return false;
}
$courses = array();
if ($course->id == SITEID) {
$courses[0] = '';
if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
@ -464,6 +470,8 @@ function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
$courses[$cc->id] = $cc->shortname;
}
}
} else {
$courses[$course->id] = $course->shortname;
}
$count=0;
@ -533,6 +541,8 @@ function print_log_xls($course, $user, $date, $order='l.time DESC', $modname,
return false;
}
$courses = array();
if ($course->id == SITEID) {
$courses[0] = '';
if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
@ -540,6 +550,8 @@ function print_log_xls($course, $user, $date, $order='l.time DESC', $modname,
$courses[$cc->id] = $cc->shortname;
}
}
} else {
$courses[$course->id] = $course->shortname;
}
$count=0;
@ -630,6 +642,118 @@ function print_log_xls($course, $user, $date, $order='l.time DESC', $modname,
return true;
}
function print_log_ods($course, $user, $date, $order='l.time DESC', $modname,
$modid, $modaction, $groupid) {
global $CFG;
require_once("$CFG->libdir/odslib.class.php");
if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
$modname, $modid, $modaction, $groupid)) {
return false;
}
$courses = array();
if ($course->id == SITEID) {
$courses[0] = '';
if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
foreach ($ccc as $cc) {
$courses[$cc->id] = $cc->shortname;
}
}
} else {
$courses[$course->id] = $course->shortname;
}
$count=0;
$ldcache = array();
$tt = getdate(time());
$today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
$strftimedatetime = get_string("strftimedatetime");
$nroPages = ceil(count($logs)/(EXCELROWS-FIRSTUSEDEXCELROW+1));
$filename = 'logs_'.userdate(time(),get_string('backupnameformat'),99,false);
$filename .= '.ods';
$workbook = new MoodleODSWorkbook('-');
$workbook->send($filename);
$worksheet = array();
$headers = array(get_string('course'), get_string('time'), get_string('ip_address'),
get_string('fullname'), get_string('action'), get_string('info'));
// Creating worksheets
for ($wsnumber = 1; $wsnumber <= $nroPages; $wsnumber++) {
$sheettitle = get_string('excel_sheettitle', 'logs', $wsnumber).$nroPages;
$worksheet[$wsnumber] =& $workbook->add_worksheet($sheettitle);
$worksheet[$wsnumber]->set_column(1, 1, 30);
$worksheet[$wsnumber]->write_string(0, 0, get_string('savedat').
userdate(time(), $strftimedatetime));
$col = 0;
foreach ($headers as $item) {
$worksheet[$wsnumber]->write(FIRSTUSEDEXCELROW-1,$col,$item,'');
$col++;
}
}
if (empty($logs['logs'])) {
$workbook->close();
return true;
}
$formatDate =& $workbook->add_format();
$formatDate->set_num_format(get_string('log_excel_date_format'));
$row = FIRSTUSEDEXCELROW;
$wsnumber = 1;
$myxls =& $worksheet[$wsnumber];
foreach ($logs['logs'] as $log) {
if (isset($ldcache[$log->module][$log->action])) {
$ld = $ldcache[$log->module][$log->action];
} else {
$ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
$ldcache[$log->module][$log->action] = $ld;
}
if ($ld && !empty($log->info)) {
// ugly hack to make sure fullname is shown correctly
if (($ld->mtable == 'user') and ($ld->field == sql_concat('firstname', "' '" , 'lastname'))) {
$log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
} else {
$log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
}
}
// Filter log->info
$log->info = format_string($log->info);
$log->info = strip_tags(urldecode($log->info)); // Some XSS protection
if ($nroPages>1) {
if ($row > EXCELROWS) {
$wsnumber++;
$myxls =& $worksheet[$wsnumber];
$row = FIRSTUSEDEXCELROW;
}
}
$myxls->write($row, 0, $courses[$log->course], '');
// Excel counts from 1/1/1900
$myxls->write_date($row, 1, $log->time, $formatDate);
$myxls->write($row, 2, $log->ip, '');
$fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
$myxls->write($row, 3, $fullname, '');
$myxls->write($row, 4, $log->module.' '.$log->action, '');
$myxls->write($row, 5, $log->info, '');
$row++;
}
$workbook->close();
return true;
}
/*
// Relies on $CFG->libdir.'/phpdocwriter/lib/include.php', which is not
// included in the default Moodle distribution.

View File

@ -80,6 +80,13 @@
print_footer($course);
}
exit;
case 'downloadasods':
if (!print_log_ods($course, $user, $date, 'l.time DESC', $modname,
$modid, $modaction, $group)) {
notify("No logs found!");
print_footer($course);
}
exit;
case 'downloadasexcel':
if (!print_log_xls($course, $user, $date, 'l.time DESC', $modname,
$modid, $modaction, $group)) {
@ -87,15 +94,6 @@
print_footer($course);
}
exit;
/*
case 'downloadasooo':
if (!print_log_ooo($course, $user, $date, 'l.time DESC', $modname,
$modid, $modaction, $group)) {
notify("No logs found!");
print_footer($course);
}
exit;
*/
}

View File

@ -206,13 +206,8 @@ function print_log_selector_form($course, $selecteduser=0, $selecteddate='today'
$logformats = array('showashtml' => get_string('displayonpage'),
'downloadascsv' => get_string('downloadtext'),
'downloadasods' => get_string('downloadods'),
'downloadasexcel' => get_string('downloadexcel'));
/*
$logformats = array('showashtml' => get_string('displayonpage'),
'downloadascsv' => get_string('downloadtext'),
'downloadasexcel' => get_string('downloadexcel'),
'downloadasooo' => get_string('downloadasooo'));
*/
choose_from_menu ($logformats, 'logformat', $logformat, false);
echo '<input type="submit" value="'.get_string('gettheselogs').'" />';
echo "</form>";

View File

@ -48,6 +48,17 @@ class MoodleODSWorkbook {
return $ws;
}
/* Create one Moodle Format
* @param array $properties array of properties [name]=value;
* valid names are set_XXXX existing
* functions without the set_ part
* i.e: [bold]=1 for set_bold(1)...Optional!
*/
function &add_format($properties = array()) {
$format = new MoodleODSFormat($this);
return $format;;
}
/* Close the Moodle Workbook
*/
function close() {
@ -126,6 +137,7 @@ class MoodleODSWorksheet {
$this->data[$row][$col] = new object();
$this->data[$row][$col]->value = $str;
$this->data[$row][$col]->type = 'string';
$this->data[$row][$col]->format = $format;
}
/* Write one number somewhere in the worksheet
@ -141,6 +153,7 @@ class MoodleODSWorksheet {
$this->data[$row][$col] = new object();
$this->data[$row][$col]->value = $num;
$this->data[$row][$col]->type = 'float';
$this->data[$row][$col]->format = $format;
}
/* Write one url somewhere in the worksheet
@ -156,6 +169,23 @@ class MoodleODSWorksheet {
$this->data[$row][$col] = new object();
$this->data[$row][$col]->value = $url;
$this->data[$row][$col]->type = 'string';
$this->data[$row][$col]->format = $format;
}
/* Write one date 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_date($row, $col, $date, $format=0) {
if (!array_key_exists($row, $this->data)) {
$this->data[$row] = array();
}
$this->data[$row][$col] = new object();
$this->data[$row][$col]->value = $date;
$this->data[$row][$col]->type = 'date';
$this->data[$row][$col]->format = $format;
}
/* Write one blanck somewhere in the worksheet
@ -205,8 +235,182 @@ class MoodleODSWorksheet {
return $this->write_string($row, $col, $token, $format);
}
}
/* Sets the height (and other settings) of one row
* @param integer $row The row to set
* @param integer $height Height we are giving to the row (null to set just format withouth setting the height)
* @param mixed $format The optional XF format we are giving to the row
* @param bool $hidden The optional hidden attribute
* @param integer $level The optional outline level (0-7)
*/
function set_row ($row, $height, $format = 0, $hidden = false, $level = 0) {
//not defined yet
}
/* Sets the width (and other settings) of one column
* @param integer $firstcol first column on the range
* @param integer $lastcol last column on the range
* @param integer $width width to set
* @param mixed $format The optional XF format to apply to the columns
* @param integer $hidden The optional hidden atribute
* @param integer $level The optional outline level (0-7)
*/
function set_column ($firstcol, $lastcol, $width, $format = 0, $hidden = false, $level = 0) {
//not defined yet
}
}
/**
* Define and operate over one Format.
*
* A big part of this class acts as a wrapper over the PEAR
* Spreadsheet_Excel_Writer_Workbook and OLE libraries
* maintaining Moodle functions isolated from underlying code.
*/
class MoodleODSFormat {
/* Constructs one Moodle Format.
* @param object $workbook The internal PEAR Workbook onject we are creating
*/
function MoodleODSFormat(&$workbook, $properties = array()) {
}
/* Set weight of the format
* @param integer $weight Weight for the text, 0 maps to 400 (normal text),
* 1 maps to 700 (bold text). Valid range is: 100-1000.
* It's Optional, default is 1 (bold).
*/
function set_bold($weight = 1) {
}
/* Set underline of the format
* @param integer $underline The value for underline. Possible values are:
* 1 => underline, 2 => double underline
*/
function set_underline($underline) {
}
/* Set italic of the format
*/
function set_italic() {
}
/* Set strikeout of the format
*/
function set_strikeout() {
}
/* Set outlining of the format
*/
function set_outline() {
}
/* Set shadow of the format
*/
function set_shadow() {
}
/* Set the script of the text
* @param integer $script The value for script type. Possible values are:
* 1 => superscript, 2 => subscript
*/
function set_script($script) {
}
/* Set color of the format
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63])
*/
function set_color($color) {
}
/* Set foreground color of the format
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63])
*/
function set_fg_color($color) {
}
/* Set background color of the format
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63])
*/
function set_bg_color($color) {
}
/* Set the fill pattern of the format
* @param integer Optional. Defaults to 1. Meaningful values are: 0-18
* 0 meaning no background.
*/
function set_pattern($pattern=1) {
}
/* Set text wrap of the format
*/
function set_text_wrap() {
}
/* Set the cell alignment of the format
* @param string $location alignment for the cell ('left', 'right', etc...)
*/
function set_align($location) {
}
/* Set the cell horizontal alignment of the format
* @param string $location alignment for the cell ('left', 'right', etc...)
*/
function set_h_align($location) {
}
/* Set the cell vertical alignment of the format
* @param string $location alignment for the cell ('top', 'vleft', etc...)
*/
function set_v_align($location) {
}
/* Set the top border of the format
* @param integer $style style for the cell. 1 => thin, 2 => thick
*/
function set_top($style) {
}
/* Set the bottom border of the format
* @param integer $style style for the cell. 1 => thin, 2 => thick
*/
function set_bottom($style) {
}
/* Set the left border of the format
* @param integer $style style for the cell. 1 => thin, 2 => thick
*/
function set_left($style) {
}
/* Set the right border of the format
* @param integer $style style for the cell. 1 => thin, 2 => thick
*/
function set_right($style) {
}
/**
* Set cells borders to the same style
* @param integer $style style to apply for all cell borders. 1 => thin, 2 => thick.
*/
function set_border($style) {
}
/* Set the numerical format of the format
* It can be date, time, currency, etc...
/* Set the numerical format of the format
* It can be date, time, currency, etc...
* @param integer $num_format The numeric format
*/
function set_num_format($num_format) {
}
}
//=============================
// OpenDocument XML functions
//=============================
function get_ods_content(&$worksheets) {
/// header
@ -217,6 +421,7 @@ function get_ods_content(&$worksheets) {
. 'xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" '
. 'xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" '
. 'xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" office:version="1.0">'
. 'xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"'
. '<office:body>'
. '<office:spreadsheet>';
@ -241,9 +446,15 @@ function get_ods_content(&$worksheets) {
$buffer .= '<table:table-row>';
for($c=0; $c<=$nc; $c++) {
if (isset($ws->data[$r][$c])) {
$buffer .= '<table:table-cell office:value-type="' . $ws->data[$r][$c]->type . '">'
. '<text:p>' . htmlspecialchars($ws->data[$r][$c]->value) . '</text:p>'
. '</table:table-cell>';
if ($ws->data[$r][$c]->type == 'date') {
$buffer .= '<table:table-cell office:value-type="date" table:style-name="Default" office:date-value="' . strftime('%Y-%m-%dT%H:%M:%S', $ws->data[$r][$c]->value) . '">'
. '<text:p>' . htmlspecialchars($ws->data[$r][$c]->value) . '</text:p>'
. '</table:table-cell>';
} else {
$buffer .= '<table:table-cell office:value-type="' . $ws->data[$r][$c]->type . '">'
. '<text:p>' . htmlspecialchars($ws->data[$r][$c]->value) . '</text:p>'
. '</table:table-cell>';
}
} else {
$buffer .= '<table:table-cell/>';
}
@ -289,6 +500,7 @@ function get_ods_styles() {
. 'xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" '
. 'xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" '
. 'xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" office:version="1.0">'
. 'xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"'
. '<office:font-face-decls>'
. '<style:font-face style:name="Arial Unicode MS" svg:font-family="\'Arial Unicode MS\'" style:font-pitch="variable"/>'
. '<style:font-face style:name="DejaVu Sans1" svg:font-family="\'DejaVu Sans\'" style:font-pitch="variable"/>'
@ -298,6 +510,7 @@ function get_ods_styles() {
. '<style:font-face style:name="DejaVu Sans" svg:font-family="\'DejaVu Sans\'" style:font-family-generic="swiss" style:font-pitch="variable"/>'
. '</office:font-face-decls>'
. '<office:styles>'
. '<style:style style:name="Default" style:family="table-cell" />'
. '<style:default-style style:family="paragraph">'
. '<style:paragraph-properties fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="0.4925in" style:writing-mode="page"/>'
. '<style:text-properties style:use-window-font-color="true" style:font-name="DejaVu Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:font-name-asian="DejaVu Sans1" style:font-size-asian="12pt" style:language-asian="none" style:country-asian="none" style:font-name-complex="DejaVu Sans1" style:font-size-complex="12pt" style:language-complex="none" style:country-complex="none" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/>'