Posts mit dem Label Typo3 werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Typo3 werden angezeigt. Alle Posts anzeigen

Mittwoch, 10. Dezember 2014

Weiße Seite nach TYPO3 Update - dank opcode Cache

OpCache sei Dank ist meine TYPO3 Seite jetzt wesentlich schneller.  Ein Minor-Update von TYPO3 einzuspielen ist aber wesentlich hackeliger geworden. Macht man es wie gewohnt:  Sourcen runterladen und entpacken, Symlink neu setzen, alten Ordner entfernen, dann kommt nach dem nächsten Mal neu Laden nur eine leere weiße Seite.

Aus dem Zustand kommt man am besten heraus, indem man erst Mal wieder die alten Sourcen an die gleiche Stelle einspielt. Als nächsten im Backend alle Caches löschen und in einem weiteren Fenster ins InstallTool wechseln. Dort unter „Important Actions“ den Befehl „Clear PHP opcode cache“ auswählen. Jetzt noch mal den Ordner der alten Sourcen löschen (ober besser erst umbenennen - das spart dann Zeit, falls es doch noch schief geht) und noch mal alle Caches löschen.

So klappt’s bei mir in etwa. Bin jetzt schon ein paarmal in das Problem gelaufen. Das nächste Mal probiere ich meine eigene Reihenfolge ganz genau aus. Aktuell ist es nur aus dem Kopf niedergeschrieben, nachdem mal wieder alles lief :)

Dienstag, 25. Dezember 2012

Typo3 Xing API Data Import Extension

Alumnivereine, die ein eigens Portal haben, werden es kennen. Fast kein User macht sich die Mühe ein vollständiges Profil aktuell zu halten. Wir haben das Problem jetzt damit gelöst, dass die User ihre Daten von Xing mit wenigen Klicks importieren können. Das Ganze ist als freie TYPO3 Extension verfügbar und zwar hier:
http://typo3.org/extensions/repository/view/dix_xingsync

Nachdem wir die Extension jetzt ca. 4 Wochen laufen haben, ist das Feedback äußerst positiv und die Zahl der Vollständigen Profile bei knapp 15 % von 600 Mitgliedern angekommen. Noch ein weiter weg bis zur Perfektion, die Seite sieht nach dem Login alleine durch die Mitgliederfotos aber wesentlich ansprechender aus als ständig auf die Dummy-Fotos zu schauen.

Nächste Schritte sind, das Thema immer wieder in Mailings anzusprechen (bei den Personen, die noch nicht vollständig sind,einfach in dem man noch einen Absatz mehr einfügt, wenn man gerade eh ein Mailing macht). Für neue Mitglieder ist der nächste Schritt eine Routine,die nach 2 und 4 Wochen dazu auffordert das Profil bitte zu aktualisieren.

Donnerstag, 14. Juni 2012

Felder doppelt im Backend - Werte unsichtbar

Ein simples Problem hat mich gestern wieder unnötig lang beschäftigt: Im Backend wurde beim editierender FE_USER Einträge das Feld für den Nachnamen zwar angezeigt,aber es war leer. Ein Blick in den Quellcode und die Datenbank zeigten schnell, dass der Wert durchaus da ist. Im Quellcode in einem unsichtbaren Feld, aber eben nicht im sichtbaren Input Field.
Am Ende war die Lösung simpel: Ich hatte das Feld doppelt im Backend, aber auf unterschiedlichen Tabs, so dass es mir nicht aufgefallen war. Zu lösen ist das dann, indem man im TCA-Array sucht, welche Werte beim Key
$TCA['fe_users']['types']['0']['showitem'] 
vorhanden sind. Bei mir stand dort zwei Mal das Feld last_name drin. Eins entfernt und schon ging's wieder...

UPDATE: Besser spät als nie eine Richtigstellung. Die Ursache war korrekt, aber die Lösung schrecklich falsch. Ich hatte in einer Extension in der ext_tables.php das Feld last_name in addToAllTCAtypes hinzugefügt, obwohl das Feld in der Extension gar nicht selbst erstellt wurde. Dort hab ich den Wert gelöscht und schon funktionierte alles wunderbar.

Donnerstag, 9. Februar 2012

Fe_Login erweitern: Username und Emailadresse zum Login verwenden


Wer kennt das nicht: Man hat eine Typo3 Seite mit Community und regelmäßig kommen Fragen per Email, weil der Username vergessen wurde? Wie schön wäre es da, wenn als Username auch die Emailadresse gehen würde. Für die Standardloginvariante fe_login wurde mein Featurerequest (http://forge.typo3.org/issues/24708) leider abgelehnt, allerdings mit dem Hinweis, wie man diese Funktionalität in einer eigenen Extension bereitstellt.

Für an diesem Feature interessiert sind, hier die Anleitung, wie man das hinbekommt.

Wichtig: Wenn man dieses Feature nutzen möchte, muss die Emailadresse einmalig (unique sein). Das kann entweder hart über die Erstellung eines Unique Index auf die fe_user Tabelle erfolgen, oder indem man im Backend und Frontend die die Werte bei Eingabe überprüft. 
Hier gibt es auch wieder 2 Varianten: Entweder sind die Emailadresse global einmalig oder nur lokal einmalig. Global bedeutet fe_users weit, lokal bedeutet, dass sie nur einmalig innerhalb einer Seite im Backend sind. Letzeres bedeutet, dass in der fe_users die Felder „pid“, „email“ und „deleted“ ZUSAMMEN  unique sein müssen.  

Ich beschreibe hier eine Variante mit Überprüfung bei Eingabe und lokaler Einmaligkeit.

Als erstes muss überprüft werden, ob es aktuell Emailadressen gibt, die doppelt vorkommen. Dabei hilft folgendes SQL:

 Select pid, email,count(1) as mycnt from fe_users where deleted = 0 group by pid,email having mycnt > 1Select pid, email,count(1) as mycnt from fe_users where deleted = 0 group by pid,email having mycnt > 1  

Diese Fälle müssen gelöst werden, bevor man die Loginvariante freischaltet.

Als nächstes brauchen wir für’s Backend die Möglichkeit sicherzustellen, dass die Emailadresse einmalig ist. Dazu müssen wir eine neue Extension erstellen oder in einer bestehenden Extension eine neue Evaluationsklasse hinzufügen. Letzteres geht in drei Schritten:
1. ext_tables.php erweitern, so dass das fe_users Feld „email“ evaluiert wird:
 $TCA['fe_users']['columns']['email']['config']['eval'] = 'trim, lower, tx_felogin_emaillogin_uniqueemail, required';  
Trim, lower und required sind bereits existente Evaluationsmethoden “felogin_emaillogin_uniqueemail”.


2. Die Methode felogin_emaillogin_uniqueemail “anmelden” in ext_localconf.php
 $TYPO3_CONF_VARS['SC_OPTIONS']['tce']['formevals']['tx_felogin_emaillogin_uniqueemail'] = 'EXT:felogin_emaillogin/Resources/Private/Classes/class.felogin_emaillogin_uniqueemaileval.php';  


3. Das php Script an den eben definierten Ort kopieren (alle Files weiter unten im  .t3x file zum Runterladen)

An dieser Stelle kann man schon mal testen, ob man im Backend 2 Nutzern die gleiche Emailadresse geben kann.

Jetzt kommt das Frontend dran. Auch hier muss in der ext_localconf.php eine Anpassung erfolgen. Es wird ein neuer Authorisierungsservice hinzugefügt:

 t3lib_extMgm::addService(  
      'felogin_emaillogin',  
      'auth',  
      'tx_felogin_emaillogin_authservice',  
      array(  
           'title' => 'FE-Authentification via eMail',  
           'description' => 'looks up given username in email field (to allow using both email and username) ',  
           'subtype' => 'getUserFE',  
           'available' => TRUE,  
           'priority' => 70, // must be higher than tx_sv_auth (50) and rsaauth (60) but lower than OpenID (75) if you want to use OpenID too  
           'quality' => 70,  
           'os' => '',  
           'exec' => '',  
           'classFile' => 'EXT:felogin_emaillogin/Resources/Private/Classes/class.felogin_emaillogin_authservice.php',  
           'className' => 'tx_felogin_emaillogin_authservice',  
      )  
 );  

Im nächsten Schritt muss die Klasse an den entsprechenden Ort kopiert werden (auch wieder im .t3x File)

Jetzt klappt das Login schon mit der Emailadresse. Allerdings sollte noch die Registrierung so angepasst werden, dass auch hier jede Emailadresse nur einmal vergeben werden kann. Dazu nutze ich die Erweiterung sr_feuser_register. Hier kann man mittels Typoscript die Anpassungen vornehmen:
 plugin.tx_srfeuserregister_pi1.edit.evalValues.email = email,uniqueLocal  
 plugin.tx_srfeuserregister_pi1.create.evalValues.email = email,uniqueLocal  

Jetzt fehlt noch das Loginformular selbst. Dort habe ich Quick and Dirty einfach die deutsche Übersetzung wie folgt angepasst.
 plugin.tx_felogin_pi1._LOCAL_LANG.de.username=Userame/Email

Alle Dateien findet ihr in folgender Extension zum herunterladen, für die ich keine Garantie übernehme, die aber funktioniert :-)

Mittwoch, 25. Januar 2012

Form: Einfaches Nachrichtensystem für Mitglieder mit Spamschutz

Das Problem: Es gibt eine Community und Personen sollen sich untereinander erreichen können, trotzdem sollen Emailadressen nicht im System angezeigt werden. Außerdem wollte ich kein weiteres großes Plugin und die Nachricht sollte direkt an die Emailadresse des anderen Nutzers gehen und den anderen Nutzer nicht dazu zwingen sich erst einloggen zu müssen.

Die Lösung: Eine Erweiterung der Form-Extension um 2 Postprocessoren: Der eine schickt Emails im Namen des eingeloggten Users an einen anderen User und sendet gleichzeitig eine Bestätigungsnachricht an den Sender (ohne aber die Emailadresse des Originalempfängers preis zu geben). Der 2. Postprocessor verhindert, dass ein User mehr als 1 Nachricht alle 60 Sekunden verschickt und baut gleich noch eine Statistik auf.

Im Typoscript sieht das Formular so aus: 
 prefix = tx_form  
 confirmation = 0  
 postProcessor {  
     1 = minimumdelaychecker  
     1 {  
        delay=60  
        errorPageID = 226  
     }  
      2 = memberMail  
      2 {  
           recipientEmailField = EmpfaengerID  
           senderEmail = sender@domain
           senderName = Absendername 
           subject = Direktnachricht von Domain Mitglied:   
           replyToField = absenderemail  
         messages {  
                success = Deine Nachricht wurde erfolgreich an das Mitglied gesendet. Du erhälst von der Email eine Kopie  
           }  
      }  
 }  
 10 = FIELDSET  
 10 {  
      legend {  
           value = Private Nachricht an ein anderes Mitglied senden  
      }  
      20 = TEXTLINE  
      20 {  
           name = absenderemail  
           readonly = readonly  
           value = {TSFE:fe_user|user|email}  
           label.value = Deine Emailadresse  
      }  
      30 = TEXTLINE  
      30 {  
           name = name  
           readonly = readonly  
           value = {TSFE:fe_user|user|first_name} {TSFE:fe_user|user|last_name}  
           label.value = Dein Name  
      }  
 32 = TEXTLINE  
 32 {  
   name = Empfänger  
 readonly=readonly  
 value = {gp:receiverName}  
 label.value = Empfänger  
 }  
      40 = TEXTAREA  
      40 {  
           cols = 50  
           rows = 10  
           name = Nachricht  
           label.value = Nachricht  
      }  
 41 = HIDDEN  
 41 {  
   name = EmpfaengerID  
  value = {gp:receiverID}  
 }  
      50 = SUBMIT  
      50 {  
           name = Submit  
           value = Abschicken  
      }  
 }  

Das Formular selbst ist sehr einfach gehalten. Wie man Variablen im Formular auswertet, habe ich in diesem Blogbeitrag erklärt.

Der "Minimumdelaychecker" ist ein Postprocessor, der eine kleine Statistik erstellt, wer wie viele Nachrichten verschickt hat und wann die letzte Nachricht geschickt wurde. Dazu werden in der fe_users-Tabelle die 2 Felder user_system_number_of_messages und user_system_last_message_timestamp erwartet. Diese Felder können natürlich auch umbenannt werden, dann muss aber auch der Postprocessor angepasst werden. Diesen Postprocessor gibt es hier zum runterladen. Wenn jemand innerhalb der im Typoscript definierten Zeit (Variable "delay") 2 Nachrichten schickt, wird er auf die Seite mit der in der ebenfalls in Typoscript (errorPageID) definierten Seite umgeleitet.

Der 2. Postprocessor ersetzt den Standard Mail Postprocessor. Runterladen könnt ihr ihn hier. Dieser Postprocessor setzt zum einen als Absender nicht die Emailadresse, die vorher im Formular angezeigt wurde, sondern diejenige, die für den eingeloggten User hinterlegt ist. So wird verhindert, dass jemand  die Daten im Form vor dem senden editiert. Das geht in HTML auch dann, wenn der die Felder - wie im Beispiel - gesperrt sind.

Was noch fehlt? Der Aufruf der des Formulars. Hier habe ich es mir einfach gemacht:. Aus einer anderen Extension heraus rufe ich die Seite, die das Formular enthält auf und übergebe per URL die ID (und den Namen des Empfängers):
?receiverID=272&receiverName=Dein%20Name

Ich hoffe, die Beschreibung ist ausführlich genug. Wenn nicht, fragt ruhig :)

Dienstag, 27. Dezember 2011

Form: Postprocessor um Kopie an Sender zu senden

Die Postprocessoren haben es mir gerade angetan. Liegt wohl daran, dass sie so schnell und schmutzig gehen ;)
In diesem Postprocessor geht es darum, wie man dem Absender auch eine Kopie zuschickt. In allen Fällen sollte man daran denken, dass so ein Formular auch als Mailschleuder genutzt werden könnte. Richtigen Schutz bietet da wohl nur ein Captcha, für eingeloggte User schreibe ich später meine Lösung dazu.
Dieser Postprocessor nimmt den Mail-Postprocessor und erweitert ihn sehr direkt. Dafür als erstes mal die Datei Mail.php kopieren und die Kopie in Mailtosendertoo.php umbenennen. Nun den Namen der Klasse in tx_form_System_Postprocessor_Mailtosendertoo ändern, bevor wir mit dem Anpassen der Funktion anfangen können.
In die Funktion process() kommt hinter den Aufruf
$this->send(); 
Noch eine neue Zeile, um die Funktion aufzurufen, in der die Kopie gesendet wird :
$this->sendCopyToSender();
Die neue Funktion sieht dann so aus:
 /**
 * Changes the To, Reply-To, Subject and sends message to the sender of this message
 * Function makes use of the same mailMessage object, thus should be used only after the original message is send* @return void
 */
protected function sendCopyToSender() {
 $this->mailMessage->setSubject("Die folgende Nachricht wurde eben in Deinem Namen via BiTS-Alumni.de verschickt");
 $this->mailMessage->setReplyTo($this->mailMessage->getSender());
 $this->mailMessage->setTo($this->typoScript['senderEmail']);
 }
 $this->send();
}
 Die Funktion tauscht entsprechend Subject, Empfänger, und ReplyTo der Email. Danach wird die Email gesendet.

Im Typoscript anstatt
 1 = Mail  
 1 {  
 …  
 }  
Jetzt:
 1 = Mailtosendertoo  
 1 {  
 …  
 }  
Der Rest bleibt gleich. Fertig!

Donnerstag, 22. Dezember 2011

Typoscript Variablen in der Form Extension auslesen

In Forum auf Typo3.net war es schon beschrieben, aber ich will hier noch mal kurz darauf eingehen, wie man die Stelle findet und warum die Lösung nicht immer zu nutzen ist.

Mit verschiedenen Extensions in Typo3 4.5 war es problemlos möglich Variablen mit Hilfe von Typoscript vorzubelegen:
{TSFE:fe_user|user|email}
Und ähnliche Werte konnte man öfter finden.
In der neuen Form ist das nicht mehr möglich. Laut diesem Issue (http://forge.typo3.org/issues/25931) im Forge liegt das an dem Securitykonzept der Extension. Die Idee der neuen Form ist offensichtlich, dass man auch Redakteuren erlaubt Forms zu erstellen. Diese wären dann in der Lage mittels Variablen eigenen Code einzuschleusen, vermute ich. Ich bin jetzt zu bequem diese Lücke gedanklich voll durchzudenken.

Für alle, bei denen es keine Redakteure gibt, hier die Quick & Dirty Lösung, mittels der man Variablen „erlauben“ kann. Alles was es braucht ist in sysext/form/Classes/ Domain/Factory/Typoscript.php in der Funktion reconstituteElement als erste Zeile folgendes:
 $arguments['value']= $this->getLocalConentObject()->insertData($arguments['value']);  

So kann dann mittels Typoscript zum Beispiel auf Werte des TSFE oder auch auf Werte, die per URL übergeben wurden, zugreifen.

 10 = Fieldset  
 10 {  
 10 = hidden  
 10.value = {TSFE:fe_user|user|email}  
 20 = hidden  
 20.value = {gp:receiverID}  
 }  


Die erste Zeile gibt die Emailadresse des eingeloggten Users zurück. Die zweite Zeile sucht in der URL nach dem Parameter receiverID und gibt deren Wert zurück. Also bspw. den Wert 23, wenn die URL so aussieht:  index.html?receiverID=23

Die Übergabe über die URL ist natürlich nicht frei von Risiken, weil jeder Nutzer hier natürlich die Werte ändern könnte. Deshalb sollte man sich genau überlegen, wann man mittels gp:… auf URL Übergaben vertraut.

Meine zugegebenermaßen sehr einfachen Tests ergaben, dass hier keine Risiken existieren. Weil jeglicher Code ja vorher bereits in HTML Sonderzeichen umgewandelt wird. Trotzdem sollte man diese Variante nur sparsam einsetzen. Wozu ich es  nutze, schreibe ich im nächsten Artikel.

Hintergrund
Wie aber findet man die Stelle in der Extension an der die Anpassung vorgenommen werden muss? In extBase Extensions kann man dazu eigentlich  in der ext_localconf.php anfangen und sich dann via Controller-Classes weiter hangeln. Für die Form Extension gilt das leider nicht ganz, weil der Einstieg etwas komplizierter ist, da die Form Extension das Standardform-Element und dessen Funktionen teilweise überschreibt.  Ein Blick in den Controller schadet aber auch nicht. Im Ordner form/Classes/Controller/ gibt es 2 Dateien: Form.php und Wizard.php. Form.php  klingt vielversprechend (wir wollen ja nicht den Backend Wizard bearbeiten).

In dieser Datei gibt es die Funktion cObjGetSingleExt, diese wird laut Kommentar 2 mal aufgerufen und trägt diesen Namen, weil der Typo3 Core das verlangt.
Am Ende ruft sie die Funktion execute() auf, die wiederrum die Funktion renderForm aufruft, wenn noch kein PostEvent stattgefunden hat (das wird in showForm() überprüft).
RenderForm ruft jetzt die Funktion buildModelFromTyposcript() des Objekts $this->typoscriptFactory auf. Klingt schon sehr nach dem, was wir wollen. Das Objekt $this->typoscriptFactory wird noch immer in Form.php erstellt und zwar mit der Zeile:

 t3lib_div::makeInstance('tx_form_Domain_Factory_Typoscript');  

Also suchen wir jetzt in Classes/Domain/Factory/Typoscript.php nach der Funktion “buildModelFromTyposcript“.
In dieser Funktion scheint die Methode createElement vielversprechend, zumal sie auch die Variable $typoscript enthält, in der die Werte, die wir im Formwizard eingegeben haben, enthalten sind. Das findet man heraus, indem man sich mittels der Extension debugster oder der php Funktion print_r() die Werte der Variable ausgeben lässt. In dem $typoscript Array sind wir daran interessiert, dass die Werte in 'value' umgeformt werden. An der Stelle ist die Extension etwas komplexer, weil reconstituteElement mehrfach rekursiv durchlaufen wird. Da die Funktion insertData() aber den Eingabewert unverändert zurück gibt, wenn es keine Variable {TSFE....} ist, kann einfach am Anfang der Funktion die besagte Zeile:
$arguments['value']= $this->getLocalConentObject()->insertData($arguments['value']);
Stehen.

Eine gute Beschreibung für extBase und Fluid habe ich jetzt auch noch bei Mittwald gefunden: http://www.mittwald.de/fileadmin/pdf/extbase_fluid.pdf
Ist zwar etwas älter, aber immer noch aktuell.