44
55use Drupal \Core \Mail \MailInterface ;
66use Drupal \Core \Mail \Plugin \Mail \PhpMail as PhpMailBase ;
7+ use Drupal \Core \Url ;
78
89/**
910 * Copy of the default Drupal mail backend, using PHP's native mail() function.
@@ -28,6 +29,8 @@ class PhpMail extends PhpMailBase implements MailInterface {
2829 public function format (array $ message ) {
2930 $ message ['body ' ] = implode ("\n\n" , $ message ['body ' ]);
3031
32+ $ message ['body ' ] = $ this ->makeUrlsAbsolute ($ message ['body ' ]);
33+
3134 return $ message ;
3235 }
3336
@@ -48,4 +51,29 @@ public function mail(array $message) {
4851 return parent ::mail ($ message );
4952 }
5053
54+ /**
55+ * Convert relative urls (paths) in html to absolute urls.
56+ */
57+ private function makeUrlsAbsolute (string $ html ) {
58+ return preg_replace_callback (
59+ '/\s(href|src)\s*=\s*(?: \'([^ \']+) \'|"([^"]+)")/ ' ,
60+ static function ($ matches ) {
61+ $ name = $ matches [1 ];
62+ $ value = $ matches [2 ] ?: $ matches [3 ];
63+ $ scheme = parse_url ($ value , PHP_URL_SCHEME );
64+ if (NULL === $ scheme ) {
65+ // We have a local path.
66+ try {
67+ $ value = Url::fromUri ('internal:/ ' . ltrim ($ value , '/ ' ), ['absolute ' => TRUE ])->toString ();
68+ }
69+ catch (\InvalidArgumentException $ exception ) {
70+ }
71+ }
72+
73+ return sprintf (' %s="%s" ' , $ name , htmlspecialchars ($ value ));
74+ },
75+ $ html
76+ );
77+ }
78+
5179}
0 commit comments