Home
Navigation
Impressum
Coder Welten - Programmierung und Optimierung
Feedreader: HM-Feedleser für WP

Code der zum Plugin HM-Feedleser gehörenden Klasse 'HM_FeedKlasse'

HM-Feedleser (Release-Version 1.08 / Plugin für WP)

Vorstellung und Beschreibung des Plugins:

  1. Feedreader mit SimpleXML (Einführung und Vorstellung eines Scripts für einen sicheren Feedreader...)
  2. Feedreader File (Einzelheiten zum Code - Variante mit file_get_contents)
  3. Feedreader mit cURL (Code mit der cURL-Variante und ergänzende Hinweise)
  4. Zugehörige Dateien (Formular, Formular-Klasse und eine CSS-Dateie)
  5. Variante mit Feed-Klasse (zur leichteren Einbindung in HTML-Seiten, Version 1.06)
  6. Feed-Klasse und Methoden (nur für HM-Feedleser ab Version 1.06)
  7. Plugin für WordPress (Feedreader als Plugin für WordPress, Version 1.08)

Hinweis

Die auf dieser Seite veröffentlichten Code-Listings entsprechen wei­test­gehend den bereits vorgestellten Listings, wurden nur für die Verwendung als WordPress Plugin angepasst.

 

» Script für einen sicheren Feedreader...

» Lizenz für Software

Code der zum Plugin HM-Feedleser (Version 1.08 / WP)
gehörenden Dateien:

Demo unter: HM-Feedleser(bei www.woder-welten.com)

Download » Plugin für WordPress


Inhalt und Code der Datei feedklasse.php

<?php
/**
 * Die HM_FeedKlasse fuer den HM-Feedleser
 *
 * @package HM-Feedleser
 * @since HM-Feedleser 1.08
 */

class HM_FeedKlasse {

    /*--------------------------------------------------------------------------------------------------------------
     Die Werte fuer die mit public definierten Eigenschaften koennen in der xml-feedleser.php editiert werden. In der
     HM_FeedKlasse sollte hingegen ohne einschlaegige Kenntnisse nichts editiert werden.
     ---------------------------------------------------------------------------------------------------------------
    */
    public  $seite;                         // Fuer die aufzurufende Feed-URI
    public  $maxim;                         // Maximale Anzahl der Ergebnisse pro Seite
    public  $maxlg;                         // Die maximale Anzahl an Zeichen pro Feed
    public  $descr;                         // Description anzeigen oder nicht
    public  $conte;                         // Content anzeigen oder nicht
    public  $summa;                         // Summary anzeigen oder nicht
    public  $linkt;                         // hm_linktext fuer den unteren Link
    public  $feedt;                         // Fuer den einleitenden Titel des Feeds, kann auch leer bleiben

    private $option;                        // Einen User Agent setzen
    private $status;                        // HTTP-Statuscode ueberpruefen
    private $antwort;                       // Die Response als Array
    private $resdata;                       // Die Response als String
    private $link  = false;                 // Werte fuer $link, $lesen und $enco sowie Startwert von $si
    private $lesen = false;
    private $laden = "";
    private $enco  = "";
    private $si =  0;

    private function wandleTags($daten) {

        $wandle  = array(

            "content:encoded" => "content",
            "dc:creator"      => "creator",
            "dc:date"         => "published"
        );
        $daten = strtr($daten, $wandle);
        $daten = preg_replace_callback("/(&[#a-z0-9]+;)/",

            function($enti) {

                return esc_html(mb_convert_encoding($enti[1], "UTF-8", "HTML-ENTITIES"));
            }, $daten);

        /*-- Fuer den Fall, dass der Feed nur als String ohne Zeilenumbrueche ausgeliefert wird. -------------------*/

        if (strpos($daten, "><item>") !== false) {

            $eing  = array(

                "><item>"        => ">\r\n<item>",
                "><title>"       => ">\r\n<title>",
                "><link>"        => ">\r\n<link>",
                "><description>" => ">\r\n<description>",
                "><content>"     => ">\r\n<content>",
                "><summary>"     => ">\r\n<summary>",
                "><enclosure>"   => ">\r\n<enclosure>",
                "><pubDate>"     => ">\r\n<pubDate>",
                "><updated>"     => ">\r\n<updated>",
                "><published>"   => ">\r\n<published",
                "><author>"      => ">\r\n<author>",
                "><creator>"     => ">\r\n<creator>"
            );
            $daten = strtr($daten, $eing);
        }
        return $daten;
    }

    /*--------------------------------------------------------------------------------------------------------------
     Die Funktion filtert HTML-Tags innerhalb und ausserhalb von CDATA-Abschnitten und wandelt erlaubte Tags in
     BBCode. Weiterhin findet eine erste ueberpruefung von Images statt, falls $image nicht gleich false.
     ---------------------------------------------------------------------------------------------------------------
    */
    private function filtereHTML($daten, $image) {

        $daten = preg_replace("/<p.*?>(.+?)<\/p>/is", "$1[br]", $daten);
        $daten = preg_replace("/<div.*?>(.+?)<\/div>/is", "$1[br]", $daten);
        $daten = preg_replace("/<span.*?>(.*?)<\/span>/is", "$1", $daten);
        $daten = preg_replace("/<br.*?>/i", "[br]", $daten);
        $daten = preg_replace("/<a href.+?>(.*?)<\/a>/is", "$1", $daten);

        if ($image === true) {
            $daten = preg_replace("/<img.*?src=\"([a-z0-9_\/=.:;&?-]+?)\.(jpg|png).*?>/is", "[img]$1.$2[/img]", $daten);
        }
        $eing  = array(

            "<b>"        => "[b]",
            "</b>"       => "[/b]",
            "<i>"        => "[i]",
            "</i>"       => "[/i]",
            "<em>"       => "[i]",
            "</em>"      => "[/i]",
            "<ul>"       => "[ul]",
            "</ul>"      => "[/ul]",
            "<li>"       => "[li]",
            "</li>"      => "[/li]",
            "<strong>"   => "[b]",
            "</strong>"  => "[/b]",
            "{"          => "",
            "}"          => ""
        );
        $daten = strtr($daten, $eing);
        $daten = preg_replace("/<.+?>/is", "", $daten);
        return $daten;
    }

    /*--------------------------------------------------------------------------------------------------------------
     Die Funktion wandelt erlaubte BBcode-Tags in HTML-Tags zurueck und ueberprueft Images. Falls Bilder die angegeben
     Hoechstmasse ueberschreiten, werden diese gleichmaessig skaliert.
     ---------------------------------------------------------------------------------------------------------------
    */
    private function formeHTML($daten) {

        $eing  = array(

            "[br]"       => "<br />",
            "[b]"        => "<b>",
            "[/b]"       => "</b>",
            "[i]"        => "<em>",
            "[/i]"       => "</em>",
            "[ul]"       => "<ul>",
            "[/ul]"      => "</ul>",
            "[li]"       => "<li>",
            "[/li]"      => "</li>"
        );
        $daten = strtr($daten, $eing);

        $daten = preg_replace("/[\n]/", "\n\t", $daten);
        $daten = preg_replace_callback("/\[img\](.+?)\[\/img\]/",

        function ($bilder) {

            @$format = getimagesize($bilder[1]);

            if($format != false) {

                if ($format["mime"] == "image/jpeg" or $format["mime"] == "image/png") {

                    $height = $format[1];
                    $width  = $format[0];

                    if ($height > MAXHOEHE){

                        $height  = MAXHOEHE;
                        $prozent = ($format[1] / $height);
                        $width   = ($format[0] / $prozent);
                    }
                    if ($width > MAXWEITE){

                        $width   = MAXWEITE;
                        $prozent = ($format[0] / $width);
                        $height  = ($format[1] / $prozent);
                    }
                    return "<img src=\"".esc_html($bilder[1])."\" alt=\"Bild\"".
                           " height=\"".round($height)."\" width=\"".round($width)."\" class=\"feedbild\" />";
                }
            }
        }, $daten);
        return $daten;
    }

    /*-- Die Funktion wandelt Datum und Uhrzeit in ein lesbares Format um. ---------------------------------------*/

    private function formeDatumZeit($daten) {

        $daten = preg_replace("/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})/", "$3.$2.$1 um $4:$5 Uhr", $daten);
        $daten = substr($daten, 0, 23);
        return $daten;
    }

    /*-- Die Funktion prueft enthaltene Links auf unerlaubte Zeichen und entfernt diese erforderlichenfalls. ------*/

    private function filtereLinks($daten) {

        if (($pos = strpos($daten, "#")) !== false) {
            $daten = substr($daten, 0, $pos);
        }
        $daten = preg_replace("/[^a-z0-9_\/=.:;&?-]/is", "", $daten);
        return $daten;
    }

    private function kuerzeFeed($daten) {

        $neuel = $this->maxlg +40;

        /*-- Zähle ob der Text mindestens $this->maxlg Zeichen hat, falls nicht gebe mit Else aus. ----------------*/

        if (strlen($daten) > $this->maxlg){

            /*-- Suche ab Position $this->maxlg nach einem Leerzeichen --------------------------------------------*/

            $laenge = strpos($daten, " ", $this->maxlg);// strip_tags($daten)

            /*-------------------------------------------------------------------------------------------------------
             Nehme diese Position bis zum gefundenen Leerzeichen als neue Länge, falls strpos nicht false meldete.
             --------------------------------------------------------------------------------------------------------
            */
            if ($laenge !== false){
                $gekuerzt = substr($daten, 0, $laenge)." [...]";
            }

            /*-- Falls false, suche noch einmal mit $this->maxlg plus 40 Zeichen gleich $neuel und trenne dann. -----*/

            elseif (strlen($daten) > $neuel){
                $neuelaenge = strpos($daten, " ", $neuel);

                if ($neuelaenge !== false){
                    $gekuerzt = substr($daten, 0, $neuelaenge)." [...]";
                }

                /*-- Falls kein Fund mit $laenge oder $neuelaenge, dann mache einen harten Schnitt. ----------------*/

                else {
                    $gekuerzt = substr($daten, 0, $neuel)." [...]";
                }
            }
            /*-- Falls etwas unerwartet schief lief, dann kuerze halt an dieser Stelle mit einem harten Schnitt. ---*/

            else {
                $gekuerzt = substr($daten, 0, $neuel)." [...]";
            }

            /*-- Falls einzelne Feeds gekürzt wurden, muss eine Validierung erfolgen. ------------------------------*/

            if (preg_match_all("/\[b\]/", $gekuerzt, $a1)) {
                $a1 = count($a1[0]);

                if (preg_match_all("/\[\/b\]/", $gekuerzt, $b1)) {
                    $b1 = count($b1[0]);

                    if ($a1 > $b1) $gekuerzt = $gekuerzt."[/b]";
                }
                if (!preg_match("/\[\/b\]/", $gekuerzt)) {
                    $gekuerzt = $gekuerzt."[/b]";
                }
            }
            if (preg_match_all("/\[i\]/", $gekuerzt, $a2)) {
                $a2 = count($a2[0]);

                if (preg_match_all("/\[\/i\]/", $gekuerzt, $b2)) {
                    $b2 = count($b2[0]);

                    if ($a2 > $b2) $gekuerzt = $gekuerzt."[/i]";
                }
                if (!preg_match("/\[\/i\]/", $gekuerzt)) {
                    $gekuerzt = $gekuerzt."[/i]";
                }
            }
            if (preg_match_all("/\[li\]/", $gekuerzt, $a3)) {
                $a3 = count($a3[0]);

                if (preg_match_all("/\[\/li\]/", $gekuerzt, $b3)) {
                    $b3 = count($b3[0]);

                    if ($a3 > $b3) $gekuerzt = $gekuerzt."[/li]";
                }
                if (!preg_match("/\[\/li\]/", $gekuerzt)) {
                    $gekuerzt = $gekuerzt."[/li]";
                }
            }
            if (preg_match_all("/\[ul\]/", $gekuerzt, $a4)) {
                $a4 = count($a4[0]);

                if (preg_match_all("/\[\/ul\]/", $gekuerzt, $b4)) {
                    $b4 = count($b4[0]);

                    if ($a4 > $b4) $gekuerzt = $gekuerzt."[/ul]";
                }
                if (!preg_match("/\[\/ul\]/", $gekuerzt)) {
                    $gekuerzt = $gekuerzt."[/ul]";
                }
            }
        }
        else {
            $gekuerzt = $daten;
        }
        return $gekuerzt;
    }

    public function hm_liefere_Feed_Content() {

        $image = false;                     // $image als Anfangswert false zuweisen
        $this->laden .= "<div class=\"feedle\">\n";

        /*-- Der Feed wird geladen und im Anschluss erfolgt die Ausgabe des Feeds ---------------------------------*/

        $this->option  = array("user-agent" => "Mozilla/5.0 (compatible; HM-Feedleser +".get_bloginfo("url").")");
        $this->antwort = wp_remote_get($this->seite, $this->option);
        $this->status  = (int) $this->antwort["response"]["code"];
        $this->resdata = (string) $this->antwort["body"];

        if ($this->status == 200 or $this->status == 304) {

            $pxml = simplexml_load_string($this->wandleTags($this->resdata), "SimpleXMLElement", LIBXML_NOCDATA);

            /*------------------------------------------------------------------------------------------------------
             Auswahl, ob Feedtitel und Eintritt fuer RSS oder fuer Atom, wobei channel->title und channel->item der
             RSS 2.0 Specification fuer Feeds entspricht, title und entry hingegen der Specification fuer Atom-Feeds.
             -------------------------------------------------------------------------------------------------------
            */
            if ($pxml->channel->title) $this->laden .= "<h2 class=\"ftitele\">".$this->feedt.$this->formeHTML( esc_html($this->filtereHTML($pxml->channel->title, $image)) )."</h2>\n";
            if ($pxml->title)          $this->laden .= "<h2 class=\"ftitele\">".$this->feedt.$this->formeHTML( esc_html($this->filtereHTML($pxml->title, $image)) )."</h2>\n";

            if ($pxml->channel->item) $this->lesen = $pxml->channel->item;  // RSS 2.0
            if ($pxml->entry)         $this->lesen = $pxml->entry;          // Atom
            if ($pxml->item)          $this->lesen = $pxml->item;           // RSS 1.0

            /*------------------------------------------------------------------------------------------------------
             Kontrolle, ob zumindest das erste oder das zweite Item einen Titel enthaelt. Falls dies wie erwartet der
             Fall sein sollte, werden noch einmal alle Titel einzeln auf Vorhandensein ueberprueft.
             -------------------------------------------------------------------------------------------------------
            */
            if (strlen($this->lesen[0]->title) > 0 or strlen($this->lesen[1]->title) > 0) {

                foreach ($this->lesen as $nachricht) {

                    if ($nachricht->title != false) {

                        /*-- Auswahl, ob Link fuer RSS $nachricht->link oder Atom $nachricht->link->attributes() --*/

                        if ($nachricht->link) {

                            if ((string)$nachricht->link) {
                                $this->link = $nachricht->link;
                            }
                            elseif ($nachricht->link->attributes()) {
                                $attr = $nachricht->link->attributes();
                                $this->link = $attr["href"];
                            }
                        }

                        /*-- Titel mit Link ----------------------------------------------------------------------*/

                        if ($nachricht->title) {
                            $this->laden .= "\x20\x20<h3><a href=\"".esc_html($this->filtereLinks($this->link))."\" class=\"feedll\" target=\"_blank\">".
                            $this->formeHTML(esc_html($this->filtereHTML($nachricht->title, $image)))."</a></h3>\n";
                        }

                        /*------------------------------------------------------------------------------------------
                         Einen Hinweis anzeigen, falls Bilder als Beilage mit enclosure der Nachricht hinzugefuegt
                         wurden.
                         -------------------------------------------------------------------------------------------
                       */
                        if ($nachricht->enclosure) {

                            if ($nachricht->enclosure->attributes()) {
                                $url = $nachricht->enclosure->attributes();

                                if (strpos($url["url"], ".jpg") or strpos($url["url"], ".png")) {

                                    $this->enco = "<br />\n\x20\x20<span class=\"flklein\">Beilage Medien: ".
                                             esc_html($this->filtereLinks($url["url"]))."</span>";
                                }
                            }
                        }

                        $image = true;       /* true nur fuer description erst einmal und falls kein Fund, dann auch
                                                fuer content und summary */

                        /*-- description und content fuer RSS und summary fuer Atom --------------------------------*/

                        if ($nachricht->description and $this->descr != false) {
                            $this->laden .= "\x20\x20<p>".$this->formeHTML($this->kuerzeFeed(esc_html($this->filtereHTML($nachricht->description, $image))))."</p>\n";

                            if ((strpos((string)$nachricht->description, "<img")) !== false) {
                                $image = false;
                            }
                        }
                        if ($nachricht->content and $this->conte != false) {
                            $this->laden .= "\x20\x20<p>".$this->formeHTML($this->kuerzeFeed(esc_html($this->filtereHTML($nachricht->content, $image))))."</p>\n";
                        }
                        if ($nachricht->summary and $this->summa != false) {
                            $this->laden .= "\x20\x20<p>".$this->formeHTML($this->kuerzeFeed(esc_html($this->filtereHTML($nachricht->summary, $image))))."</p>\n";
                        }

                        $image = false;  /*- Nur fuer den Fall, dass false nicht durch description ausgeloest wurde */

                        /*-- Link unten --------------------------------------------------------------------------*/

                        if ($this->link != false) {
                            $this->laden .= "\x20\x20<p class=\"flunten\"><a href=\"".esc_html($this->filtereLinks($this->link))."\" class=\"feedll\" target=\"_blank\">".
                                 $this->linkt."</a><br />\n";
                        }

                        /*-- pubDate fuer RSS und published und updated fuer Atom ----------------------------------*/

                        if ($nachricht->pubDate) {
                            $this->laden .= "\x20\x20<br />".esc_html(substr($nachricht->pubDate,  0, 16)).
                                 " um ".esc_html(substr($nachricht->pubDate, 17,  5))." Uhr";

                        } elseif ($nachricht->updated) {
                            $this->laden .= "\x20\x20<br />".$this->formeDatumZeit($nachricht->updated)."\n";

                        } elseif ($nachricht->published) {
                            $this->laden .= "\x20\x20<br />".$this->formeDatumZeit($nachricht->published)."\n";
                        }

                        /*-- Autor oder Creator fuer RSS und Atom -------------------------------------------------*/

                        if ($nachricht->author) {
                            $this->laden .= " von ".esc_html($this->filtereHTML($nachricht->author, $image)).$this->enco."</p>\n";

                        } elseif ($nachricht->creator) {
                            $this->laden .= " von ".esc_html($this->filtereHTML($nachricht->creator, $image)).$this->enco."</p>\n";

                        } else {
                            $this->laden .= "\x20\x20".$this->enco."</p>\n";
                        }

                        /*-- Trennlinie zwischen den einzelnen Mitteilungen --------------------------------------*/

                        $this->laden .= "\x20\x20<hr class=\"fllinie\" />\n";
                        $this->si++;
                        if ($this->si == $this->maxim) {break;
                        }
                    }
                } $this->laden .= "\x20\x20<p class=\"flcopy\"><a href=\"http://www.coder-welten.de\" target=\"_blank\">Script von www.coder-welten.de</a></p>\n</div>\n";
            } else { $this->laden .= "<br />Mehrere Titel oder Items scheinen fehlerhaft zu sein!\n";
            }
        } else { $this->laden .= $this->seite."<br />Feed konnte nicht geladen werden!\n";
        }
        return $this->laden;
    }
}

?>

Copyright © Verlag Horst Müller - Stendal - 2006 - Impressum - Datenschutz - Nutzungsbedingungen