Skip to content

Commit 9789cea

Browse files
committed
refactor: simplified Language class
1 parent 05e0835 commit 9789cea

30 files changed

+239
-187
lines changed

phpmyfaq/index.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@
8888
// Get language (default: English)
8989
//
9090
$Language = $container->get('phpmyfaq.language');
91-
$faqLangCode = $Language->setLanguage($faqConfig->get('main.languageDetection'), $faqConfig->get('main.language'));
91+
$faqLangCode = $faqConfig->get('main.languageDetection')
92+
? $Language->setLanguageWithDetection($faqConfig->get('main.language'))
93+
: $Language->setLanguageFromConfiguration($faqConfig->get('main.language'));
9294
$faqConfig->setLanguage($Language);
9395

9496
if (!Language::isASupportedLanguage($faqLangCode)) {

phpmyfaq/pdf.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@
5959

6060
// get language (default: English)
6161
$Language = $container->get('phpmyfaq.language');
62-
$faqLangCode = $Language->setLanguage($faqConfig->get('main.languageDetection'), $faqConfig->get('main.language'));
62+
$faqLangCode = $faqConfig->get('main.languageDetection')
63+
? $Language->setLanguageWithDetection($faqConfig->get('main.language'))
64+
: $Language->setLanguageFromConfiguration($faqConfig->get('main.language'));
6365
$faqConfig->setLanguage($Language);
6466

6567
// Found an article language?
@@ -79,7 +81,7 @@
7981
}
8082

8183
//
82-
// Set translation class
84+
// Set the translation class
8385
//
8486
try {
8587
Translation::create()

phpmyfaq/src/phpMyFAQ/Application.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,13 @@ private function setLanguage(): string
7474
if (!is_null($this->container)) {
7575
$configuration = $this->container->get(id: 'phpmyfaq.configuration');
7676
$language = $this->container->get(id: 'phpmyfaq.language');
77-
$currentLanguage = $language->setLanguage(
78-
(bool) $configuration->get(item: 'main.languageDetection'),
79-
$configuration->get(item: 'main.language'),
80-
);
77+
78+
$detect = (bool) $configuration->get(item: 'main.languageDetection');
79+
$configLang = $configuration->get(item: 'main.language');
80+
81+
$currentLanguage = $detect
82+
? $language->setLanguageWithDetection($configLang)
83+
: $language->setLanguageFromConfiguration($configLang);
8184

8285
require PMF_TRANSLATION_DIR . '/language_en.php';
8386
if (Language::isASupportedLanguage($currentLanguage)) {

phpmyfaq/src/phpMyFAQ/Controller/Api/PdfController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use phpMyFAQ\Faq;
2626
use phpMyFAQ\Filter;
2727
use phpMyFAQ\Service;
28+
use phpMyFAQ\Services;
2829
use phpMyFAQ\User\CurrentUser;
2930
use stdClass;
3031
use Symfony\Component\HttpFoundation\JsonResponse;

phpmyfaq/src/phpMyFAQ/Controller/Frontend/CommentController.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,9 @@ public function create(Request $request): JsonResponse
4848
$session->setCurrentUser($this->currentUser);
4949

5050
$language = $this->container->get('phpmyfaq.language');
51-
$languageCode = $language->setLanguage(
52-
$this->configuration->get('main.languageDetection'),
53-
$this->configuration->get('main.language'),
54-
);
51+
$languageCode = $this->configuration->get('main.languageDetection')
52+
? $language->setLanguageWithDetection($this->configuration->get('main.language'))
53+
: $language->setLanguageFromConfiguration($this->configuration->get('main.language'));
5554

5655
if (!$this->isCommentAllowed($this->currentUser)) {
5756
return $this->json(['error' => Translation::get('ad_msg_noauth')], Response::HTTP_FORBIDDEN);

phpmyfaq/src/phpMyFAQ/Controller/Frontend/FaqController.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,9 @@ public function create(Request $request): JsonResponse
5353
$faqPermission = new FaqPermission($this->configuration);
5454

5555
$language = $this->container->get('phpmyfaq.language');
56-
$languageCode = $language->setLanguage(
57-
$this->configuration->get('main.languageDetection'),
58-
$this->configuration->get('main.language'),
59-
);
56+
$languageCode = $this->configuration->get('main.languageDetection')
57+
? $language->setLanguageWithDetection($this->configuration->get('main.language'))
58+
: $language->setLanguageFromConfiguration($this->configuration->get('main.language'));
6059

6160
if (!$this->isAddingFaqsAllowed($this->currentUser)) {
6261
return $this->json(['error' => Translation::get('ad_msg_noauth')], Response::HTTP_FORBIDDEN);

phpmyfaq/src/phpMyFAQ/Language.php

Lines changed: 39 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
namespace phpMyFAQ;
2323

2424
use phpMyFAQ\Language\LanguageCodes;
25-
use Symfony\Component\HttpFoundation\Request;
25+
use phpMyFAQ\Language\LanguageDetector;
2626
use Symfony\Component\HttpFoundation\Session\SessionInterface;
2727

2828
/**
@@ -38,9 +38,9 @@ class Language
3838
public static string $language = '';
3939

4040
/**
41-
* The accepted language of the user agent.
41+
* Detector helper.
4242
*/
43-
private string $acceptLanguage = '';
43+
private LanguageDetector $detector;
4444

4545
/**
4646
* Constructor.
@@ -49,6 +49,7 @@ public function __construct(
4949
private readonly Configuration $configuration,
5050
private readonly SessionInterface $session,
5151
) {
52+
$this->detector = new LanguageDetector($this->configuration, $this->session);
5253
}
5354

5455
/**
@@ -63,20 +64,24 @@ public function isLanguageAvailable(int $identifier, string $table = 'faqdata'):
6364
{
6465
$output = [];
6566

66-
if ($identifier === 0) {
67-
$distinct = ' DISTINCT ';
68-
$where = '';
69-
} else {
67+
// Avoid it else: default values for all records, override if identifier is set
68+
$distinct = 'DISTINCT ';
69+
$where = '';
70+
if ($identifier !== 0) {
7071
$distinct = '';
7172
$where = ' WHERE id = ' . $identifier;
7273
}
7374

74-
$query = sprintf('SELECT %s lang FROM %s%s %s', $distinct, Database::getTablePrefix(), $table, $where);
75-
75+
// Correct spacing: "SELECT" then optional DISTINCT
76+
$query = 'SELECT ' . $distinct . 'lang FROM ' . Database::getTablePrefix() . $table . $where;
7677
$result = $this->configuration->getDb()->query($query);
7778

7879
if ($this->configuration->getDb()->numRows($result) > 0) {
79-
while ($row = $this->configuration->getDb()->fetchObject($result)) {
80+
while (true) {
81+
$row = $this->configuration->getDb()->fetchObject($result);
82+
if (!$row) {
83+
break;
84+
}
8085
$output[] = $row->lang;
8186
}
8287
}
@@ -85,24 +90,37 @@ public function isLanguageAvailable(int $identifier, string $table = 'faqdata'):
8590
}
8691

8792
/**
88-
* Sets the current language for phpMyFAQ user session.
89-
*
90-
* @param bool $configDetection Configuration detection
91-
* @param string $configLanguage Language from configuration
93+
* Sets language using browser detection combined with config fallback.
9294
*/
93-
public function setLanguage(bool $configDetection, string $configLanguage): string
95+
public function setLanguageWithDetection(string $configLanguage): string
9496
{
95-
$detectedLang = $this->detectLanguage($configDetection, $configLanguage);
96-
self::$language = $this->selectLanguage($detectedLang);
97-
$this->session->set('lang', self::$language);
97+
$detected = $this->detector->detectAllWithBrowser($configLanguage);
98+
self::$language = $this->detector->selectLanguage($detected);
99+
$this->session->set(
100+
name: 'lang',
101+
value: self::$language,
102+
);
98103
return strtolower(self::$language);
99104
}
100105

101-
public function setLanguageByAcceptLanguage(): string
106+
/**
107+
* Sets language only from the provided configuration string.
108+
*/
109+
public function setLanguageFromConfiguration(string $configLanguage): string
102110
{
103-
self::getUserAgentLanguage();
111+
$detected = $this->detector->detectAllFromConfig($configLanguage);
112+
self::$language = $this->detector->selectLanguage($detected);
113+
$this->session->set(
114+
name: 'lang',
115+
value: self::$language,
116+
);
117+
return strtolower(self::$language);
118+
}
104119

105-
return self::$language = $this->acceptLanguage;
120+
public function setLanguageByAcceptLanguage(): string
121+
{
122+
$this->detector->detectAllWithBrowser(configLanguage: '');
123+
return self::$language = $this->detector->getAcceptLanguage();
106124
}
107125

108126
/**
@@ -122,110 +140,4 @@ public function getLanguage(): string
122140
{
123141
return strtolower(self::$language);
124142
}
125-
126-
/**
127-
* Detects the language.
128-
*
129-
* @param bool $configDetection Configuration detection
130-
* @param string $configLanguage Language from configuration
131-
* @return string[]
132-
*/
133-
private function detectLanguage(bool $configDetection, string $configLanguage): array
134-
{
135-
$detectedLang = [];
136-
$this->getUserAgentLanguage();
137-
138-
$detectedLang['post'] = $this->getPostLanguage();
139-
$detectedLang['get'] = $this->getGetLanguage();
140-
$detectedLang['artget'] = $this->getArtGetLanguage();
141-
$detectedLang['session'] = $this->getSessionLanguage();
142-
$detectedLang['config'] = $this->getConfigLanguage($configLanguage);
143-
$detectedLang['detection'] = $this->getDetectionLanguage($configDetection);
144-
145-
return $detectedLang;
146-
}
147-
148-
private function getPostLanguage(): ?string
149-
{
150-
$lang = Filter::filterInput(INPUT_POST, 'language', FILTER_SANITIZE_SPECIAL_CHARS);
151-
return static::isASupportedLanguage($lang) ? $lang : null;
152-
}
153-
154-
private function getGetLanguage(): ?string
155-
{
156-
$lang = Filter::filterInput(INPUT_GET, 'lang', FILTER_SANITIZE_SPECIAL_CHARS);
157-
return static::isASupportedLanguage($lang) ? $lang : null;
158-
}
159-
160-
private function getArtGetLanguage(): ?string
161-
{
162-
$lang = Filter::filterInput(INPUT_GET, 'artlang', FILTER_SANITIZE_SPECIAL_CHARS);
163-
return static::isASupportedLanguage($lang) ? $lang : null;
164-
}
165-
166-
private function getSessionLanguage(): ?string
167-
{
168-
$lang = $this->session->get('lang');
169-
return static::isASupportedLanguage($lang) ? trim((string) $lang) : null;
170-
}
171-
172-
private function getConfigLanguage(string $configLanguage): ?string
173-
{
174-
$lang = str_replace(['language_', '.php'], '', $configLanguage);
175-
return static::isASupportedLanguage($lang) ? $lang : null;
176-
}
177-
178-
private function getDetectionLanguage(bool $configDetection): ?string
179-
{
180-
return $configDetection && static::isASupportedLanguage($this->acceptLanguage)
181-
? strtolower($this->acceptLanguage)
182-
: null;
183-
}
184-
185-
/**
186-
* Selects the language.
187-
*
188-
* @param string[] $detectedLanguage Detected language
189-
*/
190-
private function selectLanguage(array $detectedLanguage): string
191-
{
192-
$priorityOrder = ['post', 'get', 'artget', 'session', 'detection', 'config'];
193-
194-
foreach ($priorityOrder as $source) {
195-
if (!empty($detectedLanguage[$source])) {
196-
return $detectedLanguage[$source];
197-
}
198-
}
199-
200-
return 'en';
201-
}
202-
203-
/**
204-
* Gets the accepted language from the user agent.
205-
*
206-
* HTTP_ACCEPT_LANGUAGE could be like the text below:
207-
* it,pt_BR;q=0.8,en_US;q=0.5,en;q=0.3
208-
*/
209-
private function getUserAgentLanguage(): void
210-
{
211-
$languages = Request::createFromGlobals()->getLanguages();
212-
213-
foreach ($languages as $language) {
214-
if (self::isASupportedLanguage(strtoupper($language))) {
215-
$this->acceptLanguage = strtolower($language);
216-
break;
217-
}
218-
}
219-
220-
// If the browser, e.g., sends "en_us", we want to get "en" only.
221-
if ('' === $this->acceptLanguage) {
222-
foreach ($languages as $language) {
223-
$language = substr($language, 0, 2);
224-
if (self::isASupportedLanguage(strtoupper($language))) {
225-
$this->acceptLanguage = strtolower($language);
226-
break;
227-
}
228-
}
229-
}
230-
}
231143
}

0 commit comments

Comments
 (0)