[Quicktip] sshd auf einem Synology NAS / DiskStation neu starten

Synology hat einiges an seiner Linux Distribution DSM umgebastelt, sodass sich die Service Scripte nicht wie gewohnt in /etc/init.d befinden. Um den sshd neu starten zu können, muss man daher folgendes Kommando verwenden:

/usr/syno/etc.defaults/rc.d/S95sshd.sh restart

Weitere Restart Kommandos findet ihr hier:
forum.synology.com

[Quicktip] .nfo Dateien mit der Mac OSX Vorschau / Quick Look anschauen

Ihr kennt sicherlich das extrem coole Feature von Mac OSX, dass man im Finder oder auf dem Desktop nur die Leertaste drücken muss, und schon erscheint eine kleine Vorschau der jeweils gerade ausgewählten Datei. Dies geht leider nur mit einigen bekannten Formaten wie txt Dateien oder Bildern. Möchte man damit z.B. weitere Textdateien, die jedoch andere Endungen verwenden, öffnen, dann geht es nicht von Haus aus. Ein Beispiel hierfür sind z.B. .nfo Dateien.

Um auch diese Dateien per Quick Look ansehen zu können, muss man folgendes machen:

Die Datei /Applications/TextEdit.app/Contents/Info.plist editieren – dies kann man entweder per

sudo vi /Applications/TextEdit.app/Contents/Info.plist

oder über den Finder den Ordner Programme aufrufen, dort das Programm TextEdit raussuchen und anschließend per Rechtsklick den Menüpunkt “Programminhalt anzeigen” öffnen. Nun in den Ordner Contents wechseln und dort die Datei Info.plist öffnen. Achtung: hierfür werden Adminrechte benötigt!

In der Datei angekommen, bewegt euch ganz nach unten vor die beiden schließenden Tags

und fügt da folgendes ein:

<key>UTExportedTypeDeclarations</key>
	  <array>
	    <dict>
	      <key>UTTypeConformsTo</key>
	      <array>
	        <string>public.text</string>
	        <string>public.plain-text</string>
	      </array>
	      <key>UTTypeDescription</key>
	      <string>NFO information file</string>
	      <key>UTTypeIdentifier</key>
	      <string>com.macromates.textmate</string>
	      <key>UTTypeTagSpecification</key>
	      <dict>
	        <key>com.apple.ostype</key>
	        <string>TEXT</string>
	        <key>public.filename-extension</key>
	        <array>
	          <string>nfo</string>
	        </array>
	      </dict>
	    </dict>
	  </array>

Anschließend speichern und noch auf der Konsole ein

sudo touch /Applications/TextEdit.app

ausführen. Anschließend sollten auch .nfo Dateien mittles Leertaste angezeigt werden.

via macuser.de

[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] SSH Key zu Github per Shell hinzufügen

Für alle, die sich unnötige manuelle Schritte beim Hinzufügen eines neuen SSH Keys zum eigenen Github Account sparen wollen:

mit

curl --data "{\"title\": \"NAME\",\"key\": \"`cat ~/.ssh/id_rsa.pub`\"}" --request POST https://api.github.com/user/keys --user "USERNAME:PW"

wird automatisch der Public SSH Key des aktuellen Benutzers im Github Account hinterlegt.
Unter NAME wird ein eindeutiger Name für den Schlüssel angegeben, USERNAME und PW sollten selbsterklärend sein.

Noch ein kleiner Tipp am Rand: bestehende Keys werden weder überschrieben, noch doppelt hinzugefügt.

[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();