A word or two about multiple select list in user registration form

When extending user registration form (sr_feuser_register) you might need list of check-boxes or multiple select list. So after extending database and adding fields to fe_users table you’ll need to edit ext_tables.php in typo3conf/ext/sr_feuser_register folder and create new entries for this list:


$tempColumns = array(
"checkboxlist" => Array (
"exclude" => 1,
"label" => "LLL:EXT:sl_timetracking/locallang_db.xml:fe_users.checkboxlist",
"config" => Array (
"type" => "check",
'items' => Array (
Array('value1', 1), // these are actual text values that will be displayed alongside
Array('value2', 2),
Array('value3', 3),
Array('value4', 4),
Array('value5', 5),
Array('value6', 6),
Array('value7', 7),
// ...
),
)
),
);
t3lib_div::loadTCA("fe_users");
t3lib_extMgm::addTCAcolumns("fe_users",$tempColumns,6);

to display this list edit template used by sr_feuser_register e.g. typo3conf/ext/sr_feuser_register/pi1/tx_srfeuserregister_pi1_css_tmpl.html.


<div class="checkboxlist">
###TCA_INPUT_checkboxlist###
</div>

These values once checked will be stored in database table fe_users, in our case column checkboxlist. Type of database field should be integer e.g.:


CREATE TABLE fe_users (
checkboxlist int(11) DEFAULT '0' NOT NULL
);

values are stored as bitmap masks so it won’t make much sense looking at raw data. Nifty trick to decode them is to cross join a simple table of numbers, in this case named ‘tNum‘ with one column named ‘nr‘. Cross join will cause each row (number in our case) from one table to be joined to each row of another and then we just pick rows that have bitwise mask on, e.g. where (listofbits & 2 << tNum.nr) > 0.

Sample code:


SELECT
uid,
pid,
FROM_UNIXTIME(tstamp) as tstamp, -- convert timestamp to humanly readable format
username,
usergroup,
CONVERT(GROUP_CONCAT(tNum.nr + 1), CHAR(256)) as checkboxlist, -- this will concatenate list of ID's in format '1, 2, 3, 4 ...'
disable,
name,
first_name,
middle_name,
last_name,
email
-- etc
FROM
fe_users
CROSS JOIN tNum
WHERE
tNum.nr < 64
AND (checkboxlist & 2 << tNum.nr) > 0
GROUP BY
uid

a step further would be to create new lookup table with actual id-value pairs that could be joined against query above and concatenate actual string values instead of id values.
This can be queried directly in mysql console or you can use some plugin to export data in csv format, e.g. Alat Systems sql to csv exporter (assql2csv).
Worth mentioning, if you plan to have more than 32 values you’ll need to change field type from int to bigint or something otherwise you’ll experience weird behaviour selecting high [checkbox] values.