diff --git a/admin/admin_log.php b/admin/admin_log.php
index 01dbba373..83acef019 100644
--- a/admin/admin_log.php
+++ b/admin/admin_log.php
@@ -235,6 +235,11 @@ if ($log_rowset) {
case $log_type['mod_post_pin']:
case $log_type['mod_post_unpin']:
case $log_type['mod_topic_split']:
+ case $log_type['mod_topic_poll_started']:
+ case $log_type['mod_topic_poll_finished']:
+ case $log_type['mod_topic_poll_deleted']:
+ case $log_type['mod_topic_poll_added']:
+ case $log_type['mod_topic_poll_edited']:
// topic_title
if (!empty($row['log_topic_title'])) {
$topic_title = $row['log_topic_title'];
diff --git a/common.php b/common.php
index 333d2e821..d6806c4a6 100644
--- a/common.php
+++ b/common.php
@@ -350,6 +350,18 @@ function array_deep(&$var, $fn, $one_dimensional = false, $array_only = false, $
}
}
+function array_deep_merge($base, $overlay)
+{
+ foreach ($overlay as $key => $value) {
+ if (is_array($value) && isset($base[$key]) && is_array($base[$key])) {
+ $base[$key] = array_deep_merge($base[$key], $value);
+ } else {
+ $base[$key] = $value;
+ }
+ }
+ return $base;
+}
+
/**
* Hide BB_PATH
*
diff --git a/library/config.php b/library/config.php
index 95a36f6c0..127988894 100644
--- a/library/config.php
+++ b/library/config.php
@@ -75,6 +75,7 @@ $bb_cfg['cache'] = [
'bb_login_err' => ['filecache'],
'bb_poll_data' => ['filecache'],
'bb_ip2countries' => ['filecache'],
+ 'bb_lang' => ['filecache'],
],
];
diff --git a/library/includes/functions.php b/library/includes/functions.php
index 38db141cd..7af41b25d 100644
--- a/library/includes/functions.php
+++ b/library/includes/functions.php
@@ -271,10 +271,7 @@ function auth($type, $forum_id, $ug_data, array $f_access = [], $group_perm = UG
$add_auth_type_desc = ($forum_id != AUTH_LIST_ALL);
// Check forum existence
- if (!forum_exists()) {
- return [];
- }
- if ($add_auth_type_desc && !forum_exists($forum_id)) {
+ if (!forum_exists() || ($add_auth_type_desc && !forum_exists($forum_id))) {
return [];
}
@@ -1612,16 +1609,18 @@ function get_topic_title($topic_id)
function forum_exists($forum_id = null): bool
{
- if (!isset($forum_id)) {
- return (bool)DB()->fetch_row("SELECT * FROM " . BB_FORUMS . " LIMIT 1");
+ if ($forum_id === null) {
+ return (bool)DB()->fetch_row("SELECT 1 FROM " . BB_FORUMS . " LIMIT 1");
}
- return (bool)DB()->fetch_row("SELECT forum_id FROM " . BB_FORUMS . " WHERE forum_id = $forum_id LIMIT 1");
+ $forum_id = (int)$forum_id;
+ return (bool)DB()->fetch_row("SELECT 1 FROM " . BB_FORUMS . " WHERE forum_id = $forum_id LIMIT 1");
}
function cat_exists($cat_id): bool
{
- return (bool)DB()->fetch_row("SELECT cat_id FROM " . BB_CATEGORIES . " WHERE cat_id = $cat_id LIMIT 1");
+ $cat_id = (int)$cat_id;
+ return (bool)DB()->fetch_row("SELECT 1 FROM " . BB_CATEGORIES . " WHERE cat_id = $cat_id LIMIT 1");
}
function get_topic_icon($topic, $is_unread = null)
diff --git a/library/includes/init_bb.php b/library/includes/init_bb.php
index 1cb8a6c6f..e529d928f 100644
--- a/library/includes/init_bb.php
+++ b/library/includes/init_bb.php
@@ -183,7 +183,8 @@ define('FEMALE', 2);
define('NOGENDER', 0);
// Poll
-# 1 - обычный опрос
+define('POLL_DELETED', 0);
+define('POLL_STARTED', 1);
define('POLL_FINISHED', 2);
// Group avatars
diff --git a/library/language/source/main.php b/library/language/source/main.php
index 1a4b56a5c..e231359e2 100644
--- a/library/language/source/main.php
+++ b/library/language/source/main.php
@@ -2836,6 +2836,11 @@ $lang['LOG_ACTION']['LOG_TYPE'] = [
'mod_topic_tor_register' => 'Topic:
torrent registered',
'mod_topic_tor_delete' => 'Topic:
torrent deleted',
'mod_topic_renamed' => 'Topic:
renamed',
+ 'mod_topic_poll_started' => 'Topic:
poll started',
+ 'mod_topic_poll_finished' => 'Topic:
poll finished',
+ 'mod_topic_poll_deleted' => 'Topic:
poll deleted',
+ 'mod_topic_poll_added' => 'Topic:
poll added',
+ 'mod_topic_poll_edited' => 'Topic:
poll edited',
'mod_post_delete' => 'Post:
deleted',
'mod_post_pin' => 'Post:
pinned',
'mod_post_unpin' => 'Post:
unpinned',
diff --git a/poll.php b/poll.php
index f64d04b70..8ea9b6648 100644
--- a/poll.php
+++ b/poll.php
@@ -103,8 +103,15 @@ switch ($mode) {
bb_die($lang['POST_HAS_NO_POLL']);
}
+ // Log action
+ $log_action->mod('mod_topic_poll_started', [
+ 'forum_id' => $forum_id,
+ 'topic_id' => $topic_id,
+ 'topic_title' => $t_data['topic_title'],
+ ]);
+
// Starting the poll
- DB()->query("UPDATE " . BB_TOPICS . " SET topic_vote = 1 WHERE topic_id = $topic_id");
+ DB()->query("UPDATE " . BB_TOPICS . " SET topic_vote = " . POLL_STARTED . " WHERE topic_id = $topic_id");
bb_die($lang['NEW_POLL_START']);
break;
case 'poll_finish':
@@ -113,6 +120,13 @@ switch ($mode) {
bb_die($lang['POST_HAS_NO_POLL']);
}
+ // Log action
+ $log_action->mod('mod_topic_poll_finished', [
+ 'forum_id' => $forum_id,
+ 'topic_id' => $topic_id,
+ 'topic_title' => $t_data['topic_title'],
+ ]);
+
// Finishing the poll
DB()->query("UPDATE " . BB_TOPICS . " SET topic_vote = " . POLL_FINISHED . " WHERE topic_id = $topic_id");
bb_die($lang['NEW_POLL_END']);
@@ -123,6 +137,13 @@ switch ($mode) {
bb_die($lang['POST_HAS_NO_POLL']);
}
+ // Log action
+ $log_action->mod('mod_topic_poll_deleted', [
+ 'forum_id' => $forum_id,
+ 'topic_id' => $topic_id,
+ 'topic_title' => $t_data['topic_title'],
+ ]);
+
// Removing poll from database
$poll->delete_poll($topic_id);
bb_die($lang['NEW_POLL_DELETE']);
@@ -141,6 +162,13 @@ switch ($mode) {
bb_die($poll->err_msg);
}
+ // Log action
+ $log_action->mod('mod_topic_poll_added', [
+ 'forum_id' => $forum_id,
+ 'topic_id' => $topic_id,
+ 'topic_title' => $t_data['topic_title'],
+ ]);
+
// Adding poll info to the database
$poll->insert_votes_into_db($topic_id);
bb_die($lang['NEW_POLL_ADDED']);
@@ -159,6 +187,13 @@ switch ($mode) {
bb_die($poll->err_msg);
}
+ // Log action
+ $log_action->mod('mod_topic_poll_edited', [
+ 'forum_id' => $forum_id,
+ 'topic_id' => $topic_id,
+ 'topic_title' => $t_data['topic_title'],
+ ]);
+
// Updating poll info to the database
$poll->insert_votes_into_db($topic_id);
CACHE('bb_poll_data')->rm("poll_$topic_id");
diff --git a/src/Legacy/Common/User.php b/src/Legacy/Common/User.php
index b1a6a6713..5bb58c1a6 100644
--- a/src/Legacy/Common/User.php
+++ b/src/Legacy/Common/User.php
@@ -622,17 +622,50 @@ class User
define('LANG_DIR', DEFAULT_LANG_DIR);
}
- /** Temporary place source language to the global */
- $lang = [];
- require(SOURCE_LANG_DIR . 'main.php');
- $source_lang = $lang;
- unset($lang);
+ $langKey = $this->data['user_lang'];
+ $cacheKey = "merged_lang_{$langKey}";
- /** Place user language to the global */
- global $lang;
- require(LANG_DIR . 'main.php');
- setlocale(LC_ALL, $bb_cfg['lang'][$this->data['user_lang']]['locale'] ?? 'en_US.UTF-8');
- $lang += $source_lang;
+ if ($cachedLang = CACHE('bb_lang')->get($cacheKey)) {
+ global $lang;
+ $lang = $cachedLang['merged'];
+ $source_lang = $cachedLang['source'];
+ } else {
+ $sourceCacheKey = 'source_lang';
+ if (!($source_lang = CACHE('bb_lang')->get($sourceCacheKey))) {
+ $lang = [];
+ require(SOURCE_LANG_DIR . 'main.php');
+ $source_lang = $lang;
+ unset($lang);
+
+ CACHE('bb_lang')->set($sourceCacheKey, $source_lang, 86400);
+ }
+
+ $userLangCacheKey = "user_lang_{$langKey}";
+ if (!($userLang = CACHE('bb_lang')->get($userLangCacheKey))) {
+ $lang = [];
+ require(LANG_DIR . 'main.php');
+ $userLang = $lang;
+ unset($lang);
+
+ CACHE('bb_lang')->set($userLangCacheKey, $userLang, 86400);
+ }
+
+ global $lang;
+ $lang = $this->arrayMergeLangs($source_lang, $userLang);
+
+ CACHE('bb_lang')->set($cacheKey, [
+ 'merged' => $lang,
+ 'source' => $source_lang
+ ], 86400);
+ }
+
+ static $currentLocale = null;
+ $newLocale = $bb_cfg['lang'][$this->data['user_lang']]['locale'] ?? 'en_US.UTF-8';
+
+ if ($currentLocale !== $newLocale) {
+ setlocale(LC_ALL, $newLocale);
+ $currentLocale = $newLocale;
+ }
$theme = setup_style();
$DeltaTime = new DateDelta();
@@ -645,6 +678,51 @@ class User
$this->load_opt_js();
}
+ public function arrayMergeLangs($base, $overlay, $cacheKey = null)
+ {
+ if ($cacheKey && function_exists('CACHE')) {
+ if ($cached = CACHE('bb_lang')->get($cacheKey)) {
+ return $cached;
+ }
+ }
+
+ if (count($overlay) <= 10) {
+ $result = array_replace_recursive($base, $overlay);
+ } else {
+ $result = array_deep_merge($base, $overlay);
+ }
+
+ if ($cacheKey && function_exists('CACHE')) {
+ CACHE('bb_lang')->set($cacheKey, $result, 3600);
+ }
+
+ return $result;
+ }
+
+ public function clearLanguageCache($langKey = null): void
+ {
+ if ($langKey) {
+ CACHE('bb_lang')->rm("merged_lang_{$langKey}");
+ CACHE('bb_lang')->rm("user_lang_{$langKey}");
+ } else {
+ CACHE('bb_lang')->rm('source_lang');
+ }
+ }
+
+ public function clearAllLanguageCache(): void
+ {
+ global $bb_cfg;
+
+ CACHE('bb_lang')->rm('source_lang');
+
+ if (isset($bb_cfg['lang']) && is_array($bb_cfg['lang'])) {
+ foreach (array_keys($bb_cfg['lang']) as $lang) {
+ CACHE('bb_lang')->rm("merged_lang_{$lang}");
+ CACHE('bb_lang')->rm("user_lang_{$lang}");
+ }
+ }
+ }
+
/**
* Mark read
*
diff --git a/src/Legacy/LogAction.php b/src/Legacy/LogAction.php
index e4af99bb7..c200f310d 100644
--- a/src/Legacy/LogAction.php
+++ b/src/Legacy/LogAction.php
@@ -35,6 +35,11 @@ class LogAction
'mod_topic_tor_unregister' => 17,
'mod_topic_tor_register' => 18,
'mod_topic_tor_delete' => 19,
+ 'mod_topic_poll_started' => 20,
+ 'mod_topic_poll_finished' => 21,
+ 'mod_topic_poll_deleted' => 22,
+ 'mod_topic_poll_added' => 23,
+ 'mod_topic_poll_edited' => 24
];
public $log_type_select = [];
public $log_disabled = false;
diff --git a/src/Legacy/Poll.php b/src/Legacy/Poll.php
index c0d70b7bc..0dd8c290d 100644
--- a/src/Legacy/Poll.php
+++ b/src/Legacy/Poll.php
@@ -79,7 +79,7 @@ class Poll
DB()->query("REPLACE INTO " . BB_POLL_VOTES . $sql_args);
- DB()->query("UPDATE " . BB_TOPICS . " SET topic_vote = 1 WHERE topic_id = $topic_id");
+ DB()->query("UPDATE " . BB_TOPICS . " SET topic_vote = " . POLL_STARTED . " WHERE topic_id = $topic_id");
}
/**
@@ -89,7 +89,7 @@ class Poll
*/
public function delete_poll($topic_id)
{
- DB()->query("UPDATE " . BB_TOPICS . " SET topic_vote = 0 WHERE topic_id = $topic_id");
+ DB()->query("UPDATE " . BB_TOPICS . " SET topic_vote = " . POLL_DELETED . " WHERE topic_id = $topic_id");
$this->delete_votes_data($topic_id);
}
@@ -163,6 +163,6 @@ class Poll
public static function pollIsActive(array $t_data): bool
{
global $bb_cfg;
- return ($t_data['topic_vote'] == 1 && $t_data['topic_time'] > TIMENOW - $bb_cfg['poll_max_days'] * 86400);
+ return ($t_data['topic_vote'] == POLL_STARTED && $t_data['topic_time'] > TIMENOW - $bb_cfg['poll_max_days'] * 86400);
}
}