44
55namespace SpeedPuzzling \Web \Controller ;
66
7- use SpeedPuzzling \Web \Query \GetPuzzlesOverview ;
7+ use SpeedPuzzling \Web \Query \GetPuzzleIdsForSitemap ;
88use SpeedPuzzling \Web \Value \CountryCode ;
99use Symfony \Bundle \FrameworkBundle \Controller \AbstractController ;
1010use Symfony \Component \HttpFoundation \Response ;
1313
1414final class SitemapController extends AbstractController
1515{
16+ private const array LOCALES = ['cs ' , 'en ' , 'es ' , 'ja ' , 'fr ' , 'de ' ];
17+
1618 public function __construct (
17- readonly private GetPuzzlesOverview $ getPuzzlesOverview ,
19+ readonly private GetPuzzleIdsForSitemap $ getPuzzleIdsForSitemap ,
1820 ) {
1921 }
2022
@@ -31,20 +33,25 @@ public function __invoke(): Response
3133 $ staticRoutes = ['homepage ' , 'contact ' , 'faq ' , 'ladder ' , 'ladder_solo_500_pieces ' , 'ladder_solo_1000_pieces ' , 'ladder_pairs_500_pieces ' , 'ladder_pairs_1000_pieces ' , 'ladder_groups_500_pieces ' , 'ladder_groups_1000_pieces ' , 'privacy_policy ' , 'puzzles ' , 'players ' , 'recent_activity ' , 'terms_of_service ' , 'hub ' , 'events ' ];
3234
3335 foreach ($ staticRoutes as $ route ) {
34- foreach ([ ' cs ' , ' en ' , ' es ' , ' ja ' , ' fr ' , ' de ' ] as $ locale ) {
36+ foreach (self :: LOCALES as $ locale ) {
3537 $ urls [$ route ][$ locale ] = $ this ->generateUrl ($ route , ['_locale ' => $ locale ], UrlGeneratorInterface::ABSOLUTE_URL );
3638 }
3739 }
3840
39- foreach (['cs ' , 'en ' , 'es ' , 'ja ' , 'fr ' , 'de ' ] as $ locale ) {
40- foreach ($ this ->getPuzzlesOverview ->allApprovedOrAddedByPlayer (null ) as $ puzzles ) {
41- $ urls [$ puzzles ->puzzleId ][$ locale ] = $ this ->generateUrl ('puzzle_detail ' , [
41+ // Fetch puzzle IDs once (not inside locale loop!)
42+ $ puzzleIds = $ this ->getPuzzleIdsForSitemap ->allApproved ();
43+
44+ foreach ($ puzzleIds as $ puzzleId ) {
45+ foreach (self ::LOCALES as $ locale ) {
46+ $ urls [$ puzzleId ][$ locale ] = $ this ->generateUrl ('puzzle_detail ' , [
4247 '_locale ' => $ locale ,
43- 'puzzleId ' => $ puzzles -> puzzleId ,
48+ 'puzzleId ' => $ puzzleId ,
4449 ], UrlGeneratorInterface::ABSOLUTE_URL );
4550 }
51+ }
4652
47- foreach (CountryCode::cases () as $ countryCode ) {
53+ foreach (CountryCode::cases () as $ countryCode ) {
54+ foreach (self ::LOCALES as $ locale ) {
4855 $ urls ['players_per_country_ ' . $ countryCode ->name ][$ locale ] = $ this ->generateUrl ('players_per_country ' , [
4956 '_locale ' => $ locale ,
5057 'countryCode ' => $ countryCode ->name ,
@@ -53,9 +60,13 @@ public function __invoke(): Response
5360 }
5461
5562 $ response = new Response (headers: [
56- 'Content-Type ' , 'text/xml ' ,
63+ 'Content-Type ' => 'text/xml ' ,
5764 ]);
5865
66+ // Cache for 6 hours - sitemap doesn't need real-time updates
67+ $ response ->setSharedMaxAge (21600 );
68+ $ response ->setMaxAge (3600 );
69+
5970 return $ this ->render ('sitemap.xml.twig ' , [
6071 'urls ' => $ urls ,
6172 ], $ response );
0 commit comments