Uncaught TypeError

User::getDisplayname(): Return value must be of type string, null returned

/home/novaverse-web/website/forum/core/classes/Core/User.php

https://novaverse.it/forum/index.php?route=%2Fpost%2F2-kingdoms-in-apertura-oggi%21%2F
/home/novaverse-web/website/forum/core/classes/Core/User.php
     * @param string|null $password Their password.
     * @param string $method What column to check for their details in. Can be either `username` or `email`.
     *
     * @return bool True/false on success or failure respectfully.
     */
    public function adminLogin(?string $username = null, ?string $password = null, string $method = 'email'): bool {
        return $this->_commonLogin($username, $password, true, $method, true);
    }

    /**
     * Get user's display name.
     *
     * @param bool $username If true, will use their username. If false, will use their nickname.
     * @return string Their display name.
     */
    public function getDisplayname(bool $username = false): string {
        if ($username) {
            return Output::getClean($this->data()->username);
        }

        return Output::getClean($this->data()->nickname);
    }

    /**
     * Build this user's profile link.
     *
     * @return string Compiled profile URL.
     */
    public function getProfileURL(): string {
        return URL::build('/profile/' . urlencode($this->data()->username));
    }

    /**
     * Get all of a user's groups id. Logged out/non-existent users will return just `0`.
     *
     * @return array Array of all their group IDs.
     */
    public function getAllGroupIds(): array {
        if (!$this->exists()) {
            return [0 => 0];
        }
/home/novaverse-web/website/forum/modules/Ghost/pages/posts.php

// Get post
$post = DB::getInstance()->get("ghost_posts", ["id", "=", $filtered_url])->results();
$post = $post[0];

$page_title = Output::getClean($post->name);
require_once(ROOT_PATH . '/core/templates/frontend_init.php');

// Timezone
Ghost::setTimezone();

// Purify post content
$post_content_filtered = strip_tags(Output::getDecoded($post->content));
$post_content_filtered = Text::truncate($post_content_filtered, '250', ['exact' => true, 'html' => true]);

$post_author = new User($post->author);
if ($post->date < time()) {
    $smarty->assign([
        'post_name' => Output::getClean($post->name),
        'post_date' => date("M jS\, Y", Output::getClean($post->date)),
        'post_author' => $post_author->getDisplayname(),
        'post_readtime' => str_replace("{x}", $post->readtime, $ghost_language->get('ghost', 'minute_read')),
        'post_image' => Output::getClean($post->image),
        'post_content' => Output::getDecoded($post->content),
        'post_content_filtered' => $post_content_filtered,
        'post_avatar' => $post_author->getAvatar('40'),
        'post_author_styles' => $post_author->getGroupStyle(),
        'post_author_profile' => $post_author->getProfileURL(),
        'post_author_groups' => $post_author->getMainGroup()->group_html
    ]);
} else {
    require_once(ROOT_PATH . '/404.php');
    die();
}

// View Counter
if ($user->isLoggedIn() || (defined('COOKIE_CHECK') && COOKIES_ALLOWED)) {
    if (!Cookie::exists('post-' . $post->id)) {
        DB::getInstance()->increment('ghost_posts', $post->id, 'views');
        Cookie::put('post-' . $post->id, 'true', 3600);
    }
/home/novaverse-web/website/forum/index.php
        die();
    }
} else {
    // Use recursion to check - might have URL parameters in path
    $path_array = explode('/', $route);

    for ($i = count($path_array) - 2; $i > 0; $i--) {

        $new_path = '/';
        for ($n = 1; $n <= $i; $n++) {
            $new_path .= $path_array[$n] . '/';
        }

        $new_path = rtrim($new_path, '/');

        if (array_key_exists($new_path, $all_pages)) {
            $path = implode(DIRECTORY_SEPARATOR, [ROOT_PATH, 'modules', $all_pages[$new_path]['module'], $all_pages[$new_path]['file']]);

            if (file_exists($path)) {
                $pages->setActivePage($all_pages[$new_path]);
                require($path);
                die();
            }
        }
    }
}

require(ROOT_PATH . '/404.php');
/home/novaverse-web/website/forum/modules/Ghost/classes/Ghost.php
SELECT * FROM nl2_settings WHERE `name` = 'timezone';
<?php
class Ghost {
   
    // Set correct timezone
    public static function setTimezone() {
  		$timezone = DB::getInstance()->get('settings', ['name', '=', 'timezone'])->results();
  		$timezone = $timezone[0]->value;
  		date_default_timezone_set($timezone);
    }

    // Purify post name (for post URL)
    public static function purifyPostName($name) {
        $name = preg_replace('/\s/u', '-', $name);
        $name = strtolower($name);
        return Output::getClean($name);
    }

    // Trim post content to 250 characters cleanly
    public static function purifyPostContent($content) {
        $content = Output::getPurified(Output::getDecoded($content));
        $content = strip_tags($content, '<br>');
        $content = preg_replace('/^(<br\s*\/?>)*|(<br\s*\/?>)*$/i', '', $content);
        $content = preg_replace("/<br\W*?\/>/", "➍", $content);
        //$content = Util::truncate($content, '250', array('exact' => false, 'html' => true));
        $content = Text::truncate($content, '250', array('exact' => false, 'html' => true));
        $content = preg_replace("/➍/", "<br/>", $content);
/home/novaverse-web/website/forum/core/templates/frontend_init.php
SELECT * FROM nl2_page_descriptions WHERE `page` = '/post/2-kingdoms-in-apertura-oggi!';
        $default_group = $cache->retrieve('default_group');
    } else {
        try {
            $default_group = Group::find(1, 'default_group')->id;
        } catch (Exception $e) {
            $default_group = 1;
        }

        $cache->store('default_group', $default_group);
    }
}

// Page metadata
if (isset($_GET['route']) && $_GET['route'] != '/') {
    $route = rtrim($_GET['route'], '/');
} else {
    $route = '/';
}

if (!defined('PAGE_DESCRIPTION')) {
    $page_metadata = DB::getInstance()->get('page_descriptions', ['page', $route]);
    if ($page_metadata->count()) {
        $page_metadata = $page_metadata->first();
        $smarty->assign([
            'PAGE_DESCRIPTION' => str_replace('{site}', Output::getClean(SITE_NAME), Output::getPurified($page_metadata->description)),
            'PAGE_KEYWORDS' => Output::getPurified($page_metadata->tags),
        ]);

        $og_image = $page_metadata->image;
        if ($og_image) {
            $smarty->assign('OG_IMAGE', rtrim(URL::getSelfURL(), '/') . $og_image);
        }
    }
} else {
    $smarty->assign([
        'PAGE_DESCRIPTION' => str_replace('{site}', Output::getClean(SITE_NAME), Output::getPurified(PAGE_DESCRIPTION)),
        'PAGE_KEYWORDS' => (defined('PAGE_KEYWORDS') ? Output::getPurified(PAGE_KEYWORDS) : '')
    ]);
}

$smarty->assign('TITLE', $page_title);
/home/novaverse-web/website/forum/modules/Ghost/pages/posts.php
SELECT * FROM nl2_ghost_posts WHERE `id` = '/forum/index.php?route=%2Fpost%2F2';
<?php
/*
 *	Ghost module made by Coldfire
 *	https://coldfiredzn.com
 *
 */
 
define('PAGE', 'ghost');

// Ghost class
require_once(ROOT_PATH . '/modules/Ghost/classes/Ghost.php');
$ghost = new Ghost();

// Page query string checker
$filtered_url = end(explode('/post/', $_SERVER['REQUEST_URI']));
if (str_contains($filtered_url, '-')) {
    $filtered_url = substr($filtered_url, 0, strpos($filtered_url, '-'));
}

// Get post
$post = DB::getInstance()->get("ghost_posts", ["id", "=", $filtered_url])->results();
$post = $post[0];

$page_title = Output::getClean($post->name);
require_once(ROOT_PATH . '/core/templates/frontend_init.php');

// Timezone
Ghost::setTimezone();

// Purify post content
$post_content_filtered = strip_tags(Output::getDecoded($post->content));
$post_content_filtered = Text::truncate($post_content_filtered, '250', ['exact' => true, 'html' => true]);

$post_author = new User($post->author);
if ($post->date < time()) {
    $smarty->assign([
        'post_name' => Output::getClean($post->name),
        'post_date' => date("M jS\, Y", Output::getClean($post->date)),
        'post_author' => $post_author->getDisplayname(),
        'post_readtime' => str_replace("{x}", $post->readtime, $ghost_language->get('ghost', 'minute_read')),
        'post_image' => Output::getClean($post->image),
/home/novaverse-web/website/forum/core/init.php
UPDATE nl2_online_guests SET `last_seen` = '2859' WHERE `id` =;
            'user_title' => Output::getClean($user->data()->user_title),
            'avatar' => $user->getAvatar(),
            'integrations' => $user_integrations
        ]);

        // Panel access?
        if ($user->canViewStaffCP()) {
            $smarty->assign([
                'PANEL_LINK' => URL::build('/panel'),
                'PANEL' => $language->get('moderator', 'staff_cp')
            ]);
        }
    } else {
        // Perform tasks for guests
        if (!$_SESSION['checked'] || (isset($_SESSION['checked']) && $_SESSION['checked'] <= strtotime('-5 minutes'))) {
            $already_online = DB::getInstance()->get('online_guests', ['ip', $ip])->results();

            $date = date('U');

            if (count($already_online)) {
                DB::getInstance()->update('online_guests', $already_online[0]->id, ['last_seen' => $date]);
            } else {
                DB::getInstance()->insert('online_guests', ['ip' => $ip, 'last_seen' => $date]);
            }

            $_SESSION['checked'] = $date;
        }

        // Auto language enabled?
        if (Util::getSetting('auto_language_detection')) {
            $smarty->assign('AUTO_LANGUAGE', true);
        }
    }

    // Dark mode
    $cache->setCache('template_settings');
    $darkMode = $cache->isCached('darkMode') ? $cache->retrieve('darkMode') : '0';
    if ($user->isLoggedIn()) {
        $darkMode = $user->data()->night_mode !== null ? $user->data()->night_mode : $darkMode;
    } else {
        if (Cookie::exists('night_mode')) {
/home/novaverse-web/website/forum/core/init.php
SELECT * FROM nl2_online_guests WHERE `ip` = '3.145.81.98';
            'username' => $user->getDisplayname(true),
            'nickname' => $user->getDisplayname(),
            'profile' => $user->getProfileURL(),
            'panel_profile' => URL::build('/panel/user/' . urlencode($user->data()->id) . '-' . urlencode($user->data()->username)),
            'username_style' => $user->getGroupStyle(),
            'user_title' => Output::getClean($user->data()->user_title),
            'avatar' => $user->getAvatar(),
            'integrations' => $user_integrations
        ]);

        // Panel access?
        if ($user->canViewStaffCP()) {
            $smarty->assign([
                'PANEL_LINK' => URL::build('/panel'),
                'PANEL' => $language->get('moderator', 'staff_cp')
            ]);
        }
    } else {
        // Perform tasks for guests
        if (!$_SESSION['checked'] || (isset($_SESSION['checked']) && $_SESSION['checked'] <= strtotime('-5 minutes'))) {
            $already_online = DB::getInstance()->get('online_guests', ['ip', $ip])->results();

            $date = date('U');

            if (count($already_online)) {
                DB::getInstance()->update('online_guests', $already_online[0]->id, ['last_seen' => $date]);
            } else {
                DB::getInstance()->insert('online_guests', ['ip' => $ip, 'last_seen' => $date]);
            }

            $_SESSION['checked'] = $date;
        }

        // Auto language enabled?
        if (Util::getSetting('auto_language_detection')) {
            $smarty->assign('AUTO_LANGUAGE', true);
        }
    }

    // Dark mode
    $cache->setCache('template_settings');
/home/novaverse-web/website/forum/modules/Forms/module.php
SELECT id, link_location, url, icon, title, guest FROM nl2_forms;
        $pages->add('Forms', '/user/submissions', 'pages/user/submissions.php');

        // Check if module version changed
        $cache->setCache('forms_module_cache');
        if (!$cache->isCached('module_version')) {
            $cache->store('module_version', $module_version);
        } else {
            if ($module_version != $cache->retrieve('module_version')) {
                // Version have changed, Perform actions
                $this->initialiseUpdate($cache->retrieve('module_version'));

                $cache->store('module_version', $module_version);

                if ($cache->isCached('update_check')) {
                    $cache->erase('update_check');
                }
            }
        }

        try {
            $forms = $this->_db->query('SELECT id, link_location, url, icon, title, guest FROM nl2_forms')->results();
            if (count($forms)) {
                if ($user->isLoggedIn()) {
                    $group_ids = implode(',', $user->getAllGroupIds());
                } else {
                    $group_ids = implode(',', array(0));
                }

                foreach ($forms as $form) {
                    // Register form page
                    $pages->add('Forms', $form->url, 'pages/form.php', 'form-' . $form->id, true);

                    $perm = false;
                    if (!$user->isLoggedIn() && $form->guest == 1) {
                        $perm = true;
                    }

                    if (!$perm) {
                        $hasperm = $this->_db->query('SELECT form_id FROM nl2_forms_permissions WHERE form_id = ? AND post = 1 AND group_id IN(' . $group_ids . ')', array($form->id));
                        if ($hasperm->count()) {
                            $perm = true;
/home/novaverse-web/website/forum/core/classes/Integrations/IntegrationBase.php
SELECT * FROM nl2_integrations WHERE name = 'Discord';
 * @author Partydragen
 * @version 2.1.0
 * @license MIT
 */

abstract class IntegrationBase {

    private DB $_db;
    private IntegrationData $_data;
    protected string $_icon;
    private array $_errors = [];
    protected Language $_language;
    protected ?string $_settings = null;

    protected string $_name;
    protected ?int $_order;

    public function __construct() {
        $this->_db = DB::getInstance();

        $integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name]);
        if ($integration->count()) {
            $integration = $integration->first();

            $this->_data = new IntegrationData($integration);
            $this->_order = $integration->order;
        } else {
            // Register integration to database
            $this->_db->query('INSERT INTO nl2_integrations (name) VALUES (?)', [
                $this->_name
            ]);

            $integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name])->first();

            $this->_data = new IntegrationData($integration);
            $this->_order = $integration->order;
        }
    }

    /**
     * Get the name of this integration.
/home/novaverse-web/website/forum/core/classes/Integrations/IntegrationBase.php
SELECT * FROM nl2_integrations WHERE name = 'Minecraft';
 * @author Partydragen
 * @version 2.1.0
 * @license MIT
 */

abstract class IntegrationBase {

    private DB $_db;
    private IntegrationData $_data;
    protected string $_icon;
    private array $_errors = [];
    protected Language $_language;
    protected ?string $_settings = null;

    protected string $_name;
    protected ?int $_order;

    public function __construct() {
        $this->_db = DB::getInstance();

        $integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name]);
        if ($integration->count()) {
            $integration = $integration->first();

            $this->_data = new IntegrationData($integration);
            $this->_order = $integration->order;
        } else {
            // Register integration to database
            $this->_db->query('INSERT INTO nl2_integrations (name) VALUES (?)', [
                $this->_name
            ]);

            $integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name])->first();

            $this->_data = new IntegrationData($integration);
            $this->_order = $integration->order;
        }
    }

    /**
     * Get the name of this integration.
/home/novaverse-web/website/forum/modules/Core/module.php
SELECT * FROM nl2_custom_pages_permissions WHERE `group_id` = '0';
                                                $navigation->add(
                                                    $custom_page->id,
                                                    Output::getClean($custom_page->title),
                                                    (is_null($redirect)) ? URL::build(Output::urlEncodeAllowSlashes($custom_page->url)) : $redirect,
                                                    'footer', $custom_page->target ? '_blank' : null,
                                                    2000,
                                                    $custom_page->icon
                                                );
                                                break;
                                        }
                                        break 2;
                                    }

                                    break;
                                }
                            }
                        }
                    }
                }
            } else {
                $custom_page_permissions = DB::getInstance()->get('custom_pages_permissions', ['group_id', 0])->results();
                if (count($custom_page_permissions)) {
                    foreach ($custom_pages as $custom_page) {
                        $redirect = null;

                        if ($custom_page->redirect == 1) {
                            $redirect = Output::getClean($custom_page->link);
                        }

                        $pages->addCustom(Output::urlEncodeAllowSlashes($custom_page->url), Output::getClean($custom_page->title), !$custom_page->basic);

                        foreach ($custom_page_permissions as $permission) {
                            if ($permission->page_id == $custom_page->id) {
                                if ($permission->view == 1) {
                                    // Check cache for order
                                    if (!$cache->isCached($custom_page->id . '_order')) {
                                        // Create cache entry now
                                        $page_order = 200;
                                        $cache->store($custom_page->id . '_order', 200);
                                    } else {
                                        $page_order = $cache->retrieve($custom_page->id . '_order');
/home/novaverse-web/website/forum/modules/Core/module.php
SELECT * FROM nl2_custom_pages WHERE `id` <> '0';
        }

        // "More" dropdown
        $cache->setCache('navbar_icons');
        if ($cache->isCached('more_dropdown_icon')) {
            $icon = $cache->retrieve('more_dropdown_icon');
        } else {
            $icon = '';
        }

        $cache->setCache('navbar_order');
        if ($cache->isCached('more_dropdown_order')) {
            $order = $cache->retrieve('more_dropdown_order');
        } else {
            $order = 2500;
        }

        $navigation->addDropdown('more_dropdown', $language->get('general', 'more'), 'top', $order, $icon);

        // Custom pages
        $custom_pages = DB::getInstance()->get('custom_pages', ['id', '<>', 0])->results();
        if (count($custom_pages)) {
            $more = [];
            $cache->setCache('navbar_order');

            if ($user->isLoggedIn()) {
                // Check all groups
                $user_groups = $user->getAllGroupIds();

                foreach ($custom_pages as $custom_page) {
                    $redirect = null;

                    // Get redirect URL if enabled
                    if ($custom_page->redirect == 1) {
                        $redirect = $custom_page->link;
                    }

                    $pages->addCustom(Output::urlEncodeAllowSlashes($custom_page->url), Output::getClean($custom_page->title), !$custom_page->basic);

                    foreach ($user_groups as $user_group) {
                        $custom_page_permissions = DB::getInstance()->get('custom_pages_permissions', ['group_id', $user_group])->results();
/home/novaverse-web/website/forum/core/classes/Core/Settings.php
SELECT `name`, `value` FROM `nl2_settings` WHERE `module` IS NULL;
    }

    private static function setSettingsCache(?string $module, array $cache): void {
        $cache_name = $module !== null ? $module : 'core';
        self::$_cached_settings[$cache_name] = $cache;
    }

    /**
     * Get a setting from the database table `nl2_settings`.
     *
     * @param string $setting Setting to check.
     * @param ?string $fallback Fallback to return if $setting is not set in DB. Defaults to null.
     * @param string $module Module name to keep settings separate from other modules. Set module
     *                       to 'Core' for global settings.
     * @return ?string Setting from DB or $fallback.
     */
    public static function get(string $setting, ?string $fallback = null, string $module = 'core'): ?string {
        if (!self::hasSettingsCache($module)) {
            // Load all settings for this module and store it as a dictionary
            if ($module === 'core') {
                $result = DB::getInstance()->query('SELECT `name`, `value` FROM `nl2_settings` WHERE `module` IS NULL')->results();
            } else {
                $result = DB::getInstance()->query('SELECT `name`, `value` FROM `nl2_settings` WHERE `module` = ?', [$module])->results();
            }

            $cache = [];
            foreach ($result as $row) {
                $cache[$row->name] = $row->value;
            }
            self::setSettingsCache($module, $cache);
        }

        $cache = &self::getSettingsCache($module);
        return $cache[$setting] ?? $fallback;
    }

    /**
     * Modify a setting in the database table `nl2_settings`.
     *
     * @param string $setting Setting name.
     * @param string|null $new_value New setting value, or null to delete
/home/novaverse-web/website/forum/core/classes/Database/PhinxAdapter.php
SELECT version, migration_name FROM nl2_phinxlog;
     * Checks the number of existing migration files compared to executed migrations in the database.
     * Alternatively we could check the output of a Phinx command, but that takes ~8x as long to execute.
     *
     * @throws RuntimeException If these numbers don't match.
     */
    public static function ensureUpToDate(): void {
        $migration_files = array_map(
            static function ($file_name) {
                [$version, $migration_name] = explode('_', $file_name, 2);
                $migration_name = str_replace(['.php', '_'], '', ucwords($migration_name, '_'));
                return $version . '_' . $migration_name;
            },
            array_filter(scandir(__DIR__ . '/../../migrations'), static function ($file_name) {
                // Pattern that matches Phinx migration file names (eg: 20230403000000_create_stroopwafel_table.php)
                return preg_match('/^\d{14}_\w+\.php$/', $file_name);
            }),
        );

        $migration_database_entries = array_map(static function ($row) {
            return $row->version . '_' . $row->migration_name;
        }, DB::getInstance()->query('SELECT version, migration_name FROM nl2_phinxlog')->results());

        $missing = array_diff($migration_files, $migration_database_entries);
        $extra = array_diff($migration_database_entries, $migration_files);

        // Likely a pull from the repo dev branch or migrations
        // weren't run during an upgrade script.
        if (($missing_count = count($missing)) > 0) {
            echo "There are $missing_count migrations files which have not been executed:" . '<br>';
            foreach ($missing as $missing_migration) {
                echo " - $missing_migration" . '<br>';
            }
        }

        // Something went wonky, either they've deleted migration files,
        // or they've added stuff to the nl2_phinxlog table.
        if (($extra_count = count($extra)) > 0) {
            if ($missing_count > 0) {
                echo '<br>';
            }
            echo "There are $extra_count executed migrations which do not have migration files associated:" . '<br>';