1313use Contao \Validator ;
1414use Symfony \Component \HttpFoundation \Request ;
1515use Symfony \Component \HttpFoundation \Response ;
16+ use Symfony \Contracts \HttpClient \Exception \TransportExceptionInterface ;
1617use Symfony \Contracts \HttpClient \HttpClientInterface ;
1718
1819class LinkChecker
1920{
2021 public const STATUS_MAILTO = 'mailto ' ;
2122 public const STATUS_INVALID = 'invalid ' ;
2223 public const STATUS_TIMEOUT = '408 ' ;
24+ public const DEFAULT_TIMEOUT = 10 ;
2325
2426 public const CLASS_DEFAULT = 'lc-default ' ;
2527 public const CLASS_INFO = 'lc-info ' ;
@@ -39,13 +41,15 @@ public function __construct(
3941 *
4042 * @return array|bool|mixed
4143 */
42- public function test ($ varLinks )
44+ public function test ($ varLinks, int | string | null $ timeout = null )
4345 {
46+ $ timeout = $ this ->normalizeTimeout ($ timeout );
47+
4448 if (!\is_array ($ varLinks )) {
45- return $ this ->testOne ($ varLinks );
49+ return $ this ->testOne ($ varLinks, $ timeout );
4650 }
4751
48- return $ this ->testAll ($ varLinks );
52+ return $ this ->testAll ($ varLinks, $ timeout );
4953 }
5054
5155 /**
@@ -55,7 +59,7 @@ public function test($varLinks)
5559 *
5660 * @return string The translated status code, or false if the link was not tested
5761 */
58- protected function testOne (string $ url ): string
62+ protected function testOne (string $ url, int $ timeout ): string
5963 {
6064 if (str_starts_with ($ url , 'mailto: ' )) {
6165 return $ this ->getResult (static ::STATUS_MAILTO );
@@ -65,9 +69,16 @@ protected function testOne(string $url): string
6569 return $ this ->getResult (static ::STATUS_INVALID );
6670 }
6771
68- $ response = $ this ->client ->request (Request::METHOD_GET , $ url );
72+ try {
73+ $ response = $ this ->client ->request (Request::METHOD_GET , $ url , [
74+ 'max_duration ' => $ timeout ,
75+ 'timeout ' => $ timeout ,
76+ ]);
6977
70- return $ this ->getResult ($ response ->getStatusCode ());
78+ return $ this ->getResult ($ response ->getStatusCode ());
79+ } catch (TransportExceptionInterface ) {
80+ return $ this ->getResult (static ::STATUS_TIMEOUT );
81+ }
7182 }
7283
7384 /**
@@ -77,18 +88,27 @@ protected function testOne(string $url): string
7788 *
7889 * @return array The list of tested links with translated status code, or false if the link was not tested
7990 */
80- protected function testAll (array $ arrLinks ): array
91+ protected function testAll (array $ arrLinks, int $ timeout ): array
8192 {
8293 $ arrResults = [];
8394
8495 foreach ($ arrLinks as $ strKey => $ strUrl ) {
85- $ arrResults [$ strUrl ] = $ this ->testOne ($ strUrl );
96+ $ arrResults [$ strUrl ] = $ this ->testOne ($ strUrl, $ timeout );
8697 unset($ arrLinks );
8798 }
8899
89100 return $ arrResults ;
90101 }
91102
103+ protected function normalizeTimeout (int |string |null $ timeout ): int
104+ {
105+ if (null === $ timeout || '' === $ timeout || !is_numeric ($ timeout ) || (int ) $ timeout < 1 ) {
106+ return static ::DEFAULT_TIMEOUT ;
107+ }
108+
109+ return (int ) $ timeout ;
110+ }
111+
92112 /**
93113 * Get the styled result.
94114 */
0 commit comments