9fb443b320061a5dd5a7510851337d581e3bd667
[moodle.git] / lib / classes / dataformat / base.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Base class for dataformat.
19  *
20  * @package    core
21  * @subpackage dataformat
22  * @copyright  2016 Brendan Heywood (brendan@catalyst-au.net)
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 namespace core\dataformat;
28 use coding_exception;
30 /**
31  * Base class for dataformat.
32  *
33  * @package    core
34  * @subpackage dataformat
35  * @copyright  2016 Brendan Heywood (brendan@catalyst-au.net)
36  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37  */
38 abstract class base {
40     /** @var $mimetype */
41     protected $mimetype = "text/plain";
43     /** @var $extension */
44     protected $extension = ".txt";
46     /** @var $filename */
47     protected $filename = '';
49     /** @var string The location to store the output content */
50     protected $filepath = '';
52     /**
53      * Get the file extension
54      *
55      * @return string file extension
56      */
57     public function get_extension() {
58         return $this->extension;
59     }
61     /**
62      * Set download filename base
63      *
64      * @param string $filename
65      */
66     public function set_filename($filename) {
67         $this->filename = $filename;
68     }
70     /**
71      * Set file path when writing to file
72      *
73      * @param string $filepath
74      * @throws coding_exception
75      */
76     public function set_filepath(string $filepath): void {
77         $filedir = dirname($filepath);
78         if (!is_writable($filedir)) {
79             throw new coding_exception('File path is not writable');
80         }
82         $this->filepath = $filepath;
84         // Some dataformat writers may expect filename to be set too.
85         $this->set_filename(pathinfo($this->filepath, PATHINFO_FILENAME));
86     }
88     /**
89      * Set the title of the worksheet inside a spreadsheet
90      *
91      * For some formats this will be ignored.
92      *
93      * @param string $title
94      */
95     public function set_sheettitle($title) {
96     }
98     /**
99      * Output file headers to initialise the download of the file.
100      */
101     public function send_http_headers() {
102         if (defined('BEHAT_SITE_RUNNING') || PHPUNIT_TEST) {
103             // For text based formats - we cannot test the output with behat if we force a file download.
104             return;
105         }
106         if (is_https()) {
107             // HTTPS sites - watch out for IE! KB812935 and KB316431.
108             header('Cache-Control: max-age=10');
109             header('Pragma: ');
110         } else {
111             // Normal http - prevent caching at all cost.
112             header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=0');
113             header('Pragma: no-cache');
114         }
115         header('Expires: '. gmdate('D, d M Y H:i:s', 0) .' GMT');
116         header("Content-Type: $this->mimetype\n");
117         $filename = $this->filename . $this->get_extension();
118         header("Content-Disposition: attachment; filename=\"$filename\"");
119     }
121     /**
122      * Set the dataformat to be output to current file. Calling code must call {@see base::close_output_to_file()} when finished
123      */
124     public function start_output_to_file(): void {
125         // Raise memory limit to ensure we can store the entire content. Start collecting output.
126         raise_memory_limit(MEMORY_EXTRA);
128         ob_start();
129         $this->start_output();
130     }
132     /**
133      * Write the start of the file.
134      */
135     public function start_output() {
136         // Override me if needed.
137     }
139     /**
140      * Write the start of the sheet we will be adding data to.
141      *
142      * @param array $columns
143      */
144     public function start_sheet($columns) {
145         // Override me if needed.
146     }
148     /**
149      * Method to define whether the dataformat supports export of HTML
150      *
151      * @return bool
152      */
153     public function supports_html(): bool {
154         return false;
155     }
157     /**
158      * Apply formatting to the cells of a given record
159      *
160      * @param array|\stdClass $record
161      * @return array
162      */
163     protected function format_record($record): array {
164         $record = (array)$record;
166         return $record;
167     }
169     /**
170      * Write a single record
171      *
172      * @param array $record
173      * @param int $rownum
174      */
175     abstract public function write_record($record, $rownum);
177     /**
178      * Write the end of the sheet containing the data.
179      *
180      * @param array $columns
181      */
182     public function close_sheet($columns) {
183         // Override me if needed.
184     }
186     /**
187      * Write the end of the file.
188      */
189     public function close_output() {
190         // Override me if needed.
191     }
193     /**
194      * Write the data to disk. Calling code should have previously called {@see base::start_output_to_file()}
195      *
196      * @return bool Whether the write succeeded
197      */
198     public function close_output_to_file(): bool {
199         $this->close_output();
201         $filecontent = ob_get_contents();
202         ob_end_clean();
204         return file_put_contents($this->filepath, $filecontent) !== false;
205     }