route_ui-1.0.0-alpha2/src/CustomActionLinkPluginTrait.php
src/CustomActionLinkPluginTrait.php
<?php
namespace Drupal\route_ui;
use Drupal\Core\Access\AccessManagerInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
/**
* Provides common functionality for plugins to display custom action links.
*/
trait CustomActionLinkPluginTrait {
use StringTranslationTrait;
/**
* Adds the route configure form to a form.
*
* @param array $form
* The form to add the route configure form to.
* @param array $config
* Array of route configuration. Has the keys:
* - 'route_name'
* - 'route_parameters'
* - 'link_title'
* - 'add_destination'.
*
* @return array
* The form.
*/
protected function buildRouteConfigureForm(array $form, array $config): array {
// Create the form.
$form['custom_action_links'] = [
'#type' => 'container',
];
$action_links = $config['custom_action_links'] ?? [];
foreach ($action_links ?? [] as $key => $action_link) {
$form['custom_action_links'][$key]['route_details'] = [
'#type' => 'route_ui',
'#title' => $this->t('Custom action link @number details', ['@number' => $key + 1]),
'#open' => $key === 0 || !empty($action_link['route_name']),
'#route' => $action_link,
'#route_access_check' => FALSE,
];
}
// Add a empty action link to ensure we can add additional links.
$key = count($action_links);
$form['custom_action_links'][$key]['route_details'] = [
'#type' => 'route_ui',
'#title' => $this->t('Custom action link @number details', ['@number' => $key + 1]),
'#open' => $key === 0,
'#route_access_check' => FALSE,
];
return $form;
}
/**
* Converts configuration into a render array of action links.
*
* @param array $config
* The configuration.
* @param \Drupal\Core\Access\AccessManagerInterface $access_manager
* The route access manager.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
*
* @return array
* The render array.
*/
private function toRenderArray(array $config, AccessManagerInterface $access_manager, AccountInterface $account): array {
$cacheability = new CacheableMetadata();
$cacheability->addCacheContexts(['route']);
foreach ($config['custom_action_links'] as $values) {
$route_name = $values['route_name'];
$route_parameters = $values['route_parameters'];
$access = $access_manager->checkNamedRoute($route_name, $route_parameters, $account, TRUE);
$url = Url::fromRoute($route_name, $route_parameters);
if (!empty($values['add_destination'])) {
$url->setOption('query', \Drupal::service('redirect.destination')->getAsArray());
}
$links[] = [
'#theme' => 'menu_local_action',
'#link' => [
'title' => $values['link_title'],
'url' => $url,
],
'#access' => $access,
];
$cacheability->addCacheableDependency($access);
}
// Add a container to make it easy to consistently theme both the block and
// the view.
$container = [
'#theme' => 'route_ui_custom_action_links',
'#links' => $links ?? [],
];
$cacheability->applyTo($container);
return $container;
}
/**
* Massages a form value into the expected value.
*
* @param array $custom_action_links
* An array of action links as produced by the render element.
*
* @return array
* An array of action links as expected by the configuration.
*
* @todo Refactor to be part of a render element.
*/
private function massageCustomActionLinksValue(array $custom_action_links): array {
foreach ($custom_action_links as &$action_link) {
$action_link = $action_link['route_details'];
}
// Remove links with no route name.
return array_filter($custom_action_links, function ($action_link) {
return !empty($action_link['route_name']);
});
}
}
