contacts-8.x-1.x-dev/src/Controller/DashboardController.php
src/Controller/DashboardController.php
<?php
namespace Drupal\contacts\Controller;
use Drupal\Core\Ajax\AjaxHelperTrait;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseDialogCommand;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Ajax\OpenOffCanvasDialogCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Block\BlockManager;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Layout\LayoutPluginManager;
use Drupal\Core\Path\PathValidatorInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\ContextHandlerInterface;
use Drupal\Core\Plugin\Context\EntityContext;
use Drupal\Core\Plugin\ContextAwarePluginInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Core\Url;
use Drupal\contacts\Ajax\ContactsTab;
use Drupal\contacts\ContactsTabManager;
use Drupal\contacts\Entity\ContactTab;
use Drupal\contacts\Form\DashboardBlockConfigureForm;
use Drupal\contacts\Form\DashboardTabConfigureForm;
use Drupal\contacts\ManageDashboardHelper;
use Drupal\user\UserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
/**
* Controller routines for contact dashboard tabs and ajax.
*/
class DashboardController extends ControllerBase {
use AjaxHelperTrait;
use StringTranslationTrait;
/**
* The tab manager.
*
* @var \Drupal\contacts\ContactsTabManager
*/
protected $tabManager;
/**
* The block plugin manager.
*
* @var \Drupal\Core\Block\BlockManager
*/
protected $blockManager;
/**
* The current request.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* The path validator service.
*
* @var \Drupal\Core\Path\PathValidatorInterface
*/
protected $pathValidator;
/**
* The context handler.
*
* @var \Drupal\Core\Plugin\Context\ContextHandlerInterface
*/
protected $contextHandler;
/**
* The layout manager service.
*
* @var \Drupal\Core\Layout\LayoutPluginManager
*/
protected $layoutManager;
/**
* The renderer.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* Manage dashboard helper.
*
* @var \Drupal\contacts\ManageDashboardHelper
*/
protected $manageDashboardHelper;
/**
* Theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface
*/
protected ThemeManagerInterface $themeManager;
/**
* Construct the dashboard controller.
*
* @param \Drupal\contacts\ContactsTabManager $tab_manager
* The tab manager.
* @param \Drupal\Core\Block\BlockManager $block_manager
* The block plugin manager.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
* @param \Drupal\Core\Path\PathValidatorInterface $path_validator
* The path validator service.
* @param \Drupal\Core\Plugin\Context\ContextHandlerInterface $context_handler
* The context handler.
* @param \Drupal\Core\Form\FormBuilderInterface $form_builder
* The form builder service.
* @param \Drupal\Core\Layout\LayoutPluginManager $layout_manager
* The layout manager service.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer.
* @param \Drupal\contacts\ManageDashboardHelper $manage_dashboard_helper
* Manage dashboard helper.
*/
public function __construct(ContactsTabManager $tab_manager, BlockManager $block_manager, RequestStack $request_stack, PathValidatorInterface $path_validator, ContextHandlerInterface $context_handler, FormBuilderInterface $form_builder, LayoutPluginManager $layout_manager, RendererInterface $renderer, ManageDashboardHelper $manage_dashboard_helper) {
$this->tabManager = $tab_manager;
$this->blockManager = $block_manager;
$this->request = $request_stack->getCurrentRequest();
$this->pathValidator = $path_validator;
$this->contextHandler = $context_handler;
$this->formBuilder = $form_builder;
$this->layoutManager = $layout_manager;
$this->renderer = $renderer;
$this->manageDashboardHelper = $manage_dashboard_helper;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$self = new static(
$container->get('contacts.tab_manager'),
$container->get('plugin.manager.block'),
$container->get('request_stack'),
$container->get('path.validator'),
$container->get('context.handler'),
$container->get('form_builder'),
$container->get('plugin.manager.core.layout'),
$container->get('renderer'),
$container->get('contacts.manage_dashboard_helper')
);
// @todo Consolidate parameters for 4.x
$self->themeManager = $container->get('theme.manager');
return $self;
}
/**
* Main entrypoint into the Contacts search/browse page.
*
* Redirects to one of the other actions depending on which
* is configured as the default page.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse|array
* Redirect response to the default contacts screen or render array.
*/
public function dashboard() {
$config = $this->config('contacts.configuration');
// If default Contacts route isn't configured, use the legacy
// behaviour.
$route = $config->get('default_contacts_dashboard_route') ?? 'contacts.collection.all';
if ($route === 'contacts.collection.all') {
// For backwards compatibility, if we're using the legacy unified
// dashboard we need to render it under the /admin/contacts url
// rather than redirecting to /admin/contacts/all.
return $this->legacyUnifiedDashboard();
}
return $this->redirect($route);
}
/**
* Renders the Individuals dashboard browse/search page.
*
* @return array
* Render array.
*/
public function individualsDashboard() {
$build['view'] = views_embed_view('contacts_dashboard_indexed', 'individuals');
return $build;
}
/**
* Renders the Organisations dashboard browse/search page.
*
* @return array
* Render array.
*/
public function organisationsDashboard() {
$build['view'] = views_embed_view('contacts_dashboard_indexed', 'organisations');
return $build;
}
/**
* The main legacy dashboard browse/search page.
*
* @return array
* Render array.
*/
public function legacyUnifiedDashboard() {
$build = $this->blockManager
->createInstance('views_block:contacts_dashboard_indexed-full')
->build();
// Remove the theme wrapper container, which unnecessarily wraps the view
// container in an extra container that we don't want. contacts_theme
// handles applying the appropriate classes to the view div directly, so no
// need for the container.
/* @see contacts_theme_views_pre_render */
$build['#theme_wrappers'] = [];
return $build;
}
/**
* View a specific contact.
*
* @param \Drupal\user\UserInterface $user
* The user to view.
* @param string $subpage
* The name of the default tab.
*
* @return array
* Render array.
*/
public function contact(UserInterface $user, $subpage) {
$build = [
'#type' => 'html_tag',
'#tag' => 'div',
'#attributes' => ['class' => ['contact-page']],
];
$build['#attached']['library'][] = 'contacts/contact';
switch ($this->themeManager->getActiveTheme()->getName()) {
case 'claro':
$build['#attached']['library'][] = 'contacts/contact.claro';
break;
case 'seven':
$build['#attached']['library'][] = 'contacts/contact.seven';
break;
case 'gin':
$build['#attached']['library'][] = 'contacts/contact.gin';
break;
}
$blocks = [
'summary' => 'summary:contacts_dashboard',
'tabs' => 'tabs:contacts_dashboard',
];
// Make user and subpage available to blocks as contexts.
$contexts = $this->buildTabContexts($user, $subpage);
$i = 0;
foreach ($blocks as $name => $block_id) {
$block = $this->blockManager->createInstance($block_id);
if ($block instanceof ContextAwarePluginInterface) {
$this->contextHandler->applyContextMapping($block, $contexts);
}
$build[$name] = $block->build();
$build[$name]['#weight'] = $i;
$i++;
}
return $build;
}
/**
* Gets the page title for the contact page. Uses the user's name.
*
* @param \Drupal\user\UserInterface $user
* The user being viewed.
*
* @return \Drupal\Component\Render\MarkupInterface|string
* User's name.
*/
public function contactTitle(UserInterface $user) {
return $user->getDisplayName();
}
/**
* Return the AJAX command for changing tab.
*
* @param \Drupal\user\UserInterface $user
* The user we are viewing.
* @param string $subpage
* The subpage we want to view.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* The response commands.
*
* @todo Combine this method with \Drupal\contacts\Plugin\Block\ContactsDashboardTabs::buildContent().
*/
public function ajaxTab(UserInterface $user, $subpage) {
$url = Url::fromRoute('contacts.contact', [
'user' => $user->id(),
'subpage' => $subpage,
]);
// Return as non-ajax.
if (!$this->isAjax()) {
return $this->redirect('contacts.contact', [
'user' => $user->id(),
'subpage' => $subpage,
]);
}
$block = $this->blockManager->createInstance('tabs:contacts_dashboard');
// Build our contexts.
if ($block instanceof ContextAwarePluginInterface) {
$contexts = $this->buildTabContexts($user, $subpage);
// Apply the contexts to the block.
$this->contextHandler->applyContextMapping($block, $contexts);
}
$block_content = $block->build();
$content['tabs'] = [
'#theme' => 'block',
'#attributes' => [],
'#configuration' => $block->getConfiguration(),
'#plugin_id' => $block->getPluginId(),
'#base_plugin_id' => $block->getBaseId(),
'#derivative_plugin_id' => $block->getDerivativeId(),
'#weight' => $block->getConfiguration()['weight'] ?? 0,
'content' => $block_content,
];
// Load the tab.
$tab = $this->tabManager->getTabByPath($subpage);
// Create AJAX Response object.
$response = new AjaxResponse();
$response->addCommand(new ContactsTab($tab->id(), $url->toString()));
$response->addCommand(new ReplaceCommand('#contacts-tabs', $content));
$this->offCanvasCommand($response, $tab);
// Return ajax response.
return $response;
}
/**
* Adds AJAX command to response to show default tab offcanvas content.
*
* @param \Drupal\contacts\Entity\ContactTab $tab
* The tab to get content for.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* The response commands.
*/
public function offCanvasUpdate(ContactTab $tab) {
$response = new AjaxResponse();
$this->offCanvasCommand($response, $tab);
return $response;
}
/**
* Ajax command to manually show the manage dashboard sidebar.
*/
public function ajaxShowSidebar() {
$response = new AjaxResponse();
// Use a fake request based on the referrer to work out the current tab.
$fake_request = Request::create($this->request->server->get('HTTP_REFERER'));
if ($url_object = $this->pathValidator->getUrlIfValid($fake_request->getRequestUri())) {
$subpage = $url_object->getRouteParameters()['subpage'];
$tab = $this->tabManager->getTabByPath($subpage);
$this->offCanvasCommand($response, $tab);
}
return $response;
}
/**
* Adds AJAX command to response to show default tab offcanvas content.
*
* @param \Drupal\Core\Ajax\AjaxResponse $response
* Response to add command to.
* @param \Drupal\contacts\Entity\ContactTab $tab
* The tab to get content for.
*/
public function offCanvasCommand(AjaxResponse $response, ContactTab $tab) {
// Open/close the off-canvas tray.
if ($this->manageDashboardHelper->isInManageMode()) {
$main_content = $this->buildDefaultOffCanvas($tab);
$content = $this->renderer->renderRoot($main_content);
$main_content['#attached']['library'][] = 'core/drupal.dialog.off_canvas';
$response->setAttachments($main_content['#attached']);
// If the main content doesn't provide a title, use the title resolver.
$title = $main_content['#title'] ?? '';
$response->addCommand(new OpenOffCanvasDialogCommand($title, $content, []));
}
else {
$response->addCommand(new CloseDialogCommand('#drupal-off-canvas'));
}
}
/**
* Adds AJAX command to response to show default tab offcanvas content.
*
* @param \Drupal\Core\Ajax\AjaxResponse $response
* Response to add command to.
* @param \Drupal\contacts\Entity\ContactTab $tab
* The tab to get content for.
*/
public function updateTabCommand(AjaxResponse $response, ContactTab $tab) {
// Open/close the off-canvas tray.
$response->addCommand(new InvokeCommand('[data-contacts-tab-id="' . $tab->id() . '"]', 'click'));
}
/**
* Return the AJAX command for changing tab.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* The response commands.
*/
public function ajaxManageMode() {
$manage_mode = $this->manageDashboardHelper->isInManageMode();
$force = $this->request->query->get('force');
// If a different user is in manage mode, display a warning.
if (!$manage_mode && ($this->manageDashboardHelper->otherUserInManageMode()) && !$force) {
return $this->showManageModeWarning($this->manageDashboardHelper->getManageModeUser());
}
// Get parameters from referrer request.
$referrer = $this->request->server->get('HTTP_REFERER');
$fake_request = Request::create($referrer);
/** @var \Drupal\Core\Url $url_object */
$url_object = $this->pathValidator->getUrlIfValid($fake_request->getRequestUri());
if ($url_object) {
$this->manageDashboardHelper->setManageMode(!$manage_mode, (bool) $force);
$route_params = $url_object->getRouteParameters();
/** @var \Drupal\user\UserInterface $contact */
$contact = $this->entityTypeManager()->getStorage('user')->load($route_params['user']);
$response = $this->ajaxTab($contact, $route_params['subpage']);
if ($force) {
$response->addCommand(new CloseModalDialogCommand());
}
return $response;
}
return FALSE;
}
/**
* Generate an AJAX content update for a tab.
*
* @param \Drupal\contacts\Entity\ContactTab $tab
* The tab entity to refresh.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* The response commands.
*/
public function ajaxManageModeRefresh(ContactTab $tab) {
$blocks = $this->tabManager->getBlocks($tab);
$layout = $tab->get('layout') ?: 'contacts_tab_content.stacked';
$layout = $this->layoutManager->createInstance($layout, []);
$content['content'] = [
'#prefix' => '<div id="contacts-tabs-content" class="contacts-tabs-content flex-fill">',
'#suffix' => '</div>',
'#type' => 'contact_tab_content',
'#tab' => $tab,
'#layout' => $layout,
'#subpage' => $tab->getPath(),
'#blocks' => $blocks,
'#manage_mode' => TRUE,
'#attributes' => ['class' => ['dash-content']],
];
$content['messages'] = [
'#type' => 'status_messages',
'#weight' => -99,
];
// Create AJAX Response object.
$response = new AjaxResponse();
$response->addCommand(new HtmlCommand('#contacts-tabs-content', $content));
// Return ajax response.
return $response;
}
/**
* Provides a title callback to get the block's admin label.
*
* @param \Drupal\contacts\Entity\ContactTab $tab
* The the tab entity that contains the block.
* @param string $block_name
* The unique name of the block on the tab.
*
* @return \Drupal\Core\StringTranslation\TranslatableMarkup
* The title.
*/
public function offCanvasTitle(ContactTab $tab, $block_name) {
$block_config = $tab->getBlock($block_name);
$block = $this->blockManager->createInstance($block_config['id'], $block_config);
return $this->t('Configure @block', [
'@block' => $block->getPluginDefinition()['admin_label'],
]);
}
/**
* Renders the off Canvas configure form for a new block.
*
* @param \Drupal\contacts\Entity\ContactTab $tab
* The the tab entity that contains the block.
* @param string $plugin_id
* The plugin id to create a new block from.
* @param string|null $region
* The region to add the block to..
*
* @return array
* The renderable block config form.
*/
public function offCanvasBlockAdd(ContactTab $tab, $plugin_id, $region = NULL) {
$config = [];
if ($region) {
$config['region'] = $region;
}
/** @var \Drupal\Core\Block\BlockPluginInterface $block */
$block = $this->blockManager->createInstance($plugin_id, $config);
$this->tabManager->buildBlockContextMapping($tab, $block);
$block_config = $block->getConfiguration();
$block_config['create'] = TRUE;
$name = $tab->addBlock($plugin_id, $block_config);
return $this->offCanvasBlock($tab, $name);
}
/**
* Renders the off Canvas configure form for a Dashboard block.
*
* @param \Drupal\contacts\Entity\ContactTab $tab
* The the tab entity that contains the block.
* @param string $block_name
* The unique name of the block on the tab.
*
* @return array
* The renderable block config form.
*/
public function offCanvasBlock(ContactTab $tab, $block_name) {
$block_config = $tab->getBlock($block_name);
$block = $this->blockManager->createInstance($block_config['id'], $block_config);
$content = [];
$content['form '] = $this->formBuilder->getForm(DashboardBlockConfigureForm::class, $tab, $block);
$content['meta'] = method_exists($block, 'getManageMeta') ? $block->getManageMeta() : [];
return $content;
}
/**
* Renders the off Canvas configure form for a Dashboard block.
*
* @param \Drupal\contacts\Entity\ContactTab $tab
* The the tab entity that contains the block.
*
* @return array
* The renderable block config form.
*/
public function offCanvasTab(ContactTab $tab) {
$content = [];
$content['form '] = $this->formBuilder->getForm(DashboardTabConfigureForm::class, $tab);
$content['meta'] = $tab->getManageMeta();
return $content;
}
/**
* Add a block to a tab.
*
* @param \Drupal\contacts\Entity\ContactTab $tab
* The tab to add the block to.
* @param string $block_config
* The block data provided by post request.
*
* @return mixed
* The block configuration array or FALSE if adding failed.
*/
public function ajaxAddBlock(ContactTab $tab, $block_config) {
if (empty($block_config['id'])) {
// @todo Throw error - cannot create block without ID.
return FALSE;
}
/** @var \Drupal\Core\Block\BlockPluginInterface $block */
$block = $this->blockManager->createInstance($block_config['id'], $block_config);
$block_config = $block->getConfiguration();
// Give everything the tab's user context.
if ($block_config['id'] !== 'contacts_entity:user-user') {
$block_config['context_mapping'] = ['user' => 'user'];
$relationships = $tab->getRelationships();
// @todo Better relationship handling.
if (!empty($block_config['_entity_relationship']) && !empty($relationships[$block_config['_entity_relationship']])) {
$block_config['context_mapping'] = ['entity' => $block_config['_entity_relationship']];
unset($block_config['_entity_relationship']);
}
}
else {
$block_config['context_mapping'] = ['entity' => 'user'];
}
$tab->setBlock($block_config['name'], $block_config);
return $block_config;
}
/**
* Update a block regions and positions in a tab.
*
* @return \Symfony\Component\HttpFoundation\Response
* The response.
*/
public function ajaxUpdateBlocks() {
/** @var \Drupal\contacts\Entity\ContactTab $tab */
$regions = $this->request->request->get('regions');
$tab = $this->request->request->get('tab');
$tab = $this->entityTypeManager()->getStorage('contact_tab')->load($tab);
$changed = FALSE;
foreach ($regions as $region_data) {
foreach ($region_data['blocks'] as $weight => $block_info) {
$block_config = $block = $tab->getBlock($block_info['name']);
$block['weight'] = $weight;
if (!empty($region_data['region'])) {
$block['region'] = $region_data['region'];
}
// Check for changes to block config.
if (!empty(array_diff_assoc($block, $block_config))) {
$changed = TRUE;
$tab->setBlock($block['name'], $block);
}
}
}
// Return updated block configuration for verification.
$response_data = ['blocks' => $tab->getBlocks()];
// Save if anything has changed.
if ($changed) {
$tab->save();
$response_data['tab_changed'] = TRUE;
}
$response = new Response();
$response->setContent(json_encode($response_data));
$response->headers->set('Content-Type', 'application/json');
$response->setStatusCode(Response::HTTP_OK);
return $response;
}
/**
* Update the order of tabs after sorting.
*
* @return \Symfony\Component\HttpFoundation\Response
* The response.
*/
public function ajaxUpdateTabs() {
$tabs = $this->request->request->get('tabs');
$json = [];
$previous = -101;
foreach (array_filter($tabs) as $tab) {
/** @var \Drupal\contacts\Entity\ContactTab $tab */
$tab = $this->entityTypeManager()->getStorage('contact_tab')->load($tab);
$current_weight = $tab->get('weight');
// Where possible preserve the existing tab weight.
if ($previous < $current_weight) {
$new = $current_weight;
}
else {
$new = $previous + 5;
}
$tab->set('weight', $new);
$tab->save();
$json[] = ['id' => $tab->id(), 'weight' => $new];
$previous = $new;
}
$response = new Response();
$response->setContent(json_encode($json));
$response->headers->set('Content-Type', 'application/json');
$response->setStatusCode(Response::HTTP_OK);
return $response;
}
/**
* The default off canvas information in manage mode.
*
* @param \Drupal\contacts\Entity\ContactTab $tab
* The tab to add the block to.
*
* @return array
* A render array.
*/
public function buildDefaultOffCanvas(ContactTab $tab) {
$output['#title'] = $this->t('Manage Mode');
$output['content'] = ['#type' => 'container'];
$output['content']['title'] = [
'#type' => 'html_tag',
'#tag' => 'h2',
'#value' => $this->t('@label tab', ['@label' => $tab->label()]),
];
// Create a fake request so we can extract the user from the referring url.
$fake_request = Request::create($this->request->server->get('HTTP_REFERER'));
/** @var \Drupal\Core\Url $url_object */
if ($url_object = $this->pathValidator->getUrlIfValid($fake_request->getRequestUri())) {
$user = $url_object->getRouteParameters()['user'];
$destination = Url::fromRoute('contacts.contact', ['user' => $user])
->toString();
}
$link_options = [
'attributes' => ['target' => '_blank'],
'query' => ['destination' => $destination],
];
$output['content']['links'] = [
'#theme' => 'item_list',
'#items' => [
'add_tab' => [
'#type' => 'link',
'#title' => $this->t('Add Tab'),
'#weight' => 15,
'#url' => Url::fromRoute("entity.contact_tab.add_form", [], $link_options),
],
'add_profile' => [
'#type' => 'link',
'#title' => $this->t('Add Profile Type'),
'#weight' => 20,
'#url' => Url::fromRoute("entity.profile_type.add_form", [], $link_options),
],
'manage_profiles' => [
'#type' => 'link',
'#title' => $this->t('Manage Profile Types'),
'#weight' => 25,
'#url' => Url::fromRoute("entity.profile_type.collection", [], $link_options),
],
'add_role' => [
'#type' => 'link',
'#title' => $this->t('Add Contact Role'),
'#weight' => 30,
'#url' => Url::fromRoute("user.role_add", [], $link_options),
],
'manage_roles' => [
'#type' => 'link',
'#title' => $this->t('Manage Roles'),
'#weight' => 35,
'#url' => Url::fromRoute("entity.user_role.collection", [], $link_options),
],
],
'#title' => 'Create:',
];
return $output;
}
/**
* Shows a warning dialog that another user is already in manage mode.
*
* @param int $user_id
* ID of the user in manage mode.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* The ajax response.
*/
protected function showManageModeWarning($user_id) {
/** @var \Drupal\user\Entity\User $user */
$user = $this->entityTypeManager()->getStorage('user')->load($user_id);
$content = [
'message' => [
'#markup' => $this->t('Another user (@name) is already in Manage Mode. Are you sure you want to continue?', [
'@name' => $user->getDisplayName(),
]),
],
'buttons' => [
'#type' => 'actions',
// Needs form-actions class on the container and button class on the
// link, otherwise the clientside dialog behaviour won't add the link
// to the buttons area of the dialog.
'#attributes' => ['class' => 'form-actions'],
'continue' => [
'#type' => 'link',
'#url' => Url::fromRoute('contacts.ajax.manage_mode', ['force' => TRUE]),
'#title' => $this->t('Continue'),
'#attributes' => ['class' => ['use-ajax', 'button']],
],
'cancel' => [
'#type' => 'link',
'#title' => $this->t('Cancel'),
'#url' => Url::fromRoute('<none>'),
'#attributes' => ['class' => ['close-dialog', 'button']],
],
],
];
return AjaxResponse::create()->addCommand(new OpenModalDialogCommand('Warning', $content));
}
/**
* Builds contexts for use in contact dashboard tabs.
*
* @param \Drupal\user\UserInterface $user
* The user to view.
* @param string $subpage
* The sub page (tab) to pre-load.
*
* @return \Drupal\Core\Plugin\Context\Context[]
* Array of contexts.
*/
protected function buildTabContexts(UserInterface $user, $subpage): array {
$contexts = [
'user' => EntityContext::fromEntity($user),
'subpage' => new Context(new ContextDefinition('string'), $subpage),
];
return $contexts;
}
}
