浏览代码

Add autoLink improvements.

mscherer 1 年之前
父节点
当前提交
dcbd1abcf1
共有 2 个文件被更改,包括 93 次插入24 次删除
  1. 72 2
      src/View/Helper/TextHelper.php
  2. 21 22
      tests/TestCase/View/Helper/TextHelperTest.php

+ 72 - 2
src/View/Helper/TextHelper.php

@@ -71,13 +71,13 @@ class TextHelper extends CakeTextHelper {
 	}
 
 	/**
-	 * Minimizes the given URL to a maximum length
+	 * Minimizes the given URL to a minimum length.
 	 *
 	 * @param string $url the url
 	 * @param int|null $max the maximum length
 	 * @param array<string, mixed> $options
 	 * - placeholder
-	 * @return string the manipulated url (+ eventuell ...)
+	 * @return string The manipulated url (+ maybe ...)
 	 */
 	public function minimizeUrl(string $url, ?int $max = null, array $options = []): string {
 		// check if there is nothing to do
@@ -153,4 +153,74 @@ class TextHelper extends CakeTextHelper {
 		return highlight_string($string, true);
 	}
 
+	/**
+	 * Replace placeholders with links.
+	 *
+	 * @param string $text The text to operate on.
+	 * @param array<string, mixed> $htmlOptions The options for the generated links.
+	 * @return string The text with links inserted.
+	 */
+	protected function _linkUrls(string $text, array $htmlOptions): string {
+		if (!isset($htmlOptions['callable'])) {
+			$replace = [];
+			foreach ($this->_placeholders as $hash => $content) {
+				$link = $url = $content['content'];
+				$envelope = $content['envelope'];
+				if (!preg_match('#^[a-z]+\://#i', $url)) {
+					$url = 'http://' . $url;
+				}
+
+				$linkOptions = $htmlOptions;
+				unset($htmlOptions['maxLength'], $htmlOptions['stripProtocol'], $htmlOptions['ellipsis']);
+
+				$replace[$hash] = $envelope[0] . $this->Html->link($this->prepareLinkName($link, $linkOptions), $url, $htmlOptions) . $envelope[1];
+			}
+
+			return strtr($text, $replace);
+		}
+
+		$callable = $htmlOptions['callable'];
+		unset($htmlOptions['callable']);
+		if (!is_callable($callable)) {
+			throw new CakeException(sprintf('The `outbound` option must be a callable, %s given', getType($callable)));
+		}
+
+		$replace = [];
+		foreach ($this->_placeholders as $hash => $content) {
+			$link = $url = $content['content'];
+			$envelope = $content['envelope'];
+			if (!preg_match('#^[a-z]+\://#i', $url)) {
+				$url = 'http://' . $url;
+			}
+			$replace[$hash] = $envelope[0] . $callable($link, $url, $htmlOptions) . $envelope[1];
+		}
+
+		return strtr($text, $replace);
+	}
+
+	/**
+	 * @param string $link
+	 * @param array $options Options:
+	 * - stripProtocol: bool (defaults to true)
+	 * - maxLength: int (defaults to 50)
+	 * - ellipsis (defaults to UTF8 version)
+	 * @return string html/$plain
+	 */
+	protected function prepareLinkName(string $link, array $options = []): string {
+		// strip protocol if desired (default)
+		if (!isset($options['stripProtocol']) || $options['stripProtocol'] !== false) {
+			$link = $this->stripProtocol($link);
+		}
+		if (!isset($options['maxLength'])) {
+			$options['maxLength'] = 50; # should be long enough for most cases
+		}
+		// shorten display name if desired (default)
+		if (!empty($options['maxLength']) && mb_strlen($link) > $options['maxLength']) {
+			$link = mb_substr($link, 0, $options['maxLength']);
+			$link .= $options['ellipsis'] ?? '…';
+		}
+
+		return $link;
+	}
+
 }

+ 21 - 22
tests/TestCase/View/Helper/TextHelperTest.php

@@ -73,25 +73,28 @@ class TextHelperTest extends TestCase {
 	}
 
 	/**
-	 * TextExtHelperTest::testAutoLinkUrls()
-	 *
 	 * @return void
 	 */
-	public function testAutoLinkUrls() {
-		$this->skipIf(true, '//TODO: Port from 2.x');
-
-		$texts = [
-			'text http://www.cakephp.org/bla/bla some more text' => '',
-			'This is a test text with URL http://www.cakephp.org\tand some more text' => 'This is a test text with URL http://www.cakephp.org\tand some more text',
+	public function testStripProtocol(): void {
+		$urls = [
+			'http://www.cakephp.org/bla/bla' => 'www.cakephp.org/bla/bla',
+			'https://www.cakephp.org/' => 'www.cakephp.org/',
 		];
 
-		foreach ($texts as $text => $expected) {
-			//$is = $this->Text->stripProtocol($url);
-			//$this->assertEquals($expected, $is);
+		foreach ($urls as $url => $expected) {
+			$is = $this->Text->stripProtocol($url);
+			$this->assertEquals($expected, $is);
 		}
+	}
 
+	/**
+	 * TextExtHelperTest::testAutoLinkUrls()
+	 *
+	 * @return void
+	 */
+	public function testAutoLinkUrls() {
 		$text = 'Text with a url www.cot.ag/cuIb2Q/eruierieriu-erjekr and more';
-		$expected = 'Text with a url <a href="http://www.cot.ag/cuIb2Q/eruierieriu-erjekr">www.cot.ag/c...</a> and more';
+		$expected = 'Text with a url <a href="http://www.cot.ag/cuIb2Q/eruierieriu-erjekr">www.cot.ag/c</a> and more';
 		$result = $this->Text->autoLinkUrls($text, ['maxLength' => 12]);
 		$this->assertEquals($expected, $result);
 
@@ -106,7 +109,7 @@ class TextHelperTest extends TestCase {
 		$this->assertEquals($expected, $result);
 
 		$text = 'Text with a url www.cot.ag/cuIb2Q/eruierieriu-erjekrwerweuwrweir-werwer-werwerwe-werwerwer-werwerdfrffsd-werwer and more';
-		$expected = 'Text with a url <a href="http://www.cot.ag/cuIb2Q/eruierieriu-erjekrwerweuwrweir-werwer-werwerwe-werwerwer-werwerdfrffsd-werwer">www.cot.ag/cuIb2Q/eruierieriu-erjekrwerweuwrweir-w...</a> and more';
+		$expected = 'Text with a url <a href="http://www.cot.ag/cuIb2Q/eruierieriu-erjekrwerweuwrweir-werwer-werwerwe-werwerwer-werwerdfrffsd-werwer">www.cot.ag/cuIb2Q/eruierieriu-erjekrwerweuwrweir-w</a> and more';
 		$result = $this->Text->autoLinkUrls($text);
 		$this->assertEquals($expected, $result);
 	}
@@ -117,10 +120,8 @@ class TextHelperTest extends TestCase {
 	 * @return void
 	 */
 	public function testAutoLinkUrlsWithEscapeFalse() {
-		$this->skipIf(true, '//TODO: Port from 2.x');
-
 		$text = 'Text with a url www.cot.ag/cuIb2Q/eruierieriu-erjekrwerweuwrweir-werwer and more';
-		$expected = 'Text with a url <a href="http://www.cot.ag/cuIb2Q/eruierieriu-erjekrwerweuwrweir-werwer">www.cot.ag/cuIb2Q/er...</a> and more';
+		$expected = 'Text with a url <a href="http://www.cot.ag/cuIb2Q/eruierieriu-erjekrwerweuwrweir-werwer">www.cot.ag/cuIb2Q/er…</a> and more';
 		$result = $this->Text->autoLinkUrls($text, ['maxLength' => 20], ['escape' => false]);
 		$this->assertEquals($expected, $result);
 
@@ -133,7 +134,7 @@ class TextHelperTest extends TestCase {
 		*/
 
 		$text = '<h3>google<h3> a http://maps.google.de/maps?f=d&source=s_d&saddr=m%C3%BCnchen&daddr=Berlin&hl=de&geocode=FXaL3gIdGrOwACnZX4yj-XWeRzF9mLF9SrgMAQ%3BFY1xIQMdSKTMACkBWQM_N06oRzFwO15bRiAhBA&mra=ls&sll=52.532932,13.41156&sspn=0.77021,2.348328&g=berlin&ie=UTF8&t=h&z=6 link';
-		$expected = '&lt;h3&gt;google&lt;h3&gt; a <a href="http://maps.google.de/maps?f=d&amp;source=s_d&amp;saddr=m%C3%BCnchen&amp;daddr=Berlin&amp;hl=de&amp;geocode=FXaL3gIdGrOwACnZX4yj-XWeRzF9mLF9SrgMAQ%3BFY1xIQMdSKTMACkBWQM_N06oRzFwO15bRiAhBA&amp;mra=ls&amp;sll=52.532932,13.41156&amp;sspn=0.77021,2.348328&amp;g=berlin&amp;ie=UTF8&amp;t=h&amp;z=6">maps.google.de/maps?f=d&amp;source...</a> link';
+		$expected = '&lt;h3&gt;google&lt;h3&gt; a <a href="http://maps.google.de/maps?f=d&amp;source=s_d&amp;saddr=m%C3%BCnchen&amp;daddr=Berlin&amp;hl=de&amp;geocode=FXaL3gIdGrOwACnZX4yj-XWeRzF9mLF9SrgMAQ%3BFY1xIQMdSKTMACkBWQM_N06oRzFwO15bRiAhBA&amp;mra=ls&amp;sll=52.532932,13.41156&amp;sspn=0.77021,2.348328&amp;g=berlin&amp;ie=UTF8&amp;t=h&amp;z=6">maps.google.de/maps?f=d&amp;source</a> link';
 		$result = $this->Text->autoLinkUrls($text, ['maxLength' => 30]);
 		$this->assertEquals($expected, $result);
 	}
@@ -192,8 +193,6 @@ class TextHelperTest extends TestCase {
 	 * @return void
 	 */
 	public function testAutoLinkUrlsWithCakeTests() {
-		$this->skipIf(true, '//TODO: Port from 2.x');
-
 		$text = 'This is a test text';
 		$expected = 'This is a test text';
 		$result = $this->Text->autoLinkUrls($text);
@@ -211,7 +210,7 @@ class TextHelperTest extends TestCase {
 
 		$text = 'Text with a partial www.cakephp.org URL';
 		$expected = 'Text with a partial <a href="http://www.cakephp.org" \s*class="link">www.cakephp.org</a> URL';
-		$result = $this->Text->autoLinkUrls($text, [], ['class' => 'link']);
+		$result = $this->Text->autoLinkUrls($text, ['class' => 'link']);
 		$this->assertMatchesRegularExpression('#^' . $expected . '$#', $result);
 
 		$text = 'Text with a partial WWW.cakephp.org URL';
@@ -221,7 +220,7 @@ class TextHelperTest extends TestCase {
 
 		$text = 'Text with a partial WWW.cakephp.org &copy; URL';
 		$expected = 'Text with a partial <a href="http://WWW.cakephp.org"\s*>WWW.cakephp.org</a> &copy; URL';
-		$result = $this->Text->autoLinkUrls($text, ['escape' => false], ['escape' => false]);
+		$result = $this->Text->autoLinkUrls($text, ['escape' => false, 'escape' => false]);
 		$this->assertMatchesRegularExpression('#^' . $expected . '$#', $result);
 
 		$text = 'Text with a url www.cot.ag/cuIb2Q and more';
@@ -249,7 +248,7 @@ class TextHelperTest extends TestCase {
 		$this->assertEquals('ww&#8230;ge.de', $this->Text->minimizeUrl($url, 10));
 
 		$url = 'http://www.testpage.de';
-		$this->assertEquals('ww...ge.de', $this->Text->minimizeUrl($url, 10, ['placeholder' => '...']));
+		$this->assertEquals('ww…ge.de', $this->Text->minimizeUrl($url, 10, ['placeholder' => '…']));
 
 		// without full http://
 		$url = 'www.testpage.de';