{"id":554,"date":"2017-07-31T13:38:17","date_gmt":"2017-07-31T11:38:17","guid":{"rendered":"http:\/\/evileu.de\/zum-schwarzen-pinguin\/?p=554"},"modified":"2017-07-31T13:38:17","modified_gmt":"2017-07-31T11:38:17","slug":"jetzt-wirds-mir-doch-zu-dumm-wir-basteln-uns-einen-csv-importer","status":"publish","type":"post","link":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/2017\/07\/31\/jetzt-wirds-mir-doch-zu-dumm-wir-basteln-uns-einen-csv-importer\/","title":{"rendered":"Jetzt wirds mir doch zu dumm: wir basteln uns einen CSV-Importer"},"content":{"rendered":"<h2>Kostenpflichtige Plugins &#8211; seh ich doch gar nicht ein!<\/h2>\n<p>Wie ich schon mehrfach gesagt habe, habe ich erstens nicht das Budget, mir zu Testzwecken kostenpflichtige Plugins zu kaufen, und zweitens bin ich eine gro\u00dfe Anh\u00e4ngerin der Open-Source-Idee. Das ist ja mit der Hauptgrund, warum WordPress so erfolgreich ist, es ist Open Source und kostenlos, es gibt fantastische Supportforen, es gibt f\u00fcr nahezu jedes Programmierproblem eine L\u00f6sung, ohne da\u00df man Bares daf\u00fcr hinlegen mu\u00df.<\/p>\n<p>Da alle CSV-Import-Plugins die ich getestet habe in den kostenfreien Versionen keinen Import von Custom Fields k\u00f6nnen und ich diese M\u00f6glichkeit aber unbedingt brauche, gehen wir jetzt einen anderen Weg:<\/p>\n<h2>Wir schreiben unseren eigenen CSV-Importer<\/h2>\n<p>Ich bleibe dabei beim Beispiel des Turnverein Wei\u00df-Blau mit dem Mitgliederverzeichnis. Die Vorgaben bleiben gleich:<\/p>\n<ul>\n<li>die Adressdaten liegen als CSV-Datei vor (Spezifikation folgt)<\/li>\n<li>f\u00fcr jeden Mitgliederdatensatz soll ein eigener Beitrag angelegt werden<\/li>\n<li>im Beitragstitel brauchen wir die Mitgliedsnummer (ID) und den Namen<\/li>\n<li>die restlichen Adressdaten sollen in Benutzerdefinierte Felder geschrieben werden.<\/li>\n<\/ul>\n<p>Alles klar soweit? Na, dann wollen wir mal!<\/p>\n<h2>Die Spezifikation der CSV-Datei<\/h2>\n<p>Ich nehme da mal was ganz Rudiment\u00e4res, das kann sich jeder selber mit Excel und im Notepad++ zurechtschnitzen. Pro Datensatz eine Zeile, Zeilenende mit CR\/LF markiert, Trennzeichen ein Semikolon (;), kein Textbegrenzungszeichen. Kodierung UTF-8 ohne BOM. Wir haben zehn Datens\u00e4tze:<\/p>\n<div id=\"attachment_556\" style=\"width: 1156px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-556\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-556\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2017\/07\/import_notepad.jpg\" alt=\"import_notepad\" width=\"1146\" height=\"282\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2017\/07\/import_notepad.jpg 1146w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2017\/07\/import_notepad-300x74.jpg 300w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2017\/07\/import_notepad-768x189.jpg 768w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2017\/07\/import_notepad-1024x252.jpg 1024w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2017\/07\/import_notepad-624x154.jpg 624w\" sizes=\"(max-width: 1146px) 100vw, 1146px\" \/><p id=\"caption-attachment-556\" class=\"wp-caption-text\">import_notepad<\/p><\/div>\n<h2>Der Anfang: wir basteln uns ein neues Plugin<\/h2>\n<p>Das haben wir schon ein paar mal gemacht, das wiederhole ich nur im Schnelldurchgang. Plugin-Verzeichnis anlegen, PHP-Datei anlegen, Header richtig ausf\u00fcllen, AdminScreen anlegen:<\/p>\n<pre>\/*\r\nPlugin Name: Evis CSV Importer\r\nPlugin URI: http:\/\/localhost\/wordpress\/wp-content\/plugins\/evis-csv_importer\r\nDescription: Importiert eine CSV-Datei\r\nVersion: 1.0\r\nAuthor: Evi Leu\r\nAuthor URI: http:\/\/www.evileu.de\r\n*\/\r\nadd_action('admin_menu', 'evisbasicPluginMenu');\r\n\r\nfunction evisbasicPluginMenu() {\r\n$appName = 'EvisCSVImporter';\r\n$appID = 'evis-csv-importer';\r\nadd_menu_page($appName, $appName, 'administrator', $appID, 'importerpluginAdminScreen');\r\n}\r\n\r\nfunction importerpluginAdminScreen() {\r\n\u00a0\u00a0 \u00a0echo \"&lt;h1&gt;Importiere CSV Datei&lt;\/h1&gt;\";\r\n}\r\n<\/pre>\n<h2>Import starten mit Button<\/h2>\n<p>Zum starten des Imports brauchen wir noch einen Button, den legen wir wie schon oft gehabt mit einem kleinen Formular an, das kommt als erstes in die Funktion <em>importerpluginAdminScreen:<\/em><\/p>\n<pre>\/\/Begin Formular\r\necho '&lt;form method=\"post\"&gt;';\r\necho '&lt;input type=\"submit\" name = \"starten\" value=\"Import starten\"\/&gt;'.\"&lt;br&gt;\";\r\necho \"&lt;\/form&gt;\";\r\n\/\/ End Formular\r\n\r\nif (isset($_POST['starten'])){\r\n\r\n...\r\n\r\n}<\/pre>\n<h2>Pfad und Dateiname der Import-Datei fest verdrahtet<\/h2>\n<p>In die if-isset-Abfrage legen wir jetzt unsere Import-Funktionalit\u00e4t. Nat\u00fcrlich w\u00e4re es schick wenn man hier die Import-Datei mit einem Datei-\u00f6ffnen-Dialog ausw\u00e4hlen k\u00f6nnte, aber dazu brauchts eine Runde Javascript, und das sprengt hier definitiv den Rahmen. Ich machs mir einfach: da ich immer mit der selben Import-Datei arbeite, verdrahte ich den Pfad und den Dateinamen im Code, das kann sich dann jeder selber zurechtbiegen wie er es braucht. Jedenfalls wird die CSV-Datei mit fopen() ge\u00f6ffnet:<\/p>\n<pre>\/\/Pfad zur Import-Datei fest verdrahtet\r\n$datei=fopen(\"C:\/xampp\/htdocs\/alte_programmierer\/wp-content\/plugins\/evis-csv-importer\/nur_adressen.csv\",\"r+\");<\/pre>\n<h2>Datei zeilenweise einlesen und Debug-Ausgabe<\/h2>\n<p>Dann lege ich eine While-Schleife bis zum Dateiende (feof) an und lese mit fgets() zeilenweise ein. Jede Zeile wird mit explode() am Semikolon in ein Array eingespeist, und damit man gleich mal was sieht, gebe ich dieses Array dann noch zeilenweise aus, das ist nur zum Debuggen und fliegt sp\u00e4ter wieder raus. Ja, ich h\u00f6rs schon, das m\u00fc\u00dfte man mit einer for&#8230;next i Schleife machen, aber ich finde es so \u00fcbersichtlicher.<\/p>\n<pre>\/\/Begin Importdatei zeilenweise einlesen\r\nwhile(!feof($datei))\r\n{\r\n\u00a0\u00a0 \u00a0$zeile = fgets($datei);\r\n\u00a0\u00a0 \u00a0echo $zeile.\"&lt;br&gt;\";\r\n\r\n\u00a0\u00a0 \u00a0\/\/aktuelle Zeile am Semikolon in Array explodieren\r\n\u00a0\u00a0 \u00a0$arr_akt_zeile = explode(';',$zeile);\r\n\r\n\u00a0\u00a0 \u00a0\/\/Debug-Ausgabe des Arrays\r\n\u00a0\u00a0 \u00a0echo $arr_akt_zeile[0].\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0echo $arr_akt_zeile[1].\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0echo $arr_akt_zeile[2].\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0echo $arr_akt_zeile[3].\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0echo $arr_akt_zeile[4].\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0echo $arr_akt_zeile[5].\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0echo $arr_akt_zeile[6].\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0echo $arr_akt_zeile[7].\"&lt;br&gt;\";\r\n\u00a0\u00a0 \u00a0echo $arr_akt_zeile[8].\"&lt;br&gt;\";\r\n} \/\/Ende Importdatei zeilenweise einlesen\r\n\r\nfclose($datei);\u00a0 \r\n<\/pre>\n<p>Am Ende nicht vergessen mit fclose() die Importdatei wieder zu schlie\u00dfen.<\/p>\n<p>(Zwischenbemerkung: ja, ich kenne die Funktion <span class=\"function\"><strong>fgetcsv()<\/strong><\/span>, die ist aber ein bi\u00dfchen hakelig in der Bedienung. wir nehmen lieber fgets().)<\/p>\n<p>So, das wars schon mit dem zeilenweisen Import der CSV-Datei. Jetzt m\u00fcssen wir die eingelesenen Daten noch entsprechend verarbeiten, aber dazu gibt es einen neuen Beitrag.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Kostenpflichtige Plugins &#8211; seh ich doch gar nicht ein! Wie ich schon mehrfach gesagt habe, habe ich erstens nicht das Budget, mir zu Testzwecken kostenpflichtige Plugins zu kaufen, und zweitens bin ich eine gro\u00dfe Anh\u00e4ngerin der Open-Source-Idee. Das ist ja mit der Hauptgrund, warum WordPress so erfolgreich ist, es ist Open Source und kostenlos, es [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[18,25,4,8,2],"tags":[],"_links":{"self":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/554"}],"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=554"}],"version-history":[{"count":4,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/554\/revisions"}],"predecessor-version":[{"id":560,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/554\/revisions\/560"}],"wp:attachment":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/media?parent=554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/categories?post=554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/tags?post=554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}