I need to show a selection of days in an event in the frontend:
in my TCA I set the field like this:
'days' => [
'exclude' => true,
'label' => 'choose weekdays',
'config' => [
'type' => 'check',
'eval' => 'required,unique',
'items' => [
['monday',''],
['thuesday',''],
['wednesday',''],
['thursday',''],
['friday',''],
['saturday',''],
['sunday',''],
],
'cols' => 'inline',
],
],
That stores an integer in the db, but now I have to display the selected days in a fluid template in the frontend.
This is the reference regarding in the TYPO3 documentation which explains that I should check the bit-0 of values ... I've searched a lot but couldn't find anything except this question here on stack overflow, which I cannot get to work.
I strongly recommend not to use the bitmasking feature of the check
field. It's rarely worth the overhead to split the values apart again and also is a lot harder to understand for most developers.
Instead you can use a select
field, in this case selectCheckBox
should serve you well. Given a static list of items
you will get a CSV string with the selected values which is a lot easier to split, e.g. in a getter method of an Extbase domain model. If it makes sense you can even use a relation to records instead which is even cleaner but requires additional work.
If you still want to continue with bitmasks this answer may help you.
SOLUTION 1: using Mathias's solution mixed with the one of Dimitri L.
I wanted to give it here as a full solution to this particular question, so add this in the domain model:
/**
* @var int
*/
protected $days;
and then following for all the days:
/**
* Get day 1
*
* @return int
*/
public function getDay1()
{
return $this->days & 0b00000001 ? 1 : 0;
}
/**
* Set day 1
*
* @param int $day1
*/
public function setDay1($day1) {
if ($day1) {
$this->days |= 0b00000001;
} else {
$this->days &= ~0b00000001;
}
}
/**
* And so on for the other 7 days
*/
You can now use it in extbase $object->getDay1()
or in fluid {object.day1}
As Mathias stated, it quickly gets very complicated, I preferred this solution since I use it only to display the days an event takes place in a week, and in a calendar so a 0 or 1 solution was just fine.
SOLUTION 2: I ended up using the decimal bitmask value from the database directly in a viewhelper: (solution is adepted for the number of checkboxes used, in my case the 7 weekdays)
use \TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* News extension
*
* @package TYPO3
* @subpackage tx_news
*/
class CoursedaysViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper
{
/**
* @param string $days (bitmask)
* @return string checked weekdays seperated by /
*/
public function render($days)
{
// render binary, 7 digits, split into array and reverse
$days = decbin($days);
$days = sprintf('%07d', $days);
$days = str_split($days);
$days = array_reverse($days);
foreach($days as $day){
$key = 'days.' . ++$a;
if($day) $coursedays .= LocalizationUtility::translate($key, 'news_ext') . '/';
}
return substr($coursedays, 0, -1);
}
}