mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 08:56:36 +02:00
Merge branch 'MDL-75140-master' of https://github.com/aanabit/moodle
This commit is contained in:
commit
de5cd36e92
20 changed files with 822 additions and 107 deletions
79
mod/data/classes/local/importer/preset_existing_importer.php
Normal file
79
mod/data/classes/local/importer/preset_existing_importer.php
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
<?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/>.
|
||||||
|
|
||||||
|
namespace mod_data\local\importer;
|
||||||
|
|
||||||
|
use mod_data\manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data preset importer for existing presets
|
||||||
|
* @package mod_data
|
||||||
|
* @copyright 2022 Amaia Anabitarte <amaia@moodle.com>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
class preset_existing_importer extends preset_importer {
|
||||||
|
|
||||||
|
/** @var int user id. */
|
||||||
|
protected $userid;
|
||||||
|
|
||||||
|
/** @var string fullname of the preset. */
|
||||||
|
private $fullname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param manager $manager
|
||||||
|
* @param string $fullname
|
||||||
|
*/
|
||||||
|
public function __construct(manager $manager, string $fullname) {
|
||||||
|
global $USER;
|
||||||
|
|
||||||
|
list($userid, $shortname) = explode('/', $fullname, 2);
|
||||||
|
$context = $manager->get_context();
|
||||||
|
if ($userid &&
|
||||||
|
($userid != $USER->id) &&
|
||||||
|
!has_capability('mod/data:manageuserpresets', $context) &&
|
||||||
|
!has_capability('mod/data:viewalluserpresets', $context)
|
||||||
|
) {
|
||||||
|
throw new \coding_exception('Invalid preset provided');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->userid = $userid;
|
||||||
|
$this->fullname = $fullname;
|
||||||
|
$cm = $manager->get_coursemodule();
|
||||||
|
$course = $cm->get_course();
|
||||||
|
$filepath = data_preset_path($course, $userid, $shortname);
|
||||||
|
parent::__construct($manager, $filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns user ID
|
||||||
|
*
|
||||||
|
* @return int|string userid or empty string
|
||||||
|
*/
|
||||||
|
public function get_userid() {
|
||||||
|
return $this->userid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the information we need to build the importer selector.
|
||||||
|
*
|
||||||
|
* @return array Value and name for the preset importer selector
|
||||||
|
*/
|
||||||
|
public function get_preset_selector(): array {
|
||||||
|
return ['name' => 'fullname', 'value' => $this->get_userid().'/'.$this->get_directory()];
|
||||||
|
}
|
||||||
|
}
|
348
mod/data/classes/local/importer/preset_importer.php
Normal file
348
mod/data/classes/local/importer/preset_importer.php
Normal file
|
@ -0,0 +1,348 @@
|
||||||
|
<?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/>.
|
||||||
|
|
||||||
|
namespace mod_data\local\importer;
|
||||||
|
|
||||||
|
use mod_data\manager;
|
||||||
|
use mod_data\preset;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class used for data preset importers
|
||||||
|
*
|
||||||
|
* @package mod_data
|
||||||
|
* @copyright 2022 Amaia Anabitarte <amaia@moodle.com>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
abstract class preset_importer {
|
||||||
|
|
||||||
|
/** @var manager manager instance. */
|
||||||
|
private $manager;
|
||||||
|
|
||||||
|
/** @var string directory where to find the preset. */
|
||||||
|
protected $directory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param manager $manager
|
||||||
|
* @param string $directory
|
||||||
|
*/
|
||||||
|
public function __construct(manager $manager, string $directory) {
|
||||||
|
$this->manager = $manager;
|
||||||
|
$this->directory = $directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the directory the preset is located in
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function get_directory(): string {
|
||||||
|
return basename($this->directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retreive the contents of a file. That file may either be in a conventional directory of the Moodle file storage
|
||||||
|
*
|
||||||
|
* @param \file_storage|null $filestorage . Should be null if using a conventional directory
|
||||||
|
* @param \stored_file|null $fileobj the directory to look in. null if using a conventional directory
|
||||||
|
* @param string|null $dir the directory to look in. null if using the Moodle file storage
|
||||||
|
* @param string $filename the name of the file we want
|
||||||
|
* @return string|null the contents of the file or null if the file doesn't exist.
|
||||||
|
*/
|
||||||
|
public function get_file_contents(
|
||||||
|
?\file_storage &$filestorage,
|
||||||
|
?\stored_file &$fileobj,
|
||||||
|
?string $dir,
|
||||||
|
string $filename
|
||||||
|
): ?string {
|
||||||
|
if (empty($filestorage) || empty($fileobj)) {
|
||||||
|
if (substr($dir, -1) != '/') {
|
||||||
|
$dir .= '/';
|
||||||
|
}
|
||||||
|
if (file_exists($dir.$filename)) {
|
||||||
|
return file_get_contents($dir.$filename);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($filestorage->file_exists(
|
||||||
|
DATA_PRESET_CONTEXT,
|
||||||
|
DATA_PRESET_COMPONENT,
|
||||||
|
DATA_PRESET_FILEAREA,
|
||||||
|
0,
|
||||||
|
$fileobj->get_filepath(),
|
||||||
|
$filename)
|
||||||
|
) {
|
||||||
|
$file = $filestorage->get_file(
|
||||||
|
DATA_PRESET_CONTEXT,
|
||||||
|
DATA_PRESET_COMPONENT,
|
||||||
|
DATA_PRESET_FILEAREA,
|
||||||
|
0,
|
||||||
|
$fileobj->get_filepath(),
|
||||||
|
$filename
|
||||||
|
);
|
||||||
|
return $file->get_content();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the preset settings
|
||||||
|
*
|
||||||
|
* @return stdClass Settings to be imported.
|
||||||
|
*/
|
||||||
|
public function get_preset_settings(): stdClass {
|
||||||
|
global $CFG;
|
||||||
|
require_once($CFG->libdir.'/xmlize.php');
|
||||||
|
|
||||||
|
$fs = null;
|
||||||
|
$fileobj = null;
|
||||||
|
if (!preset::is_directory_a_preset($this->directory)) {
|
||||||
|
// Maybe the user requested a preset stored in the Moodle file storage.
|
||||||
|
|
||||||
|
$fs = get_file_storage();
|
||||||
|
$files = $fs->get_area_files(DATA_PRESET_CONTEXT, DATA_PRESET_COMPONENT, DATA_PRESET_FILEAREA);
|
||||||
|
|
||||||
|
// Preset name to find will be the final element of the directory.
|
||||||
|
$explodeddirectory = explode('/', $this->directory);
|
||||||
|
$presettofind = end($explodeddirectory);
|
||||||
|
|
||||||
|
// Now go through the available files available and see if we can find it.
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if (($file->is_directory() && $file->get_filepath() == '/') || !$file->is_directory()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$presetname = trim($file->get_filepath(), '/');
|
||||||
|
if ($presetname == $presettofind) {
|
||||||
|
$this->directory = $presetname;
|
||||||
|
$fileobj = $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($fileobj)) {
|
||||||
|
throw new \moodle_exception('invalidpreset', 'data', '', $this->directory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$allowedsettings = [
|
||||||
|
'intro',
|
||||||
|
'comments',
|
||||||
|
'requiredentries',
|
||||||
|
'requiredentriestoview',
|
||||||
|
'maxentries',
|
||||||
|
'rssarticles',
|
||||||
|
'approval',
|
||||||
|
'defaultsortdir',
|
||||||
|
'defaultsort'
|
||||||
|
];
|
||||||
|
|
||||||
|
$module = $this->manager->get_instance();
|
||||||
|
$result = new stdClass;
|
||||||
|
$result->settings = new stdClass;
|
||||||
|
$result->importfields = [];
|
||||||
|
$result->currentfields = $this->manager->get_field_records();
|
||||||
|
|
||||||
|
// Grab XML.
|
||||||
|
$presetxml = $this->get_file_contents($fs, $fileobj, $this->directory, 'preset.xml');
|
||||||
|
$parsedxml = xmlize($presetxml, 0);
|
||||||
|
|
||||||
|
// First, do settings. Put in user friendly array.
|
||||||
|
$settingsarray = $parsedxml['preset']['#']['settings'][0]['#'];
|
||||||
|
$result->settings = new StdClass();
|
||||||
|
foreach ($settingsarray as $setting => $value) {
|
||||||
|
if (!is_array($value) || !in_array($setting, $allowedsettings)) {
|
||||||
|
// Unsupported setting.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$result->settings->$setting = $value[0]['#'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now work out fields to user friendly array.
|
||||||
|
$fieldsarray = $parsedxml['preset']['#']['field'];
|
||||||
|
foreach ($fieldsarray as $field) {
|
||||||
|
if (!is_array($field)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$fieldstoimport = new StdClass();
|
||||||
|
foreach ($field['#'] as $param => $value) {
|
||||||
|
if (!is_array($value)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$fieldstoimport->$param = $value[0]['#'];
|
||||||
|
}
|
||||||
|
$fieldstoimport->dataid = $module->id;
|
||||||
|
$fieldstoimport->type = clean_param($fieldstoimport->type, PARAM_ALPHA);
|
||||||
|
$result->importfields[] = $fieldstoimport;
|
||||||
|
}
|
||||||
|
// Now add the HTML templates to the settings array so we can update d.
|
||||||
|
foreach (manager::TEMPLATES_LIST as $templatename => $templatefile) {
|
||||||
|
$result->settings->$templatename = $this->get_file_contents(
|
||||||
|
$fs,
|
||||||
|
$fileobj,
|
||||||
|
$this->directory,
|
||||||
|
$templatefile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result->settings->instance = $module->id;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import the preset into the given database module
|
||||||
|
*
|
||||||
|
* @param bool $overwritesettings Whether to overwrite activity settings or not.
|
||||||
|
* @return bool Wether the importing has been successful.
|
||||||
|
*/
|
||||||
|
public function import(bool $overwritesettings): bool {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
$params = $this->get_preset_settings();
|
||||||
|
$settings = $params->settings;
|
||||||
|
$newfields = $params->importfields;
|
||||||
|
$currentfields = $params->currentfields;
|
||||||
|
$preservedfields = [];
|
||||||
|
$module = $this->manager->get_instance();
|
||||||
|
|
||||||
|
// Maps fields and makes new ones.
|
||||||
|
if (!empty($newfields)) {
|
||||||
|
// We require an injective mapping, and need to know what to protect.
|
||||||
|
foreach ($newfields as $newid => $newfield) {
|
||||||
|
$cid = optional_param("field_$newid", -1, PARAM_INT);
|
||||||
|
if ($cid == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (array_key_exists($cid, $preservedfields)) {
|
||||||
|
throw new \moodle_exception('notinjectivemap', 'data');
|
||||||
|
} else {
|
||||||
|
$preservedfields[$cid] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($newfields as $newid => $newfield) {
|
||||||
|
$cid = optional_param("field_$newid", -1, PARAM_INT);
|
||||||
|
|
||||||
|
/* A mapping. Just need to change field params. Data kept. */
|
||||||
|
if ($cid != -1 && isset($currentfields[$cid])) {
|
||||||
|
$fieldobject = data_get_field_from_id($currentfields[$cid]->id, $module);
|
||||||
|
foreach ($newfield as $param => $value) {
|
||||||
|
if ($param != "id") {
|
||||||
|
$fieldobject->field->$param = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($fieldobject->field->similarfield);
|
||||||
|
$fieldobject->update_field();
|
||||||
|
unset($fieldobject);
|
||||||
|
} else {
|
||||||
|
/* Make a new field */
|
||||||
|
include_once("field/$newfield->type/field.class.php");
|
||||||
|
|
||||||
|
if (!isset($newfield->description)) {
|
||||||
|
$newfield->description = '';
|
||||||
|
}
|
||||||
|
$classname = 'data_field_'.$newfield->type;
|
||||||
|
$fieldclass = new $classname($newfield, $module);
|
||||||
|
$fieldclass->insert_field();
|
||||||
|
unset($fieldclass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get rid of all old unused data.
|
||||||
|
if (!empty($preservedfields)) {
|
||||||
|
foreach ($currentfields as $cid => $currentfield) {
|
||||||
|
if (!array_key_exists($cid, $preservedfields)) {
|
||||||
|
// Data not used anymore so wipe!
|
||||||
|
print "Deleting field $currentfield->name<br />";
|
||||||
|
|
||||||
|
$id = $currentfield->id;
|
||||||
|
// Why delete existing data records and related comments/ratings??
|
||||||
|
$DB->delete_records('data_content', ['fieldid' => $id]);
|
||||||
|
$DB->delete_records('data_fields', ['id' => $id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle special settings here.
|
||||||
|
if (!empty($settings->defaultsort)) {
|
||||||
|
if (is_numeric($settings->defaultsort)) {
|
||||||
|
// Old broken value.
|
||||||
|
$settings->defaultsort = 0;
|
||||||
|
} else {
|
||||||
|
$settings->defaultsort = (int)$DB->get_field(
|
||||||
|
'data_fields',
|
||||||
|
'id',
|
||||||
|
['dataid' => $module->id, 'name' => $settings->defaultsort]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$settings->defaultsort = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we want to overwrite all current database settings?
|
||||||
|
if ($overwritesettings) {
|
||||||
|
// All supported settings.
|
||||||
|
$overwrite = array_keys((array)$settings);
|
||||||
|
} else {
|
||||||
|
// Only templates and sorting.
|
||||||
|
$overwrite = ['singletemplate', 'listtemplate', 'listtemplateheader', 'listtemplatefooter',
|
||||||
|
'addtemplate', 'rsstemplate', 'rsstitletemplate', 'csstemplate', 'jstemplate',
|
||||||
|
'asearchtemplate', 'defaultsortdir', 'defaultsort'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now overwrite current data settings.
|
||||||
|
foreach ($module as $prop => $unused) {
|
||||||
|
if (in_array($prop, $overwrite)) {
|
||||||
|
$module->$prop = $settings->$prop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data_update_instance($module);
|
||||||
|
|
||||||
|
return $this->cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any clean up routines should go here
|
||||||
|
*
|
||||||
|
* @return bool Wether the preset has been successfully cleaned up.
|
||||||
|
*/
|
||||||
|
public function cleanup(): bool {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the importing process needs fields mapping.
|
||||||
|
*
|
||||||
|
* @return bool True if the current database needs to map the fields imported.
|
||||||
|
*/
|
||||||
|
public function needs_mapping(): bool {
|
||||||
|
return $this->manager->has_fields();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the information we need to build the importer selector.
|
||||||
|
*
|
||||||
|
* @return array Value and name for the preset importer selector
|
||||||
|
*/
|
||||||
|
public function get_preset_selector(): array {
|
||||||
|
return ['name' => 'directory', 'value' => $this->get_directory()];
|
||||||
|
}
|
||||||
|
}
|
55
mod/data/classes/local/importer/preset_upload_importer.php
Normal file
55
mod/data/classes/local/importer/preset_upload_importer.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?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/>.
|
||||||
|
|
||||||
|
namespace mod_data\local\importer;
|
||||||
|
|
||||||
|
use mod_data\manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data preset importer for uploaded presets
|
||||||
|
*
|
||||||
|
* @package mod_data
|
||||||
|
* @copyright 2022 Amaia Anabitarte <amaia@moodle.com>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
class preset_upload_importer extends preset_importer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param manager $manager
|
||||||
|
* @param string $filepath
|
||||||
|
*/
|
||||||
|
public function __construct(manager $manager, string $filepath) {
|
||||||
|
if (is_file($filepath)) {
|
||||||
|
$fp = get_file_packer();
|
||||||
|
if ($fp->extract_to_pathname($filepath, $filepath.'_extracted')) {
|
||||||
|
fulldelete($filepath);
|
||||||
|
}
|
||||||
|
$filepath .= '_extracted';
|
||||||
|
}
|
||||||
|
parent::__construct($manager, $filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean uploaded files up
|
||||||
|
*
|
||||||
|
* @return bool Wether the preset has been successfully cleaned up.
|
||||||
|
*/
|
||||||
|
public function cleanup(): bool {
|
||||||
|
return fulldelete($this->directory);
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,23 +59,11 @@ class action_bar {
|
||||||
global $PAGE, $DB;
|
global $PAGE, $DB;
|
||||||
|
|
||||||
$createfieldlink = new moodle_url('/mod/data/field.php', ['d' => $this->id]);
|
$createfieldlink = new moodle_url('/mod/data/field.php', ['d' => $this->id]);
|
||||||
$importlink = new moodle_url('/mod/data/field.php', ['d' => $this->id, 'mode' => 'import']);
|
|
||||||
$presetslink = new moodle_url('/mod/data/field.php', ['d' => $this->id, 'mode' => 'usepreset']);
|
|
||||||
|
|
||||||
$menu = [
|
$menu = [
|
||||||
$createfieldlink->out(false) => get_string('managefields', 'mod_data'),
|
$createfieldlink->out(false) => get_string('managefields', 'mod_data'),
|
||||||
$importlink->out(false) => get_string('importpreset', 'mod_data'),
|
|
||||||
$presetslink->out(false) => get_string('usestandard', 'mod_data'),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$selected = $createfieldlink->out(false);
|
$selected = $createfieldlink->out(false);
|
||||||
$mode = $this->currenturl->get_param('mode');
|
|
||||||
|
|
||||||
if ($mode == 'import') {
|
|
||||||
$selected = $importlink->out(false);
|
|
||||||
} else if ($mode === 'usepreset') {
|
|
||||||
$selected = $presetslink->out(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
$urlselect = new url_select($menu, $selected, null, 'fieldactionselect');
|
$urlselect = new url_select($menu, $selected, null, 'fieldactionselect');
|
||||||
$urlselect->set_label(get_string('fieldsnavigation', 'mod_data'), ['class' => 'sr-only']);
|
$urlselect->set_label(get_string('fieldsnavigation', 'mod_data'), ['class' => 'sr-only']);
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use mod_data\manager;
|
use mod_data\manager;
|
||||||
|
use mod_data\local\importer\preset_existing_importer;
|
||||||
|
use mod_data\local\importer\preset_upload_importer;
|
||||||
|
|
||||||
require_once('../../config.php');
|
require_once('../../config.php');
|
||||||
require_once('lib.php');
|
require_once('lib.php');
|
||||||
|
@ -119,21 +121,6 @@ $data->instance = $cm->instance;
|
||||||
***********************************/
|
***********************************/
|
||||||
$renderer = $manager->get_renderer();
|
$renderer = $manager->get_renderer();
|
||||||
|
|
||||||
if ($formimportzip->is_cancelled()) {
|
|
||||||
redirect(new moodle_url('/mod/data/field.php', ['d' => $data->id]));
|
|
||||||
} else if ($formdata = $formimportzip->get_data()) {
|
|
||||||
$fieldactionbar = $actionbar->get_fields_action_bar();
|
|
||||||
data_print_header($course, $cm, $data, false, $fieldactionbar);
|
|
||||||
echo $OUTPUT->heading(get_string('importpreset', 'data'), 2, 'mb-4');
|
|
||||||
$file = new stdClass;
|
|
||||||
$file->name = $formimportzip->get_new_filename('importfile');
|
|
||||||
$file->path = $formimportzip->save_temp_file('importfile');
|
|
||||||
$importer = new data_preset_upload_importer($course, $cm, $data, $file->path);
|
|
||||||
echo $renderer->import_setting_mappings($data, $importer);
|
|
||||||
echo $OUTPUT->footer();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($action == 'finishimport' && confirm_sesskey()) {
|
if ($action == 'finishimport' && confirm_sesskey()) {
|
||||||
data_print_header($course, $cm, $data, false);
|
data_print_header($course, $cm, $data, false);
|
||||||
$overwritesettings = optional_param('overwritesettings', false, PARAM_BOOL);
|
$overwritesettings = optional_param('overwritesettings', false, PARAM_BOOL);
|
||||||
|
@ -143,26 +130,28 @@ if ($action == 'finishimport' && confirm_sesskey()) {
|
||||||
if (!file_exists($presetdir) || !is_dir($presetdir)) {
|
if (!file_exists($presetdir) || !is_dir($presetdir)) {
|
||||||
throw new moodle_exception('cannotimport', 'error');
|
throw new moodle_exception('cannotimport', 'error');
|
||||||
}
|
}
|
||||||
$importer = new data_preset_upload_importer($course, $cm, $data, $presetdir);
|
$importer = new preset_upload_importer($manager, $presetdir);
|
||||||
} else {
|
} else {
|
||||||
$importer = new data_preset_existing_importer($course, $cm, $data, $fullname);
|
$importer = new preset_existing_importer($manager, $fullname);
|
||||||
}
|
}
|
||||||
|
|
||||||
$importer->import($overwritesettings);
|
if ($importer->needs_mapping()) {
|
||||||
$strimportsuccess = get_string('importsuccess', 'data');
|
$importer->import($overwritesettings);
|
||||||
$straddentries = get_string('addentries', 'data');
|
$strimportsuccess = get_string('importsuccess', 'data');
|
||||||
$strtodatabase = get_string('todatabase', 'data');
|
$straddentries = get_string('addentries', 'data');
|
||||||
|
$strtodatabase = get_string('todatabase', 'data');
|
||||||
|
|
||||||
if (!$DB->get_records('data_records', array('dataid' => $data->id))) {
|
if (!$DB->get_records('data_records', array('dataid' => $data->id))) {
|
||||||
echo $OUTPUT->notification("$strimportsuccess <a href='edit.php?d=$data->id'>$straddentries</a> $strtodatabase",
|
echo $OUTPUT->notification("$strimportsuccess <a href='edit.php?d=$data->id'>$straddentries</a> $strtodatabase",
|
||||||
'notifysuccess');
|
'notifysuccess');
|
||||||
} else {
|
} else {
|
||||||
echo $OUTPUT->notification("$strimportsuccess", 'notifysuccess');
|
echo $OUTPUT->notification("$strimportsuccess", 'notifysuccess');
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $OUTPUT->continue_button(new moodle_url('/mod/data/field.php', ['d' => $data->id]));
|
||||||
|
echo $OUTPUT->footer();
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
echo $OUTPUT->continue_button(new moodle_url('/mod/data/field.php', ['d' => $data->id]));
|
|
||||||
echo $OUTPUT->footer();
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
|
@ -295,34 +284,23 @@ switch ($mode) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'import':
|
|
||||||
$PAGE->navbar->add(get_string('importpreset', 'data'));
|
|
||||||
$fieldactionbar = $actionbar->get_fields_action_bar();
|
|
||||||
data_print_header($course, $cm, $data, false, $fieldactionbar);
|
|
||||||
|
|
||||||
echo $OUTPUT->heading(get_string('importpreset', 'data'), 2, 'mb-4');
|
|
||||||
echo $formimportzip->display();
|
|
||||||
echo $OUTPUT->footer();
|
|
||||||
exit;
|
|
||||||
|
|
||||||
case 'usepreset':
|
case 'usepreset':
|
||||||
|
$importer = new preset_existing_importer($manager, $fullname);
|
||||||
|
if (!$importer->needs_mapping()) {
|
||||||
|
$backurl = new moodle_url('/mod/data/field.php', ['id' => $cm->id]);
|
||||||
|
if ($importer->import(false)) {
|
||||||
|
\core\notification::success(get_string('importsuccess', 'mod_data'));
|
||||||
|
} else {
|
||||||
|
\core\notification::error(get_string('presetapplied', 'mod_data'));
|
||||||
|
}
|
||||||
|
redirect($backurl);
|
||||||
|
}
|
||||||
$PAGE->navbar->add(get_string('usestandard', 'data'));
|
$PAGE->navbar->add(get_string('usestandard', 'data'));
|
||||||
$fieldactionbar = $actionbar->get_fields_action_bar();
|
$fieldactionbar = $actionbar->get_fields_action_bar();
|
||||||
data_print_header($course, $cm, $data, false, $fieldactionbar);
|
data_print_header($course, $cm, $data, false, $fieldactionbar);
|
||||||
|
echo $OUTPUT->heading(get_string('usestandard', 'data'), 2, 'mb-4');
|
||||||
if ($action === 'select') {
|
$importer = new preset_existing_importer($manager, $fullname);
|
||||||
if (!empty($fullname)) {
|
echo $renderer->importing_preset($data, $importer);
|
||||||
echo $OUTPUT->heading(get_string('usestandard', 'data'), 2, 'mb-4');
|
|
||||||
$importer = new data_preset_existing_importer($course, $cm, $data, $fullname);
|
|
||||||
echo $renderer->import_setting_mappings($data, $importer);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
echo $OUTPUT->heading(get_string('presets', 'data'), 2, 'mb-4');
|
|
||||||
$presets = $manager->get_available_presets();
|
|
||||||
$presetsdata = new \mod_data\output\presets($data->id, $presets,
|
|
||||||
new \moodle_url('/mod/data/field.php'));
|
|
||||||
echo $renderer->render_presets($presetsdata);
|
|
||||||
}
|
|
||||||
echo $OUTPUT->footer();
|
echo $OUTPUT->footer();
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,6 @@ Fields have the format [[fieldname]]. All other tags have the format ##sometag##
|
||||||
Only the tags that are in the "Available tags" list may be used for the current template.';
|
Only the tags that are in the "Available tags" list may be used for the current template.';
|
||||||
$string['availabletodate'] = 'Available to';
|
$string['availabletodate'] = 'Available to';
|
||||||
$string['availabletodatevalidation'] = 'The available to date cannot be before the available from date.';
|
$string['availabletodatevalidation'] = 'The available to date cannot be before the available from date.';
|
||||||
$string['blank'] = 'Blank';
|
|
||||||
$string['bynameondate'] = 'by {$a->name} - {$a->date}';
|
$string['bynameondate'] = 'by {$a->name} - {$a->date}';
|
||||||
$string['calendarend'] = '{$a} closes';
|
$string['calendarend'] = '{$a} closes';
|
||||||
$string['calendarstart'] = '{$a} opens';
|
$string['calendarstart'] = '{$a} opens';
|
||||||
|
@ -452,3 +451,4 @@ $string['unsupportedexport'] = '({$a->fieldtype}) cannot be exported.';
|
||||||
$string['buttons'] = 'Actions';
|
$string['buttons'] = 'Actions';
|
||||||
$string['nolisttemplate'] = 'List template is not yet defined';
|
$string['nolisttemplate'] = 'List template is not yet defined';
|
||||||
$string['nosingletemplate'] = 'Single template is not yet defined';
|
$string['nosingletemplate'] = 'Single template is not yet defined';
|
||||||
|
$string['blank'] = 'Blank';
|
||||||
|
|
|
@ -2,3 +2,4 @@ unsupportedexport,mod_data
|
||||||
buttons,mod_data
|
buttons,mod_data
|
||||||
nosingletemplate,mod_data
|
nosingletemplate,mod_data
|
||||||
nolisttemplate,mod_data
|
nolisttemplate,mod_data
|
||||||
|
blank,mod_data
|
||||||
|
|
|
@ -1121,7 +1121,9 @@ function data_update_instance($data) {
|
||||||
require_once($CFG->dirroot.'/mod/data/locallib.php');
|
require_once($CFG->dirroot.'/mod/data/locallib.php');
|
||||||
|
|
||||||
$data->timemodified = time();
|
$data->timemodified = time();
|
||||||
$data->id = $data->instance;
|
if (!empty($data->instance)) {
|
||||||
|
$data->id = $data->instance;
|
||||||
|
}
|
||||||
|
|
||||||
if (empty($data->assessed)) {
|
if (empty($data->assessed)) {
|
||||||
$data->assessed = 0;
|
$data->assessed = 0;
|
||||||
|
@ -2271,6 +2273,9 @@ function is_directory_a_preset($directory) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class used for data preset importers
|
* Abstract class used for data preset importers
|
||||||
|
*
|
||||||
|
* @deprecated since Moodle 4.1 MDL-75140 - please do not use this class any more.
|
||||||
|
* @todo MDL-75189 Final deprecation in Moodle 4.5.
|
||||||
*/
|
*/
|
||||||
abstract class data_preset_importer {
|
abstract class data_preset_importer {
|
||||||
|
|
||||||
|
@ -2288,6 +2293,11 @@ abstract class data_preset_importer {
|
||||||
* @param string $directory
|
* @param string $directory
|
||||||
*/
|
*/
|
||||||
public function __construct($course, $cm, $module, $directory) {
|
public function __construct($course, $cm, $module, $directory) {
|
||||||
|
debugging(
|
||||||
|
'data_preset_importer is deprecated. Please use mod\\data\\local\\importer\\preset_importer instead',
|
||||||
|
DEBUG_DEVELOPER
|
||||||
|
);
|
||||||
|
|
||||||
$this->course = $course;
|
$this->course = $course;
|
||||||
$this->cm = $cm;
|
$this->cm = $cm;
|
||||||
$this->module = $module;
|
$this->module = $module;
|
||||||
|
@ -2552,10 +2562,19 @@ abstract class data_preset_importer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data preset importer for uploaded presets
|
* Data preset importer for uploaded presets
|
||||||
|
*
|
||||||
|
* @deprecated since Moodle 4.1 MDL-75140 - please do not use this class any more.
|
||||||
|
* @todo MDL-75189 Final deprecation in Moodle 4.5.
|
||||||
*/
|
*/
|
||||||
class data_preset_upload_importer extends data_preset_importer {
|
class data_preset_upload_importer extends data_preset_importer {
|
||||||
public function __construct($course, $cm, $module, $filepath) {
|
public function __construct($course, $cm, $module, $filepath) {
|
||||||
global $USER;
|
global $USER;
|
||||||
|
|
||||||
|
debugging(
|
||||||
|
'data_preset_upload_importer is deprecated. Please use mod\\data\\local\\importer\\preset_upload_importer instead',
|
||||||
|
DEBUG_DEVELOPER
|
||||||
|
);
|
||||||
|
|
||||||
if (is_file($filepath)) {
|
if (is_file($filepath)) {
|
||||||
$fp = get_file_packer();
|
$fp = get_file_packer();
|
||||||
if ($fp->extract_to_pathname($filepath, $filepath.'_extracted')) {
|
if ($fp->extract_to_pathname($filepath, $filepath.'_extracted')) {
|
||||||
|
@ -2572,11 +2591,20 @@ class data_preset_upload_importer extends data_preset_importer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data preset importer for existing presets
|
* Data preset importer for existing presets
|
||||||
|
*
|
||||||
|
* @deprecated since Moodle 4.1 MDL-75140 - please do not use this class any more.
|
||||||
|
* @todo MDL-75189 Final deprecation in Moodle 4.5.
|
||||||
*/
|
*/
|
||||||
class data_preset_existing_importer extends data_preset_importer {
|
class data_preset_existing_importer extends data_preset_importer {
|
||||||
protected $userid;
|
protected $userid;
|
||||||
public function __construct($course, $cm, $module, $fullname) {
|
public function __construct($course, $cm, $module, $fullname) {
|
||||||
global $USER;
|
global $USER;
|
||||||
|
|
||||||
|
debugging(
|
||||||
|
'data_preset_existing_importer is deprecated. Please use mod\\data\\local\\importer\\preset_existing_importer instead',
|
||||||
|
DEBUG_DEVELOPER
|
||||||
|
);
|
||||||
|
|
||||||
list($userid, $shortname) = explode('/', $fullname, 2);
|
list($userid, $shortname) = explode('/', $fullname, 2);
|
||||||
$context = context_module::instance($cm->id);
|
$context = context_module::instance($cm->id);
|
||||||
if ($userid && ($userid != $USER->id) && !has_capability('mod/data:manageuserpresets', $context) && !has_capability('mod/data:viewalluserpresets', $context)) {
|
if ($userid && ($userid != $USER->id) && !has_capability('mod/data:manageuserpresets', $context) && !has_capability('mod/data:viewalluserpresets', $context)) {
|
||||||
|
|
|
@ -32,6 +32,8 @@ use mod_data\manager;
|
||||||
use mod_data\preset;
|
use mod_data\preset;
|
||||||
use mod_data\output\action_bar;
|
use mod_data\output\action_bar;
|
||||||
use mod_data\output\preset_preview;
|
use mod_data\output\preset_preview;
|
||||||
|
use mod_data\local\importer\preset_upload_importer;
|
||||||
|
use mod_data\local\importer\preset_existing_importer;
|
||||||
|
|
||||||
require_once('../../config.php');
|
require_once('../../config.php');
|
||||||
require_once($CFG->dirroot.'/mod/data/lib.php');
|
require_once($CFG->dirroot.'/mod/data/lib.php');
|
||||||
|
@ -139,19 +141,25 @@ if ($action === 'preview') {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
echo $OUTPUT->header();
|
|
||||||
|
|
||||||
if ($formdata = $formimportzip->get_data()) {
|
if ($formdata = $formimportzip->get_data()) {
|
||||||
echo $OUTPUT->heading(get_string('importpreset', 'data'), 2, 'mb-4');
|
|
||||||
$file = new stdClass;
|
$file = new stdClass;
|
||||||
$file->name = $formimportzip->get_new_filename('importfile');
|
$file->name = $formimportzip->get_new_filename('importfile');
|
||||||
$file->path = $formimportzip->save_temp_file('importfile');
|
$file->path = $formimportzip->save_temp_file('importfile');
|
||||||
$importer = new data_preset_upload_importer($course, $cm, $data, $file->path);
|
$importer = new preset_upload_importer($manager, $file->path);
|
||||||
echo $renderer->import_setting_mappings($data, $importer);
|
if ($importer->needs_mapping()) {
|
||||||
echo $OUTPUT->footer();
|
echo $OUTPUT->header();
|
||||||
exit(0);
|
echo $OUTPUT->heading(get_string('importpreset', 'data'), 2, 'mb-4');
|
||||||
|
echo $renderer->importing_preset($data, $importer);
|
||||||
|
echo $OUTPUT->footer();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$importer->import(false);
|
||||||
|
redirect(new moodle_url('/mod/data/field.php', ['id' => $cm->id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
echo $OUTPUT->header();
|
||||||
|
|
||||||
if ($action === 'finishimport') {
|
if ($action === 'finishimport') {
|
||||||
$fullname = optional_param('fullname', '' , PARAM_PATH); // The directory the preset is in.
|
$fullname = optional_param('fullname', '' , PARAM_PATH); // The directory the preset is in.
|
||||||
// Find out preset owner userid and shortname.
|
// Find out preset owner userid and shortname.
|
||||||
|
@ -169,9 +177,9 @@ if ($action === 'finishimport') {
|
||||||
if (!file_exists($presetdir) || !is_dir($presetdir)) {
|
if (!file_exists($presetdir) || !is_dir($presetdir)) {
|
||||||
throw new \moodle_exception('cannotimport');
|
throw new \moodle_exception('cannotimport');
|
||||||
}
|
}
|
||||||
$importer = new data_preset_upload_importer($course, $cm, $data, $presetdir);
|
$importer = new preset_upload_importer($manager, $presetdir);
|
||||||
} else {
|
} else {
|
||||||
$importer = new data_preset_existing_importer($course, $cm, $data, $fullname);
|
$importer = new preset_existing_importer($manager, $fullname);
|
||||||
}
|
}
|
||||||
$importer->import($overwritesettings);
|
$importer->import($overwritesettings);
|
||||||
$strimportsuccess = get_string('importsuccess', 'data');
|
$strimportsuccess = get_string('importsuccess', 'data');
|
||||||
|
|
|
@ -23,8 +23,6 @@ Feature: Users can use the Image gallery preset
|
||||||
And I follow "Presets"
|
And I follow "Presets"
|
||||||
And I click on "fullname" "radio" in the "Image gallery" "table_row"
|
And I click on "fullname" "radio" in the "Image gallery" "table_row"
|
||||||
And I click on "Use preset" "button"
|
And I click on "Use preset" "button"
|
||||||
And I click on "Continue" "button"
|
|
||||||
And I click on "Continue" "button"
|
|
||||||
And the following "mod_data > entries" exist:
|
And the following "mod_data > entries" exist:
|
||||||
| database | user | title | description | image |
|
| database | user | title | description | image |
|
||||||
| data1 | student1 | First image | This is the description text for image 1 | first.png |
|
| data1 | student1 | First image | This is the description text for image 1 | first.png |
|
||||||
|
|
|
@ -23,8 +23,6 @@ Feature: Users can use the Journal preset
|
||||||
And I follow "Presets"
|
And I follow "Presets"
|
||||||
And I click on "fullname" "radio" in the "Journal" "table_row"
|
And I click on "fullname" "radio" in the "Journal" "table_row"
|
||||||
And I click on "Use preset" "button"
|
And I click on "Use preset" "button"
|
||||||
And I click on "Continue" "button"
|
|
||||||
And I click on "Continue" "button"
|
|
||||||
And the following "mod_data > entries" exist:
|
And the following "mod_data > entries" exist:
|
||||||
| database | user | Title | Content |
|
| database | user | Title | Content |
|
||||||
| data1 | student1 | Reflection created by student | This is the content for the entry 1 |
|
| data1 | student1 | Reflection created by student | This is the content for the entry 1 |
|
||||||
|
|
|
@ -23,8 +23,6 @@ Feature: Users can use the Proposals preset
|
||||||
And I follow "Presets"
|
And I follow "Presets"
|
||||||
And I click on "fullname" "radio" in the "Proposals" "table_row"
|
And I click on "fullname" "radio" in the "Proposals" "table_row"
|
||||||
And I click on "Use preset" "button"
|
And I click on "Use preset" "button"
|
||||||
And I click on "Continue" "button"
|
|
||||||
And I click on "Continue" "button"
|
|
||||||
And the following "mod_data > entries" exist:
|
And the following "mod_data > entries" exist:
|
||||||
| database | user | Title | Summary | Content | Status |
|
| database | user | Title | Summary | Content | Status |
|
||||||
| data1 | student1 | Project created by student | Summary 1 | Content for entry 1 | Pending |
|
| data1 | student1 | Project created by student | Summary 1 | Content for entry 1 | Pending |
|
||||||
|
|
|
@ -23,8 +23,6 @@ Feature: Users can use the Resources preset
|
||||||
And I follow "Presets"
|
And I follow "Presets"
|
||||||
And I click on "fullname" "radio" in the "Resources" "table_row"
|
And I click on "fullname" "radio" in the "Resources" "table_row"
|
||||||
And I click on "Use preset" "button"
|
And I click on "Use preset" "button"
|
||||||
And I click on "Continue" "button"
|
|
||||||
And I click on "Continue" "button"
|
|
||||||
And the following "mod_data > entries" exist:
|
And the following "mod_data > entries" exist:
|
||||||
| database | user | Title | Description | Type | Author | Web link | Cover |
|
| database | user | Title | Description | Type | Author | Web link | Cover |
|
||||||
| data1 | student1 | My favourite book | Book content | Type1 | The book author | http://myfavouritebook.cat | first.png |
|
| data1 | student1 | My favourite book | Book content | Type1 | The book author | http://myfavouritebook.cat | first.png |
|
||||||
|
|
|
@ -1,35 +1,58 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use mod_data\local\importer\preset_existing_importer;
|
||||||
|
|
||||||
defined('MOODLE_INTERNAL') || die();
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
class mod_data_renderer extends plugin_renderer_base {
|
class mod_data_renderer extends plugin_renderer_base {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rendering setting and mapping page to import a preset.
|
||||||
|
*
|
||||||
|
* @param stdClass $datamodule Database module to import to.
|
||||||
|
* @param data_preset_importer $importer Importer instance to use for the importing.
|
||||||
|
* @return string
|
||||||
|
* @deprecated since Moodle 4.1 MDL-75140 - please do not use this class any more.
|
||||||
|
* @todo MDL-75189 Final deprecation in Moodle 4.5.
|
||||||
|
*/
|
||||||
public function import_setting_mappings($datamodule, data_preset_importer $importer) {
|
public function import_setting_mappings($datamodule, data_preset_importer $importer) {
|
||||||
|
debugging('import_setting_mappings is deprecated. Please use importing_preset instead', DEBUG_DEVELOPER);
|
||||||
|
|
||||||
|
$manager = \mod_data\manager::create_from_coursemodule($datamodule);
|
||||||
|
$fullname = $importer->get_directory();
|
||||||
|
return $this->importing_preset($datamodule, new preset_existing_importer($manager, $fullname));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Importing a preset on a database module.
|
||||||
|
*
|
||||||
|
* @param stdClass $datamodule Database module to import to.
|
||||||
|
* @param \mod_data\local\importer\preset_importer $importer Importer instance to use for the importing.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function importing_preset(stdClass $datamodule, \mod_data\local\importer\preset_importer $importer): string {
|
||||||
|
|
||||||
$strblank = get_string('blank', 'data');
|
|
||||||
$strcontinue = get_string('continue');
|
$strcontinue = get_string('continue');
|
||||||
$strwarning = get_string('mappingwarning', 'data');
|
$strwarning = get_string('mappingwarning', 'data');
|
||||||
$strfieldmappings = get_string('fieldmappings', 'data');
|
$strfieldmappings = get_string('fieldmappings', 'data');
|
||||||
$strnew = get_string('new');
|
|
||||||
|
|
||||||
|
|
||||||
$params = $importer->get_preset_settings();
|
$params = $importer->get_preset_settings();
|
||||||
$settings = $params->settings;
|
|
||||||
$newfields = $params->importfields;
|
$newfields = $params->importfields;
|
||||||
$currentfields = $params->currentfields;
|
$currentfields = $params->currentfields;
|
||||||
|
|
||||||
$html = html_writer::start_tag('div', array('class'=>'presetmapping'));
|
$html = html_writer::start_tag('div', ['class'=>'presetmapping']);
|
||||||
$html .= html_writer::start_tag('form', array('method'=>'post', 'action'=>''));
|
$html .= html_writer::start_tag('form', ['method'=>'post', 'action'=>'']);
|
||||||
$html .= html_writer::start_tag('div');
|
$html .= html_writer::start_tag('div');
|
||||||
$html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'action', 'value'=>'finishimport'));
|
$html .= html_writer::empty_tag('input', ['type'=>'hidden', 'name'=>'action', 'value'=>'finishimport']);
|
||||||
$html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'sesskey', 'value'=>sesskey()));
|
$html .= html_writer::empty_tag('input', ['type'=>'hidden', 'name'=>'sesskey', 'value'=>sesskey()]);
|
||||||
$html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'d', 'value'=>$datamodule->id));
|
$html .= html_writer::empty_tag('input', ['type'=>'hidden', 'name'=>'d', 'value'=>$datamodule->id]);
|
||||||
|
|
||||||
if ($importer instanceof data_preset_existing_importer) {
|
$inputselector = $importer->get_preset_selector();
|
||||||
$html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'fullname', 'value'=>$importer->get_userid().'/'.$importer->get_directory()));
|
$html .= html_writer::empty_tag(
|
||||||
} else {
|
'input',
|
||||||
$html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'directory', 'value'=>$importer->get_directory()));
|
['type'=>'hidden', 'name'=> $inputselector['name'], 'value' => $inputselector['value']]
|
||||||
}
|
);
|
||||||
|
|
||||||
if (!empty($newfields)) {
|
if (!empty($newfields)) {
|
||||||
$html .= $this->output->heading_with_help($strfieldmappings, 'fieldmappings', 'data', '', '', 3);
|
$html .= $this->output->heading_with_help($strfieldmappings, 'fieldmappings', 'data', '', '', 3);
|
||||||
|
|
121
mod/data/tests/behat/import_presets.feature
Normal file
121
mod/data/tests/behat/import_presets.feature
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
@mod @mod_data @javascript @_file_upload
|
||||||
|
Feature: Users can import presets
|
||||||
|
In order to use presets
|
||||||
|
As a user
|
||||||
|
I need to import and apply presets from zip files
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given the following "users" exist:
|
||||||
|
| username | firstname | lastname | email |
|
||||||
|
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||||
|
And the following "courses" exist:
|
||||||
|
| fullname | shortname | category |
|
||||||
|
| Course 1 | C1 | 0 |
|
||||||
|
And the following "course enrolments" exist:
|
||||||
|
| user | course | role |
|
||||||
|
| teacher1 | C1 | editingteacher |
|
||||||
|
And the following "activities" exist:
|
||||||
|
| activity | name | intro | course | idnumber |
|
||||||
|
| data | Mountain landscapes | n | C1 | data1 |
|
||||||
|
And the following "mod_data > presets" exist:
|
||||||
|
| database | name | description |
|
||||||
|
| data1 | Saved preset 1 | The preset1 has description |
|
||||||
|
| data1 | Saved preset 2 | |
|
||||||
|
|
||||||
|
Scenario: Teacher can import from preset page on an empty database
|
||||||
|
Given I am on the "Mountain landscapes" "data activity" page logged in as teacher1
|
||||||
|
And I follow "Presets"
|
||||||
|
And I click on "Import" "link"
|
||||||
|
And I upload "mod/data/tests/fixtures/image_gallery_preset.zip" file to "Choose file" filemanager
|
||||||
|
When I click on "Save" "button"
|
||||||
|
Then I should not see "Field mappings"
|
||||||
|
And I should see "Image" in the "image" "table_row"
|
||||||
|
|
||||||
|
Scenario: Teacher can import from preset page on a database with fields
|
||||||
|
Given the following "mod_data > fields" exist:
|
||||||
|
| database | type | name | description |
|
||||||
|
| data1 | text | Test field name | Test field description |
|
||||||
|
And I am on the "Mountain landscapes" "data activity" page logged in as teacher1
|
||||||
|
And I follow "Presets"
|
||||||
|
And I click on "Import" "link"
|
||||||
|
And I upload "mod/data/tests/fixtures/image_gallery_preset.zip" file to "Choose file" filemanager
|
||||||
|
When I click on "Save" "button"
|
||||||
|
Then I should see "Field mappings"
|
||||||
|
And I should see "image"
|
||||||
|
And I should see "Create a new field" in the "image" "table_row"
|
||||||
|
|
||||||
|
Scenario: Teacher can import from preset page on a database with entries
|
||||||
|
And the following "mod_data > fields" exist:
|
||||||
|
| database | type | name | description |
|
||||||
|
| data1 | text | field1 | Test field description |
|
||||||
|
And the following "mod_data > templates" exist:
|
||||||
|
| database | name |
|
||||||
|
| data1 | singletemplate |
|
||||||
|
| data1 | listtemplate |
|
||||||
|
| data1 | addtemplate |
|
||||||
|
| data1 | asearchtemplate |
|
||||||
|
| data1 | rsstemplate |
|
||||||
|
And the following "mod_data > entries" exist:
|
||||||
|
| database | field1 |
|
||||||
|
| data1 | Student entry 1 |
|
||||||
|
And I am on the "Mountain landscapes" "data activity" page logged in as teacher1
|
||||||
|
And I follow "Presets"
|
||||||
|
And I click on "Import" "link"
|
||||||
|
And I upload "mod/data/tests/fixtures/image_gallery_preset.zip" file to "Choose file" filemanager
|
||||||
|
When I click on "Save" "button"
|
||||||
|
Then I should see "Field mappings"
|
||||||
|
And I should see "image"
|
||||||
|
And I should see "Create a new field" in the "image" "table_row"
|
||||||
|
|
||||||
|
Scenario: Teacher can import from field page on an empty database
|
||||||
|
Given I am on the "Mountain landscapes" "data activity" page logged in as teacher1
|
||||||
|
And I follow "Presets"
|
||||||
|
And I click on "Import" "button"
|
||||||
|
And I upload "mod/data/tests/fixtures/image_gallery_preset.zip" file to "Choose file" filemanager
|
||||||
|
When I click on "Save" "button"
|
||||||
|
Then I should not see "Field mappings"
|
||||||
|
And I should see "Image" in the "image" "table_row"
|
||||||
|
|
||||||
|
Scenario: Teacher can import from field page on a database with fields
|
||||||
|
Given the following "mod_data > fields" exist:
|
||||||
|
| database | type | name | description |
|
||||||
|
| data1 | text | Test field name | Test field description |
|
||||||
|
And I am on the "Mountain landscapes" "data activity" page logged in as teacher1
|
||||||
|
And I follow "Presets"
|
||||||
|
And I click on "Import" "button"
|
||||||
|
And I upload "mod/data/tests/fixtures/image_gallery_preset.zip" file to "Choose file" filemanager
|
||||||
|
When I click on "Save" "button"
|
||||||
|
Then I should see "Field mappings"
|
||||||
|
And I should see "image"
|
||||||
|
And I should see "Create a new field" in the "image" "table_row"
|
||||||
|
|
||||||
|
Scenario: Teacher can import from field page on a database with entries
|
||||||
|
And the following "mod_data > fields" exist:
|
||||||
|
| database | type | name | description |
|
||||||
|
| data1 | text | field1 | Test field description |
|
||||||
|
And the following "mod_data > templates" exist:
|
||||||
|
| database | name |
|
||||||
|
| data1 | singletemplate |
|
||||||
|
| data1 | listtemplate |
|
||||||
|
| data1 | addtemplate |
|
||||||
|
| data1 | asearchtemplate |
|
||||||
|
| data1 | rsstemplate |
|
||||||
|
And the following "mod_data > entries" exist:
|
||||||
|
| database | field1 |
|
||||||
|
| data1 | Student entry 1 |
|
||||||
|
And I am on the "Mountain landscapes" "data activity" page logged in as teacher1
|
||||||
|
And I follow "Presets"
|
||||||
|
And I click on "Import" "button"
|
||||||
|
And I upload "mod/data/tests/fixtures/image_gallery_preset.zip" file to "Choose file" filemanager
|
||||||
|
When I click on "Save" "button"
|
||||||
|
Then I should see "Field mappings"
|
||||||
|
And I should see "image"
|
||||||
|
And I should see "Create a new field" in the "image" "table_row"
|
||||||
|
|
||||||
|
Scenario: Teacher can import from zero state page on an empty database
|
||||||
|
Given I am on the "Mountain landscapes" "data activity" page logged in as teacher1
|
||||||
|
And I click on "Import a preset" "button"
|
||||||
|
And I upload "mod/data/tests/fixtures/image_gallery_preset.zip" file to "Choose file" filemanager
|
||||||
|
When I click on "Save" "button"
|
||||||
|
Then I should not see "Field mappings"
|
||||||
|
And I should see "Image" in the "image" "table_row"
|
|
@ -28,7 +28,6 @@ Feature: Users can preview presets
|
||||||
And I click on "Import" "button"
|
And I click on "Import" "button"
|
||||||
And I upload "mod/data/tests/fixtures/behat_preset.zip" file to "Choose file" filemanager
|
And I upload "mod/data/tests/fixtures/behat_preset.zip" file to "Choose file" filemanager
|
||||||
And I click on "Save" "button"
|
And I click on "Save" "button"
|
||||||
And I click on "Continue" "button"
|
|
||||||
And I follow "Templates"
|
And I follow "Templates"
|
||||||
And I click on "Save as preset" "button"
|
And I click on "Save as preset" "button"
|
||||||
And I set the field "Name" to "Saved preset by teacher1"
|
And I set the field "Name" to "Saved preset by teacher1"
|
||||||
|
@ -75,7 +74,6 @@ Feature: Users can preview presets
|
||||||
And I click on "Import" "button"
|
And I click on "Import" "button"
|
||||||
And I upload "mod/data/tests/fixtures/behat_preset.zip" file to "Choose file" filemanager
|
And I upload "mod/data/tests/fixtures/behat_preset.zip" file to "Choose file" filemanager
|
||||||
And I click on "Save" "button"
|
And I click on "Save" "button"
|
||||||
And I click on "Continue" "button"
|
|
||||||
And I follow "Templates"
|
And I follow "Templates"
|
||||||
And I click on "Save as preset" "button"
|
And I click on "Save as preset" "button"
|
||||||
And I set the field "Name" to "Saved preset by teacher1"
|
And I set the field "Name" to "Saved preset by teacher1"
|
||||||
|
@ -141,8 +139,7 @@ Feature: Users can preview presets
|
||||||
Given I follow "Presets"
|
Given I follow "Presets"
|
||||||
And I click on "Image gallery" "link"
|
And I click on "Image gallery" "link"
|
||||||
When I click on "Use preset" "button"
|
When I click on "Use preset" "button"
|
||||||
Then I should see "Field mappings"
|
Then I should see "image"
|
||||||
And I should see "image"
|
|
||||||
And I should see "title"
|
And I should see "title"
|
||||||
|
|
||||||
@javascript @_file_upload
|
@javascript @_file_upload
|
||||||
|
@ -151,7 +148,6 @@ Feature: Users can preview presets
|
||||||
And I click on "Import" "button"
|
And I click on "Import" "button"
|
||||||
And I upload "mod/data/tests/fixtures/behat_preset.zip" file to "Choose file" filemanager
|
And I upload "mod/data/tests/fixtures/behat_preset.zip" file to "Choose file" filemanager
|
||||||
And I click on "Save" "button"
|
And I click on "Save" "button"
|
||||||
And I click on "Continue" "button"
|
|
||||||
And I follow "Templates"
|
And I follow "Templates"
|
||||||
And I click on "Save as preset" "button"
|
And I click on "Save as preset" "button"
|
||||||
And I set the field "Name" to "Saved preset by teacher1"
|
And I set the field "Name" to "Saved preset by teacher1"
|
||||||
|
@ -160,5 +156,4 @@ Feature: Users can preview presets
|
||||||
When I follow "Presets"
|
When I follow "Presets"
|
||||||
And I click on "Saved preset by teacher1" "link"
|
And I click on "Saved preset by teacher1" "link"
|
||||||
And I click on "Use preset" "button"
|
And I click on "Use preset" "button"
|
||||||
Then I should see "Field mappings"
|
Then I should see "My URL field"
|
||||||
And I should see "My URL field"
|
|
||||||
|
|
BIN
mod/data/tests/fixtures/image_gallery_preset.zip
vendored
Normal file
BIN
mod/data/tests/fixtures/image_gallery_preset.zip
vendored
Normal file
Binary file not shown.
94
mod/data/tests/preset_importer_test.php
Normal file
94
mod/data/tests/preset_importer_test.php
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
<?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/>.
|
||||||
|
|
||||||
|
namespace mod_data;
|
||||||
|
|
||||||
|
use mod_data\local\importer\preset_existing_importer;
|
||||||
|
use mod_data\local\importer\preset_upload_importer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preset importer tests class for mod_data.
|
||||||
|
*
|
||||||
|
* @package mod_data
|
||||||
|
* @category test
|
||||||
|
* @copyright 2022 Amaia Anabitarte <amaia@moodle.com>
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
* @coversDefaultClass \mod_data\local\importer\preset_importer
|
||||||
|
*/
|
||||||
|
class preset_importer_test extends \advanced_testcase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for needs_mapping method.
|
||||||
|
*
|
||||||
|
* @covers ::needs_mapping
|
||||||
|
*/
|
||||||
|
public function test_needs_mapping() {
|
||||||
|
global $CFG, $USER;
|
||||||
|
|
||||||
|
$this->resetAfterTest();
|
||||||
|
$this->setAdminUser();
|
||||||
|
|
||||||
|
// Create a course and a database activity.
|
||||||
|
$course = $this->getDataGenerator()->create_course();
|
||||||
|
$activity = $this->getDataGenerator()->create_module(manager::MODULE, ['course' => $course]);
|
||||||
|
$manager = manager::create_from_instance($activity);
|
||||||
|
|
||||||
|
// Create presets and importers.
|
||||||
|
$pluginname = 'imagegallery';
|
||||||
|
$plugin = preset::create_from_plugin(null, $pluginname);
|
||||||
|
$pluginimporter = new preset_existing_importer($manager, '/' . $pluginname);
|
||||||
|
|
||||||
|
$plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_data');
|
||||||
|
$record = (object) [
|
||||||
|
'name' => 'Testing preset name',
|
||||||
|
'description' => 'Testing preset description',
|
||||||
|
];
|
||||||
|
$saved = $plugingenerator->create_preset($activity, $record);
|
||||||
|
$savedimporter = new preset_existing_importer($manager, $USER->id . '/Testing preset name');
|
||||||
|
|
||||||
|
$fixturepath = $CFG->dirroot . '/mod/data/tests/fixtures/image_gallery_preset.zip';
|
||||||
|
|
||||||
|
// Create a storage file.
|
||||||
|
$draftid = file_get_unused_draft_itemid();
|
||||||
|
$filerecord = [
|
||||||
|
'component' => 'user',
|
||||||
|
'filearea' => 'draft',
|
||||||
|
'contextid' => \context_user::instance($USER->id)->id,
|
||||||
|
'itemid' => $draftid,
|
||||||
|
'filename' => 'image_gallery_preset.zip',
|
||||||
|
'filepath' => '/'
|
||||||
|
];
|
||||||
|
$fs = get_file_storage();
|
||||||
|
$file = $fs->create_file_from_pathname($filerecord, $fixturepath);
|
||||||
|
$uploadedimporter = new preset_upload_importer($manager, $file->get_filepath());
|
||||||
|
|
||||||
|
// Needs mapping returns false for empty databases.
|
||||||
|
$this->assertFalse($pluginimporter->needs_mapping());
|
||||||
|
$this->assertFalse($savedimporter->needs_mapping());
|
||||||
|
$this->assertFalse($uploadedimporter->needs_mapping());
|
||||||
|
|
||||||
|
// Add a field to the database.
|
||||||
|
$fieldrecord = new \stdClass();
|
||||||
|
$fieldrecord->name = 'field1';
|
||||||
|
$fieldrecord->type = 'text';
|
||||||
|
$plugingenerator->create_field($fieldrecord, $activity);
|
||||||
|
|
||||||
|
// Needs mapping returns true for non-empty databases.
|
||||||
|
$this->assertTrue($pluginimporter->needs_mapping());
|
||||||
|
$this->assertTrue($savedimporter->needs_mapping());
|
||||||
|
$this->assertTrue($uploadedimporter->needs_mapping());
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,11 @@ information provided here is intended especially for developers.
|
||||||
* data_user_can_add_entry() function returns false for any user if there is no field created on the database.
|
* data_user_can_add_entry() function returns false for any user if there is no field created on the database.
|
||||||
* From now on, the data_generate_default_template method will always return a string with the template content or an empty
|
* From now on, the data_generate_default_template method will always return a string with the template content or an empty
|
||||||
string when there is no content available.
|
string when there is no content available.
|
||||||
|
* The following classes have been deprecated from lib.php because they have been moved to use manager class:
|
||||||
|
- data_preset_importer
|
||||||
|
- data_preset_existing_importer
|
||||||
|
- data_preset_upload_importer
|
||||||
|
* import_setting_mappings() function has been deprecated. Use importing_preset() instead.
|
||||||
|
|
||||||
=== 3.7 ===
|
=== 3.7 ===
|
||||||
* External functions get_entries, get_entry and search_entries now return an additional field "tags" containing the entry tags.
|
* External functions get_entries, get_entry and search_entries now return an additional field "tags" containing the entry tags.
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
defined('MOODLE_INTERNAL') || die();
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
$plugin->version = 2022082601; // The current module version (Date: YYYYMMDDXX).
|
$plugin->version = 2022100600; // The current module version (Date: YYYYMMDDXX).
|
||||||
$plugin->requires = 2022041200; // Requires this Moodle version.
|
$plugin->requires = 2022041200; // Requires this Moodle version.
|
||||||
$plugin->component = 'mod_data'; // Full name of the plugin (used for diagnostics)
|
$plugin->component = 'mod_data'; // Full name of the plugin (used for diagnostics)
|
||||||
$plugin->cron = 0;
|
$plugin->cron = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue