2828use phpMyFAQ \Faq \FaqCreationService ;
2929use phpMyFAQ \Faq \FaqDisplayService ;
3030use phpMyFAQ \Filter ;
31+ use phpMyFAQ \Language ;
32+ use phpMyFAQ \Link ;
3133use phpMyFAQ \Seo ;
3234use phpMyFAQ \Services ;
3335use phpMyFAQ \Session \Token ;
3436use phpMyFAQ \Strings ;
3537use phpMyFAQ \Translation ;
38+ use phpMyFAQ \Twig \Extensions \LanguageCodeTwigExtension ;
3639use phpMyFAQ \Utils ;
3740use phpMyFAQ \Visits ;
3841use Symfony \Component \HttpFoundation \RedirectResponse ;
3942use Symfony \Component \HttpFoundation \Request ;
4043use Symfony \Component \HttpFoundation \Response ;
4144use Symfony \Component \Routing \Attribute \Route ;
4245use Twig \Error \LoaderError ;
46+ use Twig \Extension \AttributeExtension ;
4347use Twig \TwigFilter ;
4448
4549final class FaqController extends AbstractFrontController
@@ -134,6 +138,7 @@ public function add(Request $request): Response
134138 $ templateVars [$ required ] = (int ) $ input ->input_required !== 0 ? 'required ' : '' ;
135139 }
136140
141+ $ this ->addExtension (new AttributeExtension (LanguageCodeTwigExtension::class));
137142 return $ this ->render ('add.twig ' , $ templateVars );
138143 }
139144
@@ -171,7 +176,8 @@ public function solution(Request $request): Response
171176 /**
172177 * Displays a single FAQ article with comments, ratings, and related content
173178 *
174- * @throws Exception|LoaderError*@throws \Exception
179+ * @throws Exception|LoaderError|\Exception
180+ *
175181 *
176182 */
177183 #[Route(path: '/faq/{categoryId}/{faqId}/{slug}.html ' , name: 'public.faq.show ' , methods: ['GET ' ])]
@@ -189,6 +195,21 @@ public function show(Request $request): Response
189195 $ faqId = Filter::filterVar ($ request ->query ->get ('id ' ), FILTER_VALIDATE_INT , 0 );
190196 }
191197
198+ // Get language from route parameter (for /content/ URLs) or query parameter (for legacy URLs)
199+ $ requestedLanguage =
200+ $ request ->attributes ->get ('language ' ) ?? $ request ->query ->get ('artlang ' ) ?? $ this ->configuration
201+ ->getLanguage ()
202+ ->getLanguage ();
203+
204+ // Temporarily set the language in session for this request
205+ $ session = $ this ->container ->get ('session ' );
206+ $ originalLanguage = $ session ->get ('lang ' );
207+ if ($ requestedLanguage !== $ originalLanguage ) {
208+ $ session ->set ('lang ' , $ requestedLanguage );
209+ // Update the static language variable
210+ Language::$ language = $ requestedLanguage ;
211+ }
212+
192213 $ solutionId = Filter::filterVar ($ request ->query ->get ('solution_id ' ), FILTER_VALIDATE_INT );
193214 $ highlight = Filter::filterVar ($ request ->query ->get ('highlight ' ), FILTER_SANITIZE_SPECIAL_CHARS );
194215 $ bookmarkAction = Filter::filterVar ($ request ->query ->get ('bookmark_action ' ), FILTER_SANITIZE_SPECIAL_CHARS );
@@ -244,6 +265,21 @@ public function show(Request $request): Response
244265 $ availableLanguages = $ faqDisplayService ->getAvailableLanguages ($ faq ->faqRecord ['id ' ]);
245266 $ tagsHtml = $ faqDisplayService ->getTagsHtml ($ faqId );
246267
268+ // Generate language URLs with SEO slugs
269+ $ languageUrls = [];
270+ foreach ($ availableLanguages as $ language ) {
271+ $ url = sprintf (
272+ '%sindex.php?action=faq&cat=%d&id=%d&artlang=%s ' ,
273+ $ this ->configuration ->getDefaultUrl (),
274+ $ cat ,
275+ $ faqId ,
276+ $ language ,
277+ );
278+ $ link = new Link ($ url , $ this ->configuration );
279+ $ link ->setTitle ($ question );
280+ $ languageUrls [$ language ] = $ link ->toString ();
281+ }
282+
247283 // Comment permissions
248284 $ expired = $ faqDisplayService ->isExpired ();
249285
@@ -313,14 +349,14 @@ public function show(Request $request): Response
313349 'linkToPdf ' => $ faqServices ->getPdfLink (),
314350 'msgAverageVote ' => Translation::get (key: 'msgAverageVote ' ),
315351 'renderVotingResult ' => $ faqDisplayService ->getRating ($ faqId ),
316- 'switchLanguage ' => $ faqDisplayService ->getFaqHelper ()->renderChangeLanguageSelector ($ faq , $ cat ),
352+ 'languageUrls ' => $ languageUrls ,
353+ 'currentLanguage ' => $ faq ->faqRecord ['lang ' ],
317354 'msgVoteBad ' => Translation::get (key: 'msgVoteBad ' ),
318355 'msgVoteGood ' => Translation::get (key: 'msgVoteGood ' ),
319356 'msgVoteSubmit ' => Translation::get (key: 'msgVoteSubmit ' ),
320357 'msgWriteComment ' => Translation::get (key: 'msgWriteComment ' ),
321358 'id ' => $ faqId ,
322359 'lang ' => $ this ->configuration ->getLanguage ()->getLanguage (),
323- 'msgCommentHeader ' => Translation::get (key: 'msgCommentHeader ' ),
324360 'msgNewContentName ' => Translation::get (key: 'msgNewContentName ' ),
325361 'msgNewContentMail ' => Translation::get (key: 'msgNewContentMail ' ),
326362 'defaultContentMail ' => $ this ->currentUser ->getUserId () > 0
@@ -401,6 +437,7 @@ public function show(Request $request): Response
401437 $ templateVars ['renderRelatedArticles ' ] = $ relatedFaqs ;
402438 }
403439
440+ $ this ->addExtension (new AttributeExtension (LanguageCodeTwigExtension::class));
404441 return $ this ->render ('faq.twig ' , $ templateVars );
405442 }
406443
0 commit comments