[FLOW3] Wie schreibt man einen eigenen Translation Provider?

Ein weiterer Teil, welcher in der FLOW3 Dokumentation so gut wie gar nicht abgedeckt wird, ist die Frage, wie man einen eigenen Translation Provider implementiert. FLOW3 selbst bringt nur einen Xliff Provider mit. Dieses Format ist der Standard in der Internationalisierung. Allerdings braucht man vielleicht nicht immer ein so aufgeblähtes Format und möchte einfach eine CSV Datei mit 1:1 Übersetzungen hinterlegen. Dafür sind folgende Schritte nötig:

Zuerst legen wir eine neue Klasse im Pfad “[PackageName]/I18n/TranslationProvider/CsvTranslationProvider.php” und folgendem Inhalt an:

namespace [Vendor]\[Package_Name]\I18n\TranslationProvider;
use TYPO3\FLOW3\I18n\TranslationProvider\TranslationProviderInterface;
/**
 * The concrete implementation of TranslationProviderInterface which uses CSV
 *
 * @FLOW3\Scope("singleton")
 */
class CsvTranslationProvider implements TranslationProviderInterface {
}

Da wir das TranslationProviderInterface implementieren, müssen natürlich auch die entsprechenden Methoden vorhanden sein. Diese sind die “getTranslationByOriginalLabel” und “getTranslationById”. An dieser Stelle bekommt man mit den Parametern “$originalLabel” bzw. “$labelId” das zu übersetzende Label und mit der “$locale” die entsprechend aktuell eingestellte Sprache. Zusätzlich kommen noch ein paar weitere Parameter mit, die aber für eine einfache Übersetzung per CSV nicht zwingend nötig sind. Eine Hilfsmethode, die man dann von beiden Methoden aus aufrufen kann, könnte folgendermaßen aussehen:

private function translate($key, $locale) {
    $translations = array();
    $language = $locale->getLanguage();
    if (($handle = fopen([PFAD_ZUR_CSV_DATEI], "r")) !== FALSE) {
	$translations[$language] = array();
	while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
		if(count($data) == 2) {
			$translations[$language][$data[0]] = $data[1];
		}
	}
	fclose($handle);
    }
    $translation = $key;
    if(array_key_exists($key, $this->translations[$language])) {
	$translation = $this->translations[$language][$key];
    }
    return $translation;
}

Diese Methode ist nur für diesen Beitrag beispielhaft implementiert. Natürlich sollte nicht bei jeder einzelnen Übersetzung die komplette CSV Datei in den Speicher gelesen werden. Also bitte nicht produktiv einsetzen 😉

Anschließend registriert man in der Datei “/Packages/[PackageName]/Configuration/Objects.yaml” den Provider für den I18n Translation Service:

TYPO3\FLOW3\I18n\Translator:
  properties:
    translationProvider:
      object: [Vendor]\[Package_Name]\I18n\TranslationProvider\CsvTranslationProvider

Die CSV Datei hat dann folgenden Inhalt:

Translation;Übersetzung

Sobald man diese Schritte erledigt hat, kann man in allen Fluid Templates mit dem Tag “<f:translate>Translation</f:translate>” Wörter automatisiert übersetzen lassen. Ist für das Wort keine Übersetzung vorhanden, so wird einfach das unübersetzte Wort verwendet.

[FLOW3] Wie kann man mittels Repository eine einfache Count Abfrage durchführen?

Der ORM Teil von FLOW3 besteht leider (zumindest für erfahrene Entwickler) aus sehr viel Magic, die man nicht immer so leicht durchschauen kann. So ist es eigentlich selten nötig, irgendeine Methode im Repository zu implementieren. Rein durch das Erben der Basisklasse “\TYPO3\FLOW3\Persistence\Repository” erhält man die magischen findBy*() und findAll() Methoden, mit denen man so gut wie alle notwendigen Abfragen abdeckt. Nicht so wirklich bekannt sind jedoch die parallel dazu verfügbaren countBy*() und countAll() Methoden, mit denen man allerdings keine Datenobjekte abfragt, sondern eben die Anzahl der möglichen Datensätze als Ergebnis bekommt.

Beispiel:

$userFromDresdenCount = $userRepo->countByWohnort('Dresden');

oder

$userCount = $userRepo->countAll();

Warum man in OSX Mountain Lion seine Social Network Logins hinterlegen kann

Unter iOS ist es ja bereits sehr prominent möglich, seinen Twitter und seit Version 6 auch seinen Facebook Account zu hinterlegen und somit systemweit Beiträge darüber zu schreiben. Erst jetzt ist mir aufgefallen, dass man diese Möglichkeiten auch unter OSX Mountain Lion hat, wobei der Spaß hier noch deutlich weiter geht…

Facebook und Twitter sind natürlich völlig klar und sorgen dafür, dass man in der Notification Leiste von Mountain Lion nun direkt im jeweiligen Netzwerk posten kann. Außerdem erhält man auch alle Notifications von Facebook als OSX Notification. Sehr nett. Aber was hat es z.B. mit Vimeo oder Flickr auf sich? Nun, dazu muss man einfach mal im Finder eine Bilddatei oder ein Video mit der rechten Maustaste anklicken und schon hat man folgende Möglichkeit:

oder

Es ist wirklich grandios. Kein einloggen, Upload starten, warten, Browser ja nicht schließen usw., sondern einfach nur anstoßen und machen lassen und schon landen eure Inhalte im gewünschten Netzwerk. Leider geht die Integration nicht immer gleich super weit – so ist es z.B. nicht möglich, Bilder auch auf einer Facebook Seite zu posten. Schade auch, dass Youtube nicht als Service unterstützt wird – oder ich stell mich zu blöd an. Aber mit Vimeo hat man auf jeden fall ein ordentliches Portal dabei.

Das neue Ad-Tracking unter iOS 6 und wie man es deaktiviert

Oh Apple, warum lässt du dich auf sowas ein? Du ermöglichst Werbetreibenden zu sehen, welche Dinge ich mir so im Netz anschaue (zumindest anonymisiert), damit diese geziehlt Werbung für mich schalten können. All dies wäre nicht schlimm, wenn du dies wenigstens standardmäßig deaktivieren bzw. nachfragen würdest – als absolutes Minimum aber den entsprechenden Menüpunkt an der korrekten Stelle ablegen würdest (nämlich unter dem Menüpunkt “Datenschutz” und nicht etwa in den Systeminformationen!). All dies tust du nicht, daher informiere ich nun alle iOS 6 User darüber 😉

Also, folgende Schritte sind notwendig, solltet ihr das neue Ad Tracking auf eurem Gerät deaktivieren wollen:

Wer noch ein bisschen mehr darüber erfahren möchte, der kann sich folgenden Artikel zu Gemüte führen:
http://www.businessinsider.com/ifa-apples-iphone-tracking-in-ios-6-2012-10?op=1

GeekTool Script für die Statusanzeige von Prozessen, wie z.B. httpd oder mysqld

Wenn man auf seinem OSX Desktop immer gleich sehen möchte, ob Services, wie z.B. der Apache Webserver httpd oder der MySQL Server mysqld laufen, kann man folgendes GeekTool Script verwenden:

#!/bin/bash
if [ "$(ps -Ac | grep httpd)" != "" ]; then httpServ="running";
else httpServ="offline"; fi
if [ "$(ps -Ac | grep mysqld)" != "" ]; then sqlServ="running";
else sqlServ="offline"; fi
echo "HTTP : $httpServ";
echo "SQL : $sqlServ";

Das Beispiel kann man nach der Vorlage beliebig für andere Prozesse erweitern. Per GeekTool eingebunden sieht das dann folgendermaßen aus:

Wenn der Service nicht aktiv ist, steht an Stelle von running “offline”…

[Quicktip] Shopware 4 auf andere Domain umziehen

Wenn man eine Shopware Installation auf einen anderen Server verschiebt bzw. die Domain zum Shop ändert, dann wird dieser nach korrektem Aufruf trotzdem immer wieder auf die alte URL weiter leiten. Um dies zu umgehen, muss man in der Shopware Datenbank folgendes bearbeiten:

In der Tabelle s_core_shops den jeweiligen Shop heraus suchen und anschließend die Felder “host” und “hosts” auf die neue URL setzen. Danach sollte Shopware auch unter der neuen URL korrekt funktionieren.

[FLOW3] Wie setze ich die Default Sprache (Locale) auf Deutsch?

Da die FLOW3 Dokumentation sehr lückenhaft und schlecht umgesetzt ist, möchte ich unter dem Tag “FLOW3” in Zukunft alles dokumentieren, was mir so an Problemen in der täglichen Entwicklung mit dem Framework über den Weg läuft.

Ein Beispiel hierfür ist die konkrete Umsetzung, wie man die Standard-Sprache (bzw. Standard-Locale) seiner Applikation ändern kann. Nach einiger Recherche im Netz und Studium des FLOW 3 Quellcodes kam ich zu folgender Lösung: man muss lediglich in der Settings.yaml (entweder die des Packages oder die allgemeine) folgenden Parameter setzen:

TYPO3:
  FLOW3:
    i18n:
      defaultLocale: 'de'

An Stelle des “de” kann man natürlich jede andere gültige Länderkennung bzw. Sprachkennung verwenden.