Skip to content

Commit 5d63998

Browse files
author
roadiz-ci
committed
Merge tag v2.7.33 into develop
1 parent 9dc2528 commit 5d63998

5 files changed

Lines changed: 102 additions & 1 deletion

File tree

composer.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
},
1212
"require-dev": {
1313
"phpstan/phpstan": "^2.1.36",
14-
"phpstan/phpdoc-parser": "<2"
14+
"phpstan/phpdoc-parser": "<2",
15+
"phpunit/phpunit": "^9.6"
1516
},
1617
"license": "MIT",
1718
"authors": [
@@ -27,6 +28,11 @@
2728
"RZ\\Roadiz\\Markdown\\": "src/"
2829
}
2930
},
31+
"autoload-dev": {
32+
"psr-4": {
33+
"RZ\\Roadiz\\Markdown\\Tests\\": "tests/"
34+
}
35+
},
3036
"extra": {
3137
"branch-alias": {
3238
"dev-master": "2.7.x-dev",

src/CommonMark.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,25 @@ public function line(?string $markdown = null): string
5959

6060
return $html;
6161
}
62+
63+
#[\Override]
64+
public function strip(?string $markdown = null): ?string
65+
{
66+
if (!is_string($markdown)) {
67+
return null;
68+
}
69+
/*
70+
* Strip Markdown syntax
71+
*/
72+
$markdown = $this->textExtra($markdown);
73+
// replace BR with space to avoid merged words.
74+
$markdown = str_replace(['<br>', '<br />', '<br/>'], ' ', $markdown);
75+
$markdown = strip_tags($markdown);
76+
/*
77+
* Remove control characters (including DEL).
78+
*/
79+
$markdown = preg_replace('/[\x00-\x1F\x7F]/', '', $markdown);
80+
81+
return $markdown;
82+
}
6283
}

src/MarkdownInterface.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,9 @@ public function textExtra(?string $markdown = null, bool $allowHtml = false): st
2626
* Convert Markdown to HTML using only inline HTML elements.
2727
*/
2828
public function line(?string $markdown = null): string;
29+
30+
/**
31+
* Convert Markdown then strip tags, control characters and replace br with whitespace.
32+
*/
33+
public function strip(?string $markdown = null): ?string;
2934
}

src/Twig/MarkdownExtension.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public function getFilters(): array
2323
new TwigFilter('inline_markdown', $this->inlineMarkdown(...), ['is_safe' => ['html']]),
2424
new TwigFilter('markdownExtra', $this->markdownExtra(...), ['is_safe' => ['html']]),
2525
new TwigFilter('markdown_extra', $this->markdownExtra(...), ['is_safe' => ['html']]),
26+
new TwigFilter('strip_markdown', $this->strip(...)),
27+
new TwigFilter('stripMarkdown', $this->strip(...)),
2628
];
2729
}
2830

@@ -62,4 +64,13 @@ public function markdownExtra(?string $input, bool $allowHtml = false): string
6264

6365
return $this->markdown->textExtra($input, $allowHtml);
6466
}
67+
68+
public function strip(?string $input): string
69+
{
70+
if (null === $input) {
71+
return '';
72+
}
73+
74+
return $this->markdown->strip($input) ?? '';
75+
}
6576
}

tests/CommonMarkTest.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RZ\Roadiz\Markdown\Tests;
6+
7+
use League\CommonMark\Environment\Environment;
8+
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
9+
use League\CommonMark\MarkdownConverter;
10+
use PHPUnit\Framework\TestCase;
11+
use RZ\Roadiz\Markdown\CommonMark;
12+
13+
final class CommonMarkTest extends TestCase
14+
{
15+
private function createCommonMark(): CommonMark
16+
{
17+
$environment = new Environment(['html_input' => 'strip']);
18+
$environment->addExtension(new CommonMarkCoreExtension());
19+
$converter = new MarkdownConverter($environment);
20+
21+
// strip() only relies on the textExtra converter, but the constructor
22+
// requires all five converters.
23+
return new CommonMark($converter, $converter, $converter, $converter, $converter);
24+
}
25+
26+
/**
27+
* @dataProvider stripProvider
28+
*/
29+
public function testStrip(?string $input, ?string $expected): void
30+
{
31+
$this->assertSame($expected, $this->createCommonMark()->strip($input));
32+
}
33+
34+
/**
35+
* @return array<array{0: ?string, 1: ?string}>
36+
*/
37+
public static function stripProvider(): array
38+
{
39+
return [
40+
'null returns null' => [null, null],
41+
'plain text is untouched' => ['Hello world', 'Hello world'],
42+
'markdown emphasis is stripped' => ['**Hello** _world_', 'Hello world'],
43+
'headings are stripped' => ['# Title', 'Title'],
44+
'links keep their label only' => ['[Roadiz](https://roadiz.io)', 'Roadiz'],
45+
'hard line break becomes a space' => ["Line1 \nLine2", 'Line1 Line2'],
46+
'control characters are removed' => ["a\x07b", 'ab'],
47+
'DEL character is removed' => ["a\x7Fb", 'ab'],
48+
];
49+
}
50+
51+
public function testStripRemovesHtmlTags(): void
52+
{
53+
$result = $this->createCommonMark()->strip('Some **bold** text with a [link](https://roadiz.io).');
54+
55+
$this->assertStringNotContainsString('<', (string) $result);
56+
$this->assertStringNotContainsString('>', (string) $result);
57+
}
58+
}

0 commit comments

Comments
 (0)