Guten Morgen,
nachdem ich immer im Forum nachgefragt habe wegen der Extension dynaflex und keine Antwort bekommen habe, habe ich mich selber aufgemacht, die Tiefen dieser Extension zu verstehen.
Nun, es ist mir gelungen.
Ich richte dieses Tutorial an Extensionentwickler, vorwiegend an solche, die ihre Extensions mit dem Kickstarter erstellen.
Auch werde ich hier nur auf die Grundlegenden Sachen eingehen, Hooks habe ich persönlich noch nie benutzt und werde sie hier auch nicht erläutern.
-Warum sollte man dynaflex benutzen?
Nun, es gibt sicher einige Dinge, die man mit reinen Flexforms nicht machen kann, z.B. zur Laufzeit eine variable Anzahl an Flexformfeldern oder sheets zu realisieren.
Genau an diesem Punkt setzt dynaflex an.
Ein Beispiel: Wir erstellen eine Quizextension und wollen in einem Feld eingeben wieviele Antworten es geben soll für eine Frage. Abhängig von diesem Feld lassen wir also weiter Flexformfelder rendern.
Hier kurz wie ich vorgehen werde:
1. Installation
2. Einbindung
2.1 Die Klassen-Datei
2.2 die tca.php
2.3 die localconf.php
3. Benutzung
3.1 Werte aus der Datenbank holen
3.2 Werte verarbeiten
3.3 Werte in der Datenbank speichern.
-----
1. Installation
Die Installation sollte wohl das einfachste sein, an diesem gesamten Tutorial.
Einfach die Extension "dynaflex" von typo3.org ziehen und installieren, sie bildet unsere Grundlage.
2. Einbindung
Die Einbindung ist etwas kniffelig, doch seit der version 1.7 sehr verbessert worden.
2.1 Die Klassen-Datei
Die Klassen-Datei (ich weiß, doofer Name) ist die Datei in deiner Extension, die dynaflex sagt, was sie wann machen soll.
Eine weniger gute Beispieldatei findet man bei der Documentation von dynaflex, ich nehme nun aber meine, sie sieht ungefähr so aus:
<?php
/**
* This class provides a set of configs for DynaFlex. It contains a complete DCA that configures
* how an existing flexform is modified by DynaFlex.
* It also contains a simple example for a hook, that modfies the DCA.
*/
class tx_es_abi09poll {
var $DCA = array (
0 => array (
'path' => 'tx_esabi09poll_poll/columns/flexdata/config/ds/default',
'modifications' => array (
array (
'method' => 'add',
'type' => 'sheets',
'source' => 'field',
'source_config' => array (
'table' => 'tx_esabi09poll_poll',
'db_field' => 'answers',
),
'sheet_config' => array (
'label' => 'Answer ###SINDEX###',
'name' => 'sheet',
'fields' => array (
array (
'label' => 'LLL:EXT:es_abi09poll/locallang_db.xml:tx_es_abi09poll_poll.yanswer',
'name' => 'answer',
'config' => array (
'type' => 'input',
'size' => '30',
)
),
),
),
)
)
)
);
var $cleanUpField = 'flexdata';
}
?>
In dieser Klasse habe ich definiert, dass abhängig von dem Feld "answers" in der Tabelle "tx_esabi09poll_poll" sheets gerendert werden sollen.
Also wenn "answers" also den wert 3 hat, rendert er 3 sheets mit je einem inputfeld.
Die verschiedenen Typen kann man in der Documentation von dynaflex nachlesen, ich glaube unter HOW-TO http://typo3.org/documentation/document-library/extension-manuals/dynaflex/1.11.0/view/1/3/
wichtig ist bei meinem Skript, dass das feld, was ich auslese und als Bedingung formuliere, dass das auch existiert.
Nachdem wir nun unsre Klassen-Datei geschrieben haben und unter einem aussagekräftigen namen gespeichert haben, in meinem Fall einfach "class_esabi09poll.php" wenden wir uns der tca.php zu.
2.2 Die tca.php
Die tca.php liegt jeder Extension bei, sie sorgt dafür, dass wir im Backend auch was eingeben könne, wenn wir einen neuen Datensatz anlegen.
Meine tca.php sieht nun so aus:
<?php
if (!defined ('TYPO3_MODE')) die ('Access denied.');
$TCA["tx_esabi09poll_poll"] = array (
"ctrl" => $TCA["tx_esabi09poll_poll"]["ctrl"],
"interface" => array (
"showRecordFieldList" => "hidden,starttime,endtime,titles,description,answers,checks,flexdata,user,userg,alcomment,start,showpolltime,
adminuser,adminuserg,showpolltimeend"
),
"feInterface" => $TCA["tx_esabi09poll_poll"]["feInterface"],
"columns" => array (
'hidden' => array (
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
'config' => array (
'type' => 'check',
'default' => '0'
)
),
'starttime' => array (
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.starttime',
'config' => array (
'type' => 'input',
'size' => '8',
'max' => '20',
'eval' => 'date',
'default' => '0',
'checkbox' => '0'
)
),
'endtime' => array (
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.endtime',
'config' => array (
'type' => 'input',
'size' => '8',
'max' => '20',
'eval' => 'date',
'checkbox' => '0',
'default' => '0',
'range' => array (
'upper' => mktime(0, 0, 0, 12, 31, 2020),
'lower' => mktime(0, 0, 0, date('m')-1, date('d'), date('Y'))
)
)
),
"titles" => Array (
"exclude" => 0,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.titles",
"config" => Array (
"type" => "input",
"size" => "30",
)
),
"description" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.description",
"config" => Array (
"type" => "text",
"cols" => "30",
"rows" => "5",
)
),
"answers" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.answers",
"config" => Array (
"type" => "input",
"size" => "10",
"max" => "2",
"eval" => "required",
)
),
"checks" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.checks",
"config" => Array (
"type" => "check",
)
),
"flexdata" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.flexdata",
"config" => Array (
'type' => 'flex',
'ds' => array (
'default' => '<t3datastructure>' .
' <meta />' .
' <langdisable>1</langdisable>' .
' </meta>' .
' <root>' .
' <type>array</type>' .
' <el>' .
' <lol>mm</lol>' .
' </el>' .
' </root>' .
'</t3datastructure>'
),
)
),
"user" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.user",
"config" => Array (
"type" => "select",
"foreign_table" => "fe_users",
"foreign_table_where" => "ORDER BY fe_users.uid",
"size" => 6,
"minitems" => 0,
"maxitems" => 100,
)
),
"userg" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.userg",
"config" => Array (
"type" => "select",
"foreign_table" => "fe_groups",
"foreign_table_where" => "ORDER BY fe_groups.uid",
"size" => 7,
"minitems" => 0,
"maxitems" => 100,
)
),
"alcomment" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.alcomment",
"config" => Array (
"type" => "check",
)
),
"start" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.start",
"config" => Array (
"type" => "check",
)
),
"showpolltime" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.showpolltime",
"config" => Array (
"type" => "input",
"size" => "12",
"max" => "20",
"eval" => "datetime",
"checkbox" => "0",
"default" => "0"
)
),
"adminuser" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.adminuser",
"config" => Array (
"type" => "select",
"foreign_table" => "fe_users",
"foreign_table_where" => "ORDER BY fe_users.uid",
"size" => 7,
"minitems" => 0,
"maxitems" => 100,
)
),
"adminuserg" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.adminuserg",
"config" => Array (
"type" => "select",
"foreign_table" => "fe_groups",
"foreign_table_where" => "ORDER BY fe_groups.uid",
"size" => 7,
"minitems" => 0,
"maxitems" => 100,
)
),
"showpolltimeend" => Array (
"exclude" => 1,
"label" => "LLL:EXT:es_abi09poll/locallang_db.xml:tx_esabi09poll_poll.showpolltimeend",
"config" => Array (
"type" => "input",
"size" => "12",
"max" => "20",
"eval" => "datetime",
"checkbox" => "0",
"default" => "0"
)
),
),
"types" => array (
"0" => array("showitem" => "hidden;;1;;1-1-1, titles, description;;;richtext[cut|copy|paste|formatblock|textcolor|bold|italic|underline|left|center|right|orderedlist|unorderedlist
|outdent|indent|link|table|image|line|chMode]:rte_transform[mode=ts_css], answers, checks, flexdata, user, userg, alcomment, start, showpolltime, adminuser, adminuserg, showpolltimeend")
),
"palettes" => array (
"1" => array("showitem" => "starttime, endtime")
)
);
?>
Unser Augenmerk wollen wir auf den Eintrag "answers" und "flexdata" lenken.
Während "answers" ein ganz normales inputfeld ist, ist "flexdata" sehr viel interessanter.
Als type hat dieses Feld nicht Input oder so, sondern flex, das ist wichtig, auch sieht man einen Unterschied bei ds, es ist ein Array, was unsere XML-Struktur enthält, die später erstzt wird. Die XML-Struktur müsst ihr manuell eintragen doch wenn ihr das getan habt seid ihr schon fast fertig.
GANZ WICHTIG: Wichtig ist, das zwischen den lol-tags, die bei mir die dummy-tags sind, etwas steht. Das steht nicht in der Documentation, aber ohne funktioniert es nicht.
Ich habe mir auch hier stunden-, tagelang die Zähne ausgebissen und in die Doku geguckt, aber dort steht es nicht. Dort muss irgendwas stehen.
2.3 die localconf.php
Wir müssen unsere Klassen-Datei nur noch registrieren und Typo3 sagen, dass er unsere Datei mit dynaflex einbinden soll.
Wir ergänzen in unserer localconf.php folgende zeilen:
$GLOBALS['T3_VAR']['ext']['dynaflex']['tx_esabi09poll_poll'][] = 'EXT:es_abi09poll/class.es_abi09poll.php:tx_es_abi09poll';
Hier müsst ihr anstatt tx_esabi09poll_poll eure Tabelle eintragen, bei der die Klassen-datei aktiv sein soll. Hinter das = kommt der Pfad zu eurer Klassen-Datei, in meinem Fall "class.es_abi09poll.php" und mit einem Doppelpunkt gefolgt die Klasse, die in eurer Klassen_datei die Funktionen auslöst, bei mir also tx_es_abi09poll.
Wenn ihr nun testet, müsste alles funktionieren, jedenfalls bei meinem Beispiel, das müsste dann so aussehen:
Bild: es-abi09.de/…/beispiel1.jpg
Sollte nicht sofort ein Ergebnis kommen, einfach nochmal speichern...
Nacher geht es weiter mit Punkt 3. der nichr das schwerste ist, aber auch nicht so einfach.
Gute Nacht erstmal
@just2be Entschuldige die Rechtschreibfehler und die nicht ganz optimale Formatierung.