forked from moodle/moodle
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdataformat.php
171 lines (143 loc) · 5.74 KB
/
dataformat.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<?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/>.
/**
* Class containing utility methods for dataformats
*
* @package core
* @copyright 2020 Paul Holden <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core;
use coding_exception;
use core\dataformat\base;
use core_php_time_limit;
use stored_file;
/**
* Dataformat utility class
*
* @package core
* @copyright 2020 Paul Holden <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class dataformat {
/**
* Return an instance of a dataformat writer from given dataformat type
*
* @param string $dataformat
* @return base
*
* @throws coding_exception For unknown dataformat
*/
public static function get_format_instance(string $dataformat): base {
$classname = 'dataformat_' . $dataformat . '\writer';
if (!class_exists($classname)) {
throw new coding_exception('Invalid dataformat', $dataformat);
}
return new $classname();
}
/**
* Sends a formatted data file to the browser
*
* @param string $filename
* @param string $dataformat
* @param array $columns
* @param Iterable $iterator
* @param callable|null $callback Optional callback method to apply to each record prior to writing, which accepts two
* parameters as such: function($record, bool $supportshtml) returning formatted record
* @throws coding_exception
*/
public static function download_data(string $filename, string $dataformat, array $columns, Iterable $iterator,
callable $callback = null): void {
if (ob_get_length()) {
throw new coding_exception('Output can not be buffered before calling download_data()');
}
$format = self::get_format_instance($dataformat);
// The data format export could take a while to generate.
core_php_time_limit::raise();
// Close the session so that the users other tabs in the same session are not blocked.
\core\session\manager::write_close();
// If this file was requested from a form, then mark download as complete (before sending headers).
\core_form\util::form_download_complete();
$format->set_filename($filename);
$format->send_http_headers();
$format->start_output();
$format->start_sheet($columns);
$rownum = 0;
foreach ($iterator as $row) {
if (is_callable($callback)) {
$row = $callback($row, $format->supports_html());
}
if ($row === null) {
continue;
}
$format->write_record($row, $rownum++);
}
$format->close_sheet($columns);
$format->close_output();
}
/**
* Writes a formatted data file with specified filename
*
* @param string $filename
* @param string $dataformat
* @param array $columns
* @param Iterable $iterator
* @param callable|null $callback
* @return string Complete path to the file on disk
*/
public static function write_data(string $filename, string $dataformat, array $columns, Iterable $iterator,
callable $callback = null): string {
$format = self::get_format_instance($dataformat);
// The data format export could take a while to generate.
core_php_time_limit::raise();
// Close the session so that the users other tabs in the same session are not blocked.
\core\session\manager::write_close();
$filepath = make_request_directory() . '/' . $filename . $format->get_extension();
$format->set_filepath($filepath);
$format->start_output_to_file();
$format->start_sheet($columns);
$rownum = 0;
foreach ($iterator as $row) {
if (is_callable($callback)) {
$row = $callback($row, $format->supports_html());
}
if ($row === null) {
continue;
}
$format->write_record($row, $rownum++);
}
$format->close_sheet($columns);
$format->close_output_to_file();
return $filepath;
}
/**
* Writes a formatted data file to file storage
*
* @param array $filerecord File record for storage, 'filename' extension should be omitted as it's added by the dataformat
* @param string $dataformat
* @param array $columns
* @param Iterable $iterator Iterable set of records to write
* @param callable|null $callback Optional callback method to apply to each record prior to writing
* @return stored_file
*/
public static function write_data_to_filearea(array $filerecord, string $dataformat, array $columns, Iterable $iterator,
callable $callback = null): stored_file {
$filepath = self::write_data($filerecord['filename'], $dataformat, $columns, $iterator, $callback);
// Update filename of returned file record.
$filerecord['filename'] = basename($filepath);
return get_file_storage()->create_file_from_pathname($filerecord, $filepath);
}
}