[FLOW3] Wie lege ich eine Catchall / Wildcard Route an?

Tragt einfach in eurer Routes.yaml folgendes ein:

-
  name: 'default'
  uriPattern: '({all})'
  defaults:
    '@package':    '[dein_Vendor].[dein_Package]'
    '@controller': 'Standard'
    '@action':     'index'
    '@format':     'html'

Bitte beachten: dieser Routeneintrag sollte der allerletzte sein (also ganz unten stehen), da sonst alle danach folgenden definierten Routen nicht mehr funktionieren werden.

[Quicktip] git per Samba Share zeigt alle Dateien als “geändert” an

Nehmen wir folgende Konstellation: Du hast einen Linux Server, der einen Ordner per SMB (Samba, Windows Freigabe) Share freigibt, in dem sich git Repositories befinden. Greifst du nun von einem anderen Rechner auf diese Dateien zu, so wird git alle Dateien innerhalb dieses Repositories als geändert anzeigen. Ein git diff zeigt dann z.B. folgendes:

old mode 100644
new mode 100755

Dies bedeutet nichts anderes, als dass sich die Zugriffsrechte der Dateien geändert haben. Innerhalb der Samba Share Konfiguration kann man diese Rechte (also Zugriff für Benutzer, Gruppe, Alle) regeln. In vielen Fällen wird sich diese Konfiguration von der in git eingecheckten unterscheiden. Um das Problem zu umgehen, gibt es nun folgende Möglichkeiten:

– im Samba Share Config File die Dateirechte korrekt setzen
– innerhalb des git Repositories folgenden Parameter setzen bzw. umstellen:

git config core.filemode false

Bitte beachten: Wenn dieser Parameter gesetzt wird, kann man KEINE Änderungen von Dateirechten in git committen!

Wollt ihr dies auf eurem Rechner global für alle Repositories machen, dann verwendet folgenden Befehl:

git config --global core.filemode false

Bitte hier besonders daran denken, dass nun in ALLEN git Repositories, auf die dieser Rechner zugreift, kein Committen von Änderungen an den Dateirechten möglich ist – es sei denn, der Parameter wird in einzelnen Repositories explizit überschrieben.

[Quicktip] Wenn das remote git repository keinen Push annehmen will…

Erinnerung an mich selbst: wenn mich ein remote git Repo das nächste mal mit so einer Fehlermeldung begrüßt

fatal: failed to write object
error: unpack failed: unpack-objects abnormal exit
Auto packing the repository for optimum performance.
fatal: Unable to create '/[reponame].git/packed-refs.lock': Permission denied

…dann macht es Sinn zu prüfen, ob der jeweilige User auf dem Zielserver überhaupt die entsprechenden Schreibrechte für den Repository Ordner hat…

[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