Schnellnavigation:

Kategorien

« April 2024»
S M T W T F S
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        

Letzte Nachrichten

DSGVO
26.05.2018 18:39
Trackingtools und Datenschutzerklärung
14.03.2014 23:07
1:n und n:1 Relationen in Extbase
06.12.2013 12:04
Erste Abmahnungen wegen Google Analytics
04.10.2013 12:11

Kopieren Sie diesen Link in Ihren RSS-Reader

RSS 0.91Nachrichten
RSS 2.0Nachrichten

In eigener Sache

Peter Linzenkirchner, Lisardo EDV Beratung in Augsburg. Freelance und Partner für Design- und Webagenturen in Augsburg und München. Pixelgenaue Templates, valides HTML, barrierearm. TYPO3-Projekte, Extension-Programmierung und mehr ... 

Zur Zeit wird gefiltert nach: Extensions
Filter zurücksetzen

Im Mailformular soll ein Dropdownmenü angeboten werden, mit dessen Hilfe die Zieladresse ausgewählt werden kann. Umsetzung mit der Extension Mailformplus. 

Im Template:

  1. <select name="to">
  2.     <option value="eins"###checked_to_eins###>Eins</option>
  3.     <option value="zwei"###checked_to_zwei###>Zwei</option>
  4.     <option value="drei"###checked_to_drei###>Drei</option>
  5. </select>

Im TypoScript:

  1. plugin.tx_thmailformplus_pi1.default.contact_to=TEXT
  2. plugin.tx_thmailformplus_pi1.default.contact_to.data=GPvar:to
  3. plugin.tx_thmailformplus_pi1.default.contact_to.wrap= |
  4.  
  5. [globalVar=GP:to=eins]
  6.     plugin.tx_thmailformplus_pi1.default.email_to=eins@e-mail.de
  7. [end]
  8. [globalVar=GP:to=zwei]
  9.     plugin.tx_thmailformplus_pi1.default.email_to=zwei@e-mail.de
  10. [end]
  11. [globalVar=GP:to=drei]
  12.     plugin.tx_thmailformplus_pi1.default.email_to=drei@e-mail.de
  13. [end]

Quelle: Deutschsprachige Mailingliste; Beitrag von Fabian Seltmann.

[Update]

Bei Powermail gibt es einen Eintrag hierzu direkt im Manual

 

In eigenen Extensions gibt es eine einfache Möglichkeit zu verhindern, dass beim Einbinden von Dateien für den Download – zum Beispiel aus einem Unterordner von fileadmin – diese Dateien nochmals in den /uploads/-Ordner kopiert werden. Dazu muss in der tca.php der internal_type von file auf file_refence umgestellt werden:

  1. 'file'=> array (       
  2.     'exclude'=>0,    
  3.     'label'=>'LLL:EXT:MyExtension/locallang_db.xml:tx_myExtension.file',       
  4.     'config'=> array (
  5.         'type'=>'group',
  6.         ## hier umstellen von file auf file_refence: ######
  7.         'internal_type'=>'file_reference',
  8.         'allowed'=>'',   
  9.         'disallowed'=>'php,php3',  
  10.         'max_size'=>$GLOBALS['TYPO3_CONF_VARS']['BE']['maxFileSize'],  
  11.         'uploadfolder'=>'uploads/myExtension',
  12.         'size'=>1,   
  13.         'minitems'=>0,
  14.         'maxitems'=>1,
  15.     )
  16. ),

Dadurch wird nicht mehr der reine Dateiname in der Datenbank gespeichert sondern der komplette Pfad auf die Datei. Natürlich muss das bei der weiteren Verarbeitung der Datei auch entsprechend berücksichtigt werden.

Weiterführende Links

 

Datenbankabfragen sollten in Extensions nie über die normalen SQL-Befehle erfolgen. Gründe:

  • die globale Datenbank-Abstraktionsschicht DBAL wird eingbezogen; heisst, die Extension läuft automatisch auch mit anderen Datenbanken als MySQL
  • die Verbindung zur Datenbank muss nicht eigens erstellt und beendet werden
  • die INSERT-Queries führen automatisch ein FullQuote durch (die Mindest-Absicherung gegen SQL-Injection)
  • die verfügbaren Befehle sind zum Teil einfach bequem …

Funktionen aufrufen

Die Klassen müssen nicht initialisiert werden, es reicht, sie über die GLOBALS aufzurufen:

  1. $GLOBALS['TYPO3_DB']->exec_SELECTquery( .... )

Absicherung gegen SQL-Injection

Alle Eingaben, die vom Besucher der Website kommen (also über GET oder POST) müssen vorher abgesichert werden. Das betrifft vor allem die Befehle zum Einfügen in die Datenbank, ausserdem aber auch die Übernahme von Benutzerdaten in die where-Abschnitte der SQL-Abfragen. Auch hier sollten die Typo3-Funktionen benutzt werden, damit die Quotierung für jede Datenbank passend erfolgt. Folgende Funktionen stehen zur Verfügung:

  1. # Quotieren von Zeichenketten
  2. $GLOBALS['TYPO3_DB']->fullQuoteStr($str,$table);

Parameter

  • string: Zeichenkette, die quotiert werden soll
  • string: Tabellenname (daraus entnimmt DBAL die korrekte Quotierungstechnik)

  1. # Quotieren von eindimensionalen Arrays:
  2. $GLOBALS['TYPO3_DB']->fullQuoteArray($arr,$table,$noQuote=FALSE);

Parameter

  • array: eindimensionales oder assoziatives Array mit den Daten
  • string: Tabellenname (daraus entnimmt DBAL die korrekte Quotierungstechnik)
  • string/array: Liste oder Array von Schlüsseln, die nicht quotiert werden sollen. Nur bei assoziativen Datenarrays anwenden!

  1. # kommaseparierte Listen zu Integerlisten umwandeln (über intval() )
  2. $GLOBALS['TYPO3_DB']->cleanIntList($list)

Parameter

  • string: kommaseparierte Liste mit Werten, die Integer sein sollen

  1. # Arraywerte zu Integer umwandeln (über intval() )
  2. $GLOBALS['TYPO3_DB']->cleanIntArray($arr)

Parameter

  • array: Array mit Werten, die Integer sein sollen

Datenbankabfragen

  1. # SELECT-Abfrage
  2. $GLOBALS['TYPO3_DB']->exec_SELECTquery(
  3.       $select_fields,
  4.       $from_table,
  5.       $where_clause,
  6.       $groupBy='',
  7.       $orderBy='',
  8.       $limit=''
  9. )

Parameter

  • string: Liste der Felder oder * für alle Felder
  • string: Tabelle(n). Es gelten die üblichen SQL-Regeln für Aliase
  • string: WHERE-Klausel. Wie in SQL üblich. ACHTUNG: man muss alle GET / POST-Werte hier selbst qotieren! Verwenden Sie $this->fullQuoteStr() – siehe oben. Hier nicht Befehle wie GROUP oder LIMIT verwenden.
  • string: Optionale GROUP-Anweisung
  • string: Optionale ORDER BY-Anweisung
  • string: Optionale LIMIT-Anweisung.

  1. # INSERT-Abfrage
  2. $GLOBALS['TYPO3_DB']->exec_INSERTquery    (
  3.       $table,
  4.       $fields_values,
  5.       $no_quote_fields=FALSE
  6. )

Parameter

  • string: Tabelle
  • array: Feldwerte als array mit key=>value Paaren. Die Werte werden intern quotiert. Typischerweise verwenden Sie ein Array “$insertFields” mit ‘fieldname’=>‘value’ und übergeben es als Argument.
  • string/array: Liste oder Array von Schlüsseln, die nicht quotiert werden sollen; siehe ober bei fullQuoteArray()

  1. # UPDATE-Abfrage
  2. $GLOBALS['TYPO3_DB']->exec_UPDATEquery    (
  3.       $table,
  4.       $where,
  5.       $fields_values,
  6.       $no_quote_fields=FALSE
  7. )

Parameter

  • string: Tabelle
  • string: WHERE-Anweisung, typischerweise “uid=xx”. Achtung: Sie müssen alle GET- oder POST-Parameter hier selbst quoten – siehe oben.
  • array: Feldwerte als array mit key=>value Paaren. Die Werte werden intern quotiert. Typischerweise verwenden Sie ein Array “$insertFields” mit ‘fieldname’=>‘value’ und übergeben es als Argument.
  • string/array: Liste oder Array von Schlüsseln, die nicht quotiert werden sollen; siehe ober bei fullQuoteArray()

  1. # DELETE-Abfrage
  2. $GLOBALS['TYPO3_DB']->exec_DELETEquery($table,$where)

Parameter

  • string Tabelle
  • string WHERE-Anweisung, typischerweise “uid=xx”. Achtung: Sie müssen alle GET- oder POST-Parameter hier selbst quoten – siehe oben.

Spezielle Datenbank-Anweisungen

Die folgende Funktion eignet sich hervorragend zum Auswerten einer n-n Datenverbindung, wie sie zum Beispiel bei der Verwendung von Kategorien anfällt. Bedingung ist allerdings, dass die Verbindung mit einer m_m-Tabelle erfolgt und nicht über ein einzelnes Feld mit kommaseparierter ID-Liste.

  1. # SELECT relational
  2. $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query(
  3.       $select,
  4.       $local_table,
  5.       $mm_table,
  6.       $foreign_table,
  7.       $whereClause='',
  8.       $groupBy='',
  9.       $orderBy='',
  10.       $limit=''
  11. )

Parameter

  • string: Liste der Felder oder * für alle Felder
  • string: Name der lokalen Tabelle
  • string: Name der Relationalen m_m-Tabelle
  • string: Name der fremden, verknüpften Tabelle
  • string: WHERE-Klausel. Wie in SQL üblich. ACHTUNG: man muss alle GET / POST-Werte hier selbst qotieren! Verwenden Sie $this->fullQuoteStr() – siehe oben. Hier nicht Befehle wie GROUP oder LIMIT verwenden. Es muss ein ‘ AND ‘ eingefügt werden.
  • string: Optionale GROUP-Anweisung
  • string: Optionale ORDER BY-Anweisung
  • string: Optionale LIMIT-Anweisung.

Achtung: Viele Feldnamen in Typo3 sind identisch (uid, pid, hidden etc.). Das kann bei der Auswertung zu Problemen führen, da die Felder nicht eindeutig sind! Es ist deshalb sinnvoll, imm select- und für die Tabellennamen mit Aliasen zu arbeiten:

  1. $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query(
  2.       'a.uid as a_uid, b.uid as b_uid',
  3.       'tabelle_1 a',
  4.       'tabelle_m_m',
  5.       'tabelle_2 b',
  6.       $whereClause='',
  7.       $groupBy='',
  8.       $orderBy='',
  9.       $limit=''
  10. )

Ein ganz besondere Funktion ist listQuery(): Sie ermöglicht eine einfache Behandlung von relationalen Verknüpfungen, die nicht über eine dritte m_m-Tabelle laufen sondern über Felder mit kommaseparierten Listen.

  1. $GLOBALS['TYPO3_DB']->listQuery  (
  2.       $field,
  3.       $value,
  4.       $table
  5. )

Das Problem derartiger Verknüpfungen ist, dass die Abfrage über LIKE laufen muss, und dabei zusätzlich unterschieden werden muss, auf welcher Seite des gewünschten Wertes das Komma folgt. Kern der Funktion ist diese Zeile:

  1. $where='('.$field.' LIKE \'%,'.$command.',%\' OR '.$field.' LIKE \''.$command.',%\' OR '.$field.' LIKE \'%,'.$command.'\' OR '.$field.'=\''.$command.'\')';

Parameter

  • string: Feldname, der die kommaseparierte Liste enthält
  • string: Wert, der gefunden werden soll
  • string: Tabelle, in der gesucht wird (für die korrekte Behandlung durch DBAL)

In die gleiche Richtung geht die folgende Funktion, die Srings für die LIKE-Abfrage korrekt für DBAL umsetzt:

  1. $GLOBALS['TYPO3_DB']->escapeStrForLike($str,$table)

WICHTIG: Es gibt eine hervorragende Abkürzung, um die wichtigen einschränkenden Felder in der WHERE-Abfrage automatisch einzuschließen: hidden, deleted, von/bis, Frontenduser etc. Die WHERE-Abrage muss einfach damit erweitert werden:

  1. $this->cObj->enableFields('datenbank')

Also zum Beispiel in der exec_SelectQuery:

  1. # SELECT-Abfrage
  2. $GLOBALS['TYPO3_DB']->exec_SELECTquery(
  3.       $select_fields,
  4.       $from_table,
  5.       $where_clause.$this->cObj->enableFields('datenbank'),
  6.       $groupBy='',
  7.       $orderBy='',
  8.       $limit=''
  9. )

Noch drei weitere Funktionen werden öfter gebraucht:

  1. # Liefert eine Integer zurück mit der Anzahl der betroffenen Datenzeilen, z. B. bei INSERT oder UPDATE
  2. $GLOBALS['TYPO3_DB']->sql_affected_rows( )

  1. # Liefert eine Integer, die uid des zuletzt eingefügten Datensatzes (über INSERT)
  2. $GLOBALS['TYPO3_DB']->sql_insert_id  ( )

  1. # Liefert eine Integer, mit der Anzahl der gefundenen Datensätze
  2. $GLOBALS['TYPO3_DB']->t3lib_DB.sql_num_rows($res)

Parameter

  • pointer: Der Resultpointer einer vorher erfolgten SELECT-Abfrage.

Weiterführende Links

 

Unsicher Programmierung in Extensions ist eine der größten Gefahren bezüglich der Sicherheit einer TYPO3-Installation. Während der Core regelmäßig geprüft wird und Sicherheitsmängel zügig behoben werden, gilt das für viele Extensions nicht. Die wichtigsten EXtensions werden einem regelmäßigen Audit unterworfen, aber bei weitem nicht alle, dazu sind es zuviele. Und Extensions, die ihren Weg nie ins TER finden, werden natürlich auch nie geprüft. 

TYPO3-API für Datenbank-Zugriffe

Generell sollte die TYPO3-API für alle Datenbankzugriffe verwendet werden. Diese sorgt unter anderem für das nötige Quotieren der Eingaben.

Wichtig sind hier vor allem diese beiden Methoden: 

  1. $GLOBALS['TYPO3_DB']->fullQuoteStr($str,$table)
  2. $GLOBALS['TYPO3_DB']->fullQuoteArray($arr,$table,$noQuote=FALSE);

Näheres im Abschnitt Datenbankabfragen.

Einige Methoden der Klasse t3lib_div

Die Methoden der Klassse t3lib_div werden statisch aufgerufen.

  1. // Entfernt gefährlichen Code, Rückgabewert der bereinigte String
  2. t3lib_div::removeXSS($string)
  3. // Gültige E-Mail: Rüpckgabewert true/false
  4. t3lib_div::validEmail($email)
  5. // Testet auf gültige URL, Rückgabewert tru/false
  6. t3lib_div::isValidUrl($sanitizedUrl)

Übergabeparameter

Alle GET- und POST-Variablen sollten über die entsprechenden Funktionen der TYPO3-API angesprochen werden:

  1. // Übernahme der Parameter mit Namensindex der Extension:
  2. $this->piVars['parameter'];
  3. // Wenn das nicht möglich ist, dann so:
  4. t3lib_div::_GP($var);
  5. // oder getrennt nach GET / POST
  6. t3lib_div::_GET($var);
  7. t3lib_div::_POST($var);

Wichtige PHP-Befehle

  1. // Kürzen eines UTF-8-Strings
  2. mb_substr($string,0,50);
  3. // Länge eines UTF-8-Strings prüfen
  4. mb_strlen($string);
  5. // Integer erzwingen
  6. intval($this->piVars['wert']);
  7. // Alle Tags aus einem String entfernen:
  8. strip_tags($string);
  9. // einige Tags erlauben (Achtung: die erlaubten Tags können Parameter enthalten!)
  10. strip_tags($this->piVars['wert'],'<em><i>')
  11. // Tags in Entities umwandeln:
  12. htmlspecialchars($this->piVars['wert'])

Datenfilter – neue Möglichkeiten mit PHP5

Diese Datenfilter werden in TYPO3 seit einigen Versionen ebenfalls eingesetzt. Einige kleine Anwendungsbeispiele:

  1. // Test auf korrekte URL
  2. $url='http://www.lisardo.de';
  3. if ( @filter_var($url,FILTER_VALIDATE_URL) ===FALSE){
  4.     echo$url.' falsch';
  5. }else{
  6.     echo$url.' korrekt';
  7. }
  8. // oder ein Test auf korrekte E-Mail:
  9. if(!filter_var("someone@lisardo...de",FILTER_VALIDATE_EMAIL)){
  10.       echo("E-mail falsch");
  11. }
  12. else{
  13.       echo("E-mail korrekt");
  14. }
  15. // Oder ein Test ob eine POST-Variable namens "mail" eine gültige E-Mail enthält:
  16. if (!filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL)){
  17.       echo"E-Mail ist falsch";
  18. }
  19. else{
  20.       echo"E-Mail korrekt";
  21. }

Ein schöner Überblick über alle Filter mit Beispielcode ist bei w3schools, PHP Filter Functions zu finden. eine genaue Erläuterung im offiziellen PHP-Manual, Datenfilterung

Weiterführende Links

 

 

 

 

 

Accordion mit rgaccordion von Georg Ringer

Eine sehr leistungsfähige Extension für vielseitigen Einsatz. Man kann damit:

  • alle Contentelemente einer Seite in ein Accordion zusammenfassen
  • ausgewählte Contentelemente zu einem Accordion zusammenfassen
  • ein Menü mit Accordion erstellen sowie
  • die Inhalte vieler Extensions in ein Accordion packen.

Die Dokumentation ist gut und umfassend, muss allerdings genau gelesen werden, sonst klappt es nicht … Dort sind auch Hinweise zu finden, wie die Einbindung für normale Templates und für TemplaVoila funktioniert.

rgaccordion II für einzelne Contentelemente

Die Extension besteht aus zwei Teilen: rgaccordion I erlaubt das Auswählen einzelner Inhaltselemente für das Accordion im Inhaltselement selbst, während rgaccordion II dazu gedacht ist, alle Inhaltselemente einer Seite in ein Accordion zusammenzufassen. Leider unterscheiden sich beide Extensions aber noch in einer Eigenschaft: rgaccordion II öffnet standardmäßig immer nur einen Tab, während rgaccordion I jeden Tab unabhängig öffnet oder schließt. Damit sind bei rgaccordion I immer mehrere Tabs geöffnet. Wenn immer nur ein Tab geöffnet sein soll und gleichzeitig der Anwender selbst zu bestimmen kann, welche Inhalte in das Accordion aufgenommen werden sollen, muss rgaccordion II zusätzlich konfiguriert werden:

  1. plugin.tx_rgaccordion2 {
  2.     stdWrap.outerWrap= <divclass="rgaccord2-content">|</div>
  3.     stdWrap.outerWrap.if.isTrue.field=tx_rgaccordion_accordion
  4.     stdWrap.outerWrap.stdWrap.prepend=  TEXT
  5.     stdWrap.outerWrap.stdWrap.prepend.field=header
  6.     stdWrap.outerWrap.stdWrap.prepend.ifEmpty=Test
  7.     stdWrap.outerWrap.stdWrap.prepend.wrap= <h3class="rgaccord2-toggle">|</h3>
  8.     stdWrap.outerWrap.stdWrap.prepend.if.isTrue.field=tx_rgaccordion_accordion
  9. }

Achtung: der Code muss vor dem Zuweisen des Plugins eingefügt werden.

In rgaccordion II beim Laden einen bestimmten Tab öffnen

Um beim Laden der Seite einen bestimmten Tab zu öffnen (oder auch keinen) muss das JavaScript geändert werden:

  1. window.addEvent('domready', function(){
  2. varaccordion= newAccordion('h3.rgaccord2-toggle','div.rgaccord2-content',{
  3.     alwaysHide:true,
  4.     opacity:false,
  5.     # hier kommt die Erweiterung:
  6.     display:-1,
  7.     # Ende der Erweiterung
  8.     onActive: function(toggler,element){
  9.         toggler.addClass('act');
  10.     },
  11.  
  12.     onBackground: function(toggler,element){
  13.         toggler.removeClass('act');    
  14.     }
  15. }, $('rgaccord2-nest'));   
  16.  
  17. });

display:-1 schließt alle Tabs; display:0 öffnet den ersten, danach durchnummerieren.

Damit nach dieser Änderung das Updaten der Extension noch möglich ist, sollte das JavaScript genauso wie dasCSS in fileadmin verschoben werden.

  1. page.includeCSS.file57=fileadmin/css/rgaccordion2.css
  2. page.includeJS.file51 =EXT:t3mootools/res/mootoolsv1.11.js
  3. page.includeJS.file52 =fileadmin/js/rgaccordion2.js
  4.  

Tipp: Der Eintrag »EXT:t3mootools/res/mootoolsv1.11.js« ist abhängig von der verwendeten Version von T3-Mootools. Muss man ggf. nachschlagen; der Eintrag in der Dokumentation von rgaccordion ist wahrscheinlich veraltet.

Weiterführende Links