core-bundle/src/Resources/contao/drivers/DC_Table.php
protected function listView()
	{
		$table = ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 6) ? $this->ptable : $this->strTable;
		$orderBy = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['fields'];
		$firstOrderBy = preg_replace('/\s+.*$/', '', $orderBy[0]);

		if (\is_array($this->orderBy) && $this->orderBy[0] != '')
		{
			$orderBy = $this->orderBy;
			$firstOrderBy = $this->firstOrderBy;
		}

		$query = "SELECT * FROM " . $this->strTable;

		if (!empty($this->procedure))
		{
			$query .= " WHERE " . implode(' AND ', $this->procedure);
		}

		if (!empty($this->root) && \is_array($this->root))
		{
			$query .= (!empty($this->procedure) ? " AND " : " WHERE ") . "id IN(" . implode(',', array_map('\intval', $this->root)) . ")";
		}

		if (\is_array($orderBy) && $orderBy[0] != '')
		{
			foreach ($orderBy as $k=>$v)
			{
				list($key, $direction) = explode(' ', $v, 2);

				if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['eval']['findInSet'])
				{
					if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback']))
					{
						$strClass = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback'][0];
						$strMethod = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback'][1];

						$this->import($strClass);
						$keys = $this->$strClass->$strMethod($this);
					}
					elseif (\is_callable($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback']))
					{
						$keys = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback']($this);
					}
					else
					{
						$keys = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options'];
					}

					if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['eval']['isAssociative'] || array_is_assoc($keys))
					{
						$keys = array_keys($keys);
					}

					$orderBy[$k] = $this->Database->findInSet($v, $keys);
				}
				elseif (\in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['flag'], array(5, 6, 7, 8, 9, 10)))
				{
					$orderBy[$k] = "CAST($key AS SIGNED)" . ($direction ? " $direction" : ""); // see #5503
				}
			}

			if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 3)
			{
				$firstOrderBy = 'pid';
				$showFields = $GLOBALS['TL_DCA'][$table]['list']['label']['fields'];

				$query .= " ORDER BY (SELECT " . Database::quoteIdentifier($showFields[0]) . " FROM " . $this->ptable . " WHERE " . $this->ptable . ".id=" . $this->strTable . ".pid), " . implode(', ', $orderBy);

				// Set the foreignKey so that the label is translated
				if ($GLOBALS['TL_DCA'][$table]['fields']['pid']['foreignKey'] == '')
				{
					$GLOBALS['TL_DCA'][$table]['fields']['pid']['foreignKey'] = $this->ptable . '.' . $showFields[0];
				}

				// Remove the parent field from label fields
				array_shift($showFields);
				$GLOBALS['TL_DCA'][$table]['list']['label']['fields'] = $showFields;
			}
			else
			{
				$query .= " ORDER BY " . implode(', ', $orderBy);
			}
		}

		if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 1 && ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['flag'] % 2) == 0)
		{
			$query .= " DESC";
		}

		$objRowStmt = $this->Database->prepare($query);

		if ($this->limit != '')
		{
			$arrLimit = explode(',', $this->limit);
			$objRowStmt->limit($arrLimit[1], $arrLimit[0]);
		}

		$objRow = $objRowStmt->execute($this->values);

		// Display buttos
		$return = Message::generate() . '
<div id="tl_buttons">'.((Input::get('act') == 'select' || $this->ptable) ? '
<a href="'.$this->getReferer(true, $this->ptable).'" class="header_back" title="'.StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']).'" accesskey="b" onclick="Backend.getScrollOffset()">'.$GLOBALS['TL_LANG']['MSC']['backBT'].'</a> ' : (isset($GLOBALS['TL_DCA'][$this->strTable]['config']['backlink']) ? '
<a href="contao/main.php?'.$GLOBALS['TL_DCA'][$this->strTable]['config']['backlink'].'" class="header_back" title="'.StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']).'" accesskey="b" onclick="Backend.getScrollOffset()">'.$GLOBALS['TL_LANG']['MSC']['backBT'].'</a> ' : '')) . ((Input::get('act') != 'select' && !$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable']) ? '
<a href="'.(($this->ptable != '') ? $this->addToUrl('act=create' . (($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] < 4) ? '&amp;mode=2' : '') . '&amp;pid=' . $this->intId) : $this->addToUrl('act=create')).'" class="header_new" title="'.StringUtil::specialchars($GLOBALS['TL_LANG'][$this->strTable]['new'][1]).'" accesskey="n" onclick="Backend.getScrollOffset()">'.$GLOBALS['TL_LANG'][$this->strTable]['new'][0].'</a> ' : '') . $this->generateGlobalButtons() . '
</div>';

		// Return "no records found" message
		if ($objRow->numRows < 1)
		{
			$return .= '
<p class="tl_empty">'.$GLOBALS['TL_LANG']['MSC']['noResult'].'</p>';
		}

		// List records
		else
		{
			$result = $objRow->fetchAllAssoc();

			$return .= ((Input::get('act') == 'select') ? '
<form action="'.ampersand(Environment::get('request'), true).'" id="tl_select" class="tl_form'.((Input::get('act') == 'select') ? ' unselectable' : '').'" method="post" novalidate>
<div class="tl_formbody_edit">
<input type="hidden" name="FORM_SUBMIT" value="tl_select">
<input type="hidden" name="REQUEST_TOKEN" value="'.REQUEST_TOKEN.'">' : '').'
<div class="tl_listing_container list_view" id="tl_listing">'.((Input::get('act') == 'select' || $this->strPickerFieldType == 'checkbox') ? '
<div class="tl_select_trigger">
<label for="tl_select_trigger" class="tl_select_label">'.$GLOBALS['TL_LANG']['MSC']['selectAll'].'</label> <input type="checkbox" id="tl_select_trigger" onclick="Backend.toggleCheckboxes(this)" class="tl_tree_checkbox">
</div>' : '').'
<table class="tl_listing' . ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'] ? ' showColumns' : '') . ($this->strPickerFieldType ? ' picker unselectable' : '') . '">';

			// Automatically add the "order by" field as last column if we do not have group headers
			if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'])
			{
				$blnFound = false;

				// Extract the real key and compare it to $firstOrderBy
				foreach ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'] as $f)
				{
					if (strpos($f, ':') !== false)
					{
						list($f) = explode(':', $f, 2);
					}

					if ($firstOrderBy == $f)
					{
						$blnFound = true;
						break;
					}
				}

				if (!$blnFound)
				{
					$GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][] = $firstOrderBy;
				}
			}

			// Generate the table header if the "show columns" option is active
			if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'])
			{
				$return .= '
  <tr>';

				foreach ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'] as $f)
				{
					if (strpos($f, ':') !== false)
					{
						list($f) = explode(':', $f, 2);
					}

					$return .= '
    <th class="tl_folder_tlist col_' . $f . (($f == $firstOrderBy) ? ' ordered_by' : '') . '">'.(\is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label']) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label'][0] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label']).'</th>';
			}

				$return .= '
    <th class="tl_folder_tlist tl_right_nowrap"></th>
  </tr>';
			}

			// Process result and add label and buttons
			$remoteCur = false;
			$groupclass = 'tl_folder_tlist';
			$eoCount = -1;

			foreach ($result as $row)
			{
				$args = array();
				$this->current[] = $row['id'];
				$showFields = $GLOBALS['TL_DCA'][$table]['list']['label']['fields'];

				// Label
				foreach ($showFields as $k=>$v)
				{
					// Decrypt the value
					if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['encrypt'])
					{
						$row[$v] = Encryption::decrypt(StringUtil::deserialize($row[$v]));
					}

					if (strpos($v, ':') !== false)
					{
						list($strKey, $strTable) = explode(':', $v);
						list($strTable, $strField) = explode('.', $strTable);

						$objRef = $this->Database->prepare("SELECT " . Database::quoteIdentifier($strField) . " FROM " . $strTable . " WHERE id=?")
												 ->limit(1)
												 ->execute($row[$strKey]);

						$args[$k] = $objRef->numRows ? $objRef->$strField : '';
					}
					elseif (\in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['flag'], array(5, 6, 7, 8, 9, 10)))
					{
						if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['rgxp'] == 'date')
						{
							$args[$k] = $row[$v] ? Date::parse(Config::get('dateFormat'), $row[$v]) : '-';
						}
						elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['rgxp'] == 'time')
						{
							$args[$k] = $row[$v] ? Date::parse(Config::get('timeFormat'), $row[$v]) : '-';
						}
						else
						{
							$args[$k] = $row[$v] ? Date::parse(Config::get('datimFormat'), $row[$v]) : '-';
						}
					}
					elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['isBoolean'] || ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['inputType'] == 'checkbox' && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['multiple']))
					{
						$args[$k] = $row[$v] ? $GLOBALS['TL_LANG']['MSC']['yes'] : $GLOBALS['TL_LANG']['MSC']['no'];
					}
					else
					{
						$row_v = StringUtil::deserialize($row[$v]);

						if (\is_array($row_v))
						{
							$args_k = array();

							foreach ($row_v as $option)
							{
								$args_k[] = $GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$option] ?: $option;
							}

							$args[$k] = implode(', ', $args_k);
						}
						elseif (isset($GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]]))
						{
							$args[$k] = \is_array($GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]]) ? $GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]][0] : $GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]];
						}
						elseif (($GLOBALS['TL_DCA'][$table]['fields'][$v]['eval']['isAssociative'] || array_is_assoc($GLOBALS['TL_DCA'][$table]['fields'][$v]['options'])) && isset($GLOBALS['TL_DCA'][$table]['fields'][$v]['options'][$row[$v]]))
						{
							$args[$k] = $GLOBALS['TL_DCA'][$table]['fields'][$v]['options'][$row[$v]];
						}
						else
						{
							$args[$k] = $row[$v];
						}
					}
				}

				// Shorten the label it if it is too long
				$label = vsprintf($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['format'] ?: '%s', $args);

				if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'] > 0 && $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'] < \strlen(strip_tags($label)))
				{
					$label = trim(StringUtil::substrHtml($label, $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'])) . ' …';
				}

				// Remove empty brackets (), [], {}, <> and empty tags from the label
				$label = preg_replace('/\( *\) ?|\[ *\] ?|\{ *\} ?|< *> ?/', '', $label);
				$label = preg_replace('/<[^>]+>\s*<\/[^>]+>/', '', $label);

				// Build the sorting groups
				if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] > 0)
				{
					$current = $row[$firstOrderBy];
					$orderBy = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['fields'];
					$sortingMode = (\count($orderBy) == 1 && $firstOrderBy == $orderBy[0] && $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['flag'] != '' && $GLOBALS['TL_DCA'][$this->strTable]['fields'][$firstOrderBy]['flag'] == '') ? $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['flag'] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$firstOrderBy]['flag'];
					$remoteNew = $this->formatCurrentValue($firstOrderBy, $current, $sortingMode);

					// Add the group header
					if (!$GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'] && !$GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['disableGrouping'] && ($remoteNew != $remoteCur || $remoteCur === false))
					{
						$eoCount = -1;
						$group = $this->formatGroupHeader($firstOrderBy, $remoteNew, $sortingMode, $row);
						$remoteCur = $remoteNew;

						$return .= '
  <tr>
    <td colspan="2" class="'.$groupclass.'">'.$group.'</td>
  </tr>';
						$groupclass = 'tl_folder_list';
					}
				}

				$return .= '
  <tr class="'.((++$eoCount % 2 == 0) ? 'even' : 'odd').' click2edit toggle_select hover-row">
    ';

				$colspan = 1;

				// Call the label_callback ($row, $label, $this)
				if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']) || \is_callable($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']))
				{
					if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']))
					{
						$strClass = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'][0];
						$strMethod = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'][1];

						$this->import($strClass);
						$args = $this->$strClass->$strMethod($row, $label, $this, $args);
					}
					elseif (\is_callable($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']))
					{
						$args = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']($row, $label, $this, $args);
					}

					// Handle strings and arrays
					if (!$GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'])
					{
						$label = \is_array($args) ? implode(' ', $args) : $args;
					}
					elseif (!\is_array($args))
					{
						$args = array($args);
						$colspan = \count($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields']);
					}
				}

				// Show columns
				if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'])
				{
					foreach ($args as $j=>$arg)
					{
						$return .= '<td colspan="' . $colspan . '" class="tl_file_list col_' . $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][$j] . (($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][$j] == $firstOrderBy) ? ' ordered_by' : '') . '">' . ($arg ?: '-') . '</td>';
					}
				}
				else
				{
					$return .= '<td class="tl_file_list">' . $label . '</td>';
				}

				// Buttons ($row, $table, $root, $blnCircularReference, $childs, $previous, $next)
				$return .= ((Input::get('act') == 'select') ? '
    <td class="tl_file_list tl_right_nowrap"><input type="checkbox" name="IDS[]" id="ids_'.$row['id'].'" class="tl_tree_checkbox" value="'.$row['id'].'"></td>' : '
    <td class="tl_file_list tl_right_nowrap">'.$this->generateButtons($row, $this->strTable, $this->root).($this->strPickerFieldType ? $this->getPickerInputField($row['id']) : '').'</td>') . '
  </tr>';
			}

			// Close the table
			$return .= '
</table>'.($this->strPickerFieldType == 'radio' ? '
<div class="tl_radio_reset">
<label for="tl_radio_reset" class="tl_radio_label">'.$GLOBALS['TL_LANG']['MSC']['resetSelected'].'</label> <input type="radio" name="picker" id="tl_radio_reset" value="" class="tl_tree_radio">
</div>' : '').'
</div>';

			// Close the form
			if (Input::get('act') == 'select')
			{
				// Submit buttons
				$arrButtons = array();

				if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable'])
				{
					$arrButtons['edit'] = '<button type="submit" name="edit" id="edit" class="tl_submit" accesskey="s">'.$GLOBALS['TL_LANG']['MSC']['editSelected'].'</button>';
				}

				if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notDeletable'])
				{
					$arrButtons['delete'] = '<button type="submit" name="delete" id="delete" class="tl_submit" accesskey="d" onclick="return confirm(\''.$GLOBALS['TL_LANG']['MSC']['delAllConfirm'].'\')">'.$GLOBALS['TL_LANG']['MSC']['deleteSelected'].'</button>';
				}

				if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notCopyable'])
				{
					$arrButtons['copy'] = '<button type="submit" name="copy" id="copy" class="tl_submit" accesskey="c">'.$GLOBALS['TL_LANG']['MSC']['copySelected'].'</button>';
				}

				if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable'])
				{
					$arrButtons['override'] = '<button type="submit" name="override" id="override" class="tl_submit" accesskey="v">'.$GLOBALS['TL_LANG']['MSC']['overrideSelected'].'</button>';
				}

				// Call the buttons_callback (see #4691)
				if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['select']['buttons_callback']))
				{
					foreach ($GLOBALS['TL_DCA'][$this->strTable]['select']['buttons_callback'] as $callback)
					{
						if (\is_array($callback))
						{
							$this->import($callback[0]);
							$arrButtons = $this->{$callback[0]}->{$callback[1]}($arrButtons, $this);
						}
						elseif (\is_callable($callback))
						{
							$arrButtons = $callback($arrButtons, $this);
						}
					}
				}

				if (\count($arrButtons) < 3)
				{
					$strButtons = implode(' ', $arrButtons);
				}
				else
				{
					$strButtons = array_shift($arrButtons) . ' ';
					$strButtons .= '<div class="split-button">';
					$strButtons .= array_shift($arrButtons) . '<button type="button" id="sbtog">' . Image::getHtml('navcol.svg') . '</button> <ul class="invisible">';

					foreach ($arrButtons as $strButton)
					{
						$strButtons .= '<li>' . $strButton . '</li>';
					}

					$strButtons .= '</ul></div>';
				}

				$return .= '
</div>
<div class="tl_formbody_submit" style="text-align:right">
<div class="tl_submit_container">
  ' . $strButtons . '
</div>
</div>
</form>';
			}
		}

		return $return;
	}
protected function listView()
	{
		$table = ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 6) ? $this->ptable : $this->strTable;
		$orderBy = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['fields'];
		$firstOrderBy = preg_replace('/\s+.*$/', '', $orderBy[0]);

		if (\is_array($this->orderBy) && $this->orderBy[0] != '')
		{
			$orderBy = $this->orderBy;
			$firstOrderBy = $this->firstOrderBy;
		}

		$query = "SELECT * FROM " . $this->strTable;

		if (!empty($this->procedure))
		{
			$query .= " WHERE " . implode(' AND ', $this->procedure);
		}

		if (!empty($this->root) && \is_array($this->root))
		{
			$query .= (!empty($this->procedure) ? " AND " : " WHERE ") . "id IN(" . implode(',', array_map('\intval', $this->root)) . ")";
		}

		if (\is_array($orderBy) && $orderBy[0] != '')
		{
			foreach ($orderBy as $k=>$v)
			{
				list($key, $direction) = explode(' ', $v, 2);

				if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['eval']['findInSet'])
				{
					if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback']))
					{
						$strClass = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback'][0];
						$strMethod = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback'][1];

						$this->import($strClass);
						$keys = $this->$strClass->$strMethod($this);
					}
					elseif (\is_callable($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback']))
					{
						$keys = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback']($this);
					}
					else
					{
						$keys = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options'];
					}

					if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['eval']['isAssociative'] || array_is_assoc($keys))
					{
						$keys = array_keys($keys);
					}

					$orderBy[$k] = $this->Database->findInSet($v, $keys);
				}
				elseif (\in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['flag'], array(5, 6, 7, 8, 9, 10)))
				{
					$orderBy[$k] = "CAST($key AS SIGNED)" . ($direction ? " $direction" : ""); // see #5503
				}
			}

			if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 3)
			{
				$firstOrderBy = 'pid';
				$showFields = $GLOBALS['TL_DCA'][$table]['list']['label']['fields'];

				$query .= " ORDER BY (SELECT " . Database::quoteIdentifier($showFields[0]) . " FROM " . $this->ptable . " WHERE " . $this->ptable . ".id=" . $this->strTable . ".pid), " . implode(', ', $orderBy);

				// Set the foreignKey so that the label is translated
				if ($GLOBALS['TL_DCA'][$table]['fields']['pid']['foreignKey'] == '')
				{
					$GLOBALS['TL_DCA'][$table]['fields']['pid']['foreignKey'] = $this->ptable . '.' . $showFields[0];
				}

				// Remove the parent field from label fields
				array_shift($showFields);
				$GLOBALS['TL_DCA'][$table]['list']['label']['fields'] = $showFields;
			}
			else
			{
				$query .= " ORDER BY " . implode(', ', $orderBy);
			}
		}

		if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 1 && ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['flag'] % 2) == 0)
		{
			$query .= " DESC";
		}

		$objRowStmt = $this->Database->prepare($query);

		if ($this->limit != '')
		{
			$arrLimit = explode(',', $this->limit);
			$objRowStmt->limit($arrLimit[1], $arrLimit[0]);
		}

		$objRow = $objRowStmt->execute($this->values);

		// Display buttos
		$return = Message::generate() . '
<div id="tl_buttons">'.((Input::get('act') == 'select' || $this->ptable) ? '
<a href="'.$this->getReferer(true, $this->ptable).'" class="header_back" title="'.StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']).'" accesskey="b" onclick="Backend.getScrollOffset()">'.$GLOBALS['TL_LANG']['MSC']['backBT'].'</a> ' : (isset($GLOBALS['TL_DCA'][$this->strTable]['config']['backlink']) ? '
<a href="contao/main.php?'.$GLOBALS['TL_DCA'][$this->strTable]['config']['backlink'].'" class="header_back" title="'.StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']).'" accesskey="b" onclick="Backend.getScrollOffset()">'.$GLOBALS['TL_LANG']['MSC']['backBT'].'</a> ' : '')) . ((Input::get('act') != 'select' && !$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable']) ? '
<a href="'.(($this->ptable != '') ? $this->addToUrl('act=create' . (($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] < 4) ? '&amp;mode=2' : '') . '&amp;pid=' . $this->intId) : $this->addToUrl('act=create')).'" class="header_new" title="'.StringUtil::specialchars($GLOBALS['TL_LANG'][$this->strTable]['new'][1]).'" accesskey="n" onclick="Backend.getScrollOffset()">'.$GLOBALS['TL_LANG'][$this->strTable]['new'][0].'</a> ' : '') . $this->generateGlobalButtons() . '
</div>';

		// Return "no records found" message
		if ($objRow->numRows < 1)
		{
			$return .= '
<p class="tl_empty">'.$GLOBALS['TL_LANG']['MSC']['noResult'].'</p>';
		}

		// List records
		else
		{
			$result = $objRow->fetchAllAssoc();

			$return .= ((Input::get('act') == 'select') ? '
<form action="'.ampersand(Environment::get('request'), true).'" id="tl_select" class="tl_form'.((Input::get('act') == 'select') ? ' unselectable' : '').'" method="post" novalidate>
<div class="tl_formbody_edit">
<input type="hidden" name="FORM_SUBMIT" value="tl_select">
<input type="hidden" name="REQUEST_TOKEN" value="'.REQUEST_TOKEN.'">' : '').'
<div class="tl_listing_container list_view" id="tl_listing">'.((Input::get('act') == 'select' || $this->strPickerFieldType == 'checkbox') ? '
<div class="tl_select_trigger">
<label for="tl_select_trigger" class="tl_select_label">'.$GLOBALS['TL_LANG']['MSC']['selectAll'].'</label> <input type="checkbox" id="tl_select_trigger" onclick="Backend.toggleCheckboxes(this)" class="tl_tree_checkbox">
</div>' : '').'
<table class="tl_listing' . ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'] ? ' showColumns' : '') . ($this->strPickerFieldType ? ' picker unselectable' : '') . '">';

			// Automatically add the "order by" field as last column if we do not have group headers
			if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'])
			{
				$blnFound = false;

				// Extract the real key and compare it to $firstOrderBy
				foreach ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'] as $f)
				{
					if (strpos($f, ':') !== false)
					{
						list($f) = explode(':', $f, 2);
					}

					if ($firstOrderBy == $f)
					{
						$blnFound = true;
						break;
					}
				}

				if (!$blnFound)
				{
					$GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][] = $firstOrderBy;
				}
			}

			// Generate the table header if the "show columns" option is active
			if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'])
			{
				$return .= '
  <tr>';

				foreach ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'] as $f)
				{
					if (strpos($f, ':') !== false)
					{
						list($f) = explode(':', $f, 2);
					}

					$return .= '
    <th class="tl_folder_tlist col_' . $f . (($f == $firstOrderBy) ? ' ordered_by' : '') . '">'.(\is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label']) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label'][0] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label']).'</th>';
			}

				$return .= '
    <th class="tl_folder_tlist tl_right_nowrap"></th>
  </tr>';
			}

			// Process result and add label and buttons
			$remoteCur = false;
			$groupclass = 'tl_folder_tlist';
			$eoCount = -1;

			foreach ($result as $row)
			{
				$args = array();
				$this->current[] = $row['id'];
				$showFields = $GLOBALS['TL_DCA'][$table]['list']['label']['fields'];

				// Label
				foreach ($showFields as $k=>$v)
				{
					// Decrypt the value
					if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['encrypt'])
					{
						$row[$v] = Encryption::decrypt(StringUtil::deserialize($row[$v]));
					}

					if (strpos($v, ':') !== false)
					{
						list($strKey, $strTable) = explode(':', $v);
						list($strTable, $strField) = explode('.', $strTable);

						$objRef = $this->Database->prepare("SELECT " . Database::quoteIdentifier($strField) . " FROM " . $strTable . " WHERE id=?")
												 ->limit(1)
												 ->execute($row[$strKey]);

						$args[$k] = $objRef->numRows ? $objRef->$strField : '';
					}
					elseif (\in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['flag'], array(5, 6, 7, 8, 9, 10)))
					{
						if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['rgxp'] == 'date')
						{
							$args[$k] = $row[$v] ? Date::parse(Config::get('dateFormat'), $row[$v]) : '-';
						}
						elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['rgxp'] == 'time')
						{
							$args[$k] = $row[$v] ? Date::parse(Config::get('timeFormat'), $row[$v]) : '-';
						}
						else
						{
							$args[$k] = $row[$v] ? Date::parse(Config::get('datimFormat'), $row[$v]) : '-';
						}
					}
					elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['isBoolean'] || ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['inputType'] == 'checkbox' && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['multiple']))
					{
						$args[$k] = $row[$v] ? $GLOBALS['TL_LANG']['MSC']['yes'] : $GLOBALS['TL_LANG']['MSC']['no'];
					}
					else
					{
						$row_v = StringUtil::deserialize($row[$v]);

						if (\is_array($row_v))
						{
							$args_k = array();

							foreach ($row_v as $option)
							{
								$args_k[] = $GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$option] ?: $option;
							}

							$args[$k] = implode(', ', $args_k);
						}
						elseif (isset($GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]]))
						{
							$args[$k] = \is_array($GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]]) ? $GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]][0] : $GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]];
						}
						elseif (($GLOBALS['TL_DCA'][$table]['fields'][$v]['eval']['isAssociative'] || array_is_assoc($GLOBALS['TL_DCA'][$table]['fields'][$v]['options'])) && isset($GLOBALS['TL_DCA'][$table]['fields'][$v]['options'][$row[$v]]))
						{
							$args[$k] = $GLOBALS['TL_DCA'][$table]['fields'][$v]['options'][$row[$v]];
						}
						else
						{
							$args[$k] = $row[$v];
						}
					}
				}

				// Shorten the label it if it is too long
				$label = vsprintf($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['format'] ?: '%s', $args);

				if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'] > 0 && $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'] < \strlen(strip_tags($label)))
				{
					$label = trim(StringUtil::substrHtml($label, $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'])) . ' …';
				}

				// Remove empty brackets (), [], {}, <> and empty tags from the label
				$label = preg_replace('/\( *\) ?|\[ *\] ?|\{ *\} ?|< *> ?/', '', $label);
				$label = preg_replace('/<[^>]+>\s*<\/[^>]+>/', '', $label);

				// Build the sorting groups
				if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] > 0)
				{
					$current = $row[$firstOrderBy];
					$orderBy = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['fields'];
					$sortingMode = (\count($orderBy) == 1 && $firstOrderBy == $orderBy[0] && $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['flag'] != '' && $GLOBALS['TL_DCA'][$this->strTable]['fields'][$firstOrderBy]['flag'] == '') ? $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['flag'] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$firstOrderBy]['flag'];
					$remoteNew = $this->formatCurrentValue($firstOrderBy, $current, $sortingMode);

					// Add the group header
					if (!$GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'] && !$GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['disableGrouping'] && ($remoteNew != $remoteCur || $remoteCur === false))
					{
						$eoCount = -1;
						$group = $this->formatGroupHeader($firstOrderBy, $remoteNew, $sortingMode, $row);
						$remoteCur = $remoteNew;

						$return .= '
  <tr>
    <td colspan="2" class="'.$groupclass.'">'.$group.'</td>
  </tr>';
						$groupclass = 'tl_folder_list';
					}
				}

				$return .= '
  <tr class="'.((++$eoCount % 2 == 0) ? 'even' : 'odd').' click2edit toggle_select hover-row">
    ';

				$colspan = 1;

				// Call the label_callback ($row, $label, $this)
				if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']) || \is_callable($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']))
				{
					if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']))
					{
						$strClass = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'][0];
						$strMethod = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'][1];

						$this->import($strClass);
						$args = $this->$strClass->$strMethod($row, $label, $this, $args);
					}
					elseif (\is_callable($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']))
					{
						$args = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']($row, $label, $this, $args);
					}

					// Handle strings and arrays
					if (!$GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'])
					{
						$label = \is_array($args) ? implode(' ', $args) : $args;
					}
					elseif (!\is_array($args))
					{
						$args = array($args);
						$colspan = \count($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields']);
					}
				}

				// Show columns
				if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'])
				{
					foreach ($args as $j=>$arg)
					{
						$return .= '<td colspan="' . $colspan . '" class="tl_file_list col_' . $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][$j] . (($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][$j] == $firstOrderBy) ? ' ordered_by' : '') . '">' . ($arg ?: '-') . '</td>';
					}
				}
				else
				{
					$return .= '<td class="tl_file_list">' . $label . '</td>';
				}

				// Buttons ($row, $table, $root, $blnCircularReference, $childs, $previous, $next)
				$return .= ((Input::get('act') == 'select') ? '
    <td class="tl_file_list tl_right_nowrap"><input type="checkbox" name="IDS[]" id="ids_'.$row['id'].'" class="tl_tree_checkbox" value="'.$row['id'].'"></td>' : '
    <td class="tl_file_list tl_right_nowrap">'.$this->generateButtons($row, $this->strTable, $this->root).($this->strPickerFieldType ? $this->getPickerInputField($row['id']) : '').'</td>') . '
  </tr>';
			}

			// Close the table
			$return .= '
</table>'.($this->strPickerFieldType == 'radio' ? '
<div class="tl_radio_reset">
<label for="tl_radio_reset" class="tl_radio_label">'.$GLOBALS['TL_LANG']['MSC']['resetSelected'].'</label> <input type="radio" name="picker" id="tl_radio_reset" value="" class="tl_tree_radio">
</div>' : '').'
</div>';

			// Close the form
			if (Input::get('act') == 'select')
			{
				// Submit buttons
				$arrButtons = array();

				if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable'])
				{
					$arrButtons['edit'] = '<button type="submit" name="edit" id="edit" class="tl_submit" accesskey="s">'.$GLOBALS['TL_LANG']['MSC']['editSelected'].'</button>';
				}

				if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notDeletable'])
				{
					$arrButtons['delete'] = '<button type="submit" name="delete" id="delete" class="tl_submit" accesskey="d" onclick="return confirm(\''.$GLOBALS['TL_LANG']['MSC']['delAllConfirm'].'\')">'.$GLOBALS['TL_LANG']['MSC']['deleteSelected'].'</button>';
				}

				if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notCopyable'])
				{
					$arrButtons['copy'] = '<button type="submit" name="copy" id="copy" class="tl_submit" accesskey="c">'.$GLOBALS['TL_LANG']['MSC']['copySelected'].'</button>';
				}

				if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable'])
				{
					$arrButtons['override'] = '<button type="submit" name="override" id="override" class="tl_submit" accesskey="v">'.$GLOBALS['TL_LANG']['MSC']['overrideSelected'].'</button>';
				}

				// Call the buttons_callback (see #4691)
				if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['select']['buttons_callback']))
				{
					foreach ($GLOBALS['TL_DCA'][$this->strTable]['select']['buttons_callback'] as $callback)
					{
						if (\is_array($callback))
						{
							$this->import($callback[0]);
							$arrButtons = $this->{$callback[0]}->{$callback[1]}($arrButtons, $this);
						}
						elseif (\is_callable($callback))
						{
							$arrButtons = $callback($arrButtons, $this);
						}
					}
				}

				if (\count($arrButtons) < 3)
				{
					$strButtons = implode(' ', $arrButtons);
				}
				else
				{
					$strButtons = array_shift($arrButtons) . ' ';
					$strButtons .= '<div class="split-button">';
					$strButtons .= array_shift($arrButtons) . '<button type="button" id="sbtog">' . Image::getHtml('navcol.svg') . '</button> <ul class="invisible">';

					foreach ($arrButtons as $strButton)
					{
						$strButtons .= '<li>' . $strButton . '</li>';
					}

					$strButtons .= '</ul></div>';
				}

				$return .= '
</div>
<div class="tl_formbody_submit" style="text-align:right">
<div class="tl_submit_container">
  ' . $strButtons . '
</div>
</div>
</form>';
			}
		}

		return $return;
	}
protected function listView ( ) { $ table = ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'mode' ] == 6 ) ? $ this -> ptable : $ this -> strTable ; $ orderBy = $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'fields' ] ; $ firstOrderBy = preg_replace ( '/\s+.*$/' , '' , $ orderBy [ 0 ] ) ; if ( \ is_array ( $ this -> orderBy ) && $ this -> orderBy [ 0 ] != '' ) { $ orderBy = $ this -> orderBy ; $ firstOrderBy = $ this -> firstOrderBy ; } $ query = "SELECT * FROM " . $ this -> strTable ; if ( ! empty ( $ this -> procedure ) ) { $ query .= " WHERE " . implode ( ' AND ' , $ this -> procedure ) ; } if ( ! empty ( $ this -> root ) && \ is_array ( $ this -> root ) ) { $ query .= ( ! empty ( $ this -> procedure ) ? " AND " : " WHERE " ) . "id IN(" . implode ( ',' , array_map ( '\intval' , $ this -> root ) ) . ")" ; } if ( \ is_array ( $ orderBy ) && $ orderBy [ 0 ] != '' ) { foreach ( $ orderBy as $ k => $ v ) { list ( $ key , $ direction ) = explode ( ' ' , $ v , 2 ) ; if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ key ] [ 'eval' ] [ 'findInSet' ] ) { if ( \ is_array ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ key ] [ 'options_callback' ] ) ) { $ strClass = $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ key ] [ 'options_callback' ] [ 0 ] ; $ strMethod = $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ key ] [ 'options_callback' ] [ 1 ] ; $ this -> import ( $ strClass ) ; $ keys = $ this -> $ strClass -> $ strMethod ( $ this ) ; } elseif ( \ is_callable ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ key ] [ 'options_callback' ] ) ) { $ keys = $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ key ] [ 'options_callback' ] ( $ this ) ; } else { $ keys = $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ key ] [ 'options' ] ; } if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ key ] [ 'eval' ] [ 'isAssociative' ] || array_is_assoc ( $ keys ) ) { $ keys = array_keys ( $ keys ) ; } $ orderBy [ $ k ] = $ this -> Database -> findInSet ( $ v , $ keys ) ; } elseif ( \ in_array ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ key ] [ 'flag' ] , array ( 5 , 6 , 7 , 8 , 9 , 10 ) ) ) { $ orderBy [ $ k ] = "CAST($key AS SIGNED)" . ( $ direction ? " $direction" : "" ) ; // see #5503 } } if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'mode' ] == 3 ) { $ firstOrderBy = 'pid' ; $ showFields = $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'list' ] [ 'label' ] [ 'fields' ] ; $ query .= " ORDER BY (SELECT " . Database :: quoteIdentifier ( $ showFields [ 0 ] ) . " FROM " . $ this -> ptable . " WHERE " . $ this -> ptable . ".id=" . $ this -> strTable . ".pid), " . implode ( ', ' , $ orderBy ) ; // Set the foreignKey so that the label is translated if ( $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'fields' ] [ 'pid' ] [ 'foreignKey' ] == '' ) { $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'fields' ] [ 'pid' ] [ 'foreignKey' ] = $ this -> ptable . '.' . $ showFields [ 0 ] ; } // Remove the parent field from label fields array_shift ( $ showFields ) ; $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'list' ] [ 'label' ] [ 'fields' ] = $ showFields ; } else { $ query .= " ORDER BY " . implode ( ', ' , $ orderBy ) ; } } if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'mode' ] == 1 && ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'flag' ] % 2 ) == 0 ) { $ query .= " DESC" ; } $ objRowStmt = $ this -> Database -> prepare ( $ query ) ; if ( $ this -> limit != '' ) { $ arrLimit = explode ( ',' , $ this -> limit ) ; $ objRowStmt -> limit ( $ arrLimit [ 1 ] , $ arrLimit [ 0 ] ) ; } $ objRow = $ objRowStmt -> execute ( $ this -> values ) ; // Display buttos $ return = Message :: generate ( ) . '
<div id="tl_buttons">' . ( ( Input :: get ( 'act' ) == 'select' || $ this -> ptable ) ? '
<a href="' . $ this -> getReferer ( true , $ this -> ptable ) . '" class="header_back" title="' . StringUtil :: specialchars ( $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'backBTTitle' ] ) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'backBT' ] . '</a> ' : ( isset ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'backlink' ] ) ? '
<a href="contao/main.php?' . $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'backlink' ] . '" class="header_back" title="' . StringUtil :: specialchars ( $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'backBTTitle' ] ) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'backBT' ] . '</a> ' : '' ) ) . ( ( Input :: get ( 'act' ) != 'select' && ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'closed' ] && ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'notCreatable' ] ) ? '
<a href="' . ( ( $ this -> ptable != '' ) ? $ this -> addToUrl ( 'act=create' . ( ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'mode' ] < 4 ) ? '&amp;mode=2' : '' ) . '&amp;pid=' . $ this -> intId ) : $ this -> addToUrl ( 'act=create' ) ) . '" class="header_new" title="' . StringUtil :: specialchars ( $ GLOBALS [ 'TL_LANG' ] [ $ this -> strTable ] [ 'new' ] [ 1 ] ) . '" accesskey="n" onclick="Backend.getScrollOffset()">' . $ GLOBALS [ 'TL_LANG' ] [ $ this -> strTable ] [ 'new' ] [ 0 ] . '</a> ' : '' ) . $ this -> generateGlobalButtons ( ) . '
</div>' ; // Return "no records found" message if ( $ objRow -> numRows < 1 ) { $ return .= '
<p class="tl_empty">' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'noResult' ] . '</p>' ; } // List records else { $ result = $ objRow -> fetchAllAssoc ( ) ; $ return .= ( ( Input :: get ( 'act' ) == 'select' ) ? '
<form action="' . ampersand ( Environment :: get ( 'request' ) , true ) . '" id="tl_select" class="tl_form' . ( ( Input :: get ( 'act' ) == 'select' ) ? ' unselectable' : '' ) . '" method="post" novalidate>
<div class="tl_formbody_edit">
<input type="hidden" name="FORM_SUBMIT" value="tl_select">
<input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '">' : '' ) . '
<div class="tl_listing_container list_view" id="tl_listing">' . ( ( Input :: get ( 'act' ) == 'select' || $ this -> strPickerFieldType == 'checkbox' ) ? '
<div class="tl_select_trigger">
<label for="tl_select_trigger" class="tl_select_label">' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'selectAll' ] . '</label> <input type="checkbox" id="tl_select_trigger" onclick="Backend.toggleCheckboxes(this)" class="tl_tree_checkbox">
</div>' : '' ) . '
<table class="tl_listing' . ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'showColumns' ] ? ' showColumns' : '' ) . ( $ this -> strPickerFieldType ? ' picker unselectable' : '' ) . '">' ; // Automatically add the "order by" field as last column if we do not have group headers if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'showColumns' ] ) { $ blnFound = false ; // Extract the real key and compare it to $firstOrderBy foreach ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'fields' ] as $ f ) { if ( strpos ( $ f , ':' ) !== false ) { list ( $ f ) = explode ( ':' , $ f , 2 ) ; } if ( $ firstOrderBy == $ f ) { $ blnFound = true ; break ; } } if ( ! $ blnFound ) { $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'fields' ] [ ] = $ firstOrderBy ; } } // Generate the table header if the "show columns" option is active if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'showColumns' ] ) { $ return .= '
  <tr>' ; foreach ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'fields' ] as $ f ) { if ( strpos ( $ f , ':' ) !== false ) { list ( $ f ) = explode ( ':' , $ f , 2 ) ; } $ return .= '
    <th class="tl_folder_tlist col_' . $ f . ( ( $ f == $ firstOrderBy ) ? ' ordered_by' : '' ) . '">' . ( \ is_array ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ f ] [ 'label' ] ) ? $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ f ] [ 'label' ] [ 0 ] : $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ f ] [ 'label' ] ) . '</th>' ; } $ return .= '
    <th class="tl_folder_tlist tl_right_nowrap"></th>
  </tr>' ; } // Process result and add label and buttons $ remoteCur = false ; $ groupclass = 'tl_folder_tlist' ; $ eoCount = - 1 ; foreach ( $ result as $ row ) { $ args = array ( ) ; $ this -> current [ ] = $ row [ 'id' ] ; $ showFields = $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'list' ] [ 'label' ] [ 'fields' ] ; // Label foreach ( $ showFields as $ k => $ v ) { // Decrypt the value if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ v ] [ 'eval' ] [ 'encrypt' ] ) { $ row [ $ v ] = Encryption :: decrypt ( StringUtil :: deserialize ( $ row [ $ v ] ) ) ; } if ( strpos ( $ v , ':' ) !== false ) { list ( $ strKey , $ strTable ) = explode ( ':' , $ v ) ; list ( $ strTable , $ strField ) = explode ( '.' , $ strTable ) ; $ objRef = $ this -> Database -> prepare ( "SELECT " . Database :: quoteIdentifier ( $ strField ) . " FROM " . $ strTable . " WHERE id=?" ) -> limit ( 1 ) -> execute ( $ row [ $ strKey ] ) ; $ args [ $ k ] = $ objRef -> numRows ? $ objRef -> $ strField : '' ; } elseif ( \ in_array ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ v ] [ 'flag' ] , array ( 5 , 6 , 7 , 8 , 9 , 10 ) ) ) { if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ v ] [ 'eval' ] [ 'rgxp' ] == 'date' ) { $ args [ $ k ] = $ row [ $ v ] ? Date :: parse ( Config :: get ( 'dateFormat' ) , $ row [ $ v ] ) : '-' ; } elseif ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ v ] [ 'eval' ] [ 'rgxp' ] == 'time' ) { $ args [ $ k ] = $ row [ $ v ] ? Date :: parse ( Config :: get ( 'timeFormat' ) , $ row [ $ v ] ) : '-' ; } else { $ args [ $ k ] = $ row [ $ v ] ? Date :: parse ( Config :: get ( 'datimFormat' ) , $ row [ $ v ] ) : '-' ; } } elseif ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ v ] [ 'eval' ] [ 'isBoolean' ] || ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ v ] [ 'inputType' ] == 'checkbox' && ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ v ] [ 'eval' ] [ 'multiple' ] ) ) { $ args [ $ k ] = $ row [ $ v ] ? $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'yes' ] : $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'no' ] ; } else { $ row_v = StringUtil :: deserialize ( $ row [ $ v ] ) ; if ( \ is_array ( $ row_v ) ) { $ args_k = array ( ) ; foreach ( $ row_v as $ option ) { $ args_k [ ] = $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'fields' ] [ $ v ] [ 'reference' ] [ $ option ] ? : $ option ; } $ args [ $ k ] = implode ( ', ' , $ args_k ) ; } elseif ( isset ( $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'fields' ] [ $ v ] [ 'reference' ] [ $ row [ $ v ] ] ) ) { $ args [ $ k ] = \ is_array ( $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'fields' ] [ $ v ] [ 'reference' ] [ $ row [ $ v ] ] ) ? $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'fields' ] [ $ v ] [ 'reference' ] [ $ row [ $ v ] ] [ 0 ] : $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'fields' ] [ $ v ] [ 'reference' ] [ $ row [ $ v ] ] ; } elseif ( ( $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'fields' ] [ $ v ] [ 'eval' ] [ 'isAssociative' ] || array_is_assoc ( $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'fields' ] [ $ v ] [ 'options' ] ) ) && isset ( $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'fields' ] [ $ v ] [ 'options' ] [ $ row [ $ v ] ] ) ) { $ args [ $ k ] = $ GLOBALS [ 'TL_DCA' ] [ $ table ] [ 'fields' ] [ $ v ] [ 'options' ] [ $ row [ $ v ] ] ; } else { $ args [ $ k ] = $ row [ $ v ] ; } } } // Shorten the label it if it is too long $ label = vsprintf ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'format' ] ? : '%s' , $ args ) ; if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'maxCharacters' ] > 0 && $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'maxCharacters' ] < \ strlen ( strip_tags ( $ label ) ) ) { $ label = trim ( StringUtil :: substrHtml ( $ label , $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'maxCharacters' ] ) ) . ' …'; } // Remove empty brackets (), [], {}, <> and empty tags from the label $ label = preg_replace ( '/\( *\) ?|\[ *\] ?|\{ *\} ?|< *> ?/' , '' , $ label ) ; $ label = preg_replace ( '/<[^>]+>\s*<\/[^>]+>/' , '' , $ label ) ; // Build the sorting groups if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'mode' ] > 0 ) { $ current = $ row [ $ firstOrderBy ] ; $ orderBy = $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'fields' ] ; $ sortingMode = ( \ count ( $ orderBy ) == 1 && $ firstOrderBy == $ orderBy [ 0 ] && $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'flag' ] != '' && $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ firstOrderBy ] [ 'flag' ] == '' ) ? $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'flag' ] : $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ firstOrderBy ] [ 'flag' ] ; $ remoteNew = $ this -> formatCurrentValue ( $ firstOrderBy , $ current , $ sortingMode ) ; // Add the group header if ( ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'showColumns' ] && ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'disableGrouping' ] && ( $ remoteNew != $ remoteCur || $ remoteCur === false ) ) { $ eoCount = - 1 ; $ group = $ this -> formatGroupHeader ( $ firstOrderBy , $ remoteNew , $ sortingMode , $ row ) ; $ remoteCur = $ remoteNew ; $ return .= '
  <tr>
    <td colspan="2" class="' . $ groupclass . '">' . $ group . '</td>
  </tr>' ; $ groupclass = 'tl_folder_list' ; } } $ return .= '
  <tr class="' . ( ( ++ $ eoCount % 2 == 0 ) ? 'even' : 'odd' ) . ' click2edit toggle_select hover-row">
    ' ; $ colspan = 1 ; // Call the label_callback ($row, $label, $this) if ( \ is_array ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'label_callback' ] ) || \ is_callable ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'label_callback' ] ) ) { if ( \ is_array ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'label_callback' ] ) ) { $ strClass = $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'label_callback' ] [ 0 ] ; $ strMethod = $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'label_callback' ] [ 1 ] ; $ this -> import ( $ strClass ) ; $ args = $ this -> $ strClass -> $ strMethod ( $ row , $ label , $ this , $ args ) ; } elseif ( \ is_callable ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'label_callback' ] ) ) { $ args = $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'label_callback' ] ( $ row , $ label , $ this , $ args ) ; } // Handle strings and arrays if ( ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'showColumns' ] ) { $ label = \ is_array ( $ args ) ? implode ( ' ' , $ args ) : $ args ; } elseif ( ! \ is_array ( $ args ) ) { $ args = array ( $ args ) ; $ colspan = \ count ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'fields' ] ) ; } } // Show columns if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'showColumns' ] ) { foreach ( $ args as $ j => $ arg ) { $ return .= '<td colspan="' . $ colspan . '" class="tl_file_list col_' . $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'fields' ] [ $ j ] . ( ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'label' ] [ 'fields' ] [ $ j ] == $ firstOrderBy ) ? ' ordered_by' : '' ) . '">' . ( $ arg ? : '-' ) . '</td>' ; } } else { $ return .= '<td class="tl_file_list">' . $ label . '</td>' ; } // Buttons ($row, $table, $root, $blnCircularReference, $childs, $previous, $next) $ return .= ( ( Input :: get ( 'act' ) == 'select' ) ? '
    <td class="tl_file_list tl_right_nowrap"><input type="checkbox" name="IDS[]" id="ids_' . $ row [ 'id' ] . '" class="tl_tree_checkbox" value="' . $ row [ 'id' ] . '"></td>' : '
    <td class="tl_file_list tl_right_nowrap">' . $ this -> generateButtons ( $ row , $ this -> strTable , $ this -> root ) . ( $ this -> strPickerFieldType ? $ this -> getPickerInputField ( $ row [ 'id' ] ) : '' ) . '</td>' ) . '
  </tr>' ; } // Close the table $ return .= '
</table>' . ( $ this -> strPickerFieldType == 'radio' ? '
<div class="tl_radio_reset">
<label for="tl_radio_reset" class="tl_radio_label">' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'resetSelected' ] . '</label> <input type="radio" name="picker" id="tl_radio_reset" value="" class="tl_tree_radio">
</div>' : '' ) . '
</div>' ; // Close the form if ( Input :: get ( 'act' ) == 'select' ) { // Submit buttons $ arrButtons = array ( ) ; if ( ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'notEditable' ] ) { $ arrButtons [ 'edit' ] = '<button type="submit" name="edit" id="edit" class="tl_submit" accesskey="s">' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'editSelected' ] . '</button>' ; } if ( ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'notDeletable' ] ) { $ arrButtons [ 'delete' ] = '<button type="submit" name="delete" id="delete" class="tl_submit" accesskey="d" onclick="return confirm(\'' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'delAllConfirm' ] . '\')">' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'deleteSelected' ] . '</button>' ; } if ( ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'notCopyable' ] ) { $ arrButtons [ 'copy' ] = '<button type="submit" name="copy" id="copy" class="tl_submit" accesskey="c">' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'copySelected' ] . '</button>' ; } if ( ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'notEditable' ] ) { $ arrButtons [ 'override' ] = '<button type="submit" name="override" id="override" class="tl_submit" accesskey="v">' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'overrideSelected' ] . '</button>' ; } // Call the buttons_callback (see #4691) if ( \ is_array ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'select' ] [ 'buttons_callback' ] ) ) { foreach ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'select' ] [ 'buttons_callback' ] as $ callback ) { if ( \ is_array ( $ callback ) ) { $ this -> import ( $ callback [ 0 ] ) ; $ arrButtons = $ this -> { $ callback [ 0 ] } -> { $ callback [ 1 ] } ( $ arrButtons , $ this ) ; } elseif ( \ is_callable ( $ callback ) ) { $ arrButtons = $ callback ( $ arrButtons , $ this ) ; } } } if ( \ count ( $ arrButtons ) < 3 ) { $ strButtons = implode ( ' ' , $ arrButtons ) ; } else { $ strButtons = array_shift ( $ arrButtons ) . ' ' ; $ strButtons .= '<div class="split-button">' ; $ strButtons .= array_shift ( $ arrButtons ) . '<button type="button" id="sbtog">' . Image :: getHtml ( 'navcol.svg' ) . '</button> <ul class="invisible">' ; foreach ( $ arrButtons as $ strButton ) { $ strButtons .= '<li>' . $ strButton . '</li>' ; } $ strButtons .= '</ul></div>' ; } $ return .= '
</div>
<div class="tl_formbody_submit" style="text-align:right">
<div class="tl_submit_container">
  ' . $ strButtons . '
</div>
</div>
</form>' ; } } return $ return ; }
List all records of the current table and return them as HTML string

@return string
List all records of the current table and return them as HTML string