Archiv

Archiv für die Kategorie ‘Webentwicklung’

Zend Framework mit Eclipse PDT (Galileo) und SVN

22. Februar 2010

Wer ZendStudio nicht benötigt oder sich nicht leisten kann oder will, kann mit der hier beschriebenen Konfiguration Eclipse mit Subversion für seine PHP Zend Framework Projekte unter Windows verwenden.

Zunächst gehen wir davon aus, dass Apache und PHP bereits installiert sind und dass irgendwo eine Version von Zend Framework gespeichert ist (z.B.: c:\server\library\ZendFramework-1.9.0). Darüber hinaus werden wir die Möglichkeit benötigen unter Windows symbolische Verknüpfungen anzulegen, dazu kann man einfach (falls nicht vorhanden) die junction.exe bei Microsoft herunterladen.

In diesem Beispiel gehe ich von folgender Verzeichnisstruktur aus (die natürlich auch ganz anders sein kann). Was die einzelnen Verzeichnisse beinhalten wird im Laufe der Konfiguration klar:

C:\\

  • Programme
    • eclipse
    • SlikSvn
      • bin
  • server
    • Apache
    • eclipse
      • workspaces
    • library
      • PEAR
      • ZendFramework
      • etc.
    • MySQL
    • php
    • svn
      • repository
    • vhost
    • xdebug

Als Nächstes installieren wir eclipse-php-galileo-SR1-win32.

Dann benötigen wir Subversion für Windows. Derzeit kann man von tigris.org nichts herunterladen, da das Projekt Apache übergeben wird. Wir installieren deshalb Subversion von sliksvn.com – ist ein super Paket.

Jetzt müssen wir den Subversion-Server unter Windows einrichten. Bei codinghorror.com gibt es dazu eine wunderbare Anleitung. Hier die wesentlichen Schritte zusammengefasst:

  • cmd:
    svnadmin create "c:\server\svn\repository"
  • conf/svnserve.conf des erstellten Repository:
    anon-access = none
    auth-access = write
    password-db = passwd
  • conf/passwd des erstellten Repository:
    dein-name= dein-passwort
  • Subversion als Dienst registrieren, Server starten, SVN-Editor setzen, SVN-(Test)-Verzeichnis erzeugen – cmd:
    sc create svnserver binpath= "c:\Programme\SlikSvn\bin\svnserve.exe --service -r c:\server\svn\repository" displayname= "Subversion" depend= Tcpip start= auto
    net start svnserver
    set SVN_EDITOR=c:\Programme\Notepad++\notepad++.exe
    svn mkdir svn://localhost/test

Damit wir loslegen können, müssen wir jetzt nur noch Subversion unter Eclipse konfigurieren. Dazu gibt es wiederum eine wunderbare Anleitung bei javathreads.de. Ich verzichte auf eine Zusammenfassung, hier nur der benötigte Link für die Installation des Connectors:

http://community.polarion.com/projects/subversive/download/eclipse/2.0/galileo-site/

Die eigentliche Konfiguration hier als ein kleiner Screencast:
(Die Audiospur hängt ganz schön hinterher und ich bin mit der Maus zuweilen ganz schön am Abwandern, aber worum es geht wird, denke ich, recht klar)

P.S. Unter Umständen ist es sinnvoll am Ende die Datei .buildpath und den Ordner .settings in die ignore-Liste von SVN aufzunehmen – am Besten einfach mit TortoiseSVN o.Ä.

Erstellen eines CMS mit ZendFramework – Teil 1

28. Juni 2009

Vorüberlegungen und Strategien

1. Routing

Das A und O von Webseiten sind ihre URLs. ZF bietet weitreichende Möglichkeiten mit dynamischen Routing, URLs an die gewünschten Anforderungen anzupassen. Jedoch sind die Möglichkeiten für ein professionelles CMS begrenzt.

Beispiel:

In unserem CMS möchten wir 5 verschiedene Seiten erstellen, die alle bis auf ‘News’ zunächst mit einfachen Texten und Bildern gefüllt werden sollen. Die Seitentitel lauten:

+ Home
+ Unser Unternehmen (über uns)
+ Kontakt
+ Abteilungen
+ Impressum
+ News

Da wir von Anfang an eine mehrsprachige Seite aufbauen wollen, möchten wir jede Seite in jeder verfügbaren Sprache ansprechen können. Sollte eine Seite noch nicht übersetzt worden sein, soll sie in der Standardsprache (im CMS konfigurieren wir hierfür deutsch) angezeigt werden. Auf Grund der Mehrsprachlichkeit, möchten wir, dass die URIs im Gegensatz zu den Seitentiteln auf englisch sind:

- index
- about
- contact
- – departments
- imprint
- news

Wir möchten im CMS auch konfigurieren können, ob für die Standardsprache in den URLs auch der Ländercode angezeigt werden soll.
Wenn wir zunächst zwei Sprachen (deutsch und englisch) im CMS definieren, möchten wir folgende URLs erhalten:

Mit Ländercode in der URL für die Standardsprache:

- http://example.com (mit Redirect auf:)
- http://example.com/de
- http://example.com/de/about
- http://example.com/de/contact
- http://example.com/de/contact/departments
- http://example.com/de/imprint
- http://example.com/de/news

- http://example.com/en
- http://example.com/en/about
- http://example.com/en/contact
- http://example.com/en/contact/departments
- http://example.com/en/imprint
- http://example.com/en/news

Ohne Ländercode in der URL für die Standardsprache:

- http://example.com
- http://example.com/about
- http://example.com/contact
- http://example.com/contact/departments
- http://example.com/imprint
- http://example.com/news

- http://example.com/en
- http://example.com/en/about
- http://example.com/en/contact
- http://example.com/en/contact/departments
- http://example.com/en/imprint
- http://example.com/en/news

Da es sich bei allen Seiten, bis auf ‘News’, die einen eigenen Controller bekommen sollen, um einfache Seiten mit Bildern und Texten handelt, erstellen wir für die Funktionalität einen Controller im ZF, den wir z.B. Article nennen und dessen indexAction die entsprechenden Inhalte aus einer Persistenzschicht ausliest und über die View ausgibt.

Problem:

Auch wenn mit den Routern von ZF viel möglich ist, wären die URLs in ZF so nicht darstellbar. Standardmäßig hätten wir URLs etwa in der Form: http://example.com/article/index/page/about/language/en

Lösung für das CMS:

Wir erstellen einen URL-Mapper bzw. einen Module-Controller-Action-Mapper, der aus dem Request anhand der Daten aus der Persistenzschicht die entsprechenden Segmente auf die Klassen von ZF mappt. Der Mapper bietet einerseits die gewünschte Flexibilität URLs syntaktisch und semantisch den Wünschen entsprechend aufzubauen und andererseits ermöglicht er volle Kompatibilität zum ZF Routing.

Für ein CMS hat das weitere Vorteile: Wir können noch weitere Daten zu der jeweiligen Seite bzw. URL speichern (z.B. ob die Seite überhaupt online ist, Angaben zur Resource für ACL, Seitenname etc.). Vor allem aber erhalten wir so, schon eine Liste aus der sich direkt eine Navigation erzeugt lässt. Das Datenobjekt der Persistenzschicht, wir nennen sie mal Page, hat also etwa folgende Eigenschaften:

- id
- parent_id
- name
- req_modul
- req_controller
- req_action
- zf_modul
- zf_controller
- zf_action

Unsere Seiten würden dann wie folgt gespeichert:

============================================================================================================================
| id   | parent_id | name               | req_modul | req_controller | req_action   | zf_modul | zf_controller | zf_action |
============================================================================================================================
| 1    | 0         | Home               | default   | index          | index        | default  | article       | index     |
----------------------------------------------------------------------------------------------------------------------------
| 2    | 0         | Unser Unternehmen  | default   | about          | index        | default  | article       | index     |
----------------------------------------------------------------------------------------------------------------------------
| 3    | 0         | Kontakt            | default   | contact        | index        | default  | article       | index     |
----------------------------------------------------------------------------------------------------------------------------
| 5    | 3         | Abteilungen        | default   | contact        | departments  | default  | article       | index     |
----------------------------------------------------------------------------------------------------------------------------
| 4    | 0         | Impressum          | default   | imprint        | index        | default  | article       | index     |
----------------------------------------------------------------------------------------------------------------------------
| 6    | 0         | News               | default   | news           | index        | default  | news          | index     |
============================================================================================================================

Der URL-Mapper ruft also bis auf News immer den ArticleController mit der indexAction auf. Im Mapper wird auch sichergestellt, dass die ermittelte id später in der indexAction verfügbar ist, damit diese die Inhalte, die zu der Seite gehören in der Persistenzschicht suchen und dann dem View übergeben kann.

Was ist mit der Mehrsprachlichkeit?
Die Länderkennungen sind weder Module, noch Controller, noch Actions. Vielmehr sind sie Parameter für den Controller. Deswegen entfernen wir Sie aus der URL und schreiben sie in die Registry bevor ZF den Routingprocess startet. Schnell anskizziert könnte eine Funktion, die wir in der Bootstrap vor dem Routing aufrufen etwa wie folgt aussehen:

 
    public static function setLanguage()
    {
        $oLanguageConfig = Zend_Registry::get('config')->languages;
        $sCurrentLang = $oLanguageConfig->default;
 
        if ($oLanguageConfig->enable == 1) {
            preg_match('@/[^/]*@', $_SERVER['REQUEST_URI'], $aUrlMatches);
            if (!empty($aUrlMatches)) {
                $sUrlMatch = substr($aUrlMatches[0], 1);
                $aLangs = $oLanguageConfig->lang;
                if (is_string($aLangs)) {
                    $aLangs = array($aLangs);
                }
                foreach($aLangs as $sLang) {
                    if ($sLang == $sUrlMatch) {
                        $sCurrentLang = $sLang;
                        $_SERVER['REQUEST_URI'] = substr($_SERVER['REQUEST_URI'], (strlen($sLang) + 1));
                        break;
                    }
                }
            }
        }
        Zend_Registry::set('currentLang', $sCurrentLang);
    }

Was ist mit der Mehrsprachlichkeit in der Persistenzschicht? Wir realisieren diese mit einem “page_language_overlay” Datenobjekt. Es hat folgende Eingeschaften:

- fk_page_id
- language
- name

Bevor es weiter geht, ein kleiner Exkurs zum Aufbau von URLs:

Zunächst muss man sich vor Augen halten, dass man durch den URL-Mapper sehr weitgehende Freiheiten in Bezug auf den Aufbau von URLs gewonnen hat und kaum noch an das Korsett der ZF Logik gebunden ist, dass man damit aber auch in der Verantwortung steht, den logischen Aufbau selbst zu vollziehen. Warum sollte man sich das überhaupt aufbürden? Ganz einfach:
Programmierer (und alle Technokraten dieser Welt), hätten sicher kein Problem damit, wenn URLs immer nach Schema ZF aufgebaut wären. Auftraggeber, für die letztlich das CMS gemacht wird und die unseren Lebensunterhalt finanzieren, akzeptieren aber kein:

http://example.com/article/index/page/about

sie bestehen (teilweise zu recht) auf:

http://example.com/about

Warum auf solchen URLs bestehen? Ganz einfach: Man kann sie sich besser merken (Es ist erstaunlich wie wenige Auftraggeber Bookmarks nutzen). Ach ja, auch für Suchmaschinen sind Angaben wie ‘article/index/page’ ziemlicher Blödsinn.

Schauen wir uns das Problem genauer an (unabhängig von einer möglichen Abneigung gegen Technokraten – Jenseits von Gut und Böse sozusagen) und stellen uns als Resource das klassische Offlinemedium vor: ein Buch. Schlagen wir es auf und schauen ins Inhaltsverzeichnis. Jetzt überlegen wir, wie die einzelnen Punkte im Inhaltsverzeichnis als URL mit ZF standardmäßig dargestellt werden würden. Anstatt eines Inhaltsverzeichnisses wie wir es alle kennen, würde dort etwas stehen wie:

Buch / Inhalt / zeige / Kapitel / “Götzen-Dämmerung” / Seite / 279
(module / controller / action / key / value / key / value)

Tatsächlich findet sich im Buch aber nur Folgendes im Inhaltsverzeichnis:

Götzen-Dämmerung 279

Zugegeben, weiß man ja im Internet noch nicht, dass man ein Buch aufgeschlagen hat und man weiß auch noch nicht unbedingt, dass es sich um das Buch “Jenseits von Gut und Böse” handelt – schließlich gibt es vielleicht auch andere Bücher mit gleichnamigem Kapitel und vielleicht gibt es auch Räucherkerzen die Götzen-Dämmerung heißen. Was dagegen im Ggs. zum Druckerzeugnis im Internet nicht interessiert, ist die Seite auf der das Kapitel anfängt. Nach der ZF Logik würde das zu einer Syntax etwa wie folgt führen:

http://example.com/buch/inhalt/zeige/titel/Jenseits-von-Gut-und-Boese/kapitel/Goetzen-Daemmerung

Die kürzere Syntax – die dem Auftraggeber gefällt – hingegen ist aber:

http://example.com/buch/Jenseits-von-Gut-und-Boese/Goetzen-Daemmerung

Im Grunde haben wir bei der kurzen URL aber nicht viel mehr getan, als das Verb (die Action) und die Kennzeichnung der Adjektive (oder anders gesagt, die Typen der Attribute des Buches, die keys ‘titel’ und ‘kapitel’) wegzulassen. Der Sachverhalt bezüglich der Adjektive erscheint recht klar, schließlich sagen wir ja auch nicht: “Dieses Buch hat die Farbe blau.” Vielmehr würden wir sagen “Dieses Buch ist blau.” Darüber hinaus ist in der natürlichen Sprache das Verb “sein” (in manchen Sprachen leider auch das Verb “haben”) ebenso selbstverständlich, wie im Internet die Action “zeige” oder “liste” oder “gib aus” oder “stell dar”. Deswegen können wir ja auch einfach sagen: “Dieses blaue Buch” (Nach dem Motto: “Dieser Satz kein Verb”, aber mit einem hic-deiktischem Pronomen). Erst wenn wir mit dem Buch etwas anstellen wollen, benötigen wir ein Verb:  “Ich kaufe dieses Buch von Nietzsche”. Das Buch wird dabei zum Objekt des Satzes. Das bedeutet, dass eine Information aus Subjekt + eindeutiges Attribut immer dann ausreichend ist, wenn wir das Subjekt lediglich darstellen wollen und wenn wir immer mit den gleichen Typen von Attributen unsere Auswahl treffen. Wenn wir im Internet ein Buch kaufen möchten, ist das Subjekt nicht mehr das Buch, sondern der Shop der Website, wir erhalten dann eine URL wie:

http://example.com/shop/kaufe/ISBN/3-89508-038-1

oder, falls wir annehmen, dass der Buchtitel immer eindeutig ist:

http://example.com/shop/kaufe/buch/Jenseits-von-Gut-und-Boese

Autor:Viktor Grandgeorg Kategorien:Allgemein, Webentwicklung Tags:

Test Mail Server Tool und POP2SMTP bzw. IMAP2SMTP Tool

12. Mai 2009

Test Mail Server Tool

Ein unheimlich nützliches kleines Tool um das Senden von E-Mail beim Entwickeln von Webanwendungen zu testen ist ToolHeap.

Das Programm lauscht auf localhost auf einem SMTP Port (standardmäßig 25, was sich aber einstellen lässt). Jegliche E-Mail, die an diesen Port verschickt wird, wird in einem einstellbaren Verzeichnis im eml-Format gespeichert und optional gleich mit dem assoziierten E-Mail Programm geöffnet.

P2S POP2SMTP bzw. IMAP2SMTP Tool

Ich hatte als POP2SMTP Tool bisher immer POPcon im Einsatz. Das Tool ist auch wirklich klasse es verrichtet einfach seine Arbeit und lässt sich durch so gut wie nichts beirren. Leider kostet es schon in der Standardversion 79 €. Die meisten meiner Kunden, die sich einen Small Business Server angeschafft haben, haben nicht wirklich viel Verständnis dafür, dass der teuere Server mit Exchange nicht einmal in der Lage ist anständig POP3 Postfächer abzurufen (der POP3 Connector von MS ist ja bekannter maßen ziemlicher Mist).

Gestern habe ich P2S gefunden. Ein Tool das, derzeit zumindest, nichts kostet und das Gleiche können soll wie POPcon. Ich habe es noch nicht testen können. Aber es sieht vielversprechend aus.

Neues Wordpress-Theme up and running

27. April 2009

Ich habe das aktuelle Theme “inove” von mg12 angepasst und ausgebaut. Ich habe unter Anderem die Sprachdatei für Deutsch mit Poedit vervollständigt und das Layout und die CSS etwas angepasst. Ich habe auch die sidebar.php meinen Bedürfnissen angepasst und in den Footer die Widgetfähigkeit eingebaut – Ist eigentlich recht einfach und übersichtlich.

dojo und der ewige K(r)ampf

24. April 2009

Ich habe auf einem Testrechner die wohl ausgefeilteste Referenzimplementierung die Pastebin app für Zend Framework mit dojo von Matthew Weier O’Phinney installiert. Der PHP Code und der Umgang mit Objekten ist sicher sehr elegant, aber …

Unter Windows gestaltet sich die Installation nicht ganz einfach, da Matthew mit symlinks arbeitet. Hat man kein Vista zur Hand oder kein cygwin installiert, kann man aber die junction.exe von Microsoft installieren, mit der man einfach symbolische Verknüpfungen erstallen kann.

Nach der Installation ist das Ergebnis aber eher ernüchternd. Die Performance der Anwendung ist lausig. Die Länge der Permalinks mit http://example.com/spindle/paste/display/id/nummer ist viel zu lang – ein typisches ZF Problem (von wegen module/controller/action/key1/var1). Es kann sich überhaupt nicht mit pastebin.com oder de.pastebin.ca messen.

Schlimmer finde ich jedoch, dass dojo bzw. die benutzerdefinierten Klassen von Matthiew für dojo im Microsoft Internet Explorer 7 überhaupt nicht funktionieren. Es gibt eine Fehlermeldung (eigentlich zwei) in der JS Console: Colud not load ’spindle.main’. Werde es noch gegen den IE8 testen, denke aber nicht, dass es besser geht.

Dojo an sich hat echte Probleme mit dem IE – man versuche mit dem IE8 den Dojo Feature Explorer.

Ich habe dahingehend Matthiew auch einen Kommentar geschrieben.

Ich hätte es ja eher begrüßt, wenn ZF nicht gleich dojo heiratet, sondern vielleicht lieber YUI oder Ähnliches.