{"id":1431,"date":"2018-09-07T11:30:26","date_gmt":"2018-09-07T09:30:26","guid":{"rendered":"http:\/\/evileu.de\/zum-schwarzen-pinguin\/?p=1431"},"modified":"2018-11-10T10:35:43","modified_gmt":"2018-11-10T09:35:43","slug":"quickdirty-editor-sourcecode","status":"publish","type":"post","link":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/2018\/09\/07\/quickdirty-editor-sourcecode\/","title":{"rendered":"Quick&#038;Dirty Editor Sourcecode"},"content":{"rendered":"<p>Der Editor kommt mit erstaunlich wenig Code aus, das sind gerade mal knapp 90 Zeilen. Ich gehe das hier mal der Reihe nach durch. Meine Ausgangstabelle hei\u00dft rezepte und sieht so aus:<\/p>\n<div id=\"attachment_1435\" style=\"width: 1070px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1435\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1435\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/ausgangstabelle.jpg\" alt=\"ausgangstabelle\" width=\"1060\" height=\"334\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/ausgangstabelle.jpg 1060w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/ausgangstabelle-300x95.jpg 300w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/ausgangstabelle-768x242.jpg 768w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/ausgangstabelle-1024x323.jpg 1024w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/ausgangstabelle-624x197.jpg 624w\" sizes=\"(max-width: 1060px) 100vw, 1060px\" \/><p id=\"caption-attachment-1435\" class=\"wp-caption-text\">ausgangstabelle<\/p><\/div>\n<p>Sie enth\u00e4lt nur die rudiment\u00e4ren Daten meiner Rezepte aus dem Inselfisch-Kochbuch, und zwar die ID, den post_content und den post_title.<\/p>\n<div id=\"attachment_1439\" style=\"width: 595px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1439\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1439\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/tabelle_rezepte.jpg\" alt=\"tabelle_rezepte\" width=\"585\" height=\"316\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/tabelle_rezepte.jpg 585w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/tabelle_rezepte-300x162.jpg 300w\" sizes=\"(max-width: 585px) 100vw, 585px\" \/><p id=\"caption-attachment-1439\" class=\"wp-caption-text\">tabelle_rezepte<\/p><\/div>\n<p>Wir \u00e4ndern nur den post_content, Titel und ID bleiben unangetastet.<\/p>\n<p>Zuerst bastle ich mir nat\u00fcrlich die Datenbankconnection:<\/p>\n<pre>&lt;?php\r\n\/\/file:connection.php\r\nerror_reporting(0);\r\n$servername = \"localhost\";\r\n$username = \"root\";\r\n$password = \"\";\r\n$dbname = \"conversion\";\r\n\r\n\u00a0\r\n\/\/ Create connection\r\n$conn = new mysqli($servername, $username, $password, $dbname);\r\n\/\/ Check connection\r\nif ($conn-&gt;connect_error) {\r\n\u00a0\u00a0\u00a0 die(\"Connection failed: \" . $conn-&gt;connect_error);\r\n} else {echo \"Datenbank Connection OK&lt;br&gt;\";}\r\n?&gt;<\/pre>\n<p>Die wird per require reingeholt, und dann kanns losgehen. Ich habe hier den Algorithmus aus der nummerischen Pagination zweckentfremdet und lasse mir pro Seite genau einen Datensatz anzeigen.<\/p>\n<pre>&lt;?php\r\n\/\/file:seitenweise.php\r\nheader('Content-Type: text\/html; charset=utf-8');\r\nrequire 'connection.php';\r\n\r\n\r\n$sql = \"SELECT * FROM rezepte\";\r\n$rs_result = $conn-&gt;query($sql);\r\n$row_total = $rs_result-&gt;num_rows;\r\n$gesamte_anzahl = $row_total;\r\n\r\necho \"Datens\u00e4tze gesamt: \".$row_total.\"&lt;br&gt;\";\r\n\r\n\/* 1 Datensatz pro Seite festlegen*\/\r\n$ergebnisse_pro_seite = 1;\r\n$gesamt_seiten = ceil($gesamte_anzahl\/$ergebnisse_pro_seite);\r\n\r\nif (empty($_GET['seite_nr'])) {\r\n\u00a0\u00a0\u00a0 $seite = 1;\r\n} else {\r\n\u00a0\u00a0\u00a0 $seite = $_GET['seite_nr'];\r\n\u00a0\u00a0\u00a0 if ($seite &gt; $gesamt_seiten) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $seite = 1;\r\n\u00a0\u00a0\u00a0 }\r\n}\r\n\r\n$limit = ($seite*$ergebnisse_pro_seite)-$ergebnisse_pro_seite;\r\nif($limit&lt;0){$limit =0;}<\/pre>\n<p>Zuerst z\u00e4hle ich die Datens\u00e4tze, dann lege ich fest, dass pro Seite genau ein Datensatz angezeigt werden soll. Defaultm\u00e4ssig landet der Editor bei Seite 1. Dann berechne ich mir das Limit, also beim wievielten Datensatz die Ausgabe beginnen soll. Das verwenden wir gleich mal f\u00fcr die Navigationsbuttons &#8222;Voriger Datensatz&#8220; und &#8222;N\u00e4chster Datensatz&#8220;:<\/p>\n<pre>\/\/Debug-Ausgaben und Nav-Buttons\r\necho \"Datensatz = \".($limit+1).\" von \".$row_total.\"&lt;br&gt;\";\r\necho \"Datens\u00e4tze pro Seite = \".$ergebnisse_pro_seite.\"&lt;br&gt;\";\r\nif($limit&gt;0){echo '&lt;a href=\"<span style=\"color: #008000;\">seitenweise.php?seite_nr='.($limit-1)<\/span>.'\" style=\"font-weight: bold;\"&gt;&lt;button type=\"button\"&gt;Voriger Datensatz&lt;\/button&gt;&lt;\/a&gt;';}\r\necho '&lt;a href=\"<span style=\"color: #008000;\">seitenweise.php?seite_nr='.($limit+2)<\/span>.'\" style=\"font-weight: bold;\"&gt;&lt;button type=\"button\"&gt;N\u00e4chster Datensatz&lt;\/button&gt;&lt;\/a&gt;&lt;br&gt;';<\/pre>\n<p>Dann hole ich mir auch schon den Datensatz mit der aktuellen Seitennummer:<\/p>\n<pre>\/\/Selektiere Datensatz mit der aktuellen Seitennummer\r\n$sql = ('SELECT * FROM rezepte LIMIT '.$limit.', '.$ergebnisse_pro_seite);\r\n$result = $conn-&gt;query($sql);<\/pre>\n<p>Da meine Variable $ergebnisse_pro_seite den Wert 1 hat, wird ein Datensatz pro Seite ausgegeben. Den zeige ich mir in einer while-Schleife in einer zweispaltigen Tabelle an. Die Tabelle enth\u00e4lt eine textarea, in die kommt der HTML-Code. In der zweiten Spalte wird die Vorschau ausgegeben. Zuerst schubse ich mal die ID des aktuellen Datensatzes in eine Variable, die brauchen wir sp\u00e4ter f\u00fcr den Update.<\/p>\n<p>Dann frage ich ab, ob der &#8222;\u00c4nderungen speichern&#8220;-Button gedr\u00fcckt wurde. Wenn ja, zeige ich den ge\u00e4nderten Inhalt des Editorfensters in der Tabelle an, wenn nein einfach den Originalcontent so wie er aus der Abfrage kommt.<\/p>\n<pre>\/\/Ausgabe in Tabelle mit Formular\r\n\u00a0while($row = $result-&gt;fetch_assoc()) {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #008000;\">$akt_id = $row[\"ID\"];<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"Aktuelle Datensatzid: \".$akt_id.\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;form action ='#' method = 'post'&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;input type = 'submit' name = 'absenden' value = '\u00c4nderungen speichern'&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;table border='1' cellpadding='4'&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;th&gt;\".utf8_encode($row['post_title']).\" HTML&lt;\/th&gt;&lt;th&gt;Vorschau&lt;\/th&gt;&lt;\/tr&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/Wenn Speichern gedr\u00fcckt wurde, editierten Content aus der Textarea ausgeben \r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #ff0000;\">if(isset($_POST['absenden'])){$inhalt = $_POST['content'];}<\/span>\r\n<span style=\"color: #ff0000;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0else {$inhalt = utf8_encode($row['post_content']);}<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;tr&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/<span style=\"color: #008000;\">HTML Source in Textarea ausgeben<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;td valign='top'&gt;&lt;<span style=\"color: #008000;\">textarea<\/span> rows='50' cols='80' name='content' id='content'&gt;\".<span style=\"color: #008000;\">$inhalt<\/span>.\"&lt;\/textarea&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;\/td&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/<span style=\"color: #008000;\">HTML Vorschau ausgeben<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 echo \"&lt;td valign='top'&gt;\".<span style=\"color: #008000;\">$inhalt<\/span>.\"&lt;\/td&gt;\";\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 echo \"&lt;\/tr&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;\/table&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;\/form&gt;\";<\/pre>\n<p>Jetzt fehlt nur noch der Update, der wird beim Klicken des &#8222;\u00c4nderungen speichern&#8220;-Buttons ausgel\u00f6st:<\/p>\n<pre><span style=\"color: #008000;\">if (isset($_POST['absenden'])<\/span>){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/***********Action\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$sql = \"<span style=\"color: #ff0000;\">UPDATE rezepte SET post_content =<\/span>\r\n<span style=\"color: #ff0000;\">'\".utf8_decode(addslashes($_POST['content'])).\"' WHERE ID=\".$akt_id.\"<\/span>\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/*************End Action\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 if (mysqli_query($conn, $sql)) {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0 echo \"Record updated successfully\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0 echo \"&lt;script type=\\\"text\/javascript\\\"&gt;alert('\u00c4nderungen erfolgreich gespeichert');&lt;\/script&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0else {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0 echo \"Error updating record: \" . mysqli_error($conn);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0 echo \"&lt;script type=\\\"text\/javascript\\\"&gt;alert('Fehler beim Speichern');&lt;\/script&gt;\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0} \/\/Ende von isset absenden\r\n\u00a0} \/\/Ende von while row = result<\/pre>\n<p>Im Update \u00fcberschreibe ich den Inhalt von post_content mit dem Inhalt des Editorfensters, die steckt ja in der Variablen:<\/p>\n<pre><span style=\"color: #ff0000;\">$_POST['content']<\/span><\/pre>\n<p>und zwar im Datensatz mit der aktuellen ID. Wegen der deutschen Umlaute muss ich hier mit utf8- encode und -decode arbeiten, das mu\u00df man bei einer anderen Datenbankkollation evtl anpassen. Ausserdem brauche ich noch einen addslashes(), weil meine Texte Anf\u00fchrungszeichen enthalten k\u00f6nnen. Dann mache ich noch eine kleine Fehlerbehandlung und gebe einen Javascript-Alert aus, ob der Update funktioniert hat oder nicht. Das wars auch schon &#8211; jetzt fehlt nur noch die nummerische Pagination zum anklicken des i-ten Datensatzes:<\/p>\n<pre>\u00a0\/\/Nav Links alle Seiten\r\n\u00a0for ($i=1; $i&lt;=$row_total; $i++) { \r\n\u00a0\u00a0\u00a0 echo \"&lt;a href='seitenweise.php?seite_nr=\".$i.\"'&gt;\".$i.\"&lt;\/a&gt; \"; \r\n};<\/pre>\n<p>Bittesch\u00f6n, fertig ist der Q&amp;D-Editor!<\/p>\n<div id=\"attachment_1432\" style=\"width: 1038px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1432\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1432\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/vanillekipferl_im_editor.jpg\" alt=\"vanillekipferl_im_editor\" width=\"1028\" height=\"630\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/vanillekipferl_im_editor.jpg 1028w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/vanillekipferl_im_editor-300x184.jpg 300w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/vanillekipferl_im_editor-768x471.jpg 768w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/vanillekipferl_im_editor-1024x628.jpg 1024w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/09\/vanillekipferl_im_editor-624x382.jpg 624w\" sizes=\"(max-width: 1028px) 100vw, 1028px\" \/><p id=\"caption-attachment-1432\" class=\"wp-caption-text\">vanillekipferl_im_editor<\/p><\/div>\n<h2>Tipp, auch quick&amp;dirty:<\/h2>\n<p>Man kann ganz schnell eine (primitive) Filterfunktion basteln, wenn man die beiden SQL-Strings um eine &#8222;LIKE&#8220;-Klausel erg\u00e4nzt:<\/p>\n<pre>$sql = \"SELECT * FROM rezepte WHERE post_content LIKE '%\".$filter.\"%'\";\r\n...\r\n\/\/Selektiere Datensatz mit der aktuellen Seitennummer\r\n$sql = ('SELECT * FROM rezepte WHERE post_content LIKE \"%'.$filter.'%\" LIMIT '.$limit.', '.$ergebnisse_pro_seite.'');<\/pre>\n<p>Die Variable $filter setzt man am Anfang des Skripts auf den gew\u00fcnschten Wert, zum Beispiel auf &#8222;caption&#8220; oder &#8222;&lt;ul&gt;&#8220; oder was auch immer. Dabei muss man aber ber\u00fccksichtigen, was die aktuelle Datenbankkollation als Suchkriterien akzeptiert, bei Umlauten und Sonderzeichen kommt man da sonst zu unerwarteten Ergebnissen. Aber so als kurze Arbeitshilfe ist das schon mal ganz n\u00fctzlich.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Der Editor kommt mit erstaunlich wenig Code aus, das sind gerade mal knapp 90 Zeilen. Ich gehe das hier mal der Reihe nach durch. Meine Ausgangstabelle hei\u00dft rezepte und sieht so aus: Sie enth\u00e4lt nur die rudiment\u00e4ren Daten meiner Rezepte aus dem Inselfisch-Kochbuch, und zwar die ID, den post_content und den post_title. Wir \u00e4ndern nur [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1,20,21,11,7,4,63,59],"tags":[],"_links":{"self":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1431"}],"collection":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/comments?post=1431"}],"version-history":[{"count":10,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1431\/revisions"}],"predecessor-version":[{"id":1459,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1431\/revisions\/1459"}],"wp:attachment":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/media?parent=1431"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/categories?post=1431"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/tags?post=1431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}