-
-
Notifications
You must be signed in to change notification settings - Fork 21
Description
For example, I have toggle action that simply redirects user back to the data table if everything went fine and I would like to end up back where I was. Right now I have to manually take out query parameters from Request and add them when generating row action href. Is there a build-in way that provides all data table query params (filters and pagination), instead of me, adding them manually?
Current way I do:
$request = $this->requestStack->getCurrentRequest();
$builder->addRowAction("edit", ButtonActionType::class, [
"href" => fn(User $user) => $this->urlGenerator->generate("admin.user.edit", [
...$request->query->all(),
"id" => $user->getId(),
]),
]);Something like this would be great:
$builder->addRowAction("edit", ButtonActionType::class, [
"href" => fn(User $user, array $dataTableQuery) => $this->urlGenerator->generate("admin.user.edit", [
...$dataTableQuery,
"id" => $user->getId(),
]),
]);Or even better, modify the url afterwards, so:
$builder->addRowAction("edit", ButtonActionType::class, [
"href" => fn(User $user) => $this->urlGenerator->generate("admin.user.edit", ["id" => $user->getId()]),
]);And the row action builder would parse the url, extract user params, add data table params and add back user params:
public function buildView(ActionView $view, ActionInterface $action, array $options): void
{
$dataTableQuery = ...;
if ($view->parent instanceof ColumnValueView) {
$value = $view->parent->value;
foreach (['href', 'target'] as $optionName) {
if (is_callable($options[$optionName])) {
$userUrl = $options[$optionName]($value);
} else {
$userUrl = $options[$optionName];
}
$parsedUserUrl = parse_url($userUrl);
$userQuery = [];
parse_str($parsedUserUrl["query"], $userQuery);
$replacementQuery = http_build_query([...$dataTableQuery, ...$userQuery]);
// yes, I did take php.net example
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
$user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
$pass = ($user || $pass) ? "$pass@" : '';
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
$options[$optionName] = "$scheme$user$pass$host$port$path$replacementQuery$fragment";
}
}
$view->vars = array_replace($view->vars, [
'href' => $options['href'],
'target' => $options['target'],
]);
}If this feels as a hacky solution, what about allowing us to pass simply the route and params, and data-table would add its own:
$builder->addRowAction("edit", ButtonActionType::class, [
"route" => "admin.user.edit",
"parameters" => fn(User $user) => ["id" => $user->getId()],
]);
public function buildView(ActionView $view, ActionInterface $action, array $options): void
{
if ($view->parent instanceof ColumnValueView) {
$value = $view->parent->value;
if($options["route"] !== null) {
$options["href"] = $this->urlGenerator->generate(
$options["route"],
[
...$dataTableQuery,
...$options["parameters"] ?? [],
],
);
}
}
$view->vars = array_replace($view->vars, [
'href' => $options['href'],
'target' => $options['target'],
]);
}Lastly, if we really care about having the route clickable (Symfony plugin for JetBrains), you could wrap around UrlGenerator that would automatically add data table query as parameter and we could use that instead:
$builder->addRowAction("edit", ButtonActionType::class, [
"href" => fn(User $user) => $this->dataTableUrlGenerator->generate("admin.user.edit", ["id" => $user->getId()]),
]);
// then have class DataTableUrlGenerator
namespace App\DataTable;
use Symfony\Component\Routing\Generator\UrlGenerator;
class DataTableUrlGenerator extends UrlGenerator
{
// ... whatever is needed
public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string
{
$parameters = [
...$this->getDataTableQueryParameters(),
...$parameters,
];
return parent::generate($name, $parameters, $referenceType);
}
}