Posted in
Joomla! Specials -
Legacy entfernen
Quelle (Artikel von Andrew Eddie, in Englisch): www.theartofjoomla.com
Übersetzung: Joomla! Schweiz
Willkommen zum 2. Teil der Serie.
Thema ist das Konvertieren einer bestehenden J1.0.x Komponente zu einer J1.5.x Version.
Im letzten Teil haben wir die Konstante, welche den direkten Zugriff zu der .php Datei unterbindet beschriebenen und einige Datenbankprobleme gelöst. Wir haben auch einen Einblick in die J.1.5x Übersetzungen gemacht. Nun fahren wir mit dieser Serie weiter und lösen diverse Fehler auf.
Komponenten Parameter:
Unser nächster Fehler kommt, wenn Letterman versucht, die mosComponent Klasse zu benützen, um die Komponenten Parameter aufzurufen. Sie sehen diesen Fehler in der Realität nicht soviel bei 1.0.x Komponenten, da viele Entwickler diese Möglichkeit nicht erkannt haben, diese Klasse aufzurufen. Aber mit Joomla 1.5.x erhalten Sie eine nette API (Referenzenbibliothek) für den Zugriff auf viele Funktionen, welche das Joomla Programmieren nun leichter machen.
LetterMan beinhaltet in letterman.class.php:
| $component = new mosComponent( $database ); $component->load( $letterman_id ); $GLOBALS['lm_params'] = $lm_params = new mosParameters( $component->params ); |
Wir haben nun eine Klasse dafür, genannt JComponentHelper, welche wir nun benützen können um die komplette Konfiguration aufzurufen.
Diesen Block können Sie nun zum Beispiel mit folgendem ersetzen:
| jimport( 'joomla.application.component.helper' ); $lm_params = JComponentHelper::getParams( 'com_letterman' ); $GLOBALS['lm_params'] = $lm_params; |
Obwohl dies ein funktionierender PHP-Syntax ist, dieser Aufruf mittels = neigt sich zu überladen, aber dies ist auch nur ein einfaches Beispiel. Programmieren Sie bitte, wie Sie es gerne wollen, dennoch können Sie so die Methode namens getParams aufrufen und reichen ihr den Ordner-Namen der Komponente.
Weiter unten im Letterman Code speichert es die Parameter noch einmal, so das dies dort dann Probleme gibt - aber ich werde Ihnen in einem anderen Teil der Serie einen einfachen Weg zeigen die Komponenten-Konfiguration einzubinden, so das wir dies hier erst mal ignorieren.
Die GetParams Methode liefert uns ein JParameter Objekt (dies ersetzt übrigens das mosParameter Objekt in 1.0.x).
Datenbank-Limits
Ich habe unten ein paar Zeilen abgebildet und bemerkte, das wir dort ein paar ändern müssen. Die Limits stammen noch aus den Mambo Tagen.
Ich habe festgestellt, dass eine Abfrage endet mit:| LIMIT 0, 1 |
Wir schreiben die Queries nicht mehr mit einem Limit.
Die Datenbank setQuery Methode beinhaltet einige extra Argumente von der SQL-Seite her.
Diese Argumente wurden erschaffen im Hinblick auf neue Datenbank-Anschlüsse, welche für die Zukunft gestaltet wurden(z. B. für Oracle, etc.).
Lassen Sie uns einen Blick auf diese Argumente werfen:
| function setQuery( $sql, $offset = 0, $limit = 0, $prefix='#__' ) |
Wir müssen also den LIMIT raus nehmen und rufen den SetQuery mit diesen Argumenten auf:
| $database->setQuery( $sql, 0, 1 ); |
Dies ist zwar technisch nicht ein 1.0.x auf 1.5.x Upgrade-Problem, es ist aber eine gute Praxis um Ihre Abfragen auf diese Weise zu gestalten. So entsteht auch kein Chaos mit dem letzten Argument.
Datenbank Query richtig gestalten:
Achten wir nun auf die Datenbank-Abfragen, bei denen Sie folgendes beachten sollten: Erstellen Sie unbedingt einen geschlossenen String: In Abfragen müssen Sie den String und die Zahlen in '(Hochkomma) schreiben, dies verringert das Risiko, dass Script-Kiddies die "inject" Methode verwenden können um bösartigen Code in die abfragenden Variablen zu schleusen.
Hier ist ein gutes Beispiel zu diesem Thema, wie es früher gemacht wurde und Sie unbedingt beachten und anders machen sollten:
| $sql = "SELECT subscriber_name FROM #__letterman_subscribers WHERE subscriber_email='$email'"; |
Folglich könnten nun noch andere Argumente eingefügt werden durch die Inject Methode, da dies die Anführungszeichen auch zulassen!
Um fair zu bleiben: LetterMan nutzte zuvor " (Anführungszeichen) bei der variable $email, aber ein netterer Weg ist dies mit der Datenbank Hochkomma Methode. Wir lassen das Hochkomma mittels Quote auch einfügen.
Also ändern wir das Query im Code selber:
| $sql = 'SELECT subscriber_name' . ' FROM #__letterman_subscribers' . ' WHERE subscriber_email=' . $database->Quote( $email );$database->setQuery( $sql ); |
So erhalten wir immer noch den RAW Inhalte des Wertes von $email, welchen wir nun weiter nutzen können, zum Beispiel zum Versenden eines E-Mail. Die Quote Methode hat aber noch einen anderen, wichtigen Vorteil: Die Quote Methode kann erweitert werden für verschiedene Datenbank Engines(Arten). Genau aus dem gleichen Grund handeln wir wie oben beschrieben die Limits separat.
Bitte achten Sie beim Programmieren darauf, damit die Kompatibilität zu allen Datenbanken erhalten bleibt.
Die Zeichensätze der Datenbanken(arten) sind teilweise unterschiedlich und nicht alle nutzen das Anführungszeichen und Hochkomma gleich.
Ein zweites Beispiel ist wenn wir wissen das die Werte integer sind. Wir sollten diese Werte schützen, auch dann wenn Sie direkt aus der Datenbank kommen, hier ein Beispiel:
| $sql = "SELECT idFROM #__users, #__letterman_subscribersWHERE user_id=id AND user_id='".$my->id."'"; |
Dies sollten Sie nun ändern in: (Achten Sie auf das(int) )
| $sql = 'SELECT id' . ' FROM #__users, #__letterman_subscribers' . ' WHERE user_id=id AND user_id=' . (int) $my->id; |
Ok, Sie haben es sicherlich bemerkt: aktuell nutzen ich noch nicht das JOIN Statement.
Konzentrieren wir uns zuerst darauf, die Komponente zum Laufen zu bringen.
Datenbank loadObject
Schnell bekommen wir auch den folgenden Fehler, da die Datenbank LoadObject Methode unterschiedlich gehandelt wird:
In 1.0.x übergaben wir die Objekte als ein Argument.
In 1.5.x übergibt uns dies ein Objekt.
Diese einfache kleine Änderung erzeugt einen wichtigen Effekt.
So wurde es in 1.0.x noch gemacht:
| database->loadObject( $result ); |
Und nun das selbe in der 1.5.x Programmierung:
| $result = $database->loadObject(); |
Absoluter Pfad und LiveSite aufrufen:
das nächste Problem ist aber nicht so wichtig, dennoch nützlich zu wissen:
In 1.5.x haben wir die Variable $mosConfig_absolute_path nicht mehr.
Wir haben nun etliche andere Möglichkeiten:
JPATH_SITE
Der Pfad der Seite als Ersatz zu $mosConfig_absolute_path
JPATH_ADMINISTRATOR
Der Pfad zu der Administration
JPATH_COMPONENT
Der Pfad zu der Komponente in der Sie Arbeiten.
Es existieren unzählige andere Konstanten. Werfen Sie einen Blick in die
/includes/defines.php Datei. Dort finden Sie etliche davon als Basis für Ihre Komponenten.
Hier finden Sie die Komplette API: http://api.joomla.org/
Ersetzen Sie also alle $mosConfig_absolute_path mit JPATH_SITE.
Das gleiche können Sie mit natürlich einfacher auch mit JPATH_COMPONENT machen:
So wird aus: require_once( $mosConfig_absolute_path . '/administrator/components/com_letterman/includes/contentRenderer.class.php' );
Nun in der 1.5.x das gleiche:
require_once( JPATH_COMPONENT.DS.'includes'.DS.'contentRenderer.class.php' );
Sie sehen, die Konstante für den PHP DIRECTORY_SEPARATOR ist auch implementiert worden mittels DS.
Als Beispiel:
| // change $path = JPATH_SITE . '/mambots/' . $folder . '/' . $element . '.php'; // into $path = JPATH_SITE.DS.'mambots'.DS.$folder.DS.$element.'.php'; |
Eine andere Änderung ist diese, die $mosConfig_live_site existiert auch nicht mehr, Sie wurde ersetzt durch: JURI::base().
Da die Suche und das Ersetzen sich teilweise ein bisschen schwierig gestaltet hier ein Weg dies anders zu tun:
Suchen Sie nach: global $mosConfig_live_site;
und kommentieren es mittels zwei // aus dem Code aus.
Fügen Sie genau unterhalb folgendes ein:
$mosConfig_live_site = JURI::base( true );
Sie sehen, falls Sie nun eine LiveSite benötigt wird, übergibt die JURI den Wert.
Nutzen Sie JURI::base ohne ein Argument, übergibt es den vollen URL der Seite mit einem Slash am Ende:
http://www.joomlaportal.ch/
Andere Konfigurations Variablen von früher:
$mainframe->getCfg( 'list_limit', 10 );
Zum Abfangen von anderen Konfigurationswerten, so haben Sie vorrausichtlich keine weiteren Probleme:
Falls Sie dies nutzen:
global $mosConfig_list_limit;
Dann haben Sie nun folgende Möglichkeiten:
Eine ist, Sie ändern die Instanz zu folgendem:
global $mainframe;
$listLimit = $mainframe->getCfg( 'list_limit', 10 );
Eine noch bessere Möglichkeit ist aber, Sie nutzen die JFactory Klasse um eine Kopie der Konfiguration Objekte zu erhalten:
$config = JFactory::getConfig();
$listLimit = $config->get( 'config.list_limit' );
Information über den momentanen Nutzer:
In 1.0.x hatten wir die Globale Variable: $my welche die Informationen über den Nutzer enthielten.
Diese Variable existiert in 1.5.x nicht mehr, sie wurde ersetzt durch die getUser Methode:
Der alte Weg von 1.0.x:
global $my;
Der neue Weg von 1.5.x:
$user = &JFactory::getUser();
Diese Methode liefert uns ein Objekt, aktuell ein JObject.
Sie können die Werte nun so auslesen:
| $id = $user->id;$access = $user->aid; $groupId = $user->gid; $name = $user->name; |
Oder aber auch so:
| $id = $user->get( 'id' ); $access = $user->get( 'aid' ); $groupId = $user->get( 'gid' ); $name = $user->get( 'name', 'no name supplied' ); |
Dieser Weg ist der leichteste wenn Sie einen zweiten Standard-Wert erhalten wollen.
mosGetParam und JRequest
Eine andere, oft benützte Methode war die mosGetParam.
Sie wurde ersetzt durch die mächtigere JRequest Klasse.
JRequest ist auch ein Weg um den Zugriff auf Informationen anzufordern, aber was noch wichtiger ist: Ihre vorderste Front der Verteidigung gegen böswillige Beiträge von Möchtegern-Hackern auf Ihre Website.
Dies ist nun das letzte Thema dieses Teils der Serie und wir verbringen nun ein bischen Zeit bei der Prüfung Ihres Codes:
The JRequest Klasse finden Sie in den Joomla Bibliotheken als ein Teil der Umgebung von Joomla.
Suchen Sie in: /libraries/joomla/environment/request.php.
Sie finden die komplette Joomla 1.5 Api hier: http://api.joomla.org/
Es lohnt sich, einen guten Einblick in diese Klasse zu halten, da es über 500 Zeilen sind.
Die folgenden 'GET' Methoden werden von Interesse für alle Entwickler sein.
Sofern Sie keine anders lautenden, mit zusätzlichen Argumenten, versehene Abfragen haben, werden die Joomla-Input-Filter-Klassen den Code "sauber" halten.
Die Standard-Aktion dieser Klasse ist das entfernen von potenziell gefährlichen Zeichen, bzw. HTML Tags.
Nutzen Sie den richtigen Code, da Schrägstriche entfernt werden. (Es sei den Sie haben explizit einen Schrägstrich im Code eingefügt)
Die meisten Getters (ausser 'get' selber) nutzen mindestens drei Argumente three: Den Namen der Abfragevariablen, einen Standardwert und die Abfrage Methode: Zum Beispiel get oder post etc.
So, damit ist es nun genug mit den Anweisungen, lasst uns zu den Methoden wechseln:
get
JRequest::get erlaubt den Zugriff auf saubere PHP abfrage Variablen.
Als Beispiel:
$post = JRequest::get( 'post' );
liefert in $post eine Saubere Version von $_POST, mit allen Arrays der Abfrage selbst.
Ohne ein weiteres Argument wird diese Methode Ihnen eine "saubere" Version von den Werten aus $_Request liefern.
getBool
Stellt sicher das der Wert ein boolan ist.
Ein Beispiel dazu:
$showPrint = JRequest::getBool( 'print' );
getCmd
Stellt sicher das die Resultate nur die Zeichen: A-Z, 0-9, _ (unterlinie), . (punkt) oder – (gedankenstrich) enthält.
Als Beispiel:
Der URL ist:
&task=Abcdef#123;
$task = JRequest::getCmd( 'task' );
getFloat
$task = Abcdef123.getFloat
Sorgt dafür, dass das Ergebnis ist zu einem Float Wert wird.
getInt
Dies sorgt dafür, dass der Wert ein integerer Wert ist.
Besonders nützlich, wenn wir zum Beispiel die ID abfangen wollen. Als Beispiel:
| $userId = JRequest::getInt( 'user_id', 0, 'post' ); |
getVar
Dies ist die allgemein verwendete Methode zum Abfangen der Werte einer variablen: Sie nutzen dazu ein viertes Argument.
Alle anderen getSomething Methoden sind eigentlich ein Alias für diese eine. Hier sind einige Beispiele dafür, wie Sie sie nutzen können:
So erhalten die Array-Variable cid aus der Anfrage:
$cid = JRequest::getVar( 'cid', array(), 'post', 'array' );
So bekommen nur einen String aus der Anfrage:
$name = JRequest::getVar( 'name', 'no name supplied' );
So erhalten Sie den Wert eines Cookie
$returning = JRequest::getVar( 'mycookie', '', 'cookie' );
getWord
Sorgt dafür, dass das Ergebnis nur AZ, oder _ (Unterstrich) enthält.
Zum Beispiel:
Die URI ist:
&task=A_bcdef#123,
$task = JRequest::getWord( 'task' );
Sie sehen also:
$task = A_bcdef
Mit diesem Wissen können wir uns nun wieder auf die Komponente konzentrieren.
Jede Art von mosGetParam müssen wir individuell betrachten. Kommentieren Sie also den Orginalen Text aus und fügen Ihren neuen Code unterhalb ein.
So haben Sie die Kontrolle über die Änderungen.
Beispiel:
// $cid = mosGetParam( $_POST, 'cid', array(0) );
// $task = mosGetParam( $_REQUEST, 'task' );
// $no_html = mosGetParam( $_REQUEST, 'no_html' );
Ersetzen mit:
$cid = JRequest::getVar( 'cid', array(0), 'post', 'array' );
$task = JRequest::getWord( 'task' );$no_html = JRequest::getBool( 'no_html' );
Beispiel:
// $mails_per_pageload = intval( mosGetParam( $_POST, "mails_per_pageload", 100 ));
Ersetzen mit:
$mails_per_pageload = JRequest::getInt( 'mails_per_pageload', 100, 'post' );
Damit ist nun der 2. Teil meiner Serie zum Umwandeln bestehender 1.0 Komponetnten zu einer 1.5 Version abgeschlossen.
Im nächsten Teil bearbeiten wir die Fehlersuche und Fehleranzeige. Damit sollten dann leere Bildschirme und fehlende Funktionen der Vergangenheit angehören.



0 Kommentare