Next major version 2 with PHP 8.1, Symfony 6, Tabler UI, 2FA ... (#2902)

This commit is contained in:
Kevin Papst
2022-12-31 21:19:55 +01:00
committed by GitHub
parent 95e06746bd
commit 90a0fd8a22
2164 changed files with 83700 additions and 86426 deletions

View File

@@ -9,112 +9,180 @@
namespace App\Twig;
use Symfony\Component\HttpFoundation\RequestStack;
use App\Entity\Bookmark;
use App\Entity\User;
use App\Repository\BookmarkRepository;
use App\Utils\ProfileManager;
use Symfony\Component\HttpFoundation\Session\Session;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
class DatatableExtensions extends AbstractExtension
final class DatatableExtensions extends AbstractExtension
{
/**
* @var RequestStack
* @var array<string, array<string, array<string, string|bool>>>
*/
protected $requestStack;
private array $dataTables = [];
private array $tableNames = [];
private ?string $prefix = null;
/**
* @var array
*/
protected $cookies = [];
/**
* @param RequestStack $requestStack
*/
public function __construct(RequestStack $requestStack)
public function __construct(private BookmarkRepository $bookmarkRepository, private ProfileManager $profileManager)
{
$this->requestStack = $requestStack;
}
/**
* {@inheritdoc}
*/
public function getFunctions()
public function getFunctions(): array
{
return [
new TwigFunction('is_visible_column', [$this, 'isColumnVisible']),
new TwigFunction('is_datatable_configured', [$this, 'isDatatableConfigured']),
new TwigFunction('initialize_datatable', [$this, 'initializeDatatable']),
new TwigFunction('datatable_column_class', [$this, 'getDatatableColumnClass']),
];
}
/**
* @param string $dataTable
* @return bool
*/
public function isDatatableConfigured(string $dataTable)
private function getDatatableName(string $dataTable): string
{
$cookie = $this->getVisibilityCookieName($dataTable);
if (!\array_key_exists($dataTable, $this->tableNames)) {
$this->tableNames[$dataTable] = $this->profileManager->getDatatableName($dataTable, $this->prefix);
}
return $this->requestStack->getCurrentRequest()->cookies->has($cookie);
return $this->tableNames[$dataTable];
}
/**
* @param string $dataTable
* @return string
*/
protected function getVisibilityCookieName(string $dataTable)
public function initializeDatatable(User $user, Session $session, string $dataTable, array $defaultColumns): array
{
return $dataTable . '_visibility';
}
if ($this->prefix === null) {
$this->prefix = $this->profileManager->getProfileFromSession($session);
$dataTable = $this->getDatatableName($dataTable);
}
/**
* This is only for datatables, do not use it outside this context.
*
* @param string $dataTable
* @param string $column
* @param array $columns
* @return bool
*/
public function isColumnVisible(string $dataTable, string $column, array $columns)
{
// name handling is spread between here and datatables.html.twig (data_table_column_modal)
$cookie = $this->getVisibilityCookieName($dataTable);
if (!isset($this->cookies[$cookie])) {
$visibility = false;
if ($this->requestStack->getCurrentRequest()->cookies->has($cookie)) {
$visibility = json_decode($this->requestStack->getCurrentRequest()->cookies->get($cookie), true);
if (!\array_key_exists($dataTable, $this->dataTables)) {
$columns = [];
foreach ($defaultColumns as $key => $settings) {
$columns[$key] = [
'visible' => $this->checkInColumDefinition($defaultColumns, $key),
'class' => \array_key_exists($key, $defaultColumns) ? $this->getClass($settings) : ''
];
// add an auto-generated class
$columns[$key]['class'] = trim($columns[$key]['class'] . ' col_' . $key);
}
$this->cookies[$cookie] = $visibility;
}
$values = $this->cookies[$cookie];
if (empty($values) || !\is_array($values)) {
return $this->checkInColumDefinition($columns, $column);
$bookmark = $this->bookmarkRepository->findBookmark($user, Bookmark::COLUMN_VISIBILITY, $dataTable);
if ($bookmark !== null) {
$content = $bookmark->getContent();
foreach ($content as $key => $value) {
if (!\array_key_exists($key, $columns)) {
// if a column does not exist any longer, it needs to be skipped, otherwise an error will
// be raised while accessing the visible/class keys
continue;
}
$columns[$key]['visible'] = (bool) $value;
}
// disable all columns, which were not bookmarked as visible
foreach (array_diff(array_keys($columns), array_keys($content)) as $key) {
if (!str_contains($columns[$key]['class'], 'alwaysVisible')) {
$columns[$key]['visible'] = false;
}
}
// now make sure that all columns have proper classes - this might only be applied if a bookmark exists
foreach (array_keys($columns) as $key) {
if ($columns[$key]['visible']) {
$columns[$key]['class'] = $this->makeVisible($columns[$key]['class']);
} else {
$columns[$key]['class'] = $this->makeHidden($columns[$key]['class']);
}
}
}
$this->dataTables[$dataTable] = $columns;
}
if (!isset($values[$column])) {
return $this->checkInColumDefinition($columns, $column);
return $this->dataTables[$dataTable];
}
public function getDatatableColumnClass(string $dataTable, string $column): string
{
$dataTable = $this->getDatatableName($dataTable);
if (!\array_key_exists($dataTable, $this->dataTables)) {
return '';
}
if ($values[$column] === false) {
if (!\array_key_exists($column, $this->dataTables[$dataTable])) {
return '';
}
return $this->dataTables[$dataTable][$column]['class'];
}
private function checkInColumDefinition(array $columns, string $column): bool
{
if (!\array_key_exists($column, $columns)) {
return false;
}
return true;
$tmp = $this->getClass($columns[$column]);
if (str_contains($tmp, 'alwaysVisible')) {
return true;
}
$result = true;
if (stripos($tmp, 'd-none') !== false) {
$result = false;
}
if (str_contains($tmp, '-table-cell')) {
$result = true;
}
return $result;
}
private function checkInColumDefinition(array $columns, string $column)
private function makeVisible(string $allClasses): string
{
if (\array_key_exists($column, $columns)) {
$tmp = $columns[$column];
if (\is_array($tmp)) {
$tmp = $tmp['class'];
}
foreach (explode(' ', $tmp) as $class) {
if ($class === 'hidden') {
return false;
}
$newClass = [];
foreach (explode(' ', $allClasses) as $class) {
if (!str_contains($class, '-none')) {
$newClass[] = $class;
}
}
return true;
return implode(' ', $newClass);
}
private function makeHidden(string $allClasses): string
{
$newClass = [];
foreach (explode(' ', $allClasses) as $class) {
if (!str_contains($class, '-table-cell')) {
$newClass[] = $class;
}
}
$newClass = implode(' ', $newClass);
if (!str_contains($newClass, '-none')) {
$newClass .= ' d-none';
}
return $newClass;
}
private function getClass($class): string
{
if (\is_array($class)) {
if (!\array_key_exists('class', $class)) {
return '';
}
return $class['class'];
}
if (!\is_string($class)) {
return '';
}
return $class;
}
}