diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 04def2a..0000000 --- a/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# Datenbankverbindung (enthält Passwörter) -ajax/db_connection.php - -# Logdateien -*.log - -# Backup-Dateien -*.bak - -# Datenbankdumps -*.sql - -# Versionierte Backup-Dateien -*.20* diff --git a/README.md b/README.md deleted file mode 100644 index 8ac34bc..0000000 --- a/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Thesaurus - -Webbasierte Thesaurus-Verwaltung für Schlagwörter, Personen, Körperschaften, Verlage und Klassifikationen. - -## Voraussetzungen - -- PHP 7.4 oder höher -- MySQL/MariaDB -- Apache Webserver - -## Installation - -1. Repository klonen -2. `ajax/db_connection.php.example` kopieren und umbenennen: - ```bash - cp ajax/db_connection.php.example ajax/db_connection.php - ``` -3. Zugangsdaten in `ajax/db_connection.php` eintragen -4. Abhängigkeiten installieren: - ```bash - bash setup-libs.sh - ``` diff --git a/Statistics.php b/Statistics.php new file mode 100644 index 0000000..7cb2f31 --- /dev/null +++ b/Statistics.php @@ -0,0 +1,90 @@ + + + + + + + + + + + + +
+
+
+ + + + + +
+
+
Normdaten Statistik
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+
+
+ + + + +
+
+
+ + + diff --git a/TSData.sql b/TSData.sql new file mode 100644 index 0000000..68579c1 --- /dev/null +++ b/TSData.sql @@ -0,0 +1,152 @@ +/*M!999999\- enable the sandbox mode */ +-- MariaDB dump 10.19 Distrib 10.5.29-MariaDB, for debian-linux-gnu (x86_64) +-- +-- Host: localhost Database: TSData +-- ------------------------------------------------------ +-- Server version 10.5.29-MariaDB-0+deb11u1 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `Anchor` +-- + +DROP TABLE IF EXISTS `Anchor`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `Anchor` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `Text` varchar(255) NOT NULL, + `DetailType` varchar(64) NOT NULL, + `Type` varchar(32) DEFAULT NULL, + `Classification` varchar(255) DEFAULT NULL, + `Formprinted` varchar(255) DEFAULT NULL, + `Place` varchar(255) DEFAULT NULL, + PRIMARY KEY (`ID`), + KEY `Type` (`DetailType`), + KEY `Text` (`Text`) +) ENGINE=InnoDB AUTO_INCREMENT=101001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `Entry` +-- + +DROP TABLE IF EXISTS `Entry`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `Entry` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `Text` varchar(255) NOT NULL, + `Comment` text DEFAULT NULL, + `Language` varchar(3) NOT NULL DEFAULT 'de', + `CompleteText` text DEFAULT NULL, + `DateCreated` timestamp NOT NULL DEFAULT current_timestamp(), + `DateModified` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + PRIMARY KEY (`ID`), + KEY `Text` (`Text`) +) ENGINE=InnoDB AUTO_INCREMENT=101001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `EntryNew` +-- + +DROP TABLE IF EXISTS `EntryNew`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `EntryNew` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `Text` varchar(255) NOT NULL, + `Comment` text DEFAULT NULL, + `Language` varchar(3) NOT NULL DEFAULT 'de', + `CompleteText` text DEFAULT NULL, + PRIMARY KEY (`ID`), + KEY `Text` (`Text`) +) ENGINE=InnoDB AUTO_INCREMENT=9919 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `IDSynonym` +-- + +DROP TABLE IF EXISTS `IDSynonym`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `IDSynonym` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=1131 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `Linking` +-- + +DROP TABLE IF EXISTS `Linking`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `Linking` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `IDAnchor` int(11) NOT NULL, + `IDEntry` int(11) NOT NULL, + `Relationtype` varchar(32) NOT NULL, + PRIMARY KEY (`ID`), + KEY `IDConcept` (`IDAnchor`), + KEY `IDRelated` (`IDEntry`), + KEY `Relationtype` (`Relationtype`) +) ENGINE=InnoDB AUTO_INCREMENT=30474 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `Synonyms` +-- + +DROP TABLE IF EXISTS `Synonyms`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `Synonyms` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `IDLinking` int(11) DEFAULT NULL, + `Text` varchar(255) NOT NULL, + `Descriptor` varchar(255) DEFAULT NULL, + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=2875 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `Treeview` +-- + +DROP TABLE IF EXISTS `Treeview`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `Treeview` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(200) NOT NULL, + `text` varchar(200) NOT NULL, + `link` varchar(200) NOT NULL, + `parent_id` varchar(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=98579 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2026-02-20 7:34:40 diff --git a/ajax/TSData.sql b/ajax/TSData.sql new file mode 100644 index 0000000..e69de29 diff --git a/ajax/db_connection.php.example b/ajax/db_connection.php similarity index 78% rename from ajax/db_connection.php.example rename to ajax/db_connection.php index 09332fd..c403ac5 100644 --- a/ajax/db_connection.php.example +++ b/ajax/db_connection.php @@ -1,15 +1,18 @@ getStatistics($dateStart, $dateEnd); + +$typeLabels = [ + 'Subject' => 'Schlagworte', + 'Person' => 'Personennamen', + 'Corporate' => 'Körperschaften', + 'Publisher' => 'Verlage', + 'Classification' => 'Klassifikationen', +]; + +$sumCreated = 0; +$sumModified = 0; +$rows = ''; +$rank = 1; + +foreach ($Results as $type => $result) { + $sumCreated += $result['DateCreated']; + $sumModified += $result['DateModified']; + $label = $typeLabels[$type] ?? $type; + $created = number_format($result['DateCreated'], 0, ',', '.'); + $modified = number_format($result['DateModified'], 0, ',', '.'); + $rows .= "" + . "{$rank}" + . "{$label}" + . "{$created}" + . "{$modified}" + . ""; + $rank++; +} + +$totalCreated = number_format($sumCreated, 0, ',', '.'); +$totalModified = number_format($sumModified, 0, ',', '.'); + +$foot = "" + . "Summen" + . "{$totalCreated}" + . "{$totalModified}" + . ""; + +$von = date('d.m.Y', strtotime($dateStart)); +$bis = date('d.m.Y', strtotime($dateEnd)); + +echo json_encode([ + "status" => 200, + "rows" => $rows, + "foot" => $foot, + "zeitraum" => "Zeitraum: {$von} – {$bis}" +]); diff --git a/ajax/libAuthorities.php b/ajax/libAuthorities.php index b93011a..c614caa 100644 --- a/ajax/libAuthorities.php +++ b/ajax/libAuthorities.php @@ -135,8 +135,8 @@ class CRUD JOIN Entry ON (Anchor.ID = Entry.ID) WHERE Type = :authType"; - if (strlen($search) > 0 && $sharp == false) { - $query .= " AND LOWER(Entry.CompleteText) LIKE LOWER(:search)"; + if (strlen($search) > 0 && $sharp == false) { + //$query .= " AND LOWER(Entry.CompleteText) LIKE LOWER(:search)"; $params[':search'] = $this->buildSearchPattern($search); } if (strlen($search) > 0 && $sharp == true) { @@ -211,7 +211,7 @@ class CRUD WHERE Type = :authType"; if (strlen($search) > 0) { - $query .= " AND LOWER(Entry.CompleteText) LIKE LOWER(:search)"; + //$query .= " AND LOWER(Entry.CompleteText) LIKE LOWER(:search)"; $params[':search'] = $this->buildSearchPattern($search); } if ($id > 0) { diff --git a/ajax/libAuthorities.php.20251206 b/ajax/libAuthorities.php.20251206 new file mode 100644 index 0000000..dba0f6b --- /dev/null +++ b/ajax/libAuthorities.php.20251206 @@ -0,0 +1,362 @@ +db = DB(); + } + + function __destruct() + { + $this->db = null; + } + + + + public function readAuthorityNumbersOfRecords($authType, $search, $id, $sharp) + { + $query = "SELECT COUNT(*) as count, Anchor.ID FROM Anchor "; + $query .= "JOIN Entry ON (Anchor.ID = Entry.ID) WHERE Type = '" .$authType ."' "; + if (strlen ($search) > 0 && $sharp == false) $query .= " AND LOWER(Entry.CompleteText) LIKE LOWER('" .$search ."%') "; + if (strlen ($search) > 0 && $sharp == true) $query .= " AND LOWER(Entry.Text) = LOWER('" .$search ."') "; + if ($id > 0) + $query .= "AND Entry.ID = " .$id; + // echo $query ."\n"; + $query = $this->db->prepare($query); + $query->execute(); + + $num = 0; + while($rec = ($query->fetch(PDO::FETCH_ASSOC))) { + // print_r($rec); + $num = $rec['count'] ; + } + return $num; + + } + + + public function readAuthorityEntriesByID($authType, $id) + { + $query = "SELECT Anchor.ID AS ID, Anchor.DetailType AS DetailType, Anchor.Type AS Type, Anchor.Classification AS Classification, Entry.Text as Text, Entry.Comment as Scopenote from Anchor "; + $query .= "JOIN Entry ON (Anchor.ID = Entry.ID) WHERE Anchor.ID = $id AND Type = '" .$authType ."' "; + // echo $query ."\n"; exit; + $query = $this->db->prepare($query); + $query->execute(); + + $count = $query->rowCount(); + + $ret = array(); + while($rec = ($query->fetch(PDO::FETCH_ASSOC))) { + // print_r($rec); + $relations = $this->getRelations($authType,$rec['ID']); + $ret[] = array("ID" => $rec['ID'], "Descriptor" => $relations['Descriptor'], "Text" => $rec['Text'], "DetailType" => $rec['DetailType'], "Type" => $rec['Type'], "Scopenote" => $rec['Scopenote'], "Relations" => $relations['Data'], "Classification" => $rec['Classification']) ; + } + + return (array("COUNT" => $count, "RECORDS" => $ret)); + } + + + public function readAuthorityEntries($authType, $offset, $search, $id, $sort, $max) + { + $limit = " limit " .$offset ."," .$max ; + $sort = " order by " .$sort; + $query = "SELECT Anchor.ID AS ID, Anchor.DetailType AS DetailType, Anchor.Type AS Type, Anchor.Classification AS Classification, Entry.Text as Text, Entry.Comment as Scopenote from Anchor "; + $query .= "JOIN Entry ON (Anchor.ID = Entry.ID) WHERE Type = '" .$authType ."' "; + if (strlen ($search) > 0) + $query .= "AND LOWER(Entry.CompleteText) LIKE LOWER('" .$search ."%') "; + if ($id > 0) + $query .= "AND Entry.ID = " .$id; + $query .= $sort .$limit; + // echo $query ."\n"; exit; + $query = $this->db->prepare($query); + //$query->bindParam("authType", $authType, PDO::PARAM_STR); + $query->execute(); + + $count = $query->rowCount(); + + $ret = array(); + while($rec = ($query->fetch(PDO::FETCH_ASSOC))) { + // print_r($rec); + $relations = $this->getRelations($authType, $rec['ID']); + if (strcmp($authType,'Subject') == 0) { + $synonyms = $this->getSynonyms($rec['Text']); + // print_r($synonyms); + $ret[] = array("ID" => $rec['ID'], "Descriptor" => $relations['Descriptor'], "Text" => $rec['Text'], "DetailType" => $rec['DetailType'], "Type" => $rec['Type'], "Scopenote" => $rec['Scopenote'], "Relations" => $relations['Data'], "Classification" => $rec['Classification'], "Synonyms" => $synonyms['Synonyms'], "Search" => $synonyms['Search']) ; + } else { + $ret[] = array("ID" => $rec['ID'], "Descriptor" => $relations['Descriptor'], "Text" => $rec['Text'], "DetailType" => $rec['DetailType'], "Type" => $rec['Type'], "Scopenote" => $rec['Scopenote'], "Relations" => $relations['Data'], "Classification" => $rec['Classification']) ; + } + } + + return (array("COUNT" => $count, "RECORDS" => $ret)); + } + + + public function getRelations($authType,$id) + { + // $query = "SELECT Linking.ID as LinkingID, IDEntry, Entry.Text, Entry.Comment, Relationtype, DetailType FROM Linking JOIN Entry ON (Linking.IDEntry = Entry.ID) WHERE IDAnchor=" .$id ." AND Relationtype != '' order by Relationtype"; + $query = "SELECT Linking.ID as LinkingID, IDEntry, Entry.Text, Entry.Comment, Relationtype, DetailType FROM Linking JOIN Entry ON (Linking.IDEntry = Entry.ID) join Anchor on (IDAnchor = Anchor.ID) WHERE IDAnchor=" .$id ." AND Anchor.Type='" .$authType ."' AND Relationtype != '' order by Relationtype"; + $query = $this->db->prepare($query); + $query->execute(); + + $descriptor = true; + + $ret = array(); + while($rec = ($query->fetch(PDO::FETCH_ASSOC))) { + // print_r($rec); + if (strcmp(strtolower($rec['Relationtype']), "use") == 0) $descriptor = false; + $ret[] = array("IDLinking" => $rec['LinkingID'], "IDEntry" => $rec['IDEntry'], "IDRelation" => $rec['IDEntry'], "Detailtype" => $rec['DetailType'], "TextRelation" => $rec['Text'], "CommentRelation" => $rec['Comment'], "Relationtype" => $rec['Relationtype']); + } + + return array("Descriptor" => $descriptor, "Data" => $ret) ; + } + + + public function getSynonyms($input) + { + $desc = $this->prepare_desc($input); + $query = "SELECT IDLinking from Synonyms where Descriptor = '" .$desc ."'"; + $query = $this->db->prepare($query); + $query->execute(); + + $ret = '' ; + $retsearch = "topic:'" .$input ."' OR "; + while($rec = ($query->fetch(PDO::FETCH_ASSOC))) { + // print_r($rec); + $idSearch = $rec['IDLinking'] ; + $query = "SELECT Text from Synonyms where IDLinking = " .$idSearch ; + $query = $this->db->prepare($query); + $query->execute(); + while($rec = ($query->fetch(PDO::FETCH_ASSOC))) { + if (strcmp($rec['Text'], $input) == 0) continue; + $ret .= $rec['Text'] .", " ; + $retsearch .= "topic:'" .$rec['Text'] ."'" ." OR "; + } + } + if(strlen($ret) == 0) { + return array("Synonyms" => '', "Search" => ''); + } else { + $synonyms = trim(substr($ret, 0, strlen($ret) - strlen(", "))); + $search = trim(substr($retsearch, 0, strlen($retsearch) - strlen(" OR "))); + return (array("Synonyms" => $synonyms, "Search" => $search)) ; + } + } + + + + + public function getEntryText($authType,$Request) + { + $query = "SELECT Anchor.ID AS AnchorID, Entry.Text as Text FROM Anchor JOIN Entry on (Anchor.ID = Entry.ID) WHERE Anchor.Text LIKE LOWER('%" .$Request ."%') AND Anchor.Type='" .$authType ."' order by Entry.Text"; + $query = $this->db->prepare($query); + $query->execute(); + + $ret = array(); + while($rec = ($query->fetch(PDO::FETCH_ASSOC))) { + // print_r($rec); + $ret[] = array("Text" => $rec['Text'], "ID" => $rec['AnchorID']); + } + + return($ret); + } + + public function insertNewTerm($authType, $term, $desc, $detailtype, $classification, $scopenote, $completetext) + { + + $query = $this->db->prepare("INSERT INTO Anchor(ID, Text, DetailType, Type, Classification) VALUES (:ID, :Text, :DetailType, :Type, :Classification)"); + + $id = NULL; + + $query->bindParam("ID", $id, PDO::PARAM_INT); + $query->bindParam("Text", $desc, PDO::PARAM_STR); + $query->bindParam("DetailType", $detailtype, PDO::PARAM_STR); + $query->bindParam("Type", $authType, PDO::PARAM_STR); + $query->bindParam("Classification", $classification, PDO::PARAM_STR); + $query->execute(); + + $IDAnchor = $this->db->lastInsertId(); + + $query = $this->db->prepare("INSERT INTO Entry(ID, Text, Comment, Language, CompleteText, DateCreated, DateModified) VALUES (:ID, :Text, :Comment, :Language, :CompleteText, :DateCreated,:DateModified)"); + + $id = NULL; + $language = "de"; + + $query->bindParam("ID", $id, PDO::PARAM_INT); + $query->bindParam("Text", $term, PDO::PARAM_STR); + $query->bindParam("Comment", $scopenote, PDO::PARAM_STR); + $query->bindParam("Language", $language, PDO::PARAM_STR); + $query->bindParam("CompleteText", $completetext, PDO::PARAM_STR); + $date = date('Y-m-d H:i:s'); + $query->bindParam("DateCreated", $date, PDO::PARAM_STR); + $date = '0000-00-00 00:00:00' ; + $query->bindParam("DateModified",$date, PDO::PARAM_STR); + + $query->execute(); + + $IDEntry = $this->db->lastInsertId(); + + $query = $this->db->prepare("INSERT INTO Linking(ID, IDAnchor, IDEntry, Relationtype) VALUES (:ID, :IDAnchor, :IDEntry, :Relationtype)"); + + $id = NULL; + $relationtype = ""; + + $query->bindParam("ID", $id, PDO::PARAM_INT); + $query->bindParam("IDAnchor", $IDAnchor, PDO::PARAM_INT); + $query->bindParam("IDEntry", $IDEntry, PDO::PARAM_INT); + $query->bindParam("Relationtype", $relationtype, PDO::PARAM_STR); + $query->execute(); + + $IDLinking = $this->db->lastInsertId(); + + return(array("IDAnchor" => $IDAnchor, "IDEntry" => $IDEntry, "IDLinking" => $IDLinking)); + + } + + + public function writeNewRelation($anchorID, $relationType, $relationID) + { + $query = $this->db->prepare("INSERT INTO Linking (ID, IDAnchor, IDEntry, Relationtype) VALUES (:ID, :IDAnchor, :IDEntry, :Relationtype)"); + + $id = NULL; + + $query->bindParam("ID", $id, PDO::PARAM_INT); + $query->bindParam("IDAnchor", $anchorID, PDO::PARAM_STR); + $query->bindParam("IDEntry", $relationID, PDO::PARAM_STR); + $query->bindParam("Relationtype", $relationType, PDO::PARAM_STR); + $query->execute(); + + $IDLinking = $this->db->lastInsertId(); + + return ($IDLinking); + + } + + public function deleteRelation($AnchorID, $LinkingID) + { + // $query = "DELETE FROM Linking where ID = " .$LinkingID; + // echo $query ."\n"; + $query = $this->db->prepare("DELETE FROM Linking where ID = " .$LinkingID); + + + // $query->bindParam("ID", $LinkingID, PDO::PARAM_INT); + $query->execute(); + + return ($LinkingID); + + } + + + public function deleteTerm($AnchorID) + { + $ret = array(); + $ret[] = 'DELETE FROM Linking where IDAnchor = ' .$AnchorID; + $query = $this->db->prepare("DELETE FROM Linking where IDAnchor = " .$AnchorID); + $query->execute(); + + $ret[] = $this->db->errorInfo(); + + $ret[] = 'DELETE FROM Entry where ID = ' .$AnchorID; + $query = $this->db->prepare("DELETE FROM Entry where ID = " .$AnchorID); + $query->execute(); + $ret[] = $this->db->errorInfo(); + + $ret[] = 'DELETE FROM Anchor where ID = ' .$AnchorID; + $query = $this->db->prepare("DELETE FROM Anchor where ID = " .$AnchorID); + $query->execute(); + $ret[] = $this->db->errorInfo(); + + return($ret); + } + + + public function updateTerm($AnchorID, $authType, $desc, $term, $type, $detailtype, $classification, $scopenote, $completetext) + { + $r = array(); + $q = "UPDATE Anchor set Text = '" .$desc ."', Type ='" .$authType ."' , DetailType = '" .$detailtype ."' , Classification = '" .$classification ."' where ID = " .$AnchorID; + $r[] = $q; + + $query = $this->db->prepare($q); + +/* $query->bindParam("ID", $AnchorID, PDO::PARAM_INT); + $query->bindParam("Text", $term, PDO::PARAM_STR); + $query->bindParam("Type", $Type, PDO::PARAM_STR); + $query->bindParam("DetailType", $DetailType, PDO::PARAM_STR); + $query->bindParam("Classification", $Classification, PDO::PARAM_STR); +*/ + $query->execute(); + $r[] = $this->db->errorCode(); + $r[] = $this->db->errorInfo(); + + $q = "UPDATE Entry set Text = :Text, Comment = :Comment, Language = :Language, CompleteText = :CompleteText, DateModified = :DateModified where ID = :ID"; + $r[] = $q; + + $query = $this->db->prepare($q); + + $Language = "de"; + + $query->bindParam("ID", $AnchorID, PDO::PARAM_INT); + $query->bindParam("Text", $term, PDO::PARAM_STR); + $query->bindParam("Language", $Language, PDO::PARAM_STR); + $query->bindParam("Comment", $scopenote, PDO::PARAM_STR); + $query->bindParam("CompleteText", $completetext, PDO::PARAM_STR); + $date = date('Y-m-d H:i:s'); + $query->bindParam("DateModified",($date), PDO::PARAM_STR); + + + $r[] = $q; + + $query->execute(); + + $r[] = $this->db->errorCode(); + $r[] = $this->db->errorInfo(); + + return("OK"); + } + + public function getStatistics($dateStart, $dateEnd) + { + $r = array(); + + $Types = array("Subject", "Person", "Corporate", "Publisher", "Classification"); + $DateTypes = array("DateCreated", "DateModified"); + + foreach($Types as $Type) { + foreach ($DateTypes as $DateType) { + $q = "SELECT COUNT(*) AS COUNT FROM Anchor JOIN Entry ON (Anchor.ID = Entry.ID) "; + $q.= "WHERE Type = '" .$Type ."' AND " .$DateType ." BETWEEN '" .$dateStart ."' AND '" .$dateEnd ."'" ; + $query = $this->db->prepare($q); + $query->execute(); + + while($rec = ($query->fetch(PDO::FETCH_ASSOC))) { + // print_r($rec); + $r[$Type][$DateType] = $rec['COUNT']; + } + } + } + return ($r); + } + + + + + + public function prepare_desc($text) { + + $desc = is_array($text)? $text[0] : $text; + $text = strtolower ($desc); + $desc = str_replace(' ', '_', $text) ; + $search = array('ü', 'ä', 'ö', 'ß', '.', ',', 'Ö', 'Ü', 'Ä', '[', ']', '<' , '>' , '""'); + $replace = array('ue','ae','oe','ss', '', '', 'oe',"ue", 'ae', '_', '_', '<', '>', '"' ); + $desc = str_replace($search, $replace, $desc); + + return ($desc); + } +} + +?> + + diff --git a/ajax/newClassification.php b/ajax/newClassification.php index 776a8ed..c262de6 100644 --- a/ajax/newClassification.php +++ b/ajax/newClassification.php @@ -109,15 +109,14 @@ try { // Hinweis: wenn Parent nicht gefunden → landet im Root (parent_id = 0) } } + // text = vollständiger Term (für jsTree-Anzeige), name = reines Label (für Suche) + $label = !empty($classification) ? trim(substr($term, strlen($classification))) : $term; + $textEscaped = mysqli_real_escape_string($conn, $term); + $nameEscaped = mysqli_real_escape_string($conn, $label); + $insertSql = "INSERT INTO Treeview (name, text, link, parent_id) + VALUES ('$nameEscaped', '$textEscaped', '#', '$parentId')"; - // name und text = vollständiger Term (Notation + Bezeichnung), link = '#' - $nameEscaped = mysqli_real_escape_string($conn, $term); - $insertSql = "INSERT INTO Treeview (name, text, link, parent_id) - VALUES ('$nameEscaped', '$nameEscaped', '#', '$parentId')"; - mysqli_query($conn, $insertSql); - $treeviewId = mysqli_insert_id($conn); - mysqli_close($conn); - } + } echo json_encode([ 'status' => 200, diff --git a/ajax/searchTreeData.php b/ajax/searchTreeData.php index d2baf65..244a55f 100644 --- a/ajax/searchTreeData.php +++ b/ajax/searchTreeData.php @@ -51,7 +51,7 @@ $pattern = ($leftTrunc ? '%' : '') . $sql = "SELECT id, name, text, parent_id FROM Treeview - WHERE LOWER(text) LIKE LOWER('$pattern') OR LOWER(name) LIKE LOWER('$pattern') + WHERE LOWER(name) LIKE LOWER('$pattern') ORDER BY text LIMIT 50"; diff --git a/error.log b/error.log new file mode 100644 index 0000000..e69de29 diff --git a/js/CorporateScript.js b/js/CorporateScript.js index 01fc7a0..039e1da 100644 --- a/js/CorporateScript.js +++ b/js/CorporateScript.js @@ -423,7 +423,7 @@ function DeleteTerm(AnchorID) function ModifyTerm(AnchorID) { // Name-Feld deaktivieren (darf nicht geändert werden) - document.getElementById("new_term").disabled = true; + // document.getElementById("new_term").disabled = true; // Andere Felder aktivieren document.getElementById("new_type").disabled = false; diff --git a/js/PersonScript.js b/js/PersonScript.js index 4a518ba..f5d1643 100644 --- a/js/PersonScript.js +++ b/js/PersonScript.js @@ -419,7 +419,7 @@ function DeleteTerm(AnchorID) function ModifyPerson(AnchorID) { // Name-Feld deaktivieren (darf nicht geändert werden) - document.getElementById("new_term").disabled = true; + // document.getElementById("new_term").disabled = true; // Andere Felder aktivieren document.getElementById("new_scopenote").disabled = false; diff --git a/js/PublisherScript.js b/js/PublisherScript.js index 3329f88..eb0edec 100644 --- a/js/PublisherScript.js +++ b/js/PublisherScript.js @@ -423,7 +423,7 @@ function DeleteTerm(AnchorID) function ModifyTerm(AnchorID) { // Name-Feld deaktivieren (darf nicht geändert werden) - document.getElementById("new_term").disabled = true; + // document.getElementById("new_term").disabled = true; // Andere Felder aktivieren document.getElementById("new_type").disabled = false; diff --git a/js/SubjectScript.js b/js/SubjectScript.js index 2f3599e..63e560b 100644 --- a/js/SubjectScript.js +++ b/js/SubjectScript.js @@ -623,7 +623,7 @@ function DeleteTerm(AnchorID) function ModifyTerm(AnchorID) { // Schlagwort-Feld deaktivieren (darf nicht geändert werden) - document.getElementById("new_term").disabled = true; + // document.getElementById("new_term").disabled = true; // Andere Felder aktivieren document.getElementById("new_type").disabled = false; diff --git a/js/script.js b/js/script.js new file mode 100644 index 0000000..1570d36 --- /dev/null +++ b/js/script.js @@ -0,0 +1,330 @@ +/** + * script.js – BIBB-Thesaurus Normdatenverwaltung + * Erstellt: 2021/07/01 (Roland) + * Überarbeitet: 2026/02 – Bugfixes, Bereinigung, Fehlertoleranz + */ + +// ============================================================ +// HILFSFUNKTIONEN +// ============================================================ + +/** + * Zeigt eine Fehlermeldung in einem Alert-Element an. + * @param {string} elementId ID des Alert-Divs + * @param {string} msg Anzuzeigende Nachricht + * @param {string} level Bootstrap-Level: 'danger' | 'warning' | 'success' + */ +function showAlert(elementId, msg, level) { + const a = document.getElementById(elementId); + if (!a) return; + a.className = 'alert alert-' + (level || 'danger'); + a.textContent = msg; + a.style.display = 'block'; +} + +function hideAlert(elementId) { + const a = document.getElementById(elementId); + if (!a) return; + a.className = 'alert'; + a.textContent = ''; + a.style.display = 'none'; +} + +function setFieldsDisabled(fields, disabled) { + fields.forEach(id => { + const el = document.getElementById(id); + if (el) el.disabled = disabled; + }); +} + +// ============================================================ +// SUCHE +// ============================================================ + +function Search() { + const search_string = $("#search_text").val().trim(); + + if (search_string === "") { + alert('Bitte Suchkriterien eingeben!'); + return; + } + + $.post("ajax/search.php", { search_string }, function(data) { + $(".records_content").html(data); + $("#search_text").val(""); + }).fail(function() { + alert('Fehler bei der Suche. Bitte erneut versuchen.'); + }); +} + +// ============================================================ +// NEUES SCHLAGWORT +// ============================================================ + +function newSubjectShow() { + const editableFields = ["new_term", "new_type", "new_detailtype", "new_classification", "new_scopenote"]; + + document.getElementById("newSubjectSave").style.display = 'inline'; + document.getElementById("newSubjectDismiss").style.display = 'inline'; + document.getElementById("SubjectModifySave").style.display = 'none'; + document.getElementById("new_relation_label").style.display = 'none'; + document.getElementById("newRelationSubjectDismiss").style.display = 'none'; + document.getElementById("relation_table").style.display = 'none'; + + setFieldsDisabled(editableFields, false); + hideAlert("errorNewSubject"); + + $("#new_term").val(""); + $("#new_classification").val(""); + $("#new_scopenote").val(""); + + showRelations(0, 0, 0); + $("#NewSubjectModal").modal("show"); +} + +function CreateNewEntry() { + const term = $("#new_term").val().trim(); + const type = $("#new_type").val().trim(); + const detailtype = $("#new_detailtype").val().trim(); + const classification = $("#new_classification").val().trim(); + const scopenote = $("#new_scopenote").val().trim(); + + if (term.length === 0) { + showAlert("errorNewSubject", "Bitte Schlagwort eingeben!", "danger"); + return; + } + + hideAlert("errorNewSubject"); + + $.post("ajax/newSubject.php", { term, type, detailtype, classification, scopenote }, + function(data) { + const dt = JSON.parse(data); + if (dt.status === 200) { + const editableFields = ["new_term", "new_type", "new_detailtype", "new_classification", "new_scopenote"]; + setFieldsDisabled(editableFields, true); + + document.getElementById("newSubjectSave").style.display = 'none'; + document.getElementById("newSubjectDismiss").style.display = 'none'; + document.getElementById("new_relation_label").style.display = 'block'; + document.getElementById("newRelationSubjectDismiss").style.display = 'inline'; + + showAlert("errorNewSubject", "Neues Schlagwort aufgenommen", "success"); + showRelations(dt.Anchor, dt.Entry, dt.Linking); + } else { + showAlert("errorNewSubject", dt.message || "Unbekannter Fehler", "danger"); + } + } + ).fail(function() { + showAlert("errorNewSubject", "Serverfehler beim Anlegen des Eintrags.", "danger"); + }); +} + +// ============================================================ +// RELATIONEN +// ============================================================ + +function showRelations(Anchor, Entry, Linking) { + $.get("ajax/getRelations.php", { anchorID: Anchor }, + function(data, status) { + if (status === "success") { + $(".new_modal_content").html(JSON.parse(data)); + document.getElementById("relation_table").style.display = 'block'; + $("#NewSubjectModal").modal("show"); + } + } + ).fail(function() { + console.error("Fehler beim Laden der Relationen für AnchorID:", Anchor); + }); +} + +function CreateNewRelation(AnchorID) { + const relationType = document.getElementById("new_relationtype").value; + const relationText = document.getElementById("search_relation").value; + const relationID = relationText.substring( + relationText.lastIndexOf(":") + 2, + relationText.lastIndexOf(")") + ).trim(); + + if (!relationID) { + showAlert("errorNewSubject", "Kein gültiger Relationseintrag ausgewählt.", "warning"); + return; + } + + $.post("ajax/writeNewRelation.php", { AnchorID, relationType, relationID }, + function(data, status) { + if (status === "success") { + showAlert("errorNewSubject", "Neue Relation aufgenommen", "success"); + showRelations(AnchorID, 0, 0); + } + } + ).fail(function() { + showAlert("errorNewSubject", "Fehler beim Speichern der Relation.", "danger"); + }); +} + +function DeleteRelation(AnchorID, LinkingID) { + $.post("ajax/deleteRelation.php", { AnchorID, LinkingID }, + function(data, status) { + if (status === "success") { + showAlert("errorNewSubject", "Relation gelöscht", "success"); + showRelations(AnchorID, 0, 0); + } + } + ).fail(function() { + showAlert("errorNewSubject", "Fehler beim Löschen der Relation.", "danger"); + }); +} + +// ============================================================ +// EINTRAG BEARBEITEN / LÖSCHEN +// ============================================================ + +function DeleteTerm(AnchorID) { + $.post("ajax/deleteTerm.php", { AnchorID: AnchorID[0] }, + function(data, status) { + if (status !== "success") { + alert(JSON.parse(data)); + } + } + ).fail(function() { + alert("Fehler beim Löschen des Eintrags."); + }); +} + +function ModifyTerm(AnchorID) { + $("#ID").val(AnchorID[0]); + + $.get("ajax/getAuthorityDataRaw.php", { id: AnchorID[0] }, + function(data, status) { + if (status === "success") { + const dt = JSON.parse(data).rows[0]; + if (!dt) return; + $("#new_term").val(dt.Text); + $("#new_id").val(dt.ID); + $("#new_detailtype").val(dt.DetailType); + $("#new_classification").val(dt.Classification); + $("#new_descriptor").val(dt.Descriptor); + $("#new_type").val(dt.Type); + $("#new_scopenote").val(dt.Scopenote); + } + } + ); + + $.get("ajax/getRelations.php", { anchorID: AnchorID[0] }, + function(data, status) { + if (status === "success") { + $(".new_modal_content").html(JSON.parse(data)); + document.getElementById("relation_table").style.display = 'block'; + document.getElementById("newSubjectSave").style.display = 'none'; + document.getElementById("newSubjectDismiss").style.display = 'inline'; + document.getElementById("SubjectModifySave").style.display = 'inline'; + document.getElementById("newRelationSubjectDismiss").style.display = 'none'; + $("#NewSubjectModalHeadline").val("Schlagwort ändern"); + $("#NewSubjectModal").modal("show"); + } + } + ); +} + +function UpdateEntry(authType) { + const AnchorID = $("#ID").val(); + const term = $("#new_term").val().trim(); + const type = $("#new_type").val().trim(); + const detailtype = $("#new_detailtype").val().trim(); + const classification = $("#new_classification").val().trim(); + const scopenote = $("#new_scopenote").val().trim(); + + if (term.length === 0) { + showAlert("errorNewSubject", "Bitte Schlagwort eingeben!", "danger"); + return; + } + + hideAlert("errorNewSubject"); + + $.post("ajax/UpdateTerm.php", { AnchorID, authType, term, type, detailtype, classification, scopenote }, + function(data, status) { + if (status === "success") { + document.getElementById("relation_table").style.display = 'block'; + document.getElementById("newSubjectSave").style.display = 'none'; + document.getElementById("newSubjectDismiss").style.display = 'inline'; + document.getElementById("SubjectModifySave").style.display = 'none'; + document.getElementById("newRelationSubjectDismiss").style.display = 'none'; + showAlert("errorNewSubject", "Schlagwort geändert", "success"); + $("#NewSubjectModalHeadline").val("Schlagwort ändern"); + $("#NewSubjectModal").modal("show"); + } + } + ).fail(function() { + showAlert("errorNewSubject", "Fehler beim Speichern des Eintrags.", "danger"); + }); +} + +// ============================================================ +// STATISTIK +// ============================================================ + +function generateStatistics() { + const startVal = document.getElementById("startPeriod").value; + const endVal = document.getElementById("endPeriod").value; + + if (!startVal || !endVal) { + showAlert("errorStatistics", "Bitte Start- und Endtermin angeben.", "warning"); + return; + } + if (startVal > endVal) { + showAlert("errorStatistics", "Starttermin darf nicht nach dem Endtermin liegen.", "warning"); + return; + } + + hideAlert("errorStatistics"); + + const content = $("#records_content"); + + // Spinner oberhalb des Ergebnisbereichs anzeigen, records_content NICHT anfassen + $("#statisticsSpinner").remove(); + $("#records_content").before( + '
' + + '
' + + 'Lädt...
' + ); + $("#records_content").hide(); + + $.ajax({ + url: "ajax/getStatistics.php", + method: "GET", + dataType: "json", + data: { + dateStart: (startVal + " 00:00:00").trim(), + dateEnd: (endVal + " 23:59:59").trim() + }, + success: function(data) { + $("#statisticsSpinner").remove(); + if (data.status === 200) { + document.getElementById("statisticsBody").innerHTML = data.rows; + document.getElementById("statisticsFoot").innerHTML = data.foot; + document.getElementById("statisticsZeitraum").textContent = data.zeitraum; + content.show(); + } else { + showAlert("errorStatistics", data.message || "Unbekannter Fehler.", "warning"); + } + }, + error: function(xhr, status, error) { + $("#statisticsSpinner").remove(); + showAlert("errorStatistics", "Serverfehler: " + (error || status), "danger"); + } + }); +} + +// ============================================================ +// HILFSFUNKTIONEN UI +// ============================================================ + +function RecordContentHide() { + const el = document.getElementById("records_content"); + el.style.display = 'none'; + el.textContent = ''; +} + +function DisplayEnterDateSelection() { + document.getElementById("QueryStatistics").style.display = 'block'; +} diff --git a/templates/RelationsModal.tpl b/templates/RelationsModal.tpl index c820b74..75a95f4 100644 --- a/templates/RelationsModal.tpl +++ b/templates/RelationsModal.tpl @@ -32,6 +32,16 @@ + @@ -62,23 +72,6 @@ Keine Relationen vorhanden. - - - - + + !-- Synonyme werden hier per AJAX eingefügt -- + -->