From 82e6b4705aa1ca6d0a3335d9bb16f0e9d8c40b83 Mon Sep 17 00:00:00 2001
From: Max <m.giller@tu-bs.de>
Date: Mon, 31 Jan 2022 00:11:45 +0100
Subject: [PATCH] Simple importer

---
 datasets/datasets.js              | 24 +++++++++
 datasets/datasets.php             | 87 +++++++++++++++++++++++++++----
 datasets/ks-datasets-database.php | 37 +++++++++++++
 editor/editor.php                 | 28 +++++++++-
 editor/js/interactions.js         | 43 +++++++++++++--
 5 files changed, 206 insertions(+), 13 deletions(-)

diff --git a/datasets/datasets.js b/datasets/datasets.js
index c1bc4b7..928a8cc 100644
--- a/datasets/datasets.js
+++ b/datasets/datasets.js
@@ -46,6 +46,30 @@ export function saveGraphJson(spaceId, json) {
     });
 }
 
+/**
+ * Takes the graph json object and stores it in the backend as a new space.
+ *
+ * @param {object} json Graph object
+ * @param {String} spaceName Name of space when imported.
+ * @param {String} spaceDescription Description of space when imported.
+ *
+ * @returns Promise returning state of query.
+ */
+export function importSpaceGraph(json, spaceName, spaceDescription = "") {
+    let payload = {
+        action: "import_space",
+        graph: JSON.stringify(json),
+        space_name: spaceName,
+        space_description: spaceDescription,
+    };
+
+    return jQuery.ajax({
+        type: "POST",
+        url: ks_global.ajax_url,
+        data: payload,
+    });
+}
+
 /**
  * Retrieves a list of all available spaces to choose from.
  *
diff --git a/datasets/datasets.php b/datasets/datasets.php
index 7c0e386..fab0d1a 100644
--- a/datasets/datasets.php
+++ b/datasets/datasets.php
@@ -142,21 +142,85 @@ function kg_list_spaces()
     wp_die();
 }
 
-add_action("wp_ajax_update_space", "kg_update_space"); // Fires only for logged-in-users
-//add_action("wp_ajax_nopriv_update_space", 'update_space' ); // Fires for everyone
-function kg_update_space()
+add_action("wp_ajax_import_space", "kg_import_space"); // Fires only for logged-in-users
+function kg_import_space()
 {
     // Check user capabilities
-    if (current_user_can("edit_posts")) {
-        // Use json encoding.
-        $graph = stripslashes($_POST["graph"]);
+    if (!current_user_can("edit_posts")) {
+        echo "Insufficient permissions!";
+        wp_die();
+    }
+
+    // Import space
+    $space_id = ks_insert_space($_POST["space_name"], $_POST["space_description"]);
+
+    $graph = json_decode(stripslashes($_POST["graph"]));
+
+    // Import nodes
+    $node_id_map = array();
+    foreach ($graph->nodes as $node) {
+        // Import type
+        $type_id = null;
+        $type = ks_select_nodetype_on_name($space_id, $node->type);
+        if ($type == null) {
+            // Does not actually exist yet
+            $type_id = ks_insert_nodetype(array(
+                "space_id" => $space_id,
+                "name" => $node->type,
+                "color" => get_random_color(),
+            ));
+        } else {
+            $type_id = $type->nodetype_id;
+        }
+
+        // Import node
+        $node_id = ks_insert_node(array(
+            "space_id" => $space_id,
+            "title" => $node->name, // TODO: Keys should math, both should be "title"
+            "description" => $node->description,
+            "video_url" => $node->video,
+            "header_url" => $node->header,
+            "icon_url" => $node->icon,
+            "nodetype_id" => $type_id,
+        ));
+        $node_id_map[$node->id] = $node_id;
+
+        // Import references
+        foreach ($node->references as $reference) {
+            ks_insert_rference(array(
+                "node_id" => $node_id,
+                "url" => $reference
+            ));
+        }
+    }
 
-        kg_store_new_graph($graph, $_POST["space"]);
+    // Import links
+    foreach ($graph->links as $link) {
+        ks_insert_link(array(
+            "source_node_id" => $node_id_map[$link->source],
+            "target_node_id" => $node_id_map[$link->target],
+        ));
+    }
 
-        wp_die();
-    } else {
+
+    wp_die();
+}
+
+add_action("wp_ajax_update_space", "kg_update_space"); // Fires only for logged-in-users
+function kg_update_space()
+{
+    // Check user capabilities
+    if (!current_user_can("edit_posts")) {
         echo "Insufficient permissions!";
+        wp_die();
     }
+
+    // Use json encoding.
+    $graph = stripslashes($_POST["graph"]);
+
+    kg_store_new_graph($graph, $_POST["space"]);
+
+    wp_die();
 }
 
 function kg_store_new_graph($graph, $space_id)
@@ -200,3 +264,8 @@ function ks_spaces_to_array($spaces)
 
     return $array;
 }
+
+function get_random_color()
+{
+    return str_pad(strval(decbin(rand(0, pow(2, 24)))), 24, '0', STR_PAD_LEFT);
+}
diff --git a/datasets/ks-datasets-database.php b/datasets/ks-datasets-database.php
index 8606b1e..1469afb 100644
--- a/datasets/ks-datasets-database.php
+++ b/datasets/ks-datasets-database.php
@@ -45,6 +45,30 @@ function ks_insert_space($name = null, $description = "")
     return $wpdb->insert_id;
 }
 
+function ks_insert_nodetype($nodetype)
+{
+    global $NODETYPES_TABLE;
+    return ks_insert($NODETYPES_TABLE, $nodetype);
+}
+
+function ks_insert_node($node)
+{
+    global $NODES_TABLE;
+    return ks_insert($NODES_TABLE, $node);
+}
+
+function ks_insert_link($link)
+{
+    global $LINKS_TABLE;
+    return ks_insert($LINKS_TABLE, $link);
+}
+
+function ks_insert_rference($reference)
+{
+    global $REFERENCES_TABLE;
+    return ks_insert($REFERENCES_TABLE, $reference);
+}
+
 function ks_select_space_nodes($space_id)
 {
     global $NODES_TABLE;
@@ -69,6 +93,11 @@ function ks_select_nodetype($nodetype_id)
     global $NODETYPES_TABLE;
     return ks_select_single("SELECT * FROM $NODETYPES_TABLE WHERE nodetype_id = %d", $nodetype_id);
 }
+function ks_select_nodetype_on_name($space_id, $name)
+{
+    global $NODETYPES_TABLE;
+    return ks_select_single("SELECT * FROM $NODETYPES_TABLE WHERE space_id = %d AND name = %s", array($space_id, $name));
+}
 
 function ks_select_space_references($space_id)
 {
@@ -100,3 +129,11 @@ function ks_select_single($query, $parameters = array())
         return null;
     }
 }
+
+function ks_insert($table, $data)
+{
+    global $wpdb;
+    $wpdb->insert($table, $data);
+
+    return $wpdb->insert_id;
+}
diff --git a/editor/editor.php b/editor/editor.php
index d496d1f..2cbadc0 100644
--- a/editor/editor.php
+++ b/editor/editor.php
@@ -1,7 +1,9 @@
 <div id="ks-editor">
     <!--The id "ks-editor" indicates, that the javascript associated with this should automatically be executed-->
     <h1>Interface</h1>
-    <div id="box-select-layer"><div id="2d-graph"></div></div>
+    <div id="box-select-layer">
+        <div id="2d-graph"></div>
+    </div>
     <section id="toolbar"></section>
     <section id="tool-menu">
         <div id="delete-menu" class="hidden">
@@ -93,6 +95,30 @@
             </br>
             <input type="number" onkeypress="return (event.charCode !=8 && event.charCode ==0 || (event.charCode >= 48 && event.charCode <= 57))" value="5" id="stop-physics-delay" name="stop-physics-delay" class="small-width">
             </input>
+            </br>
+            </br>
+
+
+            <h3>Import Space</h3>
+            <label for="import-space-area">Space JSON</label>
+            </br>
+            <textarea id="import-space-area" name="import-space-area" class="bottom-space">
+            </textarea>
+            </br>
+            <label for="import-space-name-text">Space Name</label>
+            </br>
+            <input type="text" id="import-space-name-text" name="import-space-name-text" class="bottom-space">
+            </input>
+            </br>
+            <label for="import-space-description-text">Space Description</label>
+            </br>
+            <textarea id="import-space-description-text" name="import-space-description-text" class="bottom-space">
+            </textarea>
+            </br>
+            <button id="import-space-btn" name="import-space-btn" class="bottom-space">Import</button>
+
+            </br>
+            </br>
         </div>
     </section>
 </div>
\ No newline at end of file
diff --git a/editor/js/interactions.js b/editor/js/interactions.js
index e1c66ea..ab721f0 100644
--- a/editor/js/interactions.js
+++ b/editor/js/interactions.js
@@ -1,6 +1,6 @@
 import jQuery from "jquery";
 import { state } from "./editor";
-import { listAllSpaces } from "../../datasets/datasets";
+import { importSpaceGraph, listAllSpaces } from "../../datasets/datasets";
 import { SPACE } from "../../config";
 
 /**
@@ -10,7 +10,12 @@ export function initInteractions() {
     jQuery("button#clear-collection").on("click", () => {
         state.clearSelectedItems();
     });
+    jQuery("button#import-space-btn").on("click", () => importSpaceFromInterface());
+    
+    loadSpacesList();
+}
 
+function loadSpacesList() {
     // Fill space dropdown
     var selectContainer = jQuery("#space-id-select");
     listAllSpaces().then((spaces) => {
@@ -20,10 +25,42 @@ export function initInteractions() {
             if (space_id === SPACE) {
                 selectedTxt = "selected ";
             }
-
-            var child = "<option " + selectedTxt + "value=\"" + space_id + "\" title=\"" + space.description + "\">" + space.name  + "</option>"
+            
+            var child = "<option " + selectedTxt + "value=\"" + space_id + "\" title=\"" + space.description + "\">" + space.name + "</option>";
             selectContainer.append(child);
         });
     });
     selectContainer.val(SPACE);
 }
+
+function importSpaceFromInterface() {
+    var json = undefined;
+    try {console.log(jQuery("#import-space-area").val());
+        json = JSON.parse(jQuery("#import-space-area").val());
+    }
+    catch (e) {
+        console.log(e);
+        alert("\"Space JSON\" not valid. Check console for details.");
+        return;
+    }
+    
+    
+    var spaceName = jQuery("#import-space-name-text").val();
+    if (spaceName.length == 0) {
+        alert("\"Space Name\" cannot be empty.");
+        return;
+    }
+
+    var spaceDescription = jQuery("#import-space-description-text").val();
+    
+    importSpaceGraph(json, spaceName, spaceDescription).then(() => {
+        loadSpacesList();
+        alert("Space imported!");
+    })
+    .catch((ex) => {
+        console.log(ex);
+        alert("Something went wrong, could not import space. Check console for further details.");
+    })
+    
+
+}
\ No newline at end of file
-- 
GitLab