Ein neues Plugin: Eine abstrakte Klasse für Elemente mit Zeichenkette

Etwas abstrakt bleibt es doch noch. Es gibt im Projekt zwei Arten von Elementen: Die einen enthalten andere Elemente, andere enthalten Text. Daher wird es zwei unterschiedliche Arten geben, wie zum einen getContent() funktioniert, und wie der Inhalt der Instanz hinzugefügt wird.

Zwei weitere abstrakte Klassen bieten sich da an, die die entsprechenden Methoden implementieren.

ALeo_Sitemap_Xml_StringContent

  1. <?php
  2. /*
  3. Wird von Elementen erweitert, die nur eine
  4. Zeichenkette als Inhalt haben.
  5. Author: Hermann J. Leopold
  6. Email: hermann.leopold@leopoldnet.de
  7. Date: 2017-02-10
  8. /*
  9. require_once('ALeo_Sitemap_Xml.php');
  10. abstract class ALeo_Sitemap_Xml_StringContent extends ALeo_Sitemap_Xml
  11. {
  12. // Darum geht es: Die Zeichenkette
  13. private $_sContent;
  14. /*
  15. Hier wird der Inhalt übergeben.
  16. /*
  17. public function setStringContent($sString)
  18. {
  19. /* Generell dienen die Ausnahmefehler dazu,
  20. Programmfehler zu vermeiden.
  21. /*
  22. // NULL ist nicht erlaubt.
  23. if (is_null($sString)) {
  24. throw new InvalidArgumentException("NULL statt Zeichenkette");
  25. }
  26. // Der Typ muss String sein,
  27. // oder konvertierbar sein.
  28. if (!is_string($sString)) {
  29. throw new InvalidArgumentException("Keine Zeichenkette (aka String)");
  30. }
  31. // Alles OK
  32. $this->_sContent = $sString;
  33. }
  34. /*
  35. Und hier wird der Inhalt wieder zurück
  36. gegeben.
  37. /*
  38. protected function getContent()
  39. {
  40. if (is_null ($this->_sContent)) {
  41. $this->_sContent = '';
  42. }
  43. // Damit nichts passiert, werden Zeichen, die
  44. // XML verwendet, umgewandelt.
  45. return html_entity_decode($this->_sContent, ENT_XML1);
  46. }
  47. }

ALeo_Sitemap_Xml_StringContent.php

Da ich versuche, den Code vernünftig im Blog darzustellen, dürfen die Codezeilen nicht zu breit werden. Auch soll der Code gut lesbar sein; daher sind einige Details etwas umständlich geraten.

Ein neues Plugin: Eine abstrakte Klasse für XML-Elemente

Weil es Spaß und Sinn macht: Eine abstrakte Klasse für XML-Elemente.

Der Vorteil einer abstrakten Klasse: Methoden, die sich nicht ändern, müssen nicht bei jeder abgeleiteten Klasse wiederholt im Code erscheinen. Es könnten auch Traits verwendet werden, jedoch sind sie nicht für den Fall gedacht, dass die Methoden zur gleichen Klassenhierarchie gehören.

ALeo_Sitemap_Xml

  1. <?php
  2. /*
  3. Hier werden bereits alle Methoden implementiert,
  4. die alle Klasssen vom Typ 'ILeo_Sitemap_Xml'
  5. gemeinsam haben.
  6. Author: Hermann J. Leopold
  7. Email: hermann.leopold@leopoldnet.de
  8. Date: 2017-02-08
  9. /*
  10. require_once('ILeo_Sitemap_Xml.php');
  11. abstract class ALeo_Sitemap_Xml implements ILeo_Sitemap_Xml
  12. {
  13. /* Hier muss bei den konkreten Klassen
  14. der Name aka Symbol zurück
  15. gegeben werden. /*
  16. protected abstract function getSymbol();
  17. /* Hier wird der Inhalt des Elements
  18. zurück gegeben. Da dies entweder
  19. Text oder andere Elemente sein
  20. können, muss auch diese Methode von
  21. jedem Element überschrieben werden.
  22. /*
  23. protected abstract function getContent();
  24. /* Mit den Attributen des Elements könnte
  25. man viel Spaß haben; eigene Klassen,
  26. schön mit addAttribute eine Liste
  27. hinzufügen...
  28. Da aber nur ein Element überhaupt
  29. Attribute hat, die dazu noch stets
  30. gleich sind, habe ich diese
  31. einfache Methode bevorzugt. /*
  32. protected function getAttributes()
  33. {
  34. // Gibt es Attribute, muss
  35. // diese Methode überschrieben
  36. // werden
  37. return '';
  38. }
  39. /* Hier die wichtige konkrete
  40. Klasse -> das Element wird erstellt /*
  41. public function toString()
  42. {
  43. // Die vielen Zeilen haben einen Grund:
  44. // Es sieht so besser im Blog aus.. 😄
  45. $sReturn = ILeo_Sitemap_Xml::csTagAuf . $this->getSymbol();
  46. $sReturn .= $this->getAttributes() . ILeo_Sitemap_Xml::csTagZu;
  47. $sReturn .= $this->getContent();
  48. $sReturn .= ILeo_Sitemap_Xml::csTagAuf;
  49. $sReturn .= '/' . $this->getSymbol();
  50. $sReturn .= ILeo_Sitemap_Xml::csTagZu;
  51. return $sReturn;
  52. }
  53. }

ALeo_Sitemap_Xml.php

Dank der getContent()-"Problematik" kann ich noch zwei abstrakte Klassen schreiben. Hurra – und ich sollte mal ein Klassendiagramm erstellen. Es könnte sich lohnen 😃

Ein neues Plugin: Schnittstellen definieren (Ⅱ)

ILeo_Sitemap_Page

Bei den Daten der einzelnen Seiten habe ich wie besprochen auf die Elemente „changefreq“ und „priority“ verzichtet. Dafür können so viele Bilder wie gewünscht hinzugefügt werden.

  1. <?php
  2. /*
  3. Deklariert Methoden und Konstanten für einen
  4. Seiteneintrag der sitemap.xml
  5. Author: Hermann J. Leopold
  6. Email: hermann.leopold@leopoldnet.de
  7. Date: 2017-02-01
  8. /*
  9. interface ILeo_Sitemap_Page
  10. {
  11. // Symbol des Url-Elements:
  12. const csUrlSymbol = "url";
  13. // Symbol für das Location-Elements
  14. const csLocationSymbol = "loc";
  15. // Symbol für das Zuletzt-geändert-Element
  16. const csLastModSymbol = "lastmod";
  17. // Hinzufügen der Bilder
  18. // Was ein Bild ausmacht, wird in der
  19. // ILeo_Sitemap_Image festgelegt.
  20. function addImage(ILeo_Sitemap_Image $oImage);
  21. // URL der Seite angeben.
  22. function setLocation($sUrl);
  23. // Datum der letzten Änderung angeben.
  24. function setLastMod($sLastMod);
  25. }

ILeo_Sitemap_Image

Die wichtigste Neuerung zum alten Plugin sitzt hier. Für jedes Bild können mehrere Texte hinterlegt werden. Die Möglichkeit, einen Link zur Lizenz zu hinterlegen habe ich behalten; wer weiß, ob es noch für was gut sein kann.

  1. <?php
  2. /*
  3. Deklariert Methoden und Konstanten für einen
  4. Bildeintrag in die sitemap.xml
  5. Author: Hermann J. Leopold
  6. Email: hermann.leopold@leopoldnet.de
  7. Date: 2017-02-02
  8. /*
  9. interface ILeo_Sitemap_Image
  10. {
  11. // Symbol des Image-Elements
  12. const csImageSymbol = "image:image";
  13. // Symbol des Location-Elements
  14. const csLocSymbol = "image:loc";
  15. // Symbol des Untertitel-Elements
  16. const csCaptionSymbol = "image:caption";
  17. // Symbol des Aufnahmeort-Elements
  18. const csGeoLoaction = "image:geo_location";
  19. // Symbol des Titel-Elements
  20. const csTitle = "image:title";
  21. // Symbol des Lizens-Elements
  22. const csLicense = "<image:license>";
  23. // Ich wechsle hier von Loc auf Url,
  24. // um Verwechslungen zu vermeiden.
  25. function setUrl($sUrl);
  26. // Angabe des Untertitels
  27. function setCaption($sCaption);
  28. // Angabe des Aufnahmeorts
  29. function setGeoLocation($sGeoLocation);
  30. // Angabe des Bildtitels
  31. function setTitle($sTitle);
  32. // Angabe der Lizens-Elements
  33. function setLicense($sLicense);
  34. }

Jetzt wird es Zeit für Konkretes.

Ein neues Plugin: Schnittstellen definieren (Ⅰ)

Ich mag Schnittstellen. Schnittstellen (engl. Interfaces) sind ein Instrument objektorientierter Programmierung und sollen – salopp gesagt – sicherstellen, dass verschiedene Programmteile verlässlich zusammen arbeiten können.

Dies spielt besonders dann eine Rolle, wenn Erweiterungen oder ähnliches später und/oder von anderen erstellt werden sollen.

Schnittstellen wären auch eine Möglichkeit für WordPress gewesen, jedoch wurde darauf verzichtet; wohl auch, da PHP keine reine objektorientierte Programmiersprache ist. Auch werden die meisten bei der Entwicklung eines Plugins darauf verzichten, ich jedoch nicht.

Mir gefällt, dass ich auf diese Weise Ideen und Anforderungen in Code festschreiben kann, ohne bereits ins Detail gehen zu müssen; und es entstehen Arbeitsanweisungen für die konkreten Klassen.

Folgende Schnittstellen sind mir in den Sinn gekommen:

ILeo_Sitemap_Xml

  1. <?php
  2. /*
  3. Deklariert Methoden und Konstanten für eine XML-Datei
  4. Author: Hermann J. Leopold
  5. Email: hermann.leopold@leopoldnet.de
  6. Date: 2017-01-30
  7. /*
  8. interface ILeo_Sitemap_Xml
  9. {
  10. // Ich mag die Idee, dass ein ständig gleich benötigtes Zeichen einmal festgelegt wird.
  11. const csTagAuf = "<";
  12. // Hier kann festgelegt werden, ob es nach einem XML-Tag einen Zeichenumbruch geben soll.
  13. // const csTagZu = ">";
  14. const csTagZu = ">\n";
  15. // Das Wichtigste: Das XML-Dokument als String
  16. function toString();
  17. }

Datei: ILeo_Sitemap_Xml.php

Natürlich wird so eine XML-Datei nicht annährend vollständig beschrieben, doch für das Plugin reicht es. Da sich Inhalt und Attribute der Elemente unterscheiden, brauche ich dafür keine Methoden vorschreiben. Das Festlegen der spitzen Klammern als Konstanten ist nicht Humor, sondern es bringt Vorteile:

  • Einmal festeglegt, kann man sie nur noch vergessen, aber nicht verwechseln. Da es auch nur eine Methode geben wird, in der die Klammern verwendet werden, sind die Tags stets richtig (oder stets falsch).
  • Bei der schließenden Klammer kann festgelegt werden, ob es Zeilenumbrüche geben soll. Diese machen zwar das XML-Dokument lesbarer, aber auch größer.

ILeo_Sitemap

  1. <?php
  2. /*
  3. Deklariert Methoden und Konstanten für eine sitemap.xml
  4. Author: Hermann J. Leopold
  5. Email: hermann.leopold@leopoldnet.de
  6. Date: 2017-01-30
  7. Verzeiht mein Denglish..
  8. /*
  9. interface ILeo_Sitemap
  10. {
  11. // Symbolname des Wurzelelements
  12. const csRootSymbol = "urlset";
  13. // Der übliche Dateiname, sollte er nicht ersetzt werden.
  14. const csDefaultName = "sitemap.xml";
  15. // Legt den Namen der Datei fest; bsp.: sitemap.xml
  16. function setSitemapName($sName);
  17. // Gibt die Url der Website an; bsp.: leopoldnet.de
  18. // Wichtig, da die Verweise meist relativ sind, aber absolut sein müssen.
  19. function setSiteUrl($sUrl);
  20. // Der Pfad zum Speichern wird auch benötigt.
  21. function setPath($sPath);
  22. // Das Wichtigste: Seiten der sitemap hinzufügen.
  23. // Was eine Seite ausmacht, wird in der ILeo_Sitemap_Page festgelegt.
  24. function addPage(ILeo_Sitemap_Page $oPage);
  25. }

Datei: ILeo_Sitemap.php

Der Name der Datei ist nicht festgelegt; somit wäre es möglich, für verschiedene Suchmaschinen unterschiedliche Sitemaps zu erstellen. Auch der Speicherpfad ist (im Rahmen des Möglichen) wählbar; es muss nicht das Wurzelverzeichnis sein.

Wichtig ist das hinzufügen der Seiten. Die dafür vorgesehene Methode ‚addPage()‘ erwartet einen Parameter vom (noch) unbekannten Typ ILeo_Sitemap_Page. Alles, was eine Seite (aka Page) ausmacht, wird in der nächsten Schnittstelle deklariert.