conn = $settings->conn;
        $this->settings = $settings;
        $this->uuid_name_cache = array();
        $this->time = microtime(true);
        $this->page = 1;
        if (isset($_GET['page'])) {
            $page = $_GET['page']; // user input
            if (filter_var($page, FILTER_VALIDATE_INT)) {
                $this->page = (int)$page;
            }
        }
        $this->name = $name;
        switch ($name) {
            case "ban":
            case "bans":
                $this->type = "ban";
                $this->table = $settings->table['bans'];
                break;
            case "mute":
            case "mutes":
                $this->type = "mute";
                $this->table = $settings->table['mutes'];
                break;
            case "warn":
            case "warnings":
                $this->type = "warn";
                $this->table = $settings->table['warnings'];
                break;
            case "kick":
            case "kicks":
                $this->type = "kick";
                $this->table = $settings->table['kicks'];
                break;
        }
        $this->permanent = array(
            'ban'  => 'Permanent Ban',
            'mute' => 'Permanent Mute',
            'warn' => 'Permanent',
            'kick' => null,
        );
        $this->expired = array(
            'ban'  => '(Unbanned)',
            'mute' => '(Unmuted)',
            'warn' => '(Expired)',
            'kick' => null,
        );
    }
    function run_query() {
        try {
            $table = $this->table;
            $active_query = $this->settings->active_query;
            $limit = $this->settings->limit_per_page;
            $offset = 0;
            if ($this->settings->show_pager) {
                $page = $this->page - 1;
                $offset = ($limit * $page);
            }
            $query = "SELECT * FROM $table $active_query GROUP BY $table.id ORDER BY time DESC LIMIT :limit OFFSET :offset";
            $st = $this->conn->prepare($query);
            $st->bindParam(':offset', $offset, PDO::PARAM_INT);
            $st->bindParam(':limit', $limit, PDO::PARAM_INT);
            $st->execute();
            return $st;
        } catch (PDOException $ex) {
            die($ex->getMessage());
        }
    }
    /**
     * Returns an  tag representing the Minecraft avatar for a specific name.
     * @param string
     * @return string
     */
    function get_avatar($name) {
        return "
$name";
    }
    /**
     * Returns the last name for a UUID, or null if their name is not recorded in the database.
     * @param string
     * @return null|string
     */
    function get_name($uuid) {
        if (array_key_exists($uuid, $this->uuid_name_cache)) return $this->uuid_name_cache[$uuid];
        $history = $this->settings->table['history'];
        $stmt = $this->conn->prepare("SELECT name FROM $history WHERE uuid=? ORDER BY date DESC LIMIT 1");
        if ($stmt->execute(array($uuid)) && $row = $stmt->fetch()) {
            $banner = $row['name'];
            $this->uuid_name_cache[$uuid] = $banner;
            return $banner;
        }
        $this->uuid_name_cache[$uuid] = null;
        return null;
    }
    /**
     * Returns the banner name for a specific row in the database
     * using their UUID->name if possible, otherwise returns their last recorded name.
     * @param row
     * @return string
     */
    function get_banner_name($row) {
        $uuid = $row['banned_by_uuid'];
        $name = $this->get_name($uuid);
        if ($name !== null) {
            return $name;
        }
        $name = $row['banned_by_name'];
        return $this->clean($name);
    }
    /**
     * Converts a timestamp (in milliseconds) to a date using the configured date format.
     * @param int
     * @return string
     */
    function millis_to_date($millis) {
        return date($this->settings->date_format, $millis / 1000);
    }
    /**
     * Prepares text to be displayed on the web interface.
     * Removes chat colours, replaces newlines with proper HTML, and sanitizes the text.
     * @param string
     * @return string
     */
    function clean($text) {
        if (strstr($text, "\xa7") || strstr($text, "&")) {
            $text = preg_replace("/(?i)(\xa7|&)[0-9A-FK-OR]/", "", $text);
        }
        $text = htmlspecialchars($text, ENT_QUOTES, "UTF-8");
        if (strstr($text, "\n")) {
            $text = preg_replace("/\n/", "
", $text);
        }
        return $text;
    }
    /**
     * Returns a string that shows the expiry date of a punishment.
     * If the punishment does not expire, it will be shown as permanent.
     * If the punishment has already expired, it will show as expired.
     * @param row
     * @return string
     */
    public function expiry($row) {
        if ($row['until'] <= 0) {
            return $this->permanent[$this->type];
        }
        $until = $this->millis_to_date($row['until']);
        if ($this->settings->show_inactive_bans && !$row['active']) {
            $until .= ' ' . $this->expired[$this->type];
        }
        return $until;
    }
    function title() {
        return ucfirst($this->name);
    }
    function print_title() {
        $title = $this->title();
        $name = $this->settings->name;
        echo "