protected function filterMenu($intFilterPanel)
{
/** @var AttributeBagInterface $objSessionBag */
$objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend');
$fields = '';
$this->bid = 'tl_buttons_a';
$sortingFields = array();
$session = $objSessionBag->all();
$filter = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4 ? $this->strTable . '_' . CURRENT_ID : $this->strTable;
// Get the sorting fields
foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'] as $k => $v) {
if (intval($v['filter']) == $intFilterPanel) {
$sortingFields[] = $k;
}
}
// Return if there are no sorting fields
if (empty($sortingFields)) {
return '';
}
// Set filter from user input
if (\Input::post('FORM_SUBMIT') == 'tl_filters') {
foreach ($sortingFields as $field) {
if (\Input::post($field, true) != 'tl_' . $field) {
$session['filter'][$filter][$field] = \Input::post($field, true);
} else {
unset($session['filter'][$filter][$field]);
}
}
$objSessionBag->replace($session);
} else {
foreach ($sortingFields as $field) {
if (isset($session['filter'][$filter][$field])) {
// Sort by day
if (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(5, 6))) {
if ($session['filter'][$filter][$field] == '') {
$this->procedure[] = $field . "=''";
} else {
$objDate = new \Date($session['filter'][$filter][$field]);
$this->procedure[] = $field . ' BETWEEN ? AND ?';
$this->values[] = $objDate->dayBegin;
$this->values[] = $objDate->dayEnd;
}
} elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(7, 8))) {
if ($session['filter'][$filter][$field] == '') {
$this->procedure[] = $field . "=''";
} else {
$objDate = new \Date($session['filter'][$filter][$field]);
$this->procedure[] = $field . ' BETWEEN ? AND ?';
$this->values[] = $objDate->monthBegin;
$this->values[] = $objDate->monthEnd;
}
} elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(9, 10))) {
if ($session['filter'][$filter][$field] == '') {
$this->procedure[] = $field . "=''";
} else {
$objDate = new \Date($session['filter'][$filter][$field]);
$this->procedure[] = $field . ' BETWEEN ? AND ?';
$this->values[] = $objDate->yearBegin;
$this->values[] = $objDate->yearEnd;
}
} elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['multiple']) {
// CSV lists (see #2890)
if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['csv'])) {
$this->procedure[] = $this->Database->findInSet('?', $field, true);
$this->values[] = $session['filter'][$filter][$field];
} else {
$this->procedure[] = $field . ' LIKE ?';
$this->values[] = '%"' . $session['filter'][$filter][$field] . '"%';
}
} else {
$this->procedure[] = $field . '=?';
$this->values[] = $session['filter'][$filter][$field];
}
}
}
}
// Add sorting options
foreach ($sortingFields as $cnt => $field) {
$arrValues = array();
$arrProcedure = array();
if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4) {
$arrProcedure[] = 'pid=?';
$arrValues[] = CURRENT_ID;
}
if (!$this->treeView && !empty($this->root) && is_array($this->root)) {
$arrProcedure[] = "id IN(" . implode(',', array_map('intval', $this->root)) . ")";
}
// Check for a static filter (see #4719)
if (!empty($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['filter']) && is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['filter'])) {
foreach ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['filter'] as $fltr) {
$arrProcedure[] = $fltr[0];
$arrValues[] = $fltr[1];
}
}
// Support empty ptable fields
if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable']) {
$arrProcedure[] = $this->ptable == 'tl_article' ? "(ptable=? OR ptable='')" : "ptable=?";
$arrValues[] = $this->ptable;
}
$what = $field;
// Optimize the SQL query (see #8485)
if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'])) {
// Sort by day
if (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(5, 6))) {
$what = "UNIX_TIMESTAMP(FROM_UNIXTIME({$field} , '%%Y-%%m-%%d')) AS {$field}";
} elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(7, 8))) {
$what = "UNIX_TIMESTAMP(FROM_UNIXTIME({$field} , '%%Y-%%m-01')) AS {$field}";
} elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(9, 10))) {
$what = "UNIX_TIMESTAMP(FROM_UNIXTIME({$field} , '%%Y-01-01')) AS {$field}";
}
}
$objFields = $this->Database->prepare("SELECT DISTINCT " . $what . " FROM " . $this->strTable . (is_array($arrProcedure) && strlen($arrProcedure[0]) ? ' WHERE ' . implode(' AND ', $arrProcedure) : ''))->execute($arrValues);
// Begin select menu
$fields .= '
<select name="' . $field . '" id="' . $field . '" class="tl_select' . (isset($session['filter'][$filter][$field]) ? ' active' : '') . '">
<option value="tl_' . $field . '">' . (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['label']) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['label'][0] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['label']) . '</option>
<option value="tl_' . $field . '">---</option>';
if ($objFields->numRows) {
$options = $objFields->fetchEach($field);
// Sort by day
if (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(5, 6))) {
$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'] == 6 ? rsort($options) : sort($options);
foreach ($options as $k => $v) {
if ($v == '') {
$options[$v] = '-';
} else {
$options[$v] = \Date::parse(\Config::get('dateFormat'), $v);
}
unset($options[$k]);
}
} elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(7, 8))) {
$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'] == 8 ? rsort($options) : sort($options);
foreach ($options as $k => $v) {
if ($v == '') {
$options[$v] = '-';
} else {
$options[$v] = date('Y-m', $v);
$intMonth = date('m', $v) - 1;
if (isset($GLOBALS['TL_LANG']['MONTHS'][$intMonth])) {
$options[$v] = $GLOBALS['TL_LANG']['MONTHS'][$intMonth] . ' ' . date('Y', $v);
}
}
unset($options[$k]);
}
} elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(9, 10))) {
$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'] == 10 ? rsort($options) : sort($options);
foreach ($options as $k => $v) {
if ($v == '') {
$options[$v] = '-';
} else {
$options[$v] = date('Y', $v);
}
unset($options[$k]);
}
}
// Manual filter
if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['multiple']) {
$moptions = array();
// TODO: find a more effective solution
foreach ($options as $option) {
// CSV lists (see #2890)
if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['csv'])) {
$doptions = \StringUtil::trimsplit($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['csv'], $option);
} else {
$doptions = \StringUtil::deserialize($option);
}
if (is_array($doptions)) {
$moptions = array_merge($moptions, $doptions);
}
}
$options = $moptions;
}
$options = array_unique($options);
$options_callback = array();
// Call the options_callback
if ((is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback']) || is_callable($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback'])) && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['reference']) {
if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback'])) {
$strClass = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback'][0];
$strMethod = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback'][1];
$this->import($strClass);
$options_callback = $this->{$strClass}->{$strMethod}($this);
} elseif (is_callable($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback'])) {
$options_callback = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback']($this);
}
// Sort options according to the keys of the callback array
$options = array_intersect(array_keys($options_callback), $options);
}
$options_sorter = array();
$blnDate = in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(5, 6, 7, 8, 9, 10));
// Options
foreach ($options as $kk => $vv) {
$value = $blnDate ? $kk : $vv;
// Options callback
if (!empty($options_callback) && is_array($options_callback)) {
$vv = $options_callback[$vv];
} elseif (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['foreignKey'])) {
$key = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['foreignKey'], 2);
$objParent = $this->Database->prepare("SELECT " . $key[1] . " AS value FROM " . $key[0] . " WHERE id=?")->limit(1)->execute($vv);
if ($objParent->numRows) {
$vv = $objParent->value;
}
} elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['isBoolean'] || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['inputType'] == 'checkbox' && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['multiple']) {
$vv = $vv != '' ? $GLOBALS['TL_LANG']['MSC']['yes'] : $GLOBALS['TL_LANG']['MSC']['no'];
} elseif ($field == 'pid') {
$this->loadDataContainer($this->ptable);
$showFields = $GLOBALS['TL_DCA'][$this->ptable]['list']['label']['fields'];
if (!$showFields[0]) {
$showFields[0] = 'id';
}
$objShowFields = $this->Database->prepare("SELECT " . $showFields[0] . " FROM " . $this->ptable . " WHERE id=?")->limit(1)->execute($vv);
if ($objShowFields->numRows) {
$vv = $objShowFields->{$showFields[0]};
}
}
$option_label = '';
// Use reference array
if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['reference'])) {
$option_label = is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['reference'][$vv]) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['reference'][$vv][0] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['reference'][$vv];
} elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['isAssociative'] || array_is_assoc($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options'])) {
$option_label = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options'][$vv];
}
// No empty options allowed
if (!strlen($option_label)) {
$option_label = $vv ?: '-';
}
$options_sorter[' <option value="' . \StringUtil::specialchars($value) . '"' . (isset($session['filter'][$filter][$field]) && $value == $session['filter'][$filter][$field] ? ' selected="selected"' : '') . '>' . $option_label . '</option>'] = Utf8::toAscii($option_label);
}
// Sort by option values
if (!$blnDate) {
natcasesort($options_sorter);
if (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(2, 4, 12))) {
$options_sorter = array_reverse($options_sorter, true);
}
}
$fields .= "\n" . implode("\n", array_keys($options_sorter));
}
// End select menu
$fields .= '
</select> ';
// Force a line-break after six elements (see #3777)
if (($cnt + 1) % 6 == 0) {
$fields .= '<br>';
}
}
return '
<div class="tl_filter tl_subpanel">
<strong>' . $GLOBALS['TL_LANG']['MSC']['filter'] . ':</strong> ' . $fields . '
</div>';
}