HM-Feedleser (Release-Version 1.08 / Plugin für WP)
Die auf dieser Seite veröffentlichten Code-Listings entsprechen weitestgehend den bereits vorgestellten Listings, wurden nur für die Verwendung als WordPress Plugin angepasst.
» Script für einen sicheren Feedreader...
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; } } ?>