Файл: wboard/source/system/controller/panel.php
Строк: 308
<?php
/**
 * Wboard
 * Control Panel
 * @author Screamer
 * @copyright 2013
 */
class Module_panel extends Module
{
    /**
     * Index of Panel
     * Switch workmode
     * @param (string) $mode Mode
     * @param (string) $arg Argument for mode
     * @return (void)
     */
    public function index($mode = 'menu', $arg = '')
    {
        if (!$this->is_root && $mode != 'login') {
            $this->redirect('w_action/panel/index/login');
        } else {
            $mode = in_array($mode, array('ban_ip', 'login', 'menu', 'logout', 'login_history', 'settings', 'board'))
                ? '_' . $mode
                : FALSE;
            if ($mode === FALSE) {
                $this->redirect('w_action/err');
            } else {
                $this->$mode($arg);
            }
        }
    }
    /**
     * Login to panel
     * @return (void)
     */
    protected function _login()
    {
        if ($this->is_root === TRUE) {
            $this->redirect();
        }
        $error = array();
        if (!empty($_POST)) {
            $ups = isset($_POST['ups']) ? trim($_POST['ups']) : '';
            $captcha = isset($_POST['captcha']) ? trim($_POST['captcha']) : '';
            if ($captcha != $_SESSION['captcha']) {
                $error['captcha'] = $this->lng->wrong_captcha;
            } elseif (!empty($ups) && $this->settings['password'] == md5(md5($ups)) ) {
                if (isset($_POST['memory'])) {
                    $cups = md5($ups);
                    setcookie("cups", $cups, time() + 3600 * 24 * 365, "/");
                }
                $_SESSION['ups'] = md5(md5($ups));
                $this->redirect('w_action/panel');
            } else {
                $error['login'] = $this->lng->authorization_isnt_passed;
            }
        }
        $this->tpl->title = $this->lng->login;
        $this->tpl->set_output($this->tpl->load('panel_login', array(
            'error' => $error,
            'captcha' => $this->tpl->load('_captcha', array('error' => $error))
        )));
    }
    /**
     * Logout from panel
     * @return (void)
     */
    protected function _logout()
    {
        setcookie("cups", "", 0,  "/");
        unset($_SESSION['ups']);
        $this->redirect();
    }
    /**
     * Display menu
     * @return (void)
     */
    protected function _menu()
    {
        $this->tpl->title = $this->lng->control_panel;
        $this->tpl->set_output($this->tpl->load('panel', array(
            'links' => array(
                anchor('w_action/panel/index/board', $this->lng->create_board),
                anchor('w_action/panel/index/settings', $this->lng->settings),
                anchor('w_action/panel/index/ban_ip', $this->lng->ban_ip),
                anchor('w_action/panel/index/login_history', $this->lng->login_history),
                anchor('w_action/pages', $this->lng->static_pages),
                anchor('w_action/panel/index/logout', $this->lng->exit),
            )
        )));
    }
    /**
     * History of visits
     * @return (void)
     */
    protected function _login_history()
    {
        $list = $this->model->login_history();
        $out = '';
        foreach ($list as $item) {
            $out .= $this->tpl->load('panel_login_history_item', array(
                'ip' => $item['ip'] != 0 ? long2ip($item['ip']) : 'none',
                'ip_via_proxy' => $item['ip_via_proxy'] != 0 ? long2ip($item['ip_via_proxy']) : 'none',
                'user_agent' => !empty($item['user_agent']) ? htmlspecialchars($item['user_agent']) : 'Not recognised',
                'time' => $this->helper->display_time($item['time']),
            ));
        }
        $this->tpl->title = $this->lng->login_history;
        $this->tpl->set_output($this->tpl->load('_container', array('data' => $out,    'total' => count($list))));
    }
    /**
     * System settings
     * @return (void)
     */
    protected function _settings()
    {
        $error = array();
        $settings = array(
            'title' => 'trim',
            'meta' => array('keywords' => 'trim', 'description' => 'trim'),
            'user' => array('style' => 'trim', 'timeshift' => 'intval'),
        );
        // Load data (from _POST or default)
        foreach ($settings as $key => $val) {
            if (is_array($val)) {
                foreach ($val as $sub_key => $sub_val) {
                    $settings[$key][$sub_key] = isset($_POST[$key][$sub_key]) ? $sub_val($_POST[$key][$sub_key]) : $this->settings[$key][$sub_key];
                }
            } else {
                $settings[$key] = isset($_POST[$key]) ? $val($_POST[$key]) : $this->settings[$key];
            }
        }
        $settings['captcha'] = $this->settings['captcha']; // Captcha
        if (!empty($_POST)) {
            if (isset($_POST['ok'])) {
                // Check title
                if (mb_strlen($settings['title']) > 30 || empty($settings['title'])) {
                    $error['title'] = sprintf($this->lng->wrong_len, 1, 30);
                }
                // Check META-keywords
                if (mb_strlen($settings['meta']['keywords']) > 1000) {
                    $error['keywords'] = sprintf($this->lng->wrong_len_more, 1000);
                }
                // Check META-description
                if (mb_strlen($settings['meta']['description']) > 1000) {
                    $error['description'] = sprintf($this->lng->wrong_len_more, 1000);
                }
                // Check CSS style
                if (!$this->helper->css_exists($settings['user']['style'])) {
                    $error['css_style'] = TRUE;
                }
                // Check timeshift
                if ($settings['user']['timeshift'] > 12 || $settings['user']['timeshift'] < -12) {
                    $settings['user']['timeshift'] = 0;
                }
                // Check captcha
                $settings['captcha'] = isset($_POST['captcha']) ? 1 : 0;
                // Change password
                $old_pass = isset($_POST['old_pass']) ? trim($_POST['old_pass']) : '';
                $new_pass = isset($_POST['new_pass']) ? trim($_POST['new_pass']) : '';
                if (!empty($old_pass) && !empty($new_pass)) {
                    if (md5(md5($old_pass)) != $this->settings['password']) {
                        $error['old'] = $this->lng->wrong_old_pass;
                    }
                    if (mb_strlen($new_pass) < 10) {
                        $error['new'] = sprintf($this->lng->wrong_len_less, 10);
                    } elseif (is_numeric($new_pass)) {
                        $error['new'] = $this->lng->wrong_num;
                    }
                    if (empty($error)) {
                        $cups = md5($new_pass);
                        setcookie("cups", $cups, time() + 3600 * 24 * 365, "/");
                        $_SESSION['ups'] = md5(md5($new_pass));
                    }
                }
                if (empty($error)) {
                    // Save data
                    $password = isset($_SESSION['ups']) ? $_SESSION['ups'] : $this->settings['password'];
                    $this->model->panel_save_settings(array(
                        'title' => $this->db->real_escape_string($settings['title']),
                        'meta' => $this->db->real_escape_string(serialize($settings['meta'])),
                        'password' => $this->db->real_escape_string($password),
                        'user' => $this->db->real_escape_string(serialize($settings['user'])),
                        'captcha' => $settings['captcha'] == 0 ? 0 : 1,
                    ));
                }
            }
            if (empty($error)) {
                $this->redirect('w_action/panel');
            }
        }
        $this->tpl->title = $this->lng->settings;
        $this->tpl->set_output($this->tpl->load('panel_settings', array(
            'data' => $settings,
            'error' => $error,
            'css_styles' => $this->helper->css_styles_list(isset($error['css_style'])),
            'server_time' => date('d.m.Y / H:i:s', time()),
        )));
    }
    /**
     * Create/Edit board
     * @param (string) $name Name of board (for edit)
     * @return (void)
     */
    protected function _board($name = '')
    {
        if (!empty($name)) {
            // Edit board
            $board = $this->model->get_board($name);
            if (!is_array($board)) {
                $this->redirect('w_action/err');
            }
        } else {
            // Create board
            $board = array('name' => '', 'description' => '', 'rules' => '', 'bump_limit' => 100, 'max_threads' => 100, 'thread_ph' => 100);
        }
        $name = htmlspecialchars($name);
        $error = array();
        if (!empty($_POST)) {
            if (isset($_POST['ok'])) {
                // Get _POST data
                foreach ($board as $key => $val) {
                    if (isset($_POST[$key])) {
                        $board[$key] = trim($_POST[$key]);
                    }
                }
                // Is board hidden?
                $board['hidden'] = isset($_POST['hidden']) ? 1 : 0;
                if (empty($name)) {
                    // Check name
                    if (preg_match('/[^da-z]+/iu', $board['name'])) {
                        $error['name'] = $this->lng->wrong_chars;
                    } elseif (empty($board['name']) || strlen($board['name']) > 5) {
                        $error['name'] = sprintf($this->lng->wrong_len, 1, 5);
                    }
                    // Check board for exists
                    $path = $this->path . 'files' . DIRECTORY_SEPARATOR . 'boards' . DIRECTORY_SEPARATOR . $board['name'];
                    if (is_dir($path)) {
                        $error['name'] = $this->lng->board_already_exists;
                    }
                }
                // Check rules
                if (strlen($board['rules']) > 1000) {
                    $error['rules'] = sprintf($this->lng->wrong_len_more, 500);
                }
                // Check description
                if (strlen($board['description']) > 255) {
                    $error['description'] = sprintf($this->lng->wrong_len_more, 255);
                }
                // Check bump limit
                $board['bump_limit'] = intval($board['bump_limit']);
                if ($board['bump_limit'] < 100 || $board['bump_limit'] > 1000) {
                    $error['bump_limit'] = $this->lng->wrong_bump_limit;
                }
                // Check deal of threads
                $board['max_threads'] = intval($board['max_threads']);
                if ($board['max_threads'] < 10 || $board['max_threads'] > 500) {
                    $error['max_threads'] = $this->lng->wrong_max_threads;
                }
                // Check threads per hour limit
                $board['thread_ph'] = intval($board['thread_ph']);
                if ($board['thread_ph'] < 1 || $board['thread_ph'] > 999) {
                    $error['thread_ph'] = $this->lng->wrong_thread_per_hour;
                }
                if (empty($error)) {
                    $this->model->save_board($board, $name);
                    if (empty($name)) {
                        mkdir($path);
                        mkdir($path . DIRECTORY_SEPARATOR . 'res');
                        file_put_contents($path . DIRECTORY_SEPARATOR . 'res' . DIRECTORY_SEPARATOR . '.htaccess', 'Deny from all');
                    }
                    $this->redirect($board['name']);
                }
            } else {
                $this->redirect((!empty($name) ? $name : 'w_action/panel'));
            }
        }
        $this->tpl->title = !empty($name) ? $this->lng->edit_board : $this->lng->create_board;
        $this->tpl->set_output($this->tpl->load('panel_board', array(
            'error' => $error,
            'data' => $board,
            'name' => empty($name),
        )));
    }
    /**
     * Ban by IP
     * @return (void)
     */
    protected function _ban_ip()
    {
        $error = '';
        if (isset($_POST['ok'])) {
            // Add IP addresses to ban list
            $addresses = array();
            $comment = isset($_POST['comment']) ? mb_substr(trim($_POST['comment']), 0, 500) : '';
            if (isset($_POST['ip'])) {
                preg_match_all('#d{1,3}.d{1,3}.d{1,3}.d{1,3}#s', $_POST['ip'], $addresses);
                $addresses = $addresses[0];
            }
            if (empty($addresses)) {
                $error = $this->lng->no_addresses_given;
            } else {
                $addresses = array_map('ip2long', $addresses);
                // Check addresses for exists
                if ($this->model->check_ban_ip($addresses) > 0) {
                    $error = $this->lng->some_addresses_banned;
                } else {
                    // Add addresses to list
                    $this->model->ban_ip($addresses, $comment);
                }
            }
        } elseif (isset($_POST['delete'])) {
            $ip = isset($_POST['ip']) ? ip2long($_POST['ip']) : FALSE;
            if ($ip !== FALSE) {
                // Remove ip from list
                $this->model->remove_ban_ip($ip);
            }
        } elseif (isset($_POST['clear'])) {
            // Clear list
            $this->model->clear_ban_ip();
        }
        if (!empty($_POST) && empty($error)) {
            $this->redirect('w_action/panel/index/ban_ip');
        }
        // Prepare list to display
        $get_list = $this->model->get_ban_ip_list();
        $list = '';
        foreach ($get_list as $item) {
            $list .= $this->tpl->load('panel_ban_ip_item', array(
                'ip' => long2ip($item['ip']),
                'time' => $this->helper->display_time($item['time']),
                'comment' => nl2br(htmlspecialchars($item['comment'], ENT_QUOTES, 'UTF-8')),
            ));
        }
        $this->tpl->title = $this->lng->ban_ip;
        $this->tpl->set_output($this->tpl->load('panel_ban_ip', array(
            'list' => $list,
            'error' => $error,
        )));
    }
}