From 16b0cc1923e055d7ee425a50fbe34e248a63efae Mon Sep 17 00:00:00 2001 From: hanoii Date: Tue, 6 Feb 2018 10:21:31 +0500 Subject: [PATCH] Issue #2942287 by hanoii: Improve drupal_url with an optional access check and add drupal_link as well --- src/TwigExtension.php | 37 +++++++++++++++++-- tests/src/Functional/TwigTweakTest.php | 11 ++++++ .../templates/twig-tweak-test.html.twig | 2 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/TwigExtension.php b/src/TwigExtension.php index 857d88c..c1e867f 100644 --- a/src/TwigExtension.php +++ b/src/TwigExtension.php @@ -4,6 +4,7 @@ namespace Drupal\twig_tweak; use Drupal\Core\Block\TitleBlockPluginInterface; use Drupal\Core\Site\Settings; +use Drupal\Core\Link; use Drupal\Core\Url; use Drupal\image\Entity\ImageStyle; use Symfony\Cmf\Component\Routing\RouteObjectInterface; @@ -37,6 +38,7 @@ class TwigExtension extends \Twig_Extension { new \Twig_SimpleFunction('drupal_set_message', [$this, 'drupalSetMessage']), new \Twig_SimpleFunction('drupal_title', [$this, 'drupalTitle']), new \Twig_SimpleFunction('drupal_url', [$this, 'drupalUrl']), + new \Twig_SimpleFunction('drupal_link', [$this, 'drupalLink']), ]; } @@ -352,23 +354,52 @@ class TwigExtension extends \Twig_Extension { } /** - * Generates a URL from internal path. + * Generates a URL from an internal path. * * @param string $user_input * User input for a link or path. * @param array $options * (optional) An array of options. + * @param bool $check_access + * (Optional) Indicates that access check is required. * * @return \Drupal\Core\Url * A new Url object based on user input. * * @see \Drupal\Core\Url::fromUserInput() */ - public function drupalUrl($user_input, array $options = []) { + public function drupalUrl($user_input, array $options = [], $check_access = FALSE) { if (!in_array($user_input[0], ['/', '#', '?'])) { $user_input = '/' . $user_input; } - return Url::fromUserInput($user_input, $options); + $url = Url::fromUserInput($user_input, $options); + if (!$check_access || $url->access()) { + return $url; + } + } + + /** + * Generates a link from an internal path. + * + * @param string $text + * The text to be used for the link. + * @param string $user_input + * User input for a link or path. + * @param array $options + * (optional) An array of options. + * @param bool $check_access + * (Optional) Indicates that access check is required. + * + * @return \Drupal\Core\Link + * A new Link object. + * + * @see \Drupal\Core\Link::fromTextAndUrl() + */ + public function drupalLink($text, $user_input, array $options = [], $check_access = FALSE) { + $url = $this->drupalUrl($user_input, $options, $check_access); + if ($url) { + return Link::fromTextAndUrl($text, $url); + } } /** diff --git a/tests/src/Functional/TwigTweakTest.php b/tests/src/Functional/TwigTweakTest.php index 3f25b21..1ed8c10 100644 --- a/tests/src/Functional/TwigTweakTest.php +++ b/tests/src/Functional/TwigTweakTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\twig_tweak\Functional; +use Drupal\Core\Link; use Drupal\Core\Url; use Drupal\Tests\BrowserTestBase; @@ -147,6 +148,16 @@ class TwigTweakTest extends BrowserTestBase { $xpath = sprintf('//div[@class = "tt-url" and text() = "%s"]', $url); $this->assertByXpath($xpath); + // Test link. + $url = Url::fromUserInput('/node/1/edit', ['absolute' => TRUE]); + $link = Link::fromTextAndUrl('Edit', $url)->toString(); + $xpath = '//div[@class = "tt-link"]'; + $this->assertEquals($link, trim($this->xpath($xpath)[0]->getHtml())); + + // Test protected link. + $xpath = '//div[@class = "tt-link-access"]'; + $this->assertEquals('', trim($this->xpath($xpath)[0]->getHtml())); + // Test token replacement. $xpath = '//div[@class = "tt-token-replace" and text() = "Site name: Drupal"]'; $this->assertByXpath($xpath); diff --git a/tests/twig_tweak_test/templates/twig-tweak-test.html.twig b/tests/twig_tweak_test/templates/twig-tweak-test.html.twig index ed606a3..a2c5478 100644 --- a/tests/twig_tweak_test/templates/twig-tweak-test.html.twig +++ b/tests/twig_tweak_test/templates/twig-tweak-test.html.twig @@ -36,6 +36,8 @@
{{ drupal_set_message('Hi!', 'warning') }}
{{ drupal_title() }}
{{ drupal_url('node/1', {absolute: true}) }}
+ +
{{ 'Site name: [site:name]' | token_replace }}
{{ 'FOO' | preg_replace('/(foo)/i', '$1-bar') }}
{{ 'public://images/ocean.jpg' | image_style('thumbnail') }}