Complex Pageelement
HowTo: Complex Pagelement
Im Rahmen dieses Tutorials wird die Erstellung von „komplexen“ Seitenelementen betrachtet. Komplex bedeutet in diesem Fall nicht kompliziert, sondern, im Vergleich zu einfachen Seitenelementen, dass Daten in der Datenbank gespeichert werden können.
Da einfache und komplexe Seitenelemente vom Aufbau her identisch sind, wird das Tutorial für ein einfaches Seitenelement als Voraussetzung zu diesem Tutorial angesehen. Eine aktuelle Version des vorausgesetzten Tutorials „HowTo: Simple Pagelement“ gibt es auf www.kajona.de online sowie zum Download.
Um mit diesem Tutorial ein paar mehr Funktionen als nur die elementarsten eines komplexen Seitenelements zu zeigen, soll ein RSS-Element erstellt werden. Mit diesem soll es möglich sein, RSS- und ATOM-Feeds anderer Seiten in die eigene Kajona-Seite zu integrieren. Es wird also nicht nur notwendig werden, Benutzereingaben wie die URL des Feeds in der Datenbank zu persistieren, sondern auch unter der Verwendung des Kajona XML API Dokumente zu verarbeiten sowie mit Hilfe der Template-Engine templatebasierte Layouts aufzubauen.
Eine aktuelle Version dieses RSS-Seitenelements gibt es auch auf www.kajona.de zum Download.
Dieses Tutorial basiert auf Kajona V3.4.
Dateistruktur erstellen
Das Erstellen der Dateistruktur erfolgt analog zum bereits aus einem früheren Tutorial bekannten „lastmodified“-Element. Für das RSSFeed-Element wird nachstehende Ordner- / Dateistruktur verwendet:
element_rssfeed
|- admin
| |- elemente
| |- class_element_rssfeed.php
|
|- installer
| |- installer_element_rssfeed.php
|
|- portal
| |-elemente
| |- class_element_rssfeed.php
|
|- templates
| |- element_rssfeed
| |- rssfeed.tpl
|- lang
|- admin
|- modul_elemente
|- lang_rssfeed_[de|en|...].php
|- portal
|- modul_elemente
- lang_rssfeed_[de|en|...].php
Im Vergleich zum lastmodified-Element kommen hier noch Textdateien für die Administrationsoberfläche sowie die Templatedateien hinzu.
Auf die Bedeutung der einzelnen Klassen wurde bereits im vorhergegangenen Tutorial eingegangen, weswegen an dieser Stelle darauf verzichtet werden soll.
Benötigte Klassen erstellen
Nachdem nun alle benötigten Dateien angelegt wurden, geht es nun an das Erstellen der benötigten Klassen, also des Programmcodes.Beginnen möchten wir hier mit dem
Installer
Im Gegensatz zum Installer des lastmodified-Elements soll das RSSFeed-Element später Daten in eine Datenbank schreiben können. Da sich die Anzahl der Felder beschränkt, kann die während der Installation von Kajona bereits angelegte Tabelle „element_universal“ verwendet werden. Sollte ein eigenes Element erstellt werden, welches eine eigene Tabellenstruktur zum Ablegen der Daten benötigt, so wäre der Installer die Stelle der Wahl (vgl. auch das Tutorial zum Erstellen eines eigenen Moduls). .
Der Dateiname des Installers des Seitenelements sollte nach dem Namensschema installer_element_name.php aufgebaut sein, in unserem Fall also installer_element_rssfeed.php. Wenn auch der Installer wie der des lastmodified-Elements augebaut ist, soll er, auf Grund der neuen Schnittstellen mit V 3.1.x schrittweise erläutert werden. Der fertige Installer ist wie folgt strukturiert (der Inhalt der gesamten Datei sowie aller anderen Dateien befindet sich auch noch einmal im Anhang dieses Dokuments).
<?php
Begonnen wird mit dem Anlegen der Klasse. Wichtig ist hierbei, dass als Klassenname der Name der aktuellen Datei ergänzt um ein vorangestelltes „class_“ verwendet wird. Sonst kann Kajona keine Instanz der Klasse anlegen. Damit die Klasse auch als Installer-Klasse gekennzeichnet wird, muss diese das Interface „interface_installer“ implementieren, sowie von der Klasse „class_installer_base“ abgeleitet werden. So wird sichergestellt, dass alle benötigten Methoden und Helfer der Klasse zur Verfügung stehen und vom Framework aufgerufen werden können.
class class_installer_element_rssfeed extends class_installer_base implements interface_installer {
Der Konstruktor sorgt, wie bereits bekannt, für das Setzen von Eigenschaften der aktuellen Klasse.
public function __construct() {
$arrModule["version"] = "3.4.0";
$arrModule["name"] = "element_rssfeed";
$arrModule["name_lang"] = "Element rssfeed";
$arrModule["nummer2"] = _pages_content_modul_id_;
parent::__construct($arrModule);
}
Benötige Module, die als Voraussetzung für das aktuelle Element gelten, können in der Methode getNeededModules() definiert werden. Ebenso ist es möglich, eine minimale Systemversion als Voraussetzung zu bestimmen, hierfür wird die Methode getMinSystemVersion() verwendet.
public function getNeededModules() {
return array("system", "pages");
}
public function getMinSystemVersion() {
return "3.4.0";
}
Da Seitenelemente (im Gegensatz zu Modulen) nur über die Methode postInstall() installiert werden, sollte die Methode hasPostInstalls(), je nach Status der Installation, true oder false zurückgeben. Hierbei wird geprüft, ob das Element bereits installiert wurde sowie ob alle benötigten Module bereits installiert wurden.
public function hasPostInstalls() {
//needed: pages
try {
$objModule = class_modul_system_module::getModuleByName("pages");
}
catch (class_exception $objE) {
return false;
}
//check, if not already existing
try {
$objElement = class_modul_pages_element::getElement("rssfeed");
}
catch (class_exception $objEx) {
}
if($objElement == null)
return true;
return false;
}
public function install() {
}
In der Methode postInstall() erfolgt die eigentliche Installation des Seitenelementes. Dies wäre auch die korrekte Stelle, um eigene Tabellen anzulegen.
Exkurs: Da das RSSFeed-Element keine eigene Tabelle benötigt, soll das Anlegen einer eigenen Tabelle anhand des tellafriend-Elements erläutert werden.
$arrFields = array();
$arrFields["content_id"] = array("char20", false);
$arrFields["tellafriend_template"] = array("char254", true);
$arrFields["tellafriend_error"] = array("char254", true);
$arrFields["tellafriend_success"] = array("char254", true);
if(!$this->objDB->createTable("element_tellafriend", $arrFields, array("content_id")))
$strReturn .= "An error occured! ...\n";
Seit Kajona V3.1.x werden Tabellen nicht mehr direkt über SQL-DDL-Kommandos erstellt, sondern über ein Baukastensystem zusammengebaut. Hierfür wird der Methode createTable() der Name der Tabelle, ein Array an Spalten sowie zwei Arrays für die Angabe der Primary Keys sowie der Indizes übergeben. Die Spaltendefinition erfolgt dabei nach dem Schema $arrFields[„spaltenname“] = array(„datentyp“, „is null“ [, default wert]), also durch Aufbau eines zweidimensionalen Arrays. Eine Dokumentation der verfügbaren Datentypen gibt es in den API-Docs der Datenbankschicht. Die Generierung des SQL-Codes wird dann vom jeweiligen Datenbanktreiber vorgenommen.
Beim RSSFeed-Element wird jedoch lediglich das Element an sich registriert, es wird keine weitere Datenbanktabelle angelegt.
public function postInstall() {
$strReturn = "";
//Register the element
$strReturn .= "Registering rssfeed-element...\n";
//check, if not already existing
try {
$objElement = class_modul_pages_element::getElement("rssfeed");
}
catch (class_exception $objEx) {
}
if($objElement == null) {
$objElement = new class_modul_pages_element();
$objElement->setStrName("rssfeed");
$objElement->setStrClassAdmin("class_element_rssfeed.php");
$objElement->setStrClassPortal("class_element_rssfeed.php");
$objElement->setIntCachetime(-1);
$objElement->setIntRepeat(0);
$objElement->saveObjectToDb();
$strReturn .= "Element registered...\n";
}
else {
$strReturn .= "Element already installed!...\n";
}
return $strReturn;
}
public function update() {
}
Da das Element unter Umständen auch Updates installieren sollte, z.B. wenn für neue Funktionen Änderungen nötig werden, kann die Verfügbarkeit von Updates dem Installer mitgeteilt werden. Dies erfolgt über die Methode „hasPostUpdates“, in welcher die Versionsnummer verglich werden:
public function hasPostUpdates() {
$objElement = null;
try {
$objElement = class_modul_pages_element::getElement("rssfeed");
if($objElement != null && version_compare($this->arrModule["version"], $objElement->getStrVersion(), ">"))
return true;
}
catch (class_exception $objEx) { }
return false;
}
Sofern hasPostUpdates die Verfügbarkeit von Updates anzeigt, ruft der Installer „postUpdate“ auf. In dieser Methode können die entsprechenden Aktionen ausgeführt werden, der nachstehende Auszug gilt als exemplarisch:
public function postUpdate() {
$strReturn = "";
if(class_modul_pages_element::getElement("rssfeed")->getStrVersion() == "3.3.1") {
$strReturn .= $this->postUpdate_331_340();
$this->objDB->flushQueryCache();
}
return $strReturn;
}
public function postUpdate_3301_331() {
$strReturn = "Updating element rssfeed to 3.3.1...\n";
$this->updateElementVersion("rssfeed", "3.3.1");
return $strReturn;
}
public function postUpdate_331_340() {
$strReturn = "Updating element rssfeed to 3.4.0...\n";
$this->updateElementVersion("rssfeed", "3.4.0");
return $strReturn;
}
}
?>
Admin-Darstellung
Im Administrationsbereich soll es dem Anwender ermöglicht werden ein Template für die Darstellung, die URL des externen Feeds sowie die Anzahl der anzuzeigenden Meldungen anzugeben.
<?php
class class_element_rssfeed extends class_element_admin implements interface_admin_element {
Die eigentliche Besonderheit komplexer Seitenelement findet sich im Konstruktor bzw. den Metainformationen, die im Konstruktor hinterlegt werden. Über die Array-Werte „table“ und „tableColumns“ erfolgt die Datenbankkonfiguration des Elements. Komplexe Elemente müssen also keinen eigenen SQL-Code mitbringen, dieser wird vom System im Hintergrund erzeugt. Hierfür muss das System natürlich wissen, welche Tabelle später als Ziel der Daten verwendet wird, sowie welche Spalten befüllt werden sollen. Von daher werden im Array-Wert „tableColumns“ alle Spalten samt deren Datentyp genannt. Als Datentypen stehen aktuell char sowie number zur Verfügung, wobei char sowohl für varchar- als auch text-Spalten verwendet wird. Damit Kajona die Werte der Felder automatisch speichern kann, sollten die HTML-Formular-Elemente analog zu den Spalten benannt werden, das wird aber später noch einmal verdeutlicht.
public function __construct() {
$arrModul["name"] = "element_rssfeed";
$arrModul["author"] = "sidler@mulchprod.de";
$arrModul["moduleId"] = _pages_elemente_modul_id_;
$arrModul["table"] = _dbprefix_."element_universal";
$arrModul["modul"] = "elemente";
$arrModul["tableColumns"]= "char1|char,char2|char,int1|number";
parent::__construct($arrModul);
}
public function getEditForm($arrElementData) {
$strReturn = "";
Um dem Benutzer eine Auswahl an möglichen Templates für die Portalausgabe anbieten zu können, werden die verfügbaren Templates im Ordner „/templates/portal/element_rssfeed“ über das Filesystem-API von Kajona geladen und in einem Array gesammelt.
$objFilesystem = new class_filesystem();
$arrTemplates = $objFilesystem->getFilelist("/templates/portal/element_rssfeed", ".tpl");
$arrTemplatesDD = array();
if(count($arrTemplates) > 0) {
foreach($arrTemplates as $strTemplate) {
$arrTemplatesDD[$strTemplate] = $strTemplate;
}
}
Der Aufbau des Eingabe-Formulars erfolgt, wie bereits bekannt, über das Admin-Toolkit. Zu bemerken ist hier, dass die Namen der Formularelemente analog zu den oben definierten Tabellen-Spalten benannt werden. Hier erfolgt als das Zusammenfügen von Datenbank und Benutzereingaben. Das Dropdown zum Selektieren eines Templates wird jedoch nur dann angezeigt, wenn mehr als ein Template vorhanden ist. Für den Fall dass nur ein Template gefunden wurde, wird da Dropdown versteckt angezeigt, kann aber vom Anwender eingeblendet werden.
if(count($arrTemplates) == 1)
$this->addOptionalFormElement(
$this->objToolkit->formInputDropdown(
"char1", $arrTemplatesDD,
$this->getText("template"),
(isset($arrElementData["char1"]) ? $arrElementData["char1"] : "" )
));
else
$strReturn .= $this->objToolkit->formInputDropdown(
"char1", $arrTemplatesDD,
$this->getText("template"),
(isset($arrElementData["char1"]) ? $arrElementData["char1"] : "" )
);
$strReturn .= $this->objToolkit->formInputText("char2", $this->getText("rssfeed_url"), (isset($arrElementData["char2"]) ? $arrElementData["char2"] : ""));
$strReturn .= $this->objToolkit->formInputText("int1", $this->getText("rssfeed_numberofposts"), (isset($arrElementData["int1"]) ? $arrElementData["int1"] : ""));
return $strReturn;
}
}
?>
Um eine Vorstellung davon zu bekommen, was die obige Datei erreicht – so sieht das Element beim Anlegen im Admin-Bereich aus:

Portal-Darstellung
Im Gegensatz zum lastmodified-Element steckt die Schwierigkeit des RSSFeed-Elements in den Portalausgaben. Hier müssen nun die Daten von Extern nachgeladen und unter Verwendung von Templates verarbeitet werden.
Der Prolog der Portalklasse ist altbekannt. Als einzige, wichtige Änderung kann die Angabe der verwendeten Tabelle der Datenbank angesehen werden. Diese wird im Konstruktor im Array-Feld „table“ definiert und der Elternklasse übergeben.
<?php
class class_element_rssfeed extends class_element_portal implements interface_portal_element {
public function __construct($objElementData) {
$arrModule["name"] = "element_rssfeed";
$arrModule["author"] = "sidler@mulchprod.de";
$arrModule["moduleId"] = _pages_elemente_modul_id_;
$arrModule["table"] = _dbprefix_."element_universal";
$arrModule["modul"] = "elemente";
parent::__construct($arrModule, $objElementData);
}
Das Laden der Inhalte erfolgt nun, ebenfalls bekannt, in der Methode loadData().
public function loadData() {
$strReturn = "";
Um den externen Feed zu laden, wird der in Kajona integrierte Remoteloader verwendet. Dieser kennt unterschiedliche Zugriffsarten um entfernte Inhalte zu laden, kann also je nach Systemkonfiguration einen bestmöglichen Weg bestimmen.
$strFeed = "";
try {
$objRemoteloader = new class_remoteloader();
$objRemoteloader->setStrHost(str_ireplace("http://", "", $this->arrElementData["char2"]));
$objRemoteloader->setIntPort(0);
$strFeed = $objRemoteloader->getRemoteContent();
}
catch (class_exception $objExeption) {
$strFeed = "";
}
In einem weiteren Schritt werden die Templates eingelesen, die im Adminbereich für die Ausgabe hinterlegt wurden. Da die Kajona-interne Templateengine mit einem Cachingmechanismus arbeitet, wird eingelesenen Abschnitten eine ID zugewiesen, welche beim späteren Füllen der Templates mit angegeben wird. Von daher wird diese zwischengespeichert.
$strFeedTemplateID = $this->objTemplate->readTemplate("/element_rssfeed/".$this->arrElementData["char1"], "rssfeed_feed");
$strPostTemplateID = $this->objTemplate->readTemplate("/element_rssfeed/".$this->arrElementData["char1"], "rssfeed_post");
Bevor mit der Verarbeitung der XML-Inhalte begonnen wird, sollte geprüft werden, ob überhaupt etwas geladen werden konnte. Sollte dies nicht der Fall sein, wird über die Text-Dateien eine Fehlermeldung ausgegeben.
$strContent = "";
$arrTemplate = array();
if(uniStrlen($strFeed) == 0) {
$strContent = $this->getText("rssfeed_errorloading");
}
else {
Nachdem sichergestellt wurde, dass Inhalte geladen wurden, kann das Parsen des XML-Baumes erfolgen. Hierfür bietet Kajona ein einfaches API, welches die Daten einliest, auf wohlgeformtheit prüft und dann weiterverarbeiten kann. Da im Fall der RSS-Feeds ein Array am einfachsten weiterzuverarbeiten ist, wird der DOM-Baum über die Methode xmlToArray() in ein Array gewandelt.
$objXmlparser = new class_xml_parser();
$objXmlparser->loadString($strFeed);
$arrFeed = $objXmlparser->xmlToArray();
if(count($arrFeed) >= 1) {
Da das Element sowohl RSS- als auch ATOM- Feeds verarbeiten können soll, wird nun das Vorhandensein der entsprechenden Elemente überprüft.
//rss feed
if(isset($arrFeed["rss"])) {
$arrTemplate["feed_title"] = $arrFeed["rss"][0]["channel"][0]["title"][0]["value"];
$arrTemplate["feed_link"] = $arrFeed["rss"][0]["channel"][0]["link"][0]["value"];
$arrTemplate["feed_description"] = $arrFeed["rss"][0]["channel"][0]["description"][0]["value"];
$intCounter = 0;
foreach ($arrFeed["rss"][0]["channel"][0]["item"] as $arrOneItem) {
$arrMessage = array();
$arrMessage["post_date"] = (isset($arrOneItem["pubDate"][0]["value"]) ? $arrOneItem["pubDate"][0]["value"] : "");
$arrMessage["post_title"] = (isset($arrOneItem["title"][0]["value"]) ? $arrOneItem["title"][0]["value"] : "");
$arrMessage["post_description"] = (isset($arrOneItem["description"][0]["value"]) ? $arrOneItem["description"][0]["value"] : "");
$arrMessage["post_link"] = (isset($arrOneItem["link"][0]["value"]) ? $arrOneItem["link"][0]["value"] : "");
Zu Beginn werden allgemeine Eigenschaften des Feeds im Array $arrTemplate gesammelt. Während des Iterierens über die einzelnen RSS Elemente, sollten von diesen die relevanten Daten gesammelt und dann in ein Template ausgegeben werden. Hierfür wurden in den vorhergegangenen Zeilen alle relevanten Inhalte im Array $arrMessage gesammelt. Dieses wird dann in ein Template geschrieben, welches zu Beginn eingelesen wurde und unter der ID $strPostTemplateID gespeichert wurde. Beim Einlesen des Templates wurde definiert, dass nur der Abschnitt „rssfeed_post“ eingelesen wird – also die Repräsentation eines einzelnen RSS-Elements. Hierbei gilt, dass bspw. das Array-Element $arrMessage[„post_title“] in den Platzhalter geschrieben wird. Das gefüllte Template wird dann der Variablen $strContent angehängt.
$strContent .= $this->objTemplate->fillTemplate($arrMessage, $strPostTemplateID);
if(++$intCounter >= $this->arrElementData["int1"])
break;
}
}
Der Aufbau der Element eines ATOM Feeds erfolgt analog, von daher wird hier nicht weiter darauf eingegangen.
//atom feed
if(isset($arrFeed["feed"]) && isset($arrFeed["feed"][0]["entry"])) {
$arrTemplate["feed_title"] = $arrFeed["feed"][0]["title"][0]["value"];
$arrTemplate["feed_link"] = $arrFeed["feed"][0]["link"][0]["attributes"]["href"];
$arrTemplate["feed_description"] = $arrFeed["feed"][0]["subtitle"][0]["value"];
$intCounter = 0;
foreach ($arrFeed["feed"][0]["entry"] as $arrOneItem) {
$arrMessage = array();
$arrMessage["post_date"] = (isset($arrOneItem["updated"][0]["value"]) ? $arrOneItem["updated"][0]["value"] : "");
$arrMessage["post_title"] = (isset($arrOneItem["title"][0]["value"]) ? $arrOneItem["title"][0]["value"] : "");
$arrMessage["post_description"] = (isset($arrOneItem["summary"][0]["value"]) ? $arrOneItem["summary"][0]["value"] : "");
$arrMessage["post_link"] = (isset($arrOneItem["link"][0]["attributes"]["href"]) ? $arrOneItem["link"][0]["attributes"]["href"] : "");
$strContent .= $this->objTemplate->fillTemplate($arrMessage, $strPostTemplateID);
if(++$intCounter >= $this->arrElementData["int1"])
break;
}
}
}
else {
$strContent = $this->getText("rssfeed_errorparsing");
}
}
Nun müssen die gesammelten Elemente nur noch in ein umschließendes Template gepackt werden – sofern das Parsen der Element erfolgreich war - fertig!
$arrTemplate["feed_content"] = $strContent;
$strReturn .= $this->objTemplate->fillTemplate($arrTemplate, $strFeedTemplateID);
return $strReturn;
}
}
?>
Template
Der erste Abschnitt des Templates stellt den umschließenden Part dar. Dieser beinhaltet allgemeine Infos zum Feed sowie die Liste an gesammelten Posts.
<rssfeed_feed>
<p></p>
<p></p>
<p></p>
<div></div>
</rssfeed_feed>
Der Abschnitt rssfeed_post wird zur Präsentation eines einzelnen Posts verwendet.
<rssfeed_post>
<div>
<div></div>
<div><a href="" target="_blank"></a></div>
<div></div>
</div>
</rssfeed_post>
Nun sollte es möglich sein, auch eigene, datenbankbasierte Elemente zu erstellen. Für Feedback, Fragen und Anregungen steht das gesamte Team, as usual, unter www.kajona.de zur Verfügung.
Anhang - installer_element_rssfeed.php
<?php
class class_installer_element_rssfeed extends class_installer_base implements interface_installer {
public function __construct() {
$arrModule["version"] = "3.4.0";
$arrModule["name"] = "element_rssfeed";
$arrModule["name_lang"] = "Element rssfeed";
$arrModule["nummer2"] = _pages_inhalte_modul_id_;
parent::__construct($arrModule);
}
public function getNeededModules() {
return array("system", "pages");
}
public function getMinSystemVersion() {
return "3.4.0";
}
public function hasPostInstalls() {
//needed: pages
try {
$objModule = class_modul_system_module::getModuleByName("pages");
}
catch (class_exception $objE) {
return false;
}
//check, if not already existing
try {
$objElement = class_modul_pages_element::getElement("rssfeed");
}
catch (class_exception $objEx) {
}
if($objElement == null)
return true;
return false;
}
public function hasPostUpdates() {
$objElement = null;
try {
$objElement = class_modul_pages_element::getElement("rssfeed");
if($objElement != null && version_compare($this->arrModule["version"], $objElement->getStrVersion(), ">"))
return true;
}
catch (class_exception $objEx) {
}
return false;
}
public function install() {
}
public function postInstall() {
$strReturn = "";
//Register the element
$strReturn .= "Registering rssfeed-element...\n";
//check, if not already existing
try {
$objElement = class_modul_pages_element::getElement("rssfeed");
}
catch (class_exception $objEx) {
}
if($objElement == null) {
$objElement = new class_modul_pages_element();
$objElement->setStrName("rssfeed");
$objElement->setStrClassAdmin("class_element_rssfeed.php");
$objElement->setStrClassPortal("class_element_rssfeed.php");
$objElement->setIntCachetime(3600);
$objElement->setIntRepeat(0);
$objElement->setStrVersion($this->getVersion());
$objElement->updateObjectToDb();
$strReturn .= "Element registered...\n";
}
else {
$strReturn .= "Element already installed!...\n";
}
return $strReturn;
}
public function update() {
}
public function postUpdate() {
$strReturn = "";
if(class_modul_pages_element::getElement("rssfeed")->getStrVersion() == "3.3.1") {
$strReturn .= $this->postUpdate_331_340();
$this->objDB->flushQueryCache();
}
return $strReturn;
}
public function postUpdate_331_340() {
$strReturn = "Updating element rssfeed to 3.4.0...\n";
$this->updateElementVersion("rssfeed", "3.4.0");
return $strReturn;
}
}
?>
Anhang - class_element_rssfeed.php (admin)
<?php
class class_element_rssfeed extends class_element_admin implements interface_admin_element {
public function __construct() {
$arrModul["name"] = "element_rssfeed";
$arrModul["author"] = "sidler@mulchprod.de";
$arrModul["moduleId"] = _pages_elemente_modul_id_;
$arrModul["table"] = _dbprefix_."element_universal";
$arrModul["modul"] = "elemente";
$arrModul["tableColumns"] = "char1|char,char2|char,int1|number";
parent::__construct($arrModul);
}
public function getEditForm($arrElementData) {
$strReturn = "";
$objFilesystem = new class_filesystem();
$arrTemplates = $objFilesystem->getFilelist("/templates/portal/element_rssfeed", ".tpl");
$arrTemplatesDD = array();
if(count($arrTemplates) > 0) {
foreach($arrTemplates as $strTemplate) {
$arrTemplatesDD[$strTemplate] = $strTemplate;
}
}
if(count($arrTemplates) == 1)
$this->addOptionalFormElement($this->objToolkit->formInputDropdown("char1", $arrTemplatesDD, $this->getText("template"), (isset($arrElementData["char1"]) ? $arrElementData["char1"] : "" )));
else
$strReturn .= $this->objToolkit->formInputDropdown("char1", $arrTemplatesDD, $this->getText("template"), (isset($arrElementData["char1"]) ? $arrElementData["char1"] : "" ));
$strReturn .= $this->objToolkit->formInputText("char2", $this->getText("rssfeed_url"), (isset($arrElementData["char2"]) ? $arrElementData["char2"] : ""));
$strReturn .= $this->objToolkit->formInputText("int1", $this->getText("rssfeed_numberofposts"), (isset($arrElementData["int1"]) ? $arrElementData["int1"] : ""));
return $strReturn;
}
}
?>
Anhang - class_element_rssfeed.php (portal)
?php
class class_element_rssfeed extends class_element_portal implements interface_portal_element {
private $arrError = array();
public function __construct($objElementData) {
$arrModule["name"] = "element_rssfeed";
$arrModule["author"] = "sidler@mulchprod.de";
$arrModule["moduleId"] = _pages_elemente_modul_id_;
$arrModule["table"] = _dbprefix_."element_universal";
$arrModule["modul"] = "elemente";
parent::__construct($arrModule, $objElementData);
}
public function loadData() {
$strReturn = "";
$strFeed = "";
try {
$objRemoteloader = new class_remoteloader();
$objRemoteloader->setStrHost(str_ireplace("http://", "", $this->arrElementData["char2"]));
$objRemoteloader->setIntPort(0);
$strFeed = $objRemoteloader->getRemoteContent();
}
catch (class_exception $objExeption) {
$strFeed = "";
}
$strFeedTemplateID = $this->objTemplate->readTemplate("/element_rssfeed/".$this->arrElementData["char1"], "rssfeed_feed");
$strPostTemplateID = $this->objTemplate->readTemplate("/element_rssfeed/".$this->arrElementData["char1"], "rssfeed_post");
$strContent = "";
$arrTemplate = array();
if(uniStrlen($strFeed) == 0) {
$strContent = $this->getText("rssfeed_errorloading");
}
else {
$objXmlparser = new class_xml_parser();
$objXmlparser->loadString($strFeed);
$arrFeed = $objXmlparser->xmlToArray();
if(count($arrFeed) >= 1) {
//rss feed
if(isset($arrFeed["rss"])) {
$arrTemplate["feed_title"] = $arrFeed["rss"][0]["channel"][0]["title"][0]["value"];
$arrTemplate["feed_link"] = $arrFeed["rss"][0]["channel"][0]["link"][0]["value"];
$arrTemplate["feed_description"] = $arrFeed["rss"][0]["channel"][0]["description"][0]["value"];
$intCounter = 0;
foreach ($arrFeed["rss"][0]["channel"][0]["item"] as $arrOneItem) {
$arrMessage = array();
$arrMessage["post_date"] = (isset($arrOneItem["pubDate"][0]["value"]) ? $arrOneItem["pubDate"][0]["value"] : "");
$arrMessage["post_title"] = (isset($arrOneItem["title"][0]["value"]) ? $arrOneItem["title"][0]["value"] : "");
$arrMessage["post_description"] = (isset($arrOneItem["description"][0]["value"]) ? $arrOneItem["description"][0]["value"] : "");
$arrMessage["post_link"] = (isset($arrOneItem["link"][0]["value"]) ? $arrOneItem["link"][0]["value"] : "");
$strContent .= $this->objTemplate->fillTemplate($arrMessage, $strPostTemplateID);
if(++$intCounter >= $this->arrElementData["int1"])
break;
}
}
//atom feed
if(isset($arrFeed["feed"]) && isset($arrFeed["feed"][0]["entry"])) {
$arrTemplate["feed_title"] = $arrFeed["feed"][0]["title"][0]["value"];
$arrTemplate["feed_link"] = $arrFeed["feed"][0]["link"][0]["attributes"]["href"];
$arrTemplate["feed_description"] = $arrFeed["feed"][0]["subtitle"][0]["value"];
$intCounter = 0;
foreach ($arrFeed["feed"][0]["entry"] as $arrOneItem) {
$arrMessage = array();
$arrMessage["post_date"] = (isset($arrOneItem["updated"][0]["value"]) ? $arrOneItem["updated"][0]["value"] : "");
$arrMessage["post_title"] = (isset($arrOneItem["title"][0]["value"]) ? $arrOneItem["title"][0]["value"] : "");
$arrMessage["post_description"] = (isset($arrOneItem["summary"][0]["value"]) ? $arrOneItem["summary"][0]["value"] : "");
$arrMessage["post_link"] = (isset($arrOneItem["link"][0]["attributes"]["href"]) ? $arrOneItem["link"][0]["attributes"]["href"] : "");
$strContent .= $this->objTemplate->fillTemplate($arrMessage, $strPostTemplateID);
if(++$intCounter >= $this->arrElementData["int1"])
break;
}
}
}
else {
$strContent = $this->getText("rssfeed_errorparsing");
}
}
$arrTemplate["feed_content"] = $strContent;
$strReturn .= $this->objTemplate->fillTemplate($arrTemplate, $strFeedTemplateID);
return $strReturn;
}
}
?>
Anhang - rssfeed.tpl
<rssfeed_feed>
<p></p>
<p></p>
<p></p>
<div></div>
</rssfeed_feed>
<rssfeed_post>
<div>
<div></div>
<div><a href="" target="_blank"></a></div>
<div></div>
</div>
</rssfeed_post>


