portfolio MDL-21079 be more selective about including libraries.
[moodle.git] / mod / data / locallib.php
CommitLineData
24ba58ee
PL
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * @package mod-data
20 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22 */
23
24/**
25 * @package mod-data
26 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28 */
29
30class data_portfolio_caller extends portfolio_module_caller_base {
31
32 /** @var int */
33 protected $recordid;
34 /** @var string */
35 protected $exporttype;
36 /** @var string */
37 protected $delimiter_name;
38
39 /** @var object */
40 private $data;
41 /**#@+ @var array */
42 private $selectedfields;
43 private $fields;
44 private $fieldtypes;
45 private $exportdata;
46 /**#@-*/
47 /**#@+ @var object */
48 private $singlerecord;
49 private $singlefield;
50 /**#@-*/
51 /**
52 * @return array
53 */
54 public static function expected_callbackargs() {
55 return array(
56 'id' => true,
57 'recordid' => false,
58 'delimiter_name' => false,
59 'exporttype' => false,
60 );
61 }
62 /**
63 * @param array $callbackargs
64 */
65 public function __construct($callbackargs) {
66 parent::__construct($callbackargs);
67 if (empty($this->exporttype)) {
68 $this->exporttype = 'csv';
69 }
70 $this->selectedfields = array();
71 foreach ($callbackargs as $key => $value) {
72 if (strpos($key, 'field_') === 0) {
73 $this->selectedfields[] = substr($key, 6);
74 }
75 }
76 }
77
78 /**
79 * @global object
80 */
81 public function load_data() {
82 global $DB;
83 if (!$this->cm = get_coursemodule_from_id('data', $this->id)) {
84 throw new portfolio_caller_exception('invalidid', 'data');
85 }
86 $this->data = $DB->get_record('data', array('id' => $this->cm->instance));
87 $fieldrecords = $DB->get_records('data_fields', array('dataid'=>$this->cm->instance), 'id');
88 // populate objets for this databases fields
89 $this->fields = array();
90 foreach ($fieldrecords as $fieldrecord) {
91 $tmp = data_get_field($fieldrecord, $this->data);
92 $this->fields[] = $tmp;
93 $this->fieldtypes[] = $tmp->type;
94 }
95
96 if ($this->recordid) {
97 //user has selected to export one single entry rather than the whole thing
98 // which is completely different
99 $this->singlerecord = $DB->get_record('data_records', array('id' => $this->recordid));
100 $this->singlerecord->content = $DB->get_records('data_content', array('recordid' => $this->singlerecord->id));
101 $this->exporttype = 'single';
102
103 list($formats, $files) = self::formats($this->fields, $this->singlerecord);
104 if (count($files) == 1 && count($this->fields) == 1) {
105 $this->singlefile = $files[0];
106 $this->exporttype = 'singlefile';
107 } else if (count($files) > 0) {
108 $this->multifiles = $files;
109 }
110 } else {
111 // all records as csv or whatever
112 $this->exportdata = data_get_exportdata($this->cm->instance, $this->fields, $this->selectedfields);
113 }
114 }
115
116 /**
117 * @todo penny later when we suport exporting to more than just csv, we may
118 * need to ask the user here if we have not already passed it
119 *
120 * @return bool
121 */
122 public function has_export_config() {
123 return false;
124 }
125
126 /**
127 * @uses PORTFOLIO_TIME_LOW
128 * @return mixed
129 */
130 public function expected_time() {
131 if ($this->exporttype == 'single') {
132 return PORTFOLIO_TIME_LOW;
133 }
134 return portfolio_expected_time_db(count($this->exportdata));
135 }
136
137 /**
138 * @return string
139 */
140 public function get_sha1() {
141 if ($this->exporttype == 'singlefile') {
142 return $this->singlefile->get_contenthash();
143 }
144 $loopdata = $this->exportdata;
145 if ($this->exporttype == 'single') {
146 $loopdata = $this->singlerecord;
147 }
148 $str = '';
149 foreach ($loopdata as $data) {
150 if (is_array($data) || is_object($data)) {
151 $testkey = array_pop(array_keys($data));
152 if (is_array($data[$testkey]) || is_object($data[$testkey])) {
153 foreach ($data as $d) {
154 $str .= implode(',', (array)$d);
155 }
156 } else {
157 $str .= implode(',', (array)$data);
158 }
159 } else {
160 $str .= $data;
161 }
162 }
163 return sha1($str . ',' . $this->exporttype);
164 }
165 /**
166 * @global object
167 */
168 public function prepare_package() {
169 global $DB;
170 $count = count($this->exportdata);
171 $content = '';
172 $filename = '';
173 switch ($this->exporttype) {
174 case 'singlefile':
175 return $this->get('exporter')->copy_existing_file($this->singlefile);
176 case 'single':
177 $content = $this->exportsingle();
178 $filename = clean_filename($this->cm->name . '-entry.html');
179 break;
180 case 'csv':
181 $content = data_export_csv($this->exportdata, $this->delimiter_name, $this->cm->name, $count, true);
182 $filename = clean_filename($this->cm->name . '.csv');
183 break;
184 case 'xls':
185 throw new portfolio_caller_exception('notimplemented', 'portfolio', '', 'xls');
186 $content = data_export_xls($this->exportdata, $this->cm->name, $count, true);
187 break;
188 case 'ods':
189 throw new portfolio_caller_exception('notimplemented', 'portfolio', '', 'ods');
190 $content = data_export_ods($this->exportdata, $this->cm->name, $count, true);
191 break;
192 default:
193 throw new portfolio_caller_exception('notimplemented', 'portfolio', '', $this->exporttype);
194 break;
195 }
196 return $this->exporter->write_new_file(
197 $content,
198 $filename,
199 ($this->exporter->get('format') instanceof PORTFOLIO_FORMAT_RICH) // if we have associate files, this is a 'manifest'
200 );
201 }
202
203 /**
204 * @return bool
205 */
206 public function check_permissions() {
207 return has_capability('mod/data:exportallentries', get_context_instance(CONTEXT_MODULE, $this->cm->id));
208 }
209
210 /**
211 * @return string
212 */
213 public static function display_name() {
214 return get_string('modulename', 'data');
215 }
216
217 /**
218 * @global object
219 * @return bool|void
220 */
221 public function __wakeup() {
222 global $CFG;
223 if (empty($CFG)) {
224 return true; // too early yet
225 }
226 foreach ($this->fieldtypes as $key => $field) {
227 require_once($CFG->dirroot . '/mod/data/field/' . $field .'/field.class.php');
228 $this->fields[$key] = unserialize(serialize($this->fields[$key]));
229 }
230 }
231
232 /**
233 * @global object
234 * @return string
235 */
236 private function exportsingle() {
237 global $DB;
238 // Replacing tags
239 $patterns = array();
240 $replacement = array();
241 $context = get_context_instance(CONTEXT_MODULE, $this->cm->id);
242
243 // Then we generate strings to replace for normal tags
244 $format = $this->get('exporter')->get('format');
245 foreach ($this->fields as $field) {
246 $patterns[]='[['.$field->field->name.']]';
247 if (is_callable(array($field, 'get_file'))) {
248 // TODO this used to be:
249 // if ($field instanceof data_field_file) {
250 // - see MDL-16493
251 if (!$file = $field->get_file($this->singlerecord->id)) {
252 $replacement[] = '';
253 continue; // probably left empty
254 }
255 $replacement[] = $format->file_output($file);
256 $this->get('exporter')->copy_existing_file($file);
257 } else {
258 $replacement[] = $field->display_browse_field($this->singlerecord->id, 'singletemplate');
259 }
260 }
261
262 // Replacing special tags (##Edit##, ##Delete##, ##More##)
263 $patterns[]='##edit##';
264 $patterns[]='##delete##';
265 $patterns[]='##export##';
266 $patterns[]='##more##';
267 $patterns[]='##moreurl##';
268 $patterns[]='##user##';
269 $patterns[]='##approve##';
270 $patterns[]='##comments##';
271 $patterns[] = '##timeadded##';
272 $patterns[] = '##timemodified##';
273 $replacement[] = '';
274 $replacement[] = '';
275 $replacement[] = '';
276 $replacement[] = '';
277 $replacement[] = '';
278 $replacement[] = '';
279 $replacement[] = '';
280 $replacement[] = '';
281 $replacement[] = userdate($this->singlerecord->timecreated);
282 $replacement[] = userdate($this->singlerecord->timemodified);
283
284 // actual replacement of the tags
285 return str_ireplace($patterns, $replacement, $this->data->singletemplate);
286 }
287
288 /**
289 * @param array $fields
290 * @param object $record
291 * @uses PORTFOLIO_FORMAT_PLAINHTML
292 * @uses PORTFOLIO_FORMAT_RICHHTML
293 * @return array
294 */
295 public static function formats($fields, $record) {
296 $formats = array(PORTFOLIO_FORMAT_PLAINHTML);
297 $includedfiles = array();
298 foreach ($fields as $singlefield) {
299 if (is_callable(array($singlefield, 'get_file'))) {
300 $includedfiles[] = $singlefield->get_file($record->id);
301 }
302 }
303 if (count($includedfiles) == 1 && count($fields) == 1) {
304 $formats= array(portfolio_format_from_file($includedfiles[0]));
305 } else if (count($includedfiles) > 0) {
306 $formats = array(PORTFOLIO_FORMAT_RICHHTML);
307 }
308 return array($formats, $includedfiles);
309 }
310
311 public static function base_supported_formats() {
312 return array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_RICHHTML, PORTFOLIO_FORMAT_PLAINHTML);
313 }
314}