From a10d1cb53f341dd91915f9eb6ec3cdbbc44584fc Mon Sep 17 00:00:00 2001
From: enured <enis.nuredini@uzh.ch>
Date: Thu, 24 Nov 2022 17:44:27 +0100
Subject: [PATCH] B14305: Implemented history function for inline editing
 report.  refs #14305

---
 extension/Classes/Core/Constants.php         |  4 +++
 extension/Classes/Core/Database/Database.php | 32 ++++++++++++++++++++
 extension/Classes/Core/QuickFormQuery.php    | 32 ++++++++++++++++++++
 javascript/src/Helper/codemirror.js          | 23 ++++++++++----
 4 files changed, 85 insertions(+), 6 deletions(-)

diff --git a/extension/Classes/Core/Constants.php b/extension/Classes/Core/Constants.php
index 023cf568a..68ab7cc69 100644
--- a/extension/Classes/Core/Constants.php
+++ b/extension/Classes/Core/Constants.php
@@ -303,6 +303,8 @@ const ERROR_DB_COLUMN_NOT_FOUND_IN_TABLE = 2014;
 const ERROR_DB_SET_CHARSET = 2015;
 const ERROR_DB_MULTI_QUERY_FAILED = 2016;
 
+const ERROR_DB_HISTORY_DATA = 2017;
+
 // onArray
 const ERROR_SUBSTITUTE_FOUND = 2100;
 
@@ -1576,6 +1578,8 @@ const T3DATA_KEYWORDS = 'keywords';
 const T3DATA_PID = 'pid';
 const T3DATA_HEADER = 'header';
 const T3DATA_REPORT_PATH_FILENAME = 'reportPathFileName';
+const T3DATA_OLD_RECORD = 'oldRecord';
+const T3DATA_NEW_RECORD = 'newRecord';
 const REPORT_INLINE_BODYTEXT = 'bodytext';
 const REPORT_FILE_EXTENSION = '.qfqr';
 const FORM_FILE_EXTENSION = '.json';
diff --git a/extension/Classes/Core/Database/Database.php b/extension/Classes/Core/Database/Database.php
index 193af4ed5..3b45ac213 100644
--- a/extension/Classes/Core/Database/Database.php
+++ b/extension/Classes/Core/Database/Database.php
@@ -1180,4 +1180,36 @@ class Database {
         return $this->sql("SELECT tableName FROM Form WHERE id=".$formId, ROW_EXPECT_GE_1, array(), "No form found with this id: '$formId'");
 
     }
+
+    /**
+     * Get beUser uid for tt_content history data
+     *
+     * @throws \UserFormException
+     * @throws \CodeException
+     * @throws \DbException
+     * @throws \UserReportException
+     */
+    public function getBeUserUid($beUserName) {
+        $dbT3 = $this->store->getVar(SYSTEM_DB_NAME_T3, STORE_SYSTEM);
+        $sql = "SELECT uid FROM `$dbT3`.`be_users` WHERE username = ?";
+        return $this->sql($sql, ROW_REGULAR, [$beUserName])[0]['uid'];
+
+    }
+
+    /**
+     * Create history record for inline editing reports.
+     *
+     * @param $dataHistory
+     * @return void
+     * @throws \CodeException
+     * @throws \DbException
+     * @throws \UserFormException
+     * @throws \UserReportException
+     */
+    public function setHistoryRecord($dataHistory) {
+        $dbT3 = $this->store->getVar(SYSTEM_DB_NAME_T3, STORE_SYSTEM);
+        $sql = "INSERT INTO `$dbT3`.`sys_history` (pid, tstamp, actiontype, usertype, userid, originaluserid, recuid, tablename, history_data, workspace)
+                VALUES (?,?,?,?,?,?,?,?,?,?)";
+        $this->sql($sql, ROW_REGULAR, $dataHistory, "Creating history record failed.");
+    }
 }
\ No newline at end of file
diff --git a/extension/Classes/Core/QuickFormQuery.php b/extension/Classes/Core/QuickFormQuery.php
index 38a267519..1cf0e911a 100644
--- a/extension/Classes/Core/QuickFormQuery.php
+++ b/extension/Classes/Core/QuickFormQuery.php
@@ -1807,6 +1807,8 @@ class QuickFormQuery {
      */
     public function saveForm() {
         if ($this->store->getVar(REPORT_SAVE, STORE_SIP . STORE_ZERO) == '1') {
+            // Before saving report, first save history to get unchanged bodytext
+            $this->saveHistory();
             $this->saveReport();
             $json = array();
             $json[REPORT_SAVE] = 1;
@@ -2297,4 +2299,34 @@ EOF;
         }
     }
 
+    /**
+     * Save report history if changes are given.
+     *
+     * @throws \CodeException
+     * @throws \UserFormException
+     * @throws \DbException
+     * @throws \UserReportException
+     */
+    private function saveHistory() {
+        $uid = $this->store::getVar(T3DATA_UID,STORE_SIP);
+        $beUser = $this->store::getVar(TYPO3_BE_USER, STORE_TYPO3);
+        $beUserUid = $this->dbArray[$this->dbIndexData]->getBeUserUid($beUser);
+
+        // If some of the following values are not given.
+        if (empty($uid) || empty($beUser) || !isset($_POST[T3DATA_BODYTEXT])) {
+            throw new \UserFormException("Some data are missed to save history (uid, beUser, bodytext).", ERROR_DB_HISTORY_DATA);
+        }
+        // Set payload values in readable typo3 array format.
+        $payload[T3DATA_NEW_RECORD][T3DATA_BODYTEXT] = $_POST[T3DATA_BODYTEXT];
+        $payload[T3DATA_OLD_RECORD][T3DATA_BODYTEXT] = $this->dbArray[$this->dbIndexData]->getBodyText($uid)[T3DATA_BODYTEXT];
+
+        // Needed values for history record: pid, tstamp, actiontype, usertype, userid, originaluserid, recuid, tablename, history_data, workspace
+        $dataHistory = [0, time(), 2, 'BE', $beUserUid, 0, $uid, 'tt_content', json_encode($payload), 0];
+
+        // Only save history if changes are given
+        if (strcmp($payload[T3DATA_OLD_RECORD][T3DATA_BODYTEXT], $payload[T3DATA_NEW_RECORD][T3DATA_BODYTEXT])) {
+            $this->dbArray[$this->dbIndexData]->setHistoryRecord($dataHistory);
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/javascript/src/Helper/codemirror.js b/javascript/src/Helper/codemirror.js
index eb7bec348..8ff37a0e7 100644
--- a/javascript/src/Helper/codemirror.js
+++ b/javascript/src/Helper/codemirror.js
@@ -115,12 +115,23 @@ $(document).ready(function(){
 
     // execute changes(post) and reload page with id of tt-content as get parameter. Staying in same window with new content.
     $(externWindow).submit(function() {
-        $.post($(externWindow).attr('action'),$(externWindow).serializeArray());
-        $('<span style="position:absolute; top:5px; right:5px; background-color: green;" class="badge badge-success">Saved</span>')
-            .insertBefore('.qfq-form-title>br')
-            .delay(3000)
-            .fadeOut(function() {
-                $(this).remove();
+        $.post($(externWindow).attr('action'),$(externWindow).serializeArray())
+            .done(function(data) {
+                console.log(data);
+                var badge;
+                if (data.status === "error") {
+                    data.message = data.message.replace(/(<([^>]+)>)/gi, "\n");
+                    alert(data.message);
+                    badge = '<span style="position:absolute; top:5px; right:5px; background-color: red;" class="badge badge-danger">Failed</span>';
+                } else {
+                    badge = '<span style="position:absolute; top:5px; right:5px; background-color: green;" class="badge badge-success">Saved</span>';
+                }
+                $(badge)
+                    .insertBefore('.qfq-form-title>br')
+                    .delay(3000)
+                    .fadeOut(function() {
+                        $(this).remove();
+                    });
             });
         return false;
     });
-- 
GitLab