{"id":1597,"date":"2023-03-14T01:31:15","date_gmt":"2023-03-14T00:31:15","guid":{"rendered":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/?p=1597"},"modified":"2023-03-16T18:10:28","modified_gmt":"2023-03-16T17:10:28","slug":"darf-ich-vorstellen-stichwort-plugin-teil-1-csv-datei-erzeugen","status":"publish","type":"post","link":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/2023\/03\/14\/darf-ich-vorstellen-stichwort-plugin-teil-1-csv-datei-erzeugen\/","title":{"rendered":"Darf ich vorstellen: Stichwort Plugin Teil 1, CSV-Datei erzeugen"},"content":{"rendered":"\r\n<p>Da ich die ganze Mechanik schon mal programmiert habe, in Access mit Visual Basic, hab ich mir relativ leicht getan es auch in PHP zu l\u00f6sen. Was gar nicht sch\u00f6n war: bei komplexeren Datenbankoperationen ist mir x-mal der Webserver abgeraucht. Deswegen hab ich dann die Notbremse gezogen und bin auf eine CSV-Datei ausgewichen. Nicht die schlechteste L\u00f6sung, was Stabilit\u00e4t und Performance angeht.<\/p>\r\n\r\n\r\n\r\n<p>Was hab ich gemacht? Ich geh da mal im Schnelldurchlauf durch, haben wir alles schon mal so oder in \u00e4hnlicher Form gehabt. Trotzdem, das eine oder andere ist vielleicht gut zu wissen.<\/p>\r\n\r\n\r\n\r\n<p>Also,, zun\u00e4chst wird ein Plugin mit einem Eintrag f\u00fcr das Admin-Men\u00fc erstellt. Dazu legt man eine Datei an, die folgendermassen aussieht:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>\/*\r\nPlugin Name: Stichworttabelle\r\nDescription: Erzeugt eine neue Stichworttabelle aus den Titeln der Beitr\u00e4ge (post_title)\r\nAuthor: Evi Leu\r\nVersion: 0.1\r\n*\/\r\n    add_action('admin_menu', 'stichworttabelle_plugin_setup_menu');\r\n\t\r\n\tfunction stichworttabelle_plugin_setup_menu(){\r\n    add_menu_page( 'Stichworttabelle', 'Stichworttabelle Plugin', 'manage_options', 'stichworttabelle', 'stichworttabelle_init' );\r\n}\r\n \r\nfunction stichworttabelle_init(){... HIER GEHTS MIT DER MAIN FUNCTION LOS<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Diese Datei kommt in ein eigenes Unterverzeichnis &#8222;Stichworttabelle&#8220; im Plugin-Verzeichnis deiner WP-Installation und hei\u00dft Stichworttabelle.php. Sie kann jetzt in der Liste der installierten Plugins aktiviert werden. Sie tut zun\u00e4chst mal nichts ausser einen Eintrag im Admin-Men\u00fc zu erzeugen, der hei\u00dft &#8222;Stichworttabelle Plugin&#8220; und ist erstmal noch eine leere Seite.<\/p>\r\n\r\n\r\n\r\n<p>Die Men\u00fcseite wird in der Funktion function stichworttabelle_init() mit Leben gef\u00fcllt, erst kommt ein bisschen Infotex, dann wird der Name der Datenbank ermittelt und ausgegeben:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>echo \"&lt;h1&gt;Stichworttabelle neu erstellen&lt;\/h1&gt;\";\r\n\techo \"Das Plugin hat zwei Funktionalit\u00e4ten: &lt;\/br&gt;&lt;\/br&gt;\r\n\t1. Diesen Admin-Men\u00fcpunkt Stichworttabelle Plugin, in dem die Stichworttabelle neu aufgebaut werden kann.&lt;\/br&gt;\r\n\tAus Performancegr\u00fcnde und wegen der Runtime-Stabilit\u00e4t wurde die Stichwortbasis in eine externe CSV-Datei ausgelagert. Diese wird neu erstellt, falls sie nicht schon vorhanden ist. Falls sie schon vorhanden sein sollte, wird sie \u00fcberschrieben. Man kann die Datei beliebig oft neu erzeugen, z.B. wenn es gr\u00f6ssere Mengen neuer Beitr\u00e4ge gibt.&lt;\/br&gt;&lt;\/br&gt;\r\n\t\r\n\t2. einen Shortcode [stichwortverzeichnis]. der an beliebiger Stelle in einem Beitrag oder einer Seite eingesetzt werden kann und dort ein Stichwortverzeichnis erzeugt.&lt;\/br&gt;&lt;\/br&gt;\";\r\n\tglobal $wpdb;\r\n\t\r\n\t\/\/Datenbankname ermitteln\r\n\t$mydatabase=$wpdb-&gt;dbname;\r\n\techo \"Sie arbeiten auf der Datenbank: \".$mydatabase.\"&lt;\/br&gt;\";\r\n\techo \"Stichworte werden aus den Titeln ihrer Beitr\u00e4ge erzeugt&lt;\/br&gt;\";<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Dann kommt ein kleines Formular, das aus genau einem Button besteht:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>\/\/***************Begin Formular\r\n\/\/Formular mit Button\r\n\/\/\"\r\n\/\/ Stichwortliste Datei neu erzeugen startet die array-Erzeugung fuellen und bef\u00fcllt die Datei stichwortliste.csv wieder\r\n\r\necho \"&lt;form action = '#' method = 'post'&gt;\";\r\n\t\r\n\techo \"&lt;input type='submit' id='el_button2' name='ButtonFuellen' value='Stichwortliste Datei neu erzeugen'&gt;\";\r\n\techo \"&lt;\/form&gt;\";\r\n\t\r\n\tif (isset($_POST['ButtonFuellen'])){\r\n\t\t\t\r\n\t\t\treturn tabelle_fuellen();\r\n\t\t}\r\n\/\/*****************End Formular<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Wenn auf den Knopf gedr\u00fcckt wird, wird die Funktion tabelle_fuellen aufgerufen. Jetzt wirds interessant:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>function tabelle_fuellen(){\r\n\t\r\n\t$neuesArray=array_erzeugen();\r\n\terzeuge_csv($neuesArray);\r\n}<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Die Variable $neuesArray wird mit Hilfe der Funktion array_erzeugen() bef\u00fcllt. Diese erstellt eine Stichwortliste aus den Titeln aller Beitr\u00e4ge in der Tabelle wp_posts, dazu gleich mehr.<\/p>\r\n\r\n\r\n\r\n<p>Dann wird die Funktion erzeuge_csv aufgerufen, sie kriegt als Parameter unser Array mit und schreibt die Eintr\u00e4ge zeilenweise in eine Datei.<\/p>\r\n\r\n\r\n\r\n<p>Frischauf, wir sehen uns die Funktion array_erzeugen() mal n\u00e4her an. Der erste Teil mit den n\u00f6tigen MySQL-Abfragen sieht so aus:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>global $wpdb;\r\n\r\n\/\/Beginn Originalcode\r\n$table_name = $wpdb-&gt;prefix.'posts';\r\n\r\n\t\/\/Datens\u00e4tze z\u00e4hlen &amp; Ausgabe Anzahl\r\n\t$count_query = \"select count(*) from $table_name where post_status='publish' and post_type = 'post'\";\r\n\t$num = $wpdb-&gt;get_var($count_query);\r\n\techo $num.\"&amp;nbsp Beitr\u00e4ge gefunden&lt;\/br&gt;\";\r\n\t\r\n\/\/******************\r\n\r\n\/\/Alle Datens\u00e4tze vom Typ post und published ausgeben\r\n$alleposts = $wpdb-&gt;get_results( \"SELECT * FROM \".$table_name.\"\r\n\t\t\t\t\t\t\t\twhere post_status='publish' and post_type = 'post' order by post_title\");\r\n\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n<p><br \/>Das \u00fcbliche Spiel wenn man die ver\u00f6ffentlichten Beitr\u00e4ge ausgeben will, man braucht in der Where-Klausel die Bedingung post_status=&#8217;publish&#8216; and post_type = &#8218;post&#8216;. Und zugegeben, man k\u00f6nnte statt select * auch select post_title verwenden, das f\u00e4llt mir erst jetzt auf.<\/p>\r\n\r\n\r\n\r\n<p>Jetzt stecken alle ver\u00f6ffentlichten Beitr\u00e4ge als Array in der Variablen $alleposts. Durch dieses Array steppe ich jetzt mit foreach durch und nehme mir die einzelnen Eintr\u00e4ge vor, die werden mit Hilfe der Funktion explode() am Leerzeichen gesplittet, mit preg_replace() von Sonderzeichen bereinigt und mit ctype_upper auf Gro\u00df\/Kleinschreibung \u00fcberpr\u00fcft, ich nehme nur die gro\u00df geschriebenen Eintr\u00e4ge. Das ist willk\u00fcrlich festgelegt, produziert aber eine sehr brauchbare Stichwortliste. Schlie\u00dflich wird der gefundene Eintrag mit array_push() in die Variable $stichwortliste weggeschrieben.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>$stichwortliste = array(); \r\n\/\/Durch alle gefundenen Datens\u00e4tze durchsteppen\r\n$zaehler = 0;\r\nforeach ( $alleposts as $einpost ) \r\n{ \r\n  \/\/ersten gefundenen Titel in array aufsplitten\r\n  $liste = explode(\" \", $einpost-&gt;post_title);\r\n  \r\n  \/\/Durch das Array durchsteppen\r\n   foreach ($liste as $einwort)\r\n  {\r\n\t  \/\/Pr\u00fcfen, ob Wort gro\u00df geschrieben ist\r\n\t  $wortanfang = substr($einwort,0,1);\r\n\t  \r\n\t  \/\/Sonderzeichen entfernen (nach Bedarf editieren)\r\n\t  $einwort = preg_replace('\/[0-9\\@\\.\\;\\\" \"\\(\\)\\:\\?\\!\\,]+\/', '', $einwort);\r\n\t  \r\n\t  \/\/nur ausgeben wenn Gro\u00df geschrieben\r\n\t  if (ctype_upper($wortanfang)){\r\n\t\t \r\n\t\t  $zaehler = $zaehler+1;\r\n\t\t  \r\n\t\t  \/\/Hier kommt der Knackpunkt: Neues Stichwort in Array schreiben\r\n\t\t  \/\/***********************************\r\n\t\t  array_push($stichwortliste, $einwort);\r\n\t\t  \/\/***********************************\r\n\t  }\/\/ ende von ctype_upper\r\n  }\/\/ ende von liste as einwort\r\n\r\n  \r\n}\/\/ende von alleposts as einpost und array bef\u00fcllen\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Es folgt noch ein bisschen Kosmetik, und ganz am Ende gibt unsere Funktion das gebrauchsfertige Array zur\u00fcck:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>\/\/Dubletten entfernen\r\n$stichwortliste= array_unique($stichwortliste);\r\n\r\n\/\/Array sortieren\r\nsort($stichwortliste);\r\n\r\n\/\/Ausgabe Anzahlen erzeugter Stichw\u00f6rter\r\necho \"Anzahl Stichw\u00f6rter in den Rohdaten: \".$zaehler.\"&lt;\/br&gt;\";\r\necho \"Gr\u00f6sse des sortierten und Dubletten-bereinigten Arrays: \".count($stichwortliste).\"&lt;\/br&gt;\";\r\necho \"&lt;h2&gt;Erzeuge neue Stichwortliste aus der Tabelle: \".$table_name.\"&lt;\/h2&gt;\";\r\n\r\nreturn $stichwortliste;\r\n}\/\/ ende array erzeugen_function<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Noch alle mit mir beieinander? Fehlt noch was? Ach ja, die Erzeugung der CSV-Datei mit Hilfe der Funktion erzeuge_csv(), damit halte ich mich jetzt nicht lange auf, die ist einigermassen selbsterkl\u00e4rend:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>function erzeuge_csv($liste){\r\n\t\r\n\tglobal $wpdb;\r\n\t\r\n\techo \"Ich erzeuge jetzt ein csv: \";\r\n\t\r\n\t\/\/***************\r\n\t\/\/ Verzeichis des aktuellen Plugins ermitteln\r\n\t$dir = plugin_dir_path( __FILE__ );\r\n\t$aktVerzeichnis = $dir;\r\n\t\/\/Dateiname fest verdrahtet\t\r\n\t$fileName = $aktVerzeichnis.'stichwortliste.csv';\r\n\techo $fileName.\"&lt;\/br&gt;\";\r\n\t\r\nif(file_exists($fileName)){\r\n\techo \"Die alte Datei wird \u00fcberschrieben&lt;\/br&gt;\";\r\n\t}\r\n    \r\n\t\/\/Gnadenlos \u00fcberschreiben, der Parameter 'w' ersetzt den alten Dateiinhalt\r\n\t\r\n    $csvFile = fopen($fileName,'w');\r\n    $head = [\"Wort\"];\r\n    fputcsv($csvFile,$head);\r\n\r\n\/\/ Variable mit den Listeneintr\u00e4gen bef\u00fcllen\r\nforeach ($liste as $einwort){\r\n$data = [\r\n    [\"$einwort\"],\r\n    \r\n];\r\n\r\n\/\/Durch alle data-Eintr\u00e4ge durchsteppen und in Datei schreiben\r\n\r\nforeach($data as $row){\r\n    fputcsv($csvFile,$row);\r\n}\r\n}\r\nfclose($csvFile);\r\n\r\n \/\/Debug-Ausgabe aller Stichworte\r\n$anzahl = sizeof($liste);\r\necho \"&lt;h2&gt;Testausgabe: \".$anzahl.\" Stichw\u00f6rter erzeugt&lt;\/h2&gt;\";\r\n\r\nforeach ($liste as $stichwort){\r\n\t\r\n\techo $stichwort.\"&lt;\/br&gt;\";\r\n\t\r\n}\r\n\t\t\r\n}\/\/ Ende function erzeuge csv\r\n\/\/*****************************************\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Falls die Datei nicht existiert, wird sie neu angelegt. Falls sie schon existiert, wird der Inhalt \u00fcberschrieben. So das wars. Jetzt einen Kaffee und sacken lassen. Und dann Hurra auf zu neuen Ufern, jetzt kommt der Teil mit dem Shortcode. Aber dazu gibts einen neuen Beitrag.<\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>Da ich die ganze Mechanik schon mal programmiert habe, in Access mit Visual Basic, hab ich mir relativ leicht getan es auch in PHP zu l\u00f6sen. Was gar nicht sch\u00f6n war: bei komplexeren Datenbankoperationen ist mir x-mal der Webserver abgeraucht. Deswegen hab ich dann die Notbremse gezogen und bin auf eine CSV-Datei ausgewichen. Nicht die [&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,8,63,14,2],"tags":[],"_links":{"self":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1597"}],"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=1597"}],"version-history":[{"count":11,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1597\/revisions"}],"predecessor-version":[{"id":1660,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1597\/revisions\/1660"}],"wp:attachment":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/media?parent=1597"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/categories?post=1597"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/tags?post=1597"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}