Skip to content

Commit

Permalink
Fixes logic order regarding theme initialization
Browse files Browse the repository at this point in the history
Signed-off-by: Jon Stovell <jonstovell@gmail.com>
  • Loading branch information
Sesquipedalian committed Feb 9, 2025
1 parent cd2f76c commit 537c94c
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 147 deletions.
3 changes: 1 addition & 2 deletions Sources/Actions/Profile/Main.php
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ public function execute(): void
Utils::$context['profile_updated'] = Lang::$txt['profile_updated_own'];
}

$this->setProfileAreas();
$menu = $this->createMenu();

$this->securityChecks();
Expand Down Expand Up @@ -847,8 +848,6 @@ protected function __construct()

Utils::$context['subs_available'] = !empty($num_subs);
}

$this->setProfileAreas();
}

/**
Expand Down
83 changes: 48 additions & 35 deletions Sources/Forum.php
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ public function __construct()
public function execute(): void
{
$this->init();

$requested_action = $_REQUEST['action'] ?? null;
$current_action = $this->findAction($requested_action);

Expand All @@ -457,33 +458,7 @@ public function execute(): void
IntegrationHook::call('integrate_init_action', [$action]);
}

$this->main();

// Is the forum in maintenance mode? (doesn't apply to administrators.)
if (
!empty(Config::$maintenance)
&& !User::$me->allowedTo('admin_forum')
&& self::$current_action?->canShowInMaintenanceMode() === false
) {
// Don't even try it, sonny.
self::inMaintenance();
}

// If guest access is off, a guest can only do one of a few actions.
if (
empty(Config::$modSettings['allow_guestAccess'])
&& User::$me->is_guest
&& (
self::$current_action?->isRestrictedGuestAccessAllowed() === false
|| (
!isset($_REQUEST['action'])
|| !in_array($_REQUEST['action'] ?? '', self::$guest_access_actions)
&& self::$current_action?->isRestrictedGuestAccessAllowed() === null
)
)
) {
User::$me->kickIfGuest(null, false);
}
$this->preflight();

if (isset($action)) {
$action->execute();
Expand Down Expand Up @@ -605,31 +580,44 @@ protected function init(): void
}
// Load the current theme. (note that ?theme=1 will also work, may be used for guest theming.)
else {
Theme::load();
Theme::load(0, false);
}

// Check if the user should be disallowed access.
User::$me->kickIfBanned();
}

/**
* The main forum loader.
*
* This method handles the main forum logic, such as checking permissions,
* logging user activity, and tracking forum statistics.
* Runs various checks that are required before calling the action.
*/
protected function main(): void
protected function preflight(): void
{
Theme::$current->initialize();

// If the user needs to accept the agreement or privacy policy, redirect now.
$this->requireAgreement();

// If we are in a topic and don't have permission to approve it then duck out now.
if (!empty(Topic::$topic_id) && empty(Board::$info->cur_topic_approved) && !User::$me->allowedTo('approve_posts') && (User::$me->id != Board::$info->cur_topic_starter || User::$me->is_guest)) {
if (
!empty(Topic::$topic_id)
&& empty(Board::$info->cur_topic_approved)
&& !User::$me->allowedTo('approve_posts')
&& (
User::$me->id != Board::$info->cur_topic_starter
|| User::$me->is_guest
)
) {
ErrorHandler::fatalLang('not_a_topic', false);
}

// Don't log if this is an attachment, avatar, toggle of editor buttons, theme option, XML feed, popup, etc.
if (self::$current_action?->canBeLogged() === true || (self::$current_action === null && !QueryString::isFilteredRequest(self::$unlogged_actions, 'action'))) {
if (
self::$current_action?->canBeLogged() === true
|| (
self::$current_action === null
&& !QueryString::isFilteredRequest(self::$unlogged_actions, 'action')
)
) {
// Log this user as online.
User::$me->logOnline();

Expand All @@ -641,6 +629,31 @@ protected function main(): void

// Make sure that our scheduled tasks have been running as intended.
Config::checkCron();

// Is the forum in maintenance mode? (doesn't apply to administrators.)
if (
!empty(Config::$maintenance)
&& !User::$me->allowedTo('admin_forum')
&& self::$current_action?->canShowInMaintenanceMode() === false
) {
// Don't even try it, sonny.
self::inMaintenance();
}

// If guest access is off, a guest can only do one of a few actions.
if (
empty(Config::$modSettings['allow_guestAccess'])
&& User::$me->is_guest
&& (
self::$current_action?->isRestrictedGuestAccessAllowed() !== true
&& (
!isset($_REQUEST['action'])
|| !in_array($_REQUEST['action'], self::$guest_access_actions)
)
)
) {
User::$me->kickIfGuest(null, false);
}
}

/**
Expand Down
224 changes: 114 additions & 110 deletions Sources/Theme.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,120 @@ class Theme
'name',
];

/****************
* Public methods
****************/

/**
* Sets a bunch of Utils::$context variables, loads templates and language
* files, and does other stuff that is required to use the theme for output.
*/
public function initialize(): void
{
$this->fixUrl();

// Create User::$me if it is missing (e.g., an error very early in the login process).
if (!isset(User::$me)) {
User::load();
}

$this->fixSmileySet();

// Some basic information...
if (!isset(Utils::$context['html_headers'])) {
Utils::$context['html_headers'] = '';
}

if (!isset(Utils::$context['javascript_files'])) {
Utils::$context['javascript_files'] = [];
}

if (!isset(Utils::$context['css_files'])) {
Utils::$context['css_files'] = [];
}

if (!isset(Utils::$context['css_header'])) {
Utils::$context['css_header'] = [];
}

if (!isset(Utils::$context['javascript_inline'])) {
Utils::$context['javascript_inline'] = ['standard' => [], 'defer' => []];
}

if (!isset(Utils::$context['javascript_vars'])) {
Utils::$context['javascript_vars'] = [];
}

Utils::$context['login_url'] = Config::$scripturl . '?action=login2';
Utils::$context['menu_separator'] = !empty($this->settings['use_image_buttons']) ? ' ' : ' | ';
Utils::$context['session_var'] = $_SESSION['session_var'];
Utils::$context['session_id'] = $_SESSION['session_value'];
Utils::$context['forum_name'] = Config::$mbname;
Utils::$context['forum_name_html_safe'] = Utils::htmlspecialchars(Utils::$context['forum_name']);
Utils::$context['header_logo_url_html_safe'] = empty($this->settings['header_logo_url']) ? '' : Utils::htmlspecialchars($this->settings['header_logo_url']);
Utils::$context['current_action'] = isset($_REQUEST['action']) ? Utils::htmlspecialchars($_REQUEST['action']) : null;
Utils::$context['current_subaction'] = $_REQUEST['sa'] ?? null;
Utils::$context['can_register'] = empty(Config::$modSettings['registration_method']) || Config::$modSettings['registration_method'] != 3;

if (isset(Config::$modSettings['load_average'])) {
Utils::$context['load_average'] = Config::$modSettings['load_average'];
}

// Detect the browser. This is separated out because it's also used in attachment downloads
BrowserDetector::call();

$this->loadTemplatesAndLangFiles();

// Allow overriding the forum's default time/number formats.
if (empty(User::$profiles[User::$me->id]['time_format']) && !empty(Lang::$txt['time_format'])) {
User::$me->time_format = Lang::$txt['time_format'];
}

// Set the character set from the template.
Utils::$context['character_set'] = empty(Config::$modSettings['global_character_set']) ? Lang::$txt['lang_character_set'] : Config::$modSettings['global_character_set'];
Utils::$context['right_to_left'] = !empty(Lang::$txt['lang_rtl']);

// Guests may still need a name.
if (User::$me->is_guest && empty(User::$me->name)) {
User::$me->name = Lang::$txt['guest_title'];
}

// Any theme-related strings that need to be loaded?
Lang::load('ThemeStrings', '', false);

// Make a special URL for the language.
$this->settings['lang_images_url'] = $this->settings['images_url'] . '/' . (!empty(Lang::$txt['image_lang']) ? Lang::$txt['image_lang'] : User::$me->language);

$this->loadCss();

$this->loadVariant();

Utils::$context['tabindex'] = 1;

$this->loadJavaScript();

$this->setupLinktree();

// Any files to include at this point?
if (!empty(Config::$modSettings['integrate_theme_include'])) {
$theme_includes = explode(',', Config::$modSettings['integrate_theme_include']);

foreach ($theme_includes as $include) {
$include = strtr(trim($include), ['$boarddir' => Config::$boarddir, '$sourcedir' => Config::$sourcedir, '$themedir' => $this->settings['theme_dir']]);

if (file_exists($include)) {
require_once $include;
}
}
}

// Call load theme integration functions.
IntegrationHook::call('integrate_load_theme');

// We are ready to go.
Utils::$context['theme_loaded'] = true;
}

/***********************
* Public static methods
***********************/
Expand Down Expand Up @@ -1881,116 +1995,6 @@ protected function __construct(int $id = 0, int $member = -1)
}
}

/**
* Sets a bunch of Utils::$context variables, loads templates and language
* files, and does other stuff that is required to use the theme for output.
*/
protected function initialize(): void
{
$this->fixUrl();

// Create User::$me if it is missing (e.g., an error very early in the login process).
if (!isset(User::$me)) {
User::load();
}

$this->fixSmileySet();

// Some basic information...
if (!isset(Utils::$context['html_headers'])) {
Utils::$context['html_headers'] = '';
}

if (!isset(Utils::$context['javascript_files'])) {
Utils::$context['javascript_files'] = [];
}

if (!isset(Utils::$context['css_files'])) {
Utils::$context['css_files'] = [];
}

if (!isset(Utils::$context['css_header'])) {
Utils::$context['css_header'] = [];
}

if (!isset(Utils::$context['javascript_inline'])) {
Utils::$context['javascript_inline'] = ['standard' => [], 'defer' => []];
}

if (!isset(Utils::$context['javascript_vars'])) {
Utils::$context['javascript_vars'] = [];
}

Utils::$context['login_url'] = Config::$scripturl . '?action=login2';
Utils::$context['menu_separator'] = !empty($this->settings['use_image_buttons']) ? ' ' : ' | ';
Utils::$context['session_var'] = $_SESSION['session_var'];
Utils::$context['session_id'] = $_SESSION['session_value'];
Utils::$context['forum_name'] = Config::$mbname;
Utils::$context['forum_name_html_safe'] = Utils::htmlspecialchars(Utils::$context['forum_name']);
Utils::$context['header_logo_url_html_safe'] = empty($this->settings['header_logo_url']) ? '' : Utils::htmlspecialchars($this->settings['header_logo_url']);
Utils::$context['current_action'] = isset($_REQUEST['action']) ? Utils::htmlspecialchars($_REQUEST['action']) : null;
Utils::$context['current_subaction'] = $_REQUEST['sa'] ?? null;
Utils::$context['can_register'] = empty(Config::$modSettings['registration_method']) || Config::$modSettings['registration_method'] != 3;

if (isset(Config::$modSettings['load_average'])) {
Utils::$context['load_average'] = Config::$modSettings['load_average'];
}

// Detect the browser. This is separated out because it's also used in attachment downloads
BrowserDetector::call();

$this->loadTemplatesAndLangFiles();

// Allow overriding the forum's default time/number formats.
if (empty(User::$profiles[User::$me->id]['time_format']) && !empty(Lang::$txt['time_format'])) {
User::$me->time_format = Lang::$txt['time_format'];
}

// Set the character set from the template.
Utils::$context['character_set'] = empty(Config::$modSettings['global_character_set']) ? Lang::$txt['lang_character_set'] : Config::$modSettings['global_character_set'];
Utils::$context['right_to_left'] = !empty(Lang::$txt['lang_rtl']);

// Guests may still need a name.
if (User::$me->is_guest && empty(User::$me->name)) {
User::$me->name = Lang::$txt['guest_title'];
}

// Any theme-related strings that need to be loaded?
Lang::load('ThemeStrings', '', false);

// Make a special URL for the language.
$this->settings['lang_images_url'] = $this->settings['images_url'] . '/' . (!empty(Lang::$txt['image_lang']) ? Lang::$txt['image_lang'] : User::$me->language);

$this->loadCss();

$this->loadVariant();

Utils::$context['tabindex'] = 1;

$this->loadJavaScript();

$this->setupLinktree();

// Any files to include at this point?
if (!empty(Config::$modSettings['integrate_theme_include'])) {
$theme_includes = explode(',', Config::$modSettings['integrate_theme_include']);

foreach ($theme_includes as $include) {
$include = strtr(trim($include), ['$boarddir' => Config::$boarddir, '$sourcedir' => Config::$sourcedir, '$themedir' => $this->settings['theme_dir']]);

if (file_exists($include)) {
require_once $include;
}
}
}

// Call load theme integration functions.
IntegrationHook::call('integrate_load_theme');

// We are ready to go.
Utils::$context['theme_loaded'] = true;
}

/**
* If the user got here using an unexpected URL, fix it.
*/
Expand Down

0 comments on commit 537c94c

Please sign in to comment.