11
11
12
12
namespace App \Twig ;
13
13
14
+ use Symfony \Component \DependencyInjection \Attribute \Autowire ;
15
+ use Symfony \Component \ErrorHandler \ErrorRenderer \FileLinkFormatter ;
14
16
use Twig \Environment ;
15
17
use Twig \Extension \AbstractExtension ;
16
18
use Twig \TemplateWrapper ;
28
30
*/
29
31
final class SourceCodeExtension extends AbstractExtension
30
32
{
33
+ private FileLinkFormatter $ fileLinkFormat ;
34
+ private string $ projectDir ;
31
35
/**
32
36
* @var callable|null
33
37
*/
34
38
private $ controller ;
35
39
40
+ public function __construct (
41
+ FileLinkFormatter $ fileLinkFormat ,
42
+ #[Autowire('%kernel.project_dir% ' )]
43
+ string $ projectDir ,
44
+ ) {
45
+ $ this ->fileLinkFormat = $ fileLinkFormat ;
46
+ $ this ->projectDir = str_replace ('\\' , '/ ' , $ projectDir ).'/ ' ;
47
+ }
48
+
36
49
public function setController (?callable $ controller ): void
37
50
{
38
51
$ this ->controller = $ controller ;
@@ -41,10 +54,29 @@ public function setController(?callable $controller): void
41
54
public function getFunctions (): array
42
55
{
43
56
return [
44
- new TwigFunction ('show_source_code ' , [$ this , 'showSourceCode ' ], ['is_safe ' => ['html ' ], 'needs_environment ' => true ]),
57
+ new TwigFunction ('link_source_file ' , $ this ->linkSourceFile (...), ['is_safe ' => ['html ' ], 'needs_environment ' => true ]),
58
+ new TwigFunction ('show_source_code ' , $ this ->showSourceCode (...), ['is_safe ' => ['html ' ], 'needs_environment ' => true ]),
45
59
];
46
60
}
47
61
62
+ /**
63
+ * Render a link to a source file.
64
+ */
65
+ public function linkSourceFile (Environment $ twig , string $ file , int $ line ): string
66
+ {
67
+ $ text = str_replace ('\\' , '/ ' , $ file );
68
+ if (str_starts_with ($ text , $ this ->projectDir )) {
69
+ $ text = substr ($ text , \strlen ($ this ->projectDir ));
70
+ }
71
+ $ link = $ this ->fileLinkFormat ->format ($ file , $ line );
72
+
73
+ return sprintf ('<a href="%s" title="Click to open this file" class="file_link">%s</a> at line %d ' ,
74
+ htmlspecialchars ($ link , \ENT_COMPAT | \ENT_SUBSTITUTE , $ twig ->getCharset ()),
75
+ htmlspecialchars ($ text , \ENT_COMPAT | \ENT_SUBSTITUTE , $ twig ->getCharset ()),
76
+ $ line ,
77
+ );
78
+ }
79
+
48
80
/**
49
81
* @param string|TemplateWrapper $template
50
82
*/
0 commit comments