Sep 24
Mit der Version 4.3 wurde TYPO3 um den “Scheduler” erweitert. Ziel ist es, automatisierte Aufgaben zu bestimmten Zeiten auszuführen. Früher wurde dazu in der Regel ein CLI-Script über Cron aufgerufen. Der Scheduler stellt eine zentrale Verwaltung dieser Aufgaben zur Verfügung. Um den Scheduler nutzen zu können, muss die System-Extension scheduler installiert sein. Des weiteren muss der Benutzer _cli_scheduler existieren. Dieser benötigt keine Admin-Rechte, sollte aber zur Sicherheit mit einem sicheren Passwort geschützt werden. Der Cron-Job ruft dann nur noch das Scheduler-Script auf. Der Pfad dazu wird im Backendmodul angezeigt. Extensions die den Scheduler einsetzen sollen, müssen ihre Tasks über einen Hook in der ext_localconf.php der Extension registrieren. In folgenden Listings sind “extkey” und “TaskName” durch entsprechende Werte zu ersetzen, also dem Extension-Key und einem Namen für den Task.
$TYPO3_CONF_VARS['SC_OPTIONS']['scheduler']['tasks']['tx_extkey_TaskName'] = array( 'extension' => $_EXTKEY, 'title' => 'LLL:EXT:'.$_EXTKEY.'/locallang.xml:TaskName.name', 'description' => 'LLL:EXT:'.$_EXTKEY.'/locallang.xml:TaskName.description', );
Die Übersetzung wird in der Datei locallang.xml hinterlegt, die, sofern sie nicht schon existiert, dafür angelegt wird. Der Aufbau kann aus der locallang_db.xml übernommen werden.
Als nächstes wird die Datei ext_autoload.php im Extension-Verzeichnis angelegt. Diese enthält folgenden Inhalt:
<?php return array( 'tx_extkey_TaskName' => t3lib_extMgm::extPath('extkey', 'scheduler/class.tx_extkey_TaskName.php') ); ?>
Der eigentliche Code, der ausgeführt werden soll, wird in die Datei scheduler/class.tx_extkey_TaskName.php geschrieben. Diese erweitert die Klasse tx_scheduler_Task und enthält die Funktion execute(), die vom Scheduler aufgerufen wird.
<?php class tx_aebhotelbewimport_import extends tx_scheduler_Task { public function execute() { // Hier kommt all der lustige Code, der ausgeführt werden soll. } } ?>
Den Return-Wert der Funktion execute() sollte man nicht vergessen, damit der Scheduler den Erfolg oder Misserfolg der Ausführung verwerten kann. Der Return-Wert ist entweder true oder false. Die Datenbankfunktionen, t3lib_div etc. stehen zur Verfügung. Auch auf $GLOBALS und $TYPO3_CONF_VARS kann zugegriffen werden. Die zeitliches Konfiguration wird im Backendmodul des Schedulers eingestellt.
Dez 14

Es gibt zahlreiche Gründe, warum man hin und wieder am TYPO3-Core herumschrauben muss.

Meist sind es Kleinigkeiten, die den Kunden stören und die nur so zu beseitigen sind. Allerdings läuft man immer die Gefahr, seine Änderungen zu verlieren, wenn man neue Sourcen einspielt. Da wäre es also sinnvoll und praktisch Aufzeichnung über seine Änderungen zu haben – am besten in einer Form, mit der sich diese sofort wieder in die aktualisierten Sourcen einspielen lassen.

Aber auch für einen anderen Zweck ist das ganze gut: Wenn man beispielsweise einen Fehler im TYPO3-System findet und diesen behebt, kann man seine Veränderung als patch-File im Bugtracker hinterlegen.

Um einen Patch zu erstellen gehen wir wie folgt vor (die Anleitung ist für Linux-Systeme):

  1. Wir speichern die zu ändernde Datei mit einem neuen Namen im selben Verzeichnis ab, in meinem Fall war dies die Datei class.t3lib_page.php im Verzeichnis typo3_src-4.1.4/t3lib/ Die Kopie der Datei habe ich beispielsweise class.t3lib_page_orig.php genannt.
  2. Nun wird die usprüngliche Datei geändert (Fehler behoben, Feauture zugefügt, …)
  3. Wenn wir mit der Änderung fertig sind, wechseln wir ins Rootverzeichnis der TYPO3-Installation.
  4. Dort setzen wir folgenden Befehl ab (alles in eine Zeile schreiben!) – die Pfade und Dateinamen müssen natürlich angepasst werden:
    diff -ruN typo3_src-4.1.4/t3lib/class.t3lib_page.php
    typo3_src-4.1.4/t3lib/class.t3lib_page_orig.php
    > patch_20071214_1.diff
  5. Das nun erstellte Patch-File heben wir an geeigneter Stelle auf.
  6. Wir können nun die Kopie der Datei wieder löschen.
  7. Wenn wir später die Änderung wieder einspielen wollen, wechseln wir wieder ins Rootverzeichnis der TYPO3-Installation und geben den folgenden Befehl ein:
    patch -p1 < patch_20071214_1.diff
  8. Gegebenenfalls muss dann das File angegeben werden, welches den Patch abbekommen soll – wenn sich die Pfade nicht verändert haben, ist dies allerdings nicht notwendig.
  9. Um den Patch nicht direkt einzuspielen, sondern einen sogenannten Trockenlauf zu machen, um zu sehen, was sich ändern würde, kann man den Parameter –dry-run verwenden.

Der Vorteil dabei ist, dass man sich die Patch-Files auch so manuell durchsehen kann, um schnell herauszubekommen, was für Änderung man im Laufe der Zeit durchgeführt hat. Wenn man wie oben das Datum in den Filenamen schreibt, hat man auch eine visuelle Kontrolle über den Zeitpunkt der Änderungen.

Dez 4

Der Titel hört sich etwas merkwürdig an, aber ich wusste nicht, wie man es anders bezeichnen soll.

Folgende Aufgabenstellung bekam ich vom Kunden:

Aus 20 zufälligen Bildern von Mitarbeitern die über das LDAP in TYPO3 eingebunden wurden, soll eine Collage erstellt werden, die aus 5 Reihen und vier Spalten besteht.

Also machen wir uns ans Werk:

Generell habe ich folgende Vorgehensweise gewählt:

  1. Einen Query über die fe_user-Tabelle, der zufällig 20 User ausliest
  2. Ein leeres Bild erzeugen, welches die Collage aufnehmen kann
  3. Durch alle zurückgelieferten Datensätze iterieren und jeweils die URL des Bildes auslesen.
  4. Dieses Bild an die entsprechende Stelle in der Collage schreiben
  5. Das fertige Bild ausgeben

Dafür bietet sich die postUserFunc aus dem stdWrap-Baukasten an, da eine Extension viel zu überdimensioniert wäre. Ich gehe davon aus, dass es einen Marker COLLAGE gibt. Wir erzeugen also auf der Seite, die die Collage bekommen soll, ein Extension-Template mit dem folgenden Inhalt:

includeLibs.something = fileadmin/scripts/collage.php

page.10.marks.COLLAGE = TEXT
page.10.marks.COLLAGE {
   postUserFunc = user_generateCollage
}

Zunächst laden wir also die Datei collage.php, die sich im Verzeichnis fileadmin/scripts befindet. Anschließend erzeugen wir am Marker COLLAGE ein TEXT-cObject, dessen Inhalt wir über die Funktion user_generateCollage bestimmen. Die Funktion (deren Name immer mit user_ anfangen muss) wiederum befindet sich in der Datei collage.php. Ich habe die Kommentare direkt in die Datei geschrieben um die jeweiligen Arbeitsschritte zu kennzeichnen. Bitte beachtet ausserdem, dass dies eine ganz speziell angepasste Auftragsarbeit war – manche Stellen hätte man sicherlich generischer anpacken können.

Inhalt der Datei: collage.php

<?php

function user_generateCollage($one,$two) {
   // nur die fe_user nehmen, die sich auf der Seite mit der
   //pid = 170 befinden
   $where .= " pid = 170";
   // eine Usergruppe (hier 27) soll ausgeblendet werden -
   // der Vorstand mag nicht auf's Bild :-)
   $where .= " AND usergroup !='27'";
   // nur Datensätze auswählen die auch ein Bild haben
   $where .= " AND image != ''";
   // stellt sicher, dass keine verstecken o. ausgeblendeten
   // Daten erfasst werden
   $enableFields = $GLOBALS['TSFE']->cObj->
                                     enableFields('fe_users');
   $where .= " ".$enableFields;
   // Zufallsgenerator an...
   $order_by = " RAND() " ;
   // ... und genau 20 Ergebnisse mitnehmen
   $limit = 20;

   // Datenbank-Query absetzen
   $res = $GLOBALS["TYPO3_DB"]->exec_SELECTquery( ' * ',
                    'fe_users', $where, '',$order_by, $limit);

   // img-Objekt aufbauen, zunächst als GIFBUILDER
   $img["file"] = 'GIFBUILDER';
   // Größe der Collage festlegen
   $img['file.']["XY"] = '228,389';
   // als Format wird PNG verwendet
   $img['file.']["format"] = 'png';
   // Die Qualität der auszugebenden Collage soll maximal sein
   $img['file.']["quality"] = '100';

   // Nun gehen wir durch alle Zeilen (aeussere Schleife)
   // und alle Spalten (innere Schleife)
   for ($y = 0; $y < 5; $y++) {
      for ($x = 0; $x < 4; $x++) {
         // zaehler fuer die verschiedenen GifBuilderObj
         $counter = $y*100 + $x*10 + 5;
         // Ergebnis holen
         $row = $GLOBALS["TYPO3_DB"]->sql_fetch_assoc($res);
         // als GifBuilderObj das Objekt IMAGE auswaehlen
         $img['file.'][$counter] = 'IMAGE';
         // sollten mehrere Bilder hinterlegt worden sein,
         // dann nimm das erste
         $image = split(",",$row['image']);
         $image = (is_array($image)) ? $image[0] : $image;
         // Pfad zur Bilddatei
         $img['file.'][$counter."."]["file"] =
                                        'uploads/pics/'.$image;
         // Format festlegen
         $img['file.'][$counter."."]["file."]['format'] = 'jpg';
         // Breite des Bildes
         $img['file.'][$counter."."]["file."]['width'] = '57';
         // Hoehe des Bildes
         $img['file.'][$counter."."]["file."]['height'] = '78';
         // Nun wird das Bild positioniert:
         //Hier ersteinmal die x-Position
         $offx = (int)($x*57)+1;
         // ... und hier die Y-Position
         $offy = (int)($y*78)+1;
         // Offset setzen
         $img['file.'][$counter."."]['offset'] = "$offx,$offy";
      }
   }
   // * Magic!! * Nun wird die Collage gerendert :-)
   $imgResource = $GLOBALS['TSFE']->cObj->IMAGE($img);
   // und zurückgegeben
   return $imgResource;
}
?>

Voilá – that’s it – und so sieht’s aus:

Die fertige Collage (Symboldarstellung)

Die “Magie” letztlich steckt darin, ein durch PHP erzeugtes TS-Array mit dem GIFBUILDER-Objekt durch die Funktion cObj->IMAGE rendern zu lassen.

Nov 2

Da ich dies gerade bei einem Projekt hatte…

Es soll aus einem Verzeichnis zufällig eine der dort vorhandenen Flash-Dateien in TYPO3 geladen und angezeigt werden. Das lässt sich logisch auch für Bilder und ähnliches umschreiben.

Folgendes TypoScript schreibt man in den Setup-Bereich des Templates – im Bereich “params” werden die Flash spezifischen Parameter notiert:

page.includeLibs.flash = fileadmin/scripts/flashrandom.php
page.10.marks.FLASH = COA_INT
page.10.marks.FLASH {
   10 = MULTIMEDIA
   10 {
      file.preUserFunc = user_flashrandom->getFlash
      params (
         width = 740
         height = 260
         type = application/x-shockwave-flash
         quality= high
         wmode = transparent
)
   }
}

In eine Datei “flashrandom.php” die wir ins Verzeichnis “fileadmin/scripts/” legen, kommt folgender PHP-Code:

<?php
class user_flashrandom {
   function getFlash ($text, $tsconf) {
      $dir = 'fileadmin/flash/hp/';
      $dh  = opendir($dir);
         while (false !== ($filename = readdir($dh))) {
            if ($filename != "." && $filename != "..") {
               $files[] = $filename;
            }
      }
      srand((float) microtime() * 10000000);
      $key = array_rand($files);
      $ret = $dir . $files[$key];
      return $ret;
   }
}
?>
Okt 23

Der RTE kann relativ einfach vergrößert werden. Neben dem RTE befindet sich das Vollbildsymbol. Mit zwei Zeilen TS im Setup Feld des Benutzers kann die Größe aber auch individuell eingestellt werden:

options.RTESmallWidth = 600
options.RTESmallHeight = 500

Die Angaben entsprechen den Pixeln, die der RTE groß sein soll.

Okt 23

Da mittlerweile zahlreiche Videotutorials zu TYPO3 erschienen sind und von jedem dieser Titel auch Demo-Videos verfügbar sind, folgt hier eine (nicht vollständige) Liste der verfügbaren kostenlosen Videos:

TYPO3 Version 4 – Video-Training (Addison Wesley)
TYPO3 4.0 für Redakteure (Addison Wesley)
TYPO3 für Profis (Addison Wesley)
TYPO3 Video-Training (Addison Wesley)
TypoScript-Videotraining (Addison Wesley)

Einstieg in TYPO3 4.0 (Galileo Computing)