Loading src/Plugin/views/area/Link.php +30 −9 Original line number Diff line number Diff line Loading @@ -70,7 +70,20 @@ class Link extends TokenizeAreaPluginBase { } /** * {@inheritdoc} * Create method. * * The base interface is undocumented, so inheritdoc fails. * * @param \Symfony\Component\DependencyInjection\ContainerInterface $container * The service container this instance should use. * @param array $configuration * An associative array containing the plugin's configuration. * @param mixed $plugin_id * The plugin Identifer. * @param mixed $plugin_definition * The plugin implementation definition. * * @see https://www.drupal.org/project/drupal/issues/2634022 */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( Loading Loading @@ -114,7 +127,7 @@ class Link extends TokenizeAreaPluginBase { * * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { public function buildOptionsForm(mixed &$form, FormStateInterface $form_state): void { parent::buildOptionsForm($form, $form_state); $form['link_text'] = [ Loading Loading @@ -249,7 +262,7 @@ class Link extends TokenizeAreaPluginBase { /** * {@inheritdoc} */ public function validateOptionsForm(&$form, FormStateInterface $form_state) { public function validateOptionsForm(mixed &$form, FormStateInterface $form_state): void { $options = $form_state->getValue('options'); // @todo validate like \Drupal\link\Plugin\Field\FieldWidget\LinkWidget Loading @@ -265,12 +278,13 @@ class Link extends TokenizeAreaPluginBase { public function render($empty = FALSE) { // Note: Method adapted from the renderAsLinkmethod from // Drupal\views\Plugin\views\field\FieldPluginBase. // @phpstan-ignore-next-line if ($empty && empty($this->options['empty'])) { return []; } $options = [ 'absolute' => !empty($this->options['absolute']) ? TRUE : FALSE, 'absolute' => !empty($this->options['absolute']) ? TRUE : FALSE, // @phpstan-ignore-line 'alias' => FALSE, 'entity' => NULL, 'entity_type' => NULL, Loading Loading @@ -302,7 +316,7 @@ class Link extends TokenizeAreaPluginBase { // If we have no $path and no $url_info['url'], we have nothing to work // with, so we just return the text. if (empty($path)) { if (strlen($path) === 0) { return $this->options['link_text']; } Loading @@ -311,12 +325,14 @@ class Link extends TokenizeAreaPluginBase { // 'http://www.example.com'. // Only do this when flag for external has been set, $path doesn't contain // a scheme and $path doesn't have a leading /. // @phpstan-ignore-next-line if ($this->options['external'] && !parse_url($path, PHP_URL_SCHEME) && strpos($path, '/') !== 0) { // There is no scheme, add the default 'http://' to the $path. $path = "http://" . $path; } } // @phpstan-ignore-next-line if (!parse_url($path, PHP_URL_SCHEME)) { $url = Url::fromUserInput('/' . ltrim($path, '/')); } Loading @@ -328,10 +344,11 @@ class Link extends TokenizeAreaPluginBase { $path = $url->setOptions($options)->toUriString(); // @phpstan-ignore-next-line if (!empty($this->options['path_case']) && $this->options['path_case'] != 'none' && !$url->isRouted()) { $path = str_replace($this->options['path'], $this->caseTransform($this->options['path'], $this->options['path_case']), $path); } // @phpstan-ignore-next-line if (!empty($url_info['replace_spaces'])) { $path = str_replace(' ', '-', $path); } Loading @@ -340,12 +357,14 @@ class Link extends TokenizeAreaPluginBase { $url_parts = UrlHelper::parse($path); // Seriously malformed URLs may return FALSE or empty arrays. // @phpstan-ignore-next-line if (empty($url_parts)) { return $this->options['link_text']; } // If the path is empty do not build a link around the given text and return // it as is. // @phpstan-ignore-next-line if (empty($url_parts['path']) && empty($url_parts['fragment']) && empty($url_parts['url'])) { return $this->options['link_text']; } Loading Loading @@ -383,24 +402,26 @@ class Link extends TokenizeAreaPluginBase { $alt = $this->tokenizeValue($this->options['alt']); // Set the title attribute of the link only if it improves accessibility. if ($alt && $alt != $this->options['link_text']) { if (strlen($alt) > 0 && $alt !== $this->options['link_text']) { $options['attributes']['title'] = Html::decodeEntities($alt); } $class = $this->tokenizeValue($this->options['link_class']); if ($class) { if (strlen($class) > 0) { $options['attributes']['class'] = [$class]; } // @phpstan-ignore-next-line if (!empty($this->options['rel']) && $rel = $this->tokenizeValue($this->options['rel'])) { $options['attributes']['rel'] = $rel; } $target = trim($this->tokenizeValue($this->options['target'])); if (!empty($target)) { if (strlen($target) > 0) { $options['attributes']['target'] = $target; } // @phpstan-ignore-next-line if (!empty($this->options['destination'])) { $options['query'] += \Drupal::destination()->getAsArray(); } Loading tests/src/Kernel/Plugin/LinkAreaTest.php +7 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ namespace Drupal\Tests\views_linkarea\Kernel\Plugin; use Drupal\user\Entity\User; use Drupal\views\Tests\ViewTestData; use Drupal\views\Views; use Drupal\Tests\views\Kernel\ViewsKernelTestBase; Loading Loading @@ -57,6 +58,12 @@ class LinkAreaTest extends ViewsKernelTestBase { $this->entityId = (int) $entity_test->id(); \Drupal::state() ->set('entity_test_entity_access.view.' . $this->entityId, TRUE); // Setup an anonymous user for our tests, else they will fail. User::create([ 'name' => '', 'uid' => 0, ])->save(); } /** Loading Loading
src/Plugin/views/area/Link.php +30 −9 Original line number Diff line number Diff line Loading @@ -70,7 +70,20 @@ class Link extends TokenizeAreaPluginBase { } /** * {@inheritdoc} * Create method. * * The base interface is undocumented, so inheritdoc fails. * * @param \Symfony\Component\DependencyInjection\ContainerInterface $container * The service container this instance should use. * @param array $configuration * An associative array containing the plugin's configuration. * @param mixed $plugin_id * The plugin Identifer. * @param mixed $plugin_definition * The plugin implementation definition. * * @see https://www.drupal.org/project/drupal/issues/2634022 */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( Loading Loading @@ -114,7 +127,7 @@ class Link extends TokenizeAreaPluginBase { * * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { public function buildOptionsForm(mixed &$form, FormStateInterface $form_state): void { parent::buildOptionsForm($form, $form_state); $form['link_text'] = [ Loading Loading @@ -249,7 +262,7 @@ class Link extends TokenizeAreaPluginBase { /** * {@inheritdoc} */ public function validateOptionsForm(&$form, FormStateInterface $form_state) { public function validateOptionsForm(mixed &$form, FormStateInterface $form_state): void { $options = $form_state->getValue('options'); // @todo validate like \Drupal\link\Plugin\Field\FieldWidget\LinkWidget Loading @@ -265,12 +278,13 @@ class Link extends TokenizeAreaPluginBase { public function render($empty = FALSE) { // Note: Method adapted from the renderAsLinkmethod from // Drupal\views\Plugin\views\field\FieldPluginBase. // @phpstan-ignore-next-line if ($empty && empty($this->options['empty'])) { return []; } $options = [ 'absolute' => !empty($this->options['absolute']) ? TRUE : FALSE, 'absolute' => !empty($this->options['absolute']) ? TRUE : FALSE, // @phpstan-ignore-line 'alias' => FALSE, 'entity' => NULL, 'entity_type' => NULL, Loading Loading @@ -302,7 +316,7 @@ class Link extends TokenizeAreaPluginBase { // If we have no $path and no $url_info['url'], we have nothing to work // with, so we just return the text. if (empty($path)) { if (strlen($path) === 0) { return $this->options['link_text']; } Loading @@ -311,12 +325,14 @@ class Link extends TokenizeAreaPluginBase { // 'http://www.example.com'. // Only do this when flag for external has been set, $path doesn't contain // a scheme and $path doesn't have a leading /. // @phpstan-ignore-next-line if ($this->options['external'] && !parse_url($path, PHP_URL_SCHEME) && strpos($path, '/') !== 0) { // There is no scheme, add the default 'http://' to the $path. $path = "http://" . $path; } } // @phpstan-ignore-next-line if (!parse_url($path, PHP_URL_SCHEME)) { $url = Url::fromUserInput('/' . ltrim($path, '/')); } Loading @@ -328,10 +344,11 @@ class Link extends TokenizeAreaPluginBase { $path = $url->setOptions($options)->toUriString(); // @phpstan-ignore-next-line if (!empty($this->options['path_case']) && $this->options['path_case'] != 'none' && !$url->isRouted()) { $path = str_replace($this->options['path'], $this->caseTransform($this->options['path'], $this->options['path_case']), $path); } // @phpstan-ignore-next-line if (!empty($url_info['replace_spaces'])) { $path = str_replace(' ', '-', $path); } Loading @@ -340,12 +357,14 @@ class Link extends TokenizeAreaPluginBase { $url_parts = UrlHelper::parse($path); // Seriously malformed URLs may return FALSE or empty arrays. // @phpstan-ignore-next-line if (empty($url_parts)) { return $this->options['link_text']; } // If the path is empty do not build a link around the given text and return // it as is. // @phpstan-ignore-next-line if (empty($url_parts['path']) && empty($url_parts['fragment']) && empty($url_parts['url'])) { return $this->options['link_text']; } Loading Loading @@ -383,24 +402,26 @@ class Link extends TokenizeAreaPluginBase { $alt = $this->tokenizeValue($this->options['alt']); // Set the title attribute of the link only if it improves accessibility. if ($alt && $alt != $this->options['link_text']) { if (strlen($alt) > 0 && $alt !== $this->options['link_text']) { $options['attributes']['title'] = Html::decodeEntities($alt); } $class = $this->tokenizeValue($this->options['link_class']); if ($class) { if (strlen($class) > 0) { $options['attributes']['class'] = [$class]; } // @phpstan-ignore-next-line if (!empty($this->options['rel']) && $rel = $this->tokenizeValue($this->options['rel'])) { $options['attributes']['rel'] = $rel; } $target = trim($this->tokenizeValue($this->options['target'])); if (!empty($target)) { if (strlen($target) > 0) { $options['attributes']['target'] = $target; } // @phpstan-ignore-next-line if (!empty($this->options['destination'])) { $options['query'] += \Drupal::destination()->getAsArray(); } Loading
tests/src/Kernel/Plugin/LinkAreaTest.php +7 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ namespace Drupal\Tests\views_linkarea\Kernel\Plugin; use Drupal\user\Entity\User; use Drupal\views\Tests\ViewTestData; use Drupal\views\Views; use Drupal\Tests\views\Kernel\ViewsKernelTestBase; Loading Loading @@ -57,6 +58,12 @@ class LinkAreaTest extends ViewsKernelTestBase { $this->entityId = (int) $entity_test->id(); \Drupal::state() ->set('entity_test_entity_access.view.' . $this->entityId, TRUE); // Setup an anonymous user for our tests, else they will fail. User::create([ 'name' => '', 'uid' => 0, ])->save(); } /** Loading