# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: moodle/mod/data/lang/en/data.php
--- moodle/mod/data/lang/en/data.php Base (1.19)
+++ moodle/mod/data/lang/en/data.php Locally Modified (Based On 1.19)
@@ -120,6 +120,7 @@
 $string['entry'] = 'Entry';
 $string['entrysaved'] = 'Your entry has been saved';
 $string['errormustbeteacher'] = 'You need to be a teacher to use this page!';
+$string['errorpresetexists'] = 'There is already a preset with the selected name';
 $string['example'] = 'Database module example';
 $string['excel'] = 'Excel';
 $string['export'] = 'Export';
@@ -197,6 +198,8 @@
 $string['list'] = 'View list';
 $string['listtemplate'] = 'List template';
 $string['longitude'] = 'Longitude';
+$string['mapexistingfield'] = 'Map to {$a}';
+$string['mapnewfield'] = 'Create a new field';
 $string['mappingwarning'] = 'All old fields not mapped to a new field will be lost and all data in that field will be removed.';
 $string['maxentries'] = 'Maximum entries';
 $string['maxentries_help'] = 'The maximum number of entries a student is allowed to submit for this activity.';
@@ -253,6 +256,7 @@
 $string['optionalfilename'] = 'Filename (optional)';
 $string['other'] = 'Other';
 $string['overwrite'] = 'Overwrite';
+$string['overrwritedesc'] = 'Overwrite the preset if it already exists';
 $string['overwritesettings'] = 'Overwrite current settings';
 $string['pagesize'] = 'Entries per page';
 $string['participants'] = 'Participants';
Index: moodle/mod/data/lib.php
--- moodle/mod/data/lib.php Base (1.285)
+++ moodle/mod/data/lib.php Locally Modified (Based On 1.285)
@@ -1862,21 +1862,19 @@
     }
 
     if ($userids = get_list_of_plugins('data/preset', '', $CFG->dataroot)) {
+        $canviewall = has_capability('mod/data:viewalluserpresets', $context);
         foreach ($userids as $userid) {
             $fulldir = $CFG->dataroot.'/data/preset/'.$userid;
-
-            if ($userid == 0 || $USER->id == $userid || has_capability('mod/data:viewalluserpresets', $context)) {
-
+            if ($userid == 0 || $USER->id == $userid || $canviewall) {
                 if ($dirs = get_list_of_plugins('data/preset/'.$userid, '', $CFG->dataroot)) {
                     foreach ($dirs as $dir) {
                         $fulldir = $CFG->dataroot.'/data/preset/'.$userid.'/'.$dir;
-
                         if (is_directory_a_preset($fulldir)) {
                             $preset = new object;
                             $preset->path = $fulldir;
                             $preset->userid = $userid;
                             $preset->shortname = $dir;
-                            $preset->name = data_preset_name($dir, $fulldir);
+                            $preset->name = $preset->shortname;
                             if (file_exists($fulldir.'/screenshot.jpg')) {
                                 $preset->screenshot = $CFG->wwwroot.'/mod/data/preset/'.$dir.'/screenshot.jpg';
                             } else if (file_exists($fulldir.'/screenshot.png')) {
@@ -1993,86 +1991,86 @@
 }
 
 /**
- * @return bool
+ * Abstract class used for data preset importers
  */
-function clean_preset($folder) {
-    $status = @unlink($folder.'/singletemplate.html') &&
-              @unlink($folder.'/listtemplate.html') &&
-              @unlink($folder.'/listtemplateheader.html') &&
-              @unlink($folder.'/listtemplatefooter.html') &&
-              @unlink($folder.'/addtemplate.html') &&
-              @unlink($folder.'/rsstemplate.html') &&
-              @unlink($folder.'/rsstitletemplate.html') &&
-              @unlink($folder.'/csstemplate.css') &&
-              @unlink($folder.'/jstemplate.js') &&
-              @unlink($folder.'/preset.xml');
+abstract class data_preset_importer {
 
-    // optional
-    @unlink($folder.'/asearchtemplate.html');
+    protected $course;
+    protected $cm;
+    protected $module;
+    protected $directory;
 
-    return $status;
-}
-
 /**
- * @package   mod-data
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+     * Constructor
+     *
+     * @param stdClass $course
+     * @param stdClass $cm
+     * @param stdClass $module
+     * @param string $directory
  */
-class PresetImporter {
-    /**
-     * @global object
-     * @param object $course
-     * @param object $cm
-     * @param object $data
-     * @param int $userid
-     * @param string $shortname
-     */
-    function PresetImporter($course, $cm, $data, $userid, $shortname) {
-        global $CFG;
+    public function __construct($course, $cm, $module, $directory) {
         $this->course = $course;
         $this->cm = $cm;
-        $this->data = $data;
-        $this->userid = $userid;
-        $this->shortname = $shortname;
-        $this->folder = data_preset_path($course, $userid, $shortname);
+        $this->module = $module;
+        $this->directory = $directory;
     }
+
     /**
-     * @global object
-     * @global object
-     * @return array
+     * Returns the name of the directory the preset is located in
+     * @return string
      */
-    function get_settings() {
-        global $CFG, $DB;
+    public function get_directory() {
+        return basename($this->directory);
+    }
+    /**
+     * Gets the preset settings
+     * @global moodle_database $DB
+     * @return stdClass
+     */
+    public function get_preset_settings() {
+        global $DB;
 
-        if (!is_directory_a_preset($this->folder)) {
-            print_error('invalidpreset', 'data', '', $this->userid.'/'.$this->shortname);
+        if (!is_directory_a_preset($this->directory)) {
+            print_error('invalidpreset', 'data', '', $this->directory);
         }
 
+        $allowed_settings = array(
+            'intro',
+            'comments',
+            'requiredentries',
+            'requiredentriestoview',
+            'maxentries',
+            'rssarticles',
+            'approval',
+            'defaultsortdir',
+            'defaultsort');
+
+        $result = new stdClass;
+        $result->settings = new stdClass;
+        $result->importfields = array();
+        $result->currentfields = $DB->get_records('data_fields', array('dataid'=>$this->module->id));
+        if (!$result->currentfields) {
+            $result->currentfields = array();
+        }
+
+
         /* Grab XML */
-        $presetxml = file_get_contents($this->folder.'/preset.xml');
+        $presetxml = file_get_contents($this->directory.'/preset.xml');
         $parsedxml = xmlize($presetxml, 0);
 
-        $allowed_settings = array('intro', 'comments', 'requiredentries', 'requiredentriestoview',
-                                  'maxentries', 'rssarticles', 'approval', 'defaultsortdir', 'defaultsort');
-
         /* First, do settings. Put in user friendly array. */
         $settingsarray = $parsedxml['preset']['#']['settings'][0]['#'];
-        $settings = new StdClass();
-
+        $result->settings = new StdClass();
         foreach ($settingsarray as $setting => $value) {
-            if (!is_array($value)) {
-                continue;
-            }
-            if (!in_array($setting, $allowed_settings)) {
+            if (!is_array($value) || !in_array($setting, $allowed_settings)) {
                 // unsupported setting
                 continue;
             }
-            $settings->$setting = $value[0]['#'];
+            $result->settings->$setting = $value[0]['#'];
         }
 
         /* Now work out fields to user friendly array */
         $fieldsarray = $parsedxml['preset']['#']['field'];
-        $fields = array();
         foreach ($fieldsarray as $field) {
             if (!is_array($field)) {
                 continue;
@@ -2084,127 +2082,53 @@
                 }
                 $f->$param = $value[0]['#'];
             }
-            $f->dataid = $this->data->id;
+            $f->dataid = $this->module->id;
             $f->type = clean_param($f->type, PARAM_ALPHA);
-            $fields[] = $f;
+            $result->importfields[] = $f;
         }
         /* Now add the HTML templates to the settings array so we can update d */
-        $settings->singletemplate     = file_get_contents($this->folder."/singletemplate.html");
-        $settings->listtemplate       = file_get_contents($this->folder."/listtemplate.html");
-        $settings->listtemplateheader = file_get_contents($this->folder."/listtemplateheader.html");
-        $settings->listtemplatefooter = file_get_contents($this->folder."/listtemplatefooter.html");
-        $settings->addtemplate        = file_get_contents($this->folder."/addtemplate.html");
-        $settings->rsstemplate        = file_get_contents($this->folder."/rsstemplate.html");
-        $settings->rsstitletemplate   = file_get_contents($this->folder."/rsstitletemplate.html");
-        $settings->csstemplate        = file_get_contents($this->folder."/csstemplate.css");
-        $settings->jstemplate         = file_get_contents($this->folder."/jstemplate.js");
+        $result->settings->singletemplate     = file_get_contents($this->directory."/singletemplate.html");
+        $result->settings->listtemplate       = file_get_contents($this->directory."/listtemplate.html");
+        $result->settings->listtemplateheader = file_get_contents($this->directory."/listtemplateheader.html");
+        $result->settings->listtemplatefooter = file_get_contents($this->directory."/listtemplatefooter.html");
+        $result->settings->addtemplate        = file_get_contents($this->directory."/addtemplate.html");
+        $result->settings->rsstemplate        = file_get_contents($this->directory."/rsstemplate.html");
+        $result->settings->rsstitletemplate   = file_get_contents($this->directory."/rsstitletemplate.html");
+        $result->settings->csstemplate        = file_get_contents($this->directory."/csstemplate.css");
+        $result->settings->jstemplate         = file_get_contents($this->directory."/jstemplate.js");
 
         //optional
-        if (file_exists($this->folder."/asearchtemplate.html")) {
-            $settings->asearchtemplate = file_get_contents($this->folder."/asearchtemplate.html");
+        if (file_exists($this->directory."/asearchtemplate.html")) {
+            $result->settings->asearchtemplate = file_get_contents($this->directory."/asearchtemplate.html");
         } else {
-            $settings->asearchtemplate = NULL;
+            $result->settings->asearchtemplate = NULL;
         }
+        $result->settings->instance = $this->module->id;
 
-        $settings->instance = $this->data->id;
-
-        /* Now we look at the current structure (if any) to work out whether we need to clear db
-           or save the data */
-        if (!$currentfields = $DB->get_records('data_fields', array('dataid'=>$this->data->id))) {
-            $currentfields = array();
+        return $result;
         }
 
-        return array($settings, $fields, $currentfields);
-    }
-
     /**
-     *
-     */
-    function import_options() {
-        global $OUTPUT;
-        if (!confirm_sesskey()) {
-            print_error('invalidsesskey');
-        }
-
-        $strblank = get_string('blank', 'data');
-        $strcontinue = get_string('continue');
-        $strwarning = get_string('mappingwarning', 'data');
-        $strfieldmappings = get_string('fieldmappings', 'data');
-        $strnew = get_string('new');
-
-        $sesskey = sesskey();
-
-        list($settings, $newfields,  $currentfields) = $this->get_settings();
-
-        echo '<div class="presetmapping"><form action="preset.php" method="post">';
-        echo '<div>';
-        echo '<input type="hidden" name="action" value="finishimport" />';
-        echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
-        echo '<input type="hidden" name="d" value="'.$this->data->id.'" />';
-        echo '<input type="hidden" name="fullname" value="'.$this->userid.'/'.$this->shortname.'" />';
-
-        if (!empty($currentfields) && !empty($newfields)) {
-            echo "<h3>$strfieldmappings ";
-            echo $OUTPUT->help_icon('fieldmappings', 'data');
-            echo '</h3><table>';
-
-            foreach ($newfields as $nid => $newfield) {
-                echo "<tr><td><label for=\"id_$newfield->name\">$newfield->name</label></td>";
-                echo '<td><select name="field_'.$nid.'" id="id_'.$newfield->name.'">';
-
-                $selected = false;
-                foreach ($currentfields as $cid => $currentfield) {
-                    if ($currentfield->type == $newfield->type) {
-                        if ($currentfield->name == $newfield->name) {
-                            echo '<option value="'.$cid.'" selected="selected">'.$currentfield->name.'</option>';
-                            $selected=true;
-                        }
-                        else {
-                            echo '<option value="'.$cid.'">'.$currentfield->name.'</option>';
-                        }
-                    }
-                }
-
-                if ($selected)
-                    echo '<option value="-1">-</option>';
-                else
-                    echo '<option value="-1" selected="selected">-</option>';
-                echo '</select></td></tr>';
-            }
-            echo '</table>';
-            echo "<p>$strwarning</p>";
-
-        } else if (empty($newfields)) {
-            print_error('nodefinedfields', 'data');
-        }
-
-        echo '<div class="overwritesettings"><label for="overwritesettings">'.get_string('overwritesettings', 'data');
-        echo '<input id="overwritesettings" name="overwritesettings" type="checkbox" /></label></div>';
-
-        echo '<input class="button" type="submit" value="'.$strcontinue.'" /></div></form></div>';
-
-    }
-
-    /**
-     * @global object
-     * @global object
+     * Import the preset into the given database module
      * @return bool
      */
-    function import() {
-        global $CFG, $DB;
+    function import($overwritesettings) {
+        global $DB;
 
-        list($settings, $newfields, $currentfields) = $this->get_settings();
+        $params = $this->get_preset_settings();
+        $settings = $params->settings;
+        $newfields = $params->importfields;
+        $currentfields = $params->currentfields;
         $preservedfields = array();
 
-        $overwritesettings = optional_param('overwritesettings', 0, PARAM_BOOL);
-
         /* Maps fields and makes new ones */
         if (!empty($newfields)) {
             /* We require an injective mapping, and need to know what to protect */
             foreach ($newfields as $nid => $newfield) {
                 $cid = optional_param("field_$nid", -1, PARAM_INT);
-                if ($cid == -1) continue;
-
+                if ($cid == -1) {
+                    continue;
+                }
                 if (array_key_exists($cid, $preservedfields)){
                     print_error('notinjectivemap', 'data');
                 }
@@ -2216,7 +2140,7 @@
 
                 /* A mapping. Just need to change field params. Data kept. */
                 if ($cid != -1 and isset($currentfields[$cid])) {
-                    $fieldobject = data_get_field_from_id($currentfields[$cid]->id, $this->data);
+                    $fieldobject = data_get_field_from_id($currentfields[$cid]->id, $this->module);
                     foreach ($newfield as $param => $value) {
                         if ($param != "id") {
                             $fieldobject->field->$param = $value;
@@ -2225,16 +2149,15 @@
                     unset($fieldobject->field->similarfield);
                     $fieldobject->update_field();
                     unset($fieldobject);
-                }
+                } else {
                 /* Make a new field */
-                else {
                     include_once("field/$newfield->type/field.class.php");
 
                     if (!isset($newfield->description)) {
                         $newfield->description = '';
                     }
                     $classname = 'data_field_'.$newfield->type;
-                    $fieldclass = new $classname($newfield, $this->data);
+                    $fieldclass = new $classname($newfield, $this->module);
                     $fieldclass->insert_field();
                     unset($fieldclass);
                 }
@@ -2250,14 +2173,6 @@
 
                     $id = $currentfield->id;
                     //Why delete existing data records and related comments/ratings??
-/*
-                    if ($content = $DB->get_records('data_content', array('fieldid'=>$id))) {
-                        foreach ($content as $item) {
-                            $DB->delete_records('data_ratings', array('recordid'=>$item->recordid));
-                            $DB->delete_records('data_comments', array('recordid'=>$item->recordid));
-                            $DB->delete_records('data_records', array('id'=>$item->recordid));
-                        }
-                    }*/
                     $DB->delete_records('data_content', array('fieldid'=>$id));
                     $DB->delete_records('data_fields', array('id'=>$id));
                 }
@@ -2270,7 +2185,7 @@
                 // old broken value
                 $settings->defaultsort = 0;
             } else {
-                $settings->defaultsort = (int)$DB->get_field('data_fields', 'id', array('dataid'=>$this->data->id, 'name'=>$settings->defaultsort));
+                $settings->defaultsort = (int)$DB->get_field('data_fields', 'id', array('dataid'=>$this->module->id, 'name'=>$settings->defaultsort));
             }
         } else {
             $settings->defaultsort = 0;
@@ -2288,24 +2203,69 @@
         }
 
         // now overwrite current data settings
-        foreach ($this->data as $prop=>$unused) {
+        foreach ($this->module as $prop=>$unused) {
             if (in_array($prop, $overwrite)) {
-                $this->data->$prop = $settings->$prop;
+                $this->module->$prop = $settings->$prop;
             }
         }
 
-        data_update_instance($this->data);
+        data_update_instance($this->module);
 
-        if (strstr($this->folder, '/temp/')) {
-        // Removes the temporary files
-            clean_preset($this->folder);
+        return $this->cleanup();
         }
 
+    /**
+     * Any clean up routines should go here
+     * @return bool
+     */
+    public function cleanup() {
         return true;
     }
 }
 
 /**
+ * Data preset importer for uploaded presets
+ */
+class data_preset_upload_importer extends data_preset_importer {
+    public function __construct($course, $cm, $module, $filepath) {
+        global $USER;
+        if (is_file($filepath)) {
+            $fp = get_file_packer();
+            if ($fp->extract_to_pathname($filepath, $filepath.'_extracted')) {
+                fulldelete($filepath);
+            }
+            $filepath .= '_extracted';
+        }
+        parent::__construct($course, $cm, $module, $filepath);
+    }
+    public function cleanup() {
+        return fulldelete($this->directory);
+    }
+}
+
+/**
+ * Data preset importer for existing presets
+ */
+class data_preset_existing_importer extends data_preset_importer {
+    protected $userid;
+    public function __construct($course, $cm, $module, $fullname) {
+        global $USER;
+        list($userid, $shortname) = explode('/', $fullname, 2);
+        $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+        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;
+        $filepath = data_preset_path($course, $userid, $shortname);
+        parent::__construct($course, $cm, $module, $filepath);
+    }
+    public function get_userid() {
+        return $this->userid;
+    }
+}
+
+/**
  * @global object
  * @global object
  * @param object $course
@@ -2888,3 +2848,137 @@
         $datanode->add($string, $url, settings_navigation::TYPE_SETTING, null, null, new pix_icon('i/rss', ''));
     }
 }
+
+function data_presets_export($course, $cm, $data) {
+    global $CFG, $DB;
+    $presetname = clean_filename($data->name) . '-preset-' . gmdate("Ymd_Hi");
+    $exportsubdir = "$course->id/moddata/data/$data->id/$presetname";
+    make_upload_directory($exportsubdir);
+    $exportdir = "$CFG->dataroot/$exportsubdir";
+
+    // Assemble "preset.xml":
+    $presetxmldata = "<preset>\n\n";
+
+    // Raw settings are not preprocessed during saving of presets
+    $raw_settings = array(
+        'intro',
+        'comments',
+        'requiredentries',
+        'requiredentriestoview',
+        'maxentries',
+        'rssarticles',
+        'approval',
+        'defaultsortdir'
+    );
+
+    $presetxmldata .= "<settings>\n";
+    // First, settings that do not require any conversion
+    foreach ($raw_settings as $setting) {
+        $presetxmldata .= "<$setting>" . htmlspecialchars($data->$setting) . "</$setting>\n";
+    }
+
+    // Now specific settings
+    if ($data->defaultsort > 0 && $sortfield = data_get_field_from_id($data->defaultsort, $data)) {
+        $presetxmldata .= '<defaultsort>' . htmlspecialchars($sortfield->field->name) . "</defaultsort>\n";
+    } else {
+        $presetxmldata .= "<defaultsort>0</defaultsort>\n";
+    }
+    $presetxmldata .= "</settings>\n\n";
+
+    // Now for the fields. Grab all that are non-empty
+    $fields = $DB->get_records('data_fields', array('dataid'=>$data->id));
+    ksort($fields);
+    if (!empty($fields)) {
+        foreach ($fields as $field) {
+            $presetxmldata .= "<field>\n";
+            foreach ($field as $key => $value) {
+                if ($value != '' && $key != 'id' && $key != 'dataid') {
+                    $presetxmldata .= "<$key>" . htmlspecialchars($value) . "</$key>\n";
+                }
+            }
+            $presetxmldata .= "</field>\n\n";
+        }
+    }
+    $presetxmldata .= '</preset>';
+
+    // After opening a file in write mode, close it asap
+    $presetxmlfile = fopen($exportdir . '/preset.xml', 'w');
+    fwrite($presetxmlfile, $presetxmldata);
+    fclose($presetxmlfile);
+
+    // Now write the template files
+    $singletemplate = fopen($exportdir . '/singletemplate.html', 'w');
+    fwrite($singletemplate, $data->singletemplate);
+    fclose($singletemplate);
+
+    $listtemplateheader = fopen($exportdir . '/listtemplateheader.html', 'w');
+    fwrite($listtemplateheader, $data->listtemplateheader);
+    fclose($listtemplateheader);
+
+    $listtemplate = fopen($exportdir . '/listtemplate.html', 'w');
+    fwrite($listtemplate, $data->listtemplate);
+    fclose($listtemplate);
+
+    $listtemplatefooter = fopen($exportdir . '/listtemplatefooter.html', 'w');
+    fwrite($listtemplatefooter, $data->listtemplatefooter);
+    fclose($listtemplatefooter);
+
+    $addtemplate = fopen($exportdir . '/addtemplate.html', 'w');
+    fwrite($addtemplate, $data->addtemplate);
+    fclose($addtemplate);
+
+    $rsstemplate = fopen($exportdir . '/rsstemplate.html', 'w');
+    fwrite($rsstemplate, $data->rsstemplate);
+    fclose($rsstemplate);
+
+    $rsstitletemplate = fopen($exportdir . '/rsstitletemplate.html', 'w');
+    fwrite($rsstitletemplate, $data->rsstitletemplate);
+    fclose($rsstitletemplate);
+
+    $csstemplate = fopen($exportdir . '/csstemplate.css', 'w');
+    fwrite($csstemplate, $data->csstemplate);
+    fclose($csstemplate);
+
+    $jstemplate = fopen($exportdir . '/jstemplate.js', 'w');
+    fwrite($jstemplate, $data->jstemplate);
+    fclose($jstemplate);
+
+    $asearchtemplate = fopen($exportdir . '/asearchtemplate.html', 'w');
+    fwrite($asearchtemplate, $data->asearchtemplate);
+    fclose($asearchtemplate);
+
+    // Check if all files have been generated
+    if (! is_directory_a_preset($exportdir)) {
+        print_error('generateerror', 'data');
+    }
+
+    $filelist = array(
+        'preset.xml',
+        'singletemplate.html',
+        'listtemplateheader.html',
+        'listtemplate.html',
+        'listtemplatefooter.html',
+        'addtemplate.html',
+        'rsstemplate.html',
+        'rsstitletemplate.html',
+        'csstemplate.css',
+        'jstemplate.js',
+        'asearchtemplate.html'
+    );
+
+    foreach ($filelist as $key => $file) {
+        $filelist[$key] = $exportdir . '/' . $filelist[$key];
+    }
+
+    $exportfile = "$CFG->dataroot/$course->id/moddata/data/$data->id/$presetname.zip";
+    file_exists($exportfile) && unlink($exportfile);
+    $status = zip_files($filelist, $exportfile);
+    // ToDo: status check
+    foreach ($filelist as $file) {
+        unlink($file);
+    }
+    rmdir($exportdir);
+
+    // Return the full path to the exported preset file:
+    return $exportfile;
+}
\ No newline at end of file
Index: moodle/mod/data/preset.php
--- moodle/mod/data/preset.php Base (1.55)
+++ moodle/mod/data/preset.php Locally Modified (Based On 1.55)
@@ -29,199 +29,97 @@
  */
 
 require_once('../../config.php');
-require_once('lib.php');
+require_once($CFG->dirroot.'/mod/data/lib.php');
+require_once($CFG->dirroot.'/mod/data/preset_form.php');
 require_once($CFG->libdir.'/xmlize.php');
 
-$id       = optional_param('id', 0, PARAM_INT);    // course module id
-$d        = optional_param('d', 0, PARAM_INT);     // database activity id
-$action   = optional_param('action', 'base', PARAM_ALPHANUM); // current action
-$fullname = optional_param('fullname', '', PARAM_PATH); // directory the preset is in
-$file     = optional_param('file', '', PARAM_PATH); // uploaded file
-
-$url = new moodle_url('/mod/data/preset.php');
-if ($action !== 'base') {
-    $url->param('action', $action);
-}
-if ($fullname !== '') {
-    $url->param('fullname', $fullname);
-}
-if ($file !== '') {
-    $url->param('file', $file);
-}
-
-// find out preset owner userid and shortname
-$parts = explode('/', $fullname);
-$userid = empty($parts[0]) ? 0 : (int)$parts[0];
-$shortname = empty($parts[1]) ? '' : $parts[1];
-unset($parts);
-unset($fullname);
-
+$id     = optional_param('id', 0, PARAM_INT);           // course module id
 if ($id) {
-    $url->param('id', $id);
-    $PAGE->set_url($url);
-    if (! $cm = get_coursemodule_from_id('data', $id)) {
-        print_error('invalidcoursemodule');
-    }
-    if (! $course = $DB->get_record('course', array('id'=>$cm->course))) {
-        print_error('coursemisconf');
-    }
-    if (! $data = $DB->get_record('data', array('id'=>$cm->instance))) {
-        print_error('invalidid', 'data');
-    }
-} else if ($d) {
-    $url->param('d', $d);
-    $PAGE->set_url($url);
-    if (! $data = $DB->get_record('data', array('id'=>$d))) {
-        print_error('invalidid', 'data');
-    }
-    if (! $course = $DB->get_record('course', array('id'=>$data->course))) {
-        print_error('coursemisconf');
-    }
-    if (! $cm = get_coursemodule_from_instance('data', $data->id, $course->id)) {
-        print_error('invalidcoursemodule');
-    }
+    $cm = get_coursemodule_from_id('data', $id, null, null, MUST_EXIST);
+    $course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST);
+    $data = $DB->get_record('data', array('id'=>$cm->instance), '*', MUST_EXIST);
 } else {
-    print_error('missingparameter');
+    $d = required_param('d', PARAM_INT);     // database activity id
+    $data = $DB->get_record('data', array('id'=>$d), '*', MUST_EXIST);
+    $course = $DB->get_record('course', array('id'=>$data->course), '*', MUST_EXIST);
+    $cm = get_coursemodule_from_instance('data', $data->id, $course->id, null, MUST_EXIST);
 }
+$context = get_context_instance(CONTEXT_MODULE, $cm->id, MUST_EXIST);
+require_login($course->id, false, $cm);
+require_capability('mod/data:managetemplates', $context);
+$PAGE->set_url(new moodle_url('/mod/data/preset.php', array('d'=>$data->id)));
+$PAGE->set_title(get_string('course') . ': ' . $course->fullname);
+$PAGE->set_heading($course->fullname);
 
 // fill in missing properties needed for updating of instance
 $data->course     = $cm->course;
 $data->cmidnumber = $cm->idnumber;
 $data->instance   = $cm->instance;
 
-if (!$context = get_context_instance(CONTEXT_MODULE, $cm->id)) {
-    print_error('cannotfindcontext');
-}
-
-require_login($course->id, false, $cm);
-
-require_capability('mod/data:managetemplates', $context);
-
-if ($userid && ($userid != $USER->id) && !has_capability('mod/data:viewalluserpresets', $context)) {
-    print_error('cannotaccesspresentsother', 'data');
-}
-
-/* Need sesskey security check here for import instruction */
-$sesskey = sesskey();
-$PAGE->set_title(get_string('course') . ': ' . $course->fullname);
-$PAGE->set_heading($course->fullname);
-
-/********************************************************************/
-/* Output */
-if ($action !== 'export') {
-    data_print_header($course, $cm, $data, 'presets');
-}
-
-switch ($action) {
-        /***************** Deleting *****************/
-    case 'confirmdelete' :
-        if (!confirm_sesskey()) { // GET request ok here
-            print_error('invalidsesskey');
-        }
-
-        if ($userid > 0 and ($userid == $USER->id || has_capability('mod/data:manageuserpresets', $context))) {
-           //ok can delete
+$presets = data_get_available_presets($context);
+$canmanage = has_capability('mod/data:manageuserpresets', $context);
+$strdelete = get_string('deleted', 'data');
+foreach ($presets as &$preset) {
+    if (!empty($preset->userid)) {
+        $presetuser = $DB->get_record('user', array('id'=>$preset->userid), 'id,firstname,lastname', MUST_EXIST);
+        $preset->description = $preset->name.' ('.fullname($presetuser, true).')';
         } else {
-            print_error('invalidrequest');
+        $preset->userid = 0;
+        $preset->description = $preset->name;
         }
-
-        $path = data_preset_path($course, $userid, $shortname);
-
-        $strwarning = get_string('deletewarning', 'data').'<br />'.
-                      data_preset_name($shortname, $path);
-
-        $optionsyes = array('fullname' => $userid.'/'.$shortname,
-                         'action' => 'delete',
-                         'd' => $data->id);
-
-        $optionsno = array('d' => $data->id);
-        echo $OUTPUT->confirm($strwarning, new moodle_url('preset.php', $optionsyes), new moodle_url('preset.php', $optionsno));
-        echo $OUTPUT->footer();
-        exit(0);
-        break;
-
-    case 'delete' :
-        if (!data_submitted() and !confirm_sesskey()) {
-            print_error('invalidrequest');
+    if ($preset->userid > 0 and ($preset->userid == $USER->id || $canmanage)) {
+        $delurl = new moodle_url('/mod/data/preset.php', array('d'=> $data->id, 'action'=>'confirmdelete', 'fullname'=>$preset->userid.'/'.$preset->shortname, 'sesskey'=>sesskey()));
+        $delicon = html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/delete'), 'class'=>'iconsmall', 'alt'=>$strdelete.' '.$preset->description));
+        $preset->description .= html_writer::link($delurl, $delicon);
         }
-
-        if ($userid > 0 and ($userid == $USER->id || has_capability('mod/data:manageuserpresets', $context))) {
-           //ok can delete
-        } else {
-            print_error('invalidrequest');
         }
 
-        $presetpath = data_preset_path($course, $userid, $shortname);
+$form_importexisting = new data_existing_preset_form(null, array('presets'=>$presets));
+$form_importexisting->set_data(array('d' => $data->id));
 
-        if (!clean_preset($presetpath)) {
-            print_error('cannotdeletepreset', 'data');
-        }
-        @rmdir($presetpath);
+$form_importzip = new data_import_preset_zip_form();
+$form_importzip->set_data(array('d' => $data->id));
 
-        $strdeleted = get_string('deleted', 'data');
-        echo $OUTPUT->notification("$shortname $strdeleted", 'notifysuccess');
-        break;
+$form_export = new data_export_form();
+$form_export->set_data(array('d' => $data->id));
 
-        /***************** Importing *****************/
-    case 'importpreset' :
-        if (!data_submitted() or !confirm_sesskey()) {
-            print_error('invalidrequest');
-        }
+$form_save = new data_save_preset_form();
+$form_save->set_data(array('d' => $data->id, 'name'=>$data->name));
 
-        $pimporter = new PresetImporter($course, $cm, $data, $userid, $shortname);
-        $pimporter->import_options();
+/* Output */
+if (!$form_export->is_submitted()) {
+    echo $OUTPUT->header();
+    echo $OUTPUT->heading(format_string($data->name));
 
-        echo $OUTPUT->footer();
-        exit(0);
-        break;
-
-        /* Imports a zip file. */
-    case 'importzip' :
-        if (!data_submitted() or !confirm_sesskey()) {
-            print_error('invalidrequest');
+    // Needed for tabs.php
+    $currenttab = 'presets';
+    $currentgroup = groups_get_activity_group($cm);
+    $groupmode = groups_get_activity_groupmode($cm);
+    include('tabs.php');
         }
 
-        if (!make_upload_directory('temp/data/'.$USER->id)) {
-            print_error('nopermissiontomkdir');
-        }
+if (optional_param('sesskey', false, PARAM_BOOL) && confirm_sesskey()) {
 
-        $presetfile = $CFG->dataroot.'/temp/data/'.$USER->id;
-        clean_preset($presetfile);
+    $renderer = $PAGE->get_renderer('mod_data');
 
-        if (!unzip_file($CFG->dataroot."/$course->id/$file", $presetfile, false)) {
-            print_error('cannotunzipfile');
-        }
-
-        $pimporter = new PresetImporter($course, $cm, $data, -$USER->id, $shortname);
-        $pimporter->import_options();
-
+    if ($formdata = $form_importexisting->get_data()) {
+        $importer = new data_preset_existing_importer($course, $cm, $data, $formdata->fullname);
+        echo $renderer->import_setting_mappings($data, $importer);
         echo $OUTPUT->footer();
+    } else if ($formdata = $form_importzip->get_data()) {
+        $file = new stdClass;
+        $file->name = $form_importzip->get_new_filename('importfile');
+        $file->path = $form_importzip->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);
-        break;
+    } else if ($formdata = $form_export->get_data()) {
 
-    case 'finishimport':
-        if (!data_submitted() or !confirm_sesskey()) {
-            print_error('invalidrequest');
+        if (headers_sent()) {
+            print_error('headersent');
         }
 
-        $pimporter = new PresetImporter($course, $cm, $data, $userid, $shortname);
-        $pimporter->import();
-
-        $strimportsuccess = get_string('importsuccess', 'data');
-        $straddentries = get_string('addentries', 'data');
-        $strtodatabase = get_string('todatabase', 'data');
-        if (!$DB->get_records('data_records', array('dataid'=>$data->id))) {
-            echo $OUTPUT->notification("$strimportsuccess <a href='edit.php?d=$data->id'>$straddentries</a> $strtodatabase", 'notifysuccess');
-        } else {
-            echo $OUTPUT->notification("$strimportsuccess", 'notifysuccess');
-        }
-        break;
-
-        /* Exports as a zip file ready for download. */
-    case 'export':
-        if (!data_submitted() or !confirm_sesskey()) {
-            print_error('invalidrequest');
-        }
         $exportfile = data_presets_export($course, $cm, $data);
         $exportfilename = basename($exportfile);
         header("Content-Type: application/download\n");
@@ -234,320 +132,96 @@
         fclose($exportfilehandler);
         unlink($exportfile);
         exit(0);
-        break;
 
-        /***************** Exporting *****************/
-    case 'save1':
-        if (!data_submitted() or !confirm_sesskey()) {
-            print_error('invalidrequest');
-        }
+    } else if ($formdata = $form_save->get_data()) {
 
-        $strcontinue = get_string('continue');
-        $strwarning = get_string('presetinfo', 'data');
-        $strname = get_string('shortname');
+        $presetdirectory = "/data/preset/$USER->id/{$formdata->name}";
 
-        echo '<div style="text-align:center">';
-        echo '<p>'.$strwarning.'</p>';
-        echo '<form action="preset.php" method="post">';
-        echo '<fieldset class="invisiblefieldset">';
-        echo '<label for="shorname">'.$strname.'</label> <input type="text" id="shorname" name="name" value="'.$data->name.'" />';
-        echo '<input type="hidden" name="action" value="save2" />';
-        echo '<input type="hidden" name="d" value="'.$data->id.'" />';
-        echo '<input type="hidden" name="sesskey" value="'.$sesskey.'" />';
-        echo '<input type="submit" value="'.$strcontinue.'" /></fieldset></form></div>';
-        echo $OUTPUT->footer();
-        exit(0);
-        break;
-
-    case 'save2':
-        if (!data_submitted() or !confirm_sesskey()) {
-            print_error('invalidrequest');
+        if (file_exists($CFG->dataroot.$presetdirectory)) {
+            if (!$formdata->overwrite) {
+                print_error('errorpresetexists', 'preset');
+            } else {
+                fulldelete($CFG->dataroot.$presetdirectory);
         }
-
-        $strcontinue = get_string('continue');
-        $stroverwrite = get_string('overwrite', 'data');
-        $strname = get_string('shortname');
-
-        $name = optional_param('name', $data->name, PARAM_FILE);
-
-        if (is_directory_a_preset("$CFG->dataroot/data/preset/$USER->id/$name")) {
-            echo $OUTPUT->notification("Preset already exists: Pick another name or overwrite");
-
-            echo '<div style="text-align:center">';
-            echo '<form action="preset.php" method="post">';
-            echo '<fieldset class="invisiblefieldset">';
-            echo '<label for="shorname">'.$strname.'</label> <input type="textbox" name="name" value="'.$name.'" />';
-            echo '<input type="hidden" name="action" value="save2" />';
-            echo '<input type="hidden" name="d" value="'.$data->id.'" />';
-            echo '<input type="hidden" name="sesskey" value="'.$sesskey.'" />';
-            echo '<input type="submit" value="'.$strcontinue.'" /></fieldset></form>';
-
-            echo '<form action="preset.php" method="post">';
-            echo '<div>';
-            echo '<input type="hidden" name="name" value="'.$name.'" />';
-            echo '<input type="hidden" name="action" value="save3" />';
-            echo '<input type="hidden" name="d" value="'.$data->id.'" />';
-            echo '<input type="hidden" name="sesskey" value="'.$sesskey.'" />';
-            echo '<input type="submit" value="'.$stroverwrite.'" /></div></form>';
-            echo '</div>';
-            echo $OUTPUT->footer();
-            exit(0);
-            break;
         }
-
-    case 'save3':
-        if (!data_submitted() or !confirm_sesskey()) {
-            print_error('invalidrequest');
-        }
-
-        $name = optional_param('name', $data->name, PARAM_FILE);
-        $presetdirectory = "/data/preset/$USER->id/$name";
-
         make_upload_directory($presetdirectory);
-        clean_preset($CFG->dataroot.$presetdirectory);
 
         $file = data_presets_export($course, $cm, $data);
         if (!unzip_file($file, $CFG->dataroot.$presetdirectory, false)) {
             print_error('cannotunziptopreset', 'data');
         }
         echo $OUTPUT->notification(get_string('savesuccess', 'data'), 'notifysuccess');
-        break;
-}
-
-$presets = data_get_available_presets($context);
-
-$strimport         = get_string('import');
-$strfromfile       = get_string('fromfile', 'data');
-$strchooseorupload = get_string('chooseorupload', 'data');
-$strusestandard    = get_string('usestandard', 'data');
-$strchoose         = get_string('choose');
-$strexport         = get_string('export', 'data');
-$strexportaszip    = get_string('exportaszip', 'data');
-$strsaveaspreset   = get_string('saveaspreset', 'data');
-$strsave           = get_string('save', 'data');
-$strdelete         = get_string('delete');
-
-echo '<div style="text-align:center">';
-echo '<table class="presets" cellpadding="5">';
-echo '<tr><td valign="top" colspan="2" align="center"><h3>'.$strexport.'</h3></td></tr>';
-
-echo '<tr><td><label>'.$strexportaszip.'</label>';
-echo $OUTPUT->help_icon('exportaszip', 'data');
-echo '</td><td>';
-$options = array();
-$options['sesskey'] = sesskey();
-$options['action']  = 'export';
-$options['d']       = $data->id;
-echo $OUTPUT->single_button(new moodle_url('preset.php', $options), $strexport);
-echo '</td></tr>';
-
-echo '<tr><td><label>'.$strsaveaspreset.'</label>';
-echo $OUTPUT->help_icon('saveaspreset', 'data');
-echo '</td><td>';
-$options = array();
-$options['sesskey'] = sesskey();
-$options['action']  = 'save1';
-$options['d']       = $data->id;
-echo $OUTPUT->single_button(new moodle_url('preset.php', $options), $strsave);
-echo '</td></tr>';
-echo '<tr><td valign="top" colspan="2" align="center"><h3>'.$strimport.'</h3></td></tr>';
-echo '<tr><td><label for="fromfile">'.$strfromfile.'</label>';
-echo $OUTPUT->help_icon('fromfile', 'data');
-echo '</td><td>';
-echo '<form id="uploadpreset" method="post" action="preset.php">';
-echo '<fieldset class="invisiblefieldset">';
-echo '<input type="hidden" name="d" value="'.$data->id.'" />';
-echo '<input type="hidden" name="action" value="importzip" />';
-echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
-echo '<input name="file" size="20" value="" id="fromfile" type="text" /><input name="coursefiles" value="'.$strchooseorupload.'" type="button" />';
-echo '<input type="submit" value="'.$strimport.'" />';
-echo '</fieldset></form>';
-echo '</td></tr>';
-
-//attach the onclick event to fromfile button
-$link = '/files/index.php?id={$course->id}&amp;choose=uploadpreset.file';
-$action = new popup_action('click', $link, 'coursefiles', array('height'=>750,'width'=>500));
-$OUTPUT->add_action_handler($action, 'fromfile');
-
-echo '<tr valign="top"><td><label>'.$strusestandard.'</label>';
-echo $OUTPUT->help_icon('usestandard', 'data');
-echo '</td><td>';
-
-echo '<form id="presets" method="post" action="preset.php" >';
-echo '<fieldset class="invisiblefieldset">';
-echo '<input type="hidden" name="d" value="'.$data->id.'" />';
-echo '<input type="hidden" name="action" value="importpreset" />';
-echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
-
-$i = 0;
-foreach ($presets as $id => $preset) {
-    $screenshot = '';
-    if (!empty($preset->userid)) {
-        $user = $DB->get_record('user', array('id'=>$preset->userid));
-        $desc = $preset->name.' ('.fullname($user, true).')';
+        echo $OUTPUT->continue_button($PAGE->url);
+        echo $OUTPUT->footer();
+        exit(0);
     } else {
-        $desc = $preset->name;
-    }
+        $action = optional_param('action', null, PARAM_ALPHA);
+        $fullname = optional_param('fullname', '', PARAM_PATH); // directory the preset is in
+        //
+        // find out preset owner userid and shortname
+        $parts = explode('/', $fullname, 2);
+        $userid = empty($parts[0]) ? 0 : (int)$parts[0];
+        $shortname = empty($parts[1]) ? '' : $parts[1];
 
-    if (!empty($preset->screenshot)) {
-        $screenshot = '<img width="150" class="presetscreenshot" src="'.$preset->screenshot.'" alt="'.get_string('screenshot').' '.$desc.'" />&nbsp;';
+        if ($userid && ($userid != $USER->id) && !has_capability('mod/data:viewalluserpresets', $context)) {
+            print_error('cannotaccesspresentsother', 'data');
     }
 
-    $fullname = $preset->userid.'/'.$preset->shortname;
-
-    $dellink = '';
-    if ($preset->userid > 0 and ($preset->userid == $USER->id || has_capability('mod/data:manageuserpresets', $context))) {
-        $dellink = '&nbsp;<a href="preset.php?d='.$data->id.'&amp;action=confirmdelete&amp;fullname='.$fullname.'&amp;sesskey='.sesskey().'">'.
-                   '<img src="'.$OUTPUT->pix_url('t/delete') . '" class="iconsmall" alt="'.$strdelete.' '.$desc.'" /></a>';
-    }
-
-    echo '<input type="radio" name="fullname" id="usepreset'.$i.'" value="'.$fullname.'" /><label for="usepreset'.$i++.'">'.$desc.'</label>'.$dellink.'<br />';
-}
-echo '<br />';
-echo '<input type="submit" value="'.$strchoose.'" />';
-echo '</fieldset></form>';
-echo '</td></tr>';
-echo '</table>';
-echo '</div>';
-
+        if ($action == 'confirmdelete') {
+            $path = data_preset_path($course, $userid, $shortname);
+            $strwarning = get_string('deletewarning', 'data').'<br />'.$shortname;
+            $optionsyes = array('fullname' => $userid.'/'.$shortname,
+                             'action' => 'delete',
+                             'd' => $data->id);
+            $optionsno = array('d' => $data->id);
+            echo $OUTPUT->confirm($strwarning, new moodle_url('preset.php', $optionsyes), new moodle_url('preset.php', $optionsno));
 echo $OUTPUT->footer();
 exit(0);
+        } else if ($action == 'delete') {
+            if (!$userid || ($userid != $USER->id && !$canmanage)) {
+               print_error('invalidrequest');
+            }
 
-################################################################################
+            $presetpath = data_preset_path($course, $userid, $shortname);
+            fulldelete($presetpath);
 
-
-function data_presets_export($course, $cm, $data) {
-    global $CFG, $DB;
-    $presetname = clean_filename($data->name) . '-preset-' . gmdate("Ymd_Hi");
-    $exportsubdir = "$course->id/moddata/data/$data->id/$presetname";
-    make_upload_directory($exportsubdir);
-    $exportdir = "$CFG->dataroot/$exportsubdir";
-
-    // Assemble "preset.xml":
-    $presetxmldata = "<preset>\n\n";
-
-    // Raw settings are not preprocessed during saving of presets
-    $raw_settings = array(
-        'intro',
-        'comments',
-        'requiredentries',
-        'requiredentriestoview',
-        'maxentries',
-        'rssarticles',
-        'approval',
-        'defaultsortdir'
-    );
-
-    $presetxmldata .= "<settings>\n";
-    // First, settings that do not require any conversion
-    foreach ($raw_settings as $setting) {
-        $presetxmldata .= "<$setting>" . htmlspecialchars($data->$setting) . "</$setting>\n";
+            $strdeleted = get_string('deleted', 'data');
+            echo $OUTPUT->notification("$shortname $strdeleted", 'notifysuccess');
+        } else if ($action == 'finishimport') {
+            $overwritesettings = optional_param('overwritesettings', false, PARAM_BOOL);
+            if (!$fullname) {
+                $presetdir = $CFG->dataroot.'/temp/forms/'.required_param('directory', PARAM_ALPHANUMEXT);
+                if (!file_exists($presetdir) || !is_dir($presetdir)) {
+                    print_error('cannotimport');
     }
-
-    // Now specific settings
-    if ($data->defaultsort > 0 && $sortfield = data_get_field_from_id($data->defaultsort, $data)) {
-        $presetxmldata .= '<defaultsort>' . htmlspecialchars($sortfield->field->name) . "</defaultsort>\n";
+                $importer = new data_preset_upload_importer($course, $cm, $data, $presetdir);
     } else {
-        $presetxmldata .= "<defaultsort>0</defaultsort>\n";
+                $importer = new data_preset_existing_importer($course, $cm, $data, $fullname);
     }
-    $presetxmldata .= "</settings>\n\n";
-
-    // Now for the fields. Grab all that are non-empty
-    $fields = $DB->get_records('data_fields', array('dataid'=>$data->id));
-    ksort($fields);
-    if (!empty($fields)) {
-        foreach ($fields as $field) {
-            $presetxmldata .= "<field>\n";
-            foreach ($field as $key => $value) {
-                if ($value != '' && $key != 'id' && $key != 'dataid') {
-                    $presetxmldata .= "<$key>" . htmlspecialchars($value) . "</$key>\n";
+            $importer->import($overwritesettings);
+            $strimportsuccess = get_string('importsuccess', 'data');
+            $straddentries = get_string('addentries', 'data');
+            $strtodatabase = get_string('todatabase', 'data');
+            if (!$DB->get_records('data_records', array('dataid'=>$data->id))) {
+                echo $OUTPUT->notification("$strimportsuccess <a href='edit.php?d=$data->id'>$straddentries</a> $strtodatabase", 'notifysuccess');
+            } else {
+                echo $OUTPUT->notification("$strimportsuccess", 'notifysuccess');
                 }
             }
-            $presetxmldata .= "</field>\n\n";
+        echo $OUTPUT->continue_button($PAGE->url);
+        echo $OUTPUT->footer();
+        exit(0);
         }
     }
-    $presetxmldata .= '</preset>';
 
-    // After opening a file in write mode, close it asap
-    $presetxmlfile = fopen($exportdir . '/preset.xml', 'w');
-    fwrite($presetxmlfile, $presetxmldata);
-    fclose($presetxmlfile);
+// Export forms
+echo $OUTPUT->heading(get_string('export', 'data'));
+$form_export->display();
+$form_save->display();
 
-    // Now write the template files
-    $singletemplate = fopen($exportdir . '/singletemplate.html', 'w');
-    fwrite($singletemplate, $data->singletemplate);
-    fclose($singletemplate);
+// Import forms
+echo $OUTPUT->heading(get_string('import'));
+$form_importzip->display();
+$form_importexisting->display();
 
-    $listtemplateheader = fopen($exportdir . '/listtemplateheader.html', 'w');
-    fwrite($listtemplateheader, $data->listtemplateheader);
-    fclose($listtemplateheader);
-
-    $listtemplate = fopen($exportdir . '/listtemplate.html', 'w');
-    fwrite($listtemplate, $data->listtemplate);
-    fclose($listtemplate);
-
-    $listtemplatefooter = fopen($exportdir . '/listtemplatefooter.html', 'w');
-    fwrite($listtemplatefooter, $data->listtemplatefooter);
-    fclose($listtemplatefooter);
-
-    $addtemplate = fopen($exportdir . '/addtemplate.html', 'w');
-    fwrite($addtemplate, $data->addtemplate);
-    fclose($addtemplate);
-
-    $rsstemplate = fopen($exportdir . '/rsstemplate.html', 'w');
-    fwrite($rsstemplate, $data->rsstemplate);
-    fclose($rsstemplate);
-
-    $rsstitletemplate = fopen($exportdir . '/rsstitletemplate.html', 'w');
-    fwrite($rsstitletemplate, $data->rsstitletemplate);
-    fclose($rsstitletemplate);
-
-    $csstemplate = fopen($exportdir . '/csstemplate.css', 'w');
-    fwrite($csstemplate, $data->csstemplate);
-    fclose($csstemplate);
-
-    $jstemplate = fopen($exportdir . '/jstemplate.js', 'w');
-    fwrite($jstemplate, $data->jstemplate);
-    fclose($jstemplate);
-
-    $asearchtemplate = fopen($exportdir . '/asearchtemplate.html', 'w');
-    fwrite($asearchtemplate, $data->asearchtemplate);
-    fclose($asearchtemplate);
-
-    // Check if all files have been generated
-    if (! is_directory_a_preset($exportdir)) {
-        print_error('generateerror', 'data');
-    }
-
-    $filelist = array(
-        'preset.xml',
-        'singletemplate.html',
-        'listtemplateheader.html',
-        'listtemplate.html',
-        'listtemplatefooter.html',
-        'addtemplate.html',
-        'rsstemplate.html',
-        'rsstitletemplate.html',
-        'csstemplate.css',
-        'jstemplate.js',
-        'asearchtemplate.html'
-    );
-
-    foreach ($filelist as $key => $file) {
-        $filelist[$key] = $exportdir . '/' . $filelist[$key];
-    }
-
-    $exportfile = "$CFG->dataroot/$course->id/moddata/data/$data->id/$presetname.zip";
-    file_exists($exportfile) && unlink($exportfile);
-    $status = zip_files($filelist, $exportfile);
-    // ToDo: status check
-    foreach ($filelist as $file) {
-        unlink($file);
-    }
-    rmdir($exportdir);
-
-    // Return the full path to the exported preset file:
-    return $exportfile;
-}
-
-
+echo $OUTPUT->footer();
\ No newline at end of file
Index: moodle/mod/data/preset_form.php
--- moodle/mod/data/preset_form.php No Base Revision
+++ moodle/mod/data/preset_form.php Locally New
@@ -0,0 +1,57 @@
+<?php
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden!');
+}
+require_once($CFG->libdir . '/formslib.php');
+
+
+class data_existing_preset_form extends moodleform {
+    public function definition() {
+        $this->_form->addElement('header', 'presets', get_string('usestandard', 'data'));
+        $this->_form->addHelpButton('presets', 'usestandard', 'data');
+
+        $this->_form->addElement('hidden', 'd');
+        $this->_form->addElement('hidden', 'action', 'confirmdelete');
+        $delete = get_string('delete');
+        foreach ($this->_customdata['presets'] as $preset) {
+            $this->_form->addElement('radio', 'fullname', null, ' '.$preset->description, $preset->userid.'/'.$preset->shortname);
+        }
+        $this->_form->addElement('submit', 'importexisting', get_string('choose'));
+    }
+}
+
+class data_import_preset_zip_form extends moodleform {
+    public function definition() {
+        $this->_form->addElement('header', 'uploadpreset', get_string('fromfile', 'data'));
+        $this->_form->addHelpButton('uploadpreset', 'fromfile', 'data');
+
+        $this->_form->addElement('hidden', 'd');
+        $this->_form->addElement('hidden', 'action', 'importzip');
+        $this->_form->addElement('filepicker', 'importfile', get_string('chooseorupload', 'data'));
+        $this->_form->addRule('importfile', null, 'required');
+        $this->_form->addElement('submit', 'uploadzip', get_string('import'));
+    }
+}
+
+class data_export_form extends moodleform {
+    public function definition() {
+        $this->_form->addElement('header', 'exportheading', get_string('exportaszip', 'data'));
+        $this->_form->addElement('hidden', 'd');
+        $this->_form->addElement('hidden', 'action', 'export');
+        $this->_form->addElement('submit', 'export', get_string('export', 'data'));
+    }
+}
+
+class data_save_preset_form extends moodleform {
+    public function definition() {
+        $this->_form->addElement('header', 'exportheading', get_string('saveaspreset', 'data'));
+        $this->_form->addElement('hidden', 'd');
+        $this->_form->addElement('hidden', 'action', 'save2');
+        $this->_form->addElement('text', 'name', get_string('shortname'));
+        $this->_form->setType('name', PARAM_FILE);
+        $this->_form->addRule('name', null, 'required');
+        $this->_form->addElement('checkbox', 'override', get_string('overwrite', 'data'), get_string('overrwritedesc', 'data'));
+        $this->_form->addElement('submit', 'saveaspreset', get_string('continue'));
+    }
+}
\ No newline at end of file
Index: moodle/mod/data/renderer.php
--- moodle/mod/data/renderer.php No Base Revision
+++ moodle/mod/data/renderer.php Locally New
@@ -0,0 +1,86 @@
+<?php
+
+defined('MOODLE_INTERNAL') || die();
+
+class mod_data_renderer extends plugin_renderer_base {
+    
+    public function import_setting_mappings($datamodule, data_preset_importer $importer) {
+
+        $strblank = get_string('blank', 'data');
+        $strcontinue = get_string('continue');
+        $strwarning = get_string('mappingwarning', 'data');
+        $strfieldmappings = get_string('fieldmappings', 'data');
+        $strnew = get_string('new');
+
+
+        $params = $importer->get_preset_settings();
+        $settings = $params->settings;
+        $newfields = $params->importfields;
+        $currentfields = $params->currentfields;
+
+        $html  = html_writer::start_tag('div', array('class'=>'presetmapping'));
+        $html .= html_writer::start_tag('form', array('method'=>'post', 'action'=>''));
+        $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', array('type'=>'hidden', 'name'=>'sesskey', 'value'=>sesskey()));
+        $html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'d', 'value'=>$datamodule->id));
+        
+        if ($importer instanceof data_preset_existing_importer) {
+            $html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'fullname', 'value'=>$importer->get_userid().'/'.$importer->get_directory()));
+        } else {
+            $html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'directory', 'value'=>$importer->get_directory()));
+        }
+
+        if (!empty($newfields)) {
+            $html .= $this->output->heading_with_help($strfieldmappings, 'fieldmappings', 'data');
+
+            $table = new html_table();
+            $table->data = array();
+
+            foreach ($newfields as $nid => $newfield) {
+                $row = array();
+                $row[0] = html_writer::tag('label', $newfield->name, array('for'=>'id_'.$newfield->name));
+                $row[1] = html_writer::start_tag('select', array('name'=>'field_'.$nid, 'id'=>'id_'.$newfield->name));
+
+                $selected = false;
+                foreach ($currentfields as $cid => $currentfield) {
+                    if ($currentfield->type != $newfield->type) {
+                        continue;
+                    }
+                    if ($currentfield->name == $newfield->name) {
+                        $row[1] .= html_writer::tag('option', get_string('mapexistingfield', 'data', $currentfield->name), array('value'=>$cid, 'selected'=>'selected'));
+                        $selected=true;
+                    } else {
+                        $row[1] .= html_writer::tag('option', get_string('mapexistingfield', 'data', $currentfield->name), array('value'=>$cid));
+                    }
+                }
+
+                if ($selected) {
+                    $row[1] .= html_writer::tag('option', get_string('mapnewfield', 'data'), array('value'=>'-1'));
+                } else {
+                    $row[1] .= html_writer::tag('option', get_string('mapnewfield', 'data'), array('value'=>'-1', 'selected'=>'selected'));
+                }
+                
+                $row[1] .= html_writer::end_tag('select');
+                $table->data[] = $row;
+            }
+            $html .= html_writer::table($table);
+            $html .= html_writer::tag('p', $strwarning);
+        } else {
+            $html .= $this->output->notification(get_string('nodefinedfields', 'data'));
+        }
+
+        $html .= html_writer::start_tag('div', array('class'=>'overwritesettings'));
+        $html .= html_writer::tag('label', get_string('overwritesettings', 'data'), array('for'=>'overwritesettings'));
+        $html .= html_writer::empty_tag('input', array('type'=>'checkbox', 'name'=>'overwritesettings', 'id'=>'overwritesettings'));
+        $html .= html_writer::end_tag('div');
+        $html .= html_writer::empty_tag('input', array('type'=>'submit', 'class'=>'button', 'value'=>$strcontinue));
+
+        $html .= html_writer::end_tag('div');
+        $html .= html_writer::end_tag('form');
+        $html .= html_writer::end_tag('div');
+
+        return $html;
+    }
+    
+}
\ No newline at end of file
