|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00024 require_once($CFG->dirroot . '/mod/data/lib.php'); 00025 require_once($CFG->libdir . '/portfolio/caller.php'); 00026 00030 class data_portfolio_caller extends portfolio_module_caller_base { 00031 00033 protected $recordid; 00034 00036 private $data; 00037 00039 private $fields; 00040 private $fieldtypes; 00041 00043 private $records; 00044 00046 private $minecount; 00047 00053 public static function expected_callbackargs() { 00054 return array( 00055 'id' => true, 00056 'recordid' => false, 00057 ); 00058 } 00059 00063 public function __construct($callbackargs) { 00064 parent::__construct($callbackargs); 00065 // set up the list of fields to export 00066 $this->selectedfields = array(); 00067 foreach ($callbackargs as $key => $value) { 00068 if (strpos($key, 'field_') === 0) { 00069 $this->selectedfields[] = substr($key, 6); 00070 } 00071 } 00072 } 00073 00079 public function load_data() { 00080 global $DB, $USER; 00081 if (!$this->cm = get_coursemodule_from_id('data', $this->id)) { 00082 throw new portfolio_caller_exception('invalidid', 'data'); 00083 } 00084 if (!$this->data = $DB->get_record('data', array('id' => $this->cm->instance))) { 00085 throw new portfolio_caller_exception('invalidid', 'data'); 00086 } 00087 $fieldrecords = $DB->get_records('data_fields', array('dataid' => $this->cm->instance), 'id'); 00088 // populate objets for this databases fields 00089 $this->fields = array(); 00090 foreach ($fieldrecords as $fieldrecord) { 00091 $tmp = data_get_field($fieldrecord, $this->data); 00092 $this->fields[] = $tmp; 00093 $this->fieldtypes[] = $tmp->type; 00094 } 00095 00096 $this->records = array(); 00097 if ($this->recordid) { 00098 $tmp = $DB->get_record('data_records', array('id' => $this->recordid)); 00099 $tmp->content = $DB->get_records('data_content', array('recordid' => $this->recordid)); 00100 $this->records[] = $tmp; 00101 } else { 00102 $where = array('dataid' => $this->data->id); 00103 if (!has_capability('mod/data:exportallentries', get_context_instance(CONTEXT_MODULE, $this->cm->id))) { 00104 $where['userid'] = $USER->id; // get them all in case, we'll unset ones that aren't ours later if necessary 00105 } 00106 $tmp = $DB->get_records('data_records', $where); 00107 foreach ($tmp as $t) { 00108 $t->content = $DB->get_records('data_content', array('recordid' => $t->id)); 00109 $this->records[] = $t; 00110 } 00111 $this->minecount = $DB->count_records('data_records', array('dataid' => $this->data->id, 'userid' => $USER->id)); 00112 } 00113 00114 if ($this->recordid) { 00115 list($formats, $files) = self::formats($this->fields, $this->records[0]); 00116 $this->set_file_and_format_data($files); 00117 } 00118 } 00119 00128 public function expected_time() { 00129 if ($this->recordid) { 00130 return $this->expected_time_file(); 00131 } else { 00132 return portfolio_expected_time_db(count($this->records)); 00133 } 00134 } 00135 00141 public function get_sha1() { 00142 // in the case that we're exporting a subclass of 'file' and we have a singlefile, 00143 // then we're not exporting any metadata, just the file by itself by mimetype. 00144 if ($this->exporter->get('format') instanceof portfolio_format_file && $this->singlefile) { 00145 return $this->get_sha1_file(); 00146 } 00147 // otherwise we're exporting some sort of multipart content so use the data 00148 $str = ''; 00149 foreach ($this->records as $record) { 00150 foreach ($record as $data) { 00151 if (is_array($data) || is_object($data)) { 00152 $testkey = array_pop(array_keys($data)); 00153 if (is_array($data[$testkey]) || is_object($data[$testkey])) { 00154 foreach ($data as $d) { 00155 $str .= implode(',', (array)$d); 00156 } 00157 } else { 00158 $str .= implode(',', (array)$data); 00159 } 00160 } else { 00161 $str .= $data; 00162 } 00163 } 00164 } 00165 return sha1($str . ',' . $this->exporter->get('formatclass')); 00166 } 00167 00173 public function prepare_package() { 00174 global $DB; 00175 $leapwriter = null; 00176 $content = ''; 00177 $filename = ''; 00178 $uid = $this->exporter->get('user')->id; 00179 $users = array(); //cache 00180 $onlymine = $this->get_export_config('mineonly'); 00181 if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) { 00182 $leapwriter = $this->exporter->get('format')->leap2a_writer(); 00183 $ids = array(); 00184 } 00185 00186 if ($this->exporter->get('format') instanceof portfolio_format_file && $this->singlefile) { 00187 return $this->get('exporter')->copy_existing_file($this->singlefile); 00188 } 00189 foreach ($this->records as $key => $record) { 00190 if ($onlymine && $record->userid != $uid) { 00191 unset($this->records[$key]); // sha1 00192 continue; 00193 } 00194 list($tmpcontent, $files) = $this->exportentry($record); 00195 $content .= $tmpcontent; 00196 if ($leapwriter) { 00197 $entry = new portfolio_format_leap2a_entry('dataentry' . $record->id, $this->data->name, 'resource', $tmpcontent); 00198 $entry->published = $record->timecreated; 00199 $entry->updated = $record->timemodified; 00200 if ($record->userid != $uid) { 00201 if (!array_key_exists($record->userid, $users)) { 00202 $users[$record->userid] = $DB->get_record('user', array('id' => $record->userid), 'id,firstname,lastname'); 00203 } 00204 $entry->author = $users[$record->userid]; 00205 } 00206 $ids[] = $entry->id; 00207 $leapwriter->link_files($entry, $files, 'dataentry' . $record->id . 'file'); 00208 $leapwriter->add_entry($entry); 00209 } 00210 } 00211 if ($leapwriter) { 00212 if (count($this->records) > 1) { // make a selection element to tie them all together 00213 $selection = new portfolio_format_leap2a_entry('datadb' . $this->data->id, 00214 get_string('entries', 'data') . ': ' . $this->data->name, 'selection'); 00215 $leapwriter->add_entry($selection); 00216 $leapwriter->make_selection($selection, $ids, 'Grouping'); 00217 } 00218 $filename = $this->exporter->get('format')->manifest_name(); 00219 $content = $leapwriter->to_xml(); 00220 } else { 00221 if (count($this->records) == 1) { 00222 $filename = clean_filename($this->cm->name . '-entry.html'); 00223 } else { 00224 $filename = clean_filename($this->cm->name . '-full.html'); 00225 } 00226 } 00227 return $this->exporter->write_new_file( 00228 $content, 00229 $filename, 00230 ($this->exporter->get('format') instanceof PORTFOLIO_FORMAT_RICH) // if we have associate files, this is a 'manifest' 00231 ); 00232 } 00233 00239 public function check_permissions() { 00240 if ($this->recordid) { 00241 if (data_isowner($this->recordid)) { 00242 return has_capability('mod/data:exportownentry', get_context_instance(CONTEXT_MODULE, $this->cm->id)); 00243 } 00244 return has_capability('mod/data:exportentry', get_context_instance(CONTEXT_MODULE, $this->cm->id)); 00245 } 00246 if ($this->has_export_config() && !$this->get_export_config('mineonly')) { 00247 return has_capability('mod/data:exportallentries', get_context_instance(CONTEXT_MODULE, $this->cm->id)); 00248 } 00249 return has_capability('mod/data:exportownentry', get_context_instance(CONTEXT_MODULE, $this->cm->id)); 00250 } 00251 00255 public static function display_name() { 00256 return get_string('modulename', 'data'); 00257 } 00258 00263 public function __wakeup() { 00264 global $CFG; 00265 if (empty($CFG)) { 00266 return true; // too early yet 00267 } 00268 foreach ($this->fieldtypes as $key => $field) { 00269 require_once($CFG->dirroot . '/mod/data/field/' . $field .'/field.class.php'); 00270 $this->fields[$key] = unserialize(serialize($this->fields[$key])); 00271 } 00272 } 00273 00281 private function exportentry($record) { 00282 // Replacing tags 00283 $patterns = array(); 00284 $replacement = array(); 00285 $context = get_context_instance(CONTEXT_MODULE, $this->cm->id); 00286 00287 $files = array(); 00288 // Then we generate strings to replace for normal tags 00289 $format = $this->get('exporter')->get('format'); 00290 foreach ($this->fields as $field) { 00291 $patterns[]='[['.$field->field->name.']]'; 00292 if (is_callable(array($field, 'get_file'))) { 00293 if (!$file = $field->get_file($record->id)) { 00294 $replacement[] = ''; 00295 continue; // probably left empty 00296 } 00297 $replacement[] = $format->file_output($file); 00298 $this->get('exporter')->copy_existing_file($file); 00299 $files[] = $file; 00300 } else { 00301 $replacement[] = $field->display_browse_field($record->id, 'singletemplate'); 00302 } 00303 } 00304 00305 // Replacing special tags (##Edit##, ##Delete##, ##More##) 00306 $patterns[]='##edit##'; 00307 $patterns[]='##delete##'; 00308 $patterns[]='##export##'; 00309 $patterns[]='##more##'; 00310 $patterns[]='##moreurl##'; 00311 $patterns[]='##user##'; 00312 $patterns[]='##approve##'; 00313 $patterns[]='##comments##'; 00314 $patterns[] = '##timeadded##'; 00315 $patterns[] = '##timemodified##'; 00316 $replacement[] = ''; 00317 $replacement[] = ''; 00318 $replacement[] = ''; 00319 $replacement[] = ''; 00320 $replacement[] = ''; 00321 $replacement[] = ''; 00322 $replacement[] = ''; 00323 $replacement[] = ''; 00324 $replacement[] = userdate($record->timecreated); 00325 $replacement[] = userdate($record->timemodified); 00326 00327 // actual replacement of the tags 00328 return array(str_ireplace($patterns, $replacement, $this->data->singletemplate), $files); 00329 } 00330 00343 public static function formats($fields, $record) { 00344 $formats = array(PORTFOLIO_FORMAT_PLAINHTML); 00345 $includedfiles = array(); 00346 foreach ($fields as $singlefield) { 00347 if (is_callable(array($singlefield, 'get_file'))) { 00348 $includedfiles[] = $singlefield->get_file($record->id); 00349 } 00350 } 00351 if (count($includedfiles) == 1 && count($fields) == 1) { 00352 $formats = array(portfolio_format_from_mimetype($includedfiles[0]->get_mimetype())); 00353 } else if (count($includedfiles) > 0) { 00354 $formats = array(PORTFOLIO_FORMAT_RICHHTML); 00355 } 00356 return array($formats, $includedfiles); 00357 } 00358 00359 public static function has_files($data) { 00360 global $DB; 00361 $fieldrecords = $DB->get_records('data_fields', array('dataid' => $data->id), 'id'); 00362 // populate objets for this databases fields 00363 foreach ($fieldrecords as $fieldrecord) { 00364 $field = data_get_field($fieldrecord, $data); 00365 if (is_callable(array($field, 'get_file'))) { 00366 return true; 00367 } 00368 } 00369 return false; 00370 } 00371 00375 public static function base_supported_formats() { 00376 return array(PORTFOLIO_FORMAT_RICHHTML, PORTFOLIO_FORMAT_PLAINHTML, PORTFOLIO_FORMAT_LEAP2A); 00377 } 00378 00379 public function has_export_config() { 00380 // if we're exporting more than just a single entry, 00381 // and we have the capability to export all entries, 00382 // then ask whether we want just our own, or all of them 00383 return (empty($this->recordid) // multi-entry export 00384 && $this->minecount > 0 // some of them are mine 00385 && $this->minecount != count($this->records) // not all of them are mine 00386 && has_capability('mod/data:exportallentries', get_context_instance(CONTEXT_MODULE, $this->cm->id))); // they actually have a choice in the matter 00387 } 00388 00389 public function export_config_form(&$mform, $instance) { 00390 if (!$this->has_export_config()) { 00391 return; 00392 } 00393 $mform->addElement('selectyesno', 'mineonly', get_string('exportownentries', 'data', (object)array('mine' => $this->minecount, 'all' => count($this->records)))); 00394 $mform->setDefault('mineonly', 1); 00395 } 00396 00397 public function get_allowed_export_config() { 00398 return array('mineonly'); 00399 } 00400 }