MDL-73210 usertours: Exported file does not contain the uploaded image

The export file now contains the attached files in the ATTO editor
We can export and import the tour to another system without losing them
 - Export process now convert the files to base64 and embed them into the export file.
 - Import process now convert the base64 from the export file to Moodle store_file.
This commit is contained in:
Huong Nguyen
2022-01-21 17:11:25 +07:00
parent 0e188470b1
commit 46b5fa0279
4 changed files with 109 additions and 19 deletions
+2 -2
View File
@@ -412,7 +412,7 @@ class helper {
* Get the specified tour.
*
* @param int $tourid The tour that the step belongs to.
* @return stdClass
* @return tour
*/
public static function get_tour($tourid) {
return tour::instance($tourid);
@@ -468,7 +468,7 @@ class helper {
* Get all of the steps in the tour.
*
* @param int $tourid The tour that the step belongs to.
* @return stdClass[]
* @return step[]
*/
public static function get_steps($tourid) {
$steps = cache::get_stepdata($tourid);
+3 -3
View File
@@ -428,7 +428,7 @@ class manager {
// Step export.
$export->steps = [];
foreach ($tour->get_steps() as $step) {
$record = $step->to_record();
$record = $step->to_record(true);
unset($record->id);
unset($record->tourid);
@@ -522,7 +522,7 @@ class manager {
// Step export.
$export->steps = [];
foreach ($tour->get_steps() as $step) {
$record = $step->to_record();
$record = $step->to_record(true);
unset($record->id);
unset($record->tourid);
@@ -674,7 +674,7 @@ class manager {
foreach ($steps as $stepconfig) {
$stepconfig->id = null;
$stepconfig->tourid = $tour->get_id();
$step = step::load_from_record($stepconfig, true);
$step = step::load_from_record($stepconfig, true, true);
$step->persist(true);
}
+103 -13
View File
@@ -24,6 +24,9 @@
namespace tool_usertours;
use context_system;
use stdClass;
defined('MOODLE_INTERNAL') || die();
/**
@@ -89,6 +92,16 @@ class step {
*/
protected $dirty = false;
/**
* @var bool $isimporting Whether the step is being imported or not.
*/
protected $isimporting;
/**
* @var stdClass[] $files The list of attached files for this step.
*/
protected $files = [];
/**
* Fetch the step instance.
*
@@ -103,12 +116,14 @@ class step {
/**
* Load the step instance.
*
* @param stdClass $record The step record to be loaded.
* @param boolean $clean Clean the values.
* @return step
* @param stdClass $record The step record to be loaded.
* @param bool $clean Clean the values.
* @param bool $isimporting Whether the step is being imported or not.
* @return step
*/
public static function load_from_record($record, $clean = false) {
public static function load_from_record($record, $clean = false, bool $isimporting = false) {
$step = new self();
$step->set_importing($isimporting);
return $step->reload_from_record($record, $clean);
}
@@ -138,9 +153,9 @@ class step {
/**
* Reload the current step from the supplied record.
*
* @param stdClass $record The step record to be loaded.
* @param boolean $clean Clean the values.
* @return step
* @param stdClass $record The step record to be loaded.
* @param bool $clean Clean the values.
* @return step
*/
protected function reload_from_record($record, $clean = false) {
$this->id = $record->id;
@@ -159,9 +174,24 @@ class step {
$this->config = json_decode($record->configdata);
$this->dirty = false;
if ($this->isimporting && isset($record->files)) {
// We are importing/exporting the step.
$this->files = $record->files;
}
return $this;
}
/**
* Set the import state for the step.
*
* @param bool $isimporting True if the step is imported, otherwise false.
* @return void
*/
protected function set_importing(bool $isimporting = false): void {
$this->isimporting = $isimporting;
}
/**
* Get the ID of the step.
*
@@ -449,13 +479,63 @@ class step {
return helper::get_delete_step_link($this->id);
}
/**
* Embed attached file to the json file for step.
*
* @return array List of files.
*/
protected function embed_files(): array {
$systemcontext = context_system::instance();
$fs = get_file_storage();
$areafiles = $fs->get_area_files($systemcontext->id, 'tool_usertours', 'stepcontent', $this->id);
$files = [];
foreach ($areafiles as $file) {
if ($file->is_directory()) {
continue;
}
$files[] = [
'name' => $file->get_filename(),
'path' => $file->get_filepath(),
'content' => base64_encode($file->get_content()),
'encode' => 'base64'
];
}
return $files;
}
/**
* Get the embed files information and create store_file for this step.
*
* @return void
*/
protected function extract_files() {
$fs = get_file_storage();
$systemcontext = context_system::instance();
foreach ($this->files as $file) {
$filename = $file->name;
$filepath = $file->path;
$filecontent = $file->content;
$filerecord = [
'contextid' => $systemcontext->id,
'component' => 'tool_usertours',
'filearea' => 'stepcontent',
'itemid' => $this->get_id(),
'filepath' => $filepath,
'filename' => $filename,
];
$fs->create_file_from_string($filerecord, base64_decode($filecontent));
}
}
/**
* Prepare this step for saving to the database.
*
* @param bool $isexporting Whether the step is being exported or not.
* @return object
*/
public function to_record() {
return (object) array(
public function to_record(bool $isexporting = false) {
$record = [
'id' => $this->id,
'tourid' => $this->tourid,
'title' => $this->title,
@@ -465,7 +545,12 @@ class step {
'targetvalue' => $this->targetvalue,
'sortorder' => $this->sortorder,
'configdata' => json_encode($this->config),
);
];
if ($isexporting) {
// We are exporting the step, adding files node to the json record.
$record['files'] = $this->embed_files();
}
return (object) $record;
}
/**
@@ -504,7 +589,7 @@ class step {
$this->get_tour()->reset_step_sortorder();
}
$systemcontext = \context_system::instance();
$systemcontext = context_system::instance();
if ($draftid = file_get_submitted_draft_itemid('content')) {
// Take any files added to the stepcontent draft file area and
// convert them into the proper event description file area. Also
@@ -521,6 +606,11 @@ class step {
);
$DB->set_field('tool_usertours_steps', 'content', $this->content, ['id' => $this->id]);
}
if ($this->isimporting) {
// We are importing the step, we need to create store_file from the json record.
$this->extract_files();
}
$this->reload();
// Notify of a change to the step configuration.
@@ -650,7 +740,7 @@ class step {
// Prepare content for editing in a form 'editor' field type.
$draftitemid = file_get_submitted_draft_itemid('tool_usertours');
$systemcontext = \context_system::instance();
$systemcontext = context_system::instance();
$data->content = [
'format' => $data->contentformat,
'itemid' => $draftitemid,
@@ -675,7 +765,7 @@ class step {
* @param stdClass $data The submitted data.
* @return $this
*/
public function handle_form_submission(local\forms\editstep &$mform, \stdClass $data) {
public function handle_form_submission(local\forms\editstep &$mform, stdClass $data) {
$this->set_title($data->title);
$this->set_content($data->content['text'], $data->content['format']);
$this->set_targettype($data->targettype);
+1 -1
View File
@@ -209,7 +209,7 @@ class tour {
/**
* Fetch all steps in the tour.
*
* @return stdClass[]
* @return step[]
*/
public function get_steps() {
if (empty($this->steps)) {