3 namespace Drupal\views\Plugin\views\field;
5 use Drupal\Core\Access\AccessManagerInterface;
6 use Drupal\Core\Form\FormStateInterface;
7 use Drupal\Core\Render\BubbleableMetadata;
8 use Drupal\Core\Routing\RedirectDestinationTrait;
9 use Drupal\views\ResultRow;
10 use Symfony\Component\DependencyInjection\ContainerInterface;
13 * Field handler to present a link to an entity.
15 * @ingroup views_field_handlers
17 abstract class LinkBase extends FieldPluginBase {
19 use RedirectDestinationTrait;
22 * The access manager service.
24 * @var \Drupal\Core\Access\AccessManagerInterface
26 protected $accessManager;
29 * Current user object.
31 * @var \Drupal\Core\Session\AccountInterface
33 protected $currentUser;
36 * Constructs a LinkBase object.
38 * @param array $configuration
39 * A configuration array containing information about the plugin instance.
40 * @param string $plugin_id
41 * The plugin_id for the plugin instance.
42 * @param mixed $plugin_definition
43 * The plugin implementation definition.
44 * @param \Drupal\Core\Access\AccessManagerInterface $access_manager
47 public function __construct(array $configuration, $plugin_id, $plugin_definition, AccessManagerInterface $access_manager) {
48 parent::__construct($configuration, $plugin_id, $plugin_definition);
49 $this->accessManager = $access_manager;
55 public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
60 $container->get('access_manager')
65 * Gets the current active user.
67 * @todo: https://www.drupal.org/node/2105123 put this method in
68 * \Drupal\Core\Plugin\PluginBase instead.
70 * @return \Drupal\Core\Session\AccountInterface
73 protected function currentUser() {
74 if (!$this->currentUser) {
75 $this->currentUser = \Drupal::currentUser();
77 return $this->currentUser;
83 protected function defineOptions() {
84 $options = parent::defineOptions();
85 $options['text'] = ['default' => $this->getDefaultLabel()];
92 public function buildOptionsForm(&$form, FormStateInterface $form_state) {
94 '#type' => 'textfield',
95 '#title' => $this->t('Text to display'),
96 '#default_value' => $this->options['text'],
98 parent::buildOptionsForm($form, $form_state);
100 // The path is set by ::renderLink() so we do not allow to set it.
101 $form['alter'] += ['path' => [], 'query' => [], 'external' => []];
102 $form['alter']['path'] += ['#access' => FALSE];
103 $form['alter']['query'] += ['#access' => FALSE];
104 $form['alter']['external'] += ['#access' => FALSE];
110 public function usesGroupBy() {
117 public function query() {
118 $this->addAdditionalFields();
124 public function render(ResultRow $row) {
125 $access = $this->checkUrlAccess($row);
126 $build = ['#markup' => $access->isAllowed() ? $this->renderLink($row) : ''];
127 BubbleableMetadata::createFromObject($access)->applyTo($build);
132 * Checks access to the link route.
134 * @param \Drupal\views\ResultRow $row
137 * @return \Drupal\Core\Access\AccessResultInterface
140 protected function checkUrlAccess(ResultRow $row) {
141 $url = $this->getUrlInfo($row);
142 return $this->accessManager->checkNamedRoute($url->getRouteName(), $url->getRouteParameters(), $this->currentUser(), TRUE);
146 * Returns the URI elements of the link.
148 * @param \Drupal\views\ResultRow $row
151 * @return \Drupal\Core\Url
152 * The URI elements of the link.
154 abstract protected function getUrlInfo(ResultRow $row);
157 * Prepares the link to view a entity.
159 * @param \Drupal\views\ResultRow $row
163 * Returns a string for the link text.
165 protected function renderLink(ResultRow $row) {
166 $this->options['alter']['make_link'] = TRUE;
167 $this->options['alter']['url'] = $this->getUrlInfo($row);
168 $text = !empty($this->options['text']) ? $this->sanitizeValue($this->options['text']) : $this->getDefaultLabel();
169 $this->addLangcode($row);
174 * Adds language information to the options.
176 * @param \Drupal\views\ResultRow $row
179 protected function addLangcode(ResultRow $row) {
180 $entity = $this->getEntity($row);
181 $langcode_key = $entity ? $entity->getEntityType()->getKey('langcode') : FALSE;
182 if ($langcode_key && isset($this->aliases[$langcode_key])) {
183 $this->options['alter']['language'] = $entity->language();
188 * Returns the default label for this link.
191 * The default link label.
193 protected function getDefaultLabel() {
194 return $this->t('link');